[cfe-commits] r111044 - in /cfe/trunk/lib/CodeGen: CGException.cpp CGException.h CodeGenFunction.cpp CodeGenFunction.h
John McCall
rjmccall at apple.com
Fri Aug 13 14:20:51 PDT 2010
Author: rjmccall
Date: Fri Aug 13 16:20:51 2010
New Revision: 111044
URL: http://llvm.org/viewvc/llvm-project?rev=111044&view=rev
Log:
Sketch out a framework for delaying the activation of a cleanup.
Not yet complete or used.
Modified:
cfe/trunk/lib/CodeGen/CGException.cpp
cfe/trunk/lib/CodeGen/CGException.h
cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
cfe/trunk/lib/CodeGen/CodeGenFunction.h
Modified: cfe/trunk/lib/CodeGen/CGException.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGException.cpp?rev=111044&r1=111043&r2=111044&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGException.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGException.cpp Fri Aug 13 16:20:51 2010
@@ -73,11 +73,13 @@
void *EHScopeStack::pushCleanup(CleanupKind Kind, size_t Size) {
assert(((Size % sizeof(void*)) == 0) && "cleanup type is misaligned");
char *Buffer = allocate(EHCleanupScope::getSizeForCleanupSize(Size));
- bool IsNormalCleanup = Kind != EHCleanup;
- bool IsEHCleanup = Kind != NormalCleanup;
+ bool IsNormalCleanup = Kind & NormalCleanup;
+ bool IsEHCleanup = Kind & EHCleanup;
+ bool IsActive = !(Kind & InactiveCleanup);
EHCleanupScope *Scope =
new (Buffer) EHCleanupScope(IsNormalCleanup,
IsEHCleanup,
+ IsActive,
Size,
BranchFixups.size(),
InnermostNormalCleanup,
Modified: cfe/trunk/lib/CodeGen/CGException.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGException.h?rev=111044&r1=111043&r2=111044&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGException.h (original)
+++ cfe/trunk/lib/CodeGen/CGException.h Fri Aug 13 16:20:51 2010
@@ -160,6 +160,12 @@
/// Whether this cleanup needs to be run along exception edges.
bool IsEHCleanup : 1;
+ /// Whether this cleanup was activated before all normal uses.
+ bool ActivatedBeforeNormalUse : 1;
+
+ /// Whether this cleanup was activated before all EH uses.
+ bool ActivatedBeforeEHUse : 1;
+
/// The amount of extra storage needed by the Cleanup.
/// Always a multiple of the scope-stack alignment.
unsigned CleanupSize : 12;
@@ -167,7 +173,7 @@
/// The number of fixups required by enclosing scopes (not including
/// this one). If this is the top cleanup scope, all the fixups
/// from this index onwards belong to this scope.
- unsigned FixupDepth : BitsRemaining - 14;
+ unsigned FixupDepth : BitsRemaining - 16;
/// The nearest normal cleanup scope enclosing this one.
EHScopeStack::stable_iterator EnclosingNormal;
@@ -183,6 +189,14 @@
/// created if needed before the cleanup is popped.
llvm::BasicBlock *EHBlock;
+ /// An optional i1 variable indicating whether this cleanup has been
+ /// activated yet. This has one of three states:
+ /// - it is null if the cleanup is inactive
+ /// - it is activeSentinel() if the cleanup is active and was not
+ /// required before activation
+ /// - it points to a valid variable
+ llvm::AllocaInst *ActiveVar;
+
/// Extra information required for cleanups that have resolved
/// branches through them. This has to be allocated on the side
/// because everything on the cleanup stack has be trivially
@@ -227,15 +241,19 @@
return sizeof(EHCleanupScope) + CleanupSize;
}
- EHCleanupScope(bool IsNormal, bool IsEH, unsigned CleanupSize,
- unsigned FixupDepth,
+ EHCleanupScope(bool IsNormal, bool IsEH, bool IsActive,
+ unsigned CleanupSize, unsigned FixupDepth,
EHScopeStack::stable_iterator EnclosingNormal,
EHScopeStack::stable_iterator EnclosingEH)
: EHScope(EHScope::Cleanup),
IsNormalCleanup(IsNormal), IsEHCleanup(IsEH),
+ ActivatedBeforeNormalUse(IsActive),
+ ActivatedBeforeEHUse(IsActive),
CleanupSize(CleanupSize), FixupDepth(FixupDepth),
EnclosingNormal(EnclosingNormal), EnclosingEH(EnclosingEH),
- NormalBlock(0), EHBlock(0), ExtInfo(0)
+ NormalBlock(0), EHBlock(0),
+ ActiveVar(IsActive ? activeSentinel() : 0),
+ ExtInfo(0)
{
assert(this->CleanupSize == CleanupSize && "cleanup size overflow");
}
@@ -252,6 +270,20 @@
llvm::BasicBlock *getEHBlock() const { return EHBlock; }
void setEHBlock(llvm::BasicBlock *BB) { EHBlock = BB; }
+ static llvm::AllocaInst *activeSentinel() {
+ return reinterpret_cast<llvm::AllocaInst*>(1);
+ }
+
+ bool isActive() const { return ActiveVar != 0; }
+ llvm::AllocaInst *getActiveVar() const { return ActiveVar; }
+ void setActiveVar(llvm::AllocaInst *Var) { ActiveVar = Var; }
+
+ bool wasActivatedBeforeNormalUse() const { return ActivatedBeforeNormalUse; }
+ void setActivatedBeforeNormalUse(bool B) { ActivatedBeforeNormalUse = B; }
+
+ bool wasActivatedBeforeEHUse() const { return ActivatedBeforeEHUse; }
+ void setActivatedBeforeEHUse(bool B) { ActivatedBeforeEHUse = B; }
+
unsigned getFixupDepth() const { return FixupDepth; }
EHScopeStack::stable_iterator getEnclosingNormalCleanup() const {
return EnclosingNormal;
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=111044&r1=111043&r2=111044&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Fri Aug 13 16:20:51 2010
@@ -1275,6 +1275,73 @@
EHStack.popNullFixups();
}
+/// Activate a cleanup that was created in an inactivated state.
+void CodeGenFunction::ActivateCleanup(EHScopeStack::stable_iterator C) {
+ assert(C != EHStack.stable_end() && "activating bottom of stack?");
+ EHCleanupScope &Scope = cast<EHCleanupScope>(*EHStack.find(C));
+ assert(!Scope.isActive() && "double activation");
+
+ // Calculate whether the cleanup was used:
+ bool Used = false;
+
+ // - as a normal cleanup
+ if (Scope.isNormalCleanup()) {
+ bool NormalUsed = false;
+ if (Scope.getNormalBlock()) {
+ NormalUsed = true;
+ } else {
+ // Check whether any enclosed cleanups were needed.
+ for (EHScopeStack::stable_iterator
+ I = EHStack.getInnermostNormalCleanup(); I != C; ) {
+ assert(C.strictlyEncloses(I));
+ EHCleanupScope &S = cast<EHCleanupScope>(*EHStack.find(I));
+ if (S.getNormalBlock()) {
+ NormalUsed = true;
+ break;
+ }
+ I = S.getEnclosingNormalCleanup();
+ }
+ }
+
+ if (NormalUsed)
+ Used = true;
+ else
+ Scope.setActivatedBeforeNormalUse(true);
+ }
+
+ // - as an EH cleanup
+ if (Scope.isEHCleanup()) {
+ bool EHUsed = false;
+ if (Scope.getEHBlock()) {
+ EHUsed = true;
+ } else {
+ // Check whether any enclosed cleanups were needed.
+ for (EHScopeStack::stable_iterator
+ I = EHStack.getInnermostEHCleanup(); I != C; ) {
+ assert(C.strictlyEncloses(I));
+ EHCleanupScope &S = cast<EHCleanupScope>(*EHStack.find(I));
+ if (S.getEHBlock()) {
+ EHUsed = true;
+ break;
+ }
+ I = S.getEnclosingEHCleanup();
+ }
+ }
+
+ if (EHUsed)
+ Used = true;
+ else
+ Scope.setActivatedBeforeEHUse(true);
+ }
+
+ llvm::AllocaInst *Var = EHCleanupScope::activeSentinel();
+ if (Used) {
+ Var = CreateTempAlloca(Builder.getInt1Ty());
+ InitTempAlloca(Var, Builder.getFalse());
+ }
+ Scope.setActiveVar(Var);
+}
+
llvm::Value *CodeGenFunction::getNormalCleanupDestSlot() {
if (!NormalCleanupDest)
NormalCleanupDest =
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=111044&r1=111043&r2=111044&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Fri Aug 13 16:20:51 2010
@@ -96,7 +96,16 @@
llvm::BranchInst *InitialBranch;
};
-enum CleanupKind { NormalAndEHCleanup, EHCleanup, NormalCleanup };
+enum CleanupKind {
+ EHCleanup = 0x1,
+ NormalCleanup = 0x2,
+ NormalAndEHCleanup = EHCleanup | NormalCleanup,
+
+ InactiveCleanup = 0x4,
+ InactiveEHCleanup = EHCleanup | InactiveCleanup,
+ InactiveNormalCleanup = NormalCleanup | InactiveCleanup,
+ InactiveNormalAndEHCleanup = NormalAndEHCleanup | InactiveCleanup
+};
/// A stack of scopes which respond to exceptions, including cleanups
/// and catch blocks.
@@ -520,6 +529,8 @@
/// process all branch fixups.
void PopCleanupBlock(bool FallThroughIsBranchThrough = false);
+ void ActivateCleanup(EHScopeStack::stable_iterator Cleanup);
+
/// \brief Enters a new scope for capturing cleanups, all of which
/// will be executed once the scope is exited.
class RunCleanupsScope {
More information about the cfe-commits
mailing list