@@ -437,8 +437,81 @@ module Interval_domain = struct
437
437
) (point Z. zero) (Shostak.Bitv. embed r)
438
438
end
439
439
440
+ let normal_form_bv bv =
441
+ let rec loop cte mask r_sz acc = function
442
+ | [] -> List. rev acc, (cte, mask, r_sz)
443
+ | { Bitv. bv = Bitv. Cte n ; sz } :: bv' ->
444
+ let cte = Z. (cte lsl sz lor n) in
445
+ let mask = Z. (mask lsl sz lor (extract minus_one 0 sz)) in
446
+ let acc =
447
+ match acc with
448
+ | [] -> []
449
+ | _ -> { Bitv. bv = Bitv. Cte Z. zero ; sz } :: acc
450
+ in
451
+ loop cte mask (r_sz + sz) acc bv'
452
+ | x :: bv' ->
453
+ let cte = Z. (cte lsl x.sz) in
454
+ let mask = Z. (mask lsl x.sz) in
455
+ loop cte mask (r_sz + x.sz) (x :: acc) bv'
456
+ in loop Z. zero Z. zero 0 [] bv
457
+
458
+ let normal_form_r r =
459
+ let bv, ofs = normal_form_bv (Shostak.Bitv. embed r) in
460
+ match bv with
461
+ | [] -> None , ofs
462
+ | bv -> Some (Shostak.Bitv. is_mine bv), ofs
463
+
464
+ module NF = struct
465
+ type expr = X .r
466
+
467
+ type var = X .r
468
+
469
+ type ofs = Z .t * Z .t * int
470
+
471
+ let pp_ofs ppf (cte , mask , sz ) =
472
+ Fmt. pf ppf " %s & %s [%d]"
473
+ (Z. format " %b" cte) (Z. format " %b" mask) sz
474
+
475
+ let ofs_sub (cte1 , mask1 , sz1 ) (cte2 , mask2 , sz2 ) =
476
+ assert (sz1 = sz2);
477
+ assert (Z. equal (Z. logand mask2 (Z. lognot mask1)) Z. zero);
478
+ assert (Z. equal (Z. logand mask2 cte1) cte2);
479
+ let cte = Z. sub cte1 cte2 in
480
+ assert (Z. equal cte (Z. logand cte1 (Z. lognot mask2)));
481
+ let sz = Z. numbits (Z. extract (Z. lognot mask2) 0 sz1) in
482
+ (Z. extract cte 0 sz, Z. extract mask1 0 sz, sz)
483
+
484
+ let decompose = normal_form_r
485
+ end
486
+
487
+ module IDD = struct
488
+ type var = X .r
489
+
490
+ type ofs = Z .t * Z .t * int
491
+
492
+ let default_domain r =
493
+ Interval_domain. map_leaves (fun r ->
494
+ Interval_domain. unknown (X. type_info r)
495
+ ) r
496
+
497
+ type domain = Interval_domain .t
498
+
499
+ let constant (cte , _ , _ ) =
500
+ Intervals.Int. of_bounds (Closed cte) (Closed cte)
501
+
502
+ let add_offset (cte , _ , _ ) d =
503
+ Intervals.Int. add d (Intervals.Int. of_bounds (Closed cte) (Closed cte))
504
+
505
+ let sub_offset _ (cte , _ , _ ) d =
506
+ Intervals.Int. sub d (Intervals.Int. of_bounds (Closed cte) (Closed cte))
507
+ end
508
+
440
509
module Interval_domains =
441
- Rel_utils. Domains_make (Interval_domain )(Rel_utils. Explained (Constraint ))
510
+ Rel_utils. Domains_make
511
+ (Interval_domain )
512
+ (Rel_utils. Explained (Constraint ))
513
+ (IDD )
514
+ (NF )
442
515
443
516
module Interval_domains_uf =
444
517
Rel_utils. UfDomainMap (Interval_domain )(Interval_domains )
@@ -499,8 +572,44 @@ module Domain : Rel_utils.Domain with type t = Bitlist.t = struct
499
572
invalid_arg " unknown"
500
573
end
501
574
575
+ module BDD = struct
576
+ type var = X .r
577
+
578
+ type ofs = Z .t * Z .t * int
579
+
580
+ type domain = Bitlist .t
581
+
582
+ let default_domain r =
583
+ Domain. map_leaves (fun r ->
584
+ Domain. unknown (X. type_info r)
585
+ ) r
586
+
587
+ let widen sz d =
588
+ let width = Bitlist. width d in
589
+ assert (width < = sz);
590
+ if width = sz then d else
591
+ Bitlist. concat (Bitlist. exact (sz - width) Z. zero Explanation. empty) d
592
+
593
+ let constant (cte , _ , sz ) =
594
+ Bitlist. exact sz cte Explanation. empty
595
+
596
+ let add_offset (cte , mask , sz ) d =
597
+ assert (sz > 0 );
598
+ let d = widen sz d in
599
+ let mask = Bitlist. exact sz mask Explanation. empty in
600
+ let cte = Bitlist. exact sz cte Explanation. empty in
601
+ Bitlist. logor d (Bitlist. logand cte mask)
602
+
603
+ let sub_offset r (_cte , mask , sz ) d =
604
+ let r_sz = match X. type_info r with Tbitv n -> n | _ -> assert false in
605
+ assert (sz > 0 );
606
+ assert (Bitlist. width d = sz);
607
+ let mask = Bitlist. exact sz mask Explanation. empty in
608
+ Bitlist. extract (Bitlist. logand d (Bitlist. lognot mask)) 0 (r_sz - 1 )
609
+ end
610
+
502
611
module Domains =
503
- Rel_utils. Domains_make (Domain )(Rel_utils. Explained (Constraint ))
612
+ Rel_utils. Domains_make (Domain )(Rel_utils. Explained (Constraint ))( BDD )( NF )
504
613
module Domains_uf =
505
614
Rel_utils. UfDomainMap (Domain )(Domains )
506
615
@@ -1218,7 +1327,7 @@ let propagate_bitlist queue dom =
1218
1327
let update r d = update ~ex: Explanation. empty (handle dom r) d
1219
1328
in
1220
1329
if X. is_a_leaf r then
1221
- Domains.Variables . iter_parents r (fun p ->
1330
+ Domains.VS . iter_parents r (fun p ->
1222
1331
if X. is_a_leaf p then
1223
1332
assert (X. equal r p)
1224
1333
else
@@ -1243,7 +1352,7 @@ let propagate_intervals queue dom =
1243
1352
let update r d = update ~ex: Explanation. empty (handle dom r) d
1244
1353
in
1245
1354
if X. is_a_leaf r then
1246
- Interval_domains_uf.Variables . iter_parents r (fun p ->
1355
+ Interval_domains.VS . iter_parents r (fun p ->
1247
1356
if X. is_a_leaf p then
1248
1357
assert (X. equal r p)
1249
1358
else
@@ -1391,18 +1500,6 @@ let rec propagate_all uf eqs bdom idom =
1391
1500
else
1392
1501
eqs, bdom, idom
1393
1502
1394
- module Watch = struct
1395
- type t = int
1396
-
1397
- let pp ppf n = Fmt. pf ppf " w%d" n
1398
-
1399
- let equal = Int. equal
1400
-
1401
- let compare = Int. compare
1402
-
1403
- let hash : int -> int = Hashtbl. hash
1404
- end
1405
-
1406
1503
type t =
1407
1504
{ delayed : Rel_utils.Delayed .t
1408
1505
; terms : SX .t
0 commit comments