Skip to content

Commit 3398e1e

Browse files
authored
Cfg_simplify pass (#3768)
* Move all dead code passes into Cfg_simplify and delete trap handlers * Fix catch-try*.cmm tests * Add compilation flag -cfg-eliminate-dead-trap-handlers * Add flag cfg-eliminate-dead-trap-handlers to some github ci jobs
1 parent 5bf0975 commit 3398e1e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+439
-734
lines changed

.github/workflows/build.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ jobs:
6565
os: ubuntu-latest
6666
build_ocamlparam: ''
6767
use_runtime: d
68-
ocamlparam: '_,O3=1,flambda2-expert-cont-lifting-budget=200'
68+
ocamlparam: '_,O3=1,flambda2-expert-cont-lifting-budget=200,cfg-invariants=1,cfg-eliminate-dead-trap-handlers=1'
6969

7070
- name: flambda2_frame_pointers_oclassic_polling
7171
config: --enable-middle-end=flambda2 --enable-frame-pointers --enable-poll-insertion --enable-flambda-invariants
@@ -164,8 +164,8 @@ jobs:
164164
- name: cfg-invariants
165165
config: --enable-middle-end=flambda2
166166
os: ubuntu-latest
167-
build_ocamlparam: '_,w=-46,regalloc=cfg'
168-
ocamlparam: '_,w=-46,regalloc=cfg,cfg-invariants=1'
167+
build_ocamlparam: '_,w=-46,regalloc=cfg,cfg-invariants=1,cfg-eliminate-dead-trap-handlers=1'
168+
ocamlparam: '_,w=-46,regalloc=cfg,cfg-invariants=1,cfg-eliminate-dead-trap-handlers=1'
169169
check_arch: true
170170

171171
- name: vectorizer

backend/amd64/proc.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,7 @@ let destroyed_at_basic (basic : Cfg_intf.S.basic) =
596596
| Isextend32 | Izextend32 | Ipause
597597
| Ilfence | Isfence | Imfence)
598598
| Name_for_debugger _ | Dls_get)
599-
| Poptrap | Prologue ->
599+
| Poptrap _ | Prologue ->
600600
if fp then [| rbp |] else [||]
601601
| Stack_check _ ->
602602
assert false (* the instruction is added after register allocation *)

backend/amd64/regalloc_stack_operands.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ let basic (map : spilled_map) (instr : Cfg.basic Cfg.instruction) =
255255
| Ibswap _))
256256
| Reloadretaddr
257257
| Pushtrap _
258-
| Poptrap
258+
| Poptrap _
259259
| Prologue ->
260260
(* no rewrite *)
261261
May_still_have_spilled_registers

backend/arm64/proc.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ let destroyed_at_basic (basic : Cfg_intf.S.basic) =
388388
| Intop _ | Intop_imm _ | Intop_atomic _
389389
| Name_for_debugger _ | Probe_is_enabled _ | Opaque
390390
| Begin_region | End_region | Dls_get)
391-
| Poptrap | Prologue
391+
| Poptrap _ | Prologue
392392
-> [||]
393393
| Stack_check _ -> assert false (* not supported *)
394394

backend/cfg/cfg.ml

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ type basic_block =
4343
mutable exn : Label.t option;
4444
mutable can_raise : bool;
4545
mutable is_trap_handler : bool;
46-
mutable dead : bool;
4746
mutable cold : bool
4847
}
4948

@@ -187,17 +186,43 @@ let add_block_exn t block =
187186
Label.format block.start;
188187
Label.Tbl.add t.blocks block.start block
189188

