|
12 | 12 |
|
13 | 13 | #define DEBUG_TYPE "sil-dce"
|
14 | 14 | #include "swift/Basic/Assertions.h"
|
| 15 | +#include "swift/SIL/BasicBlockBits.h" |
15 | 16 | #include "swift/SIL/DebugUtils.h"
|
| 17 | +#include "swift/SIL/MemAccessUtils.h" |
| 18 | +#include "swift/SIL/NodeBits.h" |
16 | 19 | #include "swift/SIL/OwnershipUtils.h"
|
17 | 20 | #include "swift/SIL/SILArgument.h"
|
18 | 21 | #include "swift/SIL/SILBasicBlock.h"
|
19 |
| -#include "swift/SIL/BasicBlockBits.h" |
20 |
| -#include "swift/SIL/NodeBits.h" |
21 | 22 | #include "swift/SIL/SILBuilder.h"
|
22 | 23 | #include "swift/SIL/SILFunction.h"
|
23 | 24 | #include "swift/SIL/SILUndef.h"
|
@@ -254,6 +255,48 @@ static BuiltinInst *getProducer(CondFailInst *CFI) {
|
254 | 255 |
|
255 | 256 | // Determine which instructions from this function we need to keep.
|
256 | 257 | void DCE::markLive() {
|
| 258 | + auto processBorrow = [&](BorrowedValue borrow) { |
| 259 | + // Populate guaranteedPhiDependencies for this borrow |
| 260 | + findGuaranteedPhiDependencies(borrow); |
| 261 | + if (!borrow.hasReborrow()) { |
| 262 | + return; |
| 263 | + } |
| 264 | + |
| 265 | + // If the borrow was not computed from another |
| 266 | + // borrow, return. |
| 267 | + SILValue baseValue; |
| 268 | + if (auto *beginBorrow = dyn_cast<BeginBorrowInst>(*borrow)) { |
| 269 | + auto borrowOp = beginBorrow->getOperand(); |
| 270 | + if (borrowOp->getOwnershipKind() != OwnershipKind::Guaranteed) { |
| 271 | + return; |
| 272 | + } |
| 273 | + baseValue = borrowOp; |
| 274 | + } else { |
| 275 | + auto *loadBorrow = cast<LoadBorrowInst>(*borrow); |
| 276 | + auto accessBase = AccessBase::compute(loadBorrow->getOperand()); |
| 277 | + if (!accessBase.isReference()) { |
| 278 | + return; |
| 279 | + } |
| 280 | + baseValue = accessBase.getReference(); |
| 281 | + } |
| 282 | + // If the borrow was computed from another |
| 283 | + // borrow, disable DCE of the outer borrow. |
| 284 | + // This is because, when a reborrow is dead, DCE has to insert |
| 285 | + // end_borrows in predecessor blocks and it cannot yet handle borrow |
| 286 | + // nesting. |
| 287 | + // TODO: Instead of disabling DCE of outer borrow, consider inserting |
| 288 | + // end_borrows inside-out. |
| 289 | + SmallVector<SILValue, 4> roots; |
| 290 | + findGuaranteedReferenceRoots(baseValue, |
| 291 | + /*lookThroughNestedBorrows=*/false, roots); |
| 292 | + // Visit the end_borrows of all the borrow scopes that this |
| 293 | + // begin_borrow could be borrowing, and mark them live. |
| 294 | + for (auto root : roots) { |
| 295 | + visitTransitiveEndBorrows(root, [&](EndBorrowInst *endBorrow) { |
| 296 | + markInstructionLive(endBorrow); |
| 297 | + }); |
| 298 | + } |
| 299 | + }; |
257 | 300 | // Find the initial set of instructions in this function that appear
|
258 | 301 | // to be live in the sense that they are not trivially something we
|
259 | 302 | // can delete by examining only that instruction.
|
@@ -327,32 +370,12 @@ void DCE::markLive() {
|
327 | 370 | }
|
328 | 371 | case SILInstructionKind::BeginBorrowInst: {
|
329 | 372 | auto *borrowInst = cast<BeginBorrowInst>(&I);
|
330 |
| - // Populate guaranteedPhiDependencies for this borrowInst |
331 |
| - findGuaranteedPhiDependencies(BorrowedValue(borrowInst)); |
332 |
| - auto disableBorrowDCE = [&](SILValue borrow) { |
333 |
| - visitTransitiveEndBorrows(borrow, [&](EndBorrowInst *endBorrow) { |
334 |
| - markInstructionLive(endBorrow); |
335 |
| - }); |
336 |
| - }; |
337 |
| - // If we have a begin_borrow of a @guaranteed operand, disable DCE'ing |
338 |
| - // of parent borrow scopes. Dead reborrows needs complex handling, which |
339 |
| - // is why it is disabled for now. |
340 |
| - if (borrowInst->getOperand()->getOwnershipKind() == |
341 |
| - OwnershipKind::Guaranteed) { |
342 |
| - SmallVector<SILValue, 4> roots; |
343 |
| - findGuaranteedReferenceRoots(borrowInst->getOperand(), |
344 |
| - /*lookThroughNestedBorrows=*/false, |
345 |
| - roots); |
346 |
| - // Visit the end_borrows of all the borrow scopes that this |
347 |
| - // begin_borrow could be borrowing, and mark them live. |
348 |
| - for (auto root : roots) { |
349 |
| - disableBorrowDCE(root); |
350 |
| - } |
351 |
| - } |
| 373 | + processBorrow(BorrowedValue(borrowInst)); |
352 | 374 | break;
|
353 | 375 | }
|
354 | 376 | case SILInstructionKind::LoadBorrowInst: {
|
355 |
| - findGuaranteedPhiDependencies(BorrowedValue(cast<LoadBorrowInst>(&I))); |
| 377 | + auto *loadBorrowInst = cast<LoadBorrowInst>(&I); |
| 378 | + processBorrow(BorrowedValue(loadBorrowInst)); |
356 | 379 | break;
|
357 | 380 | }
|
358 | 381 | default:
|
|
0 commit comments