@@ -258,13 +258,14 @@ let rebuild_switch ~simplify_let dacc ~arms ~scrutinee ~scrutinee_ty uacc
258258 in
259259 after_rebuild expr uacc
260260
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 ) =
262268 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
268269 let arms, dacc =
269270 let typing_env_at_use = DA. typing_env dacc in
270271 Target_imm.Map. fold (fun arm action (arms , dacc ) ->
@@ -308,3 +309,83 @@ let simplify_switch ~simplify_let dacc switch ~down_to_up =
308309 down_to_up dacc
309310 ~rebuild: (rebuild_switch ~simplify_let dacc ~arms ~scrutinee
310311 ~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