mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
[WebAssembly] Add Wasm personality and isScopedEHPersonality()
Summary: - Add wasm personality function - Re-categorize the existing `isFuncletEHPersonality()` function into two different functions: `isFuncletEHPersonality()` and `isScopedEHPersonality(). This becomes necessary as wasm EH uses scoped EH instructions (catchswitch, catchpad/ret, and cleanuppad/ret) but not outlined funclets. - Changed some callsites of `isFuncletEHPersonality()` to `isScopedEHPersonality()` if they are related to scoped EH IR-level stuff. Reviewers: majnemer, dschuff, rnk Subscribers: jfb, sbc100, jgravelle-google, eraman, JDevlieghere, sunfish, llvm-commits Differential Revision: https://reviews.llvm.org/D45559 llvm-svn: 332667
This commit is contained in:
parent
ddc80b6937
commit
75cf5b8d47
@ -32,7 +32,8 @@ enum class EHPersonality {
|
||||
MSVC_Win64SEH,
|
||||
MSVC_CXX,
|
||||
CoreCLR,
|
||||
Rust
|
||||
Rust,
|
||||
Wasm_CXX
|
||||
};
|
||||
|
||||
/// See if the given exception handling personality function is one
|
||||
@ -74,6 +75,22 @@ inline bool isFuncletEHPersonality(EHPersonality Pers) {
|
||||
llvm_unreachable("invalid enum");
|
||||
}
|
||||
|
||||
/// Returns true if this personality uses scope-style EH IR instructions:
|
||||
/// catchswitch, catchpad/ret, and cleanuppad/ret.
|
||||
inline bool isScopedEHPersonality(EHPersonality Pers) {
|
||||
switch (Pers) {
|
||||
case EHPersonality::MSVC_CXX:
|
||||
case EHPersonality::MSVC_X86SEH:
|
||||
case EHPersonality::MSVC_Win64SEH:
|
||||
case EHPersonality::CoreCLR:
|
||||
case EHPersonality::Wasm_CXX:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
llvm_unreachable("invalid enum");
|
||||
}
|
||||
|
||||
/// Return true if this personality may be safely removed if there
|
||||
/// are no invoke instructions remaining in the current function.
|
||||
inline bool isNoOpWithoutInvoke(EHPersonality Pers) {
|
||||
|
@ -25,20 +25,21 @@ EHPersonality llvm::classifyEHPersonality(const Value *Pers) {
|
||||
if (!F)
|
||||
return EHPersonality::Unknown;
|
||||
return StringSwitch<EHPersonality>(F->getName())
|
||||
.Case("__gnat_eh_personality", EHPersonality::GNU_Ada)
|
||||
.Case("__gxx_personality_v0", EHPersonality::GNU_CXX)
|
||||
.Case("__gxx_personality_seh0",EHPersonality::GNU_CXX)
|
||||
.Case("__gxx_personality_sj0", EHPersonality::GNU_CXX_SjLj)
|
||||
.Case("__gcc_personality_v0", EHPersonality::GNU_C)
|
||||
.Case("__gcc_personality_seh0",EHPersonality::GNU_C)
|
||||
.Case("__gcc_personality_sj0", EHPersonality::GNU_C_SjLj)
|
||||
.Case("__objc_personality_v0", EHPersonality::GNU_ObjC)
|
||||
.Case("_except_handler3", EHPersonality::MSVC_X86SEH)
|
||||
.Case("_except_handler4", EHPersonality::MSVC_X86SEH)
|
||||
.Case("__C_specific_handler", EHPersonality::MSVC_Win64SEH)
|
||||
.Case("__CxxFrameHandler3", EHPersonality::MSVC_CXX)
|
||||
.Case("ProcessCLRException", EHPersonality::CoreCLR)
|
||||
.Case("rust_eh_personality", EHPersonality::Rust)
|
||||
.Case("__gnat_eh_personality", EHPersonality::GNU_Ada)
|
||||
.Case("__gxx_personality_v0", EHPersonality::GNU_CXX)
|
||||
.Case("__gxx_personality_seh0", EHPersonality::GNU_CXX)
|
||||
.Case("__gxx_personality_sj0", EHPersonality::GNU_CXX_SjLj)
|
||||
.Case("__gcc_personality_v0", EHPersonality::GNU_C)
|
||||
.Case("__gcc_personality_seh0", EHPersonality::GNU_C)
|
||||
.Case("__gcc_personality_sj0", EHPersonality::GNU_C_SjLj)
|
||||
.Case("__objc_personality_v0", EHPersonality::GNU_ObjC)
|
||||
.Case("_except_handler3", EHPersonality::MSVC_X86SEH)
|
||||
.Case("_except_handler4", EHPersonality::MSVC_X86SEH)
|
||||
.Case("__C_specific_handler", EHPersonality::MSVC_Win64SEH)
|
||||
.Case("__CxxFrameHandler3", EHPersonality::MSVC_CXX)
|
||||
.Case("ProcessCLRException", EHPersonality::CoreCLR)
|
||||
.Case("rust_eh_personality", EHPersonality::Rust)
|
||||
.Case("__gxx_wasm_personality_v0", EHPersonality::Wasm_CXX)
|
||||
.Default(EHPersonality::Unknown);
|
||||
}
|
||||
|
||||
@ -55,6 +56,7 @@ StringRef llvm::getEHPersonalityName(EHPersonality Pers) {
|
||||
case EHPersonality::MSVC_CXX: return "__CxxFrameHandler3";
|
||||
case EHPersonality::CoreCLR: return "ProcessCLRException";
|
||||
case EHPersonality::Rust: return "rust_eh_personality";
|
||||
case EHPersonality::Wasm_CXX: return "__gxx_wasm_personality_v0";
|
||||
case EHPersonality::Unknown: llvm_unreachable("Unknown EHPersonality!");
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ void llvm::computeLoopSafetyInfo(LoopSafetyInfo *SafetyInfo, Loop *CurLoop) {
|
||||
Function *Fn = CurLoop->getHeader()->getParent();
|
||||
if (Fn->hasPersonalityFn())
|
||||
if (Constant *PersonalityFn = Fn->getPersonalityFn())
|
||||
if (isFuncletEHPersonality(classifyEHPersonality(PersonalityFn)))
|
||||
if (isScopedEHPersonality(classifyEHPersonality(PersonalityFn)))
|
||||
SafetyInfo->BlockColors = colorEHFunclets(*Fn);
|
||||
}
|
||||
|
||||
|
@ -195,9 +195,9 @@ bool DwarfEHPrepare::InsertUnwindResumeCalls(Function &Fn) {
|
||||
if (Resumes.empty())
|
||||
return false;
|
||||
|
||||
// Check the personality, don't do anything if it's funclet-based.
|
||||
// Check the personality, don't do anything if it's scope-based.
|
||||
EHPersonality Pers = classifyEHPersonality(Fn.getPersonalityFn());
|
||||
if (isFuncletEHPersonality(Pers))
|
||||
if (isScopedEHPersonality(Pers))
|
||||
return false;
|
||||
|
||||
LLVMContext &Ctx = Fn.getContext();
|
||||
|
@ -646,7 +646,7 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) {
|
||||
!(AsmInfo &&
|
||||
AsmInfo->getExceptionHandlingType() == ExceptionHandling::SjLj &&
|
||||
BB && isa<SwitchInst>(BB->getTerminator())) &&
|
||||
!isFuncletEHPersonality(classifyEHPersonality(F.getPersonalityFn())))
|
||||
!isScopedEHPersonality(classifyEHPersonality(F.getPersonalityFn())))
|
||||
report("MBB has more than one landing pad successor", MBB);
|
||||
|
||||
// Call AnalyzeBranch. If it succeeds, there several more conditions to check.
|
||||
|
@ -41,7 +41,7 @@ using namespace llvm;
|
||||
static cl::opt<bool> DisableDemotion(
|
||||
"disable-demotion", cl::Hidden,
|
||||
cl::desc(
|
||||
"Clone multicolor basic blocks but do not demote cross funclet values"),
|
||||
"Clone multicolor basic blocks but do not demote cross scopes"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool> DisableCleanups(
|
||||
@ -106,8 +106,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 a funclet-based personality.
|
||||
if (!isFuncletEHPersonality(Personality))
|
||||
// Do nothing if this is not a scope-based personality.
|
||||
if (!isScopedEHPersonality(Personality))
|
||||
return false;
|
||||
|
||||
DL = &Fn.getParent()->getDataLayout();
|
||||
|
@ -2567,6 +2567,7 @@ static bool isCatchAll(EHPersonality Personality, Constant *TypeInfo) {
|
||||
case EHPersonality::MSVC_Win64SEH:
|
||||
case EHPersonality::MSVC_CXX:
|
||||
case EHPersonality::CoreCLR:
|
||||
case EHPersonality::Wasm_CXX:
|
||||
return TypeInfo->isNullValue();
|
||||
}
|
||||
llvm_unreachable("invalid enum");
|
||||
|
@ -504,11 +504,11 @@ static bool functionHasLines(Function &F) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool isUsingFuncletBasedEH(Function &F) {
|
||||
static bool isUsingScopeBasedEH(Function &F) {
|
||||
if (!F.hasPersonalityFn()) return false;
|
||||
|
||||
EHPersonality Personality = classifyEHPersonality(F.getPersonalityFn());
|
||||
return isFuncletEHPersonality(Personality);
|
||||
return isScopedEHPersonality(Personality);
|
||||
}
|
||||
|
||||
static bool shouldKeepInEntry(BasicBlock::iterator It) {
|
||||
@ -551,8 +551,8 @@ void GCOVProfiler::emitProfileNotes() {
|
||||
DISubprogram *SP = F.getSubprogram();
|
||||
if (!SP) continue;
|
||||
if (!functionHasLines(F)) continue;
|
||||
// TODO: Functions using funclet-based EH are currently not supported.
|
||||
if (isUsingFuncletBasedEH(F)) continue;
|
||||
// TODO: Functions using scope-based EH are currently not supported.
|
||||
if (isUsingScopeBasedEH(F)) continue;
|
||||
|
||||
// gcov expects every function to start with an entry block that has a
|
||||
// single successor, so split the entry block to make sure of that.
|
||||
@ -630,8 +630,8 @@ bool GCOVProfiler::emitProfileArcs() {
|
||||
DISubprogram *SP = F.getSubprogram();
|
||||
if (!SP) continue;
|
||||
if (!functionHasLines(F)) continue;
|
||||
// TODO: Functions using funclet-based EH are currently not supported.
|
||||
if (isUsingFuncletBasedEH(F)) continue;
|
||||
// TODO: Functions using scope-based EH are currently not supported.
|
||||
if (isUsingScopeBasedEH(F)) continue;
|
||||
if (!Result) Result = true;
|
||||
|
||||
unsigned Edges = 0;
|
||||
|
@ -550,7 +550,7 @@ bool ObjCARCContract::runOnFunction(Function &F) {
|
||||
|
||||
DenseMap<BasicBlock *, ColorVector> BlockColors;
|
||||
if (F.hasPersonalityFn() &&
|
||||
isFuncletEHPersonality(classifyEHPersonality(F.getPersonalityFn())))
|
||||
isScopedEHPersonality(classifyEHPersonality(F.getPersonalityFn())))
|
||||
BlockColors = colorEHFunclets(F);
|
||||
|
||||
LLVM_DEBUG(llvm::dbgs() << "**** ObjCARC Contract ****\n");
|
||||
|
@ -722,7 +722,7 @@ void ObjCARCOpt::OptimizeIndividualCalls(Function &F) {
|
||||
|
||||
DenseMap<BasicBlock *, ColorVector> BlockColors;
|
||||
if (F.hasPersonalityFn() &&
|
||||
isFuncletEHPersonality(classifyEHPersonality(F.getPersonalityFn())))
|
||||
isScopedEHPersonality(classifyEHPersonality(F.getPersonalityFn())))
|
||||
BlockColors = colorEHFunclets(F);
|
||||
|
||||
// Visit all objc_* calls in F.
|
||||
|
@ -73,8 +73,8 @@ IRBuilder<> *EscapeEnumerator::Next() {
|
||||
F.setPersonalityFn(PersFn);
|
||||
}
|
||||
|
||||
if (isFuncletEHPersonality(classifyEHPersonality(F.getPersonalityFn()))) {
|
||||
report_fatal_error("Funclet EH not supported");
|
||||
if (isScopedEHPersonality(classifyEHPersonality(F.getPersonalityFn()))) {
|
||||
report_fatal_error("Scoped EH not supported");
|
||||
}
|
||||
|
||||
LandingPadInst *LPad =
|
||||
|
@ -1569,7 +1569,7 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI,
|
||||
Instruction *CallSiteEHPad = nullptr;
|
||||
if (CallerPersonality) {
|
||||
EHPersonality Personality = classifyEHPersonality(CallerPersonality);
|
||||
if (isFuncletEHPersonality(Personality)) {
|
||||
if (isScopedEHPersonality(Personality)) {
|
||||
Optional<OperandBundleUse> ParentFunclet =
|
||||
CS.getOperandBundle(LLVMContext::OB_funclet);
|
||||
if (ParentFunclet)
|
||||
|
Loading…
Reference in New Issue
Block a user