diff options
author | Reid Kleckner <rnk@google.com> | 2015-08-27 23:27:47 +0000 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2015-08-27 23:27:47 +0000 |
commit | 0e2882345daead6cd9368eda4107e860d9141e35 (patch) | |
tree | be2bbccebdc6d0f2648fe9612ff4338b1f8b4f2f /llvm/lib/CodeGen/AsmPrinter/WinException.cpp | |
parent | 67bc8d6b3f69f83e6f2688d960b8a273cee57a20 (diff) | |
download | bcm5719-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.cpp | 58 |
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 = |