xref: /aosp_15_r20/external/llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- IndirectCallPromotion.cpp - Promote indirect calls to direct calls ===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                      The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file implements the transformation that promotes indirect calls to
11*9880d681SAndroid Build Coastguard Worker // conditional direct calls when the indirect-call value profile metadata is
12*9880d681SAndroid Build Coastguard Worker // available.
13*9880d681SAndroid Build Coastguard Worker //
14*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
15*9880d681SAndroid Build Coastguard Worker 
16*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Statistic.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Triple.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/CFG.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/IndirectCallPromotionAnalysis.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/IndirectCallSiteVisitor.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/CallSite.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DiagnosticInfo.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/IRBuilder.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/InstIterator.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/InstVisitor.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Instructions.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/IntrinsicInst.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/MDBuilder.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Module.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/Pass.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/ProfileData/InstrProfReader.h"
33*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
34*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/Instrumentation.h"
35*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/PGOInstrumentation.h"
36*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/Utils/BasicBlockUtils.h"
37*9880d681SAndroid Build Coastguard Worker #include <string>
38*9880d681SAndroid Build Coastguard Worker #include <utility>
39*9880d681SAndroid Build Coastguard Worker #include <vector>
40*9880d681SAndroid Build Coastguard Worker 
41*9880d681SAndroid Build Coastguard Worker using namespace llvm;
42*9880d681SAndroid Build Coastguard Worker 
43*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "pgo-icall-prom"
44*9880d681SAndroid Build Coastguard Worker 
45*9880d681SAndroid Build Coastguard Worker STATISTIC(NumOfPGOICallPromotion, "Number of indirect call promotions.");
46*9880d681SAndroid Build Coastguard Worker STATISTIC(NumOfPGOICallsites, "Number of indirect call candidate sites.");
47*9880d681SAndroid Build Coastguard Worker 
48*9880d681SAndroid Build Coastguard Worker // Command line option to disable indirect-call promotion with the default as
49*9880d681SAndroid Build Coastguard Worker // false. This is for debug purpose.
50*9880d681SAndroid Build Coastguard Worker static cl::opt<bool> DisableICP("disable-icp", cl::init(false), cl::Hidden,
51*9880d681SAndroid Build Coastguard Worker                                 cl::desc("Disable indirect call promotion"));
52*9880d681SAndroid Build Coastguard Worker 
53*9880d681SAndroid Build Coastguard Worker // Set the cutoff value for the promotion. If the value is other than 0, we
54*9880d681SAndroid Build Coastguard Worker // stop the transformation once the total number of promotions equals the cutoff
55*9880d681SAndroid Build Coastguard Worker // value.
56*9880d681SAndroid Build Coastguard Worker // For debug use only.
57*9880d681SAndroid Build Coastguard Worker static cl::opt<unsigned>
58*9880d681SAndroid Build Coastguard Worker     ICPCutOff("icp-cutoff", cl::init(0), cl::Hidden, cl::ZeroOrMore,
59*9880d681SAndroid Build Coastguard Worker               cl::desc("Max number of promotions for this compilaiton"));
60*9880d681SAndroid Build Coastguard Worker 
61*9880d681SAndroid Build Coastguard Worker // If ICPCSSkip is non zero, the first ICPCSSkip callsites will be skipped.
62*9880d681SAndroid Build Coastguard Worker // For debug use only.
63*9880d681SAndroid Build Coastguard Worker static cl::opt<unsigned>
64*9880d681SAndroid Build Coastguard Worker     ICPCSSkip("icp-csskip", cl::init(0), cl::Hidden, cl::ZeroOrMore,
65*9880d681SAndroid Build Coastguard Worker               cl::desc("Skip Callsite up to this number for this compilaiton"));
66*9880d681SAndroid Build Coastguard Worker 
67*9880d681SAndroid Build Coastguard Worker // Set if the pass is called in LTO optimization. The difference for LTO mode
68*9880d681SAndroid Build Coastguard Worker // is the pass won't prefix the source module name to the internal linkage
69*9880d681SAndroid Build Coastguard Worker // symbols.
70*9880d681SAndroid Build Coastguard Worker static cl::opt<bool> ICPLTOMode("icp-lto", cl::init(false), cl::Hidden,
71*9880d681SAndroid Build Coastguard Worker                                 cl::desc("Run indirect-call promotion in LTO "
72*9880d681SAndroid Build Coastguard Worker                                          "mode"));
73*9880d681SAndroid Build Coastguard Worker 
74*9880d681SAndroid Build Coastguard Worker // If the option is set to true, only call instructions will be considered for
75*9880d681SAndroid Build Coastguard Worker // transformation -- invoke instructions will be ignored.
76*9880d681SAndroid Build Coastguard Worker static cl::opt<bool>
77*9880d681SAndroid Build Coastguard Worker     ICPCallOnly("icp-call-only", cl::init(false), cl::Hidden,
78*9880d681SAndroid Build Coastguard Worker                 cl::desc("Run indirect-call promotion for call instructions "
79*9880d681SAndroid Build Coastguard Worker                          "only"));
80*9880d681SAndroid Build Coastguard Worker 
81*9880d681SAndroid Build Coastguard Worker // If the option is set to true, only invoke instructions will be considered for
82*9880d681SAndroid Build Coastguard Worker // transformation -- call instructions will be ignored.
83*9880d681SAndroid Build Coastguard Worker static cl::opt<bool> ICPInvokeOnly("icp-invoke-only", cl::init(false),
84*9880d681SAndroid Build Coastguard Worker                                    cl::Hidden,
85*9880d681SAndroid Build Coastguard Worker                                    cl::desc("Run indirect-call promotion for "
86*9880d681SAndroid Build Coastguard Worker                                             "invoke instruction only"));
87*9880d681SAndroid Build Coastguard Worker 
88*9880d681SAndroid Build Coastguard Worker // Dump the function level IR if the transformation happened in this
89*9880d681SAndroid Build Coastguard Worker // function. For debug use only.
90*9880d681SAndroid Build Coastguard Worker static cl::opt<bool>
91*9880d681SAndroid Build Coastguard Worker     ICPDUMPAFTER("icp-dumpafter", cl::init(false), cl::Hidden,
92*9880d681SAndroid Build Coastguard Worker                  cl::desc("Dump IR after transformation happens"));
93*9880d681SAndroid Build Coastguard Worker 
94*9880d681SAndroid Build Coastguard Worker namespace {
95*9880d681SAndroid Build Coastguard Worker class PGOIndirectCallPromotionLegacyPass : public ModulePass {
96*9880d681SAndroid Build Coastguard Worker public:
97*9880d681SAndroid Build Coastguard Worker   static char ID;
98*9880d681SAndroid Build Coastguard Worker 
PGOIndirectCallPromotionLegacyPass(bool InLTO=false)99*9880d681SAndroid Build Coastguard Worker   PGOIndirectCallPromotionLegacyPass(bool InLTO = false)
100*9880d681SAndroid Build Coastguard Worker       : ModulePass(ID), InLTO(InLTO) {
101*9880d681SAndroid Build Coastguard Worker     initializePGOIndirectCallPromotionLegacyPassPass(
102*9880d681SAndroid Build Coastguard Worker         *PassRegistry::getPassRegistry());
103*9880d681SAndroid Build Coastguard Worker   }
104*9880d681SAndroid Build Coastguard Worker 
getPassName() const105*9880d681SAndroid Build Coastguard Worker   const char *getPassName() const override {
106*9880d681SAndroid Build Coastguard Worker     return "PGOIndirectCallPromotion";
107*9880d681SAndroid Build Coastguard Worker   }
108*9880d681SAndroid Build Coastguard Worker 
109*9880d681SAndroid Build Coastguard Worker private:
110*9880d681SAndroid Build Coastguard Worker   bool runOnModule(Module &M) override;
111*9880d681SAndroid Build Coastguard Worker 
112*9880d681SAndroid Build Coastguard Worker   // If this pass is called in LTO. We need to special handling the PGOFuncName
113*9880d681SAndroid Build Coastguard Worker   // for the static variables due to LTO's internalization.
114*9880d681SAndroid Build Coastguard Worker   bool InLTO;
115*9880d681SAndroid Build Coastguard Worker };
116*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace
117*9880d681SAndroid Build Coastguard Worker 
118*9880d681SAndroid Build Coastguard Worker char PGOIndirectCallPromotionLegacyPass::ID = 0;
119*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS(PGOIndirectCallPromotionLegacyPass, "pgo-icall-prom",
120*9880d681SAndroid Build Coastguard Worker                 "Use PGO instrumentation profile to promote indirect calls to "
121*9880d681SAndroid Build Coastguard Worker                 "direct calls.",
122*9880d681SAndroid Build Coastguard Worker                 false, false)
123*9880d681SAndroid Build Coastguard Worker 
createPGOIndirectCallPromotionLegacyPass(bool InLTO)124*9880d681SAndroid Build Coastguard Worker ModulePass *llvm::createPGOIndirectCallPromotionLegacyPass(bool InLTO) {
125*9880d681SAndroid Build Coastguard Worker   return new PGOIndirectCallPromotionLegacyPass(InLTO);
126*9880d681SAndroid Build Coastguard Worker }
127*9880d681SAndroid Build Coastguard Worker 
128*9880d681SAndroid Build Coastguard Worker namespace {
129*9880d681SAndroid Build Coastguard Worker // The class for main data structure to promote indirect calls to conditional
130*9880d681SAndroid Build Coastguard Worker // direct calls.
131*9880d681SAndroid Build Coastguard Worker class ICallPromotionFunc {
132*9880d681SAndroid Build Coastguard Worker private:
133*9880d681SAndroid Build Coastguard Worker   Function &F;
134*9880d681SAndroid Build Coastguard Worker   Module *M;
135*9880d681SAndroid Build Coastguard Worker 
136*9880d681SAndroid Build Coastguard Worker   // Symtab that maps indirect call profile values to function names and
137*9880d681SAndroid Build Coastguard Worker   // defines.
138*9880d681SAndroid Build Coastguard Worker   InstrProfSymtab *Symtab;
139*9880d681SAndroid Build Coastguard Worker 
140*9880d681SAndroid Build Coastguard Worker   enum TargetStatus {
141*9880d681SAndroid Build Coastguard Worker     OK,                   // Should be able to promote.
142*9880d681SAndroid Build Coastguard Worker     NotAvailableInModule, // Cannot find the target in current module.
143*9880d681SAndroid Build Coastguard Worker     ReturnTypeMismatch,   // Return type mismatch b/w target and indirect-call.
144*9880d681SAndroid Build Coastguard Worker     NumArgsMismatch,      // Number of arguments does not match.
145*9880d681SAndroid Build Coastguard Worker     ArgTypeMismatch       // Type mismatch in the arguments (cannot bitcast).
146*9880d681SAndroid Build Coastguard Worker   };
147*9880d681SAndroid Build Coastguard Worker 
148*9880d681SAndroid Build Coastguard Worker   // Test if we can legally promote this direct-call of Target.
149*9880d681SAndroid Build Coastguard Worker   TargetStatus isPromotionLegal(Instruction *Inst, uint64_t Target,
150*9880d681SAndroid Build Coastguard Worker                                 Function *&F);
151*9880d681SAndroid Build Coastguard Worker 
152*9880d681SAndroid Build Coastguard Worker   // A struct that records the direct target and it's call count.
153*9880d681SAndroid Build Coastguard Worker   struct PromotionCandidate {
154*9880d681SAndroid Build Coastguard Worker     Function *TargetFunction;
155*9880d681SAndroid Build Coastguard Worker     uint64_t Count;
PromotionCandidate__anonccd0911e0211::ICallPromotionFunc::PromotionCandidate156*9880d681SAndroid Build Coastguard Worker     PromotionCandidate(Function *F, uint64_t C) : TargetFunction(F), Count(C) {}
157*9880d681SAndroid Build Coastguard Worker   };
158*9880d681SAndroid Build Coastguard Worker 
159*9880d681SAndroid Build Coastguard Worker   // Check if the indirect-call call site should be promoted. Return the number
160*9880d681SAndroid Build Coastguard Worker   // of promotions. Inst is the candidate indirect call, ValueDataRef
161*9880d681SAndroid Build Coastguard Worker   // contains the array of value profile data for profiled targets,
162*9880d681SAndroid Build Coastguard Worker   // TotalCount is the total profiled count of call executions, and
163*9880d681SAndroid Build Coastguard Worker   // NumCandidates is the number of candidate entries in ValueDataRef.
164*9880d681SAndroid Build Coastguard Worker   std::vector<PromotionCandidate> getPromotionCandidatesForCallSite(
165*9880d681SAndroid Build Coastguard Worker       Instruction *Inst, const ArrayRef<InstrProfValueData> &ValueDataRef,
166*9880d681SAndroid Build Coastguard Worker       uint64_t TotalCount, uint32_t NumCandidates);
167*9880d681SAndroid Build Coastguard Worker 
168*9880d681SAndroid Build Coastguard Worker   // Main function that transforms Inst (either a indirect-call instruction, or
169*9880d681SAndroid Build Coastguard Worker   // an invoke instruction , to a conditional call to F. This is like:
170*9880d681SAndroid Build Coastguard Worker   //     if (Inst.CalledValue == F)
171*9880d681SAndroid Build Coastguard Worker   //        F(...);
172*9880d681SAndroid Build Coastguard Worker   //     else
173*9880d681SAndroid Build Coastguard Worker   //        Inst(...);
174*9880d681SAndroid Build Coastguard Worker   //     end
175*9880d681SAndroid Build Coastguard Worker   // TotalCount is the profile count value that the instruction executes.
176*9880d681SAndroid Build Coastguard Worker   // Count is the profile count value that F is the target function.
177*9880d681SAndroid Build Coastguard Worker   // These two values are being used to update the branch weight.
178*9880d681SAndroid Build Coastguard Worker   void promote(Instruction *Inst, Function *F, uint64_t Count,
179*9880d681SAndroid Build Coastguard Worker                uint64_t TotalCount);
180*9880d681SAndroid Build Coastguard Worker 
181*9880d681SAndroid Build Coastguard Worker   // Promote a list of targets for one indirect-call callsite. Return
182*9880d681SAndroid Build Coastguard Worker   // the number of promotions.
183*9880d681SAndroid Build Coastguard Worker   uint32_t tryToPromote(Instruction *Inst,
184*9880d681SAndroid Build Coastguard Worker                         const std::vector<PromotionCandidate> &Candidates,
185*9880d681SAndroid Build Coastguard Worker                         uint64_t &TotalCount);
186*9880d681SAndroid Build Coastguard Worker 
StatusToString(const TargetStatus S)187*9880d681SAndroid Build Coastguard Worker   static const char *StatusToString(const TargetStatus S) {
188*9880d681SAndroid Build Coastguard Worker     switch (S) {
189*9880d681SAndroid Build Coastguard Worker     case OK:
190*9880d681SAndroid Build Coastguard Worker       return "OK to promote";
191*9880d681SAndroid Build Coastguard Worker     case NotAvailableInModule:
192*9880d681SAndroid Build Coastguard Worker       return "Cannot find the target";
193*9880d681SAndroid Build Coastguard Worker     case ReturnTypeMismatch:
194*9880d681SAndroid Build Coastguard Worker       return "Return type mismatch";
195*9880d681SAndroid Build Coastguard Worker     case NumArgsMismatch:
196*9880d681SAndroid Build Coastguard Worker       return "The number of arguments mismatch";
197*9880d681SAndroid Build Coastguard Worker     case ArgTypeMismatch:
198*9880d681SAndroid Build Coastguard Worker       return "Argument Type mismatch";
199*9880d681SAndroid Build Coastguard Worker     }
200*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Should not reach here");
201*9880d681SAndroid Build Coastguard Worker   }
202*9880d681SAndroid Build Coastguard Worker 
203*9880d681SAndroid Build Coastguard Worker   // Noncopyable
204*9880d681SAndroid Build Coastguard Worker   ICallPromotionFunc(const ICallPromotionFunc &other) = delete;
205*9880d681SAndroid Build Coastguard Worker   ICallPromotionFunc &operator=(const ICallPromotionFunc &other) = delete;
206*9880d681SAndroid Build Coastguard Worker 
207*9880d681SAndroid Build Coastguard Worker public:
ICallPromotionFunc(Function & Func,Module * Modu,InstrProfSymtab * Symtab)208*9880d681SAndroid Build Coastguard Worker   ICallPromotionFunc(Function &Func, Module *Modu, InstrProfSymtab *Symtab)
209*9880d681SAndroid Build Coastguard Worker       : F(Func), M(Modu), Symtab(Symtab) {
210*9880d681SAndroid Build Coastguard Worker   }
211*9880d681SAndroid Build Coastguard Worker   bool processFunction();
212*9880d681SAndroid Build Coastguard Worker };
213*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace
214*9880d681SAndroid Build Coastguard Worker 
215*9880d681SAndroid Build Coastguard Worker ICallPromotionFunc::TargetStatus
isPromotionLegal(Instruction * Inst,uint64_t Target,Function * & TargetFunction)216*9880d681SAndroid Build Coastguard Worker ICallPromotionFunc::isPromotionLegal(Instruction *Inst, uint64_t Target,
217*9880d681SAndroid Build Coastguard Worker                                      Function *&TargetFunction) {
218*9880d681SAndroid Build Coastguard Worker   Function *DirectCallee = Symtab->getFunction(Target);
219*9880d681SAndroid Build Coastguard Worker   if (DirectCallee == nullptr)
220*9880d681SAndroid Build Coastguard Worker     return NotAvailableInModule;
221*9880d681SAndroid Build Coastguard Worker   // Check the return type.
222*9880d681SAndroid Build Coastguard Worker   Type *CallRetType = Inst->getType();
223*9880d681SAndroid Build Coastguard Worker   if (!CallRetType->isVoidTy()) {
224*9880d681SAndroid Build Coastguard Worker     Type *FuncRetType = DirectCallee->getReturnType();
225*9880d681SAndroid Build Coastguard Worker     if (FuncRetType != CallRetType &&
226*9880d681SAndroid Build Coastguard Worker         !CastInst::isBitCastable(FuncRetType, CallRetType))
227*9880d681SAndroid Build Coastguard Worker       return ReturnTypeMismatch;
228*9880d681SAndroid Build Coastguard Worker   }
229*9880d681SAndroid Build Coastguard Worker 
230*9880d681SAndroid Build Coastguard Worker   // Check if the arguments are compatible with the parameters
231*9880d681SAndroid Build Coastguard Worker   FunctionType *DirectCalleeType = DirectCallee->getFunctionType();
232*9880d681SAndroid Build Coastguard Worker   unsigned ParamNum = DirectCalleeType->getFunctionNumParams();
233*9880d681SAndroid Build Coastguard Worker   CallSite CS(Inst);
234*9880d681SAndroid Build Coastguard Worker   unsigned ArgNum = CS.arg_size();
235*9880d681SAndroid Build Coastguard Worker 
236*9880d681SAndroid Build Coastguard Worker   if (ParamNum != ArgNum && !DirectCalleeType->isVarArg())
237*9880d681SAndroid Build Coastguard Worker     return NumArgsMismatch;
238*9880d681SAndroid Build Coastguard Worker 
239*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 0; I < ParamNum; ++I) {
240*9880d681SAndroid Build Coastguard Worker     Type *PTy = DirectCalleeType->getFunctionParamType(I);
241*9880d681SAndroid Build Coastguard Worker     Type *ATy = CS.getArgument(I)->getType();
242*9880d681SAndroid Build Coastguard Worker     if (PTy == ATy)
243*9880d681SAndroid Build Coastguard Worker       continue;
244*9880d681SAndroid Build Coastguard Worker     if (!CastInst::castIsValid(Instruction::BitCast, CS.getArgument(I), PTy))
245*9880d681SAndroid Build Coastguard Worker       return ArgTypeMismatch;
246*9880d681SAndroid Build Coastguard Worker   }
247*9880d681SAndroid Build Coastguard Worker 
248*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << " #" << NumOfPGOICallPromotion << " Promote the icall to "
249*9880d681SAndroid Build Coastguard Worker                << Symtab->getFuncName(Target) << "\n");
250*9880d681SAndroid Build Coastguard Worker   TargetFunction = DirectCallee;
251*9880d681SAndroid Build Coastguard Worker   return OK;
252*9880d681SAndroid Build Coastguard Worker }
253*9880d681SAndroid Build Coastguard Worker 
254*9880d681SAndroid Build Coastguard Worker // Indirect-call promotion heuristic. The direct targets are sorted based on
255*9880d681SAndroid Build Coastguard Worker // the count. Stop at the first target that is not promoted.
256*9880d681SAndroid Build Coastguard Worker std::vector<ICallPromotionFunc::PromotionCandidate>
getPromotionCandidatesForCallSite(Instruction * Inst,const ArrayRef<InstrProfValueData> & ValueDataRef,uint64_t TotalCount,uint32_t NumCandidates)257*9880d681SAndroid Build Coastguard Worker ICallPromotionFunc::getPromotionCandidatesForCallSite(
258*9880d681SAndroid Build Coastguard Worker     Instruction *Inst, const ArrayRef<InstrProfValueData> &ValueDataRef,
259*9880d681SAndroid Build Coastguard Worker     uint64_t TotalCount, uint32_t NumCandidates) {
260*9880d681SAndroid Build Coastguard Worker   std::vector<PromotionCandidate> Ret;
261*9880d681SAndroid Build Coastguard Worker 
262*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << " \nWork on callsite #" << NumOfPGOICallsites << *Inst
263*9880d681SAndroid Build Coastguard Worker                << " Num_targets: " << ValueDataRef.size()
264*9880d681SAndroid Build Coastguard Worker                << " Num_candidates: " << NumCandidates << "\n");
265*9880d681SAndroid Build Coastguard Worker   NumOfPGOICallsites++;
266*9880d681SAndroid Build Coastguard Worker   if (ICPCSSkip != 0 && NumOfPGOICallsites <= ICPCSSkip) {
267*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << " Skip: User options.\n");
268*9880d681SAndroid Build Coastguard Worker     return Ret;
269*9880d681SAndroid Build Coastguard Worker   }
270*9880d681SAndroid Build Coastguard Worker 
271*9880d681SAndroid Build Coastguard Worker   for (uint32_t I = 0; I < NumCandidates; I++) {
272*9880d681SAndroid Build Coastguard Worker     uint64_t Count = ValueDataRef[I].Count;
273*9880d681SAndroid Build Coastguard Worker     assert(Count <= TotalCount);
274*9880d681SAndroid Build Coastguard Worker     uint64_t Target = ValueDataRef[I].Value;
275*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << " Candidate " << I << " Count=" << Count
276*9880d681SAndroid Build Coastguard Worker                  << "  Target_func: " << Target << "\n");
277*9880d681SAndroid Build Coastguard Worker 
278*9880d681SAndroid Build Coastguard Worker     if (ICPInvokeOnly && dyn_cast<CallInst>(Inst)) {
279*9880d681SAndroid Build Coastguard Worker       DEBUG(dbgs() << " Not promote: User options.\n");
280*9880d681SAndroid Build Coastguard Worker       break;
281*9880d681SAndroid Build Coastguard Worker     }
282*9880d681SAndroid Build Coastguard Worker     if (ICPCallOnly && dyn_cast<InvokeInst>(Inst)) {
283*9880d681SAndroid Build Coastguard Worker       DEBUG(dbgs() << " Not promote: User option.\n");
284*9880d681SAndroid Build Coastguard Worker       break;
285*9880d681SAndroid Build Coastguard Worker     }
286*9880d681SAndroid Build Coastguard Worker     if (ICPCutOff != 0 && NumOfPGOICallPromotion >= ICPCutOff) {
287*9880d681SAndroid Build Coastguard Worker       DEBUG(dbgs() << " Not promote: Cutoff reached.\n");
288*9880d681SAndroid Build Coastguard Worker       break;
289*9880d681SAndroid Build Coastguard Worker     }
290*9880d681SAndroid Build Coastguard Worker     Function *TargetFunction = nullptr;
291*9880d681SAndroid Build Coastguard Worker     TargetStatus Status = isPromotionLegal(Inst, Target, TargetFunction);
292*9880d681SAndroid Build Coastguard Worker     if (Status != OK) {
293*9880d681SAndroid Build Coastguard Worker       StringRef TargetFuncName = Symtab->getFuncName(Target);
294*9880d681SAndroid Build Coastguard Worker       const char *Reason = StatusToString(Status);
295*9880d681SAndroid Build Coastguard Worker       DEBUG(dbgs() << " Not promote: " << Reason << "\n");
296*9880d681SAndroid Build Coastguard Worker       emitOptimizationRemarkMissed(
297*9880d681SAndroid Build Coastguard Worker           F.getContext(), "pgo-icall-prom", F, Inst->getDebugLoc(),
298*9880d681SAndroid Build Coastguard Worker           Twine("Cannot promote indirect call to ") +
299*9880d681SAndroid Build Coastguard Worker               (TargetFuncName.empty() ? Twine(Target) : Twine(TargetFuncName)) +
300*9880d681SAndroid Build Coastguard Worker               Twine(" with count of ") + Twine(Count) + ": " + Reason);
301*9880d681SAndroid Build Coastguard Worker       break;
302*9880d681SAndroid Build Coastguard Worker     }
303*9880d681SAndroid Build Coastguard Worker     Ret.push_back(PromotionCandidate(TargetFunction, Count));
304*9880d681SAndroid Build Coastguard Worker     TotalCount -= Count;
305*9880d681SAndroid Build Coastguard Worker   }
306*9880d681SAndroid Build Coastguard Worker   return Ret;
307*9880d681SAndroid Build Coastguard Worker }
308*9880d681SAndroid Build Coastguard Worker 
309*9880d681SAndroid Build Coastguard Worker // Create a diamond structure for If_Then_Else. Also update the profile
310*9880d681SAndroid Build Coastguard Worker // count. Do the fix-up for the invoke instruction.
createIfThenElse(Instruction * Inst,Function * DirectCallee,uint64_t Count,uint64_t TotalCount,BasicBlock ** DirectCallBB,BasicBlock ** IndirectCallBB,BasicBlock ** MergeBB)311*9880d681SAndroid Build Coastguard Worker static void createIfThenElse(Instruction *Inst, Function *DirectCallee,
312*9880d681SAndroid Build Coastguard Worker                              uint64_t Count, uint64_t TotalCount,
313*9880d681SAndroid Build Coastguard Worker                              BasicBlock **DirectCallBB,
314*9880d681SAndroid Build Coastguard Worker                              BasicBlock **IndirectCallBB,
315*9880d681SAndroid Build Coastguard Worker                              BasicBlock **MergeBB) {
316*9880d681SAndroid Build Coastguard Worker   CallSite CS(Inst);
317*9880d681SAndroid Build Coastguard Worker   Value *OrigCallee = CS.getCalledValue();
318*9880d681SAndroid Build Coastguard Worker 
319*9880d681SAndroid Build Coastguard Worker   IRBuilder<> BBBuilder(Inst);
320*9880d681SAndroid Build Coastguard Worker   LLVMContext &Ctx = Inst->getContext();
321*9880d681SAndroid Build Coastguard Worker   Value *BCI1 =
322*9880d681SAndroid Build Coastguard Worker       BBBuilder.CreateBitCast(OrigCallee, Type::getInt8PtrTy(Ctx), "");
323*9880d681SAndroid Build Coastguard Worker   Value *BCI2 =
324*9880d681SAndroid Build Coastguard Worker       BBBuilder.CreateBitCast(DirectCallee, Type::getInt8PtrTy(Ctx), "");
325*9880d681SAndroid Build Coastguard Worker   Value *PtrCmp = BBBuilder.CreateICmpEQ(BCI1, BCI2, "");
326*9880d681SAndroid Build Coastguard Worker 
327*9880d681SAndroid Build Coastguard Worker   uint64_t ElseCount = TotalCount - Count;
328*9880d681SAndroid Build Coastguard Worker   uint64_t MaxCount = (Count >= ElseCount ? Count : ElseCount);
329*9880d681SAndroid Build Coastguard Worker   uint64_t Scale = calculateCountScale(MaxCount);
330*9880d681SAndroid Build Coastguard Worker   MDBuilder MDB(Inst->getContext());
331*9880d681SAndroid Build Coastguard Worker   MDNode *BranchWeights = MDB.createBranchWeights(
332*9880d681SAndroid Build Coastguard Worker       scaleBranchCount(Count, Scale), scaleBranchCount(ElseCount, Scale));
333*9880d681SAndroid Build Coastguard Worker   TerminatorInst *ThenTerm, *ElseTerm;
334*9880d681SAndroid Build Coastguard Worker   SplitBlockAndInsertIfThenElse(PtrCmp, Inst, &ThenTerm, &ElseTerm,
335*9880d681SAndroid Build Coastguard Worker                                 BranchWeights);
336*9880d681SAndroid Build Coastguard Worker   *DirectCallBB = ThenTerm->getParent();
337*9880d681SAndroid Build Coastguard Worker   (*DirectCallBB)->setName("if.true.direct_targ");
338*9880d681SAndroid Build Coastguard Worker   *IndirectCallBB = ElseTerm->getParent();
339*9880d681SAndroid Build Coastguard Worker   (*IndirectCallBB)->setName("if.false.orig_indirect");
340*9880d681SAndroid Build Coastguard Worker   *MergeBB = Inst->getParent();
341*9880d681SAndroid Build Coastguard Worker   (*MergeBB)->setName("if.end.icp");
342*9880d681SAndroid Build Coastguard Worker 
343*9880d681SAndroid Build Coastguard Worker   // Special handing of Invoke instructions.
344*9880d681SAndroid Build Coastguard Worker   InvokeInst *II = dyn_cast<InvokeInst>(Inst);
345*9880d681SAndroid Build Coastguard Worker   if (!II)
346*9880d681SAndroid Build Coastguard Worker     return;
347*9880d681SAndroid Build Coastguard Worker 
348*9880d681SAndroid Build Coastguard Worker   // We don't need branch instructions for invoke.
349*9880d681SAndroid Build Coastguard Worker   ThenTerm->eraseFromParent();
350*9880d681SAndroid Build Coastguard Worker   ElseTerm->eraseFromParent();
351*9880d681SAndroid Build Coastguard Worker 
352*9880d681SAndroid Build Coastguard Worker   // Add jump from Merge BB to the NormalDest. This is needed for the newly
353*9880d681SAndroid Build Coastguard Worker   // created direct invoke stmt -- as its NormalDst will be fixed up to MergeBB.
354*9880d681SAndroid Build Coastguard Worker   BranchInst::Create(II->getNormalDest(), *MergeBB);
355*9880d681SAndroid Build Coastguard Worker }
356*9880d681SAndroid Build Coastguard Worker 
357*9880d681SAndroid Build Coastguard Worker // Find the PHI in BB that have the CallResult as the operand.
getCallRetPHINode(BasicBlock * BB,Instruction * Inst)358*9880d681SAndroid Build Coastguard Worker static bool getCallRetPHINode(BasicBlock *BB, Instruction *Inst) {
359*9880d681SAndroid Build Coastguard Worker   BasicBlock *From = Inst->getParent();
360*9880d681SAndroid Build Coastguard Worker   for (auto &I : *BB) {
361*9880d681SAndroid Build Coastguard Worker     PHINode *PHI = dyn_cast<PHINode>(&I);
362*9880d681SAndroid Build Coastguard Worker     if (!PHI)
363*9880d681SAndroid Build Coastguard Worker       continue;
364*9880d681SAndroid Build Coastguard Worker     int IX = PHI->getBasicBlockIndex(From);
365*9880d681SAndroid Build Coastguard Worker     if (IX == -1)
366*9880d681SAndroid Build Coastguard Worker       continue;
367*9880d681SAndroid Build Coastguard Worker     Value *V = PHI->getIncomingValue(IX);
368*9880d681SAndroid Build Coastguard Worker     if (dyn_cast<Instruction>(V) == Inst)
369*9880d681SAndroid Build Coastguard Worker       return true;
370*9880d681SAndroid Build Coastguard Worker   }
371*9880d681SAndroid Build Coastguard Worker   return false;
372*9880d681SAndroid Build Coastguard Worker }
373*9880d681SAndroid Build Coastguard Worker 
374*9880d681SAndroid Build Coastguard Worker // This method fixes up PHI nodes in BB where BB is the UnwindDest of an
375*9880d681SAndroid Build Coastguard Worker // invoke instruction. In BB, there may be PHIs with incoming block being
376*9880d681SAndroid Build Coastguard Worker // OrigBB (the MergeBB after if-then-else splitting). After moving the invoke
377*9880d681SAndroid Build Coastguard Worker // instructions to its own BB, OrigBB is no longer the predecessor block of BB.
378*9880d681SAndroid Build Coastguard Worker // Instead two new predecessors are added: IndirectCallBB and DirectCallBB,
379*9880d681SAndroid Build Coastguard Worker // so the PHI node's incoming BBs need to be fixed up accordingly.
fixupPHINodeForUnwind(Instruction * Inst,BasicBlock * BB,BasicBlock * OrigBB,BasicBlock * IndirectCallBB,BasicBlock * DirectCallBB)380*9880d681SAndroid Build Coastguard Worker static void fixupPHINodeForUnwind(Instruction *Inst, BasicBlock *BB,
381*9880d681SAndroid Build Coastguard Worker                                   BasicBlock *OrigBB,
382*9880d681SAndroid Build Coastguard Worker                                   BasicBlock *IndirectCallBB,
383*9880d681SAndroid Build Coastguard Worker                                   BasicBlock *DirectCallBB) {
384*9880d681SAndroid Build Coastguard Worker   for (auto &I : *BB) {
385*9880d681SAndroid Build Coastguard Worker     PHINode *PHI = dyn_cast<PHINode>(&I);
386*9880d681SAndroid Build Coastguard Worker     if (!PHI)
387*9880d681SAndroid Build Coastguard Worker       continue;
388*9880d681SAndroid Build Coastguard Worker     int IX = PHI->getBasicBlockIndex(OrigBB);
389*9880d681SAndroid Build Coastguard Worker     if (IX == -1)
390*9880d681SAndroid Build Coastguard Worker       continue;
391*9880d681SAndroid Build Coastguard Worker     Value *V = PHI->getIncomingValue(IX);
392*9880d681SAndroid Build Coastguard Worker     PHI->addIncoming(V, IndirectCallBB);
393*9880d681SAndroid Build Coastguard Worker     PHI->setIncomingBlock(IX, DirectCallBB);
394*9880d681SAndroid Build Coastguard Worker   }
395*9880d681SAndroid Build Coastguard Worker }
396*9880d681SAndroid Build Coastguard Worker 
397*9880d681SAndroid Build Coastguard Worker // This method fixes up PHI nodes in BB where BB is the NormalDest of an
398*9880d681SAndroid Build Coastguard Worker // invoke instruction. In BB, there may be PHIs with incoming block being
399*9880d681SAndroid Build Coastguard Worker // OrigBB (the MergeBB after if-then-else splitting). After moving the invoke
400*9880d681SAndroid Build Coastguard Worker // instructions to its own BB, a new incoming edge will be added to the original
401*9880d681SAndroid Build Coastguard Worker // NormalDstBB from the IndirectCallBB.
fixupPHINodeForNormalDest(Instruction * Inst,BasicBlock * BB,BasicBlock * OrigBB,BasicBlock * IndirectCallBB,Instruction * NewInst)402*9880d681SAndroid Build Coastguard Worker static void fixupPHINodeForNormalDest(Instruction *Inst, BasicBlock *BB,
403*9880d681SAndroid Build Coastguard Worker                                       BasicBlock *OrigBB,
404*9880d681SAndroid Build Coastguard Worker                                       BasicBlock *IndirectCallBB,
405*9880d681SAndroid Build Coastguard Worker                                       Instruction *NewInst) {
406*9880d681SAndroid Build Coastguard Worker   for (auto &I : *BB) {
407*9880d681SAndroid Build Coastguard Worker     PHINode *PHI = dyn_cast<PHINode>(&I);
408*9880d681SAndroid Build Coastguard Worker     if (!PHI)
409*9880d681SAndroid Build Coastguard Worker       continue;
410*9880d681SAndroid Build Coastguard Worker     int IX = PHI->getBasicBlockIndex(OrigBB);
411*9880d681SAndroid Build Coastguard Worker     if (IX == -1)
412*9880d681SAndroid Build Coastguard Worker       continue;
413*9880d681SAndroid Build Coastguard Worker     Value *V = PHI->getIncomingValue(IX);
414*9880d681SAndroid Build Coastguard Worker     if (dyn_cast<Instruction>(V) == Inst) {
415*9880d681SAndroid Build Coastguard Worker       PHI->setIncomingBlock(IX, IndirectCallBB);
416*9880d681SAndroid Build Coastguard Worker       PHI->addIncoming(NewInst, OrigBB);
417*9880d681SAndroid Build Coastguard Worker       continue;
418*9880d681SAndroid Build Coastguard Worker     }
419*9880d681SAndroid Build Coastguard Worker     PHI->addIncoming(V, IndirectCallBB);
420*9880d681SAndroid Build Coastguard Worker   }
421*9880d681SAndroid Build Coastguard Worker }
422*9880d681SAndroid Build Coastguard Worker 
423*9880d681SAndroid Build Coastguard Worker // Add a bitcast instruction to the direct-call return value if needed.
insertCallRetCast(const Instruction * Inst,Instruction * DirectCallInst,Function * DirectCallee)424*9880d681SAndroid Build Coastguard Worker static Instruction *insertCallRetCast(const Instruction *Inst,
425*9880d681SAndroid Build Coastguard Worker                                       Instruction *DirectCallInst,
426*9880d681SAndroid Build Coastguard Worker                                       Function *DirectCallee) {
427*9880d681SAndroid Build Coastguard Worker   if (Inst->getType()->isVoidTy())
428*9880d681SAndroid Build Coastguard Worker     return DirectCallInst;
429*9880d681SAndroid Build Coastguard Worker 
430*9880d681SAndroid Build Coastguard Worker   Type *CallRetType = Inst->getType();
431*9880d681SAndroid Build Coastguard Worker   Type *FuncRetType = DirectCallee->getReturnType();
432*9880d681SAndroid Build Coastguard Worker   if (FuncRetType == CallRetType)
433*9880d681SAndroid Build Coastguard Worker     return DirectCallInst;
434*9880d681SAndroid Build Coastguard Worker 
435*9880d681SAndroid Build Coastguard Worker   BasicBlock *InsertionBB;
436*9880d681SAndroid Build Coastguard Worker   if (CallInst *CI = dyn_cast<CallInst>(DirectCallInst))
437*9880d681SAndroid Build Coastguard Worker     InsertionBB = CI->getParent();
438*9880d681SAndroid Build Coastguard Worker   else
439*9880d681SAndroid Build Coastguard Worker     InsertionBB = (dyn_cast<InvokeInst>(DirectCallInst))->getNormalDest();
440*9880d681SAndroid Build Coastguard Worker 
441*9880d681SAndroid Build Coastguard Worker   return (new BitCastInst(DirectCallInst, CallRetType, "",
442*9880d681SAndroid Build Coastguard Worker                           InsertionBB->getTerminator()));
443*9880d681SAndroid Build Coastguard Worker }
444*9880d681SAndroid Build Coastguard Worker 
445*9880d681SAndroid Build Coastguard Worker // Create a DirectCall instruction in the DirectCallBB.
446*9880d681SAndroid Build Coastguard Worker // Parameter Inst is the indirect-call (invoke) instruction.
447*9880d681SAndroid Build Coastguard Worker // DirectCallee is the decl of the direct-call (invoke) target.
448*9880d681SAndroid Build Coastguard Worker // DirecallBB is the BB that the direct-call (invoke) instruction is inserted.
449*9880d681SAndroid Build Coastguard Worker // MergeBB is the bottom BB of the if-then-else-diamond after the
450*9880d681SAndroid Build Coastguard Worker // transformation. For invoke instruction, the edges from DirectCallBB and
451*9880d681SAndroid Build Coastguard Worker // IndirectCallBB to MergeBB are removed before this call (during
452*9880d681SAndroid Build Coastguard Worker // createIfThenElse).
createDirectCallInst(const Instruction * Inst,Function * DirectCallee,BasicBlock * DirectCallBB,BasicBlock * MergeBB)453*9880d681SAndroid Build Coastguard Worker static Instruction *createDirectCallInst(const Instruction *Inst,
454*9880d681SAndroid Build Coastguard Worker                                          Function *DirectCallee,
455*9880d681SAndroid Build Coastguard Worker                                          BasicBlock *DirectCallBB,
456*9880d681SAndroid Build Coastguard Worker                                          BasicBlock *MergeBB) {
457*9880d681SAndroid Build Coastguard Worker   Instruction *NewInst = Inst->clone();
458*9880d681SAndroid Build Coastguard Worker   if (CallInst *CI = dyn_cast<CallInst>(NewInst)) {
459*9880d681SAndroid Build Coastguard Worker     CI->setCalledFunction(DirectCallee);
460*9880d681SAndroid Build Coastguard Worker     CI->mutateFunctionType(DirectCallee->getFunctionType());
461*9880d681SAndroid Build Coastguard Worker   } else {
462*9880d681SAndroid Build Coastguard Worker     // Must be an invoke instruction. Direct invoke's normal destination is
463*9880d681SAndroid Build Coastguard Worker     // fixed up to MergeBB. MergeBB is the place where return cast is inserted.
464*9880d681SAndroid Build Coastguard Worker     // Also since IndirectCallBB does not have an edge to MergeBB, there is no
465*9880d681SAndroid Build Coastguard Worker     // need to insert new PHIs into MergeBB.
466*9880d681SAndroid Build Coastguard Worker     InvokeInst *II = dyn_cast<InvokeInst>(NewInst);
467*9880d681SAndroid Build Coastguard Worker     assert(II);
468*9880d681SAndroid Build Coastguard Worker     II->setCalledFunction(DirectCallee);
469*9880d681SAndroid Build Coastguard Worker     II->mutateFunctionType(DirectCallee->getFunctionType());
470*9880d681SAndroid Build Coastguard Worker     II->setNormalDest(MergeBB);
471*9880d681SAndroid Build Coastguard Worker   }
472*9880d681SAndroid Build Coastguard Worker 
473*9880d681SAndroid Build Coastguard Worker   DirectCallBB->getInstList().insert(DirectCallBB->getFirstInsertionPt(),
474*9880d681SAndroid Build Coastguard Worker                                      NewInst);
475*9880d681SAndroid Build Coastguard Worker 
476*9880d681SAndroid Build Coastguard Worker   // Clear the value profile data.
477*9880d681SAndroid Build Coastguard Worker   NewInst->setMetadata(LLVMContext::MD_prof, 0);
478*9880d681SAndroid Build Coastguard Worker   CallSite NewCS(NewInst);
479*9880d681SAndroid Build Coastguard Worker   FunctionType *DirectCalleeType = DirectCallee->getFunctionType();
480*9880d681SAndroid Build Coastguard Worker   unsigned ParamNum = DirectCalleeType->getFunctionNumParams();
481*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 0; I < ParamNum; ++I) {
482*9880d681SAndroid Build Coastguard Worker     Type *ATy = NewCS.getArgument(I)->getType();
483*9880d681SAndroid Build Coastguard Worker     Type *PTy = DirectCalleeType->getParamType(I);
484*9880d681SAndroid Build Coastguard Worker     if (ATy != PTy) {
485*9880d681SAndroid Build Coastguard Worker       BitCastInst *BI = new BitCastInst(NewCS.getArgument(I), PTy, "", NewInst);
486*9880d681SAndroid Build Coastguard Worker       NewCS.setArgument(I, BI);
487*9880d681SAndroid Build Coastguard Worker     }
488*9880d681SAndroid Build Coastguard Worker   }
489*9880d681SAndroid Build Coastguard Worker 
490*9880d681SAndroid Build Coastguard Worker   return insertCallRetCast(Inst, NewInst, DirectCallee);
491*9880d681SAndroid Build Coastguard Worker }
492*9880d681SAndroid Build Coastguard Worker 
493*9880d681SAndroid Build Coastguard Worker // Create a PHI to unify the return values of calls.
insertCallRetPHI(Instruction * Inst,Instruction * CallResult,Function * DirectCallee)494*9880d681SAndroid Build Coastguard Worker static void insertCallRetPHI(Instruction *Inst, Instruction *CallResult,
495*9880d681SAndroid Build Coastguard Worker                              Function *DirectCallee) {
496*9880d681SAndroid Build Coastguard Worker   if (Inst->getType()->isVoidTy())
497*9880d681SAndroid Build Coastguard Worker     return;
498*9880d681SAndroid Build Coastguard Worker 
499*9880d681SAndroid Build Coastguard Worker   BasicBlock *RetValBB = CallResult->getParent();
500*9880d681SAndroid Build Coastguard Worker 
501*9880d681SAndroid Build Coastguard Worker   BasicBlock *PHIBB;
502*9880d681SAndroid Build Coastguard Worker   if (InvokeInst *II = dyn_cast<InvokeInst>(CallResult))
503*9880d681SAndroid Build Coastguard Worker     RetValBB = II->getNormalDest();
504*9880d681SAndroid Build Coastguard Worker 
505*9880d681SAndroid Build Coastguard Worker   PHIBB = RetValBB->getSingleSuccessor();
506*9880d681SAndroid Build Coastguard Worker   if (getCallRetPHINode(PHIBB, Inst))
507*9880d681SAndroid Build Coastguard Worker     return;
508*9880d681SAndroid Build Coastguard Worker 
509*9880d681SAndroid Build Coastguard Worker   PHINode *CallRetPHI = PHINode::Create(Inst->getType(), 0);
510*9880d681SAndroid Build Coastguard Worker   PHIBB->getInstList().push_front(CallRetPHI);
511*9880d681SAndroid Build Coastguard Worker   Inst->replaceAllUsesWith(CallRetPHI);
512*9880d681SAndroid Build Coastguard Worker   CallRetPHI->addIncoming(Inst, Inst->getParent());
513*9880d681SAndroid Build Coastguard Worker   CallRetPHI->addIncoming(CallResult, RetValBB);
514*9880d681SAndroid Build Coastguard Worker }
515*9880d681SAndroid Build Coastguard Worker 
516*9880d681SAndroid Build Coastguard Worker // This function does the actual indirect-call promotion transformation:
517*9880d681SAndroid Build Coastguard Worker // For an indirect-call like:
518*9880d681SAndroid Build Coastguard Worker //     Ret = (*Foo)(Args);
519*9880d681SAndroid Build Coastguard Worker // It transforms to:
520*9880d681SAndroid Build Coastguard Worker //     if (Foo == DirectCallee)
521*9880d681SAndroid Build Coastguard Worker //        Ret1 = DirectCallee(Args);
522*9880d681SAndroid Build Coastguard Worker //     else
523*9880d681SAndroid Build Coastguard Worker //        Ret2 = (*Foo)(Args);
524*9880d681SAndroid Build Coastguard Worker //     Ret = phi(Ret1, Ret2);
525*9880d681SAndroid Build Coastguard Worker // It adds type casts for the args do not match the parameters and the return
526*9880d681SAndroid Build Coastguard Worker // value. Branch weights metadata also updated.
promote(Instruction * Inst,Function * DirectCallee,uint64_t Count,uint64_t TotalCount)527*9880d681SAndroid Build Coastguard Worker void ICallPromotionFunc::promote(Instruction *Inst, Function *DirectCallee,
528*9880d681SAndroid Build Coastguard Worker                                  uint64_t Count, uint64_t TotalCount) {
529*9880d681SAndroid Build Coastguard Worker   assert(DirectCallee != nullptr);
530*9880d681SAndroid Build Coastguard Worker   BasicBlock *BB = Inst->getParent();
531*9880d681SAndroid Build Coastguard Worker   // Just to suppress the non-debug build warning.
532*9880d681SAndroid Build Coastguard Worker   (void)BB;
533*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "\n\n== Basic Block Before ==\n");
534*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << *BB << "\n");
535*9880d681SAndroid Build Coastguard Worker 
536*9880d681SAndroid Build Coastguard Worker   BasicBlock *DirectCallBB, *IndirectCallBB, *MergeBB;
537*9880d681SAndroid Build Coastguard Worker   createIfThenElse(Inst, DirectCallee, Count, TotalCount, &DirectCallBB,
538*9880d681SAndroid Build Coastguard Worker                    &IndirectCallBB, &MergeBB);
539*9880d681SAndroid Build Coastguard Worker 
540*9880d681SAndroid Build Coastguard Worker   Instruction *NewInst =
541*9880d681SAndroid Build Coastguard Worker       createDirectCallInst(Inst, DirectCallee, DirectCallBB, MergeBB);
542*9880d681SAndroid Build Coastguard Worker 
543*9880d681SAndroid Build Coastguard Worker   // Move Inst from MergeBB to IndirectCallBB.
544*9880d681SAndroid Build Coastguard Worker   Inst->removeFromParent();
545*9880d681SAndroid Build Coastguard Worker   IndirectCallBB->getInstList().insert(IndirectCallBB->getFirstInsertionPt(),
546*9880d681SAndroid Build Coastguard Worker                                        Inst);
547*9880d681SAndroid Build Coastguard Worker 
548*9880d681SAndroid Build Coastguard Worker   if (InvokeInst *II = dyn_cast<InvokeInst>(Inst)) {
549*9880d681SAndroid Build Coastguard Worker     // At this point, the original indirect invoke instruction has the original
550*9880d681SAndroid Build Coastguard Worker     // UnwindDest and NormalDest. For the direct invoke instruction, the
551*9880d681SAndroid Build Coastguard Worker     // NormalDest points to MergeBB, and MergeBB jumps to the original
552*9880d681SAndroid Build Coastguard Worker     // NormalDest. MergeBB might have a new bitcast instruction for the return
553*9880d681SAndroid Build Coastguard Worker     // value. The PHIs are with the original NormalDest. Since we now have two
554*9880d681SAndroid Build Coastguard Worker     // incoming edges to NormalDest and UnwindDest, we have to do some fixups.
555*9880d681SAndroid Build Coastguard Worker     //
556*9880d681SAndroid Build Coastguard Worker     // UnwindDest will not use the return value. So pass nullptr here.
557*9880d681SAndroid Build Coastguard Worker     fixupPHINodeForUnwind(Inst, II->getUnwindDest(), MergeBB, IndirectCallBB,
558*9880d681SAndroid Build Coastguard Worker                           DirectCallBB);
559*9880d681SAndroid Build Coastguard Worker     // We don't need to update the operand from NormalDest for DirectCallBB.
560*9880d681SAndroid Build Coastguard Worker     // Pass nullptr here.
561*9880d681SAndroid Build Coastguard Worker     fixupPHINodeForNormalDest(Inst, II->getNormalDest(), MergeBB,
562*9880d681SAndroid Build Coastguard Worker                               IndirectCallBB, NewInst);
563*9880d681SAndroid Build Coastguard Worker   }
564*9880d681SAndroid Build Coastguard Worker 
565*9880d681SAndroid Build Coastguard Worker   insertCallRetPHI(Inst, NewInst, DirectCallee);
566*9880d681SAndroid Build Coastguard Worker 
567*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "\n== Basic Blocks After ==\n");
568*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << *BB << *DirectCallBB << *IndirectCallBB << *MergeBB << "\n");
569*9880d681SAndroid Build Coastguard Worker 
570*9880d681SAndroid Build Coastguard Worker   emitOptimizationRemark(
571*9880d681SAndroid Build Coastguard Worker       F.getContext(), "pgo-icall-prom", F, Inst->getDebugLoc(),
572*9880d681SAndroid Build Coastguard Worker       Twine("Promote indirect call to ") + DirectCallee->getName() +
573*9880d681SAndroid Build Coastguard Worker           " with count " + Twine(Count) + " out of " + Twine(TotalCount));
574*9880d681SAndroid Build Coastguard Worker }
575*9880d681SAndroid Build Coastguard Worker 
576*9880d681SAndroid Build Coastguard Worker // Promote indirect-call to conditional direct-call for one callsite.
tryToPromote(Instruction * Inst,const std::vector<PromotionCandidate> & Candidates,uint64_t & TotalCount)577*9880d681SAndroid Build Coastguard Worker uint32_t ICallPromotionFunc::tryToPromote(
578*9880d681SAndroid Build Coastguard Worker     Instruction *Inst, const std::vector<PromotionCandidate> &Candidates,
579*9880d681SAndroid Build Coastguard Worker     uint64_t &TotalCount) {
580*9880d681SAndroid Build Coastguard Worker   uint32_t NumPromoted = 0;
581*9880d681SAndroid Build Coastguard Worker 
582*9880d681SAndroid Build Coastguard Worker   for (auto &C : Candidates) {
583*9880d681SAndroid Build Coastguard Worker     uint64_t Count = C.Count;
584*9880d681SAndroid Build Coastguard Worker     promote(Inst, C.TargetFunction, Count, TotalCount);
585*9880d681SAndroid Build Coastguard Worker     assert(TotalCount >= Count);
586*9880d681SAndroid Build Coastguard Worker     TotalCount -= Count;
587*9880d681SAndroid Build Coastguard Worker     NumOfPGOICallPromotion++;
588*9880d681SAndroid Build Coastguard Worker     NumPromoted++;
589*9880d681SAndroid Build Coastguard Worker   }
590*9880d681SAndroid Build Coastguard Worker   return NumPromoted;
591*9880d681SAndroid Build Coastguard Worker }
592*9880d681SAndroid Build Coastguard Worker 
593*9880d681SAndroid Build Coastguard Worker // Traverse all the indirect-call callsite and get the value profile
594*9880d681SAndroid Build Coastguard Worker // annotation to perform indirect-call promotion.
processFunction()595*9880d681SAndroid Build Coastguard Worker bool ICallPromotionFunc::processFunction() {
596*9880d681SAndroid Build Coastguard Worker   bool Changed = false;
597*9880d681SAndroid Build Coastguard Worker   ICallPromotionAnalysis ICallAnalysis;
598*9880d681SAndroid Build Coastguard Worker   for (auto &I : findIndirectCallSites(F)) {
599*9880d681SAndroid Build Coastguard Worker     uint32_t NumVals, NumCandidates;
600*9880d681SAndroid Build Coastguard Worker     uint64_t TotalCount;
601*9880d681SAndroid Build Coastguard Worker     auto ICallProfDataRef = ICallAnalysis.getPromotionCandidatesForInstruction(
602*9880d681SAndroid Build Coastguard Worker         I, NumVals, TotalCount, NumCandidates);
603*9880d681SAndroid Build Coastguard Worker     if (!NumCandidates)
604*9880d681SAndroid Build Coastguard Worker       continue;
605*9880d681SAndroid Build Coastguard Worker     auto PromotionCandidates = getPromotionCandidatesForCallSite(
606*9880d681SAndroid Build Coastguard Worker         I, ICallProfDataRef, TotalCount, NumCandidates);
607*9880d681SAndroid Build Coastguard Worker     uint32_t NumPromoted = tryToPromote(I, PromotionCandidates, TotalCount);
608*9880d681SAndroid Build Coastguard Worker     if (NumPromoted == 0)
609*9880d681SAndroid Build Coastguard Worker       continue;
610*9880d681SAndroid Build Coastguard Worker 
611*9880d681SAndroid Build Coastguard Worker     Changed = true;
612*9880d681SAndroid Build Coastguard Worker     // Adjust the MD.prof metadata. First delete the old one.
613*9880d681SAndroid Build Coastguard Worker     I->setMetadata(LLVMContext::MD_prof, 0);
614*9880d681SAndroid Build Coastguard Worker     // If all promoted, we don't need the MD.prof metadata.
615*9880d681SAndroid Build Coastguard Worker     if (TotalCount == 0 || NumPromoted == NumVals)
616*9880d681SAndroid Build Coastguard Worker       continue;
617*9880d681SAndroid Build Coastguard Worker     // Otherwise we need update with the un-promoted records back.
618*9880d681SAndroid Build Coastguard Worker     annotateValueSite(*M, *I, ICallProfDataRef.slice(NumPromoted), TotalCount,
619*9880d681SAndroid Build Coastguard Worker                       IPVK_IndirectCallTarget, NumCandidates);
620*9880d681SAndroid Build Coastguard Worker   }
621*9880d681SAndroid Build Coastguard Worker   return Changed;
622*9880d681SAndroid Build Coastguard Worker }
623*9880d681SAndroid Build Coastguard Worker 
624*9880d681SAndroid Build Coastguard Worker // A wrapper function that does the actual work.
promoteIndirectCalls(Module & M,bool InLTO)625*9880d681SAndroid Build Coastguard Worker static bool promoteIndirectCalls(Module &M, bool InLTO) {
626*9880d681SAndroid Build Coastguard Worker   if (DisableICP)
627*9880d681SAndroid Build Coastguard Worker     return false;
628*9880d681SAndroid Build Coastguard Worker   InstrProfSymtab Symtab;
629*9880d681SAndroid Build Coastguard Worker   Symtab.create(M, InLTO);
630*9880d681SAndroid Build Coastguard Worker   bool Changed = false;
631*9880d681SAndroid Build Coastguard Worker   for (auto &F : M) {
632*9880d681SAndroid Build Coastguard Worker     if (F.isDeclaration())
633*9880d681SAndroid Build Coastguard Worker       continue;
634*9880d681SAndroid Build Coastguard Worker     if (F.hasFnAttribute(Attribute::OptimizeNone))
635*9880d681SAndroid Build Coastguard Worker       continue;
636*9880d681SAndroid Build Coastguard Worker     ICallPromotionFunc ICallPromotion(F, &M, &Symtab);
637*9880d681SAndroid Build Coastguard Worker     bool FuncChanged = ICallPromotion.processFunction();
638*9880d681SAndroid Build Coastguard Worker     if (ICPDUMPAFTER && FuncChanged) {
639*9880d681SAndroid Build Coastguard Worker       DEBUG(dbgs() << "\n== IR Dump After =="; F.print(dbgs()));
640*9880d681SAndroid Build Coastguard Worker       DEBUG(dbgs() << "\n");
641*9880d681SAndroid Build Coastguard Worker     }
642*9880d681SAndroid Build Coastguard Worker     Changed |= FuncChanged;
643*9880d681SAndroid Build Coastguard Worker     if (ICPCutOff != 0 && NumOfPGOICallPromotion >= ICPCutOff) {
644*9880d681SAndroid Build Coastguard Worker       DEBUG(dbgs() << " Stop: Cutoff reached.\n");
645*9880d681SAndroid Build Coastguard Worker       break;
646*9880d681SAndroid Build Coastguard Worker     }
647*9880d681SAndroid Build Coastguard Worker   }
648*9880d681SAndroid Build Coastguard Worker   return Changed;
649*9880d681SAndroid Build Coastguard Worker }
650*9880d681SAndroid Build Coastguard Worker 
runOnModule(Module & M)651*9880d681SAndroid Build Coastguard Worker bool PGOIndirectCallPromotionLegacyPass::runOnModule(Module &M) {
652*9880d681SAndroid Build Coastguard Worker   // Command-line option has the priority for InLTO.
653*9880d681SAndroid Build Coastguard Worker   return promoteIndirectCalls(M, InLTO | ICPLTOMode);
654*9880d681SAndroid Build Coastguard Worker }
655*9880d681SAndroid Build Coastguard Worker 
run(Module & M,AnalysisManager<Module> & AM)656*9880d681SAndroid Build Coastguard Worker PreservedAnalyses PGOIndirectCallPromotion::run(Module &M, AnalysisManager<Module> &AM) {
657*9880d681SAndroid Build Coastguard Worker   if (!promoteIndirectCalls(M, InLTO | ICPLTOMode))
658*9880d681SAndroid Build Coastguard Worker     return PreservedAnalyses::all();
659*9880d681SAndroid Build Coastguard Worker 
660*9880d681SAndroid Build Coastguard Worker   return PreservedAnalyses::none();
661*9880d681SAndroid Build Coastguard Worker }
662