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 @@ -97,13 +97,6 @@ MarkOutlinedColdCC("pi-mark-coldcc", cl::init(false), cl::Hidden, cl::desc("Mark outline function calls with ColdCC")); -#ifndef NDEBUG -// Command line option to debug partial-inlining. The default is none: -static cl::opt TracePartialInlining("trace-partial-inlining", - cl::init(false), cl::Hidden, - cl::desc("Trace partial inlining.")); -#endif - // This is an option used by testing: static cl::opt SkipCostAnalysis("skip-partial-inlining-cost-analysis", cl::init(false), cl::ZeroOrMore, @@ -159,7 +152,7 @@ // Returns the number of blocks to be inlined including all blocks // in Entries and one return block. - unsigned GetNumInlinedBlocks() const { return Entries.size() + 1; } + unsigned getNumInlinedBlocks() const { return Entries.size() + 1; } // A set of blocks including the function entry that guard // the region to be outlined. @@ -215,7 +208,7 @@ // function (only if we partially inlined early returns) as there is a // possibility to further "peel" early return statements that were left in the // outline function due to code size. - std::pair unswitchFunction(Function *F); + std::pair unswitchFunction(Function &F); // This class speculatively clones the function to be partial inlined. // At the end of partial inlining, the remaining callsites to the cloned @@ -238,7 +231,7 @@ // Prepare for function outlining: making sure there is only // one incoming edge from the extracted/outlined region to // the return block. - void NormalizeReturnBlock(); + void normalizeReturnBlock() const; // Do function outlining for cold regions. bool doMultiRegionFunctionOutlining(); @@ -285,13 +278,14 @@ // The result is no larger than 1 and is represented using BP. // (Note that the outlined region's 'head' block can only have incoming // edges from the guarding entry blocks). - BranchProbability getOutliningCallBBRelativeFreq(FunctionCloner &Cloner); + BranchProbability + getOutliningCallBBRelativeFreq(FunctionCloner &Cloner) const; // Return true if the callee of CB should be partially inlined with // profit. bool shouldPartialInline(CallBase &CB, FunctionCloner &Cloner, BlockFrequency WeightedOutliningRcost, - OptimizationRemarkEmitter &ORE); + OptimizationRemarkEmitter &ORE) const; // Try to inline DuplicateFunction (cloned from F with call to // the OutlinedFunction into its callers. Return true @@ -300,10 +294,11 @@ // Compute the mapping from use site of DuplicationFunction to the enclosing // BB's profile count. - void computeCallsiteToProfCountMap(Function *DuplicateFunction, - DenseMap &SiteCountMap); + void + computeCallsiteToProfCountMap(Function *DuplicateFunction, + DenseMap &SiteCountMap) const; - bool IsLimitReached() { + bool isLimitReached() const { return (MaxNumPartialInlining != -1 && NumPartialInlining >= MaxNumPartialInlining); } @@ -315,12 +310,12 @@ return nullptr; } - static CallBase *getOneCallSiteTo(Function *F) { - User *User = *F->user_begin(); + static CallBase *getOneCallSiteTo(Function &F) { + User *User = *F.user_begin(); return getSupportedCallBase(User); } - std::tuple getOneDebugLoc(Function *F) { + std::tuple getOneDebugLoc(Function &F) const { CallBase *CB = getOneCallSiteTo(F); DebugLoc DLoc = CB->getDebugLoc(); BasicBlock *Block = CB->getParent(); @@ -333,16 +328,19 @@ // outlined function itself; // - The second value is the estimated size of the new call sequence in // basic block Cloner.OutliningCallBB; - std::tuple computeOutliningCosts(FunctionCloner &Cloner); + std::tuple computeOutliningCosts(FunctionCloner &Cloner) const; // Compute the 'InlineCost' of block BB. InlineCost is a proxy used to // approximate both the size and runtime cost (Note that in the current // inline cost analysis, there is no clear distinction there either). static int computeBBInlineCost(BasicBlock *BB, TargetTransformInfo *TTI); - std::unique_ptr computeOutliningInfo(Function *F); + std::unique_ptr + computeOutliningInfo(Function &F) const; + std::unique_ptr - computeOutliningColdRegionsInfo(Function *F, OptimizationRemarkEmitter &ORE); + computeOutliningColdRegionsInfo(Function &F, + OptimizationRemarkEmitter &ORE) const; }; struct PartialInlinerLegacyPass : public ModulePass { @@ -394,20 +392,20 @@ } // end anonymous namespace std::unique_ptr -PartialInlinerImpl::computeOutliningColdRegionsInfo(Function *F, - OptimizationRemarkEmitter &ORE) { - BasicBlock *EntryBlock = &F->front(); +PartialInlinerImpl::computeOutliningColdRegionsInfo( + Function &F, OptimizationRemarkEmitter &ORE) const { + BasicBlock *EntryBlock = &F.front(); - DominatorTree DT(*F); + DominatorTree DT(F); LoopInfo LI(DT); - BranchProbabilityInfo BPI(*F, LI); + BranchProbabilityInfo BPI(F, LI); std::unique_ptr ScopedBFI; BlockFrequencyInfo *BFI; if (!GetBFI) { - ScopedBFI.reset(new BlockFrequencyInfo(*F, BPI, LI)); + ScopedBFI.reset(new BlockFrequencyInfo(F, BPI, LI)); BFI = ScopedBFI.get(); } else - BFI = &(GetBFI(*F)); + BFI = &(GetBFI(F)); // Return if we don't have profiling information. if (!PSI.hasInstrumentationProfile()) @@ -436,8 +434,9 @@ << " has more than one region exit edge."; }); return nullptr; - } else - ExitBlock = Block; + } + + ExitBlock = Block; } } } @@ -452,15 +451,14 @@ // Use the same computeBBInlineCost function to compute the cost savings of // the outlining the candidate region. - TargetTransformInfo *FTTI = &GetTTI(*F); + TargetTransformInfo *FTTI = &GetTTI(F); int OverallFunctionCost = 0; - for (auto &BB : *F) + for (auto &BB : F) OverallFunctionCost += computeBBInlineCost(&BB, FTTI); -#ifndef NDEBUG - if (TracePartialInlining) - dbgs() << "OverallFunctionCost = " << OverallFunctionCost << "\n"; -#endif + LLVM_DEBUG(dbgs() << "OverallFunctionCost = " << OverallFunctionCost + << "\n";); + int MinOutlineRegionCost = static_cast(OverallFunctionCost * MinRegionSizeRatio); BranchProbability MinBranchProbability( @@ -472,6 +470,7 @@ DenseMap VisitedMap; DFS.push_back(CurrEntry); VisitedMap[CurrEntry] = true; + // Use Depth First Search on the basic blocks to find CFG edges that are // considered cold. // Cold regions considered must also have its inline cost compared to the @@ -479,53 +478,53 @@ // if it reduced the inline cost of the function by 'MinOutlineRegionCost' or // more. while (!DFS.empty()) { - auto *thisBB = DFS.back(); + auto *ThisBB = DFS.back(); DFS.pop_back(); // Only consider regions with predecessor blocks that are considered // not-cold (default: part of the top 99.99% of all block counters) // AND greater than our minimum block execution count (default: 100). - if (PSI.isColdBlock(thisBB, BFI) || - BBProfileCount(thisBB) < MinBlockCounterExecution) + if (PSI.isColdBlock(ThisBB, BFI) || + BBProfileCount(ThisBB) < MinBlockCounterExecution) continue; - for (auto SI = succ_begin(thisBB); SI != succ_end(thisBB); ++SI) { + for (auto SI = succ_begin(ThisBB); SI != succ_end(ThisBB); ++SI) { if (VisitedMap[*SI]) continue; VisitedMap[*SI] = true; DFS.push_back(*SI); // If branch isn't cold, we skip to the next one. - BranchProbability SuccProb = BPI.getEdgeProbability(thisBB, *SI); + BranchProbability SuccProb = BPI.getEdgeProbability(ThisBB, *SI); if (SuccProb > MinBranchProbability) continue; -#ifndef NDEBUG - if (TracePartialInlining) { - dbgs() << "Found cold edge: " << thisBB->getName() << "->" - << (*SI)->getName() << "\nBranch Probability = " << SuccProb - << "\n"; - } -#endif + + LLVM_DEBUG(dbgs() << "Found cold edge: " << ThisBB->getName() << "->" + << SI->getName() + << "\nBranch Probability = " << SuccProb << "\n";); + SmallVector DominateVector; DT.getDescendants(*SI, DominateVector); + // We can only outline single entry regions (for now). if (!IsSingleEntry(DominateVector)) continue; + BasicBlock *ExitBlock = nullptr; // We can only outline single exit regions (for now). if (!(ExitBlock = IsSingleExit(DominateVector))) continue; + int OutlineRegionCost = 0; for (auto *BB : DominateVector) OutlineRegionCost += computeBBInlineCost(BB, &GetTTI(*BB->getParent())); -#ifndef NDEBUG - if (TracePartialInlining) - dbgs() << "OutlineRegionCost = " << OutlineRegionCost << "\n"; -#endif + LLVM_DEBUG(dbgs() << "OutlineRegionCost = " << OutlineRegionCost + << "\n";); if (OutlineRegionCost < MinOutlineRegionCost) { ORE.emit([&]() { return OptimizationRemarkAnalysis(DEBUG_TYPE, "TooCostly", &SI->front()) - << ore::NV("Callee", F) << " inline cost-savings smaller than " + << ore::NV("Callee", &F) + << " inline cost-savings smaller than " << ore::NV("Cost", MinOutlineRegionCost); }); continue; @@ -536,31 +535,28 @@ // variables. for (auto *BB : DominateVector) VisitedMap[BB] = true; + // ReturnBlock here means the block after the outline call BasicBlock *ReturnBlock = ExitBlock->getSingleSuccessor(); - // assert(ReturnBlock && "ReturnBlock is NULL somehow!"); FunctionOutliningMultiRegionInfo::OutlineRegionInfo RegInfo( DominateVector, DominateVector.front(), ExitBlock, ReturnBlock); OutliningInfo->ORI.push_back(RegInfo); -#ifndef NDEBUG - if (TracePartialInlining) { - dbgs() << "Found Cold Candidate starting at block: " - << DominateVector.front()->getName() << "\n"; - } -#endif + LLVM_DEBUG(dbgs() << "Found Cold Candidate starting at block: " + << DominateVector.front()->getName() << "\n";); ColdCandidateFound = true; NumColdRegionsFound++; } } + if (ColdCandidateFound) return OutliningInfo; - else - return std::unique_ptr(); + + return std::unique_ptr(); } std::unique_ptr -PartialInlinerImpl::computeOutliningInfo(Function *F) { - BasicBlock *EntryBlock = &F->front(); +PartialInlinerImpl::computeOutliningInfo(Function &F) const { + BasicBlock *EntryBlock = &F.front(); BranchInst *BR = dyn_cast(EntryBlock->getTerminator()); if (!BR || BR->isUnconditional()) return std::unique_ptr(); @@ -603,7 +599,7 @@ // The number of blocks to be inlined has already reached // the limit. When MaxNumInlineBlocks is set to 0 or 1, this // disables partial inlining for the function. - if (OutliningInfo->GetNumInlinedBlocks() >= MaxNumInlineBlocks) + if (OutliningInfo->getNumInlinedBlocks() >= MaxNumInlineBlocks) break; if (succ_size(CurrEntry) != 2) @@ -623,8 +619,7 @@ break; } - BasicBlock *CommSucc; - BasicBlock *OtherSucc; + BasicBlock *CommSucc, *OtherSucc; std::tie(CommSucc, OtherSucc) = GetCommonSucc(Succ1, Succ2); if (!CommSucc) @@ -640,7 +635,7 @@ // Do sanity check of the entries: threre should not // be any successors (not in the entry set) other than // {ReturnBlock, NonReturnBlock} - assert(OutliningInfo->Entries[0] == &F->front() && + assert(OutliningInfo->Entries[0] == &F.front() && "Function Entry must be the first in Entries vector"); DenseSet Entries; for (BasicBlock *E : OutliningInfo->Entries) @@ -649,7 +644,7 @@ // Returns true of BB has Predecessor which is not // in Entries set. auto HasNonEntryPred = [Entries](BasicBlock *BB) { - for (auto Pred : predecessors(BB)) { + for (auto *Pred : predecessors(BB)) { if (!Entries.count(Pred)) return true; } @@ -658,7 +653,7 @@ auto CheckAndNormalizeCandidate = [Entries, HasNonEntryPred](FunctionOutliningInfo *OutliningInfo) { for (BasicBlock *E : OutliningInfo->Entries) { - for (auto Succ : successors(E)) { + for (auto *Succ : successors(E)) { if (Entries.count(Succ)) continue; if (Succ == OutliningInfo->ReturnBlock) @@ -678,7 +673,7 @@ // Now further growing the candidate's inlining region by // peeling off dominating blocks from the outlining region: - while (OutliningInfo->GetNumInlinedBlocks() < MaxNumInlineBlocks) { + while (OutliningInfo->getNumInlinedBlocks() < MaxNumInlineBlocks) { BasicBlock *Cand = OutliningInfo->NonReturnBlock; if (succ_size(Cand) != 2) break; @@ -708,11 +703,11 @@ } // Check if there is PGO data or user annotated branch data: -static bool hasProfileData(Function *F, FunctionOutliningInfo *OI) { - if (F->hasProfileData()) +static bool hasProfileData(const Function &F, const FunctionOutliningInfo &OI) { + if (F.hasProfileData()) return true; // Now check if any of the entry block has MD_prof data: - for (auto *E : OI->Entries) { + for (auto *E : OI.Entries) { BranchInst *BR = dyn_cast(E->getTerminator()); if (!BR || BR->isUnconditional()) continue; @@ -723,8 +718,8 @@ return false; } -BranchProbability -PartialInlinerImpl::getOutliningCallBBRelativeFreq(FunctionCloner &Cloner) { +BranchProbability PartialInlinerImpl::getOutliningCallBBRelativeFreq( + FunctionCloner &Cloner) const { BasicBlock *OutliningCallBB = Cloner.OutlinedFunctions.back().second; auto EntryFreq = Cloner.ClonedFuncBFI->getBlockFreq(&Cloner.ClonedFunc->getEntryBlock()); @@ -733,13 +728,13 @@ // FIXME Hackery needed because ClonedFuncBFI is based on the function BEFORE // we outlined any regions, so we may encounter situations where the // OutliningCallFreq is *slightly* bigger than the EntryFreq. - if (OutliningCallFreq.getFrequency() > EntryFreq.getFrequency()) { + if (OutliningCallFreq.getFrequency() > EntryFreq.getFrequency()) OutliningCallFreq = EntryFreq; - } + auto OutlineRegionRelFreq = BranchProbability::getBranchProbability( OutliningCallFreq.getFrequency(), EntryFreq.getFrequency()); - if (hasProfileData(Cloner.OrigFunc, Cloner.ClonedOI.get())) + if (hasProfileData(*Cloner.OrigFunc, *Cloner.ClonedOI.get())) return OutlineRegionRelFreq; // When profile data is not available, we need to be conservative in @@ -765,7 +760,7 @@ bool PartialInlinerImpl::shouldPartialInline( CallBase &CB, FunctionCloner &Cloner, BlockFrequency WeightedOutliningRcost, - OptimizationRemarkEmitter &ORE) { + OptimizationRemarkEmitter &ORE) const { using namespace ore; Function *Callee = CB.getCalledFunction(); @@ -907,7 +902,7 @@ } std::tuple -PartialInlinerImpl::computeOutliningCosts(FunctionCloner &Cloner) { +PartialInlinerImpl::computeOutliningCosts(FunctionCloner &Cloner) const { int OutliningFuncCallCost = 0, OutlinedFunctionCost = 0; for (auto FuncBBPair : Cloner.OutlinedFunctions) { Function *OutlinedFunc = FuncBBPair.first; @@ -944,7 +939,7 @@ // after the function is partially inlined into the callsite. void PartialInlinerImpl::computeCallsiteToProfCountMap( Function *DuplicateFunction, - DenseMap &CallSiteToProfCountMap) { + DenseMap &CallSiteToProfCountMap) const { std::vector Users(DuplicateFunction->user_begin(), DuplicateFunction->user_end()); Function *CurrentCaller = nullptr; @@ -996,9 +991,9 @@ ClonedOI->ReturnBlock = cast(VMap[OI->ReturnBlock]); ClonedOI->NonReturnBlock = cast(VMap[OI->NonReturnBlock]); - for (BasicBlock *BB : OI->Entries) { + for (BasicBlock *BB : OI->Entries) ClonedOI->Entries.push_back(cast(VMap[BB])); - } + for (BasicBlock *E : OI->ReturnBlockPreds) { BasicBlock *NewE = cast(VMap[E]); ClonedOI->ReturnBlockPreds.push_back(NewE); @@ -1025,9 +1020,9 @@ for (FunctionOutliningMultiRegionInfo::OutlineRegionInfo RegionInfo : OI->ORI) { SmallVector Region; - for (BasicBlock *BB : RegionInfo.Region) { + for (BasicBlock *BB : RegionInfo.Region) Region.push_back(cast(VMap[BB])); - } + BasicBlock *NewEntryBlock = cast(VMap[RegionInfo.EntryBlock]); BasicBlock *NewExitBlock = cast(VMap[RegionInfo.ExitBlock]); BasicBlock *NewReturnBlock = nullptr; @@ -1042,8 +1037,8 @@ F->replaceAllUsesWith(ClonedFunc); } -void PartialInlinerImpl::FunctionCloner::NormalizeReturnBlock() { - auto getFirstPHI = [](BasicBlock *BB) { +void PartialInlinerImpl::FunctionCloner::normalizeReturnBlock() const { + auto GetFirstPHI = [](BasicBlock *BB) { BasicBlock::iterator I = BB->begin(); PHINode *FirstPhi = nullptr; while (I != BB->end()) { @@ -1069,7 +1064,7 @@ // of which will go outside. BasicBlock *PreReturn = ClonedOI->ReturnBlock; // only split block when necessary: - PHINode *FirstPhi = getFirstPHI(PreReturn); + PHINode *FirstPhi = GetFirstPHI(PreReturn); unsigned NumPredsFromEntries = ClonedOI->ReturnBlockPreds.size(); if (!FirstPhi || FirstPhi->getNumIncomingValues() <= NumPredsFromEntries + 1) @@ -1117,9 +1112,8 @@ for (auto *DP : DeadPhis) DP->eraseFromParent(); - for (auto E : ClonedOI->ReturnBlockPreds) { + for (auto *E : ClonedOI->ReturnBlockPreds) E->getTerminator()->replaceUsesOfWith(PreReturn, ClonedOI->ReturnBlock); - } } bool PartialInlinerImpl::FunctionCloner::doMultiRegionFunctionOutlining() { @@ -1160,24 +1154,21 @@ CE.findInputsOutputs(Inputs, Outputs, Sinks); -#ifndef NDEBUG - if (TracePartialInlining) { + LLVM_DEBUG({ dbgs() << "inputs: " << Inputs.size() << "\n"; dbgs() << "outputs: " << Outputs.size() << "\n"; for (Value *value : Inputs) dbgs() << "value used in func: " << *value << "\n"; for (Value *output : Outputs) dbgs() << "instr used in func: " << *output << "\n"; - } -#endif + }); + // Do not extract regions that have live exit variables. if (Outputs.size() > 0 && !ForceLiveExit) continue; - Function *OutlinedFunc = CE.extractCodeRegion(CEAC); - - if (OutlinedFunc) { - CallBase *OCS = PartialInlinerImpl::getOneCallSiteTo(OutlinedFunc); + if (Function *OutlinedFunc = CE.extractCodeRegion(CEAC)) { + CallBase *OCS = PartialInlinerImpl::getOneCallSiteTo(*OutlinedFunc); BasicBlock *OutliningCallBB = OCS->getParent(); assert(OutliningCallBB->getParent() == ClonedFunc); OutlinedFunctions.push_back(std::make_pair(OutlinedFunc,OutliningCallBB)); @@ -1245,8 +1236,7 @@ if (OutlinedFunc) { BasicBlock *OutliningCallBB = - PartialInlinerImpl::getOneCallSiteTo(OutlinedFunc) - ->getParent(); + PartialInlinerImpl::getOneCallSiteTo(*OutlinedFunc)->getParent(); assert(OutliningCallBB->getParent() == ClonedFunc); OutlinedFunctions.push_back(std::make_pair(OutlinedFunc, OutliningCallBB)); } else @@ -1275,52 +1265,48 @@ } } -std::pair PartialInlinerImpl::unswitchFunction(Function *F) { - - if (F->hasAddressTaken()) +std::pair PartialInlinerImpl::unswitchFunction(Function &F) { + if (F.hasAddressTaken()) return {false, nullptr}; // Let inliner handle it - if (F->hasFnAttribute(Attribute::AlwaysInline)) + if (F.hasFnAttribute(Attribute::AlwaysInline)) return {false, nullptr}; - if (F->hasFnAttribute(Attribute::NoInline)) + if (F.hasFnAttribute(Attribute::NoInline)) return {false, nullptr}; - if (PSI.isFunctionEntryCold(F)) + if (PSI.isFunctionEntryCold(&F)) return {false, nullptr}; - if (F->users().empty()) + if (F.users().empty()) return {false, nullptr}; - OptimizationRemarkEmitter ORE(F); + OptimizationRemarkEmitter ORE(&F); // Only try to outline cold regions if we have a profile summary, which // implies we have profiling information. - if (PSI.hasProfileSummary() && F->hasProfileData() && + if (PSI.hasProfileSummary() && F.hasProfileData() && !DisableMultiRegionPartialInline) { std::unique_ptr OMRI = computeOutliningColdRegionsInfo(F, ORE); if (OMRI) { - FunctionCloner Cloner(F, OMRI.get(), ORE, LookupAssumptionCache, GetTTI); + FunctionCloner Cloner(&F, OMRI.get(), ORE, LookupAssumptionCache, GetTTI); -#ifndef NDEBUG - if (TracePartialInlining) { + LLVM_DEBUG({ dbgs() << "HotCountThreshold = " << PSI.getHotCountThreshold() << "\n"; dbgs() << "ColdCountThreshold = " << PSI.getColdCountThreshold() << "\n"; - } -#endif + }); + bool DidOutline = Cloner.doMultiRegionFunctionOutlining(); if (DidOutline) { -#ifndef NDEBUG - if (TracePartialInlining) { + LLVM_DEBUG({ dbgs() << ">>>>>> Outlined (Cloned) Function >>>>>>\n"; Cloner.ClonedFunc->print(dbgs()); dbgs() << "<<<<<< Outlined (Cloned) Function <<<<<<\n"; - } -#endif + }); if (tryPartialInline(Cloner)) return {true, nullptr}; @@ -1335,17 +1321,15 @@ if (!OI) return {false, nullptr}; - FunctionCloner Cloner(F, OI.get(), ORE, LookupAssumptionCache, GetTTI); - Cloner.NormalizeReturnBlock(); + FunctionCloner Cloner(&F, OI.get(), ORE, LookupAssumptionCache, GetTTI); + Cloner.normalizeReturnBlock(); Function *OutlinedFunction = Cloner.doSingleRegionFunctionOutlining(); if (!OutlinedFunction) return {false, nullptr}; - bool AnyInline = tryPartialInline(Cloner); - - if (AnyInline) + if (tryPartialInline(Cloner)) return {true, OutlinedFunction}; return {false, nullptr}; @@ -1363,9 +1347,9 @@ // Only calculate RelativeToEntryFreq when we are doing single region // outlining. BranchProbability RelativeToEntryFreq; - if (Cloner.ClonedOI) { + if (Cloner.ClonedOI) RelativeToEntryFreq = getOutliningCallBBRelativeFreq(Cloner); - } else + else // RelativeToEntryFreq doesn't make sense when we have more than one // outlined call because each call will have a different relative frequency // to the entry block. We can consider using the average, but the @@ -1383,7 +1367,7 @@ OptimizationRemarkEmitter OrigFuncORE(Cloner.OrigFunc); DebugLoc DLoc; BasicBlock *Block; - std::tie(DLoc, Block) = getOneDebugLoc(Cloner.ClonedFunc); + std::tie(DLoc, Block) = getOneDebugLoc(*Cloner.ClonedFunc); OrigFuncORE.emit([&]() { return OptimizationRemarkAnalysis(DEBUG_TYPE, "OutlineRegionTooSmall", DLoc, Block) @@ -1414,7 +1398,7 @@ for (User *User : Users) { CallBase *CB = getSupportedCallBase(User); - if (IsLimitReached()) + if (isLimitReached()) continue; OptimizationRemarkEmitter CallerORE(CB->getCaller()); @@ -1451,7 +1435,6 @@ NumPartialInlined++; else NumColdOutlinePartialInlined++; - } if (AnyInline) { @@ -1464,7 +1447,6 @@ return OptimizationRemark(DEBUG_TYPE, "PartiallyInlined", Cloner.OrigFunc) << "Partially inlined into at least one caller"; }); - } return AnyInline; @@ -1498,7 +1480,7 @@ if (Recursive) continue; - std::pair Result = unswitchFunction(CurrFunc); + std::pair Result = unswitchFunction(*CurrFunc); if (Result.second) Worklist.push_back(Result.second); Changed |= Result.first;