@@ -164,6 +164,11 @@ class MemoryToRegisters {
164
164
// / AllocStackInst itself!
165
165
void removeSingleBlockAllocation (AllocStackInst *ASI);
166
166
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);
167
172
public:
168
173
// / C'tor
169
174
MemoryToRegisters (SILFunction &Func, DominanceInfo *Dt) : F(Func), DT(Dt),
@@ -821,6 +826,61 @@ void StackAllocationPromoter::run() {
821
826
promoteAllocationToPhi ();
822
827
}
823
828
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
+
824
884
bool MemoryToRegisters::run () {
825
885
bool Changed = false ;
826
886
@@ -840,68 +900,14 @@ bool MemoryToRegisters::run() {
840
900
continue ;
841
901
}
842
902
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 ())
877
907
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++;
887
909
Changed = true ;
888
- continue ;
889
910
}
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 ;
905
911
}
906
912
}
907
913
return Changed;
0 commit comments