From: John McCall Date: Sat, 14 Aug 2010 07:46:19 +0000 (+0000) Subject: More cleanup enabling. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=838d796d020f6a8cd2b2d1e2a0a85c83bbf29543;p=clang More cleanup enabling. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111070 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGException.h b/lib/CodeGen/CGException.h index f40e3e32c2..f1294746a4 100644 --- a/lib/CodeGen/CGException.h +++ b/lib/CodeGen/CGException.h @@ -565,6 +565,28 @@ EHScopeStack::stabilize(iterator ir) const { return stable_iterator(EndOfBuffer - ir.Ptr); } +inline EHScopeStack::stable_iterator +EHScopeStack::getInnermostActiveNormalCleanup() const { + for (EHScopeStack::stable_iterator + I = getInnermostNormalCleanup(), E = stable_end(); I != E; ) { + EHCleanupScope &S = cast(*find(I)); + if (S.isActive()) return I; + I = S.getEnclosingNormalCleanup(); + } + return stable_end(); +} + +inline EHScopeStack::stable_iterator +EHScopeStack::getInnermostActiveEHCleanup() const { + for (EHScopeStack::stable_iterator + I = getInnermostEHCleanup(), E = stable_end(); I != E; ) { + EHCleanupScope &S = cast(*find(I)); + if (S.isActive()) return I; + I = S.getEnclosingEHCleanup(); + } + return stable_end(); +} + } } diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index b3ac8f1ddb..5bee016d7e 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -805,6 +805,7 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { assert(isa(*EHStack.begin()) && "top not a cleanup!"); EHCleanupScope &Scope = cast(*EHStack.begin()); assert(Scope.getFixupDepth() <= EHStack.getNumBranchFixups()); + assert(Scope.isActive() && "cleanup was still inactive when popped!"); // Check whether we need an EH cleanup. This is only true if we've // generated a lazy EH cleanup block. @@ -1100,11 +1101,15 @@ void CodeGenFunction::EmitBranchThroughCleanup(JumpDest Dest) { // Create the branch. llvm::BranchInst *BI = Builder.CreateBr(Dest.getBlock()); - // If we're not in a cleanup scope, or if the destination scope is - // the current normal-cleanup scope, we don't need to worry about - // fixups. - if (!EHStack.hasNormalCleanups() || - Dest.getScopeDepth() == EHStack.getInnermostNormalCleanup()) { + // Calculate the innermost active normal cleanup. + EHScopeStack::stable_iterator + TopCleanup = EHStack.getInnermostActiveNormalCleanup(); + + // If we're not in an active normal cleanup scope, or if the + // destination scope is within the innermost active normal cleanup + // scope, we don't need to worry about fixups. + if (TopCleanup == EHStack.stable_end() || + TopCleanup.encloses(Dest.getScopeDepth())) { // works for invalid Builder.ClearInsertionPoint(); return; } @@ -1131,12 +1136,12 @@ void CodeGenFunction::EmitBranchThroughCleanup(JumpDest Dest) { // Adjust BI to point to the first cleanup block. { EHCleanupScope &Scope = - cast(*EHStack.find(EHStack.getInnermostNormalCleanup())); + cast(*EHStack.find(TopCleanup)); BI->setSuccessor(0, CreateNormalEntry(*this, Scope)); } // Add this destination to all the scopes involved. - EHScopeStack::stable_iterator I = EHStack.getInnermostNormalCleanup(); + EHScopeStack::stable_iterator I = TopCleanup; EHScopeStack::stable_iterator E = Dest.getScopeDepth(); if (E.strictlyEncloses(I)) { while (true) { @@ -1173,13 +1178,17 @@ void CodeGenFunction::EmitBranchThroughEHCleanup(UnwindDest Dest) { // Create the branch. llvm::BranchInst *BI = Builder.CreateBr(Dest.getBlock()); + // Calculate the innermost active cleanup. + EHScopeStack::stable_iterator + InnermostCleanup = EHStack.getInnermostActiveEHCleanup(); + // If the destination is in the same EH cleanup scope as us, we // don't need to thread through anything. - if (Dest.getScopeDepth() == EHStack.getInnermostEHCleanup()) { + if (InnermostCleanup.encloses(Dest.getScopeDepth())) { Builder.ClearInsertionPoint(); return; } - assert(EHStack.hasEHCleanups()); + assert(InnermostCleanup != EHStack.stable_end()); // Store the index at the start. llvm::ConstantInt *Index = Builder.getInt32(Dest.getDestIndex()); @@ -1188,14 +1197,13 @@ void CodeGenFunction::EmitBranchThroughEHCleanup(UnwindDest Dest) { // Adjust BI to point to the first cleanup block. { EHCleanupScope &Scope = - cast(*EHStack.find(EHStack.getInnermostEHCleanup())); + cast(*EHStack.find(InnermostCleanup)); BI->setSuccessor(0, CreateEHEntry(*this, Scope)); } // Add this destination to all the scopes involved. for (EHScopeStack::stable_iterator - I = EHStack.getInnermostEHCleanup(), - E = Dest.getScopeDepth(); ; ) { + I = InnermostCleanup, E = Dest.getScopeDepth(); ; ) { assert(E.strictlyEncloses(I)); EHCleanupScope &Scope = cast(*EHStack.find(I)); assert(Scope.isEHCleanup()); diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 3d212b5f78..a7c3a289da 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -127,7 +127,15 @@ public: bool isValid() const { return Size >= 0; } + /// Returns true if this scope encloses I. + /// Returns false if I is invalid. + /// This scope must be valid. bool encloses(stable_iterator I) const { return Size <= I.Size; } + + /// Returns true if this scope strictly encloses I: that is, + /// if it encloses I and is not I. + /// Returns false is I is invalid. + /// This scope must be valid. bool strictlyEncloses(stable_iterator I) const { return Size < I.Size; } friend bool operator==(stable_iterator A, stable_iterator B) { @@ -317,6 +325,7 @@ public: stable_iterator getInnermostNormalCleanup() const { return InnermostNormalCleanup; } + stable_iterator getInnermostActiveNormalCleanup() const; // CGException.h /// Determines whether there are any EH cleanups on the stack. bool hasEHCleanups() const { @@ -328,6 +337,7 @@ public: stable_iterator getInnermostEHCleanup() const { return InnermostEHCleanup; } + stable_iterator getInnermostActiveEHCleanup() const; // CGException.h /// An unstable reference to a scope-stack depth. Invalidated by /// pushes but not pops.