@@ -45,8 +45,11 @@ namespace swift {
4545// / dealloc_stack %1
4646// / \endcode
4747// /
48+ // / Each allocation must still be properly jointly post-dominated by
49+ // / its deallocations. StackNesting only fixes the nesting of allocations
50+ // / deallocations; it does not insert required deallocations that are
51+ // / missing entirely.
4852class StackNesting {
49-
5053public:
5154
5255 // / The possible return values of fixNesting().
@@ -61,122 +64,6 @@ class StackNesting {
6164 CFG
6265 };
6366
64- private:
65- typedef SmallBitVector BitVector;
66-
67- // / Data stored for each block (actually for each block which is not dead).
68- struct BlockInfo {
69- // / The list of stack allocating/deallocating instructions in the block.
70- llvm::SmallVector<SILInstruction *, 8 > StackInsts;
71-
72- // / The bit-set of alive stack locations at the block entry.
73- BitVector AliveStackLocsAtEntry;
74-
75- // / The bit-set of alive stack locations at the block exit.
76- BitVector AliveStackLocsAtExit;
77-
78- // / Used in the setup function to walk over the CFG.
79- bool visited = false ;
80-
81- // / True for dead-end blocks, i.e. blocks from which there is no path to
82- // / a function exit, e.g. blocks which end with `unreachable` or an
83- // / infinite loop.
84- bool isDeadEnd = false ;
85- };
86-
87- // / Data stored for each stack location (= allocation).
88- // /
89- // / Each stack location is allocated by a single allocation instruction.
90- struct StackLoc {
91- StackLoc (SILInstruction *Alloc) : Alloc(Alloc) {}
92-
93- // / Back-link to the allocation instruction.
94- SILInstruction *Alloc;
95-
96- // / Bit-set which represents all alive locations at this allocation.
97- // / It obviously includes this location itself. And it includes all "outer"
98- // / locations which surround this location.
99- BitVector AliveLocs;
100- };
101-
102- // / Mapping from stack allocations (= locations) to bit numbers.
103- llvm::DenseMap<SILInstruction *, unsigned > StackLoc2BitNumbers;
104-
105- // / The list of stack locations. The index into this array is also the bit
106- // / number in the bit-sets.
107- llvm::SmallVector<StackLoc, 8 > StackLocs;
108-
109- BasicBlockData<BlockInfo> BlockInfos;
110-
111- StackNesting (SILFunction *F) : BlockInfos(F) { }
112-
113- // / Performs correction of stack nesting by moving stack-deallocation
114- // / instructions down the control flow.
115- // /
116- // / Returns the status of what changes were made.
117- Changes run ();
118-
119- // / For debug dumping.
120- void dump () const ;
121-
122- static void dumpBits (const BitVector &Bits);
123-
124- // / Initializes the data structures.
125- void setup ();
126-
127- // / Solves the dataflow problem.
128- // /
129- // / Returns true if there is a nesting of locations in any way, which can
130- // / potentially in the wrong order.
131- bool solve ();
132-
133- bool analyze () {
134- setup ();
135- return solve ();
136- }
137-
138- // / Insert deallocation instructions for all locations which are alive before
139- // / the InsertionPoint (AliveBefore) but not alive after the InsertionPoint
140- // / (AliveAfter).
141- // /
142- // / Returns true if any deallocations were inserted.
143- bool insertDeallocs (const BitVector &AliveBefore, const BitVector &AliveAfter,
144- SILInstruction *InsertionPoint,
145- std::optional<SILLocation> Location);
146-
147- // / Returns the location bit number for a stack allocation instruction.
148- int bitNumberForAlloc (SILInstruction *AllocInst) {
149- assert (AllocInst->isAllocatingStack ());
150- return StackLoc2BitNumbers[AllocInst];
151- }
152-
153- // / Returns the location bit number for a stack deallocation instruction.
154- int bitNumberForDealloc (SILInstruction *DeallocInst) {
155- assert (DeallocInst->isDeallocatingStack ());
156- auto *AllocInst = getAllocForDealloc (DeallocInst);
157- return bitNumberForAlloc (AllocInst);
158- }
159-
160- // / Returns the stack allocation instruction for a stack deallocation
161- // / instruction.
162- SILInstruction *getAllocForDealloc (SILInstruction *Dealloc) const {
163- SILValue op = Dealloc->getOperand (0 );
164- while (auto *mvi = dyn_cast<MoveValueInst>(op)) {
165- op = mvi->getOperand ();
166- }
167- return op->getDefiningInstruction ();
168- }
169-
170- // / Insert deallocations at block boundaries.
171- Changes insertDeallocsAtBlockBoundaries ();
172-
173- // / Modifies the SIL to end up with a correct stack nesting.
174- // /
175- // / Returns the status of what changes were made.
176- Changes adaptDeallocs ();
177-
178- public:
179-
18067 // / Performs correction of stack nesting by moving stack-deallocation
18168 // / instructions down the control flow.
18269 // /
0 commit comments