190-
let remove_block_exn t label =
191-
match Label.Tbl.find t.blocks label with
192-
| exception Not_found ->
193-
Misc.fatal_errorf "Cfg.remove_block_exn: block %a not found" Label.format
194-
label
195-
| _ -> Label.Tbl.remove t.blocks label
189+
let remove_trap_instructions t removed_trap_handlers =
190+
let remove_trap_instr _ b =
191+
DLL.iter_cell b.body ~f:(fun cell ->
192+
let i = DLL.value cell in
193+
match i.desc with
194+
| Pushtrap { lbl_handler } | Poptrap { lbl_handler } ->
195+
if Label.Set.mem lbl_handler removed_trap_handlers
196+
then DLL.delete_curr cell
197+
| Op _ | Reloadretaddr | Prologue | Stack_check _ -> ())
198+
in
199+
if not (Label.Set.is_empty removed_trap_handlers)
200+
then (
201+
(* CR-someday gyorsh: avoid iterating over all the instructions to just to
202+
remove a few pushtrap/poptrap. *)
203+
assert Config.flambda2;
204+
(* remove Lpushtrap and Lpoptrap instructions that refer to dead labels. *)
205+
Label.Tbl.iter remove_trap_instr t.blocks)
196206

197207
let remove_blocks t labels_to_remove =
208+
let removed_labels = ref Label.Set.empty in
209+
let removed_trap_handlers = ref Label.Set.empty in
198210
Label.Tbl.filter_map_inplace
199-
(fun l b -> if Label.Set.mem l labels_to_remove then None else Some b)
200-
t.blocks
211+
(fun l b ->
212+
if Label.Set.mem l labels_to_remove
213+
then (
214+
if b.is_trap_handler
215+
then removed_trap_handlers := Label.Set.add l !removed_trap_handlers;
216+
removed_labels := Label.Set.add l !removed_labels;
217+
None)
218+
else Some b)
219+
t.blocks;
220+
let labels_not_found = Label.Set.diff labels_to_remove !removed_labels in
221+
if not (Label.Set.is_empty labels_not_found)
222+
then
223+
Misc.fatal_errorf "Cfg.remove_blocks: not found blocks %a" Label.Set.print
224+
labels_not_found;
225+
remove_trap_instructions t !removed_trap_handlers
201226

202227
let get_block t label = Label.Tbl.find_opt t.blocks label
203228

@@ -262,7 +287,8 @@ let dump_basic ppf (basic : basic) =
262287
| Reloadretaddr -> fprintf ppf "Reloadretaddr"
263288
| Pushtrap { lbl_handler } ->
264289
fprintf ppf "Pushtrap handler=%a" Label.format lbl_handler
265-
| Poptrap -> fprintf ppf "Poptrap"
290+
| Poptrap { lbl_handler } ->
291+
fprintf ppf "Poptrap handler=%a" Label.format lbl_handler
266292
| Prologue -> fprintf ppf "Prologue"
267293
| Stack_check { max_frame_size_bytes } ->
268294
fprintf ppf "Stack_check size=%d" max_frame_size_bytes
@@ -449,7 +475,7 @@ let is_pure_basic : basic -> bool = function
449475
wouldn't be. Saying it's not pure doesn't decrease the generated code
450476
quality and is future-proof.*)
451477
false
452-
| Pushtrap _ | Poptrap ->
478+
| Pushtrap _ | Poptrap _ ->
453479
(* Those instructions modify the trap stack which actually modifies the
454480
stack pointer. *)
455481
false
@@ -491,7 +517,7 @@ let is_noop_move instr =
491517
| Intop_imm _ | Intop_atomic _ | Floatop _ | Opaque | Reinterpret_cast _
492518
| Static_cast _ | Probe_is_enabled _ | Specific _ | Name_for_debugger _
493519
| Begin_region | End_region | Dls_get | Poll | Alloc _ )
494-
| Reloadretaddr | Pushtrap _ | Poptrap | Prologue | Stack_check _ ->
520+
| Reloadretaddr | Pushtrap _ | Poptrap _ | Prologue | Stack_check _ ->
495521
false
496522

497523
let set_stack_offset (instr : _ instruction) stack_offset =
@@ -564,7 +590,6 @@ let make_empty_block ?label terminator : basic_block =
564590
exn = None;
565591
can_raise = false;
566592
is_trap_handler = false;
567-
dead = false;
568593
cold = false
569594
}
570595

