@@ -181,6 +181,10 @@ struct UseDefChainVisitor
181
181
// / values. We assert that all instructions that are CONSTANT_TRANSLATION
182
182
// / LookThrough to make sure they stay in sync.
183
183
static bool isStaticallyLookThroughInst (SILInstruction *inst) {
184
+ if (auto cast = SILDynamicCastInst::getAs (inst))
185
+ if (cast.isRCIdentityPreserving ())
186
+ return true ;
187
+
184
188
switch (inst->getKind ()) {
185
189
default :
186
190
return false ;
@@ -220,6 +224,37 @@ static bool isStaticallyLookThroughInst(SILInstruction *inst) {
220
224
}
221
225
}
222
226
227
+ static bool isLookThroughIfResultNonSendable (SILInstruction *inst) {
228
+ switch (inst->getKind ()) {
229
+ default :
230
+ return false ;
231
+ case SILInstructionKind::TupleElementAddrInst:
232
+ case SILInstructionKind::StructElementAddrInst:
233
+ case SILInstructionKind::RawPointerToRefInst:
234
+ return true ;
235
+ }
236
+ }
237
+
238
+ static bool isLookThroughIfOperandNonSendable (SILInstruction *inst) {
239
+ switch (inst->getKind ()) {
240
+ default :
241
+ return false ;
242
+ case SILInstructionKind::RefToRawPointerInst:
243
+ return true ;
244
+ }
245
+ }
246
+
247
+ static bool isLookThroughIfOperandAndResultSendable (SILInstruction *inst) {
248
+ switch (inst->getKind ()) {
249
+ default :
250
+ return false ;
251
+ case SILInstructionKind::UncheckedTrivialBitCastInst:
252
+ case SILInstructionKind::UncheckedBitwiseCastInst:
253
+ case SILInstructionKind::UncheckedValueCastInst:
254
+ return true ;
255
+ }
256
+ }
257
+
223
258
static SILValue getUnderlyingTrackedObjectValue (SILValue value) {
224
259
auto *fn = value->getFunction ();
225
260
SILValue result = value;
@@ -236,35 +271,26 @@ static SILValue getUnderlyingTrackedObjectValue(SILValue value) {
236
271
temp = svi->getOperand (0 );
237
272
}
238
273
239
- if (auto cast = SILDynamicCastInst::getAs (svi)) {
240
- if (cast.isRCIdentityPreserving ()) {
241
- temp = svi->getOperand (0 );
242
- }
243
- }
244
-
245
274
// If we have a cast and our operand and result are non-Sendable, treat it
246
275
// as a look through.
247
- if (isa<UncheckedTrivialBitCastInst, UncheckedBitwiseCastInst,
248
- UncheckedValueCastInst>(svi)) {
276
+ if (isLookThroughIfOperandAndResultSendable (svi)) {
249
277
if (isNonSendableType (svi->getType (), fn) &&
250
278
isNonSendableType (svi->getOperand (0 )->getType (), fn)) {
251
279
temp = svi->getOperand (0 );
252
280
}
253
281
}
254
- }
255
282
256
- if ( auto *r = dyn_cast<RefToRawPointerInst>(temp )) {
257
- // If our operand is a non-Sendable type, look through this instruction.
258
- if ( isNonSendableType (r ->getOperand ()-> getType (), fn)) {
259
- temp = r-> getOperand ();
283
+ if ( isLookThroughIfResultNonSendable (svi )) {
284
+ if ( isNonSendableType (svi-> getType (), fn)) {
285
+ temp = svi ->getOperand (0 );
286
+ }
260
287
}
261
- }
262
288
263
- if ( auto *r = dyn_cast<RawPointerToRefInst>(temp )) {
264
- // If our result is a non-Sendable type, look through this
265
- // instruction. Builtin.RawPointer is always non-Sendable.
266
- if ( isNonSendableType (r-> getType (), fn)) {
267
- temp = r-> getOperand ();
289
+ if ( isLookThroughIfOperandNonSendable (svi )) {
290
+ // If our operand is a non-Sendable type, look through this instruction.
291
+ if ( isNonSendableType (svi-> getOperand ( 0 )-> getType (), fn)) {
292
+ temp = svi-> getOperand ( 0 );
293
+ }
268
294
}
269
295
}
270
296
@@ -1829,6 +1855,11 @@ class PartitionOpTranslator {
1829
1855
1830
1856
case TranslationSemantics::LookThrough:
1831
1857
assert (inst->getNumOperands () == 1 );
1858
+ assert ((isStaticallyLookThroughInst (inst) ||
1859
+ isLookThroughIfResultNonSendable (inst) ||
1860
+ isLookThroughIfOperandNonSendable (inst) ||
1861
+ isLookThroughIfOperandAndResultSendable (inst)) &&
1862
+ " Out of sync... should return true for one of these categories!" );
1832
1863
return translateSILLookThrough (inst->getResults (), inst->getOperand (0 ));
1833
1864
1834
1865
case TranslationSemantics::Store:
@@ -2259,6 +2290,7 @@ CONSTANT_TRANSLATION(DeallocPackMetadataInst, Asserting)
2259
2290
// of the Sendable addr. That would require adding more logic though.
2260
2291
#define LOOKTHROUGH_IF_NONSENDABLE_RESULT_REQUIRE_OTHERWISE (INST ) \
2261
2292
TranslationSemantics PartitionOpTranslator::visit##INST(INST *inst) { \
2293
+ assert (isLookThroughIfResultNonSendable (inst) && " Out of sync?!" ); \
2262
2294
if (isNonSendableType (inst->getType ())) { \
2263
2295
return TranslationSemantics::LookThrough; \
2264
2296
} \
@@ -2294,6 +2326,7 @@ IGNORE_IF_SENDABLE_RESULT_ASSIGN_OTHERWISE(StructExtractInst)
2294
2326
#define CAST_WITH_MAYBE_SENDABLE_NONSENDABLE_OP_AND_RESULT (INST ) \
2295
2327
\
2296
2328
TranslationSemantics PartitionOpTranslator::visit##INST(INST *cast) { \
2329
+ assert (isLookThroughIfOperandAndResultSendable (cast) && " Out of sync" ); \
2297
2330
bool isOperandNonSendable = \
2298
2331
isNonSendableType (cast->getOperand ()->getType ()); \
2299
2332
bool isResultNonSendable = isNonSendableType (cast->getType ()); \
@@ -2324,6 +2357,7 @@ CAST_WITH_MAYBE_SENDABLE_NONSENDABLE_OP_AND_RESULT(UncheckedValueCastInst)
2324
2357
2325
2358
TranslationSemantics
2326
2359
PartitionOpTranslator::visitRawPointerToRefInst (RawPointerToRefInst *r) {
2360
+ assert (isLookThroughIfResultNonSendable (r) && " Out of sync" );
2327
2361
// If our result is non sendable, perform a look through.
2328
2362
if (isNonSendableType (r->getType ()))
2329
2363
return TranslationSemantics::LookThrough;
@@ -2334,6 +2368,8 @@ PartitionOpTranslator::visitRawPointerToRefInst(RawPointerToRefInst *r) {
2334
2368
2335
2369
TranslationSemantics
2336
2370
PartitionOpTranslator::visitRefToRawPointerInst (RefToRawPointerInst *r) {
2371
+ assert (isLookThroughIfOperandNonSendable (r) && " Out of sync" );
2372
+
2337
2373
// If our source ref is non sendable, perform a look through.
2338
2374
if (isNonSendableType (r->getOperand ()->getType ()))
2339
2375
return TranslationSemantics::LookThrough;
@@ -2345,6 +2381,7 @@ PartitionOpTranslator::visitRefToRawPointerInst(RefToRawPointerInst *r) {
2345
2381
2346
2382
TranslationSemantics
2347
2383
PartitionOpTranslator::visitMarkDependenceInst (MarkDependenceInst *mdi) {
2384
+ assert (isStaticallyLookThroughInst (mdi) && " Out of sync" );
2348
2385
translateSILLookThrough (mdi->getResults (), mdi->getValue ());
2349
2386
translateSILRequire (mdi->getBase ());
2350
2387
return TranslationSemantics::Special;
@@ -2360,8 +2397,12 @@ PartitionOpTranslator::visitPointerToAddressInst(PointerToAddressInst *ptai) {
2360
2397
2361
2398
TranslationSemantics PartitionOpTranslator::visitUnconditionalCheckedCastInst (
2362
2399
UnconditionalCheckedCastInst *ucci) {
2363
- if (SILDynamicCastInst (ucci).isRCIdentityPreserving ())
2400
+ if (SILDynamicCastInst (ucci).isRCIdentityPreserving ()) {
2401
+ assert (isStaticallyLookThroughInst (ucci) && " Out of sync" );
2364
2402
return TranslationSemantics::LookThrough;
2403
+ }
2404
+
2405
+ assert (!isStaticallyLookThroughInst (ucci) && " Out of sync" );
2365
2406
return TranslationSemantics::Assign;
2366
2407
}
2367
2408
0 commit comments