@@ -35,275 +35,6 @@ SILValue swift::getUnderlyingObject(SILValue V) {
35
35
}
36
36
}
37
37
38
- // / Returns true if the ValueBase inside V is an apply whose callee is a no read
39
- // / builtin.
40
- static bool isNoReadBuiltinInst (SILValue V) {
41
- auto *BI = dyn_cast<BuiltinInst>(V);
42
- return BI && !BI->mayReadOrWriteMemory ();
43
- }
44
-
45
- // / Is Inst an instruction which escapes if and only if one of its results
46
- // / escape?
47
- static bool isTransitiveEscapeInst (SILInstruction *Inst) {
48
- switch (Inst->getKind ()) {
49
- case ValueKind::AllocBoxInst:
50
- case ValueKind::AllocExistentialBoxInst:
51
- case ValueKind::AllocRefInst:
52
- case ValueKind::AllocRefDynamicInst:
53
- case ValueKind::AllocStackInst:
54
- case ValueKind::AllocValueBufferInst:
55
- case ValueKind::BuiltinInst:
56
- case ValueKind::ApplyInst:
57
- case ValueKind::TryApplyInst:
58
- case ValueKind::WitnessMethodInst:
59
- case ValueKind::CopyAddrInst:
60
- case ValueKind::RetainValueInst:
61
- case ValueKind::DeallocBoxInst:
62
- case ValueKind::DeallocExistentialBoxInst:
63
- case ValueKind::DeallocRefInst:
64
- case ValueKind::DeallocPartialRefInst:
65
- case ValueKind::DeallocStackInst:
66
- case ValueKind::DeallocValueBufferInst:
67
- case ValueKind::DebugValueAddrInst:
68
- case ValueKind::DebugValueInst:
69
- case ValueKind::DestroyAddrInst:
70
- case ValueKind::ReleaseValueInst:
71
- case ValueKind::AutoreleaseValueInst:
72
- case ValueKind::FloatLiteralInst:
73
- case ValueKind::FunctionRefInst:
74
- case ValueKind::IntegerLiteralInst:
75
- case ValueKind::LoadInst:
76
- case ValueKind::LoadUnownedInst:
77
- case ValueKind::LoadWeakInst:
78
- case ValueKind::MetatypeInst:
79
- case ValueKind::ObjCProtocolInst:
80
- case ValueKind::GlobalAddrInst:
81
- case ValueKind::StoreInst:
82
- case ValueKind::StoreUnownedInst:
83
- case ValueKind::StoreWeakInst:
84
- case ValueKind::StringLiteralInst:
85
- case ValueKind::CopyBlockInst:
86
- case ValueKind::StrongReleaseInst:
87
- case ValueKind::StrongPinInst: // Pin handle is independently managed
88
- case ValueKind::StrongRetainInst:
89
- case ValueKind::StrongRetainUnownedInst:
90
- case ValueKind::StrongUnpinInst:
91
- case ValueKind::UnownedReleaseInst:
92
- case ValueKind::UnownedRetainInst:
93
- case ValueKind::IsUniqueInst:
94
- case ValueKind::IsUniqueOrPinnedInst:
95
- case ValueKind::InjectEnumAddrInst:
96
- case ValueKind::DeinitExistentialAddrInst:
97
- case ValueKind::UnreachableInst:
98
- case ValueKind::IsNonnullInst:
99
- case ValueKind::CondFailInst:
100
- case ValueKind::DynamicMethodBranchInst:
101
- case ValueKind::ReturnInst:
102
- case ValueKind::ThrowInst:
103
- case ValueKind::FixLifetimeInst:
104
- return false ;
105
-
106
- case ValueKind::AddressToPointerInst:
107
- case ValueKind::ValueMetatypeInst:
108
- case ValueKind::BranchInst:
109
- case ValueKind::CheckedCastBranchInst:
110
- case ValueKind::CheckedCastAddrBranchInst:
111
- case ValueKind::ClassMethodInst:
112
- case ValueKind::CondBranchInst:
113
- case ValueKind::ConvertFunctionInst:
114
- case ValueKind::DynamicMethodInst:
115
- case ValueKind::EnumInst:
116
- case ValueKind::IndexAddrInst:
117
- case ValueKind::IndexRawPointerInst:
118
- case ValueKind::InitBlockStorageHeaderInst:
119
- case ValueKind::InitEnumDataAddrInst:
120
- case ValueKind::InitExistentialAddrInst:
121
- case ValueKind::InitExistentialMetatypeInst:
122
- case ValueKind::InitExistentialRefInst:
123
- case ValueKind::ObjCExistentialMetatypeToObjectInst:
124
- case ValueKind::ObjCMetatypeToObjectInst:
125
- case ValueKind::ObjCToThickMetatypeInst:
126
- case ValueKind::UncheckedRefCastInst:
127
- case ValueKind::UncheckedRefCastAddrInst:
128
- case ValueKind::UncheckedAddrCastInst:
129
- case ValueKind::UncheckedTrivialBitCastInst:
130
- case ValueKind::UncheckedBitwiseCastInst:
131
- case ValueKind::MarkDependenceInst:
132
- case ValueKind::OpenExistentialAddrInst:
133
- case ValueKind::OpenExistentialMetatypeInst:
134
- case ValueKind::OpenExistentialRefInst:
135
- case ValueKind::OpenExistentialBoxInst:
136
- case ValueKind::PartialApplyInst:
137
- case ValueKind::ProjectBoxInst:
138
- case ValueKind::ProjectValueBufferInst:
139
- case ValueKind::PointerToAddressInst:
140
- case ValueKind::PointerToThinFunctionInst:
141
- case ValueKind::ProjectBlockStorageInst:
142
- case ValueKind::ExistentialMetatypeInst:
143
- case ValueKind::RawPointerToRefInst:
144
- case ValueKind::RefElementAddrInst:
145
- case ValueKind::RefToRawPointerInst:
146
- case ValueKind::RefToUnmanagedInst:
147
- case ValueKind::RefToUnownedInst:
148
- case ValueKind::SelectEnumInst:
149
- case ValueKind::SelectEnumAddrInst:
150
- case ValueKind::SelectValueInst:
151
- case ValueKind::StructElementAddrInst:
152
- case ValueKind::StructExtractInst:
153
- case ValueKind::StructInst:
154
- case ValueKind::SuperMethodInst:
155
- case ValueKind::SwitchEnumAddrInst:
156
- case ValueKind::SwitchEnumInst:
157
- case ValueKind::SwitchValueInst:
158
- case ValueKind::UncheckedEnumDataInst:
159
- case ValueKind::UncheckedTakeEnumDataAddrInst:
160
- case ValueKind::ThickToObjCMetatypeInst:
161
- case ValueKind::ThinFunctionToPointerInst:
162
- case ValueKind::ThinToThickFunctionInst:
163
- case ValueKind::TupleElementAddrInst:
164
- case ValueKind::TupleExtractInst:
165
- case ValueKind::TupleInst:
166
- case ValueKind::UnconditionalCheckedCastInst:
167
- case ValueKind::UnconditionalCheckedCastAddrInst:
168
- case ValueKind::UnmanagedToRefInst:
169
- case ValueKind::UnownedToRefInst:
170
- case ValueKind::UpcastInst:
171
- case ValueKind::RefToBridgeObjectInst:
172
- case ValueKind::BridgeObjectToRefInst:
173
- case ValueKind::BridgeObjectToWordInst:
174
- return true ;
175
-
176
- case ValueKind::AssignInst:
177
- case ValueKind::MarkFunctionEscapeInst:
178
- case ValueKind::MarkUninitializedInst:
179
- llvm_unreachable (" Invalid in canonical SIL." );
180
-
181
- case ValueKind::SILArgument:
182
- case ValueKind::SILUndef:
183
- llvm_unreachable (" These do not use other values." );
184
- }
185
- }
186
-
187
- // / Maximum amount of ValueCapture queries.
188
- static unsigned const ValueCaptureSearchThreshold = 32 ;
189
-
190
- namespace {
191
-
192
- // / Are there any uses that should be ignored as capture uses.
193
- // /
194
- // / TODO: Expand this if we ever do the store of pointer analysis mentioned in
195
- // / Basic AA.
196
- enum CaptureException : unsigned {
197
- None=0 ,
198
- ReturnsCannotCapture=1 ,
199
- };
200
-
201
- } // end anonymous namespace
202
-
203
- // / Returns true if V is a value that is used in a manner such that we know its
204
- // / captured or we don't understand whether or not it was captured. In such a
205
- // / case to be conservative, we must assume it is captured.
206
- // / FIXME: Maybe put this on SILValue?
207
- static bool valueMayBeCaptured (SILValue V, CaptureException Exception) {
208
- llvm::SmallVector<Operand *, ValueCaptureSearchThreshold> Worklist;
209
- llvm::SmallPtrSet<Operand *, ValueCaptureSearchThreshold> Visited;
210
- unsigned Count = 0 ;
211
-
212
- DEBUG (llvm::dbgs () << " Checking for capture.\n " );
213
-
214
-
215
- // All uses of V to the worklist.
216
- for (auto *UI : V.getUses ()) {
217
- // If we have more uses than the threshold, be conservative and bail so we
218
- // don't use too much compile time.
219
- if (Count++ >= ValueCaptureSearchThreshold)
220
- return true ;
221
- Visited.insert (UI);
222
- Worklist.push_back (UI);
223
- }
224
-
225
- // Until the worklist is empty...
226
- while (!Worklist.empty ()) {
227
- // Pop off an operand and grab the operand's user...
228
- Operand *Op = Worklist.pop_back_val ();
229
- SILInstruction *Inst = Op->getUser ();
230
-
231
- DEBUG (llvm::dbgs () << " Visiting: " << *Inst);
232
-
233
- // If Inst is an instruction with the transitive escape property, V escapes
234
- // if and only if the results of Inst escape as well.
235
- if (isTransitiveEscapeInst (Inst)) {
236
- DEBUG (llvm::dbgs () << " Found transitive escape "
237
- " instruction!\n " );
238
- for (auto *UI : Inst->getUses ()) {
239
- // If we have more uses than the threshold, be conservative and bail
240
- // so we don't use too much compile time.
241
- if (Count++ >= ValueCaptureSearchThreshold)
242
- return true ;
243
-
244
- if (Visited.insert (UI).second ) {
245
- Worklist.push_back (UI);
246
- }
247
- }
248
- continue ;
249
- }
250
-
251
- // An apply of a builtin that does not read memory cannot capture a value.
252
- //
253
- // TODO: Use analysis of the other function perhaps to see if it captures
254
- // memory in some manner?
255
- // TODO: Add in knowledge about how parameters work on swift to make this
256
- // more aggressive.
257
- if (isNoReadBuiltinInst (Inst))
258
- continue ;
259
-
260
- // Loading from a pointer does not cause it to be captured.
261
- if (isa<LoadInst>(Inst))
262
- continue ;
263
-
264
- // If we have a store and are storing into the pointer, this is not a
265
- // capture. Otherwise it is safe.
266
- if (auto *SI = dyn_cast<StoreInst>(Inst)) {
267
- if (SI->getDest () == Op->get ()) {
268
- continue ;
269
- } else {
270
- return true ;
271
- }
272
- }
273
-
274
- // Deallocation instructions don't capture.
275
- if (isa<DeallocationInst>(Inst))
276
- continue ;
277
-
278
- // Debug instructions don't capture.
279
- if (isa<DebugValueInst>(Inst) || isa<DebugValueAddrInst>(Inst))
280
- continue ;
281
-
282
- // RefCountOperations don't capture.
283
- //
284
- // The release case is true since Swift does not allow destructors to
285
- // resurrect objects. This is enforced via a runtime failure.
286
- if (isa<RefCountingInst>(Inst))
287
- continue ;
288
-
289
- // If we have a return instruction and we are assuming that returns don't
290
- // capture, we are safe.
291
- if (Exception == CaptureException::ReturnsCannotCapture &&
292
- isa<ReturnInst>(Inst))
293
- continue ;
294
-
295
- // We could not prove that Inst does not capture V. Be conservative and
296
- // return true.
297
- DEBUG (llvm::dbgs () << " Could not prove that inst does not capture "
298
- " V!\n " );
299
- return true ;
300
- }
301
-
302
- // We successfully proved that V is not captured. Return false.
303
- DEBUG (llvm::dbgs () << " V was not captured!\n " );
304
- return false ;
305
- }
306
-
307
38
bool swift::isNotAliasingArgument (SILValue V,
308
39
InoutAliasingAssumption isInoutAliasing) {
309
40
auto *Arg = dyn_cast<SILArgument>(V);
@@ -321,32 +52,6 @@ bool swift::pointsToLocalObject(SILValue V,
321
52
isNotAliasingArgument (V, isInoutAliasing);
322
53
}
323
54
324
- // / Return true if the pointer is to a function-local object that never escapes
325
- // / from the function.
326
- bool swift::isNonEscapingLocalObject (SILValue V) {
327
- // If this is a local allocation, or the result of a no read apply inst (which
328
- // cannot affect memory in the caller), check to see if the allocation
329
- // escapes.
330
- if (isa<AllocationInst>(*V) || isNoReadBuiltinInst (V))
331
- return !valueMayBeCaptured (V, CaptureException::ReturnsCannotCapture);
332
-
333
- // If this is a no alias argument then it has not escaped before entering the
334
- // function. Check if it escapes inside the function.
335
- if (isNotAliasingArgument (V))
336
- return !valueMayBeCaptured (V, CaptureException::ReturnsCannotCapture);
337
-
338
- // If this is an enum value. If it or its operand does not escape, it is
339
- // local.
340
- if (auto *EI = dyn_cast<EnumInst>(V))
341
- return !EI->hasOperand () ||
342
- !valueMayBeCaptured (EI->getOperand (),
343
- CaptureException::ReturnsCannotCapture);
344
-
345
- // Otherwise we could not prove that V is a non escaping local object. Be
346
- // conservative and return false.
347
- return false ;
348
- }
349
-
350
55
// / Check if the value \p Value is known to be zero, non-zero or unknown.
351
56
IsZeroKind swift::isZeroValue (SILValue Value) {
352
57
// Inspect integer literals.
0 commit comments