1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-26 12:43:36 +01:00

[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

llvm-svn: 249455
This commit is contained in:
Joseph Tremoulet 2015-10-06 20:28:16 +00:00
parent 881e383547
commit d1c89447ca
11 changed files with 31 additions and 26 deletions

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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();

View File

@ -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();

View File

@ -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 ||

View File

@ -1207,8 +1207,10 @@ static void
findUnwindDestinations(FunctionLoweringInfo &FuncInfo,
const BasicBlock *EHPadBB,
SmallVectorImpl<MachineBasicBlock *> &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<LandingPadInst>(Pad)) {
@ -1224,8 +1226,8 @@ findUnwindDestinations(FunctionLoweringInfo &FuncInfo,
} else if (const auto *CPI = dyn_cast<CatchPadInst>(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<CatchEndPadInst>(Pad)) {

View File

@ -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<MachineBasicBlock *, 4> ClauseBBs;
const IntrinsicInst *ActionsCall =
dyn_cast<IntrinsicInst>(LLVMBB->getFirstInsertionPt());

View File

@ -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<LandingPadInst *, 4> LPads;

View File

@ -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();
}

View File

@ -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

View File

@ -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");