diff options
Diffstat (limited to 'lib/CodeGen/CGCleanup.cpp')
| -rw-r--r-- | lib/CodeGen/CGCleanup.cpp | 46 | 
1 files changed, 36 insertions, 10 deletions
diff --git a/lib/CodeGen/CGCleanup.cpp b/lib/CodeGen/CGCleanup.cpp index 18ed3e543d204..d97e40554ef20 100644 --- a/lib/CodeGen/CGCleanup.cpp +++ b/lib/CodeGen/CGCleanup.cpp @@ -52,8 +52,10 @@ DominatingValue<RValue>::saved_type::save(CodeGenFunction &CGF, RValue rv) {        llvm::StructType::get(V.first->getType(), V.second->getType(),                              (void*) nullptr);      llvm::Value *addr = CGF.CreateTempAlloca(ComplexTy, "saved-complex"); -    CGF.Builder.CreateStore(V.first, CGF.Builder.CreateStructGEP(addr, 0)); -    CGF.Builder.CreateStore(V.second, CGF.Builder.CreateStructGEP(addr, 1)); +    CGF.Builder.CreateStore(V.first, +                            CGF.Builder.CreateStructGEP(ComplexTy, addr, 0)); +    CGF.Builder.CreateStore(V.second, +                            CGF.Builder.CreateStructGEP(ComplexTy, addr, 1));      return saved_type(addr, ComplexAddress);    } @@ -82,9 +84,9 @@ RValue DominatingValue<RValue>::saved_type::restore(CodeGenFunction &CGF) {      return RValue::getAggregate(CGF.Builder.CreateLoad(Value));    case ComplexAddress: {      llvm::Value *real = -      CGF.Builder.CreateLoad(CGF.Builder.CreateStructGEP(Value, 0)); +        CGF.Builder.CreateLoad(CGF.Builder.CreateStructGEP(nullptr, Value, 0));      llvm::Value *imag = -      CGF.Builder.CreateLoad(CGF.Builder.CreateStructGEP(Value, 1)); +        CGF.Builder.CreateLoad(CGF.Builder.CreateStructGEP(nullptr, Value, 1));      return RValue::getComplex(real, imag);    }    } @@ -123,6 +125,17 @@ char *EHScopeStack::allocate(size_t Size) {    return StartOfData;  } +bool EHScopeStack::containsOnlyLifetimeMarkers( +    EHScopeStack::stable_iterator Old) const { +  for (EHScopeStack::iterator it = begin(); stabilize(it) != Old; it++) { +    EHCleanupScope *cleanup = dyn_cast<EHCleanupScope>(&*it); +    if (!cleanup || !cleanup->isLifetimeMarker()) +      return false; +  } + +  return true; +} +  EHScopeStack::stable_iterator  EHScopeStack::getInnermostActiveNormalCleanup() const {    for (stable_iterator si = getInnermostNormalCleanup(), se = stable_end(); @@ -469,8 +482,14 @@ static void EmitCleanup(CodeGenFunction &CGF,                          EHScopeStack::Cleanup *Fn,                          EHScopeStack::Cleanup::Flags flags,                          llvm::Value *ActiveFlag) { -  // EH cleanups always occur within a terminate scope. -  if (flags.isForEHCleanup()) CGF.EHStack.pushTerminate(); +  // Itanium EH cleanups occur within a terminate scope. Microsoft SEH doesn't +  // have this behavior, and the Microsoft C++ runtime will call terminate for +  // us if the cleanup throws. +  bool PushedTerminate = false; +  if (flags.isForEHCleanup() && !CGF.getTarget().getCXXABI().isMicrosoft()) { +    CGF.EHStack.pushTerminate(); +    PushedTerminate = true; +  }    // If there's an active flag, load it and skip the cleanup if it's    // false. @@ -493,7 +512,8 @@ static void EmitCleanup(CodeGenFunction &CGF,      CGF.EmitBlock(ContBB);    // Leave the terminate scope. -  if (flags.isForEHCleanup()) CGF.EHStack.popTerminate(); +  if (PushedTerminate) +    CGF.EHStack.popTerminate();  }  static void ForwardPrebranchedFallthrough(llvm::BasicBlock *Exit, @@ -739,7 +759,15 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) {            Scope.getNumBranchAfters() == 1) {          assert(!BranchThroughDest || !IsActive); -        // TODO: clean up the possibly dead stores to the cleanup dest slot. +        // Clean up the possibly dead store to the cleanup dest slot. +        llvm::Instruction *NormalCleanupDestSlot = +            cast<llvm::Instruction>(getNormalCleanupDestSlot()); +        if (NormalCleanupDestSlot->hasOneUse()) { +          NormalCleanupDestSlot->user_back()->eraseFromParent(); +          NormalCleanupDestSlot->eraseFromParent(); +          NormalCleanupDest = nullptr; +        } +          llvm::BasicBlock *BranchAfter = Scope.getBranchAfterBlock(0);          InstsToAppend.push_back(llvm::BranchInst::Create(BranchAfter)); @@ -861,8 +889,6 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) {    // Emit the EH cleanup if required.    if (RequiresEHCleanup) { -    ApplyDebugLocation AutoRestoreLocation(*this, CurEHLocation); -      CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();      EmitBlock(EHEntry);  | 
