xref: /openbsd-src/gnu/llvm/llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
109467b48Spatrick //===- IndirectCallPromotion.cpp - Optimizations based on value profiling -===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick // This file implements the transformation that promotes indirect calls to
1009467b48Spatrick // conditional direct calls when the indirect-call value profile metadata is
1109467b48Spatrick // available.
1209467b48Spatrick //
1309467b48Spatrick //===----------------------------------------------------------------------===//
1409467b48Spatrick 
1509467b48Spatrick #include "llvm/ADT/ArrayRef.h"
1609467b48Spatrick #include "llvm/ADT/Statistic.h"
1709467b48Spatrick #include "llvm/ADT/StringRef.h"
1809467b48Spatrick #include "llvm/Analysis/IndirectCallPromotionAnalysis.h"
1909467b48Spatrick #include "llvm/Analysis/IndirectCallVisitor.h"
2009467b48Spatrick #include "llvm/Analysis/OptimizationRemarkEmitter.h"
2109467b48Spatrick #include "llvm/Analysis/ProfileSummaryInfo.h"
2209467b48Spatrick #include "llvm/IR/DiagnosticInfo.h"
2309467b48Spatrick #include "llvm/IR/Function.h"
2409467b48Spatrick #include "llvm/IR/InstrTypes.h"
2509467b48Spatrick #include "llvm/IR/Instructions.h"
2609467b48Spatrick #include "llvm/IR/LLVMContext.h"
2709467b48Spatrick #include "llvm/IR/MDBuilder.h"
2809467b48Spatrick #include "llvm/IR/PassManager.h"
2909467b48Spatrick #include "llvm/IR/Value.h"
3009467b48Spatrick #include "llvm/ProfileData/InstrProf.h"
3109467b48Spatrick #include "llvm/Support/Casting.h"
3209467b48Spatrick #include "llvm/Support/CommandLine.h"
3309467b48Spatrick #include "llvm/Support/Debug.h"
3409467b48Spatrick #include "llvm/Support/Error.h"
3509467b48Spatrick #include "llvm/Support/raw_ostream.h"
3609467b48Spatrick #include "llvm/Transforms/Instrumentation.h"
3709467b48Spatrick #include "llvm/Transforms/Instrumentation/PGOInstrumentation.h"
3809467b48Spatrick #include "llvm/Transforms/Utils/CallPromotionUtils.h"
3909467b48Spatrick #include <cassert>
4009467b48Spatrick #include <cstdint>
4109467b48Spatrick #include <memory>
4209467b48Spatrick #include <string>
4309467b48Spatrick #include <utility>
4409467b48Spatrick #include <vector>
4509467b48Spatrick 
4609467b48Spatrick using namespace llvm;
4709467b48Spatrick 
4809467b48Spatrick #define DEBUG_TYPE "pgo-icall-prom"
4909467b48Spatrick 
5009467b48Spatrick STATISTIC(NumOfPGOICallPromotion, "Number of indirect call promotions.");
5109467b48Spatrick STATISTIC(NumOfPGOICallsites, "Number of indirect call candidate sites.");
5209467b48Spatrick 
5309467b48Spatrick // Command line option to disable indirect-call promotion with the default as
5409467b48Spatrick // false. This is for debug purpose.
5509467b48Spatrick static cl::opt<bool> DisableICP("disable-icp", cl::init(false), cl::Hidden,
5609467b48Spatrick                                 cl::desc("Disable indirect call promotion"));
5709467b48Spatrick 
5809467b48Spatrick // Set the cutoff value for the promotion. If the value is other than 0, we
5909467b48Spatrick // stop the transformation once the total number of promotions equals the cutoff
6009467b48Spatrick // value.
6109467b48Spatrick // For debug use only.
6209467b48Spatrick static cl::opt<unsigned>
63*d415bd75Srobert     ICPCutOff("icp-cutoff", cl::init(0), cl::Hidden,
6409467b48Spatrick               cl::desc("Max number of promotions for this compilation"));
6509467b48Spatrick 
6609467b48Spatrick // If ICPCSSkip is non zero, the first ICPCSSkip callsites will be skipped.
6709467b48Spatrick // For debug use only.
6809467b48Spatrick static cl::opt<unsigned>
69*d415bd75Srobert     ICPCSSkip("icp-csskip", cl::init(0), cl::Hidden,
7009467b48Spatrick               cl::desc("Skip Callsite up to this number for this compilation"));
7109467b48Spatrick 
7209467b48Spatrick // Set if the pass is called in LTO optimization. The difference for LTO mode
7309467b48Spatrick // is the pass won't prefix the source module name to the internal linkage
7409467b48Spatrick // symbols.
7509467b48Spatrick static cl::opt<bool> ICPLTOMode("icp-lto", cl::init(false), cl::Hidden,
7609467b48Spatrick                                 cl::desc("Run indirect-call promotion in LTO "
7709467b48Spatrick                                          "mode"));
7809467b48Spatrick 
7909467b48Spatrick // Set if the pass is called in SamplePGO mode. The difference for SamplePGO
8009467b48Spatrick // mode is it will add prof metadatato the created direct call.
8109467b48Spatrick static cl::opt<bool>
8209467b48Spatrick     ICPSamplePGOMode("icp-samplepgo", cl::init(false), cl::Hidden,
8309467b48Spatrick                      cl::desc("Run indirect-call promotion in SamplePGO mode"));
8409467b48Spatrick 
8509467b48Spatrick // If the option is set to true, only call instructions will be considered for
8609467b48Spatrick // transformation -- invoke instructions will be ignored.
8709467b48Spatrick static cl::opt<bool>
8809467b48Spatrick     ICPCallOnly("icp-call-only", cl::init(false), cl::Hidden,
8909467b48Spatrick                 cl::desc("Run indirect-call promotion for call instructions "
9009467b48Spatrick                          "only"));
9109467b48Spatrick 
9209467b48Spatrick // If the option is set to true, only invoke instructions will be considered for
9309467b48Spatrick // transformation -- call instructions will be ignored.
9409467b48Spatrick static cl::opt<bool> ICPInvokeOnly("icp-invoke-only", cl::init(false),
9509467b48Spatrick                                    cl::Hidden,
9609467b48Spatrick                                    cl::desc("Run indirect-call promotion for "
9709467b48Spatrick                                             "invoke instruction only"));
9809467b48Spatrick 
9909467b48Spatrick // Dump the function level IR if the transformation happened in this
10009467b48Spatrick // function. For debug use only.
10109467b48Spatrick static cl::opt<bool>
10209467b48Spatrick     ICPDUMPAFTER("icp-dumpafter", cl::init(false), cl::Hidden,
10309467b48Spatrick                  cl::desc("Dump IR after transformation happens"));
10409467b48Spatrick 
10509467b48Spatrick namespace {
10609467b48Spatrick 
10709467b48Spatrick // The class for main data structure to promote indirect calls to conditional
10809467b48Spatrick // direct calls.
10909467b48Spatrick class ICallPromotionFunc {
11009467b48Spatrick private:
11109467b48Spatrick   Function &F;
11209467b48Spatrick   Module *M;
11309467b48Spatrick 
11409467b48Spatrick   // Symtab that maps indirect call profile values to function names and
11509467b48Spatrick   // defines.
11609467b48Spatrick   InstrProfSymtab *Symtab;
11709467b48Spatrick 
11809467b48Spatrick   bool SamplePGO;
11909467b48Spatrick 
12009467b48Spatrick   OptimizationRemarkEmitter &ORE;
12109467b48Spatrick 
12209467b48Spatrick   // A struct that records the direct target and it's call count.
12309467b48Spatrick   struct PromotionCandidate {
12409467b48Spatrick     Function *TargetFunction;
12509467b48Spatrick     uint64_t Count;
12609467b48Spatrick 
PromotionCandidate__anond2a4b99d0111::ICallPromotionFunc::PromotionCandidate12709467b48Spatrick     PromotionCandidate(Function *F, uint64_t C) : TargetFunction(F), Count(C) {}
12809467b48Spatrick   };
12909467b48Spatrick 
13009467b48Spatrick   // Check if the indirect-call call site should be promoted. Return the number
13109467b48Spatrick   // of promotions. Inst is the candidate indirect call, ValueDataRef
13209467b48Spatrick   // contains the array of value profile data for profiled targets,
13309467b48Spatrick   // TotalCount is the total profiled count of call executions, and
13409467b48Spatrick   // NumCandidates is the number of candidate entries in ValueDataRef.
13509467b48Spatrick   std::vector<PromotionCandidate> getPromotionCandidatesForCallSite(
136097a140dSpatrick       const CallBase &CB, const ArrayRef<InstrProfValueData> &ValueDataRef,
13709467b48Spatrick       uint64_t TotalCount, uint32_t NumCandidates);
13809467b48Spatrick 
13909467b48Spatrick   // Promote a list of targets for one indirect-call callsite. Return
14009467b48Spatrick   // the number of promotions.
141097a140dSpatrick   uint32_t tryToPromote(CallBase &CB,
14209467b48Spatrick                         const std::vector<PromotionCandidate> &Candidates,
14309467b48Spatrick                         uint64_t &TotalCount);
14409467b48Spatrick 
14509467b48Spatrick public:
ICallPromotionFunc(Function & Func,Module * Modu,InstrProfSymtab * Symtab,bool SamplePGO,OptimizationRemarkEmitter & ORE)14609467b48Spatrick   ICallPromotionFunc(Function &Func, Module *Modu, InstrProfSymtab *Symtab,
14709467b48Spatrick                      bool SamplePGO, OptimizationRemarkEmitter &ORE)
14809467b48Spatrick       : F(Func), M(Modu), Symtab(Symtab), SamplePGO(SamplePGO), ORE(ORE) {}
14909467b48Spatrick   ICallPromotionFunc(const ICallPromotionFunc &) = delete;
15009467b48Spatrick   ICallPromotionFunc &operator=(const ICallPromotionFunc &) = delete;
15109467b48Spatrick 
15209467b48Spatrick   bool processFunction(ProfileSummaryInfo *PSI);
15309467b48Spatrick };
15409467b48Spatrick 
15509467b48Spatrick } // end anonymous namespace
15609467b48Spatrick 
15709467b48Spatrick // Indirect-call promotion heuristic. The direct targets are sorted based on
15809467b48Spatrick // the count. Stop at the first target that is not promoted.
15909467b48Spatrick std::vector<ICallPromotionFunc::PromotionCandidate>
getPromotionCandidatesForCallSite(const CallBase & CB,const ArrayRef<InstrProfValueData> & ValueDataRef,uint64_t TotalCount,uint32_t NumCandidates)16009467b48Spatrick ICallPromotionFunc::getPromotionCandidatesForCallSite(
161097a140dSpatrick     const CallBase &CB, const ArrayRef<InstrProfValueData> &ValueDataRef,
16209467b48Spatrick     uint64_t TotalCount, uint32_t NumCandidates) {
16309467b48Spatrick   std::vector<PromotionCandidate> Ret;
16409467b48Spatrick 
165097a140dSpatrick   LLVM_DEBUG(dbgs() << " \nWork on callsite #" << NumOfPGOICallsites << CB
16609467b48Spatrick                     << " Num_targets: " << ValueDataRef.size()
16709467b48Spatrick                     << " Num_candidates: " << NumCandidates << "\n");
16809467b48Spatrick   NumOfPGOICallsites++;
16909467b48Spatrick   if (ICPCSSkip != 0 && NumOfPGOICallsites <= ICPCSSkip) {
17009467b48Spatrick     LLVM_DEBUG(dbgs() << " Skip: User options.\n");
17109467b48Spatrick     return Ret;
17209467b48Spatrick   }
17309467b48Spatrick 
17409467b48Spatrick   for (uint32_t I = 0; I < NumCandidates; I++) {
17509467b48Spatrick     uint64_t Count = ValueDataRef[I].Count;
17609467b48Spatrick     assert(Count <= TotalCount);
17773471bf0Spatrick     (void)TotalCount;
17809467b48Spatrick     uint64_t Target = ValueDataRef[I].Value;
17909467b48Spatrick     LLVM_DEBUG(dbgs() << " Candidate " << I << " Count=" << Count
18009467b48Spatrick                       << "  Target_func: " << Target << "\n");
18109467b48Spatrick 
182097a140dSpatrick     if (ICPInvokeOnly && isa<CallInst>(CB)) {
18309467b48Spatrick       LLVM_DEBUG(dbgs() << " Not promote: User options.\n");
18409467b48Spatrick       ORE.emit([&]() {
185097a140dSpatrick         return OptimizationRemarkMissed(DEBUG_TYPE, "UserOptions", &CB)
18609467b48Spatrick                << " Not promote: User options";
18709467b48Spatrick       });
18809467b48Spatrick       break;
18909467b48Spatrick     }
190097a140dSpatrick     if (ICPCallOnly && isa<InvokeInst>(CB)) {
19109467b48Spatrick       LLVM_DEBUG(dbgs() << " Not promote: User option.\n");
19209467b48Spatrick       ORE.emit([&]() {
193097a140dSpatrick         return OptimizationRemarkMissed(DEBUG_TYPE, "UserOptions", &CB)
19409467b48Spatrick                << " Not promote: User options";
19509467b48Spatrick       });
19609467b48Spatrick       break;
19709467b48Spatrick     }
19809467b48Spatrick     if (ICPCutOff != 0 && NumOfPGOICallPromotion >= ICPCutOff) {
19909467b48Spatrick       LLVM_DEBUG(dbgs() << " Not promote: Cutoff reached.\n");
20009467b48Spatrick       ORE.emit([&]() {
201097a140dSpatrick         return OptimizationRemarkMissed(DEBUG_TYPE, "CutOffReached", &CB)
20209467b48Spatrick                << " Not promote: Cutoff reached";
20309467b48Spatrick       });
20409467b48Spatrick       break;
20509467b48Spatrick     }
20609467b48Spatrick 
20773471bf0Spatrick     // Don't promote if the symbol is not defined in the module. This avoids
20873471bf0Spatrick     // creating a reference to a symbol that doesn't exist in the module
20973471bf0Spatrick     // This can happen when we compile with a sample profile collected from
21073471bf0Spatrick     // one binary but used for another, which may have profiled targets that
21173471bf0Spatrick     // aren't used in the new binary. We might have a declaration initially in
21273471bf0Spatrick     // the case where the symbol is globally dead in the binary and removed by
21373471bf0Spatrick     // ThinLTO.
21409467b48Spatrick     Function *TargetFunction = Symtab->getFunction(Target);
21573471bf0Spatrick     if (TargetFunction == nullptr || TargetFunction->isDeclaration()) {
21609467b48Spatrick       LLVM_DEBUG(dbgs() << " Not promote: Cannot find the target\n");
21709467b48Spatrick       ORE.emit([&]() {
218097a140dSpatrick         return OptimizationRemarkMissed(DEBUG_TYPE, "UnableToFindTarget", &CB)
21909467b48Spatrick                << "Cannot promote indirect call: target with md5sum "
22009467b48Spatrick                << ore::NV("target md5sum", Target) << " not found";
22109467b48Spatrick       });
22209467b48Spatrick       break;
22309467b48Spatrick     }
22409467b48Spatrick 
22509467b48Spatrick     const char *Reason = nullptr;
226097a140dSpatrick     if (!isLegalToPromote(CB, TargetFunction, &Reason)) {
22709467b48Spatrick       using namespace ore;
22809467b48Spatrick 
22909467b48Spatrick       ORE.emit([&]() {
230097a140dSpatrick         return OptimizationRemarkMissed(DEBUG_TYPE, "UnableToPromote", &CB)
23109467b48Spatrick                << "Cannot promote indirect call to "
23209467b48Spatrick                << NV("TargetFunction", TargetFunction) << " with count of "
23309467b48Spatrick                << NV("Count", Count) << ": " << Reason;
23409467b48Spatrick       });
23509467b48Spatrick       break;
23609467b48Spatrick     }
23709467b48Spatrick 
23809467b48Spatrick     Ret.push_back(PromotionCandidate(TargetFunction, Count));
23909467b48Spatrick     TotalCount -= Count;
24009467b48Spatrick   }
24109467b48Spatrick   return Ret;
24209467b48Spatrick }
24309467b48Spatrick 
promoteIndirectCall(CallBase & CB,Function * DirectCallee,uint64_t Count,uint64_t TotalCount,bool AttachProfToDirectCall,OptimizationRemarkEmitter * ORE)244097a140dSpatrick CallBase &llvm::pgo::promoteIndirectCall(CallBase &CB, Function *DirectCallee,
24509467b48Spatrick                                          uint64_t Count, uint64_t TotalCount,
24609467b48Spatrick                                          bool AttachProfToDirectCall,
24709467b48Spatrick                                          OptimizationRemarkEmitter *ORE) {
24809467b48Spatrick 
24909467b48Spatrick   uint64_t ElseCount = TotalCount - Count;
25009467b48Spatrick   uint64_t MaxCount = (Count >= ElseCount ? Count : ElseCount);
25109467b48Spatrick   uint64_t Scale = calculateCountScale(MaxCount);
252097a140dSpatrick   MDBuilder MDB(CB.getContext());
25309467b48Spatrick   MDNode *BranchWeights = MDB.createBranchWeights(
25409467b48Spatrick       scaleBranchCount(Count, Scale), scaleBranchCount(ElseCount, Scale));
25509467b48Spatrick 
256097a140dSpatrick   CallBase &NewInst =
257097a140dSpatrick       promoteCallWithIfThenElse(CB, DirectCallee, BranchWeights);
25809467b48Spatrick 
25909467b48Spatrick   if (AttachProfToDirectCall) {
260097a140dSpatrick     MDBuilder MDB(NewInst.getContext());
261097a140dSpatrick     NewInst.setMetadata(
26209467b48Spatrick         LLVMContext::MD_prof,
26309467b48Spatrick         MDB.createBranchWeights({static_cast<uint32_t>(Count)}));
26409467b48Spatrick   }
26509467b48Spatrick 
26609467b48Spatrick   using namespace ore;
26709467b48Spatrick 
26809467b48Spatrick   if (ORE)
26909467b48Spatrick     ORE->emit([&]() {
270097a140dSpatrick       return OptimizationRemark(DEBUG_TYPE, "Promoted", &CB)
27109467b48Spatrick              << "Promote indirect call to " << NV("DirectCallee", DirectCallee)
27209467b48Spatrick              << " with count " << NV("Count", Count) << " out of "
27309467b48Spatrick              << NV("TotalCount", TotalCount);
27409467b48Spatrick     });
27509467b48Spatrick   return NewInst;
27609467b48Spatrick }
27709467b48Spatrick 
27809467b48Spatrick // Promote indirect-call to conditional direct-call for one callsite.
tryToPromote(CallBase & CB,const std::vector<PromotionCandidate> & Candidates,uint64_t & TotalCount)27909467b48Spatrick uint32_t ICallPromotionFunc::tryToPromote(
280097a140dSpatrick     CallBase &CB, const std::vector<PromotionCandidate> &Candidates,
28109467b48Spatrick     uint64_t &TotalCount) {
28209467b48Spatrick   uint32_t NumPromoted = 0;
28309467b48Spatrick 
284*d415bd75Srobert   for (const auto &C : Candidates) {
28509467b48Spatrick     uint64_t Count = C.Count;
286097a140dSpatrick     pgo::promoteIndirectCall(CB, C.TargetFunction, Count, TotalCount, SamplePGO,
287097a140dSpatrick                              &ORE);
28809467b48Spatrick     assert(TotalCount >= Count);
28909467b48Spatrick     TotalCount -= Count;
29009467b48Spatrick     NumOfPGOICallPromotion++;
29109467b48Spatrick     NumPromoted++;
29209467b48Spatrick   }
29309467b48Spatrick   return NumPromoted;
29409467b48Spatrick }
29509467b48Spatrick 
29609467b48Spatrick // Traverse all the indirect-call callsite and get the value profile
29709467b48Spatrick // annotation to perform indirect-call promotion.
processFunction(ProfileSummaryInfo * PSI)29809467b48Spatrick bool ICallPromotionFunc::processFunction(ProfileSummaryInfo *PSI) {
29909467b48Spatrick   bool Changed = false;
30009467b48Spatrick   ICallPromotionAnalysis ICallAnalysis;
301097a140dSpatrick   for (auto *CB : findIndirectCalls(F)) {
30209467b48Spatrick     uint32_t NumVals, NumCandidates;
30309467b48Spatrick     uint64_t TotalCount;
30409467b48Spatrick     auto ICallProfDataRef = ICallAnalysis.getPromotionCandidatesForInstruction(
305097a140dSpatrick         CB, NumVals, TotalCount, NumCandidates);
30609467b48Spatrick     if (!NumCandidates ||
30709467b48Spatrick         (PSI && PSI->hasProfileSummary() && !PSI->isHotCount(TotalCount)))
30809467b48Spatrick       continue;
30909467b48Spatrick     auto PromotionCandidates = getPromotionCandidatesForCallSite(
310097a140dSpatrick         *CB, ICallProfDataRef, TotalCount, NumCandidates);
311097a140dSpatrick     uint32_t NumPromoted = tryToPromote(*CB, PromotionCandidates, TotalCount);
31209467b48Spatrick     if (NumPromoted == 0)
31309467b48Spatrick       continue;
31409467b48Spatrick 
31509467b48Spatrick     Changed = true;
31609467b48Spatrick     // Adjust the MD.prof metadata. First delete the old one.
317097a140dSpatrick     CB->setMetadata(LLVMContext::MD_prof, nullptr);
31809467b48Spatrick     // If all promoted, we don't need the MD.prof metadata.
31909467b48Spatrick     if (TotalCount == 0 || NumPromoted == NumVals)
32009467b48Spatrick       continue;
32109467b48Spatrick     // Otherwise we need update with the un-promoted records back.
322097a140dSpatrick     annotateValueSite(*M, *CB, ICallProfDataRef.slice(NumPromoted), TotalCount,
32309467b48Spatrick                       IPVK_IndirectCallTarget, NumCandidates);
32409467b48Spatrick   }
32509467b48Spatrick   return Changed;
32609467b48Spatrick }
32709467b48Spatrick 
32809467b48Spatrick // A wrapper function that does the actual work.
promoteIndirectCalls(Module & M,ProfileSummaryInfo * PSI,bool InLTO,bool SamplePGO,ModuleAnalysisManager * AM=nullptr)32909467b48Spatrick static bool promoteIndirectCalls(Module &M, ProfileSummaryInfo *PSI,
33009467b48Spatrick                                  bool InLTO, bool SamplePGO,
33109467b48Spatrick                                  ModuleAnalysisManager *AM = nullptr) {
33209467b48Spatrick   if (DisableICP)
33309467b48Spatrick     return false;
33409467b48Spatrick   InstrProfSymtab Symtab;
33509467b48Spatrick   if (Error E = Symtab.create(M, InLTO)) {
33609467b48Spatrick     std::string SymtabFailure = toString(std::move(E));
33773471bf0Spatrick     M.getContext().emitError("Failed to create symtab: " + SymtabFailure);
33809467b48Spatrick     return false;
33909467b48Spatrick   }
34009467b48Spatrick   bool Changed = false;
34109467b48Spatrick   for (auto &F : M) {
34209467b48Spatrick     if (F.isDeclaration() || F.hasOptNone())
34309467b48Spatrick       continue;
34409467b48Spatrick 
34509467b48Spatrick     std::unique_ptr<OptimizationRemarkEmitter> OwnedORE;
34609467b48Spatrick     OptimizationRemarkEmitter *ORE;
34709467b48Spatrick     if (AM) {
34809467b48Spatrick       auto &FAM =
34909467b48Spatrick           AM->getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
35009467b48Spatrick       ORE = &FAM.getResult<OptimizationRemarkEmitterAnalysis>(F);
35109467b48Spatrick     } else {
35209467b48Spatrick       OwnedORE = std::make_unique<OptimizationRemarkEmitter>(&F);
35309467b48Spatrick       ORE = OwnedORE.get();
35409467b48Spatrick     }
35509467b48Spatrick 
35609467b48Spatrick     ICallPromotionFunc ICallPromotion(F, &M, &Symtab, SamplePGO, *ORE);
35709467b48Spatrick     bool FuncChanged = ICallPromotion.processFunction(PSI);
35809467b48Spatrick     if (ICPDUMPAFTER && FuncChanged) {
35909467b48Spatrick       LLVM_DEBUG(dbgs() << "\n== IR Dump After =="; F.print(dbgs()));
36009467b48Spatrick       LLVM_DEBUG(dbgs() << "\n");
36109467b48Spatrick     }
36209467b48Spatrick     Changed |= FuncChanged;
36309467b48Spatrick     if (ICPCutOff != 0 && NumOfPGOICallPromotion >= ICPCutOff) {
36409467b48Spatrick       LLVM_DEBUG(dbgs() << " Stop: Cutoff reached.\n");
36509467b48Spatrick       break;
36609467b48Spatrick     }
36709467b48Spatrick   }
36809467b48Spatrick   return Changed;
36909467b48Spatrick }
37009467b48Spatrick 
run(Module & M,ModuleAnalysisManager & AM)37109467b48Spatrick PreservedAnalyses PGOIndirectCallPromotion::run(Module &M,
37209467b48Spatrick                                                 ModuleAnalysisManager &AM) {
37309467b48Spatrick   ProfileSummaryInfo *PSI = &AM.getResult<ProfileSummaryAnalysis>(M);
37409467b48Spatrick 
37509467b48Spatrick   if (!promoteIndirectCalls(M, PSI, InLTO | ICPLTOMode,
37609467b48Spatrick                             SamplePGO | ICPSamplePGOMode, &AM))
37709467b48Spatrick     return PreservedAnalyses::all();
37809467b48Spatrick 
37909467b48Spatrick   return PreservedAnalyses::none();
38009467b48Spatrick }
381