@@ -258,13 +258,14 @@ let rebuild_switch ~simplify_let dacc ~arms ~scrutinee ~scrutinee_ty uacc
258
258
in
259
259
after_rebuild expr uacc
260
260
261
- let simplify_switch ~simplify_let dacc switch ~down_to_up =
261
+ let simplify_switch_aux ~simplify_let
262
+ ~scrutinee ~scrutinee_ty
263
+ ~tagged_scrutinee :_ ~not_scrutinee :_
264
+ dacc switch
265
+ ~(down_to_up :
266
+ (Rebuilt_expr.t * Upwards_acc.t,
267
+ Rebuilt_expr.t * Upwards_acc.t) Simplify_common.down_to_up ) =
262
268
let module AC = Apply_cont in
263
- let scrutinee = Switch. scrutinee switch in
264
- let scrutinee_ty =
265
- S. simplify_simple dacc scrutinee ~min_name_mode: NM. normal
266
- in
267
- let scrutinee = T. get_alias_exn scrutinee_ty in
268
269
let arms, dacc =
269
270
let typing_env_at_use = DA. typing_env dacc in
270
271
Target_imm.Map. fold (fun arm action (arms , dacc ) ->
@@ -308,3 +309,83 @@ let simplify_switch ~simplify_let dacc switch ~down_to_up =
308
309
down_to_up dacc
309
310
~rebuild: (rebuild_switch ~simplify_let dacc ~arms ~scrutinee
310
311
~scrutinee_ty )
312
+
313
+ let simplify_switch
314
+ ~(simplify_let :Flambda.Let.t Simplify_common.expr_simplifier )
315
+ ~original_expr
316
+ dacc switch
317
+ ~(down_to_up :
318
+ (Rebuilt_expr.t * Upwards_acc.t,
319
+ Rebuilt_expr.t * Upwards_acc.t) Simplify_common.down_to_up ) =
320
+ let scrutinee = Switch. scrutinee switch in
321
+ let scrutinee_ty =
322
+ S. simplify_simple dacc scrutinee ~min_name_mode: NM. normal
323
+ in
324
+ let scrutinee = T. get_alias_exn scrutinee_ty in
325
+ let find_cse_simple prim =
326
+ let with_fixed_value = P.Eligible_for_cse. create_exn prim in
327
+ match DE. find_cse (DA. denv dacc) with_fixed_value with
328
+ | None -> None
329
+ | Some simple ->
330
+ let canonical =
331
+ TE. get_canonical_simple_exn (DA. typing_env dacc) simple
332
+ ~min_name_mode: NM. normal
333
+ ~name_mode_of_existing_simple: NM. normal
334
+ in
335
+ match canonical with
336
+ | exception Not_found -> None
337
+ | simple -> Some simple
338
+ in
339
+ let create_def name prim =
340
+ let bound_to = Variable. create name in
341
+ let bound_to = Var_in_binding_pos. create bound_to NM. normal in
342
+ let defining_expr = Named. create_prim prim Debuginfo. none in
343
+ let let_expr =
344
+ Let. create (Bindable_let_bound. singleton bound_to)
345
+ defining_expr
346
+ ~body: original_expr
347
+ ~free_names_of_body: Unknown
348
+ in
349
+ simplify_let dacc let_expr ~down_to_up
350
+ in
351
+ let tag_prim = P. Unary (Box_number Untagged_immediate , scrutinee) in
352
+ Simple. pattern_match scrutinee
353
+ ~const: (fun const ->
354
+ match Reg_width_things.Const. descr const with
355
+ | Naked_immediate imm ->
356
+ let tagged_scrutinee =
357
+ Simple. const (Reg_width_things.Const. tagged_immediate imm)
358
+ in
359
+ let not_scrutinee =
360
+ let not_imm =
361
+ if Target_imm. equal imm Target_imm. zero then
362
+ Target_imm. one
363
+ else
364
+ (* If the scrutinee is neither zero nor one, this value
365
+ won't be used *)
366
+ Target_imm. zero
367
+ in
368
+ Simple. const (Reg_width_things.Const. tagged_immediate not_imm)
369
+ in
370
+ simplify_switch_aux dacc switch ~down_to_up
371
+ ~tagged_scrutinee ~not_scrutinee
372
+ ~scrutinee ~scrutinee_ty
373
+ ~simplify_let
374
+ | Tagged_immediate _ | Naked_float _ | Naked_int32 _
375
+ | Naked_int64 _ | Naked_nativeint _ ->
376
+ Misc. fatal_errorf " Switch scrutinee is not a naked immediate: %a"
377
+ Simple. print scrutinee)
378
+ ~name: (fun _ ->
379
+ match find_cse_simple tag_prim with
380
+ | None ->
381
+ create_def " tagged_scrutinee" tag_prim
382
+ | Some tagged_scrutinee ->
383
+ let not_prim = P. Unary (Boolean_not , tagged_scrutinee) in
384
+ match find_cse_simple not_prim with
385
+ | None ->
386
+ create_def " not_scrutinee" not_prim
387
+ | Some not_scrutinee ->
388
+ simplify_switch_aux dacc switch ~down_to_up
389
+ ~tagged_scrutinee ~not_scrutinee
390
+ ~simplify_let
391
+ ~scrutinee ~scrutinee_ty )
0 commit comments