|
13 | 13 | #define DEBUG_TYPE "allocbox-to-stack" |
14 | 14 | #include "swift/AST/DiagnosticsSIL.h" |
15 | 15 | #include "swift/Basic/BlotMapVector.h" |
| 16 | +#include "swift/Basic/GraphNodeWorklist.h" |
16 | 17 | #include "swift/SIL/ApplySite.h" |
| 18 | +#include "swift/SIL/BasicBlockDatastructures.h" |
17 | 19 | #include "swift/SIL/Dominance.h" |
18 | 20 | #include "swift/SIL/SILArgument.h" |
19 | 21 | #include "swift/SIL/SILBuilder.h" |
20 | 22 | #include "swift/SIL/SILCloner.h" |
21 | | -#include "swift/SIL/BasicBlockDatastructures.h" |
22 | 23 | #include "swift/SILOptimizer/PassManager/Passes.h" |
23 | 24 | #include "swift/SILOptimizer/PassManager/Transforms.h" |
24 | 25 | #include "swift/SILOptimizer/Utils/InstOptUtils.h" |
|
27 | 28 | #include "swift/SILOptimizer/Utils/StackNesting.h" |
28 | 29 | #include "swift/SILOptimizer/Utils/ValueLifetime.h" |
29 | 30 | #include "llvm/ADT/DenseMap.h" |
| 31 | +#include "llvm/ADT/STLExtras.h" |
30 | 32 | #include "llvm/ADT/SmallPtrSet.h" |
31 | 33 | #include "llvm/ADT/SmallSet.h" |
32 | 34 | #include "llvm/ADT/SmallVector.h" |
@@ -538,13 +540,35 @@ static bool rewriteAllocBoxAsAllocStack(AllocBoxInst *ABI) { |
538 | 540 | SILBuilderWithScope Builder(ABI); |
539 | 541 | assert(ABI->getBoxType()->getLayout()->getFields().size() == 1 |
540 | 542 | && "rewriting multi-field box not implemented"); |
541 | | - auto &mod = ABI->getFunction()->getModule(); |
542 | | - bool isLexical = mod.getASTContext().SILOpts.supportsLexicalLifetimes(mod); |
543 | | - auto *ASI = Builder.createAllocStack( |
544 | | - ABI->getLoc(), |
545 | | - getSILBoxFieldType(TypeExpansionContext(*ABI->getFunction()), |
546 | | - ABI->getBoxType(), ABI->getModule().Types, 0), |
547 | | - ABI->getVarInfo(), ABI->hasDynamicLifetime(), isLexical); |
| 543 | + auto ty = getSILBoxFieldType(TypeExpansionContext(*ABI->getFunction()), |
| 544 | + ABI->getBoxType(), ABI->getModule().Types, 0); |
| 545 | + auto isLexical = [&]() -> bool { |
| 546 | + auto &mod = ABI->getFunction()->getModule(); |
| 547 | + bool lexicalLifetimesEnabled = |
| 548 | + mod.getASTContext().SILOpts.supportsLexicalLifetimes(mod); |
| 549 | + if (!lexicalLifetimesEnabled) |
| 550 | + return false; |
| 551 | + // Look for lexical borrows of the alloc_box. |
| 552 | + GraphNodeWorklist<Operand *, 4> worklist; |
| 553 | + worklist.initializeRange(ABI->getUses()); |
| 554 | + while (auto *use = worklist.pop()) { |
| 555 | + // See through mark_uninitialized and non-lexical begin_borrow |
| 556 | + // instructions. It's verified that lexical begin_borrows of SILBoxType |
| 557 | + // values originate either from AllocBoxInsts or SILFunctionArguments. |
| 558 | + if (auto *mui = dyn_cast<MarkUninitializedInst>(use->getUser())) { |
| 559 | + for (auto *use : mui->getUses()) |
| 560 | + worklist.insert(use); |
| 561 | + } else if (auto *bbi = dyn_cast<BeginBorrowInst>(use->getUser())) { |
| 562 | + if (bbi->isLexical()) |
| 563 | + return true; |
| 564 | + for (auto *use : bbi->getUses()) |
| 565 | + worklist.insert(use); |
| 566 | + } |
| 567 | + } |
| 568 | + return false; |
| 569 | + }; |
| 570 | + auto *ASI = Builder.createAllocStack(ABI->getLoc(), ty, ABI->getVarInfo(), |
| 571 | + ABI->hasDynamicLifetime(), isLexical()); |
548 | 572 |
|
549 | 573 | // Transfer a mark_uninitialized if we have one. |
550 | 574 | SILValue StackBox = ASI; |
|
0 commit comments