@@ -852,13 +852,17 @@ function sroa_mutables!(ir::IRCode, defuses::IdDict{Int, Tuple{SPCSet, SSADefUse
852852 typ = typ:: DataType
853853 # Partition defuses by field
854854 fielddefuse = SSADefUse[SSADefUse () for _ = 1 : fieldcount (typ)]
855+ all_forwarded = true
855856 for use in defuse. uses
856857 stmt = ir[SSAValue (use)] # == `getfield` call
857858 # We may have discovered above that this use is dead
858859 # after the getfield elim of immutables. In that case,
859860 # it would have been deleted. That's fine, just ignore
860861 # the use in that case.
861- stmt === nothing && continue
862+ if stmt === nothing
863+ all_forwarded = false
864+ continue
865+ end
862866 field = try_compute_fieldidx_stmt (ir, stmt:: Expr , typ)
863867 field === nothing && @goto skip
864868 push! (fielddefuse[field]. uses, use)
@@ -928,7 +932,12 @@ function sroa_mutables!(ir::IRCode, defuses::IdDict{Int, Tuple{SPCSet, SSADefUse
928932 end
929933 end
930934 preserve_uses === nothing && continue
931- push! (intermediaries, newidx)
935+ if all_forwarded
936+ # this means all ccall preserves have been replaced with forwarded loads
937+ # so we can potentially eliminate the allocation, otherwise we must preserve
938+ # the whole allocation.
939+ push! (intermediaries, newidx)
940+ end
932941 # Insert the new preserves
933942 for (use, new_preserves) in preserve_uses
934943 ir[SSAValue (use)] = form_new_preserves (ir[SSAValue (use)]:: Expr , intermediaries, new_preserves)
@@ -938,15 +947,16 @@ function sroa_mutables!(ir::IRCode, defuses::IdDict{Int, Tuple{SPCSet, SSADefUse
938947 end
939948end
940949
941- function form_new_preserves (origex:: Expr , preserved :: Vector{Int} , new_preserves:: Vector{Any} )
950+ function form_new_preserves (origex:: Expr , intermediates :: Vector{Int} , new_preserves:: Vector{Any} )
942951 newex = Expr (:foreigncall )
943952 nccallargs = length (origex. args[3 ]:: SimpleVector )
944953 for i in 1 : (6 + nccallargs- 1 )
945954 push! (newex. args, origex. args[i])
946955 end
947956 for i in (6 + nccallargs): length (origex. args)
948957 x = origex. args[i]
949- if isa (x, SSAValue) && x. id in preserved
958+ # don't need to preserve intermediaries
959+ if isa (x, SSAValue) && x. id in intermediates
950960 continue
951961 end
952962 push! (newex. args, x)
0 commit comments