backend/cfg/cfg.mli

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,12 @@ type basic_block =
5454
mutable is_trap_handler : bool;
5555
(** Is this block a trap handler (i.e. is it an exn successor of another
5656
block) or not? *)
57-
mutable dead : bool;
58-
(** This block must be unreachable from function entry. This field is
59-
set during cfg construction (if trap stacks are unresolved) and used
60-
during dead block elimination for checking. *)
6157
mutable cold : bool
6258
(* CR-someday gyorsh: The current implementation allows multiple
6359
pushtraps in each block means that different trap stacks are
6460
associated with the block at different points. At most one
65-
instruction in each block can raise, and always the last one. After
66-
we split the blocks based on Pushtrap/Poptrap, each block will have a
61+
instruction in each block can raise, and always the last one. If we
62+
split the blocks based on Pushtrap/Poptrap, each block will have a
6763
unique trap stack associated with it. [exns] will not be needed, as
6864
the exn-successor will be uniquely determined by can_raise + top of
6965
trap stack. *)
@@ -143,8 +139,6 @@ val mem_block : t -> Label.t -> bool
143139

144140
val add_block_exn : t -> basic_block -> unit
145141

146-
val remove_block_exn : t -> Label.t -> unit
147-
148142
val remove_blocks : t -> Label.Set.t -> unit
149143

150144
val get_block : t -> Label.t -> basic_block option

backend/cfg/cfg_available_regs.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ module Transfer = struct
309309
| Reinterpret_cast _ | Static_cast _ | Probe_is_enabled _ | Opaque
310310
| Begin_region | End_region | Specific _ | Dls_get | Poll | Alloc _
311311
)
312-
| Reloadretaddr | Pushtrap _ | Poptrap | Prologue | Stack_check _ ->
312+
| Reloadretaddr | Pushtrap _ | Poptrap _ | Prologue | Stack_check _ ->
313313
let is_op_end_region = function[@ocaml.warning "-4"]
314314
| Cfg.(Op End_region) -> true
315315
| _ -> false

backend/cfg/cfg_comballoc.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ let rec find_next_allocation : cell option -> allocation option =
3939
| Reinterpret_cast _ | Static_cast _ | Probe_is_enabled _ | Opaque
4040
| Begin_region | End_region | Specific _ | Name_for_debugger _ | Dls_get
4141
| Poll )
42-
| Reloadretaddr | Pushtrap _ | Poptrap | Prologue | Stack_check _ ->
42+
| Reloadretaddr | Pushtrap _ | Poptrap _ | Prologue | Stack_check _ ->
4343
find_next_allocation (DLL.next cell))
4444

4545
(* [find_compatible_allocations cell ~curr_mode ~curr_size] returns the
@@ -80,7 +80,7 @@ let find_compatible_allocations :
8080
| Local -> return ()
8181
| Heap -> loop allocations (DLL.next cell) ~curr_mode ~curr_size)
8282
| Op Poll -> return ()
83-
| Reloadretaddr | Poptrap | Prologue | Pushtrap _ | Stack_check _ ->
83+
| Reloadretaddr | Poptrap _ | Prologue | Pushtrap _ | Stack_check _ ->
8484
(* CR-soon xclerc for xclerc: is it too conservative? (note: only the
8585
`Pushtrap` case may be too conservative) *)
8686
{ allocations = List.rev allocations; next_cell = Some cell }

backend/cfg/cfg_cse.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ module Cse_generic (Target : Cfg_cse_target_intf.S) = struct
347347
fun state n cell ->
348348
let i = DLL.value cell in
349349
match i.desc with
350-
| Reloadretaddr | Pushtrap _ | Poptrap | Prologue | Stack_check _ -> n
350+
| Reloadretaddr | Pushtrap _ | Poptrap _ | Prologue | Stack_check _ -> n
351351
| Op (Move | Spill | Reload) ->
352352
(* For moves, we associate the same value number to the result reg as to
353353
the argument reg. *)

backend/cfg/cfg_deadcode.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ let remove_deadcode (body : Cfg.basic_instruction_list) changed liveness
2222
match instr.desc with
2323
| Op _ as op ->
2424
Cfg.is_pure_basic op && Reg.disjoint_set_array !used_after instr.res
25-
| Reloadretaddr | Pushtrap _ | Poptrap | Prologue | Stack_check _ ->
25+
| Reloadretaddr | Pushtrap _ | Poptrap _ | Prologue | Stack_check _ ->
2626
false
2727
in
2828
used_after := before;

0 commit comments

Comments
 (0)