@@ -101,6 +101,9 @@ class DestroyHoisting {
101
101
102
102
void moveDestroys (MemoryDataflow &dataFlow);
103
103
104
+ bool locationOverlaps (const MemoryLocations::Location *loc,
105
+ const Bits &destroys);
106
+
104
107
void moveDestroysInBlock (SILBasicBlock *block, Bits &activeDestroys,
105
108
SmallVectorImpl<SILInstruction *> &toRemove);
106
109
@@ -415,6 +418,19 @@ void DestroyHoisting::moveDestroys(MemoryDataflow &dataFlow) {
415
418
}
416
419
}
417
420
421
+ bool DestroyHoisting::locationOverlaps (const MemoryLocations::Location *loc,
422
+ const Bits &destroys) {
423
+ // We cannot just check if 'loc->subLocations' has any common bits with
424
+ // 'destroys', because subLocations don't include the "self" bit if all sub
425
+ // locations cover the whole location.
426
+ for (int subIdx = loc->subLocations .find_first (); subIdx >= 0 ;
427
+ subIdx = loc->subLocations .find_next (subIdx)) {
428
+ if (destroys.anyCommon (locations.getLocation (subIdx)->selfAndParents ))
429
+ return true ;
430
+ }
431
+ return false ;
432
+ }
433
+
418
434
void DestroyHoisting::moveDestroysInBlock (
419
435
SILBasicBlock *block, Bits &activeDestroys,
420
436
SmallVectorImpl<SILInstruction *> &toRemove) {
@@ -435,11 +451,9 @@ void DestroyHoisting::moveDestroysInBlock(
435
451
// debug_value_addr does not count as real use of a location. If we are
436
452
// moving a destroy_addr above a debug_value_addr, just delete that
437
453
// debug_value_addr.
438
- if (auto *dvaLoc = locations.getLocation (DVA->getOperand ())) {
439
- if (activeDestroys.anyCommon (dvaLoc->subLocations ) ||
440
- activeDestroys.anyCommon (dvaLoc->selfAndParents ))
441
- toRemove.push_back (DVA);
442
- }
454
+ auto *dvaLoc = locations.getLocation (DVA->getOperand ());
455
+ if (dvaLoc && locationOverlaps (dvaLoc, activeDestroys))
456
+ toRemove.push_back (DVA);
443
457
} else if (I.mayHaveSideEffects ()) {
444
458
// Delete all destroy_addr and debug_value_addr which are scheduled for
445
459
// removal.
0 commit comments