summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2015-08-27 23:27:47 +0000
committerReid Kleckner <rnk@google.com>2015-08-27 23:27:47 +0000
commit0e2882345daead6cd9368eda4107e860d9141e35 (patch)
treebe2bbccebdc6d0f2648fe9612ff4338b1f8b4f2f /llvm/lib/CodeGen/AsmPrinter/WinException.cpp
parent67bc8d6b3f69f83e6f2688d960b8a273cee57a20 (diff)
downloadbcm5719-llvm-0e2882345daead6cd9368eda4107e860d9141e35.tar.gz
bcm5719-llvm-0e2882345daead6cd9368eda4107e860d9141e35.zip
[WinEH] Add some support for code generating catchpad
We can now run 32-bit programs with empty catch bodies. The next step is to change PEI so that we get funclet prologues and epilogues. llvm-svn: 246235
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/WinException.cpp')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/WinException.cpp58
1 files changed, 36 insertions, 22 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
index 4151101e22b..547dc4cbdc3 100644
--- a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
@@ -62,6 +62,7 @@ void WinException::beginFunction(const MachineFunction *MF) {
// If any landing pads survive, we need an EH table.
bool hasLandingPads = !MMI->getLandingPads().empty();
+ bool hasEHFunclets = MMI->hasEHFunclets();
const Function *F = MF->getFunction();
const Function *ParentF = MMI->getWinEHParent(F);
@@ -78,19 +79,21 @@ void WinException::beginFunction(const MachineFunction *MF) {
F->hasPersonalityFn() && !isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&
F->needsUnwindTableEntry();
- shouldEmitPersonality = forceEmitPersonality || (hasLandingPads &&
- PerEncoding != dwarf::DW_EH_PE_omit && Per);
+ shouldEmitPersonality =
+ forceEmitPersonality || ((hasLandingPads || hasEHFunclets) &&
+ PerEncoding != dwarf::DW_EH_PE_omit && Per);
unsigned LSDAEncoding = TLOF.getLSDAEncoding();
shouldEmitLSDA = shouldEmitPersonality &&
LSDAEncoding != dwarf::DW_EH_PE_omit;
- // If we're not using CFI, we don't want the CFI or the personality. If
- // WinEHPrepare outlined something, we should emit the LSDA.
+ // If we're not using CFI, we don't want the CFI or the personality, but we
+ // might want EH tables if we had EH pads.
+ // FIXME: If WinEHPrepare outlined something, we should emit the LSDA. Remove
+ // this once WinEHPrepare stops doing that.
if (!Asm->MAI->usesWindowsCFI()) {
- bool HasOutlinedChildren =
- F->hasFnAttribute("wineh-parent") && F == ParentF;
- shouldEmitLSDA = HasOutlinedChildren;
+ shouldEmitLSDA =
+ hasEHFunclets || (F->hasFnAttribute("wineh-parent") && F == ParentF);
shouldEmitPersonality = false;
return;
}
@@ -185,7 +188,10 @@ const MCExpr *WinException::create32bitRef(const MCSymbol *Value) {
const MCExpr *WinException::create32bitRef(const Value *V) {
if (!V)
return MCConstantExpr::create(0, Asm->OutContext);
- return create32bitRef(Asm->getSymbol(cast<GlobalValue>(V)));
+ // FIXME: Delete the GlobalValue case once the new IR is fully functional.
+ if (const auto *GV = dyn_cast<GlobalValue>(V))
+ return create32bitRef(Asm->getSymbol(GV));
+ return create32bitRef(MMI->getAddrLabelSymbol(cast<BasicBlock>(V)));
}
/// Emit the language-specific data that __C_specific_handler expects. This
@@ -320,14 +326,17 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
extendIP2StateTable(MF, ParentF, FuncInfo);
- // Defer emission until we've visited the parent function and all the catch
- // handlers. Cleanups don't contribute to the ip2state table, so don't count
- // them.
- if (ParentF != F && !FuncInfo.CatchHandlerMaxState.count(F))
- return;
- ++FuncInfo.NumIPToStateFuncsVisited;
- if (FuncInfo.NumIPToStateFuncsVisited != FuncInfo.CatchHandlerMaxState.size())
- return;
+ if (!MMI->hasEHFunclets()) {
+ // Defer emission until we've visited the parent function and all the
+ // catch handlers. Cleanups don't contribute to the ip2state table, so
+ // don't count them.
+ if (ParentF != F && !FuncInfo.CatchHandlerMaxState.count(F))
+ return;
+ ++FuncInfo.NumIPToStateFuncsVisited;
+ if (FuncInfo.NumIPToStateFuncsVisited !=
+ FuncInfo.CatchHandlerMaxState.size())
+ return;
+ }
} else {
FuncInfoXData = Asm->OutContext.getOrCreateLSDASymbol(ParentLinkageName);
emitEHRegistrationOffsetLabel(FuncInfo, ParentLinkageName);
@@ -410,11 +419,13 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
HandlerMaps.push_back(HandlerMapXData);
- int CatchHigh = -1;
- for (WinEHHandlerType &HT : TBME.HandlerArray)
- CatchHigh =
- std::max(CatchHigh,
- FuncInfo.CatchHandlerMaxState[cast<Function>(HT.Handler)]);
+ int CatchHigh = TBME.CatchHigh;
+ if (CatchHigh == -1) {
+ for (WinEHHandlerType &HT : TBME.HandlerArray)
+ CatchHigh = std::max(
+ CatchHigh,
+ FuncInfo.CatchHandlerMaxState[cast<Function>(HT.Handler)]);
+ }
assert(TBME.TryLow <= TBME.TryHigh);
OS.EmitIntValue(TBME.TryLow, 4); // TryLow
@@ -456,7 +467,10 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
OS.EmitIntValue(HT.Adjectives, 4); // Adjectives
OS.EmitValue(create32bitRef(HT.TypeDescriptor), 4); // Type
OS.EmitValue(FrameAllocOffsetRef, 4); // CatchObjOffset
- OS.EmitValue(create32bitRef(HT.Handler), 4); // Handler
+ if (HT.HandlerMBB) // Handler
+ OS.EmitValue(create32bitRef(HT.HandlerMBB->getSymbol()), 4);
+ else
+ OS.EmitValue(create32bitRef(HT.Handler), 4);
if (shouldEmitPersonality) {
MCSymbol *ParentFrameOffset =
OpenPOWER on IntegriCloud