@@ -75,11 +75,10 @@ namespace {
7575class TempRValueOptPass : public SILFunctionTransform {
7676 AliasAnalysis *aa = nullptr ;
7777
78- bool collectLoads (Operand *userOp, SILInstruction *userInst,
79- SingleValueInstruction *addr, SILValue srcObject,
78+ bool collectLoads (Operand *addressUse, CopyAddrInst *originalCopy,
8079 SmallPtrSetImpl<SILInstruction *> &loadInsts);
8180 bool collectLoadsFromProjection (SingleValueInstruction *projection,
82- SILValue srcAddr ,
81+ CopyAddrInst *originalCopy ,
8382 SmallPtrSetImpl<SILInstruction *> &loadInsts);
8483
8584 bool
@@ -103,15 +102,15 @@ class TempRValueOptPass : public SILFunctionTransform {
103102} // anonymous namespace
104103
105104bool TempRValueOptPass::collectLoadsFromProjection (
106- SingleValueInstruction *projection, SILValue srcAddr ,
105+ SingleValueInstruction *projection, CopyAddrInst *originalCopy ,
107106 SmallPtrSetImpl<SILInstruction *> &loadInsts) {
108107 // Transitively look through projections on stack addresses.
109108 for (auto *projUseOper : projection->getUses ()) {
110109 auto *user = projUseOper->getUser ();
111110 if (user->isTypeDependentOperand (*projUseOper))
112111 continue ;
113112
114- if (!collectLoads (projUseOper, user, projection, srcAddr , loadInsts))
113+ if (!collectLoads (projUseOper, originalCopy , loadInsts))
115114 return false ;
116115 }
117116 return true ;
@@ -155,12 +154,15 @@ bool TempRValueOptPass::canApplyBeTreatedAsLoad(
155154// / location at \address. The temporary must be initialized by the original copy
156155// / and never written to again. Therefore, collectLoads disallows any operation
157156// / that may write to memory at \p address.
158- bool TempRValueOptPass::collectLoads (
159- Operand *userOp, SILInstruction *user, SingleValueInstruction *address,
160- SILValue srcAddr, SmallPtrSetImpl<SILInstruction *> &loadInsts) {
157+ bool TempRValueOptPass::
158+ collectLoads (Operand *addressUse, CopyAddrInst *originalCopy,
159+ SmallPtrSetImpl<SILInstruction *> &loadInsts) {
160+ SILInstruction *user = addressUse->getUser ();
161+ SILValue address = addressUse->get ();
162+
161163 // All normal uses (loads) must be in the initialization block.
162164 // (The destroy and dealloc are commonly in a different block though.)
163- SILBasicBlock *block = address ->getParent ();
165+ SILBasicBlock *block = originalCopy ->getParent ();
164166 if (user->getParent () != block)
165167 return false ;
166168
@@ -192,8 +194,7 @@ bool TempRValueOptPass::collectLoads(
192194 // If the user is the value operand of the MarkDependenceInst we have to
193195 // transitively explore its uses until we reach a load or return false
194196 for (auto *mdiUseOper : mdi->getUses ()) {
195- if (!collectLoads (mdiUseOper, mdiUseOper->getUser (), mdi, srcAddr,
196- loadInsts))
197+ if (!collectLoads (mdiUseOper, originalCopy, loadInsts))
197198 return false ;
198199 }
199200 return true ;
@@ -204,14 +205,16 @@ bool TempRValueOptPass::collectLoads(
204205 LLVM_FALLTHROUGH;
205206 case SILInstructionKind::ApplyInst:
206207 case SILInstructionKind::TryApplyInst: {
207- if (!canApplyBeTreatedAsLoad (userOp, ApplySite (user), srcAddr))
208+ if (!canApplyBeTreatedAsLoad (addressUse, ApplySite (user),
209+ originalCopy->getSrc ()))
208210 return false ;
209211 // Everything is okay with the function call. Register it as a "load".
210212 loadInsts.insert (user);
211213 return true ;
212214 }
213215 case SILInstructionKind::BeginApplyInst: {
214- if (!canApplyBeTreatedAsLoad (userOp, ApplySite (user), srcAddr))
216+ if (!canApplyBeTreatedAsLoad (addressUse, ApplySite (user),
217+ originalCopy->getSrc ()))
215218 return false ;
216219
217220 auto beginApply = cast<BeginApplyInst>(user);
@@ -235,7 +238,7 @@ bool TempRValueOptPass::collectLoads(
235238 << *user);
236239 return false ;
237240 }
238- return collectLoadsFromProjection (oeai, srcAddr , loadInsts);
241+ return collectLoadsFromProjection (oeai, originalCopy , loadInsts);
239242 }
240243 case SILInstructionKind::UncheckedTakeEnumDataAddrInst: {
241244 // In certain cases, unchecked_take_enum_data_addr invalidates the
@@ -249,14 +252,13 @@ bool TempRValueOptPass::collectLoads(
249252 return false ;
250253 }
251254
252- return collectLoadsFromProjection (utedai, srcAddr , loadInsts);
255+ return collectLoadsFromProjection (utedai, originalCopy , loadInsts);
253256 }
254257 case SILInstructionKind::StructElementAddrInst:
255258 case SILInstructionKind::TupleElementAddrInst:
256- case SILInstructionKind::UncheckedAddrCastInst: {
259+ case SILInstructionKind::UncheckedAddrCastInst:
257260 return collectLoadsFromProjection (cast<SingleValueInstruction>(user),
258- srcAddr, loadInsts);
259- }
261+ originalCopy, loadInsts);
260262 case SILInstructionKind::LoadInst:
261263 // Loads are the end of the data flow chain. The users of the load can't
262264 // access the temporary storage.
@@ -448,7 +450,7 @@ bool TempRValueOptPass::tryOptimizeCopyIntoTemp(CopyAddrInst *copyInst) {
448450 }
449451 }
450452
451- if (!collectLoads (useOper, user, tempObj, copySrc , loadInsts))
453+ if (!collectLoads (useOper, copyInst , loadInsts))
452454 return false ;
453455 }
454456
0 commit comments