-
Notifications
You must be signed in to change notification settings - Fork 85
/
Copy pathregalloc_split_utils.ml
111 lines (93 loc) · 3.56 KB
/
regalloc_split_utils.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
[@@@ocaml.warning "+a-30-40-41-42"]
open! Int_replace_polymorphic_compare [@@ocaml.warning "-66"]
open! Regalloc_utils
let split_live_ranges : bool Lazy.t =
bool_of_param ~default:true "SPLIT_LIVE_RANGES"
let split_more_destruction_points : bool Lazy.t =
bool_of_param "SPLIT_MORE_DESTR_POINTS"
let log_function = lazy (make_log_function ~label:"split")
let indent () = (Lazy.force log_function).indent ()
let dedent () = (Lazy.force log_function).dedent ()
let log : type a. ?no_eol:unit -> (a, Format.formatter, unit) format -> a =
fun ?no_eol fmt -> (Lazy.force log_function).log ?no_eol fmt
let log_dominance_frontier : Cfg.t -> Cfg_dominators.t -> unit =
fun cfg doms ->
log "dominance frontier:";
indent ();
Cfg.iter_blocks cfg ~f:(fun label _block ->
let frontier = Cfg_dominators.find_dominance_frontier doms label in
log "block %a" Label.format label;
Label.Set.iter
(fun frontier_label -> log "block %a" Label.format frontier_label)
frontier);
dedent ()
let log_dominator_tree : Cfg_dominators.dominator_tree -> unit =
fun dom_tree ->
let rec ldt tree =
log ". %a" Label.format tree.Cfg_dominators.label;
indent ();
List.iter tree.Cfg_dominators.children ~f:(fun child -> ldt child);
dedent ()
in
ldt dom_tree
let log_dominator_forest : Cfg_dominators.dominator_tree list -> unit =
fun dom_forest ->
List.iter dom_forest ~f:(fun dom_tree -> log_dominator_tree dom_tree)
let log_substitution : Substitution.t -> unit =
fun subst ->
Reg.Tbl.iter
(fun old_reg new_reg ->
log "%a -> %a" Printreg.reg old_reg Printreg.reg new_reg)
subst
let log_substitutions : Substitution.map -> unit =
fun substs ->
log "substitutions:";
Label.Tbl.iter
(fun label (subst : Substitution.t) ->
indent ();
log "subst for block %a" Label.format label;
indent ();
log_substitution subst;
dedent ();
dedent ())
substs
let log_stack_subst : Substitution.t -> unit =
fun stack_subst ->
log "stack substitution:";
indent ();
log_substitution stack_subst;
dedent ()
let filter_unknown : Reg.Set.t -> Reg.Set.t =
fun regset -> Reg.Set.filter Reg.is_unknown regset
let live_at_block_beginning : Cfg_with_infos.t -> Label.t -> Reg.Set.t =
fun cfg_with_infos label ->
let block = Cfg_with_infos.get_block_exn cfg_with_infos label in
let first_id = Cfg.first_instruction_id block in
match Cfg_with_infos.liveness_find_opt cfg_with_infos first_id with
| None ->
fatal "liveness information missing for instruction %a" InstructionId.format
first_id
| Some { Cfg_liveness.before; across = _ } -> filter_unknown before
type destruction_kind =
| Destruction_on_all_paths
| Destruction_only_on_exceptional_path
let equal_destruction_kind left right =
match left, right with
| Destruction_on_all_paths, Destruction_on_all_paths
| Destruction_only_on_exceptional_path, Destruction_only_on_exceptional_path
->
true
| (Destruction_on_all_paths | Destruction_only_on_exceptional_path), _ ->
false
let destruction_point_at_end : Cfg.basic_block -> destruction_kind option =
fun block ->
let more_destruction_points = Lazy.force split_more_destruction_points in
if Proc.is_destruction_point ~more_destruction_points block.terminator.desc
then Some Destruction_on_all_paths
else if Option.is_none block.exn
then None
else (
assert (Cfg.can_raise_terminator block.terminator.desc);
if Label.Set.is_empty (Cfg.successor_labels block ~normal:true ~exn:false)
then Some Destruction_on_all_paths
else Some Destruction_only_on_exceptional_path)