llvm.org GIT mirror llvm / 8136c73
[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 Joseph Tremoulet 4 years ago
11 changed file(s) with 31 addition(s) and 26 deletion(s). Raw diff Collapse all Expand all
2828 MSVC_X86SEH,
2929 MSVC_Win64SEH,
3030 MSVC_CXX,
31 CoreCLR
3132 };
3233
3334 /// \brief See if the given exception handling personality function is one
4950 llvm_unreachable("invalid enum");
5051 }
5152
52 /// \brief Returns true if this is an MSVC personality function.
53 inline bool isMSVCEHPersonality(EHPersonality Pers) {
54 // The two SEH personality functions can catch asynch exceptions. We assume
55 // unknown personalities don't catch asynch exceptions.
53 /// \brief Returns true if this is a personality function that invokes
54 /// handler funclets (which must return to it).
55 inline bool isFuncletEHPersonality(EHPersonality Pers) {
5656 switch (Pers) {
5757 case EHPersonality::MSVC_CXX:
5858 case EHPersonality::MSVC_X86SEH:
5959 case EHPersonality::MSVC_Win64SEH:
60 case EHPersonality::CoreCLR:
6061 return true;
6162 default: return false;
6263 }
3333 .Case("_except_handler4", EHPersonality::MSVC_X86SEH)
3434 .Case("__C_specific_handler", EHPersonality::MSVC_Win64SEH)
3535 .Case("__CxxFrameHandler3", EHPersonality::MSVC_CXX)
36 .Case("ProcessCLRException", EHPersonality::CoreCLR)
3637 .Default(EHPersonality::Unknown);
3738 }
3839
112112 if (F->hasPersonalityFn())
113113 Per = classifyEHPersonality(F->getPersonalityFn());
114114
115 // Get rid of any dead landing pads if we're not using a Windows EH scheme. In
116 // Windows EH schemes, the landing pad is not actually reachable. It only
117 // exists so that we can emit the right table data.
118 if (!isMSVCEHPersonality(Per))
115 // Get rid of any dead landing pads if we're not using funclets. In funclet
116 // schemes, the landing pad is not actually reachable. It only exists so
117 // that we can emit the right table data.
118 if (!isFuncletEHPersonality(Per))
119119 MMI->TidyLandingPads();
120120
121121 endFunclet();
191191 if (Resumes.empty())
192192 return false;
193193
194 // Check the personality, don't do anything if it's for MSVC.
194 // Check the personality, don't do anything if it's funclet-based.
195195 EHPersonality Pers = classifyEHPersonality(Fn.getPersonalityFn());
196 if (isMSVCEHPersonality(Pers))
196 if (isFuncletEHPersonality(Pers))
197197 return false;
198198
199199 LLVMContext &Ctx = Fn.getContext();
272272 LPads.push_back(LPI);
273273 }
274274
275 // If this is an MSVC EH personality, we need to do a bit more work.
275 // If this personality uses funclets, we need to do a bit more work.
276276 if (!Fn->hasPersonalityFn())
277277 return;
278278 EHPersonality Personality = classifyEHPersonality(Fn->getPersonalityFn());
279 if (!isMSVCEHPersonality(Personality))
279 if (!isFuncletEHPersonality(Personality))
280280 return;
281281
282282 if (Personality == EHPersonality::MSVC_Win64SEH ||
12061206 findUnwindDestinations(FunctionLoweringInfo &FuncInfo,
12071207 const BasicBlock *EHPadBB,
12081208 SmallVectorImpl &UnwindDests) {
1209 bool IsMSVCCXX = classifyEHPersonality(FuncInfo.Fn->getPersonalityFn()) ==
1210 EHPersonality::MSVC_CXX;
1209 EHPersonality Personality =
1210 classifyEHPersonality(FuncInfo.Fn->getPersonalityFn());
1211 bool IsMSVCCXX = Personality == EHPersonality::MSVC_CXX;
1212 bool IsCoreCLR = Personality == EHPersonality::CoreCLR;
12111213 while (EHPadBB) {
12121214 const Instruction *Pad = EHPadBB->getFirstNonPHI();
12131215 if (isa(Pad)) {
12231225 } else if (const auto *CPI = dyn_cast(Pad)) {
12241226 // Add the catchpad handler to the possible destinations.
12251227 UnwindDests.push_back(FuncInfo.MBBMap[CPI->getNormalDest()]);
1226 // In MSVC C++, catchblocks are funclets and need prologues.
1227 if (IsMSVCCXX)
1228 // In MSVC C++ and CoreCLR, catchblocks are funclets and need prologues.
1229 if (IsMSVCCXX || IsCoreCLR)
12281230 UnwindDests.back()->setIsEHFuncletEntry();
12291231 EHPadBB = CPI->getUnwindDest();
12301232 } else if (const auto *CEPI = dyn_cast(Pad)) {
940940 BuildMI(*MBB, FuncInfo->InsertPt, SDB->getCurDebugLoc(), II)
941941 .addSym(Label);
942942
943 // If this is an MSVC-style personality function, we need to split the landing
943 // If this personality function uses funclets, we need to split the landing
944944 // pad into several BBs.
945945 const BasicBlock *LLVMBB = MBB->getBasicBlock();
946946 const Constant *Personality = MF->getFunction()->getPersonalityFn();
948948 MF->getMMI().addPersonality(PF);
949949 EHPersonality PersonalityType = classifyEHPersonality(Personality);
950950
951 if (isMSVCEHPersonality(PersonalityType)) {
951 if (isFuncletEHPersonality(PersonalityType)) {
952952 SmallVector ClauseBBs;
953953 const IntrinsicInst *ActionsCall =
954954 dyn_cast(LLVMBB->getFirstInsertionPt());
432432 // Classify the personality to see what kind of preparation we need.
433433 Personality = classifyEHPersonality(Fn.getPersonalityFn());
434434
435 // Do nothing if this is not an MSVC personality.
436 if (!isMSVCEHPersonality(Personality))
435 // Do nothing if this is not a funclet-based personality.
436 if (!isFuncletEHPersonality(Personality))
437437 return false;
438438
439439 SmallVector LPads;
33893389 const uint32_t *Mask = RegInfo->getCallPreservedMask(MF, CallConv);
33903390 assert(Mask && "Missing call preserved mask for calling convention");
33913391
3392 // If this is an invoke in a 32-bit function using an MSVC personality, assume
3393 // the function clobbers all registers. If an exception is thrown, the runtime
3394 // will not restore CSRs.
3392 // If this is an invoke in a 32-bit function using a funclet-based
3393 // personality, assume the function clobbers all registers. If an exception
3394 // is thrown, the runtime will not restore CSRs.
33953395 // FIXME: Model this more precisely so that we can register allocate across
33963396 // the normal edge and spill and fill across the exceptional edge.
33973397 if (!Is64Bit && CLI.CS && CLI.CS->isInvoke()) {
34003400 CallerFn->hasPersonalityFn()
34013401 ? classifyEHPersonality(CallerFn->getPersonalityFn())
34023402 : EHPersonality::Unknown;
3403 if (isMSVCEHPersonality(Pers))
3403 if (isFuncletEHPersonality(Pers))
34043404 Mask = RegInfo->getNoPreservedMask();
34053405 }
34063406
155155 if (WinEHParentName != F.getName() && !WinEHParentName.empty())
156156 return false;
157157
158 // Check the personality. Do nothing if this is not an MSVC personality.
158 // Check the personality. Do nothing if this personality doesn't use funclets.
159159 if (!F.hasPersonalityFn())
160160 return false;
161161 PersonalityFn =
163163 if (!PersonalityFn)
164164 return false;
165165 Personality = classifyEHPersonality(PersonalityFn);
166 if (!isMSVCEHPersonality(Personality))
166 if (!isFuncletEHPersonality(Personality))
167167 return false;
168168
169169 // Skip this function if there are no EH pads and we aren't using IR-level
23612361 case EHPersonality::MSVC_X86SEH:
23622362 case EHPersonality::MSVC_Win64SEH:
23632363 case EHPersonality::MSVC_CXX:
2364 case EHPersonality::CoreCLR:
23642365 return TypeInfo->isNullValue();
23652366 }
23662367 llvm_unreachable("invalid enum");