diff --git a/llvm/include/llvm/Analysis/InlineCost.h b/llvm/include/llvm/Analysis/InlineCost.h --- a/llvm/include/llvm/Analysis/InlineCost.h +++ b/llvm/include/llvm/Analysis/InlineCost.h @@ -130,15 +130,23 @@ int getCostDelta() const { return Threshold - getCost(); } }; -/// InlineResult is basically true or false. For false results the message -/// describes a reason why it is decided not to inline. -struct InlineResult { - const char *message = nullptr; - InlineResult(bool result, const char *message = nullptr) - : message(result ? nullptr : (message ? message : "cost > threshold")) {} - InlineResult(const char *message = nullptr) : message(message) {} - operator bool() const { return !message; } - operator const char *() const { return message; } +/// ResultWithMessage is basically true or false. For false results the message +/// describes a reason. +class ResultWithMessage { + const char *Message = nullptr; + ResultWithMessage(const char *Message = nullptr) : Message(Message) {} + +public: + static ResultWithMessage success() { return {}; } + static ResultWithMessage failure(const char *Reason) { + return ResultWithMessage(Reason); + } + bool isSuccess() const { return Message == nullptr; } + const char *getFailureReason() const { + assert(!isSuccess() && + "getFailureReason should only be called in failure cases"); + return Message; + } }; /// Thresholds to tune inline cost analysis. The inline cost analysis decides @@ -231,7 +239,7 @@ ProfileSummaryInfo *PSI, OptimizationRemarkEmitter *ORE); /// Minimal filter to detect invalid constructs for inlining. -InlineResult isInlineViable(Function &Callee); +ResultWithMessage isInlineViable(Function &Callee); } #endif diff --git a/llvm/include/llvm/Transforms/Utils/Cloning.h b/llvm/include/llvm/Transforms/Utils/Cloning.h --- a/llvm/include/llvm/Transforms/Utils/Cloning.h +++ b/llvm/include/llvm/Transforms/Utils/Cloning.h @@ -229,13 +229,13 @@ /// and all varargs at the callsite will be passed to any calls to /// ForwardVarArgsTo. The caller of InlineFunction has to make sure any varargs /// are only used by ForwardVarArgsTo. -InlineResult InlineFunction(CallBase *CB, InlineFunctionInfo &IFI, - AAResults *CalleeAAR = nullptr, - bool InsertLifetime = true); -InlineResult InlineFunction(CallSite CS, InlineFunctionInfo &IFI, - AAResults *CalleeAAR = nullptr, - bool InsertLifetime = true, - Function *ForwardVarArgsTo = nullptr); +ResultWithMessage InlineFunction(CallBase *CB, InlineFunctionInfo &IFI, + AAResults *CalleeAAR = nullptr, + bool InsertLifetime = true); +ResultWithMessage InlineFunction(CallSite CS, InlineFunctionInfo &IFI, + AAResults *CalleeAAR = nullptr, + bool InsertLifetime = true, + Function *ForwardVarArgsTo = nullptr); /// Clones a loop \p OrigLoop. Returns the loop and the blocks in \p /// Blocks. diff --git a/llvm/lib/Analysis/InlineCost.cpp b/llvm/lib/Analysis/InlineCost.cpp --- a/llvm/lib/Analysis/InlineCost.cpp +++ b/llvm/lib/Analysis/InlineCost.cpp @@ -133,8 +133,9 @@ /// Called at the end of the analysis of the callsite. Return the outcome of /// the analysis, i.e. 'InlineResult(true)' if the inlining may happen, or /// the reason it can't. - virtual InlineResult finalizeAnalysis() { return true; } - + virtual ResultWithMessage finalizeAnalysis() { + return ResultWithMessage::success(); + } /// Called when we're about to start processing a basic block, and every time /// we are done processing an instruction. Return true if there is no point in /// continuing the analysis (e.g. we've determined already the call site is @@ -145,8 +146,9 @@ /// contexts propagated). It checks callsite-specific information. Return a /// reason analysis can't continue if that's the case, or 'true' if it may /// continue. - virtual InlineResult onAnalysisStart() { return true; } - + virtual ResultWithMessage onAnalysisStart() { + return ResultWithMessage::success(); + } /// Called if the analysis engine decides SROA cannot be done for the given /// alloca. virtual void onDisableSROA(AllocaInst *Arg) {} @@ -293,7 +295,7 @@ bool allowSizeGrowth(CallBase &Call); // Custom analysis routines. - InlineResult analyzeBlock(BasicBlock *BB, + ResultWithMessage analyzeBlock(BasicBlock *BB, SmallPtrSetImpl &EphValues); // Disable several entry points to the visitor so we don't accidentally use @@ -346,7 +348,7 @@ PSI(PSI), F(Callee), DL(F.getParent()->getDataLayout()), ORE(ORE), CandidateCall(Call), EnableLoadElimination(true) {} - InlineResult analyze(); + ResultWithMessage analyze(); // Keep a bunch of stats about the cost savings found so we can print them // out when debugging. @@ -458,7 +460,7 @@ /// to instantiate the derived class. InlineCostCallAnalyzer CA(TTI, GetAssumptionCache, GetBFI, PSI, ORE, *F, Call, IndirectCallParams, false); - if (CA.analyze()) { + if (CA.analyze().isSuccess()) { // We were able to inline the indirect call! Subtract the cost from the // threshold to get the bonus we want to apply, but don't go below zero. Cost -= std::max(0, CA.getThreshold() - CA.getCost()); @@ -538,7 +540,8 @@ SingleBB = false; } } - InlineResult finalizeAnalysis() override { + + ResultWithMessage finalizeAnalysis() override { // Loops generally act a lot like calls in that they act like barriers to // movement, require a certain amount of setup, etc. So when optimising for // size, we penalise any call sites that perform loops. We do this after all @@ -566,7 +569,9 @@ else if (NumVectorInstructions <= NumInstructions / 2) Threshold -= VectorBonus / 2; - return Cost < std::max(1, Threshold); + if (Cost < std::max(1, Threshold)) + return ResultWithMessage::success(); + return ResultWithMessage::failure("Cost over threshold."); } bool shouldStop() override { // Bail out the moment we cross the threshold. This means we'll under-count @@ -578,7 +583,7 @@ LoadEliminationCost += InlineConstants::InstrCost; } - InlineResult onAnalysisStart() override { + ResultWithMessage onAnalysisStart() override { // Perform some tweaks to the cost and threshold based on the direct // callsite information. @@ -618,9 +623,9 @@ // Check if we're done. This can happen due to bonuses and penalties. if (Cost >= Threshold && !ComputeFullInlineCost) - return "high cost"; + return ResultWithMessage::failure("high cost"); - return true; + return ResultWithMessage::success(); } public: @@ -1734,7 +1739,7 @@ /// aborts early if the threshold has been exceeded or an impossible to inline /// construct has been detected. It returns false if inlining is no longer /// viable, and true if inlining remains viable. -InlineResult +ResultWithMessage CallAnalyzer::analyzeBlock(BasicBlock *BB, SmallPtrSetImpl &EphValues) { for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) { @@ -1768,26 +1773,26 @@ using namespace ore; // If the visit this instruction detected an uninlinable pattern, abort. - InlineResult IR; + ResultWithMessage IR = ResultWithMessage::success(); if (IsRecursiveCall) - IR = "recursive"; + IR = ResultWithMessage::failure("recursive"); else if (ExposesReturnsTwice) - IR = "exposes returns twice"; + IR = ResultWithMessage::failure("exposes returns twice"); else if (HasDynamicAlloca) - IR = "dynamic alloca"; + IR = ResultWithMessage::failure("dynamic alloca"); else if (HasIndirectBr) - IR = "indirect branch"; + IR = ResultWithMessage::failure("indirect branch"); else if (HasUninlineableIntrinsic) - IR = "uninlinable intrinsic"; + IR = ResultWithMessage::failure("uninlinable intrinsic"); else if (InitsVargArgs) - IR = "varargs"; - if (!IR) { + IR = ResultWithMessage::failure("varargs"); + if (!IR.isSuccess()) { if (ORE) ORE->emit([&]() { return OptimizationRemarkMissed(DEBUG_TYPE, "NeverInline", &CandidateCall) << NV("Callee", &F) << " has uninlinable pattern (" - << NV("InlineResult", IR.message) + << NV("InlineResult", IR.getFailureReason()) << ") and cost is not fully computed"; }); return IR; @@ -1798,22 +1803,25 @@ // the caller stack usage dramatically. if (IsCallerRecursive && AllocatedSize > InlineConstants::TotalAllocaSizeRecursiveCaller) { - InlineResult IR = "recursive and allocates too much stack space"; + auto IR = ResultWithMessage::failure( + "recursive and allocates too much stack space"); if (ORE) ORE->emit([&]() { return OptimizationRemarkMissed(DEBUG_TYPE, "NeverInline", &CandidateCall) - << NV("Callee", &F) << " is " << NV("InlineResult", IR.message) + << NV("Callee", &F) << " is " + << NV("InlineResult", IR.getFailureReason()) << ". Cost is not fully computed"; }); return IR; } if (shouldStop()) - return false; + return ResultWithMessage::failure( + "Call site analysis is not favorable to inlining."); } - return true; + return ResultWithMessage::success(); } /// Compute the base pointer and cumulative constant offsets for V. @@ -1900,15 +1908,15 @@ /// factors and heuristics. If this method returns false but the computed cost /// is below the computed threshold, then inlining was forcibly disabled by /// some artifact of the routine. -InlineResult CallAnalyzer::analyze() { +ResultWithMessage CallAnalyzer::analyze() { ++NumCallsAnalyzed; auto Result = onAnalysisStart(); - if (!Result) + if (!Result.isSuccess()) return Result; if (F.empty()) - return true; + return ResultWithMessage::success(); Function *Caller = CandidateCall.getFunction(); // Check if the caller function is recursive itself. @@ -1983,12 +1991,13 @@ if (BB->hasAddressTaken()) for (User *U : BlockAddress::get(&*BB)->users()) if (!isa(*U)) - return "blockaddress used outside of callbr"; + return ResultWithMessage::failure( + "blockaddress used outside of callbr"); // Analyze the cost of this block. If we blow through the threshold, this // returns false, and we can bail on out. - InlineResult IR = analyzeBlock(BB, EphValues); - if (!IR) + ResultWithMessage IR = analyzeBlock(BB, EphValues); + if (!IR.isSuccess()) return IR; Instruction *TI = BB->getTerminator(); @@ -2034,7 +2043,7 @@ // inlining this would cause the removal of the caller (so the instruction // is not actually duplicated, just moved). if (!OnlyOneCallAndLocalLinkage && ContainsNoDuplicateCall) - return "noduplicate"; + return ResultWithMessage::failure("noduplicate"); return finalizeAnalysis(); } @@ -2140,9 +2149,9 @@ // whenever possible. if (Call.hasFnAttr(Attribute::AlwaysInline)) { auto IsViable = isInlineViable(*Callee); - if (IsViable) + if (IsViable.isSuccess()) return llvm::InlineCost::getAlways("always inline attribute"); - return llvm::InlineCost::getNever(IsViable.message); + return llvm::InlineCost::getNever(IsViable.getFailureReason()); } // Never inline functions with conflicting attributes (unless callee has @@ -2177,32 +2186,33 @@ InlineCostCallAnalyzer CA(CalleeTTI, GetAssumptionCache, GetBFI, PSI, ORE, *Callee, Call, Params); - InlineResult ShouldInline = CA.analyze(); + ResultWithMessage ShouldInline = CA.analyze(); LLVM_DEBUG(CA.dump()); // Check if there was a reason to force inlining or no inlining. - if (!ShouldInline && CA.getCost() < CA.getThreshold()) - return InlineCost::getNever(ShouldInline.message); - if (ShouldInline && CA.getCost() >= CA.getThreshold()) + if (!ShouldInline.isSuccess() && CA.getCost() < CA.getThreshold()) + return InlineCost::getNever(ShouldInline.getFailureReason()); + if (ShouldInline.isSuccess() && CA.getCost() >= CA.getThreshold()) return InlineCost::getAlways("empty function"); return llvm::InlineCost::get(CA.getCost(), CA.getThreshold()); } -InlineResult llvm::isInlineViable(Function &F) { +ResultWithMessage llvm::isInlineViable(Function &F) { bool ReturnsTwice = F.hasFnAttribute(Attribute::ReturnsTwice); for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE; ++BI) { // Disallow inlining of functions which contain indirect branches. if (isa(BI->getTerminator())) - return "contains indirect branches"; + return ResultWithMessage::failure("contains indirect branches"); // Disallow inlining of blockaddresses which are used by non-callbr // instructions. if (BI->hasAddressTaken()) for (User *U : BlockAddress::get(&*BI)->users()) if (!isa(*U)) - return "blockaddress used outside of callbr"; + return ResultWithMessage::failure( + "blockaddress used outside of callbr"); for (auto &II : *BI) { CallBase *Call = dyn_cast(&II); @@ -2211,13 +2221,13 @@ // Disallow recursive calls. if (&F == Call->getCalledFunction()) - return "recursive call"; + return ResultWithMessage::failure("recursive call"); // Disallow calls which expose returns-twice to a function not previously // attributed as such. if (!ReturnsTwice && isa(Call) && cast(Call)->canReturnTwice()) - return "exposes returns-twice attribute"; + return ResultWithMessage::failure("exposes returns-twice attribute"); if (Call->getCalledFunction()) switch (Call->getCalledFunction()->getIntrinsicID()) { @@ -2226,20 +2236,23 @@ case llvm::Intrinsic::icall_branch_funnel: // Disallow inlining of @llvm.icall.branch.funnel because current // backend can't separate call targets from call arguments. - return "disallowed inlining of @llvm.icall.branch.funnel"; + return ResultWithMessage::failure( + "disallowed inlining of @llvm.icall.branch.funnel"); case llvm::Intrinsic::localescape: // Disallow inlining functions that call @llvm.localescape. Doing this // correctly would require major changes to the inliner. - return "disallowed inlining of @llvm.localescape"; + return ResultWithMessage::failure( + "disallowed inlining of @llvm.localescape"); case llvm::Intrinsic::vastart: // Disallow inlining of functions that initialize VarArgs with // va_start. - return "contains VarArgs initialized with va_start"; + return ResultWithMessage::failure( + "contains VarArgs initialized with va_start"); } } } - return true; + return ResultWithMessage::success(); } // APIs to create InlineParams based on command line flags and/or other diff --git a/llvm/lib/CodeGen/SafeStack.cpp b/llvm/lib/CodeGen/SafeStack.cpp --- a/llvm/lib/CodeGen/SafeStack.cpp +++ b/llvm/lib/CodeGen/SafeStack.cpp @@ -708,7 +708,8 @@ bool SafeStack::ShouldInlinePointerAddress(CallSite &CS) { Function *Callee = CS.getCalledFunction(); - if (CS.hasFnAttr(Attribute::AlwaysInline) && isInlineViable(*Callee)) + if (CS.hasFnAttr(Attribute::AlwaysInline) && + isInlineViable(*Callee).isSuccess()) return true; if (Callee->isInterposable() || Callee->hasFnAttribute(Attribute::NoInline) || CS.isNoInline()) diff --git a/llvm/lib/Target/AMDGPU/AMDGPUInline.cpp b/llvm/lib/Target/AMDGPU/AMDGPUInline.cpp --- a/llvm/lib/Target/AMDGPU/AMDGPUInline.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUInline.cpp @@ -190,9 +190,9 @@ if (CS.hasFnAttr(Attribute::AlwaysInline)) { auto IsViable = isInlineViable(*Callee); - if (IsViable) + if (IsViable.isSuccess()) return llvm::InlineCost::getAlways("alwaysinline viable"); - return llvm::InlineCost::getNever(IsViable.message); + return llvm::InlineCost::getNever(IsViable.getFailureReason()); } if (isWrapperOnlyCall(CS)) diff --git a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp --- a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp +++ b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp @@ -48,7 +48,7 @@ SmallVector InlinedFunctions; for (Function &F : M) if (!F.isDeclaration() && F.hasFnAttribute(Attribute::AlwaysInline) && - isInlineViable(F)) { + isInlineViable(F).isSuccess()) { Calls.clear(); for (User *U : F.users()) @@ -60,7 +60,8 @@ // FIXME: We really shouldn't be able to fail to inline at this point! // We should do something to log or check the inline failures here. Changed |= - InlineFunction(CS, IFI, /*CalleeAAR=*/nullptr, InsertLifetime); + InlineFunction(CS, IFI, /*CalleeAAR=*/nullptr, InsertLifetime) + .isSuccess(); // Remember to try and delete this function afterward. This both avoids // re-walking the rest of the module and avoids dealing with any iterator @@ -167,8 +168,8 @@ return InlineCost::getNever("no alwaysinline attribute"); auto IsViable = isInlineViable(*Callee); - if (!IsViable) - return InlineCost::getNever(IsViable.message); + if (!IsViable.isSuccess()) + return InlineCost::getNever(IsViable.getFailureReason()); return InlineCost::getAlways("always inliner"); } diff --git a/llvm/lib/Transforms/IPO/Inliner.cpp b/llvm/lib/Transforms/IPO/Inliner.cpp --- a/llvm/lib/Transforms/IPO/Inliner.cpp +++ b/llvm/lib/Transforms/IPO/Inliner.cpp @@ -271,7 +271,7 @@ /// available from other functions inlined into the caller. If we are able to /// inline this call site we attempt to reuse already available allocas or add /// any new allocas to the set if not possible. -static InlineResult InlineCallIfPossible( +static ResultWithMessage InlineCallIfPossible( CallSite CS, InlineFunctionInfo &IFI, InlinedArrayAllocasTy &InlinedArrayAllocas, int InlineHistory, bool InsertLifetime, function_ref &AARGetter, @@ -283,8 +283,8 @@ // Try to inline the function. Get the list of static allocas that were // inlined. - InlineResult IR = InlineFunction(CS, IFI, &AAR, InsertLifetime); - if (!IR) + ResultWithMessage IR = InlineFunction(CS, IFI, &AAR, InsertLifetime); + if (!IR.isSuccess()) return IR; if (InlinerFunctionImportStats != InlinerFunctionImportStatsOpts::No) @@ -684,16 +684,18 @@ // Attempt to inline the function. using namespace ore; - InlineResult IR = InlineCallIfPossible( + ResultWithMessage IR = InlineCallIfPossible( CS, InlineInfo, InlinedArrayAllocas, InlineHistoryID, InsertLifetime, AARGetter, ImportedFunctionsStats); - if (!IR) { - setInlineRemark(CS, std::string(IR) + "; " + inlineCostStr(*OIC)); + if (!IR.isSuccess()) { + setInlineRemark(CS, std::string(IR.getFailureReason()) + "; " + + inlineCostStr(*OIC)); ORE.emit([&]() { return OptimizationRemarkMissed(DEBUG_TYPE, "NotInlined", DLoc, Block) << NV("Callee", Callee) << " will not be inlined into " - << NV("Caller", Caller) << ": " << NV("Reason", IR.message); + << NV("Caller", Caller) << ": " + << NV("Reason", IR.getFailureReason()); }); continue; } @@ -1075,13 +1077,13 @@ using namespace ore; - InlineResult IR = InlineFunction(CS, IFI); - if (!IR) { - setInlineRemark(CS, std::string(IR) + "; " + inlineCostStr(*OIC)); + ResultWithMessage IR = InlineFunction(CS, IFI); + if (!IR.isSuccess()) { + setInlineRemark(CS, std::string(IR.getFailureReason()) + "; " + inlineCostStr(*OIC)); ORE.emit([&]() { return OptimizationRemarkMissed(DEBUG_TYPE, "NotInlined", DLoc, Block) << NV("Callee", &Callee) << " will not be inlined into " - << NV("Caller", &F) << ": " << NV("Reason", IR.message); + << NV("Caller", &F) << ": " << NV("Reason", IR.getFailureReason()); }); continue; } diff --git a/llvm/lib/Transforms/IPO/PartialInlining.cpp b/llvm/lib/Transforms/IPO/PartialInlining.cpp --- a/llvm/lib/Transforms/IPO/PartialInlining.cpp +++ b/llvm/lib/Transforms/IPO/PartialInlining.cpp @@ -769,7 +769,7 @@ assert(Callee == Cloner.ClonedFunc); if (SkipCostAnalysis) - return isInlineViable(*Callee); + return isInlineViable(*Callee).isSuccess(); Function *Caller = CS.getCaller(); auto &CalleeTTI = (*GetTTI)(*Callee); @@ -1411,7 +1411,8 @@ // bail on vararg functions. if (!InlineFunction(CS, IFI, nullptr, true, (Cloner.ClonedOI ? Cloner.OutlinedFunctions.back().first - : nullptr))) + : nullptr)) + .isSuccess()) continue; CallerORE.emit(OR); diff --git a/llvm/lib/Transforms/IPO/SampleProfile.cpp b/llvm/lib/Transforms/IPO/SampleProfile.cpp --- a/llvm/lib/Transforms/IPO/SampleProfile.cpp +++ b/llvm/lib/Transforms/IPO/SampleProfile.cpp @@ -909,7 +909,7 @@ return false; } InlineFunctionInfo IFI(nullptr, &GetAC); - if (InlineFunction(CS, IFI)) { + if (InlineFunction(CS, IFI).isSuccess()) { // The call to InlineFunction erases I, so we can't pass it here. ORE->emit(OptimizationRemark(CSINLINE_DEBUG, "InlineSuccess", DLoc, BB) << "inlined callee '" << ore::NV("Callee", CalledFunction) diff --git a/llvm/lib/Transforms/Scalar/PlaceSafepoints.cpp b/llvm/lib/Transforms/Scalar/PlaceSafepoints.cpp --- a/llvm/lib/Transforms/Scalar/PlaceSafepoints.cpp +++ b/llvm/lib/Transforms/Scalar/PlaceSafepoints.cpp @@ -650,7 +650,7 @@ // Do the actual inlining InlineFunctionInfo IFI; - bool InlineStatus = InlineFunction(PollCall, IFI); + bool InlineStatus = InlineFunction(PollCall, IFI).isSuccess(); assert(InlineStatus && "inline must succeed"); (void)InlineStatus; // suppress warning in release-asserts diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -84,9 +84,10 @@ cl::init(true), cl::Hidden, cl::desc("Convert align attributes to assumptions during inlining.")); -llvm::InlineResult llvm::InlineFunction(CallBase *CB, InlineFunctionInfo &IFI, - AAResults *CalleeAAR, - bool InsertLifetime) { +llvm::ResultWithMessage llvm::InlineFunction(CallBase *CB, + InlineFunctionInfo &IFI, + AAResults *CalleeAAR, + bool InsertLifetime) { return InlineFunction(CallSite(CB), IFI, CalleeAAR, InsertLifetime); } @@ -1557,17 +1558,16 @@ /// instruction 'call B' is inlined, and 'B' calls 'C', then the call to 'C' now /// exists in the instruction stream. Similarly this will inline a recursive /// function by one level. -llvm::InlineResult llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI, - AAResults *CalleeAAR, - bool InsertLifetime, - Function *ForwardVarArgsTo) { +llvm::ResultWithMessage +llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI, AAResults *CalleeAAR, + bool InsertLifetime, Function *ForwardVarArgsTo) { Instruction *TheCall = CS.getInstruction(); assert(TheCall->getParent() && TheCall->getFunction() && "Instruction not in function!"); // FIXME: we don't inline callbr yet. if (isa(TheCall)) - return false; + return ResultWithMessage::failure("We don't inline callbr yet."); // If IFI has any state in it, zap it before we fill it in. IFI.reset(); @@ -1575,7 +1575,7 @@ Function *CalledFunc = CS.getCalledFunction(); if (!CalledFunc || // Can't inline external function or indirect CalledFunc->isDeclaration()) // call! - return "external or indirect"; + return ResultWithMessage::failure("external or indirect"); // The inliner does not know how to inline through calls with operand bundles // in general ... @@ -1589,7 +1589,7 @@ if (Tag == LLVMContext::OB_funclet) continue; - return "unsupported operand bundle"; + return ResultWithMessage::failure("unsupported operand bundle"); } } @@ -1608,7 +1608,7 @@ if (!Caller->hasGC()) Caller->setGC(CalledFunc->getGC()); else if (CalledFunc->getGC() != Caller->getGC()) - return "incompatible GC"; + return ResultWithMessage::failure("incompatible GC"); } // Get the personality function from the callee if it contains a landing pad. @@ -1632,7 +1632,7 @@ // 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 "incompatible personality"; + return ResultWithMessage::failure("incompatible personality"); } // We need to figure out which funclet the callsite was in so that we may @@ -1657,7 +1657,7 @@ // for catchpads. for (const BasicBlock &CalledBB : *CalledFunc) { if (isa(CalledBB.getFirstNonPHI())) - return "catch in cleanup funclet"; + return ResultWithMessage::failure("catch in cleanup funclet"); } } } else if (isAsynchronousEHPersonality(Personality)) { @@ -1665,7 +1665,7 @@ // funclet in the callee. for (const BasicBlock &CalledBB : *CalledFunc) { if (CalledBB.isEHPad()) - return "SEH in cleanup funclet"; + return ResultWithMessage::failure("SEH in cleanup funclet"); } } } @@ -2275,7 +2275,7 @@ Returns[0]->eraseFromParent(); // We are now done with the inlining. - return true; + return ResultWithMessage::success(); } // Otherwise, we have the normal case, of more than one block to inline or @@ -2437,5 +2437,5 @@ } } - return true; + return ResultWithMessage::success(); }