54#define DEBUG_TYPE "pgo-icall-prom"
56STATISTIC(NumOfPGOICallPromotion,
"Number of indirect call promotions.");
57STATISTIC(NumOfPGOICallsites,
"Number of indirect call candidate sites.");
68using VTableAddressPointOffsetValMap =
72struct VirtualCallSiteInfo {
82using VirtualCallSiteTypeInfoMap =
93static std::optional<uint64_t>
101 TypeId && TypeId->getString() == CompatibleType)
115 assert(AddressPointOffset < VTable->getGlobalSize(M.getDataLayout()) &&
116 "Out-of-bound access");
126 return PN->getIncomingBlock(U);
141 "Guaranteed by ICP transformation");
149 UserBB = getUserBasicBlock(
Use, UserInst);
152 if (UserBB != DestBB)
155 return UserBB !=
nullptr;
163 if (!isDestBBSuitableForSink(
I, DestBlock))
174 if (
C->isInlineAsm() ||
C->cannotMerge() ||
C->isConvergent())
178 if (
I->mayWriteToMemory())
183 if (
I->mayReadFromMemory()) {
186 E =
I->getParent()->end();
191 if (Scan->mayWriteToMemory())
197 I->moveBefore(*DestBlock, InsertPos);
208static int tryToSinkInstructions(
BasicBlock *OriginalBB,
217 if (tryToSinkInstruction(&
I, IndirectCallBB))
225class IndirectCallPromoter {
227 const InstrumentationOptions &Opts;
233 InstrProfSymtab *
const Symtab;
235 const bool SamplePGO;
238 const VirtualCallSiteTypeInfoMap &VirtualCSInfo;
240 VTableAddressPointOffsetValMap &VTableAddressPointOffsetVal;
242 OptimizationRemarkEmitter &ORE;
244 const DenseSet<StringRef> &IgnoredBaseTypes;
247 struct PromotionCandidate {
250 const uint32_t Index;
259 VTableGUIDCountsMap VTableGUIDAndCounts;
263 : TargetFunction(
F), Count(
C), Index(
I) {}
271 std::vector<PromotionCandidate> getPromotionCandidatesForCallSite(
273 uint64_t TotalCount, uint32_t NumCandidates);
278 bool tryToPromoteWithFuncCmp(
281 uint32_t NumCandidates, VTableGUIDCountsMap &VTableGUIDCounts);
286 bool tryToPromoteWithVTableCmp(
288 uint64_t TotalFuncCount, uint32_t NumCandidates,
290 VTableGUIDCountsMap &VTableGUIDCounts);
293 bool isProfitableToCompareVTables(
const CallBase &CB,
298 bool shouldSkipVTable(
uint64_t VTableGUID);
307 Instruction *computeVTableInfos(
const CallBase *CB,
308 VTableGUIDCountsMap &VTableGUIDCounts,
309 std::vector<PromotionCandidate> &Candidates);
311 Constant *getOrCreateVTableAddressPointVar(GlobalVariable *GV,
314 void updateFuncValueProfiles(CallBase &CB,
318 void updateVPtrValueProfiles(Instruction *VPtr,
319 VTableGUIDCountsMap &VTableGUIDCounts);
324 IndirectCallPromoter(
326 InstrProfSymtab *Symtab,
bool SamplePGO,
327 const VirtualCallSiteTypeInfoMap &VirtualCSInfo,
328 VTableAddressPointOffsetValMap &VTableAddressPointOffsetVal,
329 const DenseSet<StringRef> &IgnoredBaseTypes,
330 OptimizationRemarkEmitter &ORE)
331 : Opts(Opts), F(
Func), M(M), Symtab(Symtab), SamplePGO(SamplePGO),
332 VirtualCSInfo(VirtualCSInfo),
333 VTableAddressPointOffsetVal(VTableAddressPointOffsetVal), ORE(ORE),
334 IgnoredBaseTypes(IgnoredBaseTypes) {}
335 IndirectCallPromoter(
const IndirectCallPromoter &) =
delete;
336 IndirectCallPromoter &operator=(
const IndirectCallPromoter &) =
delete;
354 if (TargetFunction ==
nullptr) {
357 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnableToFindTarget", &CB)
358 <<
"Cannot promote indirect call: target with md5sum "
359 <<
NV(
"target md5sum", Target)
360 <<
" not found (count=" <<
NV(
"Count",
Count) <<
")";
364 if (!Opts.icp_allow_decls && TargetFunction->
isDeclaration()) {
365 LLVM_DEBUG(
dbgs() <<
" Not promote: target definition is not available\n");
367 return OptimizationRemarkMissed(
DEBUG_TYPE,
"NoTargetDef", &CB)
368 <<
"Do not promote indirect call: target with md5sum "
369 <<
NV(
"target md5sum", Target)
370 <<
" definition not available (count=" <<
ore::NV(
"Count",
Count)
376 const char *Reason =
nullptr;
380 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnableToPromote", &CB)
381 <<
"Cannot promote indirect call to "
382 <<
NV(
"TargetFunction", TargetFunction)
383 <<
" (count=" <<
NV(
"Count",
Count) <<
"): " << Reason;
392std::vector<IndirectCallPromoter::PromotionCandidate>
393IndirectCallPromoter::getPromotionCandidatesForCallSite(
395 uint64_t TotalCount, uint32_t NumCandidates) {
396 std::vector<PromotionCandidate> Ret;
398 LLVM_DEBUG(
dbgs() <<
" \nWork on callsite #" << NumOfPGOICallsites << CB
399 <<
" Num_targets: " << ValueDataRef.
size()
400 <<
" Num_candidates: " << NumCandidates <<
"\n");
401 NumOfPGOICallsites++;
402 if (Opts.icp_csskip != 0 && NumOfPGOICallsites <= Opts.icp_csskip) {
407 for (uint32_t
I = 0;
I < NumCandidates;
I++) {
413 <<
" Target_func: " << Target <<
"\n");
418 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UserOptions", &CB)
419 <<
" Not promote: User options";
426 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UserOptions", &CB)
427 <<
" Not promote: User options";
431 if (Opts.icp_cutoff != 0 && NumOfPGOICallPromotion >= Opts.icp_cutoff) {
434 return OptimizationRemarkMissed(
DEBUG_TYPE,
"CutOffReached", &CB)
435 <<
" Not promote: Cutoff reached";
441 if (!isValidTarget(Target, TargetFunction, CB,
Count)) {
442 if (Opts.icp_allow_candidate_skip)
448 Ret.push_back(PromotionCandidate(TargetFunction,
Count,
I));
454Constant *IndirectCallPromoter::getOrCreateVTableAddressPointVar(
455 GlobalVariable *GV,
uint64_t AddressPointOffset) {
457 VTableAddressPointOffsetVal[GV].try_emplace(AddressPointOffset,
nullptr);
459 Iter->second = getVTableAddressPointOffset(GV, AddressPointOffset);
463Instruction *IndirectCallPromoter::computeVTableInfos(
464 const CallBase *CB, VTableGUIDCountsMap &GUIDCountsMap,
465 std::vector<PromotionCandidate> &Candidates) {
493 auto Iter = VirtualCSInfo.find(CB);
494 if (Iter == VirtualCSInfo.end())
498 << NumOfPGOICallsites <<
"\n");
500 const auto &VirtualCallInfo = Iter->second;
503 SmallDenseMap<Function *, int, 4> CalleeIndexMap;
504 for (
size_t I = 0;
I < Candidates.size();
I++)
505 CalleeIndexMap[Candidates[
I].TargetFunction] =
I;
509 *VirtualCallInfo.VPtr, IPVK_VTableTarget,
511 if (VTableValueDataArray.empty())
515 for (
const auto &V : VTableValueDataArray) {
517 GUIDCountsMap[VTableVal] =
V.Count;
520 LLVM_DEBUG(
dbgs() <<
" Cannot find vtable definition for " << VTableVal
521 <<
"; maybe the vtable isn't imported\n");
525 std::optional<uint64_t> MaybeAddressPointOffset =
526 getAddressPointOffset(*VTableVar, VirtualCallInfo.CompatibleTypeStr);
527 if (!MaybeAddressPointOffset)
530 const uint64_t AddressPointOffset = *MaybeAddressPointOffset;
534 VTableVar, AddressPointOffset + VirtualCallInfo.FunctionOffset, M);
537 auto CalleeIndexIter = CalleeIndexMap.
find(Callee);
538 if (CalleeIndexIter == CalleeIndexMap.
end())
541 auto &Candidate = Candidates[CalleeIndexIter->second];
545 Candidate.VTableGUIDAndCounts[VTableVal] =
V.Count;
546 Candidate.AddressPoints.push_back(
547 getOrCreateVTableAddressPointVar(VTableVar, AddressPointOffset));
564 uint64_t
Count, uint64_t TotalCount,
565 bool AttachProfToDirectCall,
571 if (AttachProfToDirectCall)
580 <<
"Promote indirect call to " << NV(
"DirectCallee", DirectCallee)
581 <<
" with count " << NV(
"Count",
Count) <<
" out of "
582 << NV(
"TotalCount", TotalCount);
588bool IndirectCallPromoter::tryToPromoteWithFuncCmp(
591 uint32_t NumCandidates, VTableGUIDCountsMap &VTableGUIDCounts) {
594 for (
const auto &
C : Candidates) {
595 uint64_t FuncCount =
C.Count;
598 assert(TotalCount >= FuncCount);
599 TotalCount -= FuncCount;
600 NumOfPGOICallPromotion++;
604 ICallProfDataRef[
C.Index].Count = 0;
612 uint64_t SumVTableCount = 0;
613 for (
const auto &[GUID, VTableCount] :
C.VTableGUIDAndCounts)
614 SumVTableCount += VTableCount;
616 for (
const auto &[GUID, VTableCount] :
C.VTableGUIDAndCounts) {
617 APInt APFuncCount((
unsigned)128, FuncCount,
false );
618 APFuncCount *= VTableCount;
619 VTableGUIDCounts[GUID] -= APFuncCount.udiv(SumVTableCount).getZExtValue();
622 if (NumPromoted == 0)
625 assert(NumPromoted <= ICallProfDataRef.
size() &&
626 "Number of promoted functions should not be greater than the number "
627 "of values in profile metadata");
629 updateFuncValueProfiles(CB, ICallProfDataRef, TotalCount, NumCandidates);
630 updateVPtrValueProfiles(VPtr, VTableGUIDCounts);
634void IndirectCallPromoter::updateFuncValueProfiles(
636 uint64_t TotalCount, uint32_t MaxMDCount) {
642 const InstrProfValueData &
RHS) {
643 return LHS.Count >
RHS.Count;
650 return ProfData.Count <= Count;
659void IndirectCallPromoter::updateVPtrValueProfiles(
660 Instruction *VPtr, VTableGUIDCountsMap &VTableGUIDCounts) {
665 std::vector<InstrProfValueData> VTableValueProfiles;
667 for (
auto [GUID,
Count] : VTableGUIDCounts) {
671 VTableValueProfiles.push_back({
GUID,
Count});
672 TotalVTableCount +=
Count;
675 [](
const InstrProfValueData &
LHS,
const InstrProfValueData &
RHS) {
676 return LHS.Count >
RHS.Count;
680 IPVK_VTableTarget, VTableValueProfiles.size());
683bool IndirectCallPromoter::tryToPromoteWithVTableCmp(
685 uint64_t TotalFuncCount, uint32_t NumCandidates,
687 VTableGUIDCountsMap &VTableGUIDCounts) {
690 for (
const auto &Candidate : Candidates) {
691 for (
auto &[GUID,
Count] : Candidate.VTableGUIDAndCounts)
699 CB, VPtr, Candidate.TargetFunction, Candidate.AddressPoints,
701 TotalFuncCount - Candidate.Count));
703 int SinkCount = tryToSinkInstructions(OriginalBB, CB.
getParent());
708 const auto &VTableGUIDAndCounts = Candidate.VTableGUIDAndCounts;
709 Remark <<
"Promote indirect call to "
710 <<
ore::NV(
"DirectCallee", Candidate.TargetFunction)
711 <<
" with count " <<
ore::NV(
"Count", Candidate.Count)
712 <<
" out of " <<
ore::NV(
"TotalCount", TotalFuncCount) <<
", sink "
713 <<
ore::NV(
"SinkCount", SinkCount)
714 <<
" instruction(s) and compare "
715 <<
ore::NV(
"VTable", VTableGUIDAndCounts.size())
719 std::set<uint64_t> GUIDSet;
720 for (
auto [GUID,
Count] : VTableGUIDAndCounts)
721 GUIDSet.insert(GUID);
722 for (
auto Iter = GUIDSet.begin(); Iter != GUIDSet.end(); Iter++) {
723 if (Iter != GUIDSet.begin())
733 PromotedFuncCount.
push_back({Candidate.Index, Candidate.Count});
735 assert(TotalFuncCount >= Candidate.Count &&
736 "Within one prof metadata, total count is the sum of counts from "
737 "individual <target, count> pairs");
741 TotalFuncCount -= std::min(TotalFuncCount, Candidate.Count);
742 NumOfPGOICallPromotion++;
745 if (PromotedFuncCount.
empty())
754 for (
size_t I = 0;
I < PromotedFuncCount.
size();
I++) {
755 uint32_t
Index = PromotedFuncCount[
I].first;
756 ICallProfDataRef[
Index].Count -=
757 std::max(PromotedFuncCount[
I].second, ICallProfDataRef[Index].
Count);
759 updateFuncValueProfiles(CB, ICallProfDataRef, TotalFuncCount, NumCandidates);
760 updateVPtrValueProfiles(VPtr, VTableGUIDCounts);
766bool IndirectCallPromoter::processFunction(ProfileSummaryInfo *PSI) {
768 ICallPromotionAnalysis ICallAnalysis;
770 uint32_t NumCandidates;
773 CB, TotalCount, NumCandidates);
779 LLVM_DEBUG(
dbgs() <<
"Don't promote the cold candidate: TotalCount="
780 << TotalCount <<
"\n");
786 if (Opts.icp_allow_hot_only &&
789 : Opts.hot_func_cutoff_for_icp,
791 LLVM_DEBUG(
dbgs() <<
"Don't promote the non-hot candidate: TotalCount="
792 << TotalCount <<
"\n");
797 auto PromotionCandidates = getPromotionCandidatesForCallSite(
798 *CB, ICallProfDataRef, TotalCount, NumCandidates);
800 VTableGUIDCountsMap VTableGUIDCounts;
802 computeVTableInfos(CB, VTableGUIDCounts, PromotionCandidates);
804 if (isProfitableToCompareVTables(*CB, PromotionCandidates))
805 Changed |= tryToPromoteWithVTableCmp(*CB, VPtr, PromotionCandidates,
806 TotalCount, NumCandidates,
807 ICallProfDataRef, VTableGUIDCounts);
809 Changed |= tryToPromoteWithFuncCmp(*CB, VPtr, PromotionCandidates,
810 TotalCount, ICallProfDataRef,
811 NumCandidates, VTableGUIDCounts);
818bool IndirectCallPromoter::isProfitableToCompareVTables(
822 LLVM_DEBUG(
dbgs() <<
"\nEvaluating vtable profitability for callsite #"
823 << NumOfPGOICallsites << CB <<
"\n");
824 const size_t CandidateSize = Candidates.
size();
825 for (
size_t I = 0;
I < CandidateSize;
I++) {
826 auto &Candidate = Candidates[
I];
827 auto &VTableGUIDAndCounts = Candidate.VTableGUIDAndCounts;
830 dbgs() <<
" Candidate " <<
I <<
" FunctionCount: " << Candidate.Count
831 <<
", VTableCounts:";
832 for (
const auto &[GUID,
Count] : VTableGUIDAndCounts)
840 for (
auto &[GUID,
Count] : VTableGUIDAndCounts) {
841 CandidateVTableCount +=
Count;
843 if (shouldSkipVTable(GUID))
847 if (CandidateVTableCount <
848 Candidate.Count * Opts.icp_vtable_percentage_threshold) {
850 dbgs() <<
" function count " << Candidate.Count
851 <<
" and its vtable sum count " << CandidateVTableCount
852 <<
" have discrepancies. Bail out vtable comparison.\n");
862 int MaxNumVTable = 1;
863 if (
I == CandidateSize - 1)
864 MaxNumVTable = Opts.icp_max_num_vtable_last_candidate;
866 if ((
int)Candidate.AddressPoints.size() > MaxNumVTable) {
867 LLVM_DEBUG(
dbgs() <<
" allow at most " << MaxNumVTable <<
" and got "
868 << Candidate.AddressPoints.size()
869 <<
" vtables. Bail out for vtable comparison.\n");
877bool IndirectCallPromoter::shouldSkipVTable(
uint64_t VTableGUID) {
878 if (IgnoredBaseTypes.empty())
883 assert(VTableVar &&
"VTableVar must exist for GUID in VTableGUIDAndCounts");
886 VTableVar->
getMetadata(LLVMContext::MD_type, Types);
888 for (
auto *
Type : Types)
890 if (IgnoredBaseTypes.contains(TypeId->getString())) {
892 "out of vtable comparison.");
906 VirtualCallSiteTypeInfoMap &VirtualCSInfo) {
917 if (!TypeTestFunc || TypeTestFunc->
use_empty())
933 if (!CompatibleTypeId)
940 auto &DT = LookupDomTree(*CI->getFunction());
943 for (
auto &DevirtCall : DevirtCalls) {
951 VirtualCSInfo[&CB] = {DevirtCall.Offset, VTablePtr,
952 CompatibleTypeId->getString()};
961 if (Opts.disable_icp)
965 std::string SymtabFailure =
toString(std::move(
E));
966 M.getContext().emitError(
"Failed to create symtab: " + SymtabFailure);
970 VirtualCallSiteTypeInfoMap VirtualCSInfo;
977 IgnoredBaseTypes.
insert_range(Opts.icp_ignored_base_types);
987 VTableAddressPointOffsetValMap VTableAddressPointOffsetVal;
990 if (
F.isDeclaration() ||
F.hasOptNone())
997 IndirectCallPromoter CallPromoter(
998 Opts,
F, M, &Symtab, SamplePGO, VirtualCSInfo,
999 VTableAddressPointOffsetVal, IgnoredBaseTypes, ORE);
1000 bool FuncChanged = CallPromoter.processFunction(PSI);
1001 if (Opts.icp_dumpafter && FuncChanged) {
1006 if (Opts.icp_cutoff != 0 && NumOfPGOICallPromotion >= Opts.icp_cutoff) {
1020 SamplePGO | Opts.icp_samplepgo,
MAM))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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.
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.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
bool empty() const
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; assumes that the block is well-formed.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
static LLVM_SUPPRESS_DEPRECATED_DECLARATIONS_POP Constant * getInBoundsPtrAdd(Constant *Ptr, Constant *Offset)
Create a getelementptr inbounds i8, ptr, offset constant expression.
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 metadata of given kind attached to this GlobalObject.
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 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.
Represent a mutable reference to an array (0 or more elements consecutively in memory),...
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 isHotCountNthPercentile(int PercentileCutoff, uint64_t C) const
Returns true if count C is considered hot with regard to a given hot percentile cutoff value.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
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)
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
@ 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.
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.
const InstrumentationOptions & getInstrumentationOptions(const LLVMContext &C)
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.
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.
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 >
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
LLVM_ABI cl::opt< int > ProfileSummaryCutoffHot
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 unsigned getMaxNumVTableAnnotations(const LLVMContext &C)
Return -icp-max-num-vtables.
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...
LLVM_ABI 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.
LLVM_ABI 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)