aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CodeGenFunction.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-08-13 21:20:51 +0000
committerJohn McCall <rjmccall@apple.com>2010-08-13 21:20:51 +0000
commitcd2d2b7814e0104ed41a8da159a06a8ca77b70d8 (patch)
treeaded9c80726d4e0490a0ac59fc7d249ddb04ea85 /lib/CodeGen/CodeGenFunction.cpp
parent05eac86d547892847ca95b5350e28d681150fa68 (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.cpp67
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 =