Skip to content

Commit 47fbb05

Browse files
committed
Refactor the body of the mem2reg transformation out to a helper function
to reduce indentation and simplify the logic, NFC.
1 parent ba7ed9a commit 47fbb05

File tree

1 file changed

+65
-59
lines changed

1 file changed

+65
-59
lines changed

lib/SILOptimizer/Transforms/SILMem2Reg.cpp

Lines changed: 65 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,11 @@ class MemoryToRegisters {
164164
/// AllocStackInst itself!
165165
void removeSingleBlockAllocation(AllocStackInst *ASI);
166166

167+
/// Attempt to promote the specified stack allocation, returning true if so
168+
/// or false if not. On success, all uses of the AllocStackInst have been
169+
/// removed, but the ASI itself is still in the program.
170+
bool promoteSingleAllocation(AllocStackInst *ASI,
171+
DomTreeLevelMap &DomTreeLevels);
167172
public:
168173
/// C'tor
169174
MemoryToRegisters(SILFunction &Func, DominanceInfo *Dt) : F(Func), DT(Dt),
@@ -821,6 +826,61 @@ void StackAllocationPromoter::run() {
821826
promoteAllocationToPhi();
822827
}
823828

829+
/// Attempt to promote the specified stack allocation, returning true if so
830+
/// or false if not. On success, this returns true and usually drops all of the
831+
/// uses of the AllocStackInst, but never deletes the ASI itself. Callers
832+
/// should check to see if the ASI is dead after this and remove it if so.
833+
bool MemoryToRegisters::promoteSingleAllocation(AllocStackInst *alloc,
834+
DomTreeLevelMap &DomTreeLevels){
835+
DEBUG(llvm::dbgs() << "*** Memory to register looking at: " << *alloc);
836+
NumAllocStackFound++;
837+
838+
// Don't handle captured AllocStacks.
839+
bool inSingleBlock = false;
840+
if (isCaptured(alloc, inSingleBlock)) {
841+
NumAllocStackCaptured++;
842+
return false;
843+
}
844+
845+
// Remove write-only AllocStacks.
846+
if (isWriteOnlyAllocation(alloc)) {
847+
eraseUsesOfInstruction(alloc);
848+
849+
DEBUG(llvm::dbgs() << "*** Deleting store-only AllocStack: " << *alloc);
850+
return true;
851+
}
852+
853+
// For AllocStacks that are only used within a single basic blocks, use
854+
// the linear sweep to remove the AllocStack.
855+
if (inSingleBlock) {
856+
removeSingleBlockAllocation(alloc);
857+
858+
DEBUG(llvm::dbgs() << "*** Deleting single block AllocStackInst: "
859+
<< *alloc);
860+
if (!alloc->use_empty()) {
861+
// Handle a corner case where the ASI still has uses:
862+
// This can come up if the source contains a withUnsafePointer where
863+
// the pointer escapes. It's illegal code but we should not crash.
864+
// Re-insert a dealloc_stack so that the verifier is happy.
865+
B.setInsertionPoint(std::next(alloc->getIterator()));
866+
B.createDeallocStack(alloc->getLoc(), alloc);
867+
}
868+
return true;
869+
}
870+
871+
DEBUG(llvm::dbgs() << "*** Need to insert BB arguments for " << *alloc);
872+
873+
// Promote this allocation.
874+
StackAllocationPromoter(alloc, DT, DomTreeLevels, B).run();
875+
876+
// Make sure that all of the allocations were promoted into registers.
877+
assert(isWriteOnlyAllocation(alloc) && "Non-write uses left behind");
878+
// ... and erase the allocation.
879+
eraseUsesOfInstruction(alloc);
880+
return true;
881+
}
882+
883+
824884
bool MemoryToRegisters::run() {
825885
bool Changed = false;
826886

@@ -840,68 +900,14 @@ bool MemoryToRegisters::run() {
840900
continue;
841901
}
842902

843-
DEBUG(llvm::dbgs() << "*** Memory to register looking at: " << *I);
844-
NumAllocStackFound++;
845-
846-
// Don't handle captured AllocStacks.
847-
bool inSingleBlock = false;
848-
if (isCaptured(ASI, inSingleBlock)) {
849-
NumAllocStackCaptured++;
850-
++I;
851-
continue;
852-
}
853-
854-
// Remove write-only AllocStacks.
855-
if (isWriteOnlyAllocation(ASI)) {
856-
eraseUsesOfInstruction(ASI);
857-
858-
DEBUG(llvm::dbgs() << "*** Deleting store-only AllocStack: " << *ASI);
859-
I++;
860-
ASI->eraseFromParent();
861-
Changed = true;
862-
NumInstRemoved++;
863-
continue;
864-
}
865-
866-
// For AllocStacks that are only used within a single basic blocks, use
867-
// the linear sweep to remove the AllocStack.
868-
if (inSingleBlock) {
869-
removeSingleBlockAllocation(ASI);
870-
871-
DEBUG(llvm::dbgs() << "*** Deleting single block AllocStackInst: "
872-
<< *ASI);
873-
I++;
874-
if (ASI->use_empty()) {
875-
// After removing all the allocation instructions the ASI should not
876-
// have any uses.
903+
bool promoted = promoteSingleAllocation(ASI, DomTreeLevels);
904+
++I;
905+
if (promoted) {
906+
if (ASI->use_empty())
877907
ASI->eraseFromParent();
878-
NumInstRemoved++;
879-
} else {
880-
// Handle a corner case where the ASI still has uses:
881-
// This can come up if the source contains a withUnsafePointer where
882-
// the pointer escapes. It's illegal code but we should not crash.
883-
// Re-insert a dealloc_stack so that the verifier is happy.
884-
B.setInsertionPoint(std::next(ASI->getIterator()));
885-
B.createDeallocStack(ASI->getLoc(), ASI);
886-
}
908+
NumInstRemoved++;
887909
Changed = true;
888-
continue;
889910
}
890-
891-
DEBUG(llvm::dbgs() << "*** Need to insert Phis for " << *ASI);
892-
893-
// Promote this allocation.
894-
StackAllocationPromoter(ASI, DT, DomTreeLevels, B).run();
895-
896-
// Make sure that all of the allocations were promoted into registers.
897-
assert(isWriteOnlyAllocation(ASI) && "Non-write uses left behind");
898-
// ... and erase the allocation.
899-
eraseUsesOfInstruction(ASI);
900-
901-
I++;
902-
ASI->eraseFromParent();
903-
NumInstRemoved++;
904-
Changed = true;
905911
}
906912
}
907913
return Changed;

0 commit comments

Comments
 (0)