@@ -1065,9 +1065,14 @@ function mark_phi_cycles!(compact::IncrementalCompact, safe_phis::SPCSet, phi::I
10651065 end
10661066end
10671067
1068+ function is_some_union (@nospecialize (t))
1069+ isa (t, MaybeUndef) && (t = t. typ)
1070+ return isa (t, Union)
1071+ end
1072+
10681073function 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 ])
10711076end
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