From 8136c73a751eba041521ab451d0c87ebc57a3608 Mon Sep 17 00:00:00 2001 From: Joseph Tremoulet Date: Tue, 6 Oct 2015 20:28:16 +0000 Subject: [PATCH 1/1] [WinEH] Recognize CoreCLR personality function Summary: - Add CoreCLR to if/else ladders and switches as appropriate. - Rename isMSVCEHPersonality to isFuncletEHPersonality to better reflect what it captures. Reviewers: majnemer, andrew.w.kaylor, rnk Subscribers: pgavlin, AndyAyers, llvm-commits Differential Revision: http://reviews.llvm.org/D13449 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@249455 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Analysis/LibCallSemantics.h | 9 +++++---- lib/Analysis/LibCallSemantics.cpp | 1 + lib/CodeGen/AsmPrinter/WinException.cpp | 8 ++++---- lib/CodeGen/DwarfEHPrepare.cpp | 4 ++-- lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp | 4 ++-- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 10 ++++++---- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 4 ++-- lib/CodeGen/WinEHPrepare.cpp | 4 ++-- lib/Target/X86/X86ISelLowering.cpp | 8 ++++---- lib/Target/X86/X86WinEHState.cpp | 4 ++-- lib/Transforms/InstCombine/InstructionCombining.cpp | 1 + 11 files changed, 31 insertions(+), 26 deletions(-) diff --git a/include/llvm/Analysis/LibCallSemantics.h b/include/llvm/Analysis/LibCallSemantics.h index a23dc08feb7..14ecb55f340 100644 --- a/include/llvm/Analysis/LibCallSemantics.h +++ b/include/llvm/Analysis/LibCallSemantics.h @@ -29,6 +29,7 @@ class InvokeInst; MSVC_X86SEH, MSVC_Win64SEH, MSVC_CXX, + CoreCLR }; /// \brief See if the given exception handling personality function is one @@ -50,14 +51,14 @@ class InvokeInst; llvm_unreachable("invalid enum"); } - /// \brief Returns true if this is an MSVC personality function. - inline bool isMSVCEHPersonality(EHPersonality Pers) { - // The two SEH personality functions can catch asynch exceptions. We assume - // unknown personalities don't catch asynch exceptions. + /// \brief Returns true if this is a personality function that invokes + /// handler funclets (which must return to it). + inline bool isFuncletEHPersonality(EHPersonality Pers) { switch (Pers) { case EHPersonality::MSVC_CXX: case EHPersonality::MSVC_X86SEH: case EHPersonality::MSVC_Win64SEH: + case EHPersonality::CoreCLR: return true; default: return false; } diff --git a/lib/Analysis/LibCallSemantics.cpp b/lib/Analysis/LibCallSemantics.cpp index 0ae13dd5afb..b91ff20aee2 100644 --- a/lib/Analysis/LibCallSemantics.cpp +++ b/lib/Analysis/LibCallSemantics.cpp @@ -34,6 +34,7 @@ EHPersonality llvm::classifyEHPersonality(const Value *Pers) { .Case("_except_handler4", EHPersonality::MSVC_X86SEH) .Case("__C_specific_handler", EHPersonality::MSVC_Win64SEH) .Case("__CxxFrameHandler3", EHPersonality::MSVC_CXX) + .Case("ProcessCLRException", EHPersonality::CoreCLR) .Default(EHPersonality::Unknown); } diff --git a/lib/CodeGen/AsmPrinter/WinException.cpp b/lib/CodeGen/AsmPrinter/WinException.cpp index 7764a6e716e..4f1d5cb864a 100644 --- a/lib/CodeGen/AsmPrinter/WinException.cpp +++ b/lib/CodeGen/AsmPrinter/WinException.cpp @@ -113,10 +113,10 @@ void WinException::endFunction(const MachineFunction *MF) { if (F->hasPersonalityFn()) Per = classifyEHPersonality(F->getPersonalityFn()); - // Get rid of any dead landing pads if we're not using a Windows EH scheme. In - // Windows EH schemes, the landing pad is not actually reachable. It only - // exists so that we can emit the right table data. - if (!isMSVCEHPersonality(Per)) + // Get rid of any dead landing pads if we're not using funclets. In funclet + // schemes, the landing pad is not actually reachable. It only exists so + // that we can emit the right table data. + if (!isFuncletEHPersonality(Per)) MMI->TidyLandingPads(); endFunclet(); diff --git a/lib/CodeGen/DwarfEHPrepare.cpp b/lib/CodeGen/DwarfEHPrepare.cpp index e019dfbc8f7..0f6e1463f10 100644 --- a/lib/CodeGen/DwarfEHPrepare.cpp +++ b/lib/CodeGen/DwarfEHPrepare.cpp @@ -192,9 +192,9 @@ bool DwarfEHPrepare::InsertUnwindResumeCalls(Function &Fn) { if (Resumes.empty()) return false; - // Check the personality, don't do anything if it's for MSVC. + // Check the personality, don't do anything if it's funclet-based. EHPersonality Pers = classifyEHPersonality(Fn.getPersonalityFn()); - if (isMSVCEHPersonality(Pers)) + if (isFuncletEHPersonality(Pers)) return false; LLVMContext &Ctx = Fn.getContext(); diff --git a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp index 7da68deaaa3..fb455943f90 100644 --- a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp +++ b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp @@ -273,11 +273,11 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf, LPads.push_back(LPI); } - // If this is an MSVC EH personality, we need to do a bit more work. + // If this personality uses funclets, we need to do a bit more work. if (!Fn->hasPersonalityFn()) return; EHPersonality Personality = classifyEHPersonality(Fn->getPersonalityFn()); - if (!isMSVCEHPersonality(Personality)) + if (!isFuncletEHPersonality(Personality)) return; if (Personality == EHPersonality::MSVC_Win64SEH || diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index d498c547bfd..fc140f65571 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -1207,8 +1207,10 @@ static void findUnwindDestinations(FunctionLoweringInfo &FuncInfo, const BasicBlock *EHPadBB, SmallVectorImpl &UnwindDests) { - bool IsMSVCCXX = classifyEHPersonality(FuncInfo.Fn->getPersonalityFn()) == - EHPersonality::MSVC_CXX; + EHPersonality Personality = + classifyEHPersonality(FuncInfo.Fn->getPersonalityFn()); + bool IsMSVCCXX = Personality == EHPersonality::MSVC_CXX; + bool IsCoreCLR = Personality == EHPersonality::CoreCLR; while (EHPadBB) { const Instruction *Pad = EHPadBB->getFirstNonPHI(); if (isa(Pad)) { @@ -1224,8 +1226,8 @@ findUnwindDestinations(FunctionLoweringInfo &FuncInfo, } else if (const auto *CPI = dyn_cast(Pad)) { // Add the catchpad handler to the possible destinations. UnwindDests.push_back(FuncInfo.MBBMap[CPI->getNormalDest()]); - // In MSVC C++, catchblocks are funclets and need prologues. - if (IsMSVCCXX) + // In MSVC C++ and CoreCLR, catchblocks are funclets and need prologues. + if (IsMSVCCXX || IsCoreCLR) UnwindDests.back()->setIsEHFuncletEntry(); EHPadBB = CPI->getUnwindDest(); } else if (const auto *CEPI = dyn_cast(Pad)) { diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index c449ea8ba91..c20270d9a7e 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -941,7 +941,7 @@ bool SelectionDAGISel::PrepareEHLandingPad() { BuildMI(*MBB, FuncInfo->InsertPt, SDB->getCurDebugLoc(), II) .addSym(Label); - // If this is an MSVC-style personality function, we need to split the landing + // If this personality function uses funclets, we need to split the landing // pad into several BBs. const BasicBlock *LLVMBB = MBB->getBasicBlock(); const Constant *Personality = MF->getFunction()->getPersonalityFn(); @@ -949,7 +949,7 @@ bool SelectionDAGISel::PrepareEHLandingPad() { MF->getMMI().addPersonality(PF); EHPersonality PersonalityType = classifyEHPersonality(Personality); - if (isMSVCEHPersonality(PersonalityType)) { + if (isFuncletEHPersonality(PersonalityType)) { SmallVector ClauseBBs; const IntrinsicInst *ActionsCall = dyn_cast(LLVMBB->getFirstInsertionPt()); diff --git a/lib/CodeGen/WinEHPrepare.cpp b/lib/CodeGen/WinEHPrepare.cpp index 3b6187594e9..88a639e8778 100644 --- a/lib/CodeGen/WinEHPrepare.cpp +++ b/lib/CodeGen/WinEHPrepare.cpp @@ -433,8 +433,8 @@ bool WinEHPrepare::runOnFunction(Function &Fn) { // Classify the personality to see what kind of preparation we need. Personality = classifyEHPersonality(Fn.getPersonalityFn()); - // Do nothing if this is not an MSVC personality. - if (!isMSVCEHPersonality(Personality)) + // Do nothing if this is not a funclet-based personality. + if (!isFuncletEHPersonality(Personality)) return false; SmallVector LPads; diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index bb5c3770233..c3d3354c47c 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -3390,9 +3390,9 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, const uint32_t *Mask = RegInfo->getCallPreservedMask(MF, CallConv); assert(Mask && "Missing call preserved mask for calling convention"); - // If this is an invoke in a 32-bit function using an MSVC personality, assume - // the function clobbers all registers. If an exception is thrown, the runtime - // will not restore CSRs. + // If this is an invoke in a 32-bit function using a funclet-based + // personality, assume the function clobbers all registers. If an exception + // is thrown, the runtime will not restore CSRs. // FIXME: Model this more precisely so that we can register allocate across // the normal edge and spill and fill across the exceptional edge. if (!Is64Bit && CLI.CS && CLI.CS->isInvoke()) { @@ -3401,7 +3401,7 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, CallerFn->hasPersonalityFn() ? classifyEHPersonality(CallerFn->getPersonalityFn()) : EHPersonality::Unknown; - if (isMSVCEHPersonality(Pers)) + if (isFuncletEHPersonality(Pers)) Mask = RegInfo->getNoPreservedMask(); } diff --git a/lib/Target/X86/X86WinEHState.cpp b/lib/Target/X86/X86WinEHState.cpp index 3a73338284c..993879e399b 100644 --- a/lib/Target/X86/X86WinEHState.cpp +++ b/lib/Target/X86/X86WinEHState.cpp @@ -156,7 +156,7 @@ bool WinEHStatePass::runOnFunction(Function &F) { if (WinEHParentName != F.getName() && !WinEHParentName.empty()) return false; - // Check the personality. Do nothing if this is not an MSVC personality. + // Check the personality. Do nothing if this personality doesn't use funclets. if (!F.hasPersonalityFn()) return false; PersonalityFn = @@ -164,7 +164,7 @@ bool WinEHStatePass::runOnFunction(Function &F) { if (!PersonalityFn) return false; Personality = classifyEHPersonality(PersonalityFn); - if (!isMSVCEHPersonality(Personality)) + if (!isFuncletEHPersonality(Personality)) return false; // Skip this function if there are no EH pads and we aren't using IR-level diff --git a/lib/Transforms/InstCombine/InstructionCombining.cpp b/lib/Transforms/InstCombine/InstructionCombining.cpp index 72548dc69ca..8ce6ce799f9 100644 --- a/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -2362,6 +2362,7 @@ static bool isCatchAll(EHPersonality Personality, Constant *TypeInfo) { case EHPersonality::MSVC_X86SEH: case EHPersonality::MSVC_Win64SEH: case EHPersonality::MSVC_CXX: + case EHPersonality::CoreCLR: return TypeInfo->isNullValue(); } llvm_unreachable("invalid enum"); -- 2.34.1