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