@@ -91,7 +91,7 @@ bool swift::mayDecrementRefCount(SILInstruction *User,
91
91
// Use Analysis
92
92
// ===----------------------------------------------------------------------===//
93
93
94
- // / Returns true if a builtin apply cannot use reference counted values.
94
+ // / Returns true if a builtin apply can use reference counted values.
95
95
// /
96
96
// / The main case that this handles here are builtins that via read none imply
97
97
// / that they cannot read globals and at the same time do not take any
@@ -106,28 +106,33 @@ static bool canApplyOfBuiltinUseNonTrivialValues(BuiltinInst *BInst) {
106
106
if (II.hasAttribute (llvm::Attribute::ReadNone)) {
107
107
for (auto &Op : BInst->getAllOperands ()) {
108
108
if (!Op.get ()->getType ().isTrivial (*F)) {
109
- return false ;
109
+ return true ;
110
110
}
111
111
}
112
112
}
113
113
114
- return true ;
114
+ return false ;
115
115
}
116
116
117
117
auto &BI = BInst->getBuiltinInfo ();
118
- if (BI.isReadNone ()) {
119
- for (auto &Op : BInst->getAllOperands ()) {
120
- if (!Op.get ()->getType ().isTrivial (*F)) {
121
- return false ;
122
- }
118
+ if (!BI.isReadNone ())
119
+ return true ;
120
+
121
+ for (auto &Op : BInst->getAllOperands ()) {
122
+ if (!Op.get ()->getType ().isTrivial (*F)) {
123
+ return true ;
123
124
}
124
125
}
125
-
126
- return true ;
126
+ return false ;
127
127
}
128
128
129
- // / Returns true if Inst is a function that we know never uses ref count values.
130
- bool swift::canNeverUseValues (SILInstruction *Inst) {
129
+ // / Returns true if \p Inst may access any indirect object either via an address
130
+ // / or reference.
131
+ // /
132
+ // / If these instructions do have an address or reference type operand, then
133
+ // / they only operate on the value of the address itself, not the
134
+ // / memory. i.e. they don't dereference the address.
135
+ bool swift::canUseObject (SILInstruction *Inst) {
131
136
switch (Inst->getKind ()) {
132
137
// These instructions do not use other values.
133
138
case SILInstructionKind::FunctionRefInst:
@@ -142,33 +147,36 @@ bool swift::canNeverUseValues(SILInstruction *Inst) {
142
147
case SILInstructionKind::AllocBoxInst:
143
148
case SILInstructionKind::MetatypeInst:
144
149
case SILInstructionKind::WitnessMethodInst:
145
- return true ;
150
+ return false ;
146
151
147
152
// DeallocStackInst do not use reference counted values.
148
153
case SILInstructionKind::DeallocStackInst:
149
- return true ;
154
+ return false ;
150
155
151
156
// Debug values do not use referenced counted values in a manner we care
152
157
// about.
153
158
case SILInstructionKind::DebugValueInst:
154
159
case SILInstructionKind::DebugValueAddrInst:
155
- return true ;
160
+ return false ;
156
161
157
162
// Casts do not use pointers in a manner that we care about since we strip
158
163
// them during our analysis. The reason for this is if the cast is not dead
159
164
// then there must be some other use after the cast that we will protect if a
160
165
// release is not in between the cast and the use.
166
+ //
167
+ // Note: UncheckedRefCastAddrInst moves a reference into a new object. While
168
+ // the net reference count should be zero, there's no guarantee it won't
169
+ // access the object.
161
170
case SILInstructionKind::UpcastInst:
162
171
case SILInstructionKind::AddressToPointerInst:
163
172
case SILInstructionKind::PointerToAddressInst:
164
173
case SILInstructionKind::UncheckedRefCastInst:
165
- case SILInstructionKind::UncheckedRefCastAddrInst:
166
174
case SILInstructionKind::UncheckedAddrCastInst:
167
175
case SILInstructionKind::RefToRawPointerInst:
168
176
case SILInstructionKind::RawPointerToRefInst:
169
177
case SILInstructionKind::UnconditionalCheckedCastInst:
170
178
case SILInstructionKind::UncheckedBitwiseCastInst:
171
- return true ;
179
+ return false ;
172
180
173
181
// If we have a trivial bit cast between trivial types, it is not something
174
182
// that can use ref count ops in a way we care about. We do need to be careful
@@ -183,7 +191,7 @@ bool swift::canNeverUseValues(SILInstruction *Inst) {
183
191
// safe.
184
192
case SILInstructionKind::UncheckedTrivialBitCastInst: {
185
193
SILValue Op = cast<UncheckedTrivialBitCastInst>(Inst)->getOperand ();
186
- return Op->getType ().isTrivial (*Inst->getFunction ());
194
+ return ! Op->getType ().isTrivial (*Inst->getFunction ());
187
195
}
188
196
189
197
// Typed GEPs do not use pointers. The user of the typed GEP may but we will
@@ -198,18 +206,18 @@ bool swift::canNeverUseValues(SILInstruction *Inst) {
198
206
case SILInstructionKind::UncheckedEnumDataInst:
199
207
case SILInstructionKind::IndexAddrInst:
200
208
case SILInstructionKind::IndexRawPointerInst:
201
- return true ;
209
+ return false ;
202
210
203
211
// Aggregate formation by themselves do not create new uses since it is their
204
212
// users that would create the appropriate uses.
205
213
case SILInstructionKind::EnumInst:
206
214
case SILInstructionKind::StructInst:
207
215
case SILInstructionKind::TupleInst:
208
- return true ;
216
+ return false ;
209
217
210
218
// Only uses non reference counted values.
211
219
case SILInstructionKind::CondFailInst:
212
- return true ;
220
+ return false ;
213
221
214
222
case SILInstructionKind::BuiltinInst: {
215
223
auto *BI = cast<BuiltinInst>(Inst);
@@ -221,9 +229,9 @@ bool swift::canNeverUseValues(SILInstruction *Inst) {
221
229
// dead, LLVM will clean it up.
222
230
case SILInstructionKind::BranchInst:
223
231
case SILInstructionKind::CondBranchInst:
224
- return true ;
225
- default :
226
232
return false ;
233
+ default :
234
+ return true ;
227
235
}
228
236
}
229
237
@@ -268,14 +276,15 @@ static bool canTerminatorUseValue(TermInst *TI, SILValue Ptr,
268
276
269
277
270
278
bool swift::mayHaveSymmetricInterference (SILInstruction *User, SILValue Ptr, AliasAnalysis *AA) {
279
+ // If Inst is an instruction that we know can never use values with reference
280
+ // semantics, return true. Check this before AliasAnalysis because some memory
281
+ // operations, like dealloc_stack, don't use ref counted values.
282
+ if (!canUseObject (User))
283
+ return false ;
284
+
271
285
// Check whether releasing this value can call deinit and interfere with User.
272
286
if (AA->mayValueReleaseInterfereWithInstruction (User, Ptr))
273
287
return true ;
274
-
275
- // If Inst is an instruction that we know can never use values with reference
276
- // semantics, return true.
277
- if (canNeverUseValues (User))
278
- return false ;
279
288
280
289
// If the user is a load or a store and we can prove that it does not access
281
290
// the object then return true.
0 commit comments