diff options
Diffstat (limited to 'llvm/lib')
25 files changed, 200 insertions, 140 deletions
diff --git a/llvm/lib/Analysis/LibCallSemantics.cpp b/llvm/lib/Analysis/LibCallSemantics.cpp index e98540ba7e9..003c81e87b6 100644 --- a/llvm/lib/Analysis/LibCallSemantics.cpp +++ b/llvm/lib/Analysis/LibCallSemantics.cpp @@ -80,9 +80,8 @@ EHPersonality llvm::classifyEHPersonality(const Value *Pers) { .Default(EHPersonality::Unknown); } -bool llvm::canSimplifyInvokeNoUnwind(const InvokeInst *II) { - const LandingPadInst *LP = II->getLandingPadInst(); - EHPersonality Personality = classifyEHPersonality(LP->getPersonalityFn()); +bool llvm::canSimplifyInvokeNoUnwind(const Function *F) { + EHPersonality Personality = classifyEHPersonality(F->getPersonalityFn()); // We can't simplify any invokes to nounwind functions if the personality // function wants to catch asynch exceptions. The nounwind attribute only // implies that the function does not throw synchronous exceptions. diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 064b74304a9..a121e59e1f1 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -4057,7 +4057,7 @@ bool LLParser::ParseTypeAndBasicBlock(BasicBlock *&BB, LocTy &Loc, /// FunctionHeader /// ::= OptionalLinkage OptionalVisibility OptionalCallingConv OptRetAttrs /// OptUnnamedAddr Type GlobalName '(' ArgList ')' OptFuncAttrs OptSection -/// OptionalAlign OptGC OptionalPrefix OptionalPrologue +/// OptionalAlign OptGC OptionalPrefix OptionalPrologue OptPersonalityFn bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { // Parse the linkage. LocTy LinkageLoc = Lex.getLoc(); @@ -4139,6 +4139,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { LocTy UnnamedAddrLoc; Constant *Prefix = nullptr; Constant *Prologue = nullptr; + Constant *PersonalityFn = nullptr; Comdat *C; if (ParseArgumentList(ArgList, isVarArg) || @@ -4155,7 +4156,9 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { (EatIfPresent(lltok::kw_prefix) && ParseGlobalTypeAndValue(Prefix)) || (EatIfPresent(lltok::kw_prologue) && - ParseGlobalTypeAndValue(Prologue))) + ParseGlobalTypeAndValue(Prologue)) || + (EatIfPresent(lltok::kw_personality) && + ParseGlobalTypeAndValue(PersonalityFn))) return true; if (FuncAttrs.contains(Attribute::Builtin)) @@ -4254,6 +4257,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { Fn->setAlignment(Alignment); Fn->setSection(Section); Fn->setComdat(C); + Fn->setPersonalityFn(PersonalityFn); if (!GC.empty()) Fn->setGC(GC.c_str()); Fn->setPrefixData(Prefix); Fn->setPrologueData(Prologue); @@ -5105,14 +5109,11 @@ int LLParser::ParsePHI(Instruction *&Inst, PerFunctionState &PFS) { /// ::= 'filter' TypeAndValue ( ',' TypeAndValue )* bool LLParser::ParseLandingPad(Instruction *&Inst, PerFunctionState &PFS) { Type *Ty = nullptr; LocTy TyLoc; - Value *PersFn; LocTy PersFnLoc; - if (ParseType(Ty, TyLoc) || - ParseToken(lltok::kw_personality, "expected 'personality'") || - ParseTypeAndValue(PersFn, PersFnLoc, PFS)) + if (ParseType(Ty, TyLoc)) return true; - std::unique_ptr<LandingPadInst> LP(LandingPadInst::Create(Ty, PersFn, 0)); + std::unique_ptr<LandingPadInst> LP(LandingPadInst::Create(Ty, 0)); LP->setCleanup(EatIfPresent(lltok::kw_cleanup)); while (Lex.getKind() == lltok::kw_catch || Lex.getKind() == lltok::kw_filter){ diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 10e0410c025..ccb9d5dd038 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -150,6 +150,7 @@ class BitcodeReader : public GVMaterializer { std::vector<std::pair<GlobalAlias*, unsigned> > AliasInits; std::vector<std::pair<Function*, unsigned> > FunctionPrefixes; std::vector<std::pair<Function*, unsigned> > FunctionPrologues; + std::vector<std::pair<Function*, unsigned> > FunctionPersonalityFns; SmallVector<Instruction*, 64> InstsWithTBAATag; @@ -2031,11 +2032,13 @@ std::error_code BitcodeReader::resolveGlobalAndAliasInits() { std::vector<std::pair<GlobalAlias*, unsigned> > AliasInitWorklist; std::vector<std::pair<Function*, unsigned> > FunctionPrefixWorklist; std::vector<std::pair<Function*, unsigned> > FunctionPrologueWorklist; + std::vector<std::pair<Function*, unsigned> > FunctionPersonalityFnWorklist; GlobalInitWorklist.swap(GlobalInits); AliasInitWorklist.swap(AliasInits); FunctionPrefixWorklist.swap(FunctionPrefixes); FunctionPrologueWorklist.swap(FunctionPrologues); + FunctionPersonalityFnWorklist.swap(FunctionPersonalityFns); while (!GlobalInitWorklist.empty()) { unsigned ValID = GlobalInitWorklist.back().second; @@ -2093,6 +2096,19 @@ std::error_code BitcodeReader::resolveGlobalAndAliasInits() { FunctionPrologueWorklist.pop_back(); } + while (!FunctionPersonalityFnWorklist.empty()) { + unsigned ValID = FunctionPersonalityFnWorklist.back().second; + if (ValID >= ValueList.size()) { + FunctionPersonalityFns.push_back(FunctionPersonalityFnWorklist.back()); + } else { + if (Constant *C = dyn_cast_or_null<Constant>(ValueList[ValID])) + FunctionPersonalityFnWorklist.back().first->setPersonalityFn(C); + else + return error("Expected a constant"); + } + FunctionPersonalityFnWorklist.pop_back(); + } + return std::error_code(); } @@ -3023,6 +3039,9 @@ std::error_code BitcodeReader::parseModule(bool Resume, if (Record.size() > 13 && Record[13] != 0) FunctionPrefixes.push_back(std::make_pair(Func, Record[13]-1)); + if (Record.size() > 14 && Record[14] != 0) + FunctionPersonalityFns.push_back(std::make_pair(Func, Record[14] - 1)); + ValueList.push_back(Func); // If this is a function with a body, remember the prototype we are @@ -3976,21 +3995,35 @@ std::error_code BitcodeReader::parseFunctionBody(Function *F) { break; } - case bitc::FUNC_CODE_INST_LANDINGPAD: { + case bitc::FUNC_CODE_INST_LANDINGPAD: + case bitc::FUNC_CODE_INST_LANDINGPAD_OLD: { // LANDINGPAD: [ty, val, val, num, (id0,val0 ...)?] unsigned Idx = 0; - if (Record.size() < 4) - return error("Invalid record"); + if (BitCode == bitc::FUNC_CODE_INST_LANDINGPAD) { + if (Record.size() < 3) + return error("Invalid record"); + } else { + assert(BitCode == bitc::FUNC_CODE_INST_LANDINGPAD_OLD); + if (Record.size() < 4) + return error("Invalid record"); + } Type *Ty = getTypeByID(Record[Idx++]); if (!Ty) return error("Invalid record"); - Value *PersFn = nullptr; - if (getValueTypePair(Record, Idx, NextValueNo, PersFn)) - return error("Invalid record"); + if (BitCode == bitc::FUNC_CODE_INST_LANDINGPAD_OLD) { + Value *PersFn = nullptr; + if (getValueTypePair(Record, Idx, NextValueNo, PersFn)) + return error("Invalid record"); + + if (!F->hasPersonalityFn()) + F->setPersonalityFn(cast<Constant>(PersFn)); + else if (F->getPersonalityFn() != cast<Constant>(PersFn)) + return error("Personality function mismatch"); + } bool IsCleanup = !!Record[Idx++]; unsigned NumClauses = Record[Idx++]; - LandingPadInst *LP = LandingPadInst::Create(Ty, PersFn, NumClauses); + LandingPadInst *LP = LandingPadInst::Create(Ty, NumClauses); LP->setCleanup(IsCleanup); for (unsigned J = 0; J != NumClauses; ++J) { LandingPadInst::ClauseType CT = diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index cb8fafd3450..6da329d3b23 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -695,7 +695,7 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, for (const Function &F : *M) { // FUNCTION: [type, callingconv, isproto, linkage, paramattrs, alignment, // section, visibility, gc, unnamed_addr, prologuedata, - // dllstorageclass, comdat, prefixdata] + // dllstorageclass, comdat, prefixdata, personalityfn] Vals.push_back(VE.getTypeID(F.getFunctionType())); Vals.push_back(F.getCallingConv()); Vals.push_back(F.isDeclaration()); @@ -712,6 +712,8 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, Vals.push_back(F.hasComdat() ? VE.getComdatID(F.getComdat()) : 0); Vals.push_back(F.hasPrefixData() ? (VE.getValueID(F.getPrefixData()) + 1) : 0); + Vals.push_back( + F.hasPersonalityFn() ? (VE.getValueID(F.getPersonalityFn()) + 1) : 0); unsigned AbbrevToUse = 0; Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse); @@ -1859,7 +1861,6 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, const LandingPadInst &LP = cast<LandingPadInst>(I); Code = bitc::FUNC_CODE_INST_LANDINGPAD; Vals.push_back(VE.getTypeID(LP.getType())); - PushValueAndType(LP.getPersonalityFn(), InstID, Vals, VE); Vals.push_back(LP.isCleanup()); Vals.push_back(LP.getNumClauses()); for (unsigned I = 0, E = LP.getNumClauses(); I != E; ++I) { diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp index 74d4dd89bb4..fbbe93f6877 100644 --- a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -93,6 +93,9 @@ static OrderMap orderModule(const Module &M) { if (F.hasPrologueData()) if (!isa<GlobalValue>(F.getPrologueData())) orderValue(F.getPrologueData(), OM); + if (F.hasPersonalityFn()) + if (!isa<GlobalValue>(F.getPersonalityFn())) + orderValue(F.getPersonalityFn(), OM); } OM.LastGlobalConstantID = OM.size(); @@ -274,6 +277,8 @@ static UseListOrderStack predictUseListOrder(const Module &M) { predictValueUseListOrder(F.getPrefixData(), nullptr, OM, Stack); if (F.hasPrologueData()) predictValueUseListOrder(F.getPrologueData(), nullptr, OM, Stack); + if (F.hasPersonalityFn()) + predictValueUseListOrder(F.getPersonalityFn(), nullptr, OM, Stack); } return Stack; @@ -326,6 +331,11 @@ ValueEnumerator::ValueEnumerator(const Module &M, if (F.hasPrologueData()) EnumerateValue(F.getPrologueData()); + // Enumerate the personality functions. + for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) + if (I->hasPersonalityFn()) + EnumerateValue(I->getPersonalityFn()); + // Enumerate the metadata type. // // TODO: Move this to ValueEnumerator::EnumerateOperandType() once bitcode diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 4c194c263b0..3c2f1d9ebcf 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -548,6 +548,10 @@ void AsmPrinter::EmitFunctionHeader() { if (F->hasPrefixData()) EmitGlobalConstant(F->getPrefixData()); + // Emit the personality function. + if (F->hasPersonalityFn()) + EmitGlobalConstant(F->getPersonalityFn()); + // Emit the CurrentFnSym. This is a virtual function to allow targets to // do their wild and crazy things as required. EmitFunctionEntryLabel(); diff --git a/llvm/lib/CodeGen/DwarfEHPrepare.cpp b/llvm/lib/CodeGen/DwarfEHPrepare.cpp index 42656fb08db..e019dfbc8f7 100644 --- a/llvm/lib/CodeGen/DwarfEHPrepare.cpp +++ b/llvm/lib/CodeGen/DwarfEHPrepare.cpp @@ -181,27 +181,22 @@ size_t DwarfEHPrepare::pruneUnreachableResumes( bool DwarfEHPrepare::InsertUnwindResumeCalls(Function &Fn) { SmallVector<ResumeInst*, 16> Resumes; SmallVector<LandingPadInst*, 16> CleanupLPads; - bool FoundLP = false; for (BasicBlock &BB : Fn) { if (auto *RI = dyn_cast<ResumeInst>(BB.getTerminator())) Resumes.push_back(RI); - if (auto *LP = BB.getLandingPadInst()) { + if (auto *LP = BB.getLandingPadInst()) if (LP->isCleanup()) CleanupLPads.push_back(LP); - // Check the personality on the first landingpad. Don't do anything if - // it's for MSVC. - if (!FoundLP) { - FoundLP = true; - EHPersonality Pers = classifyEHPersonality(LP->getPersonalityFn()); - if (isMSVCEHPersonality(Pers)) - return false; - } - } } if (Resumes.empty()) return false; + // Check the personality, don't do anything if it's for MSVC. + EHPersonality Pers = classifyEHPersonality(Fn.getPersonalityFn()); + if (isMSVCEHPersonality(Pers)) + return false; + LLVMContext &Ctx = Fn.getContext(); size_t ResumesLeft = pruneUnreachableResumes(Fn, Resumes, CleanupLPads); diff --git a/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp index e6116245bb4..ecaa2c97271 100644 --- a/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp @@ -259,8 +259,8 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf, // If this is an MSVC EH personality, we need to do a bit more work. EHPersonality Personality = EHPersonality::Unknown; - if (!LPads.empty()) - Personality = classifyEHPersonality(LPads.back()->getPersonalityFn()); + if (Fn->hasPersonalityFn()) + Personality = classifyEHPersonality(Fn->getPersonalityFn()); if (!isMSVCEHPersonality(Personality)) return; @@ -546,8 +546,10 @@ void llvm::ComputeUsesVAFloatArgument(const CallInst &I, /// landingpad instruction and add them to the specified machine module info. void llvm::AddLandingPadInfo(const LandingPadInst &I, MachineModuleInfo &MMI, MachineBasicBlock *MBB) { - MMI.addPersonality(MBB, - cast<Function>(I.getPersonalityFn()->stripPointerCasts())); + MMI.addPersonality( + MBB, + cast<Function>( + I.getParent()->getParent()->getPersonalityFn()->stripPointerCasts())); if (I.isCleanup()) MMI.addCleanup(MBB); diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 22f592afae7..ec5a6bfa3dd 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -938,8 +938,10 @@ bool SelectionDAGISel::PrepareEHLandingPad() { // pad into several BBs. const BasicBlock *LLVMBB = MBB->getBasicBlock(); const LandingPadInst *LPadInst = LLVMBB->getLandingPadInst(); - MF->getMMI().addPersonality( - MBB, cast<Function>(LPadInst->getPersonalityFn()->stripPointerCasts())); + MF->getMMI().addPersonality(MBB, cast<Function>(LPadInst->getParent() + ->getParent() + ->getPersonalityFn() + ->stripPointerCasts())); EHPersonality Personality = MF->getMMI().getPersonalityType(); if (isMSVCEHPersonality(Personality)) { diff --git a/llvm/lib/CodeGen/ShadowStackGCLowering.cpp b/llvm/lib/CodeGen/ShadowStackGCLowering.cpp index 7c0b2bb4569..e7b2a8e72d2 100644 --- a/llvm/lib/CodeGen/ShadowStackGCLowering.cpp +++ b/llvm/lib/CodeGen/ShadowStackGCLowering.cpp @@ -144,10 +144,14 @@ public: BasicBlock *CleanupBB = BasicBlock::Create(C, CleanupBBName, &F); Type *ExnTy = StructType::get(Type::getInt8PtrTy(C), Type::getInt32Ty(C), nullptr); - Constant *PersFn = F.getParent()->getOrInsertFunction( - "__gcc_personality_v0", FunctionType::get(Type::getInt32Ty(C), true)); + if (!F.hasPersonalityFn()) { + Constant *PersFn = F.getParent()->getOrInsertFunction( + "__gcc_personality_v0", + FunctionType::get(Type::getInt32Ty(C), true)); + F.setPersonalityFn(PersFn); + } LandingPadInst *LPad = - LandingPadInst::Create(ExnTy, PersFn, 1, "cleanup.lpad", CleanupBB); + LandingPadInst::Create(ExnTy, 1, "cleanup.lpad", CleanupBB); LPad->setCleanup(true); ResumeInst *RI = ResumeInst::Create(LPad, CleanupBB); diff --git a/llvm/lib/CodeGen/SjLjEHPrepare.cpp b/llvm/lib/CodeGen/SjLjEHPrepare.cpp index 42d277ebed0..116fd5be033 100644 --- a/llvm/lib/CodeGen/SjLjEHPrepare.cpp +++ b/llvm/lib/CodeGen/SjLjEHPrepare.cpp @@ -227,7 +227,7 @@ Value *SjLjEHPrepare::setupFunctionContext(Function &F, // Personality function IRBuilder<> Builder(EntryBB->getTerminator()); if (!PersonalityFn) - PersonalityFn = LPads[0]->getPersonalityFn(); + PersonalityFn = F.getPersonalityFn(); Value *PersonalityFieldPtr = Builder.CreateConstGEP2_32( FunctionContextTy, FuncCtx, 0, 3, "pers_fn_gep"); Builder.CreateStore( diff --git a/llvm/lib/CodeGen/WinEHPrepare.cpp b/llvm/lib/CodeGen/WinEHPrepare.cpp index 6bdc9c95d61..7934a4d9da2 100644 --- a/llvm/lib/CodeGen/WinEHPrepare.cpp +++ b/llvm/lib/CodeGen/WinEHPrepare.cpp @@ -111,7 +111,7 @@ private: bool outlineHandler(ActionHandler *Action, Function *SrcFn, LandingPadInst *LPad, BasicBlock *StartBB, FrameVarInfoMap &VarInfo); - void addStubInvokeToHandlerIfNeeded(Function *Handler, Value *PersonalityFn); + void addStubInvokeToHandlerIfNeeded(Function *Handler); void mapLandingPadBlocks(LandingPadInst *LPad, LandingPadActions &Actions); CatchHandler *findCatchHandler(BasicBlock *BB, BasicBlock *&NextBB, @@ -379,7 +379,7 @@ bool WinEHPrepare::runOnFunction(Function &Fn) { return false; // Classify the personality to see what kind of preparation we need. - Personality = classifyEHPersonality(LPads.back()->getPersonalityFn()); + Personality = classifyEHPersonality(Fn.getPersonalityFn()); // Do nothing if this is not an MSVC personality. if (!isMSVCEHPersonality(Personality)) @@ -1265,8 +1265,7 @@ static bool isCatchBlock(BasicBlock *BB) { return false; } -static BasicBlock *createStubLandingPad(Function *Handler, - Value *PersonalityFn) { +static BasicBlock *createStubLandingPad(Function *Handler) { // FIXME: Finish this! LLVMContext &Context = Handler->getContext(); BasicBlock *StubBB = BasicBlock::Create(Context, "stub"); @@ -1275,7 +1274,7 @@ static BasicBlock *createStubLandingPad(Function *Handler, LandingPadInst *LPad = Builder.CreateLandingPad( llvm::StructType::get(Type::getInt8PtrTy(Context), Type::getInt32Ty(Context), nullptr), - PersonalityFn, 0); + 0); // Insert a call to llvm.eh.actions so that we don't try to outline this lpad. Function *ActionIntrin = Intrinsic::getDeclaration(Handler->getParent(), Intrinsic::eh_actions); @@ -1290,8 +1289,7 @@ static BasicBlock *createStubLandingPad(Function *Handler, // landing pad if none is found. The code that generates the .xdata tables for // the handler needs at least one landing pad to identify the parent function's // personality. -void WinEHPrepare::addStubInvokeToHandlerIfNeeded(Function *Handler, - Value *PersonalityFn) { +void WinEHPrepare::addStubInvokeToHandlerIfNeeded(Function *Handler) { ReturnInst *Ret = nullptr; UnreachableInst *Unreached = nullptr; for (BasicBlock &BB : *Handler) { @@ -1323,7 +1321,7 @@ void WinEHPrepare::addStubInvokeToHandlerIfNeeded(Function *Handler, // parent block. We want to replace that with an invoke call, so we can // erase it now. OldRetBB->getTerminator()->eraseFromParent(); - BasicBlock *StubLandingPad = createStubLandingPad(Handler, PersonalityFn); + BasicBlock *StubLandingPad = createStubLandingPad(Handler); Function *F = Intrinsic::getDeclaration(Handler->getParent(), Intrinsic::donothing); InvokeInst::Create(F, NewRetBB, StubLandingPad, None, "", OldRetBB); @@ -1379,6 +1377,7 @@ bool WinEHPrepare::outlineHandler(ActionHandler *Action, Function *SrcFn, Handler = createHandlerFunc(Type::getVoidTy(Context), SrcFn->getName() + ".cleanup", M, ParentFP); } + Handler->setPersonalityFn(SrcFn->getPersonalityFn()); HandlerToParentFP[Handler] = ParentFP; Handler->addFnAttr("wineh-parent", SrcFn->getName()); BasicBlock *Entry = &Handler->getEntryBlock(); @@ -1456,7 +1455,7 @@ bool WinEHPrepare::outlineHandler(ActionHandler *Action, Function *SrcFn, ClonedEntryBB->eraseFromParent(); // Make sure we can identify the handler's personality later. - addStubInvokeToHandlerIfNeeded(Handler, LPad->getPersonalityFn()); + addStubInvokeToHandlerIfNeeded(Handler); if (auto *CatchAction = dyn_cast<CatchHandler>(Action)) { WinEHCatchDirector *CatchDirector = diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 05f7e08555f..23393ccd5c0 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -109,6 +109,10 @@ static OrderMap orderModule(const Module *M) { if (!isa<GlobalValue>(F.getPrologueData())) orderValue(F.getPrologueData(), OM); + if (F.hasPersonalityFn()) + if (!isa<GlobalValue>(F.getPersonalityFn())) + orderValue(F.getPersonalityFn(), OM); + orderValue(&F, OM); if (F.isDeclaration()) @@ -2540,6 +2544,10 @@ void AssemblyWriter::printFunction(const Function *F) { Out << " prologue "; writeOperand(F->getPrologueData(), true); } + if (F->hasPersonalityFn()) { + Out << " personality "; + writeOperand(F->getPersonalityFn(), /*PrintType=*/true); + } SmallVector<std::pair<unsigned, MDNode *>, 4> MDs; F->getAllMetadata(MDs); @@ -2782,8 +2790,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) { } else if (const LandingPadInst *LPI = dyn_cast<LandingPadInst>(&I)) { Out << ' '; TypePrinter.print(I.getType(), Out); - Out << " personality "; - writeOperand(I.getOperand(0), true); Out << '\n'; + if (LPI->isCleanup() || LPI->getNumClauses() != 0) + Out << '\n'; if (LPI->isCleanup()) Out << " cleanup"; diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp index d476434542e..23e923d4112 100644 --- a/llvm/lib/IR/Core.cpp +++ b/llvm/lib/IR/Core.cpp @@ -2249,11 +2249,8 @@ LLVMValueRef LLVMBuildInvoke(LLVMBuilderRef B, LLVMValueRef Fn, } LLVMValueRef LLVMBuildLandingPad(LLVMBuilderRef B, LLVMTypeRef Ty, - LLVMValueRef PersFn, unsigned NumClauses, - const char *Name) { - return wrap(unwrap(B)->CreateLandingPad(unwrap(Ty), - cast<Function>(unwrap(PersFn)), - NumClauses, Name)); + unsigned NumClauses, const char *Name) { + return wrap(unwrap(B)->CreateLandingPad(unwrap(Ty), NumClauses, Name)); } LLVMValueRef LLVMBuildResume(LLVMBuilderRef B, LLVMValueRef Exn) { diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index 2b439bb46bf..bc57dee0af0 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -248,8 +248,8 @@ void Function::eraseFromParent() { Function::Function(FunctionType *Ty, LinkageTypes Linkage, const Twine &name, Module *ParentModule) - : GlobalObject(PointerType::getUnqual(Ty), Value::FunctionVal, nullptr, 0, - Linkage, name), + : GlobalObject(PointerType::getUnqual(Ty), Value::FunctionVal, + OperandTraits<Function>::op_begin(this), 0, Linkage, name), Ty(Ty) { assert(FunctionType::isValidReturnType(getReturnType()) && "invalid return type"); @@ -279,6 +279,9 @@ Function::~Function() { // Remove the function from the on-the-side GC table. clearGC(); + + // FIXME: needed by operator delete + setFunctionNumOperands(1); } void Function::BuildLazyArguments() const { @@ -331,6 +334,8 @@ void Function::dropAllReferences() { // Metadata is stored in a side-table. clearMetadata(); + + setPersonalityFn(nullptr); } void Function::addAttribute(unsigned i, Attribute::AttrKind attr) { @@ -426,6 +431,10 @@ void Function::copyAttributesFrom(const GlobalValue *Src) { setPrologueData(SrcF->getPrologueData()); else setPrologueData(nullptr); + if (SrcF->hasPersonalityFn()) + setPersonalityFn(SrcF->getPersonalityFn()); + else + setPersonalityFn(nullptr); } /// \brief This does the actual lookup of an intrinsic ID which @@ -976,3 +985,22 @@ Optional<uint64_t> Function::getEntryCount() const { } return None; } + +void Function::setPersonalityFn(Constant *C) { + if (!C) { + if (hasPersonalityFn()) { + // Note, the num operands is used to compute the offset of the operand, so + // the order here matters. Clearing the operand then clearing the num + // operands ensures we have the correct offset to the operand. + Op<0>().set(nullptr); + setFunctionNumOperands(0); + } + } else { + // Note, the num operands is used to compute the offset of the operand, so + // the order here matters. We need to set num operands to 1 first so that + // we get the correct offset to the first operand when we set it. + if (!hasPersonalityFn()) + setFunctionNumOperands(1); + Op<0>().set(C); + } +} diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp index 0e2fe391aa6..d45b5110536 100644 --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -153,18 +153,16 @@ Value *PHINode::hasConstantValue() const { // LandingPadInst Implementation //===----------------------------------------------------------------------===// -LandingPadInst::LandingPadInst(Type *RetTy, Value *PersonalityFn, - unsigned NumReservedValues, const Twine &NameStr, - Instruction *InsertBefore) - : Instruction(RetTy, Instruction::LandingPad, nullptr, 0, InsertBefore) { - init(PersonalityFn, 1 + NumReservedValues, NameStr); +LandingPadInst::LandingPadInst(Type *RetTy, unsigned NumReservedValues, + const Twine &NameStr, Instruction *InsertBefore) + : Instruction(RetTy, Instruction::LandingPad, nullptr, 0, InsertBefore) { + init(NumReservedValues, NameStr); } -LandingPadInst::LandingPadInst(Type *RetTy, Value *PersonalityFn, - unsigned NumReservedValues, const Twine &NameStr, - BasicBlock *InsertAtEnd) - : Instruction(RetTy, Instruction::LandingPad, nullptr, 0, InsertAtEnd) { - init(PersonalityFn, 1 + NumReservedValues, NameStr); +LandingPadInst::LandingPadInst(Type *RetTy, unsigned NumReservedValues, + const Twine &NameStr, BasicBlock *InsertAtEnd) + : Instruction(RetTy, Instruction::LandingPad, nullptr, 0, InsertAtEnd) { + init(NumReservedValues, NameStr); } LandingPadInst::LandingPadInst(const LandingPadInst &LP) @@ -180,28 +178,22 @@ LandingPadInst::LandingPadInst(const LandingPadInst &LP) setCleanup(LP.isCleanup()); } -LandingPadInst *LandingPadInst::Create(Type *RetTy, Value *PersonalityFn, - unsigned NumReservedClauses, +LandingPadInst *LandingPadInst::Create(Type *RetTy, unsigned NumReservedClauses, const Twine &NameStr, Instruction *InsertBefore) { - return new LandingPadInst(RetTy, PersonalityFn, NumReservedClauses, NameStr, - InsertBefore); + return new LandingPadInst(RetTy, NumReservedClauses, NameStr, InsertBefore); } -LandingPadInst *LandingPadInst::Create(Type *RetTy, Value *PersonalityFn, - unsigned NumReservedClauses, +LandingPadInst *LandingPadInst::Create(Type *RetTy, unsigned NumReservedClauses, const Twine &NameStr, BasicBlock *InsertAtEnd) { - return new LandingPadInst(RetTy, PersonalityFn, NumReservedClauses, NameStr, - InsertAtEnd); + return new LandingPadInst(RetTy, NumReservedClauses, NameStr, InsertAtEnd); } -void LandingPadInst::init(Value *PersFn, unsigned NumReservedValues, - const Twine &NameStr) { +void LandingPadInst::init(unsigned NumReservedValues, const Twine &NameStr) { ReservedSpace = NumReservedValues; - setNumHungOffUseOperands(1); + setNumHungOffUseOperands(0); allocHungoffUses(ReservedSpace); - Op<0>() = PersFn; setName(NameStr); setCleanup(false); } @@ -211,7 +203,7 @@ void LandingPadInst::init(Value *PersFn, unsigned NumReservedValues, void LandingPadInst::growOperands(unsigned Size) { unsigned e = getNumOperands(); if (ReservedSpace >= e + Size) return; - ReservedSpace = (e + Size / 2) * 2; + ReservedSpace = (std::max(e, 1U) + Size / 2) * 2; growHungoffUses(ReservedSpace); } diff --git a/llvm/lib/IR/TypeFinder.cpp b/llvm/lib/IR/TypeFinder.cpp index 1d2b808d650..7accc5bef53 100644 --- a/llvm/lib/IR/TypeFinder.cpp +++ b/llvm/lib/IR/TypeFinder.cpp @@ -50,6 +50,9 @@ void TypeFinder::run(const Module &M, bool onlyNamed) { if (FI->hasPrologueData()) incorporateValue(FI->getPrologueData()); + if (FI->hasPersonalityFn()) + incorporateValue(FI->getPersonalityFn()); + // First incorporate the arguments. for (Function::const_arg_iterator AI = FI->arg_begin(), AE = FI->arg_end(); AI != AE; ++AI) diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 13b451a06b2..51d1cdbb117 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -181,11 +181,6 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport { /// \brief Track unresolved string-based type references. SmallDenseMap<const MDString *, const MDNode *, 32> UnresolvedTypeRefs; - /// \brief The personality function referenced by the LandingPadInsts. - /// All LandingPadInsts within the same function must use the same - /// personality function. - const Value *PersonalityFn; - /// \brief Whether we've seen a call to @llvm.frameescape in this function /// already. bool SawFrameEscape; @@ -196,8 +191,7 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport { public: explicit Verifier(raw_ostream &OS) - : VerifierSupport(OS), Context(nullptr), PersonalityFn(nullptr), - SawFrameEscape(false) {} + : VerifierSupport(OS), Context(nullptr), SawFrameEscape(false) {} bool verify(const Function &F) { M = F.getParent(); @@ -231,7 +225,6 @@ public: // FIXME: We strip const here because the inst visitor strips const. visit(const_cast<Function &>(F)); InstsInThisBlock.clear(); - PersonalityFn = nullptr; SawFrameEscape = false; return !Broken; @@ -1757,6 +1750,8 @@ void Verifier::visitFunction(const Function &F) { "invalid linkage type for function declaration", &F); Assert(MDs.empty(), "function without a body cannot have metadata", &F, MDs.empty() ? nullptr : MDs.front().second); + Assert(!F.hasPersonalityFn(), + "Function declaration shouldn't have a personality routine", &F); } else { // Verify that this function (which has a body) is not named "llvm.*". It // is not legal to define intrinsics. @@ -2795,22 +2790,16 @@ void Verifier::visitLandingPadInst(LandingPadInst &LPI) { &LPI); } + Function *F = LPI.getParent()->getParent(); + Assert(F->hasPersonalityFn(), + "LandingPadInst needs to be in a function with a personality.", &LPI); + // The landingpad instruction must be the first non-PHI instruction in the // block. Assert(LPI.getParent()->getLandingPadInst() == &LPI, "LandingPadInst not the first non-PHI instruction in the block.", &LPI); - // The personality functions for all landingpad instructions within the same - // function should match. - if (PersonalityFn) - Assert(LPI.getPersonalityFn() == PersonalityFn, - "Personality function doesn't match others in function", &LPI); - PersonalityFn = LPI.getPersonalityFn(); - - // All operands must be constants. - Assert(isa<Constant>(PersonalityFn), "Personality function is not constant!", - &LPI); for (unsigned i = 0, e = LPI.getNumClauses(); i < e; ++i) { Constant *Clause = LPI.getClause(i); if (LPI.isCatch(i)) { diff --git a/llvm/lib/Linker/LinkModules.cpp b/llvm/lib/Linker/LinkModules.cpp index 484a457876b..7ae8c025e33 100644 --- a/llvm/lib/Linker/LinkModules.cpp +++ b/llvm/lib/Linker/LinkModules.cpp @@ -1194,6 +1194,11 @@ bool ModuleLinker::linkFunctionBody(Function &Dst, Function &Src) { Dst.setPrologueData(MapValue(Src.getPrologueData(), ValueMap, RF_None, &TypeMap, &ValMaterializer)); + // Link in the personality function. + if (Src.hasPersonalityFn()) + Dst.setPersonalityFn(MapValue(Src.getPersonalityFn(), ValueMap, RF_None, + &TypeMap, &ValMaterializer)); + // Go through and convert function arguments over, remembering the mapping. Function::arg_iterator DI = Dst.arg_begin(); for (Argument &Arg : Src.args()) { diff --git a/llvm/lib/Target/X86/X86WinEHState.cpp b/llvm/lib/Target/X86/X86WinEHState.cpp index 356d0a77132..673141105b3 100644 --- a/llvm/lib/Target/X86/X86WinEHState.cpp +++ b/llvm/lib/Target/X86/X86WinEHState.cpp @@ -146,16 +146,10 @@ bool WinEHStatePass::runOnFunction(Function &F) { return false; // Check the personality. Do nothing if this is not an MSVC personality. - LandingPadInst *LP = nullptr; - for (BasicBlock &BB : F) { - LP = BB.getLandingPadInst(); - if (LP) - break; - } - if (!LP) + if (!F.hasPersonalityFn()) return false; PersonalityFn = - dyn_cast<Function>(LP->getPersonalityFn()->stripPointerCasts()); + dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts()); if (!PersonalityFn) return false; Personality = classifyEHPersonality(PersonalityFn); diff --git a/llvm/lib/Transforms/IPO/GlobalDCE.cpp b/llvm/lib/Transforms/IPO/GlobalDCE.cpp index ba04c80508c..61d0ff94a34 100644 --- a/llvm/lib/Transforms/IPO/GlobalDCE.cpp +++ b/llvm/lib/Transforms/IPO/GlobalDCE.cpp @@ -228,6 +228,9 @@ void GlobalDCE::GlobalIsNeeded(GlobalValue *G) { if (F->hasPrologueData()) MarkUsedGlobalsAsNeeded(F->getPrologueData()); + if (F->hasPersonalityFn()) + MarkUsedGlobalsAsNeeded(F->getPersonalityFn()); + for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) for (User::op_iterator U = I->op_begin(), E = I->op_end(); U != E; ++U) diff --git a/llvm/lib/Transforms/IPO/PruneEH.cpp b/llvm/lib/Transforms/IPO/PruneEH.cpp index 1943b930cbf..ade31d05525 100644 --- a/llvm/lib/Transforms/IPO/PruneEH.cpp +++ b/llvm/lib/Transforms/IPO/PruneEH.cpp @@ -177,7 +177,7 @@ bool PruneEH::SimplifyFunction(Function *F) { bool MadeChange = false; for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { if (InvokeInst *II = dyn_cast<InvokeInst>(BB->getTerminator())) - if (II->doesNotThrow() && canSimplifyInvokeNoUnwind(II)) { + if (II->doesNotThrow() && canSimplifyInvokeNoUnwind(F)) { SmallVector<Value*, 8> Args(II->op_begin(), II->op_end() - 3); // Insert a call instruction before the invoke. CallInst *Call = CallInst::Create(II->getCalledValue(), Args, "", II); diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index 9d602c6a9e2..d690a795e00 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -2353,7 +2353,8 @@ Instruction *InstCombiner::visitLandingPadInst(LandingPadInst &LI) { // The logic here should be correct for any real-world personality function. // However if that turns out not to be true, the offending logic can always // be conditioned on the personality function, like the catch-all logic is. - EHPersonality Personality = classifyEHPersonality(LI.getPersonalityFn()); + EHPersonality Personality = + classifyEHPersonality(LI.getParent()->getParent()->getPersonalityFn()); // Simplify the list of clauses, eg by removing repeated catch clauses // (these are often created by inlining). @@ -2620,7 +2621,6 @@ Instruction *InstCombiner::visitLandingPadInst(LandingPadInst &LI) { // with a new one. if (MakeNewInstruction) { LandingPadInst *NLI = LandingPadInst::Create(LI.getType(), - LI.getPersonalityFn(), NewClauses.size()); for (unsigned i = 0, e = NewClauses.size(); i != e; ++i) NLI->addClause(NewClauses[i]); @@ -2691,7 +2691,8 @@ bool InstCombiner::run() { } // Instruction isn't dead, see if we can constant propagate it. - if (!I->use_empty() && isa<Constant>(I->getOperand(0))) { + if (!I->use_empty() && + (I->getNumOperands() == 0 || isa<Constant>(I->getOperand(0)))) { if (Constant *C = ConstantFoldInstruction(I, DL, TLI)) { DEBUG(dbgs() << "IC: ConstFold to: " << *C << " from: " << *I << '\n'); @@ -2846,7 +2847,8 @@ static bool AddReachableCodeToWorklist(BasicBlock *BB, const DataLayout &DL, } // ConstantProp instruction if trivially constant. - if (!Inst->use_empty() && isa<Constant>(Inst->getOperand(0))) + if (!Inst->use_empty() && + (Inst->getNumOperands() == 0 || isa<Constant>(Inst->getOperand(0)))) if (Constant *C = ConstantFoldInstruction(Inst, DL, TLI)) { DEBUG(dbgs() << "IC: ConstFold to: " << *C << " from: " << *Inst << '\n'); diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp index ddeaff06d3c..d2d60d7cd9f 100644 --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -949,35 +949,23 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI, } // Get the personality function from the callee if it contains a landing pad. - Value *CalleePersonality = nullptr; - for (Function::const_iterator I = CalledFunc->begin(), E = CalledFunc->end(); - I != E; ++I) - if (const InvokeInst *II = dyn_cast<InvokeInst>(I->getTerminator())) { - const BasicBlock *BB = II->getUnwindDest(); - const LandingPadInst *LP = BB->getLandingPadInst(); - CalleePersonality = LP->getPersonalityFn(); - break; - } + Constant *CalledPersonality = + CalledFunc->hasPersonalityFn() ? CalledFunc->getPersonalityFn() : nullptr; // Find the personality function used by the landing pads of the caller. If it // exists, then check to see that it matches the personality function used in // the callee. - if (CalleePersonality) { - for (Function::const_iterator I = Caller->begin(), E = Caller->end(); - I != E; ++I) - if (const InvokeInst *II = dyn_cast<InvokeInst>(I->getTerminator())) { - const BasicBlock *BB = II->getUnwindDest(); - const LandingPadInst *LP = BB->getLandingPadInst(); - - // If the personality functions match, then we can perform the - // inlining. Otherwise, we can't inline. - // TODO: This isn't 100% true. Some personality functions are proper - // supersets of others and can be used in place of the other. - if (LP->getPersonalityFn() != CalleePersonality) - return false; - - break; - } + Constant *CallerPersonality = + Caller->hasPersonalityFn() ? Caller->getPersonalityFn() : nullptr; + if (CalledPersonality) { + if (!CallerPersonality) + Caller->setPersonalityFn(CalledPersonality); + // If the personality functions match, then we can perform the + // inlining. Otherwise, we can't inline. + // TODO: This isn't 100% true. Some personality functions are proper + // supersets of others and can be used in place of the other. + else if (CalledPersonality != CallerPersonality) + return false; } // Get an iterator to the last basic block in the function, which will have diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index 70c77b06d62..57b4e23f226 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -1173,10 +1173,11 @@ static void changeToCall(InvokeInst *II) { II->eraseFromParent(); } -static bool markAliveBlocks(BasicBlock *BB, +static bool markAliveBlocks(Function &F, SmallPtrSetImpl<BasicBlock*> &Reachable) { SmallVector<BasicBlock*, 128> Worklist; + BasicBlock *BB = F.begin(); Worklist.push_back(BB); Reachable.insert(BB); bool Changed = false; @@ -1247,7 +1248,7 @@ static bool markAliveBlocks(BasicBlock *BB, if (isa<ConstantPointerNull>(Callee) || isa<UndefValue>(Callee)) { changeToUnreachable(II, true); Changed = true; - } else if (II->doesNotThrow() && canSimplifyInvokeNoUnwind(II)) { + } else if (II->doesNotThrow() && canSimplifyInvokeNoUnwind(&F)) { if (II->use_empty() && II->onlyReadsMemory()) { // jump to the normal destination branch. BranchInst::Create(II->getNormalDest(), II); @@ -1272,7 +1273,7 @@ static bool markAliveBlocks(BasicBlock *BB, /// otherwise. bool llvm::removeUnreachableBlocks(Function &F) { SmallPtrSet<BasicBlock*, 128> Reachable; - bool Changed = markAliveBlocks(F.begin(), Reachable); + bool Changed = markAliveBlocks(F, Reachable); // If there are unreachable blocks in the CFG... if (Reachable.size() == F.size()) |