60 #define DEBUG_TYPE "pgo-icall-prom" 62 STATISTIC(NumOfPGOICallPromotion,
"Number of indirect call promotions.");
63 STATISTIC(NumOfPGOICallsites,
"Number of indirect call candidate sites.");
68 cl::desc(
"Disable indirect call promotion"));
76 cl::desc(
"Max number of promotions for this compilation"));
82 cl::desc(
"Skip Callsite up to this number for this compilation"));
88 cl::desc(
"Run indirect-call promotion in LTO " 95 cl::desc(
"Run indirect-call promotion in SamplePGO mode"));
101 cl::desc(
"Run indirect-call promotion for call instructions " 108 cl::desc(
"Run indirect-call promotion for " 109 "invoke instruction only"));
115 cl::desc(
"Dump IR after transformation happens"));
119 class PGOIndirectCallPromotionLegacyPass :
public ModulePass {
123 PGOIndirectCallPromotionLegacyPass(
bool InLTO =
false,
bool SamplePGO =
false)
124 :
ModulePass(ID), InLTO(InLTO), SamplePGO(SamplePGO) {
133 StringRef getPassName()
const override {
return "PGOIndirectCallPromotion"; }
136 bool runOnModule(
Module &M)
override;
152 "Use PGO instrumentation profile to promote indirect " 153 "calls to direct calls.",
163 return new PGOIndirectCallPromotionLegacyPass(InLTO, SamplePGO);
170 class ICallPromotionFunc {
184 struct PromotionCandidate {
188 PromotionCandidate(
Function *F, uint64_t
C) : TargetFunction(F), Count(C) {}
196 std::vector<PromotionCandidate> getPromotionCandidatesForCallSite(
198 uint64_t TotalCount,
uint32_t NumCandidates);
203 const std::vector<PromotionCandidate> &Candidates,
204 uint64_t &TotalCount);
209 :
F(Func), M(Modu), Symtab(Symtab), SamplePGO(SamplePGO), ORE(ORE) {}
210 ICallPromotionFunc(
const ICallPromotionFunc &) =
delete;
211 ICallPromotionFunc &operator=(
const ICallPromotionFunc &) =
delete;
220 std::vector<ICallPromotionFunc::PromotionCandidate>
221 ICallPromotionFunc::getPromotionCandidatesForCallSite(
223 uint64_t TotalCount,
uint32_t NumCandidates) {
224 std::vector<PromotionCandidate>
Ret;
226 LLVM_DEBUG(
dbgs() <<
" \nWork on callsite #" << NumOfPGOICallsites << *Inst
227 <<
" Num_targets: " << ValueDataRef.
size()
228 <<
" Num_candidates: " << NumCandidates <<
"\n");
229 NumOfPGOICallsites++;
236 uint64_t Count = ValueDataRef[
I].Count;
237 assert(Count <= TotalCount);
238 uint64_t
Target = ValueDataRef[
I].Value;
240 <<
" Target_func: " << Target <<
"\n");
246 <<
" Not promote: User options";
254 <<
" Not promote: User options";
262 <<
" Not promote: Cutoff reached";
268 if (TargetFunction ==
nullptr) {
272 <<
"Cannot promote indirect call: target with md5sum " 273 <<
ore::NV(
"target md5sum", Target) <<
" not found";
278 const char *Reason =
nullptr;
284 <<
"Cannot promote indirect call to " 285 <<
NV(
"TargetFunction", TargetFunction) <<
" with count of " 286 <<
NV(
"Count", Count) <<
": " << Reason;
291 Ret.push_back(PromotionCandidate(TargetFunction, Count));
299 uint64_t Count, uint64_t TotalCount,
300 bool AttachProfToDirectCall,
303 uint64_t ElseCount = TotalCount - Count;
304 uint64_t MaxCount = (Count >= ElseCount ? Count : ElseCount);
307 MDNode *BranchWeights = MDB.createBranchWeights(
313 if (AttachProfToDirectCall) {
325 <<
"Promote indirect call to " <<
NV(
"DirectCallee", DirectCallee)
326 <<
" with count " <<
NV(
"Count", Count) <<
" out of " 327 <<
NV(
"TotalCount", TotalCount);
333 uint32_t ICallPromotionFunc::tryToPromote(
334 Instruction *Inst,
const std::vector<PromotionCandidate> &Candidates,
335 uint64_t &TotalCount) {
338 for (
auto &
C : Candidates) {
339 uint64_t Count =
C.Count;
342 assert(TotalCount >= Count);
344 NumOfPGOICallPromotion++;
353 bool Changed =
false;
359 I, NumVals, TotalCount, NumCandidates);
360 if (!NumCandidates ||
363 auto PromotionCandidates = getPromotionCandidatesForCallSite(
364 I, ICallProfDataRef, TotalCount, NumCandidates);
365 uint32_t NumPromoted = tryToPromote(
I, PromotionCandidates, TotalCount);
366 if (NumPromoted == 0)
373 if (TotalCount == 0 || NumPromoted == NumVals)
377 IPVK_IndirectCallTarget, NumCandidates);
384 bool InLTO,
bool SamplePGO,
390 std::string SymtabFailure =
toString(std::move(
E));
391 LLVM_DEBUG(
dbgs() <<
"Failed to create symtab: " << SymtabFailure <<
"\n");
395 bool Changed =
false;
397 if (
F.isDeclaration())
402 std::unique_ptr<OptimizationRemarkEmitter> OwnedORE;
409 OwnedORE = llvm::make_unique<OptimizationRemarkEmitter>(&
F);
410 ORE = OwnedORE.get();
413 ICallPromotionFunc ICallPromotion(
F, &M, &Symtab, SamplePGO, *ORE);
414 bool FuncChanged = ICallPromotion.processFunction(PSI);
419 Changed |= FuncChanged;
428 bool PGOIndirectCallPromotionLegacyPass::runOnModule(
Module &M) {
430 &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
const Function & getFunction() const
A symbol table used for function PGO name look-up with keys (such as pointers, md5hash values) to the...
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
DiagnosticInfoOptimizationBase::Argument NV
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
This class represents lattice values for constants.
A Module instance is used to store all the information related to an LLVM module. ...
void push_back(const T &Elt)
Analysis providing profile information.
LLVMContext & getContext() const
All values hold a context through their type.
bool isLegalToPromote(CallSite CS, Function *Callee, const char **FailureReason=nullptr)
Return true if the given indirect call site can be made to call Callee.
STATISTIC(NumFunctions, "Total number of functions")
bool isHotCount(uint64_t C)
Returns true if count C is considered hot.
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
std::string toString(Error E)
Write all error messages (if any) in E to a string.
An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
A Use represents the edge between a Value definition and its users.
This file contains the simple types necessary to represent the attributes associated with functions a...
This file provides the interface for IR based instrumentation passes ( (profile-gen, and profile-use).
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Instruction * promoteIndirectCall(Instruction *Inst, Function *F, uint64_t Count, uint64_t TotalCount, bool AttachProfToDirectCall, OptimizationRemarkEmitter *ORE)
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
bool hasProfileSummary()
Returns true if profile summary is available.
initializer< Ty > init(const Ty &Val)
A set of analyses that are preserved following a run of a transformation pass.
An analysis pass based on the new PM to deliver ProfileSummaryInfo.
size_t size() const
size - Get the array size.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Represent the analysis usage information of a pass.
static uint64_t calculateCountScale(uint64_t MaxCount)
Calculate what to divide by to scale counts.
static uint32_t scaleBranchCount(uint64_t Count, uint64_t Scale)
Scale an individual branch count.
void annotateValueSite(Module &M, Instruction &Inst, const InstrProfRecord &InstrProfR, InstrProfValueKind ValueKind, uint32_t SiteIndx, uint32_t MaxMDCount=3)
Get the value profile data for value site SiteIdx from InstrProfR and annotate the instruction Inst w...
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
Error create(object::SectionRef &Section)
Create InstrProfSymtab from an object file section which contains function PGO names.
Instruction * promoteCallWithIfThenElse(CallSite CS, Function *Callee, MDNode *BranchWeights=nullptr)
Promote the given indirect call site to conditionally call Callee.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
void initializePGOIndirectCallPromotionLegacyPassPass(PassRegistry &)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Target - Wrapper for Target specific information.
pgo instr Read PGO instrumentation profile
std::vector< Instruction * > findIndirectCalls(Function &F)
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Lightweight error class with error context and mandatory checking.
StringRef - Represent a constant reference to a string, i.e.
A container for analyses that lazily runs them and caches their results.
This header defines various interfaces for pass management in LLVM.
ModulePass * createPGOIndirectCallPromotionLegacyPass(bool InLTO=false, bool SamplePGO=false)
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...