diff options
author | John McCall <rjmccall@apple.com> | 2010-08-13 21:20:51 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-08-13 21:20:51 +0000 |
commit | cd2d2b7814e0104ed41a8da159a06a8ca77b70d8 (patch) | |
tree | aded9c80726d4e0490a0ac59fc7d249ddb04ea85 /lib/CodeGen/CodeGenFunction.cpp | |
parent | 05eac86d547892847ca95b5350e28d681150fa68 (diff) |
Sketch out a framework for delaying the activation of a cleanup.
Not yet complete or used.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111044 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r-- | lib/CodeGen/CodeGenFunction.cpp | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index e5cfa624b2..b3ac8f1ddb 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -1275,6 +1275,73 @@ void CodeGenFunction::ResolveBranchFixups(llvm::BasicBlock *Block) { 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 = |