@@ -67,6 +67,9 @@ class TempRValueOptPass : public SILFunctionTransform {
67
67
bool collectLoads (Operand *userOp, SILInstruction *userInst,
68
68
SingleValueInstruction *addr, SILValue srcObject,
69
69
SmallPtrSetImpl<SILInstruction *> &loadInsts);
70
+ bool collectLoadsFromProjection (SingleValueInstruction *projection,
71
+ SILValue srcAddr,
72
+ SmallPtrSetImpl<SILInstruction *> &loadInsts);
70
73
71
74
bool
72
75
checkNoSourceModification (CopyAddrInst *copyInst, SILValue copySrc,
@@ -85,6 +88,29 @@ class TempRValueOptPass : public SILFunctionTransform {
85
88
86
89
} // anonymous namespace
87
90
91
+ bool TempRValueOptPass::collectLoadsFromProjection (
92
+ SingleValueInstruction *projection, SILValue srcAddr,
93
+ SmallPtrSetImpl<SILInstruction *> &loadInsts) {
94
+ if (!srcAddr) {
95
+ LLVM_DEBUG (
96
+ llvm::dbgs ()
97
+ << " Temp has addr_projection use?! Can not yet promote to value"
98
+ << *projection);
99
+ return false ;
100
+ }
101
+
102
+ // Transitively look through projections on stack addresses.
103
+ for (auto *projUseOper : projection->getUses ()) {
104
+ auto *user = projUseOper->getUser ();
105
+ if (user->isTypeDependentOperand (*projUseOper))
106
+ continue ;
107
+
108
+ if (!collectLoads (projUseOper, user, projection, srcAddr, loadInsts))
109
+ return false ;
110
+ }
111
+ return true ;
112
+ }
113
+
88
114
// / Transitively explore all data flow uses of the given \p address until
89
115
// / reaching a load or returning false.
90
116
// /
@@ -199,32 +225,13 @@ bool TempRValueOptPass::collectLoads(
199
225
<< *user);
200
226
return false ;
201
227
}
202
- LLVM_FALLTHROUGH ;
228
+ return collectLoadsFromProjection (oeai, srcAddr, loadInsts) ;
203
229
}
204
230
case SILInstructionKind::StructElementAddrInst:
205
231
case SILInstructionKind::TupleElementAddrInst: {
206
- auto *proj = cast<SingleValueInstruction>(user);
207
-
208
- if (!srcAddr) {
209
- LLVM_DEBUG (
210
- llvm::dbgs ()
211
- << " Temp has addr_projection use?! Can not yet promote to value"
212
- << *user);
213
- return false ;
214
- }
215
-
216
- // Transitively look through projections on stack addresses.
217
- for (auto *projUseOper : proj->getUses ()) {
218
- auto *user = projUseOper->getUser ();
219
- if (user->isTypeDependentOperand (*projUseOper))
220
- continue ;
221
-
222
- if (!collectLoads (projUseOper, user, proj, srcAddr, loadInsts))
223
- return false ;
224
- }
225
- return true ;
232
+ return collectLoadsFromProjection (cast<SingleValueInstruction>(user),
233
+ srcAddr, loadInsts);
226
234
}
227
-
228
235
case SILInstructionKind::LoadInst:
229
236
// Loads are the end of the data flow chain. The users of the load can't
230
237
// access the temporary storage.
0 commit comments