47#include <unordered_map>
53#define DEBUG_TYPE "pgo-icall-prom"
55STATISTIC(NumOfPGOICallPromotion,
"Number of indirect call promotions.");
56STATISTIC(NumOfPGOICallsites,
"Number of indirect call candidate sites.");
67 cl::desc(
"Disable indirect call promotion"));
75 cl::desc(
"Max number of promotions for this compilation"));
81 cl::desc(
"Skip Callsite up to this number for this compilation"));
86 cl::desc(
"Promote the target candidate even when the definition "
87 " is not available"));
93 cl::desc(
"Promote the target candidate only if it is a "
94 "hot function. Otherwise, warm functions can "
101 cl::desc(
"Continue with the remaining targets instead of exiting "
102 "when failing in a candidate"));
108 cl::desc(
"Run indirect-call promotion in LTO "
115 cl::desc(
"Run indirect-call promotion in SamplePGO mode"));
121 cl::desc(
"Run indirect-call promotion for call instructions "
128 cl::desc(
"Run indirect-call promotion for "
129 "invoke instruction only"));
135 cl::desc(
"Dump IR after transformation happens"));
141 cl::desc(
"The percentage threshold of vtable-count / function-count for "
142 "cost-benefit analysis."));
153 cl::desc(
"The maximum number of vtable for the last candidate."));
158 "A list of mangled vtable type info names. Classes specified by the "
159 "type info names and their derived ones will not be vtable-ICP'ed. "
160 "Useful when the profiled types and actual types in the optimized "
161 "binary could be different due to profiling limitations. Type info "
162 "names are those string literals used in LLVM type metadata"));
169using VTableAddressPointOffsetValMap =
173struct VirtualCallSiteInfo {
183using VirtualCallSiteTypeInfoMap =
194static std::optional<uint64_t>
198 VTableVar.
getMetadata(LLVMContext::MD_type, Types);
202 TypeId && TypeId->getString() == CompatibleType)
216 assert(AddressPointOffset < VTable->getGlobalSize(M.getDataLayout()) &&
217 "Out-of-bound access");
227 return PN->getIncomingBlock(U);
242 "Guaranteed by ICP transformation");
253 UserBB = getUserBasicBlock(
Use, UserInst);
256 if (UserBB != DestBB)
259 return UserBB !=
nullptr;
267 if (!isDestBBSuitableForSink(
I, DestBlock))
278 if (
C->isInlineAsm() ||
C->cannotMerge() ||
C->isConvergent())
282 if (
I->mayWriteToMemory())
287 if (
I->mayReadFromMemory()) {
290 E =
I->getParent()->end();
295 if (Scan->mayWriteToMemory())
301 I->moveBefore(*DestBlock, InsertPos);
312static int tryToSinkInstructions(
BasicBlock *OriginalBB,
321 if (tryToSinkInstruction(&
I, IndirectCallBB))
329class IndirectCallPromoter {
336 InstrProfSymtab *
const Symtab;
338 const bool SamplePGO;
341 const VirtualCallSiteTypeInfoMap &VirtualCSInfo;
343 VTableAddressPointOffsetValMap &VTableAddressPointOffsetVal;
345 OptimizationRemarkEmitter &ORE;
347 const DenseSet<StringRef> &IgnoredBaseTypes;
350 struct PromotionCandidate {
352 const uint64_t Count;
353 const uint32_t Index;
362 VTableGUIDCountsMap VTableGUIDAndCounts;
365 PromotionCandidate(Function *
F, uint64_t
C, uint32_t
I)
366 : TargetFunction(
F), Count(
C), Index(
I) {}
374 std::vector<PromotionCandidate> getPromotionCandidatesForCallSite(
376 uint64_t TotalCount, uint32_t NumCandidates);
381 bool tryToPromoteWithFuncCmp(
384 uint32_t NumCandidates, VTableGUIDCountsMap &VTableGUIDCounts);
389 bool tryToPromoteWithVTableCmp(
391 uint64_t TotalFuncCount, uint32_t NumCandidates,
393 VTableGUIDCountsMap &VTableGUIDCounts);
396 bool isProfitableToCompareVTables(
const CallBase &CB,
401 bool shouldSkipVTable(uint64_t VTableGUID);
410 Instruction *computeVTableInfos(
const CallBase *CB,
411 VTableGUIDCountsMap &VTableGUIDCounts,
412 std::vector<PromotionCandidate> &Candidates);
414 Constant *getOrCreateVTableAddressPointVar(GlobalVariable *GV,
415 uint64_t AddressPointOffset);
417 void updateFuncValueProfiles(CallBase &CB,
419 uint64_t Sum, uint32_t MaxMDCount);
421 void updateVPtrValueProfiles(Instruction *VPtr,
422 VTableGUIDCountsMap &VTableGUIDCounts);
424 bool isValidTarget(uint64_t, Function *,
const CallBase &, uint64_t);
427 IndirectCallPromoter(
428 Function &Func,
Module &M, InstrProfSymtab *Symtab,
bool SamplePGO,
429 const VirtualCallSiteTypeInfoMap &VirtualCSInfo,
430 VTableAddressPointOffsetValMap &VTableAddressPointOffsetVal,
431 const DenseSet<StringRef> &IgnoredBaseTypes,
432 OptimizationRemarkEmitter &ORE)
433 : F(
Func), M(M), Symtab(Symtab), SamplePGO(SamplePGO),
434 VirtualCSInfo(VirtualCSInfo),
435 VTableAddressPointOffsetVal(VTableAddressPointOffsetVal), ORE(ORE),
436 IgnoredBaseTypes(IgnoredBaseTypes) {}
437 IndirectCallPromoter(
const IndirectCallPromoter &) =
delete;
438 IndirectCallPromoter &operator=(
const IndirectCallPromoter &) =
delete;
456 if (TargetFunction ==
nullptr) {
459 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnableToFindTarget", &CB)
460 <<
"Cannot promote indirect call: target with md5sum "
461 <<
NV(
"target md5sum", Target)
462 <<
" not found (count=" <<
NV(
"Count",
Count) <<
")";
467 LLVM_DEBUG(
dbgs() <<
" Not promote: target definition is not available\n");
469 return OptimizationRemarkMissed(
DEBUG_TYPE,
"NoTargetDef", &CB)
470 <<
"Do not promote indirect call: target with md5sum "
471 <<
NV(
"target md5sum", Target)
472 <<
" definition not available (count=" <<
ore::NV(
"Count",
Count)
478 const char *Reason =
nullptr;
482 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnableToPromote", &CB)
483 <<
"Cannot promote indirect call to "
484 <<
NV(
"TargetFunction", TargetFunction)
485 <<
" (count=" <<
NV(
"Count",
Count) <<
"): " << Reason;
494std::vector<IndirectCallPromoter::PromotionCandidate>
495IndirectCallPromoter::getPromotionCandidatesForCallSite(
497 uint64_t TotalCount, uint32_t NumCandidates) {
498 std::vector<PromotionCandidate> Ret;
500 LLVM_DEBUG(
dbgs() <<
" \nWork on callsite #" << NumOfPGOICallsites << CB
501 <<
" Num_targets: " << ValueDataRef.
size()
502 <<
" Num_candidates: " << NumCandidates <<
"\n");
503 NumOfPGOICallsites++;
509 for (uint32_t
I = 0;
I < NumCandidates;
I++) {
510 uint64_t
Count = ValueDataRef[
I].Count;
513 uint64_t
Target = ValueDataRef[
I].Value;
515 <<
" Target_func: " << Target <<
"\n");
520 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UserOptions", &CB)
521 <<
" Not promote: User options";
528 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UserOptions", &CB)
529 <<
" Not promote: User options";
536 return OptimizationRemarkMissed(
DEBUG_TYPE,
"CutOffReached", &CB)
537 <<
" Not promote: Cutoff reached";
543 if (!isValidTarget(Target, TargetFunction, CB,
Count)) {
550 Ret.push_back(PromotionCandidate(TargetFunction,
Count,
I));
556Constant *IndirectCallPromoter::getOrCreateVTableAddressPointVar(
557 GlobalVariable *GV, uint64_t AddressPointOffset) {
559 VTableAddressPointOffsetVal[GV].try_emplace(AddressPointOffset,
nullptr);
561 Iter->second = getVTableAddressPointOffset(GV, AddressPointOffset);
565Instruction *IndirectCallPromoter::computeVTableInfos(
566 const CallBase *CB, VTableGUIDCountsMap &GUIDCountsMap,
567 std::vector<PromotionCandidate> &Candidates) {
595 auto Iter = VirtualCSInfo.find(CB);
596 if (Iter == VirtualCSInfo.end())
600 << NumOfPGOICallsites <<
"\n");
602 const auto &VirtualCallInfo = Iter->second;
605 SmallDenseMap<Function *, int, 4> CalleeIndexMap;
606 for (
size_t I = 0;
I < Candidates.size();
I++)
607 CalleeIndexMap[Candidates[
I].TargetFunction] =
I;
609 uint64_t TotalVTableCount = 0;
610 auto VTableValueDataArray =
613 if (VTableValueDataArray.empty())
617 for (
const auto &V : VTableValueDataArray) {
618 uint64_t VTableVal =
V.Value;
619 GUIDCountsMap[VTableVal] =
V.Count;
622 LLVM_DEBUG(
dbgs() <<
" Cannot find vtable definition for " << VTableVal
623 <<
"; maybe the vtable isn't imported\n");
627 std::optional<uint64_t> MaybeAddressPointOffset =
628 getAddressPointOffset(*VTableVar, VirtualCallInfo.CompatibleTypeStr);
629 if (!MaybeAddressPointOffset)
632 const uint64_t AddressPointOffset = *MaybeAddressPointOffset;
636 VTableVar, AddressPointOffset + VirtualCallInfo.FunctionOffset, M);
639 auto CalleeIndexIter = CalleeIndexMap.
find(Callee);
640 if (CalleeIndexIter == CalleeIndexMap.
end())
643 auto &Candidate = Candidates[CalleeIndexIter->second];
647 Candidate.VTableGUIDAndCounts[VTableVal] =
V.Count;
648 Candidate.AddressPoints.push_back(
649 getOrCreateVTableAddressPointVar(VTableVar, AddressPointOffset));
667 bool AttachProfToDirectCall,
673 if (AttachProfToDirectCall)
682 <<
"Promote indirect call to " << NV(
"DirectCallee", DirectCallee)
683 <<
" with count " << NV(
"Count",
Count) <<
" out of "
684 << NV(
"TotalCount", TotalCount);
690bool IndirectCallPromoter::tryToPromoteWithFuncCmp(
693 uint32_t NumCandidates, VTableGUIDCountsMap &VTableGUIDCounts) {
696 for (
const auto &
C : Candidates) {
700 assert(TotalCount >= FuncCount);
701 TotalCount -= FuncCount;
702 NumOfPGOICallPromotion++;
706 ICallProfDataRef[
C.Index].Count = 0;
715 for (
const auto &[GUID, VTableCount] :
C.VTableGUIDAndCounts)
716 SumVTableCount += VTableCount;
718 for (
const auto &[GUID, VTableCount] :
C.VTableGUIDAndCounts) {
719 APInt APFuncCount((
unsigned)128, FuncCount,
false );
720 APFuncCount *= VTableCount;
721 VTableGUIDCounts[GUID] -= APFuncCount.udiv(SumVTableCount).getZExtValue();
724 if (NumPromoted == 0)
727 assert(NumPromoted <= ICallProfDataRef.
size() &&
728 "Number of promoted functions should not be greater than the number "
729 "of values in profile metadata");
731 updateFuncValueProfiles(CB, ICallProfDataRef, TotalCount, NumCandidates);
732 updateVPtrValueProfiles(VPtr, VTableGUIDCounts);
736void IndirectCallPromoter::updateFuncValueProfiles(
738 uint64_t TotalCount, uint32_t MaxMDCount) {
744 const InstrProfValueData &
RHS) {
745 return LHS.Count >
RHS.Count;
751 [](uint64_t
Count,
const InstrProfValueData &ProfData) {
752 return ProfData.Count <= Count;
761void IndirectCallPromoter::updateVPtrValueProfiles(
762 Instruction *VPtr, VTableGUIDCountsMap &VTableGUIDCounts) {
767 std::vector<InstrProfValueData> VTableValueProfiles;
768 uint64_t TotalVTableCount = 0;
769 for (
auto [GUID,
Count] : VTableGUIDCounts) {
773 VTableValueProfiles.push_back({
GUID,
Count});
774 TotalVTableCount +=
Count;
777 [](
const InstrProfValueData &
LHS,
const InstrProfValueData &
RHS) {
778 return LHS.Count >
RHS.Count;
782 IPVK_VTableTarget, VTableValueProfiles.size());
785bool IndirectCallPromoter::tryToPromoteWithVTableCmp(
787 uint64_t TotalFuncCount, uint32_t NumCandidates,
789 VTableGUIDCountsMap &VTableGUIDCounts) {
792 for (
const auto &Candidate : Candidates) {
793 for (
auto &[GUID,
Count] : Candidate.VTableGUIDAndCounts)
801 CB, VPtr, Candidate.TargetFunction, Candidate.AddressPoints,
803 TotalFuncCount - Candidate.Count));
805 int SinkCount = tryToSinkInstructions(OriginalBB, CB.
getParent());
810 const auto &VTableGUIDAndCounts = Candidate.VTableGUIDAndCounts;
811 Remark <<
"Promote indirect call to "
812 <<
ore::NV(
"DirectCallee", Candidate.TargetFunction)
813 <<
" with count " <<
ore::NV(
"Count", Candidate.Count)
814 <<
" out of " <<
ore::NV(
"TotalCount", TotalFuncCount) <<
", sink "
815 <<
ore::NV(
"SinkCount", SinkCount)
816 <<
" instruction(s) and compare "
817 <<
ore::NV(
"VTable", VTableGUIDAndCounts.size())
821 std::set<uint64_t> GUIDSet;
822 for (
auto [GUID,
Count] : VTableGUIDAndCounts)
823 GUIDSet.insert(GUID);
824 for (
auto Iter = GUIDSet.begin(); Iter != GUIDSet.end(); Iter++) {
825 if (Iter != GUIDSet.begin())
835 PromotedFuncCount.
push_back({Candidate.Index, Candidate.Count});
837 assert(TotalFuncCount >= Candidate.Count &&
838 "Within one prof metadata, total count is the sum of counts from "
839 "individual <target, count> pairs");
843 TotalFuncCount -= std::min(TotalFuncCount, Candidate.Count);
844 NumOfPGOICallPromotion++;
847 if (PromotedFuncCount.
empty())
856 for (
size_t I = 0;
I < PromotedFuncCount.
size();
I++) {
857 uint32_t
Index = PromotedFuncCount[
I].first;
858 ICallProfDataRef[
Index].Count -=
859 std::max(PromotedFuncCount[
I].second, ICallProfDataRef[Index].
Count);
861 updateFuncValueProfiles(CB, ICallProfDataRef, TotalFuncCount, NumCandidates);
862 updateVPtrValueProfiles(VPtr, VTableGUIDCounts);
868bool IndirectCallPromoter::processFunction(ProfileSummaryInfo *PSI) {
870 ICallPromotionAnalysis ICallAnalysis;
872 uint32_t NumCandidates;
875 CB, TotalCount, NumCandidates);
881 LLVM_DEBUG(
dbgs() <<
"Don't promote the cold candidate: TotalCount="
882 << TotalCount <<
"\n");
887 LLVM_DEBUG(
dbgs() <<
"Don't promote the non-hot candidate: TotalCount="
888 << TotalCount <<
"\n");
893 auto PromotionCandidates = getPromotionCandidatesForCallSite(
894 *CB, ICallProfDataRef, TotalCount, NumCandidates);
896 VTableGUIDCountsMap VTableGUIDCounts;
898 computeVTableInfos(CB, VTableGUIDCounts, PromotionCandidates);
900 if (isProfitableToCompareVTables(*CB, PromotionCandidates))
901 Changed |= tryToPromoteWithVTableCmp(*CB, VPtr, PromotionCandidates,
902 TotalCount, NumCandidates,
903 ICallProfDataRef, VTableGUIDCounts);
905 Changed |= tryToPromoteWithFuncCmp(*CB, VPtr, PromotionCandidates,
906 TotalCount, ICallProfDataRef,
907 NumCandidates, VTableGUIDCounts);
914bool IndirectCallPromoter::isProfitableToCompareVTables(
918 LLVM_DEBUG(
dbgs() <<
"\nEvaluating vtable profitability for callsite #"
919 << NumOfPGOICallsites << CB <<
"\n");
920 const size_t CandidateSize = Candidates.
size();
921 for (
size_t I = 0;
I < CandidateSize;
I++) {
922 auto &Candidate = Candidates[
I];
923 auto &VTableGUIDAndCounts = Candidate.VTableGUIDAndCounts;
926 dbgs() <<
" Candidate " <<
I <<
" FunctionCount: " << Candidate.Count
927 <<
", VTableCounts:";
928 for (
const auto &[GUID,
Count] : VTableGUIDAndCounts)
934 uint64_t CandidateVTableCount = 0;
936 for (
auto &[GUID,
Count] : VTableGUIDAndCounts) {
937 CandidateVTableCount +=
Count;
939 if (shouldSkipVTable(GUID))
945 dbgs() <<
" function count " << Candidate.Count
946 <<
" and its vtable sum count " << CandidateVTableCount
947 <<
" have discrepancies. Bail out vtable comparison.\n");
957 int MaxNumVTable = 1;
958 if (
I == CandidateSize - 1)
961 if ((
int)Candidate.AddressPoints.size() > MaxNumVTable) {
962 LLVM_DEBUG(
dbgs() <<
" allow at most " << MaxNumVTable <<
" and got "
963 << Candidate.AddressPoints.size()
964 <<
" vtables. Bail out for vtable comparison.\n");
972bool IndirectCallPromoter::shouldSkipVTable(uint64_t VTableGUID) {
973 if (IgnoredBaseTypes.empty())
978 assert(VTableVar &&
"VTableVar must exist for GUID in VTableGUIDAndCounts");
981 VTableVar->
getMetadata(LLVMContext::MD_type, Types);
983 for (
auto *
Type : Types)
985 if (IgnoredBaseTypes.contains(TypeId->getString())) {
987 "out of vtable comparison.");
1001 VirtualCallSiteTypeInfoMap &VirtualCSInfo) {
1012 if (!TypeTestFunc || TypeTestFunc->
use_empty())
1028 if (!CompatibleTypeId)
1035 auto &DT = LookupDomTree(*CI->getFunction());
1038 for (
auto &DevirtCall : DevirtCalls) {
1046 VirtualCSInfo[&CB] = {DevirtCall.Offset, VTablePtr,
1047 CompatibleTypeId->getString()};
1059 std::string SymtabFailure =
toString(std::move(
E));
1060 M.getContext().emitError(
"Failed to create symtab: " + SymtabFailure);
1064 VirtualCallSiteTypeInfoMap VirtualCSInfo;
1081 VTableAddressPointOffsetValMap VTableAddressPointOffsetVal;
1084 if (
F.isDeclaration() ||
F.hasOptNone())
1091 IndirectCallPromoter CallPromoter(
F, M, &Symtab, SamplePGO, VirtualCSInfo,
1092 VTableAddressPointOffsetVal,
1093 IgnoredBaseTypes, ORE);
1094 bool FuncChanged = CallPromoter.processFunction(PSI);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines the DenseMap class.
This header defines various interfaces for pass management in LLVM.
Machine Check Debug Module
static bool processFunction(Function &F, NVPTXTargetMachine &TM)
This file provides the interface for IR based instrumentation passes ( (profile-gen,...
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
This file contains the declarations for profiling metadata utility functions.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Class for arbitrary precision integers.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
bool empty() const
empty - Check if the array is empty.
LLVM Basic Block Representation.
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
LLVM_ABI const BasicBlock * getUniquePredecessor() const
Return the predecessor of this block if it has a unique predecessor block.
InstListType::iterator iterator
Instruction iterators...
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
static Constant * getInBoundsGetElementPtr(Type *Ty, Constant *C, ArrayRef< Constant * > IdxList)
Create an "inbounds" getelementptr.
This is an important base class in LLVM.
iterator find(const_arg_type_t< KeyT > Val)
Implements a dense probed hash-table based set.
Analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Lightweight error class with error context and mandatory checking.
MDNode * getMetadata(unsigned KindID) const
Get the current metadata attachments for the given kind, if any.
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
A symbol table used for function [IR]PGO name look-up with keys (such as pointers,...
GlobalVariable * getGlobalVariable(uint64_t MD5Hash) const
Return the global variable corresponding to md5 hash.
LLVM_ABI Error create(object::SectionRef &Section)
Create InstrProfSymtab from an object file section which contains function PGO names.
Function * getFunction(uint64_t FuncMD5Hash) const
Return function from the name's md5 hash. Return nullptr if not found.
LLVM_ABI bool isDebugOrPseudoInst() const LLVM_READONLY
Return true if the instruction is a DbgInfoIntrinsic or PseudoProbeInst.
LLVM_ABI unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
This is an important class for using LLVM in a threaded context.
LLVM_ABI MDNode * createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight, bool IsExpected=false)
Return metadata containing two branch weights.
A Module instance is used to store all the information related to an LLVM module.
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
An analysis pass based on the new PM to deliver ProfileSummaryInfo.
Analysis providing profile information.
bool hasProfileSummary() const
Returns true if profile summary is available.
LLVM_ABI bool isColdCount(uint64_t C) const
Returns true if count C is considered cold.
LLVM_ABI bool isHotCount(uint64_t C) const
Returns true if count C is considered hot.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Target - Wrapper for Target specific information.
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
A Use represents the edge between a Value definition and its users.
User * getUser() const
Returns the User that contains this Use.
LLVMContext & getContext() const
All values hold a context through their type.
iterator_range< use_iterator > uses()
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
void insert_range(Range &&R)
const ParentTy * getParent() const
@ C
The default llvm calling convention, compatible with C.
@ BasicBlock
Various leaf nodes.
LLVM_ABI Function * getDeclarationIfExists(const Module *M, ID id)
Look up the Function declaration of the intrinsic id in the Module M and return it if it exists.
initializer< Ty > init(const Ty &Val)
Add a small namespace to avoid name clashes with the classes used in the streaming interface.
DiagnosticInfoOptimizationBase::Argument NV
LLVM_ABI CallBase & promoteIndirectCall(CallBase &CB, Function *F, uint64_t Count, uint64_t TotalCount, bool AttachProfToDirectCall, OptimizationRemarkEmitter *ORE)
NodeAddr< FuncNode * > Func
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
void stable_sort(R &&Range)
LLVM_ABI bool isLegalToPromote(const CallBase &CB, Function *Callee, const char **FailureReason=nullptr)
Return true if the given indirect call site can be made to call Callee.
std::vector< CallBase * > findIndirectCalls(Function &F)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI CallBase & promoteCallWithIfThenElse(CallBase &CB, Function *Callee, MDNode *BranchWeights=nullptr)
Promote the given indirect call site to conditionally call Callee.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
cl::opt< unsigned > MaxNumVTableAnnotations("icp-max-num-vtables", cl::init(6), cl::Hidden, cl::desc("Max number of vtables annotated for a vtable load instruction."))
auto upper_bound(R &&Range, T &&Value)
Provide wrappers to std::upper_bound which take ranges instead of having to pass begin/end explicitly...
cl::opt< bool > EnableVTableProfileUse("enable-vtable-profile-use", cl::init(false), cl::desc("If ThinLTO and WPD is enabled and this option is true, vtable " "profiles will be used by ICP pass for more efficient indirect " "call sequence. If false, type profiles won't be used."))
LLVM_ABI 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...
auto reverse(ContainerTy &&C)
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionAddr VTableAddr Count
LLVM_ABI SmallVector< InstrProfValueData, 4 > getValueProfDataFromInst(const Instruction &Inst, InstrProfValueKind ValueKind, uint32_t MaxNumValueData, uint64_t &TotalC, bool GetNoICPValue=false)
Extract the value profile data from Inst and returns them if Inst is annotated with value profile dat...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
MutableArrayRef(T &OneElt) -> MutableArrayRef< T >
ArrayRef(const T &OneElt) -> ArrayRef< T >
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
uint32_t scaleBranchCount(uint64_t Count, uint64_t Scale)
Scale an individual branch count.
LLVM_ABI void setFittedBranchWeights(Instruction &I, ArrayRef< uint64_t > Weights, bool IsExpected, bool ElideAllZero=false)
Variant of setBranchWeights where the Weights will be fit first to uint32_t by shifting right.
uint64_t calculateCountScale(uint64_t MaxCount)
Calculate what to divide by to scale counts.
LLVM_ABI CallBase & promoteCallWithVTableCmp(CallBase &CB, Instruction *VPtr, Function *Callee, ArrayRef< Constant * > AddressPoints, MDNode *BranchWeights)
This is similar to promoteCallWithIfThenElse except that the condition to promote a virtual call is t...
void findDevirtualizableCallsForTypeTest(SmallVectorImpl< DevirtCallSite > &DevirtCalls, SmallVectorImpl< CallInst * > &Assumes, const CallInst *CI, DominatorTree &DT)
Given a call to the intrinsic @llvm.type.test, find all devirtualizable call sites based on the call ...
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
std::pair< Function *, Constant * > getFunctionAtVTableOffset(GlobalVariable *GV, uint64_t Offset, Module &M)
Given a vtable and a specified offset, returns the function and the trivial pointer at the specified ...
static Instruction * tryGetVTableInstruction(CallBase *CB)