Skip to content

Commit a0093d2

Browse files
authored
adce: Slight tweak to phinode elimination (#43948)
Just a slight tweak to #43922 to also allow the implicit narrowing from other phi users. It's not a particularly common occurrence, but can happen particularly when running the adce pass twice, (because that narrows the types of some phis by dropping edges).
1 parent a7beb93 commit a0093d2

File tree

1 file changed

+31
-9
lines changed

1 file changed

+31
-9
lines changed

base/compiler/ssair/passes.jl

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,9 +1065,14 @@ function mark_phi_cycles!(compact::IncrementalCompact, safe_phis::SPCSet, phi::I
10651065
end
10661066
end
10671067

1068+
function is_some_union(@nospecialize(t))
1069+
isa(t, MaybeUndef) && (t = t.typ)
1070+
return isa(t, Union)
1071+
end
1072+
10681073
function is_union_phi(compact::IncrementalCompact, idx::Int)
10691074
inst = compact.result[idx]
1070-
return isa(inst[:inst], PhiNode) && isa(inst[:type], Union)
1075+
return isa(inst[:inst], PhiNode) && is_some_union(inst[:type])
10711076
end
10721077

10731078
"""
@@ -1097,7 +1102,7 @@ function adce_pass!(ir::IRCode)
10971102
for ((_, idx), stmt) in compact
10981103
if isa(stmt, PhiNode)
10991104
push!(all_phis, idx)
1100-
if isa(compact.result[idx][:type], Union)
1105+
if is_some_union(compact.result[idx][:type])
11011106
push!(unionphis, Pair{Int,Any}(idx, Union{}))
11021107
end
11031108
elseif isa(stmt, PiNode)
@@ -1106,7 +1111,7 @@ function adce_pass!(ir::IRCode)
11061111
r = searchsorted(unionphis, val.id; by = first)
11071112
if !isempty(r)
11081113
unionphi = unionphis[first(r)]
1109-
t = Union{unionphi[2], widenconst(stmt.typ)}
1114+
t = tmerge(unionphi[2], stmt.typ)
11101115
unionphis[first(r)] = Pair{Int,Any}(unionphi[1], t)
11111116
end
11121117
end
@@ -1132,19 +1137,35 @@ function adce_pass!(ir::IRCode)
11321137
end
11331138
non_dce_finish!(compact)
11341139
for phi in all_phis
1135-
count_uses(compact.result[phi][:inst]::PhiNode, phi_uses)
1140+
inst = compact.result[phi]
1141+
for ur in userefs(inst[:inst]::PhiNode)
1142+
use = ur[]
1143+
if isa(use, SSAValue)
1144+
phi_uses[use.id] += 1
1145+
stmt = compact.result[use.id][:inst]
1146+
if isa(stmt, PhiNode)
1147+
r = searchsorted(unionphis, use.id; by=first)
1148+
if !isempty(r)
1149+
unionphi = unionphis[first(r)]
1150+
unionphis[first(r)] = Pair{Int,Any}(unionphi[1],
1151+
tmerge(unionphi[2], inst[:type]))
1152+
end
1153+
end
1154+
end
1155+
end
11361156
end
11371157
# Narrow any union phi nodes that have unused branches
11381158
for i = 1:length(unionphis)
11391159
unionphi = unionphis[i]
11401160
phi = unionphi[1]
11411161
t = unionphi[2]
1142-
if phi_uses[phi] != 0
1143-
continue
1144-
end
11451162
if t === Union{}
11461163
compact.result[phi][:inst] = nothing
11471164
continue
1165+
elseif t === Any
1166+
continue
1167+
elseif compact.result[phi][:type] t
1168+
continue
11481169
end
11491170
to_drop = Int[]
11501171
stmt = compact[phi]
@@ -1153,14 +1174,15 @@ function adce_pass!(ir::IRCode)
11531174
if !isassigned(stmt.values, i)
11541175
# Should be impossible to have something used only by PiNodes that's undef
11551176
push!(to_drop, i)
1156-
elseif !hasintersect(widenconst(argextype(stmt.values[i], compact)), t)
1177+
elseif !hasintersect(widenconst(argextype(stmt.values[i], compact)),
1178+
widenconst(t))
11571179
push!(to_drop, i)
11581180
end
11591181
end
1182+
compact.result[phi][:type] = t
11601183
isempty(to_drop) && continue
11611184
deleteat!(stmt.values, to_drop)
11621185
deleteat!(stmt.edges, to_drop)
1163-
compact.result[phi][:type] = t
11641186
end
11651187
# Perform simple DCE for unused values
11661188
extra_worklist = Int[]

0 commit comments

Comments
 (0)