|
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