r247349 - [SEH] Use cleanupendpad so that WinEHPrepare gets the coloring right
Reid Kleckner via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 10 15:11:14 PDT 2015
Author: rnk
Date: Thu Sep 10 17:11:13 2015
New Revision: 247349
URL: http://llvm.org/viewvc/llvm-project?rev=247349&view=rev
Log:
[SEH] Use cleanupendpad so that WinEHPrepare gets the coloring right
Cleanupendpad is a lot like catchendpad, so we can reuse the same
EHScopeStack type.
Modified:
cfe/trunk/lib/CodeGen/CGCleanup.cpp
cfe/trunk/lib/CodeGen/CGCleanup.h
cfe/trunk/lib/CodeGen/CGException.cpp
cfe/trunk/lib/CodeGen/EHScopeStack.h
cfe/trunk/test/CodeGen/exceptions-seh-new.c
Modified: cfe/trunk/lib/CodeGen/CGCleanup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCleanup.cpp?rev=247349&r1=247348&r2=247349&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCleanup.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCleanup.cpp Thu Sep 10 17:11:13 2015
@@ -262,10 +262,10 @@ void EHScopeStack::pushTerminate() {
InnermostEHScope = stable_begin();
}
-void EHScopeStack::pushCatchEnd(llvm::BasicBlock *CatchEndBlockBB) {
- char *Buffer = allocate(EHCatchEndScope::getSize());
- auto *CES = new (Buffer) EHCatchEndScope(InnermostEHScope);
- CES->setCachedEHDispatchBlock(CatchEndBlockBB);
+void EHScopeStack::pushPadEnd(llvm::BasicBlock *PadEndBB) {
+ char *Buffer = allocate(EHPadEndScope::getSize());
+ auto *CES = new (Buffer) EHPadEndScope(InnermostEHScope);
+ CES->setCachedEHDispatchBlock(PadEndBB);
InnermostEHScope = stable_begin();
}
Modified: cfe/trunk/lib/CodeGen/CGCleanup.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCleanup.h?rev=247349&r1=247348&r2=247349&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCleanup.h (original)
+++ cfe/trunk/lib/CodeGen/CGCleanup.h Thu Sep 10 17:11:13 2015
@@ -101,7 +101,7 @@ protected:
};
public:
- enum Kind { Cleanup, Catch, Terminate, Filter, CatchEnd };
+ enum Kind { Cleanup, Catch, Terminate, Filter, PadEnd };
EHScope(Kind kind, EHScopeStack::stable_iterator enclosingEHScope)
: CachedLandingPad(nullptr), CachedEHDispatchBlock(nullptr),
@@ -474,14 +474,14 @@ public:
}
};
-class EHCatchEndScope : public EHScope {
+class EHPadEndScope : public EHScope {
public:
- EHCatchEndScope(EHScopeStack::stable_iterator enclosingEHScope)
- : EHScope(CatchEnd, enclosingEHScope) {}
- static size_t getSize() { return sizeof(EHCatchEndScope); }
+ EHPadEndScope(EHScopeStack::stable_iterator enclosingEHScope)
+ : EHScope(PadEnd, enclosingEHScope) {}
+ static size_t getSize() { return sizeof(EHPadEndScope); }
static bool classof(const EHScope *scope) {
- return scope->getKind() == CatchEnd;
+ return scope->getKind() == PadEnd;
}
};
@@ -523,8 +523,8 @@ public:
Size = EHTerminateScope::getSize();
break;
- case EHScope::CatchEnd:
- Size = EHCatchEndScope::getSize();
+ case EHScope::PadEnd:
+ Size = EHPadEndScope::getSize();
break;
}
Ptr += llvm::RoundUpToAlignment(Size, ScopeStackAlignment);
@@ -574,12 +574,12 @@ inline void EHScopeStack::popTerminate()
deallocate(EHTerminateScope::getSize());
}
-inline void EHScopeStack::popCatchEnd() {
+inline void EHScopeStack::popPadEnd() {
assert(!empty() && "popping exception stack when not empty");
- EHCatchEndScope &scope = cast<EHCatchEndScope>(*begin());
+ EHPadEndScope &scope = cast<EHPadEndScope>(*begin());
InnermostEHScope = scope.getEnclosingEHScope();
- deallocate(EHCatchEndScope::getSize());
+ deallocate(EHPadEndScope::getSize());
}
inline EHScopeStack::iterator EHScopeStack::find(stable_iterator sp) const {
Modified: cfe/trunk/lib/CodeGen/CGException.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGException.cpp?rev=247349&r1=247348&r2=247349&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGException.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGException.cpp Thu Sep 10 17:11:13 2015
@@ -601,8 +601,8 @@ CodeGenFunction::getEHDispatchBlock(EHSc
dispatchBlock = getTerminateHandler();
break;
- case EHScope::CatchEnd:
- llvm_unreachable("CatchEnd unnecessary for Itanium!");
+ case EHScope::PadEnd:
+ llvm_unreachable("PadEnd unnecessary for Itanium!");
}
scope.setCachedEHDispatchBlock(dispatchBlock);
}
@@ -645,8 +645,8 @@ CodeGenFunction::getMSVCDispatchBlock(EH
DispatchBlock->setName("terminate");
break;
- case EHScope::CatchEnd:
- llvm_unreachable("CatchEnd dispatch block missing!");
+ case EHScope::PadEnd:
+ llvm_unreachable("PadEnd dispatch block missing!");
}
EHS.setCachedEHDispatchBlock(DispatchBlock);
return DispatchBlock;
@@ -662,7 +662,7 @@ static bool isNonEHScope(const EHScope &
case EHScope::Filter:
case EHScope::Catch:
case EHScope::Terminate:
- case EHScope::CatchEnd:
+ case EHScope::PadEnd:
return false;
}
@@ -721,8 +721,8 @@ llvm::BasicBlock *CodeGenFunction::EmitL
case EHScope::Terminate:
return getTerminateLandingPad();
- case EHScope::CatchEnd:
- llvm_unreachable("CatchEnd unnecessary for Itanium!");
+ case EHScope::PadEnd:
+ llvm_unreachable("PadEnd unnecessary for Itanium!");
case EHScope::Catch:
case EHScope::Cleanup:
@@ -790,8 +790,8 @@ llvm::BasicBlock *CodeGenFunction::EmitL
case EHScope::Catch:
break;
- case EHScope::CatchEnd:
- llvm_unreachable("CatchEnd unnecessary for Itanium!");
+ case EHScope::PadEnd:
+ llvm_unreachable("PadEnd unnecessary for Itanium!");
}
EHCatchScope &catchScope = cast<EHCatchScope>(*I);
@@ -1028,7 +1028,7 @@ void CodeGenFunction::ExitCXXTryStmt(con
isa<CXXConstructorDecl>(CurCodeDecl);
if (CatchEndBlockBB)
- EHStack.pushCatchEnd(CatchEndBlockBB);
+ EHStack.pushPadEnd(CatchEndBlockBB);
// Perversely, we emit the handlers backwards precisely because we
// want them to appear in source order. In all of these cases, the
@@ -1083,7 +1083,7 @@ void CodeGenFunction::ExitCXXTryStmt(con
EmitBlock(ContBB);
incrementProfileCounter(&S);
if (CatchEndBlockBB)
- EHStack.popCatchEnd();
+ EHStack.popPadEnd();
}
namespace {
@@ -1397,8 +1397,10 @@ void CodeGenFunction::EmitSEHTryStmt(con
namespace {
struct PerformSEHFinally final : EHScopeStack::Cleanup {
llvm::Function *OutlinedFinally;
- PerformSEHFinally(llvm::Function *OutlinedFinally)
- : OutlinedFinally(OutlinedFinally) {}
+ EHScopeStack::stable_iterator EnclosingScope;
+ PerformSEHFinally(llvm::Function *OutlinedFinally,
+ EHScopeStack::stable_iterator EnclosingScope)
+ : OutlinedFinally(OutlinedFinally), EnclosingScope(EnclosingScope) {}
void Emit(CodeGenFunction &CGF, Flags F) override {
ASTContext &Context = CGF.getContext();
@@ -1423,7 +1425,28 @@ struct PerformSEHFinally final : EHScope
CGM.getTypes().arrangeFreeFunctionCall(Args, FPT,
/*chainCall=*/false);
+ // If this is the normal cleanup or using the old EH IR, just emit the call.
+ if (!F.isForEHCleanup() || !CGM.getCodeGenOpts().NewMSEH) {
+ CGF.EmitCall(FnInfo, OutlinedFinally, ReturnValueSlot(), Args);
+ return;
+ }
+
+ // Build a cleanupendpad to unwind through.
+ llvm::BasicBlock *CleanupBB = CGF.Builder.GetInsertBlock();
+ llvm::BasicBlock *CleanupEndBB = CGF.createBasicBlock("ehcleanup.end");
+ llvm::Instruction *PadInst = CleanupBB->getFirstNonPHI();
+ auto *CPI = cast<llvm::CleanupPadInst>(PadInst);
+ CGBuilderTy(CGF, CleanupEndBB)
+ .CreateCleanupEndPad(CPI, CGF.getEHDispatchBlock(EnclosingScope));
+
+ // Push and pop the cleanupendpad around the call.
+ CGF.EHStack.pushPadEnd(CleanupEndBB);
CGF.EmitCall(FnInfo, OutlinedFinally, ReturnValueSlot(), Args);
+ CGF.EHStack.popPadEnd();
+
+ // Insert the catchendpad block here.
+ CGF.CurFn->getBasicBlockList().insertAfter(CGF.Builder.GetInsertBlock(),
+ CleanupEndBB);
}
};
}
@@ -1779,7 +1802,8 @@ void CodeGenFunction::EnterSEHTryStmt(co
HelperCGF.GenerateSEHFinallyFunction(*this, *Finally);
// Push a cleanup for __finally blocks.
- EHStack.pushCleanup<PerformSEHFinally>(NormalAndEHCleanup, FinallyFunc);
+ EHStack.pushCleanup<PerformSEHFinally>(NormalAndEHCleanup, FinallyFunc,
+ EHStack.getInnermostEHScope());
return;
}
Modified: cfe/trunk/lib/CodeGen/EHScopeStack.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/EHScopeStack.h?rev=247349&r1=247348&r2=247349&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/EHScopeStack.h (original)
+++ cfe/trunk/lib/CodeGen/EHScopeStack.h Thu Sep 10 17:11:13 2015
@@ -334,9 +334,9 @@ public:
/// Pops a terminate handler off the stack.
void popTerminate();
- void pushCatchEnd(llvm::BasicBlock *CatchEndBlockBB);
+ void pushPadEnd(llvm::BasicBlock *PadEndBB);
- void popCatchEnd();
+ void popPadEnd();
// Returns true iff the current scope is either empty or contains only
// lifetime markers, i.e. no real cleanup code
Modified: cfe/trunk/test/CodeGen/exceptions-seh-new.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/exceptions-seh-new.c?rev=247349&r1=247348&r2=247349&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/exceptions-seh-new.c (original)
+++ cfe/trunk/test/CodeGen/exceptions-seh-new.c Thu Sep 10 17:11:13 2015
@@ -182,8 +182,12 @@ int basic_finally(int g) {
// CHECK: [[cleanuppad]]
// CHECK: %[[padtoken:[^ ]*]] = cleanuppad []
// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
-// CHECK: call void @"\01?fin$0 at 0@basic_finally@@"({{i8( zeroext)?}} 1, i8* %[[fp]])
+// CHECK: invoke void @"\01?fin$0 at 0@basic_finally@@"({{i8( zeroext)?}} 1, i8* %[[fp]])
+// CHECK: to label %[[cleanupcont:[^ ]*]] unwind label %[[cleanupend:[^ ]*]]
+// CHECK: [[cleanupcont]]
// CHECK: cleanupret %[[padtoken]] unwind to caller
+// CHECK: [[cleanupend]]
+// CHECK: cleanupendpad %[[padtoken]] unwind to caller
// CHECK: define internal void @"\01?fin$0 at 0@basic_finally@@"({{i8( zeroext)?}} %abnormal_termination, i8* %frame_pointer)
// CHECK: call i8* @llvm.localrecover(i8* bitcast (i32 (i32)* @basic_finally to i8*), i8* %frame_pointer, i32 0)
More information about the cfe-commits
mailing list