@@ -78,6 +78,9 @@ type change =
78
78
| Ccommu of commutable ref * commutable
79
79
| Cuniv of type_expr option ref * type_expr option
80
80
| Ctypeset of TypeSet .t ref * TypeSet .t
81
+ | Cmode_upper of alloc_mode_var * alloc_mode_const
82
+ | Cmode_lower of alloc_mode_var * alloc_mode_const
83
+ | Cmode_vlower of alloc_mode_var * alloc_mode_var list
81
84
82
85
type changes =
83
86
Change of change * changes ref
@@ -93,6 +96,19 @@ let log_change ch =
93
96
r := Change (ch, r');
94
97
Weak. set ! trail 0 (Some r')
95
98
99
+ let log_changes chead ctail =
100
+ if chead = Unchanged then (assert (! ctail = Unchanged ))
101
+ else match Weak. get ! trail 0 with None -> ()
102
+ | Some r ->
103
+ r := chead;
104
+ Weak. set ! trail 0 (Some ctail)
105
+
106
+ let append_change ctail ch =
107
+ assert (! (! ctail) = Unchanged );
108
+ let r' = ref Unchanged in
109
+ (! ctail) := Change (ch, r');
110
+ ctail := r'
111
+
96
112
(* *** Representative of a type ****)
97
113
98
114
let rec field_kind_repr =
@@ -718,6 +734,9 @@ let undo_change = function
718
734
| Ccommu (r , v ) -> r := v
719
735
| Cuniv (r , v ) -> r := v
720
736
| Ctypeset (r , v ) -> r := v
737
+ | Cmode_upper (v , u ) -> v.upper < - u
738
+ | Cmode_lower (v , l ) -> v.lower < - l
739
+ | Cmode_vlower (v , vs ) -> v.vlower < - vs
721
740
722
741
type snapshot = changes ref * int
723
742
let last_snapshot = s_ref 0
@@ -864,58 +883,78 @@ module Alloc_mode = struct
864
883
else Printf.fprintf ppf "v%d" i);
865
884
Printf.fprintf ppf "[%a%a]" pp_c v.lower pp_c v.upper
866
885
*)
867
- let submode_cv m v =
886
+
887
+ let set_lower ~log v lower =
888
+ append_change log (Cmode_lower (v, v.lower));
889
+ v.lower < - lower
890
+
891
+ let set_upper ~log v upper =
892
+ append_change log (Cmode_upper (v, v.upper));
893
+ v.upper < - upper
894
+
895
+ let set_vlower ~log v vlower =
896
+ append_change log (Cmode_vlower (v, v.vlower));
897
+ v.vlower < - vlower
898
+
899
+ let submode_cv ~log m v =
868
900
(* Printf.printf " %a <= %a\n" pp_c m pp_v v; *)
869
901
if le_const m v.lower then ()
870
902
else if not (le_const m v.upper) then raise NotSubmode
871
903
else begin
872
904
let m = join_const v.lower m in
873
- v.lower < - m;
874
- if m = v.upper then v.vlower < - []
905
+ set_lower ~log v m;
906
+ if m = v.upper then set_vlower ~log v []
875
907
end
876
908
877
- let rec submode_vc v m =
909
+ let rec submode_vc ~ log v m =
878
910
(* Printf.printf " %a <= %a\n" pp_v v pp_c m; *)
879
911
if le_const v.upper m then ()
880
912
else if not (le_const v.lower m) then raise NotSubmode
881
913
else begin
882
914
let m = meet_const v.upper m in
883
- v.upper < - m;
915
+ set_upper ~log v m;
884
916
v.vlower |> List. iter (fun a ->
885
917
(* a <= v <= m *)
886
- submode_vc a m;
887
- v.lower < - join_const v.lower a.lower;
918
+ submode_vc ~log a m;
919
+ set_lower ~log v ( join_const v.lower a.lower) ;
888
920
);
889
- if v.lower = m then v.vlower < - []
921
+ if v.lower = m then set_vlower ~log v []
890
922
end
891
923
892
- let submode_vv a b =
924
+ let submode_vv ~ log a b =
893
925
(* Printf.printf " %a <= %a\n" pp_v a pp_v b; *)
894
926
if le_const a.upper b.lower then ()
895
927
else if List. memq a b.vlower then ()
896
928
else begin
897
- submode_vc a b.upper;
898
- b.vlower < - a :: b.vlower;
899
- submode_cv a.lower b;
929
+ submode_vc ~log a b.upper;
930
+ set_vlower ~log b ( a :: b.vlower) ;
931
+ submode_cv ~log a.lower b;
900
932
end
901
933
902
934
let submode a b =
935
+ let log_head = ref Unchanged in
936
+ let log = ref log_head in
903
937
match
904
938
match a, b with
905
939
| Amode a , Amode b ->
906
940
if not (le_const a b) then raise NotSubmode
907
941
| Amodevar v , Amode c ->
908
942
(* Printf.printf "%a <= %a\n" pp_v v pp_c c; *)
909
- submode_vc v c
943
+ submode_vc ~log v c
910
944
| Amode c , Amodevar v ->
911
945
(* Printf.printf "%a <= %a\n" pp_c c pp_v v; *)
912
- submode_cv c v
946
+ submode_cv ~log c v
913
947
| Amodevar a , Amodevar b ->
914
948
(* Printf.printf "%a <= %a\n" pp_v a pp_v b; *)
915
- submode_vv a b
949
+ submode_vv ~log a b
916
950
with
917
- | () -> Ok ()
918
- | exception NotSubmode -> Error ()
951
+ | () ->
952
+ log_changes ! log_head ! log;
953
+ Ok ()
954
+ | exception NotSubmode ->
955
+ let backlog = rev_log [] ! log_head in
956
+ List. iter undo_change backlog;
957
+ Error ()
919
958
920
959
let submode_exn t1 t2 =
921
960
match submode t1 t2 with
@@ -946,7 +985,7 @@ module Alloc_mode = struct
946
985
if all_equal v rest then v
947
986
else begin
948
987
let v = fresh () in
949
- List. iter (fun v' -> submode_vv v' v ) vars;
988
+ List. iter (fun v' -> submode_exn ( Amodevar v') ( Amodevar v) ) vars;
950
989
v
951
990
end
952
991
in
@@ -963,7 +1002,7 @@ module Alloc_mode = struct
963
1002
let constrain_upper = function
964
1003
| Amode m -> m
965
1004
| Amodevar v ->
966
- submode_cv v.upper v ;
1005
+ submode_exn ( Amode v.upper) ( Amodevar v) ;
967
1006
v.upper
968
1007
969
1008
let compress_vlower v =
@@ -977,7 +1016,7 @@ module Alloc_mode = struct
977
1016
trans_low v'
978
1017
end
979
1018
and trans_low v' =
980
- submode_cv v'.lower v ;
1019
+ submode_exn ( Amode v'.lower) ( Amodevar v) ;
981
1020
List. iter trans v'.vlower
982
1021
in
983
1022
List. iter trans_low v.vlower
@@ -986,16 +1025,16 @@ module Alloc_mode = struct
986
1025
| Amode m -> m
987
1026
| Amodevar v ->
988
1027
compress_vlower v;
989
- submode_vc v v.lower;
1028
+ submode_exn ( Amodevar v) ( Amode v.lower) ;
990
1029
v.lower
991
1030
992
1031
let newvar () = Amodevar (fresh () )
993
1032
994
1033
let check_const = function
995
1034
| Amode m -> Some m
996
- | Amodevar v when v.lower = v.upper ->
997
- Some v.lower
998
- | Amodevar _ -> None
1035
+ | Amodevar v ->
1036
+ compress_vlower v;
1037
+ if v.lower = v.upper then Some v.lower else None
999
1038
1000
1039
let print_const ppf = function
1001
1040
| Global -> Format. fprintf ppf " Global"
0 commit comments