aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGCleanup.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CGCleanup.cpp')
-rw-r--r--lib/CodeGen/CGCleanup.cpp40
1 files changed, 26 insertions, 14 deletions
diff --git a/lib/CodeGen/CGCleanup.cpp b/lib/CodeGen/CGCleanup.cpp
index 9e079c65d2..f9ffc9373f 100644
--- a/lib/CodeGen/CGCleanup.cpp
+++ b/lib/CodeGen/CGCleanup.cpp
@@ -251,8 +251,7 @@ void CodeGenFunction::initFullExprCleanup() {
// Initialize it to false at a site that's guaranteed to be run
// before each evaluation.
- llvm::BasicBlock *block = OutermostConditional->getStartingBlock();
- new llvm::StoreInst(Builder.getFalse(), active, &block->back());
+ setBeforeOutermostConditional(Builder.getFalse(), active);
// Initialize it to true at the current location.
Builder.CreateStore(Builder.getTrue(), active);
@@ -1000,14 +999,15 @@ enum ForActivation_t {
/// extra uses *after* the change-over point.
static void SetupCleanupBlockActivation(CodeGenFunction &CGF,
EHScopeStack::stable_iterator C,
- ForActivation_t Kind) {
+ ForActivation_t kind,
+ llvm::Instruction *dominatingIP) {
EHCleanupScope &Scope = cast<EHCleanupScope>(*CGF.EHStack.find(C));
// We always need the flag if we're activating the cleanup in a
// conditional context, because we have to assume that the current
// location doesn't necessarily dominate the cleanup's code.
bool isActivatedInConditional =
- (Kind == ForActivation && CGF.isInConditionalBranch());
+ (kind == ForActivation && CGF.isInConditionalBranch());
bool needFlag = false;
@@ -1030,32 +1030,44 @@ static void SetupCleanupBlockActivation(CodeGenFunction &CGF,
// If it hasn't yet been used as either, we're done.
if (!needFlag) return;
- llvm::AllocaInst *Var = Scope.getActiveFlag();
- if (!Var) {
- Var = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(), "cleanup.isactive");
- Scope.setActiveFlag(Var);
+ llvm::AllocaInst *var = Scope.getActiveFlag();
+ if (!var) {
+ var = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(), "cleanup.isactive");
+ Scope.setActiveFlag(var);
+
+ assert(dominatingIP && "no existing variable and no dominating IP!");
// Initialize to true or false depending on whether it was
// active up to this point.
- CGF.InitTempAlloca(Var, CGF.Builder.getInt1(Kind == ForDeactivation));
+ llvm::Value *value = CGF.Builder.getInt1(kind == ForDeactivation);
+
+ // If we're in a conditional block, ignore the dominating IP and
+ // use the outermost conditional branch.
+ if (CGF.isInConditionalBranch()) {
+ CGF.setBeforeOutermostConditional(value, var);
+ } else {
+ new llvm::StoreInst(value, var, dominatingIP);
+ }
}
- CGF.Builder.CreateStore(CGF.Builder.getInt1(Kind == ForActivation), Var);
+ CGF.Builder.CreateStore(CGF.Builder.getInt1(kind == ForActivation), var);
}
/// Activate a cleanup that was created in an inactivated state.
-void CodeGenFunction::ActivateCleanupBlock(EHScopeStack::stable_iterator C) {
+void CodeGenFunction::ActivateCleanupBlock(EHScopeStack::stable_iterator C,
+ llvm::Instruction *dominatingIP) {
assert(C != EHStack.stable_end() && "activating bottom of stack?");
EHCleanupScope &Scope = cast<EHCleanupScope>(*EHStack.find(C));
assert(!Scope.isActive() && "double activation");
- SetupCleanupBlockActivation(*this, C, ForActivation);
+ SetupCleanupBlockActivation(*this, C, ForActivation, dominatingIP);
Scope.setActive(true);
}
/// Deactive a cleanup that was created in an active state.
-void CodeGenFunction::DeactivateCleanupBlock(EHScopeStack::stable_iterator C) {
+void CodeGenFunction::DeactivateCleanupBlock(EHScopeStack::stable_iterator C,
+ llvm::Instruction *dominatingIP) {
assert(C != EHStack.stable_end() && "deactivating bottom of stack?");
EHCleanupScope &Scope = cast<EHCleanupScope>(*EHStack.find(C));
assert(Scope.isActive() && "double deactivation");
@@ -1071,7 +1083,7 @@ void CodeGenFunction::DeactivateCleanupBlock(EHScopeStack::stable_iterator C) {
}
// Otherwise, follow the general case.
- SetupCleanupBlockActivation(*this, C, ForDeactivation);
+ SetupCleanupBlockActivation(*this, C, ForDeactivation, dominatingIP);
Scope.setActive(false);
}