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:
parent
881e383547
commit
d1c89447ca
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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 ||
|
||||
|
@ -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)) {
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user