19
19
#include " swift/SIL/SILCloner.h"
20
20
#include " swift/SILOptimizer/PassManager/Transforms.h"
21
21
#include " swift/SILOptimizer/Utils/Local.h"
22
+ #include " swift/SILOptimizer/Utils/StackNesting.h"
22
23
#include " llvm/ADT/DenseMap.h"
23
24
#include " llvm/ADT/SmallPtrSet.h"
24
25
#include " llvm/ADT/SmallSet.h"
@@ -395,8 +396,7 @@ static bool canPromoteAllocBox(AllocBoxInst *ABI,
395
396
396
397
// / rewriteAllocBoxAsAllocStack - Replace uses of the alloc_box with a
397
398
// / new alloc_stack, but do not delete the alloc_box yet.
398
- static bool rewriteAllocBoxAsAllocStack (AllocBoxInst *ABI,
399
- llvm::SmallVectorImpl<TermInst *> &Returns) {
399
+ static bool rewriteAllocBoxAsAllocStack (AllocBoxInst *ABI) {
400
400
DEBUG (llvm::dbgs () << " *** Promoting alloc_box to stack: " << *ABI);
401
401
402
402
llvm::SmallVector<SILInstruction*, 4 > FinalReleases;
@@ -405,8 +405,7 @@ static bool rewriteAllocBoxAsAllocStack(AllocBoxInst *ABI,
405
405
406
406
// Promote this alloc_box to an alloc_stack. Insert the alloc_stack
407
407
// at the beginning of the function.
408
- auto &Entry = ABI->getFunction ()->front ();
409
- SILBuilder BuildAlloc (&Entry, Entry.begin ());
408
+ SILBuilder BuildAlloc (ABI);
410
409
BuildAlloc.setCurrentDebugScope (ABI->getDebugScope ());
411
410
assert (ABI->getBoxType ()->getLayout ()->getFields ().size () == 1
412
411
&& " rewriting multi-field box not implemented" );
@@ -440,25 +439,18 @@ static bool rewriteAllocBoxAsAllocStack(AllocBoxInst *ABI,
440
439
.getTypeLowering (ABI->getBoxType ()->getFieldType (ABI->getModule (), 0 ));
441
440
auto Loc = CleanupLocation::get (ABI->getLoc ());
442
441
443
- // For non-trivial types, insert destroys for each final release-like
444
- // instruction we found that isn't an explicit dealloc_box.
445
- if (!Lowering.isTrivial ()) {
446
- for (auto LastRelease : FinalReleases) {
447
- if (isa<DeallocBoxInst>(LastRelease))
448
- continue ;
449
-
450
- SILBuilderWithScope BuildDestroy (LastRelease);
451
- BuildDestroy.emitDestroyAddrAndFold (Loc, PointerResult);
442
+ for (auto LastRelease : FinalReleases) {
443
+ SILBuilderWithScope Builder (LastRelease);
444
+ if (!isa<DeallocBoxInst>(LastRelease)&& !Lowering.isTrivial ()) {
445
+ // For non-trivial types, insert destroys for each final release-like
446
+ // instruction we found that isn't an explicit dealloc_box.
447
+ Builder.emitDestroyAddrAndFold (Loc, PointerResult);
452
448
}
449
+ Builder.createDeallocStack (Loc, ASI);
453
450
}
454
451
455
- for (auto Return : Returns) {
456
- SILBuilderWithScope BuildDealloc (Return);
457
- BuildDealloc.createDeallocStack (Loc, ASI);
458
- }
459
-
460
- // Remove any retain and release instructions. Since all uses of result #1
461
- // are gone, this only walks through uses of result #0 (the retain count
452
+ // Remove any retain and release instructions. Since all uses of project_box
453
+ // are gone, this only walks through uses of the box itself (the retain count
462
454
// pointer).
463
455
while (!ABI->use_empty ()) {
464
456
auto *User = (*ABI->use_begin ())->getUser ();
@@ -825,7 +817,6 @@ rewritePartialApplies(llvm::SmallVectorImpl<Operand *> &PromotedOperands,
825
817
static unsigned
826
818
rewritePromotedBoxes (llvm::SmallVectorImpl<AllocBoxInst *> &Promoted,
827
819
llvm::SmallVectorImpl<Operand *> &PromotedOperands,
828
- llvm::SmallVectorImpl<TermInst *> &Returns,
829
820
bool &CFGChanged) {
830
821
// First we'll rewrite any partial applies that we can to remove the
831
822
// box container pointer from the operands.
@@ -835,7 +826,7 @@ rewritePromotedBoxes(llvm::SmallVectorImpl<AllocBoxInst *> &Promoted,
835
826
auto rend = Promoted.rend ();
836
827
for (auto I = Promoted.rbegin (); I != rend; ++I) {
837
828
auto *ABI = *I;
838
- if (rewriteAllocBoxAsAllocStack (ABI, Returns )) {
829
+ if (rewriteAllocBoxAsAllocStack (ABI)) {
839
830
++Count;
840
831
ABI->eraseFromParent ();
841
832
}
@@ -849,13 +840,8 @@ class AllocBoxToStack : public SILFunctionTransform {
849
840
void run () override {
850
841
llvm::SmallVector<AllocBoxInst *, 8 > Promotable;
851
842
llvm::SmallVector<Operand *, 8 > PromotedOperands;
852
- llvm::SmallVector<TermInst *, 8 > Returns;
853
843
854
844
for (auto &BB : *getFunction ()) {
855
- auto *Term = BB.getTerminator ();
856
- if (Term->isFunctionExiting ())
857
- Returns.push_back (Term);
858
-
859
845
for (auto &I : BB)
860
846
if (auto *ABI = dyn_cast<AllocBoxInst>(&I))
861
847
if (canPromoteAllocBox (ABI, PromotedOperands))
@@ -864,9 +850,14 @@ class AllocBoxToStack : public SILFunctionTransform {
864
850
865
851
if (!Promotable.empty ()) {
866
852
bool CFGChanged = false ;
867
- auto Count = rewritePromotedBoxes (Promotable, PromotedOperands, Returns,
853
+ auto Count = rewritePromotedBoxes (Promotable, PromotedOperands,
868
854
CFGChanged);
869
855
NumStackPromoted += Count;
856
+ if (Count) {
857
+ StackNesting SN;
858
+ if (SN.correctStackNesting (getFunction ()) == StackNesting::Changes::CFG)
859
+ CFGChanged = true ;
860
+ }
870
861
871
862
invalidateAnalysis (CFGChanged ?
872
863
SILAnalysis::InvalidationKind::FunctionBody :
0 commit comments