Skip to content

Commit fae2ec3

Browse files
committed
Assorted minor improvements to the cleanup system.
1 parent 1155ade commit fae2ec3

File tree

5 files changed

+43
-33
lines changed

5 files changed

+43
-33
lines changed

include/swift/Basic/DiverseStack.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,10 +366,14 @@ template <class T> class DiverseStackImpl : private DiverseStackBase {
366366
void pop(stable_iterator stable_iter) {
367367
iterator iter = find(stable_iter);
368368
checkIterator(iter);
369+
#ifndef NDEBUG
369370
while (Begin != iter.Ptr) {
370371
pop();
371372
checkIterator(iter);
372373
}
374+
#else
375+
Begin = iter.Ptr;
376+
#endif
373377
}
374378
};
375379

lib/SILGen/Cleanup.cpp

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -75,45 +75,52 @@ void CleanupManager::popAndEmitCleanup(CleanupHandle handle,
7575

7676
void CleanupManager::emitCleanups(CleanupsDepth depth, CleanupLocation loc,
7777
ForUnwind_t forUnwind, bool popCleanups) {
78-
auto begin = stack.stable_begin();
79-
while (begin != depth) {
80-
auto iter = stack.find(begin);
81-
78+
auto cur = stack.stable_begin();
79+
#ifndef NDEBUG
80+
auto topOfStack = cur;
81+
#endif
82+
while (cur != depth) {
83+
// Copy the cleanup off the stack if it needs to be emitted.
84+
// This is necessary both because we might need to pop the cleanup and
85+
// because the cleanup might push other cleanups that will invalidate
86+
// references onto the stack.
87+
auto iter = stack.find(cur);
8288
Cleanup &stackCleanup = *iter;
89+
Optional<CleanupBuffer> copiedCleanup;
90+
if (stackCleanup.isActive() && SGF.B.hasValidInsertionPoint()) {
91+
copiedCleanup.emplace(stackCleanup);
92+
}
8393

84-
// Copy it off the cleanup stack in case the cleanup pushes a new cleanup
85-
// and the backing storage is re-allocated.
86-
CleanupBuffer buffer(stackCleanup);
87-
Cleanup &cleanup = buffer.getCopy();
88-
89-
// Advance stable iterator.
90-
begin = stack.stabilize(++iter);
94+
// Advance the iterator.
95+
cur = stack.stabilize(++iter);
9196

92-
// Pop now.
93-
if (popCleanups)
97+
// Pop now if that was requested.
98+
if (popCleanups) {
9499
stack.pop();
95100

96-
if (cleanup.isActive() && SGF.B.hasValidInsertionPoint())
97-
cleanup.emit(SGF, loc, forUnwind);
101+
#ifndef NDEBUG
102+
topOfStack = stack.stable_begin();
103+
#endif
104+
}
98105

99-
stack.checkIterator(begin);
106+
// Emit the cleanup.
107+
if (copiedCleanup) {
108+
copiedCleanup->getCopy().emit(SGF, loc, forUnwind);
109+
#ifndef NDEBUG
110+
if (hasAnyActiveCleanups(stack.stable_begin(), topOfStack)) {
111+
copiedCleanup->getCopy().dump(SGF);
112+
llvm_unreachable("cleanup left active cleanups on stack");
113+
}
114+
#endif
115+
}
116+
117+
stack.checkIterator(cur);
100118
}
101119
}
102120

103-
/// Leave a scope, with all its cleanups.
121+
/// Leave a scope, emitting all the cleanups that are currently active.
104122
void CleanupManager::endScope(CleanupsDepth depth, CleanupLocation loc) {
105-
stack.checkIterator(depth);
106-
107-
// FIXME: Thread a branch through the cleanups if there are any active
108-
// cleanups and we have a valid insertion point.
109-
110-
if (!::hasAnyActiveCleanups(stack.begin(), stack.find(depth))) {
111-
return;
112-
}
113-
114-
// Iteratively mark cleanups dead and pop them.
115-
// Maybe we'd get better results if we marked them all dead in one shot?
116-
emitCleanups(depth, loc, NotForUnwind);
123+
emitCleanups(depth, loc, NotForUnwind, /*popCleanups*/ true);
117124
}
118125

119126
bool CleanupManager::hasAnyActiveCleanups(CleanupsDepth from,

lib/SILGen/Cleanup.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,7 @@ class LLVM_LIBRARY_VISIBILITY CleanupManager {
136136

137137
void popTopDeadCleanups(CleanupsDepth end);
138138
void emitCleanups(CleanupsDepth depth, CleanupLocation l,
139-
ForUnwind_t forUnwind,
140-
bool popCleanups=true);
139+
ForUnwind_t forUnwind, bool popCleanups);
141140
void endScope(CleanupsDepth depth, CleanupLocation l);
142141

143142
Cleanup &initCleanup(Cleanup &cleanup, size_t allocSize, CleanupState state);

lib/SILGen/SILGenLValue.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ struct LValueWritebackCleanup : Cleanup {
4747

4848
void emit(SILGenFunction &SGF, CleanupLocation loc,
4949
ForUnwind_t forUnwind) override {
50+
FullExpr scope(SGF.Cleanups, loc);
51+
5052
// TODO: honor forUnwind!
5153
auto &evaluation = *SGF.FormalEvalContext.find(Depth);
5254
assert(evaluation.getKind() == FormalAccess::Exclusive);

lib/SILGen/Scope.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,6 @@ RValue Scope::popPreservingValue(RValue &&rv) {
120120
}
121121

122122
void Scope::popImpl() {
123-
SmallVector<SILValue, 16> cleanupsToPropagateToOuterScope;
124-
125123
cleanups.stack.checkIterator(depth);
126124
cleanups.stack.checkIterator(cleanups.innermostScope);
127125
assert(cleanups.innermostScope == depth && "popping scopes out of order");

0 commit comments

Comments
 (0)