mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[silgen] Create CleanupManager::dump and the relevant dump methods to dump the current cleanups.
This is useful to discover when a specific cleanup is being eliminated while debugging. The implementation is compiled out when assertions are disabled. rdar://29791263
This commit is contained in:
@@ -116,6 +116,8 @@ public:
|
||||
return Depth != (std::size_t) -1;
|
||||
}
|
||||
|
||||
std::size_t getDepth() const { return Depth; }
|
||||
|
||||
/// A helper class that wraps a stable_iterator as something that
|
||||
/// pretends to be a non-null pointer.
|
||||
///
|
||||
|
||||
@@ -232,3 +232,32 @@ void CleanupStateRestorationScope::pop() {
|
||||
cleanup.setState(stateToRestore);
|
||||
}
|
||||
}
|
||||
|
||||
llvm::raw_ostream &Lowering::operator<<(llvm::raw_ostream &os,
|
||||
CleanupState state) {
|
||||
switch (state) {
|
||||
case CleanupState::Dormant:
|
||||
return os << "Dormant";
|
||||
case CleanupState::Dead:
|
||||
return os << "Dead";
|
||||
case CleanupState::Active:
|
||||
return os << "Active";
|
||||
case CleanupState::PersistentlyActive:
|
||||
return os << "PersistentlyActive";
|
||||
}
|
||||
}
|
||||
|
||||
void CleanupManager::dump() const {
|
||||
#ifndef NDEBUG
|
||||
auto begin = Stack.stable_begin();
|
||||
auto end = Stack.stable_end();
|
||||
while (begin != end) {
|
||||
auto iter = Stack.find(begin);
|
||||
const Cleanup &stackCleanup = *iter;
|
||||
llvm::errs() << "CLEANUP DEPTH: " << begin.getDepth() << "\n";
|
||||
stackCleanup.dump();
|
||||
begin = Stack.stabilize(++iter);
|
||||
Stack.checkIterator(begin);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -52,6 +52,8 @@ enum class CleanupState {
|
||||
PersistentlyActive
|
||||
};
|
||||
|
||||
llvm::raw_ostream &operator<<(raw_ostream &os, CleanupState state);
|
||||
|
||||
class LLVM_LIBRARY_VISIBILITY Cleanup {
|
||||
unsigned allocatedSize;
|
||||
CleanupState state;
|
||||
@@ -72,6 +74,7 @@ public:
|
||||
bool isDead() const { return state == CleanupState::Dead; }
|
||||
|
||||
virtual void emit(SILGenFunction &Gen, CleanupLocation L) = 0;
|
||||
virtual void dump() const = 0;
|
||||
};
|
||||
|
||||
/// A cleanup depth is generally used to denote the set of cleanups
|
||||
@@ -198,6 +201,9 @@ public:
|
||||
/// True if there are any active cleanups in the scope between the specified
|
||||
/// cleanup handle and the current top of stack.
|
||||
bool hasAnyActiveCleanups(CleanupsDepth from);
|
||||
|
||||
/// Dump the output of each cleanup on this stack.
|
||||
void dump() const;
|
||||
};
|
||||
|
||||
/// An RAII object that allows the state of a cleanup to be
|
||||
|
||||
@@ -3805,6 +3805,14 @@ public:
|
||||
void emit(SILGenFunction &gen, CleanupLocation l) override {
|
||||
gen.B.createDeallocBox(l, box);
|
||||
}
|
||||
|
||||
void dump() const override {
|
||||
#ifndef NDEBUG
|
||||
llvm::errs() << "DeallocateUninitializedBox "
|
||||
<< "State:" << getState() << " "
|
||||
<< "Box: " << box << "\n";
|
||||
#endif
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
@@ -4922,6 +4930,14 @@ namespace {
|
||||
void emit(SILGenFunction &gen, CleanupLocation l) override {
|
||||
gen.emitUninitializedArrayDeallocation(l, Array);
|
||||
}
|
||||
|
||||
void dump() const override {
|
||||
#ifndef NDEBUG
|
||||
llvm::errs() << "DeallocateUninitializedArray "
|
||||
<< "State:" << getState() << " "
|
||||
<< "Array:" << Array << "\n";
|
||||
#endif
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
|
||||
@@ -120,6 +120,13 @@ namespace {
|
||||
void emit(SILGenFunction &gen, CleanupLocation l) override {
|
||||
gen.B.emitDestroyValueOperation(l, closure);
|
||||
}
|
||||
void dump() const override {
|
||||
#ifndef NDEBUG
|
||||
llvm::errs() << "CleanupClosureConstant\n"
|
||||
<< "State:" << getState() << "\n"
|
||||
<< "closure:" << closure << "\n";
|
||||
#endif
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
@@ -214,6 +221,15 @@ public:
|
||||
void emit(SILGenFunction &gen, CleanupLocation l) override {
|
||||
gen.B.createEndBorrow(l, borrowed, original);
|
||||
}
|
||||
|
||||
void dump() const override {
|
||||
#ifndef NDEBUG
|
||||
llvm::errs() << "EndBorrowCleanup "
|
||||
<< "State:" << getState() << "\n"
|
||||
<< "original:" << original << "\n"
|
||||
<< "borrowed:" << borrowed << "\n";
|
||||
#endif
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
@@ -229,6 +245,14 @@ public:
|
||||
else
|
||||
gen.B.emitDestroyValueOperation(l, v);
|
||||
}
|
||||
|
||||
void dump() const override {
|
||||
#ifndef NDEBUG
|
||||
llvm::errs() << "ReleaseValueCleanup\n"
|
||||
<< "State:" << getState() << "\n"
|
||||
<< "Value:" << v << "\n";
|
||||
#endif
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
@@ -242,6 +266,14 @@ public:
|
||||
void emit(SILGenFunction &gen, CleanupLocation l) override {
|
||||
gen.B.createDeallocStack(l, Addr);
|
||||
}
|
||||
|
||||
void dump() const override {
|
||||
#ifndef NDEBUG
|
||||
llvm::errs() << "DeallocStackCleanup\n"
|
||||
<< "State:" << getState() << "\n"
|
||||
<< "Addr:" << Addr << "\n";
|
||||
#endif
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
@@ -255,6 +287,15 @@ public:
|
||||
void emit(SILGenFunction &gen, CleanupLocation l) override {
|
||||
gen.destroyLocalVariable(l, Var);
|
||||
}
|
||||
|
||||
void dump() const override {
|
||||
#ifndef NDEBUG
|
||||
llvm::errs() << "DestroyLocalVariable\n"
|
||||
<< "State:" << getState() << "\n";
|
||||
// TODO: Make sure we dump var.
|
||||
llvm::errs() << "\n";
|
||||
#endif
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
@@ -268,6 +309,15 @@ public:
|
||||
void emit(SILGenFunction &gen, CleanupLocation l) override {
|
||||
gen.deallocateUninitializedLocalVariable(l, Var);
|
||||
}
|
||||
|
||||
void dump() const override {
|
||||
#ifndef NDEBUG
|
||||
llvm::errs() << "DeallocateUninitializedLocalVariable\n"
|
||||
<< "State:" << getState() << "\n";
|
||||
// TODO: Make sure we dump var.
|
||||
llvm::errs() << "\n";
|
||||
#endif
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
@@ -1196,6 +1246,14 @@ namespace {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void dump() const override {
|
||||
#ifndef NDEBUG
|
||||
llvm::errs() << "DeinitExistentialCleanup\n"
|
||||
<< "State:" << getState() << "\n"
|
||||
<< "Value:" << existentialAddr << "\n";
|
||||
#endif
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
|
||||
@@ -93,6 +93,13 @@ namespace {
|
||||
void emit(SILGenFunction &gen, CleanupLocation loc) override {
|
||||
gen.getWritebackStack()[Depth].performWriteback(gen, /*isFinal*/ false);
|
||||
}
|
||||
|
||||
void dump() const override {
|
||||
#ifndef NDEBUG
|
||||
llvm::errs() << "LValueWritebackCleanup\n"
|
||||
<< "State: " << getState() << "Depth: " << Depth << "\n";
|
||||
#endif
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
|
||||
@@ -746,6 +746,12 @@ namespace {
|
||||
void emit(SILGenFunction &gen, CleanupLocation loc) override {
|
||||
gen.B.createDeallocValueBuffer(loc, ValueType, Buffer);
|
||||
}
|
||||
void dump() const override {
|
||||
#ifndef NDEBUG
|
||||
llvm::errs() << "DeallocateValueBuffer\n"
|
||||
<< "State: " << getState() << "Buffer: " << Buffer << "\n";
|
||||
#endif
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
|
||||
@@ -64,6 +64,12 @@ public:
|
||||
void emit(SILGenFunction &gen, CleanupLocation l) override {
|
||||
gen.B.emitDestroyValueOperation(l, box);
|
||||
}
|
||||
void dump() const override {
|
||||
#ifndef NDEBUG
|
||||
llvm::errs() << "DeallocateValueBuffer\n"
|
||||
<< "State: " << getState() << "box: " << box << "\n";
|
||||
#endif
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
|
||||
@@ -405,6 +405,12 @@ namespace {
|
||||
void emit(SILGenFunction &SGF, CleanupLocation l) override {
|
||||
assert(false && "Sema didn't catch exit out of a defer?");
|
||||
}
|
||||
void dump() const override {
|
||||
#ifndef NDEBUG
|
||||
llvm::errs() << "DeferEscapeCheckerCleanup\n"
|
||||
<< "State: " << getState() << "\n";
|
||||
#endif
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
@@ -425,6 +431,12 @@ namespace {
|
||||
if (SGF.B.hasValidInsertionPoint())
|
||||
SGF.Cleanups.setCleanupState(TheCleanup, CleanupState::Dead);
|
||||
}
|
||||
void dump() const override {
|
||||
#ifndef NDEBUG
|
||||
llvm::errs() << "DeferCleanup\n"
|
||||
<< "State: " << getState() << "\n";
|
||||
#endif
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
|
||||
Reference in New Issue
Block a user