@@ -186,6 +186,62 @@ let add_cont_dep blocks defs (pc, args) =
186
186
| Some block -> add_arg_dep defs block.params args
187
187
| None -> () (* Dead continuation *)
188
188
189
+ let empty_body b =
190
+ match b with
191
+ | [] | [ Event _ ] -> true
192
+ | _ -> false
193
+
194
+ let remove_empty_blocks ~live_vars (p : Code.program ) : Code.program =
195
+ let shortcuts = Hashtbl. create 16 in
196
+ let rec resolve_rec visited ((pc , args ) as cont ) =
197
+ if Addr.Set. mem pc visited
198
+ then cont
199
+ else
200
+ match Hashtbl. find_opt shortcuts pc with
201
+ | Some (params , cont ) ->
202
+ let pc', args' = resolve_rec (Addr.Set. add pc visited) cont in
203
+ let s = Subst. from_map (Subst. build_mapping params args) in
204
+ pc', List. map ~f: s args'
205
+ | None -> cont
206
+ in
207
+ let resolve cont = resolve_rec Addr.Set. empty cont in
208
+ Addr.Map. iter
209
+ (fun pc block ->
210
+ match block with
211
+ | { params; body; branch = Branch cont ; _ } when empty_body body ->
212
+ let args =
213
+ List. fold_left
214
+ ~f: (fun args x -> Var.Set. add x args)
215
+ ~init: Var.Set. empty
216
+ (snd cont)
217
+ in
218
+ (* We can skip an empty block if its parameters are only
219
+ used as argument to the continuation *)
220
+ if
221
+ List. for_all
222
+ ~f: (fun x -> live_vars.(Var. idx x) = 1 && Var.Set. mem x args)
223
+ params
224
+ then Hashtbl. add shortcuts pc (params, cont)
225
+ | _ -> () )
226
+ p.blocks;
227
+ let blocks =
228
+ Addr.Map. map
229
+ (fun block ->
230
+ { block with
231
+ branch =
232
+ (let branch = block.branch in
233
+ match branch with
234
+ | Branch cont -> Branch (resolve cont)
235
+ | Cond (x , cont1 , cont2 ) -> Cond (x, resolve cont1, resolve cont2)
236
+ | Switch (x , a1 ) -> Switch (x, Array. map ~f: resolve a1)
237
+ | Pushtrap (cont1 , x , cont2 ) -> Pushtrap (resolve cont1, x, resolve cont2)
238
+ | Poptrap cont -> Poptrap (resolve cont)
239
+ | Return _ | Raise _ | Stop -> branch)
240
+ })
241
+ p.blocks
242
+ in
243
+ { p with blocks }
244
+
189
245
let f ({ blocks; _ } as p : Code.program ) =
190
246
let t = Timer. make () in
191
247
let nv = Var. count () in
0 commit comments