763763 estate:: EscapeState , change:: EscapeChange )
764764 (; xidx, xinfo) = change
765765 anychanged = _propagate_escape_change! (op, estate, xidx, xinfo)
766+ # COMBAK is there a more efficient method of escape information equalization on aliasset?
766767 aliases = getaliases (xidx, estate)
767768 if aliases != = nothing
768769 for aidx in aliases
809810 yroot = find_root! (estate. aliasset, yidx)
810811 if xroot ≠ yroot
811812 union! (estate. aliasset, xroot, yroot)
812- xinfo = estate. escapes[xidx]
813- yinfo = estate. escapes[yidx]
814- xyinfo = xinfo ⊔ ₑ yinfo
815- estate. escapes[xidx] = xyinfo
816- estate. escapes[yidx] = xyinfo
817813 return true
818814 end
819815 return false
@@ -851,6 +847,10 @@ function add_alias_change!(astate::AnalysisState, @nospecialize(x), @nospecializ
851847 yidx = iridx (y, estate)
852848 if xidx != = nothing && yidx != = nothing && ! isaliased (xidx, yidx, astate. estate)
853849 pushfirst! (astate. changes, AliasChange (xidx, yidx))
850+ # add new escape change here so that it's shared among the expanded `aliasset` in `propagate_escape_change!`
851+ xinfo = estate. escapes[xidx]
852+ yinfo = estate. escapes[yidx]
853+ add_escape_change! (astate, x, xinfo ⊔ ₑ yinfo)
854854 end
855855 return nothing
856856end
@@ -937,6 +937,8 @@ function compute_frameinfo(ir::IRCode)
937937 end
938938 arrayinfo[idx] = dims
939939 elseif arrayinfo != = nothing
940+ # TODO this super limited alias analysis is able to handle only very simple cases
941+ # this should be replaced with a proper forward dimension analysis
940942 if isa (stmt, PhiNode)
941943 values = stmt. values
942944 local dims = nothing
@@ -946,12 +948,13 @@ function compute_frameinfo(ir::IRCode)
946948 if isa (val, SSAValue) && haskey (arrayinfo, val. id)
947949 if dims === nothing
948950 dims = arrayinfo[val. id]
949- elseif dims ≠ arrayinfo[val . id]
950- dims = nothing
951- break
951+ continue
952+ elseif dims == arrayinfo[val . id]
953+ continue
952954 end
953955 end
954956 end
957+ @goto next_stmt
955958 end
956959 if dims != = nothing
957960 arrayinfo[idx] = dims
@@ -1066,6 +1069,8 @@ function escape_invoke!(astate::AnalysisState, pc::Int, args::Vector{Any})
10661069 add_escape_change! (astate, arg, info)
10671070 end
10681071 end
1072+ # we should disable the alias analysis on this newly introduced object
1073+ add_escape_change! (astate, ret, EscapeInfo (retinfo, true ))
10691074 end
10701075end
10711076
@@ -1107,28 +1112,30 @@ function escape_new!(astate::AnalysisState, pc::Int, args::Vector{Any})
11071112 # fields are known precisely: propagate escape information imposed on recorded possibilities to the exact field values
11081113 infos = AliasInfo. infos
11091114 nf = length (infos)
1110- objinfo = ignore_aliasinfo (objinfo)
1115+ objinfo′ = ignore_aliasinfo (objinfo)
11111116 for i in 2 : nargs
11121117 i- 1 > nf && break # may happen when e.g. ϕ-node merges values with different types
11131118 arg = args[i]
11141119 add_alias_escapes! (astate, arg, infos[i- 1 ])
11151120 push! (infos[i- 1 ], - pc) # record def
11161121 # propagate the escape information of this object ignoring field information
1117- add_escape_change! (astate, arg, objinfo)
1122+ add_escape_change! (astate, arg, objinfo′ )
11181123 add_liveness_change! (astate, arg, pc)
11191124 end
1125+ add_escape_change! (astate, obj, EscapeInfo (objinfo, AliasInfo)) # update with new AliasInfo
11201126 elseif isa (AliasInfo, Unindexable) && ! AliasInfo. array
11211127 # fields are known partially: propagate escape information imposed on recorded possibilities to all fields values
11221128 info = AliasInfo. info
1123- objinfo = ignore_aliasinfo (objinfo)
1129+ objinfo′ = ignore_aliasinfo (objinfo)
11241130 for i in 2 : nargs
11251131 arg = args[i]
11261132 add_alias_escapes! (astate, arg, info)
11271133 push! (info, - pc) # record def
11281134 # propagate the escape information of this object ignoring field information
1129- add_escape_change! (astate, arg, objinfo)
1135+ add_escape_change! (astate, arg, objinfo′ )
11301136 add_liveness_change! (astate, arg, pc)
11311137 end
1138+ add_escape_change! (astate, obj, EscapeInfo (objinfo, AliasInfo)) # update with new AliasInfo
11321139 else
11331140 # this object has been used as array, but it is allocated as struct here (i.e. should throw)
11341141 # update obj's field information and just handle this case conservatively
@@ -1405,23 +1412,19 @@ function escape_builtin!(::typeof(getfield), astate::AnalysisState, pc::Int, arg
14051412 isa (AliasInfo, Unindexable) && @goto record_unindexable_use
14061413 @label record_indexable_use
14071414 push! (AliasInfo. infos[fidx], pc) # record use
1408- objinfo = EscapeInfo (objinfo, AliasInfo)
1409- add_escape_change! (astate, obj, objinfo)
1415+ add_escape_change! (astate, obj, EscapeInfo (objinfo, AliasInfo)) # update with new AliasInfo
14101416 elseif isa (AliasInfo, Unindexable) && ! AliasInfo. array
14111417 @label record_unindexable_use
14121418 push! (AliasInfo. info, pc) # record use
1413- objinfo = EscapeInfo (objinfo, AliasInfo)
1414- add_escape_change! (astate, obj, objinfo)
1419+ add_escape_change! (astate, obj, EscapeInfo (objinfo, AliasInfo)) # update with new AliasInfo
14151420 else
14161421 # this object has been used as array, but it is used as struct here (i.e. should throw)
14171422 # update obj's field information and just handle this case conservatively
14181423 objinfo = escape_unanalyzable_obj! (astate, obj, objinfo)
14191424 @label conservative_propagation
1420- # the field couldn't be analyzed precisely: propagate the escape information
1421- # imposed on the return value of this `getfield` call to the object itself
1422- # as the most conservative propagation
1423- ssainfo = estate[SSAValue (pc)]
1424- add_escape_change! (astate, obj, ssainfo)
1425+ # at the extreme case, a field of `obj` may point to `obj` itself
1426+ # so add the alias change here as the most conservative propagation
1427+ add_alias_change! (astate, obj, SSAValue (pc))
14251428 end
14261429 return false
14271430end
@@ -1457,7 +1460,7 @@ function escape_builtin!(::typeof(setfield!), astate::AnalysisState, pc::Int, ar
14571460 add_alias_escapes! (astate, val, AliasInfo. infos[fidx])
14581461 push! (AliasInfo. infos[fidx], - pc) # record def
14591462 objinfo = EscapeInfo (objinfo, AliasInfo)
1460- add_escape_change! (astate, obj, objinfo)
1463+ add_escape_change! (astate, obj, objinfo) # update with new AliasInfo
14611464 # propagate the escape information of this object ignoring field information
14621465 add_escape_change! (astate, val, ignore_aliasinfo (objinfo))
14631466 elseif isa (AliasInfo, Unindexable) && ! AliasInfo. array
@@ -1466,7 +1469,7 @@ function escape_builtin!(::typeof(setfield!), astate::AnalysisState, pc::Int, ar
14661469 add_alias_escapes! (astate, val, AliasInfo. info)
14671470 push! (AliasInfo. info, - pc) # record def
14681471 objinfo = EscapeInfo (objinfo, AliasInfo)
1469- add_escape_change! (astate, obj, objinfo)
1472+ add_escape_change! (astate, obj, objinfo) # update with new AliasInfo
14701473 # propagate the escape information of this object ignoring field information
14711474 add_escape_change! (astate, val, ignore_aliasinfo (objinfo))
14721475 else
@@ -1544,8 +1547,9 @@ function escape_builtin!(::typeof(arrayref), astate::AnalysisState, pc::Int, arg
15441547 # update ary's element information and just handle this case conservatively
15451548 aryinfo = escape_unanalyzable_obj! (astate, ary, aryinfo)
15461549 @label conservative_propagation
1547- ssainfo = estate[SSAValue (pc)]
1548- add_escape_change! (astate, ary, ssainfo)
1550+ # at the extreme case, an element of `ary` may point to `ary` itself
1551+ # so add the alias change here as the most conservative propagation
1552+ add_alias_change! (astate, ary, SSAValue (pc))
15491553 end
15501554 return true
15511555end
0 commit comments