@@ -449,10 +449,10 @@ function lift_comparison!(compact::IncrementalCompact, idx::Int,
449449 lifted_val = perform_lifting! (compact, visited_phinodes, cmp, lifting_cache, Bool, lifted_leaves, val)
450450 @assert lifted_val != = nothing
451451
452- # global assertion_counter
453- # assertion_counter::Int += 1
454- # insert_node_here!(compact, Expr(:assert_egal, Symbol(string("assert_egal_", assertion_counter)), SSAValue(idx), lifted_val), nothing, 0, true)
455- # return
452+ # global assertion_counter
453+ # assertion_counter::Int += 1
454+ # insert_node_here!(compact, Expr(:assert_egal, Symbol(string("assert_egal_", assertion_counter)), SSAValue(idx), lifted_val), nothing, 0, true)
455+ # return
456456 compact[idx] = lifted_val. x
457457end
458458
@@ -734,17 +734,6 @@ function getfield_elim_pass!(ir::IRCode)
734734 result_t = make_MaybeUndef (result_t)
735735 end
736736
737- # @Base.show result_t
738- # @Base.show stmt
739- # for (k,v) in lifted_leaves
740- # @Base.show (k, v)
741- # if isa(k, AnySSAValue)
742- # @Base.show compact[k]
743- # end
744- # if isa(v, RefValue) && isa(v.x, AnySSAValue)
745- # @Base.show compact[v.x]
746- # end
747- # end
748737 val = perform_lifting! (compact, visited_phinodes, field, lifting_cache, result_t, lifted_leaves, stmt. args[2 ])
749738
750739 # Insert the undef check if necessary
@@ -761,8 +750,8 @@ function getfield_elim_pass!(ir::IRCode)
761750
762751 # global assertion_counter
763752 # assertion_counter::Int += 1
764- # insert_node_here!(compact, Expr(:assert_egal, Symbol(string("assert_egal_", assertion_counter)), SSAValue(idx), val), nothing, 0, true)
765- # continue
753+ # insert_node_here!(compact, Expr(:assert_egal, Symbol(string("assert_egal_", assertion_counter)), SSAValue(idx), val), nothing, 0, true)
754+ # continue
766755 compact[idx] = val === nothing ? nothing : val. x
767756 end
768757
@@ -894,7 +883,8 @@ function getfield_elim_pass!(ir::IRCode)
894883 ir[SSAValue (use)] = new_expr
895884 end
896885 end
897- ir
886+
887+ return ir
898888end
899889# assertion_counter = 0
900890
935925"""
936926 adce_pass!(ir::IRCode) -> newir::IRCode
937927
938- Aggressive Dead Code Elimination pass to eliminate code.
928+ Aggressive Dead Code Elimination pass.
929+
930+ In addition to a simple DCE for unused values and allocations,
931+ this pass also nullifies `typeassert` calls that can be proved to be no-op,
932+ in order to allow LLVM to emit simpler code down the road.
933+
934+ Note that this pass is more effective after SROA optimization (i.e. `getfield_elim_pass!`),
935+ since SROA often allows this pass to:
936+ - eliminate allocation of object whose field references are all replaced with scalar values, and
937+ - nullify `typeassert` call whose first operand has been replaced with a scalar value
938+ (, which may have introduced new type information that inference did not understand)
939+
940+ Also note that currently this pass _needs_ to run after `getfield_elim_pass!`, because
941+ the `typeassert` elimination depends on the transformation within `getfield_elim_pass!`
942+ which redirects references of `typeassert`ed value to the corresponding `PiNode`.
939943"""
940944function adce_pass! (ir:: IRCode )
941945 phi_uses = fill (0 , length (ir. stmts) + length (ir. new_nodes))
@@ -944,6 +948,14 @@ function adce_pass!(ir::IRCode)
944948 for ((_, idx), stmt) in compact
945949 if isa (stmt, PhiNode)
946950 push! (all_phis, idx)
951+ elseif isexpr (stmt, :call )
952+ # nullify safe `typeassert` calls
953+ if is_known_call (stmt, typeassert, compact) && length (stmt. args) == 3
954+ ty, isexact = instanceof_tfunc (compact_exprtype (compact, stmt. args[3 ]))
955+ if isexact && compact_exprtype (compact, stmt. args[2 ]) ⊑ ty
956+ compact[idx] = nothing
957+ end
958+ end
947959 end
948960 end
949961 non_dce_finish! (compact)
0 commit comments