54#define DEBUG_TYPE "pgo-icall-prom"
56STATISTIC(NumOfPGOICallPromotion,
"Number of indirect call promotions.");
57STATISTIC(NumOfPGOICallsites,
"Number of indirect call candidate sites.");
70using VTableAddressPointOffsetValMap =
74struct VirtualCallSiteInfo {
84using VirtualCallSiteTypeInfoMap =
95static std::optional<uint64_t>
103 TypeId && TypeId->getString() == CompatibleType)
117 assert(AddressPointOffset < VTable->getGlobalSize(M.getDataLayout()) &&
118 "Out-of-bound access");
128 return PN->getIncomingBlock(U);
143 "Guaranteed by ICP transformation");
154 UserBB = getUserBasicBlock(
Use, UserInst);
157 if (UserBB != DestBB)
160 return UserBB !=
nullptr;
168 if (!isDestBBSuitableForSink(
I, DestBlock))
179 if (
C->isInlineAsm() ||
C->cannotMerge() ||
C->isConvergent())
183 if (
I->mayWriteToMemory())
188 if (
I->mayReadFromMemory()) {
191 E =
I->getParent()->end();
196 if (Scan->mayWriteToMemory())
202 I->moveBefore(*DestBlock, InsertPos);
213static int tryToSinkInstructions(
BasicBlock *OriginalBB,
222 if (tryToSinkInstruction(&
I, IndirectCallBB))
230class IndirectCallPromoter {
232 const InstrumentationOptions &Opts;
238 InstrProfSymtab *
const Symtab;
240 const bool SamplePGO;
243 const VirtualCallSiteTypeInfoMap &VirtualCSInfo;
245 VTableAddressPointOffsetValMap &VTableAddressPointOffsetVal;
247 OptimizationRemarkEmitter &ORE;
249 const DenseSet<StringRef> &IgnoredBaseTypes;
252 struct PromotionCandidate {
255 const uint32_t Index;
264 VTableGUIDCountsMap VTableGUIDAndCounts;
268 : TargetFunction(
F), Count(
C), Index(
I) {}
276 std::vector<PromotionCandidate> getPromotionCandidatesForCallSite(
278 uint64_t TotalCount, uint32_t NumCandidates);
283 bool tryToPromoteWithFuncCmp(
286 uint32_t NumCandidates, VTableGUIDCountsMap &VTableGUIDCounts);
291 bool tryToPromoteWithVTableCmp(
293 uint64_t TotalFuncCount, uint32_t NumCandidates,
295 VTableGUIDCountsMap &VTableGUIDCounts);
298 bool isProfitableToCompareVTables(
const CallBase &CB,
303 bool shouldSkipVTable(
uint64_t VTableGUID);
312 Instruction *computeVTableInfos(
const CallBase *CB,
313 VTableGUIDCountsMap &VTableGUIDCounts,
314 std::vector<PromotionCandidate> &Candidates);
316 Constant *getOrCreateVTableAddressPointVar(GlobalVariable *GV,
319 void updateFuncValueProfiles(CallBase &CB,
323 void updateVPtrValueProfiles(Instruction *VPtr,
324 VTableGUIDCountsMap &VTableGUIDCounts);
329 IndirectCallPromoter(
331 InstrProfSymtab *Symtab,
bool SamplePGO,
332 const VirtualCallSiteTypeInfoMap &VirtualCSInfo,
333 VTableAddressPointOffsetValMap &VTableAddressPointOffsetVal,
334 const DenseSet<StringRef> &IgnoredBaseTypes,
335 OptimizationRemarkEmitter &ORE)
336 : Opts(Opts), F(
Func), M(M), Symtab(Symtab), SamplePGO(SamplePGO),
337 VirtualCSInfo(VirtualCSInfo),
338 VTableAddressPointOffsetVal(VTableAddressPointOffsetVal), ORE(ORE),
339 IgnoredBaseTypes(IgnoredBaseTypes) {}
340 IndirectCallPromoter(
const IndirectCallPromoter &) =
delete;
341 IndirectCallPromoter &operator=(
const IndirectCallPromoter &) =
delete;
359 if (TargetFunction ==
nullptr) {
362 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnableToFindTarget", &CB)
363 <<
"Cannot promote indirect call: target with md5sum "
364 <<
NV(
"target md5sum", Target)
365 <<
" not found (count=" <<
NV(
"Count",
Count) <<
")";
369 if (!Opts.icp_allow_decls && TargetFunction->
isDeclaration()) {
370 LLVM_DEBUG(
dbgs() <<
" Not promote: target definition is not available\n");
372 return OptimizationRemarkMissed(
DEBUG_TYPE,
"NoTargetDef", &CB)
373 <<
"Do not promote indirect call: target with md5sum "
374 <<
NV(
"target md5sum", Target)
375 <<
" definition not available (count=" <<
ore::NV(
"Count",
Count)
381 const char *Reason =
nullptr;
385 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnableToPromote", &CB)
386 <<
"Cannot promote indirect call to "
387 <<
NV(
"TargetFunction", TargetFunction)
388 <<
" (count=" <<
NV(
"Count",
Count) <<
"): " << Reason;
397std::vector<IndirectCallPromoter::PromotionCandidate>
398IndirectCallPromoter::getPromotionCandidatesForCallSite(
400 uint64_t TotalCount, uint32_t NumCandidates) {
401 std::vector<PromotionCandidate> Ret;
403 LLVM_DEBUG(
dbgs() <<
" \nWork on callsite #" << NumOfPGOICallsites << CB
404 <<
" Num_targets: " << ValueDataRef.
size()
405 <<
" Num_candidates: " << NumCandidates <<
"\n");
406 NumOfPGOICallsites++;
407 if (Opts.icp_csskip != 0 && NumOfPGOICallsites <= Opts.icp_csskip) {
412 for (uint32_t
I = 0;
I < NumCandidates;
I++) {
418 <<
" Target_func: " << Target <<
"\n");
423 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UserOptions", &CB)
424 <<
" Not promote: User options";
431 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UserOptions", &CB)
432 <<
" Not promote: User options";
436 if (Opts.icp_cutoff != 0 && NumOfPGOICallPromotion >= Opts.icp_cutoff) {
439 return OptimizationRemarkMissed(
DEBUG_TYPE,
"CutOffReached", &CB)
440 <<
" Not promote: Cutoff reached";
446 if (!isValidTarget(Target, TargetFunction, CB,
Count)) {
447 if (Opts.icp_allow_candidate_skip)
453 Ret.push_back(PromotionCandidate(TargetFunction,
Count,
I));
459Constant *IndirectCallPromoter::getOrCreateVTableAddressPointVar(
460 GlobalVariable *GV,
uint64_t AddressPointOffset) {
462 VTableAddressPointOffsetVal[GV].try_emplace(AddressPointOffset,
nullptr);
464 Iter->second = getVTableAddressPointOffset(GV, AddressPointOffset);
468Instruction *IndirectCallPromoter::computeVTableInfos(
469 const CallBase *CB, VTableGUIDCountsMap &GUIDCountsMap,
470 std::vector<PromotionCandidate> &Candidates) {
498 auto Iter = VirtualCSInfo.find(CB);
499 if (Iter == VirtualCSInfo.end())
503 << NumOfPGOICallsites <<
"\n");
505 const auto &VirtualCallInfo = Iter->second;
508 SmallDenseMap<Function *, int, 4> CalleeIndexMap;
509 for (
size_t I = 0;
I < Candidates.size();
I++)
510 CalleeIndexMap[Candidates[
I].TargetFunction] =
I;
513 auto VTableValueDataArray =
516 if (VTableValueDataArray.empty())
520 for (
const auto &V : VTableValueDataArray) {
522 GUIDCountsMap[VTableVal] =
V.Count;
525 LLVM_DEBUG(
dbgs() <<
" Cannot find vtable definition for " << VTableVal
526 <<
"; maybe the vtable isn't imported\n");
530 std::optional<uint64_t> MaybeAddressPointOffset =
531 getAddressPointOffset(*VTableVar, VirtualCallInfo.CompatibleTypeStr);
532 if (!MaybeAddressPointOffset)
535 const uint64_t AddressPointOffset = *MaybeAddressPointOffset;
539 VTableVar, AddressPointOffset + VirtualCallInfo.FunctionOffset, M);
542 auto CalleeIndexIter = CalleeIndexMap.
find(Callee);
543 if (CalleeIndexIter == CalleeIndexMap.
end())
546 auto &Candidate = Candidates[CalleeIndexIter->second];
550 Candidate.VTableGUIDAndCounts[VTableVal] =
V.Count;
551 Candidate.AddressPoints.push_back(
552 getOrCreateVTableAddressPointVar(VTableVar, AddressPointOffset));
569 uint64_t
Count, uint64_t TotalCount,
570 bool AttachProfToDirectCall,
576 if (AttachProfToDirectCall)
585 <<
"Promote indirect call to " << NV(
"DirectCallee", DirectCallee)
586 <<
" with count " << NV(
"Count",
Count) <<
" out of "
587 << NV(
"TotalCount", TotalCount);
593bool IndirectCallPromoter::tryToPromoteWithFuncCmp(
596 uint32_t NumCandidates, VTableGUIDCountsMap &VTableGUIDCounts) {
599 for (
const auto &
C : Candidates) {
600 uint64_t FuncCount =
C.Count;
603 assert(TotalCount >= FuncCount);
604 TotalCount -= FuncCount;
605 NumOfPGOICallPromotion++;
609 ICallProfDataRef[
C.Index].Count = 0;
617 uint64_t SumVTableCount = 0;
618 for (
const auto &[GUID, VTableCount] :
C.VTableGUIDAndCounts)
619 SumVTableCount += VTableCount;
621 for (
const auto &[GUID, VTableCount] :
C.VTableGUIDAndCounts) {
622 APInt APFuncCount((
unsigned)128, FuncCount,
false );
623 APFuncCount *= VTableCount;
624 VTableGUIDCounts[GUID] -= APFuncCount.udiv(SumVTableCount).getZExtValue();
627 if (NumPromoted == 0)
630 assert(NumPromoted <= ICallProfDataRef.
size() &&
631 "Number of promoted functions should not be greater than the number "
632 "of values in profile metadata");
634 updateFuncValueProfiles(CB, ICallProfDataRef, TotalCount, NumCandidates);
635 updateVPtrValueProfiles(VPtr, VTableGUIDCounts);
639void IndirectCallPromoter::updateFuncValueProfiles(
641 uint64_t TotalCount, uint32_t MaxMDCount) {
647 const InstrProfValueData &
RHS) {
648 return LHS.Count >
RHS.Count;
655 return ProfData.Count <= Count;
664void IndirectCallPromoter::updateVPtrValueProfiles(
665 Instruction *VPtr, VTableGUIDCountsMap &VTableGUIDCounts) {
670 std::vector<InstrProfValueData> VTableValueProfiles;
672 for (
auto [GUID,
Count] : VTableGUIDCounts) {
676 VTableValueProfiles.push_back({
GUID,
Count});
677 TotalVTableCount +=
Count;
680 [](
const InstrProfValueData &
LHS,
const InstrProfValueData &
RHS) {
681 return LHS.Count >
RHS.Count;
685 IPVK_VTableTarget, VTableValueProfiles.size());
688bool IndirectCallPromoter::tryToPromoteWithVTableCmp(
690 uint64_t TotalFuncCount, uint32_t NumCandidates,
692 VTableGUIDCountsMap &VTableGUIDCounts) {
695 for (
const auto &Candidate : Candidates) {
696 for (
auto &[GUID,
Count] : Candidate.VTableGUIDAndCounts)
704 CB, VPtr, Candidate.TargetFunction, Candidate.AddressPoints,
706 TotalFuncCount - Candidate.Count));
708 int SinkCount = tryToSinkInstructions(OriginalBB, CB.
getParent());
713 const auto &VTableGUIDAndCounts = Candidate.VTableGUIDAndCounts;
714 Remark <<
"Promote indirect call to "
715 <<
ore::NV(
"DirectCallee", Candidate.TargetFunction)
716 <<
" with count " <<
ore::NV(
"Count", Candidate.Count)
717 <<
" out of " <<
ore::NV(
"TotalCount", TotalFuncCount) <<
", sink "
718 <<
ore::NV(
"SinkCount", SinkCount)
719 <<
" instruction(s) and compare "
720 <<
ore::NV(
"VTable", VTableGUIDAndCounts.size())
724 std::set<uint64_t> GUIDSet;
725 for (
auto [GUID,
Count] : VTableGUIDAndCounts)
726 GUIDSet.insert(GUID);
727 for (
auto Iter = GUIDSet.begin(); Iter != GUIDSet.end(); Iter++) {
728 if (Iter != GUIDSet.begin())
738 PromotedFuncCount.
push_back({Candidate.Index, Candidate.Count});
740 assert(TotalFuncCount >= Candidate.Count &&
741 "Within one prof metadata, total count is the sum of counts from "
742 "individual <target, count> pairs");
746 TotalFuncCount -= std::min(TotalFuncCount, Candidate.Count);
747 NumOfPGOICallPromotion++;
750 if (PromotedFuncCount.
empty())
759 for (
size_t I = 0;
I < PromotedFuncCount.
size();
I++) {
760 uint32_t
Index = PromotedFuncCount[
I].first;
761 ICallProfDataRef[
Index].Count -=
762 std::max(PromotedFuncCount[
I].second, ICallProfDataRef[Index].
Count);
764 updateFuncValueProfiles(CB, ICallProfDataRef, TotalFuncCount, NumCandidates);
765 updateVPtrValueProfiles(VPtr, VTableGUIDCounts);
771bool IndirectCallPromoter::processFunction(ProfileSummaryInfo *PSI) {
773 ICallPromotionAnalysis ICallAnalysis;
775 uint32_t NumCandidates;
778 CB, TotalCount, NumCandidates);
784 LLVM_DEBUG(
dbgs() <<
"Don't promote the cold candidate: TotalCount="
785 << TotalCount <<
"\n");
791 if (Opts.icp_allow_hot_only &&
794 : Opts.hot_func_cutoff_for_icp,
796 LLVM_DEBUG(
dbgs() <<
"Don't promote the non-hot candidate: TotalCount="
797 << TotalCount <<
"\n");
802 auto PromotionCandidates = getPromotionCandidatesForCallSite(
803 *CB, ICallProfDataRef, TotalCount, NumCandidates);
805 VTableGUIDCountsMap VTableGUIDCounts;
807 computeVTableInfos(CB, VTableGUIDCounts, PromotionCandidates);
809 if (isProfitableToCompareVTables(*CB, PromotionCandidates))
810 Changed |= tryToPromoteWithVTableCmp(*CB, VPtr, PromotionCandidates,
811 TotalCount, NumCandidates,
812 ICallProfDataRef, VTableGUIDCounts);
814 Changed |= tryToPromoteWithFuncCmp(*CB, VPtr, PromotionCandidates,
815 TotalCount, ICallProfDataRef,
816 NumCandidates, VTableGUIDCounts);
823bool IndirectCallPromoter::isProfitableToCompareVTables(
827 LLVM_DEBUG(
dbgs() <<
"\nEvaluating vtable profitability for callsite #"
828 << NumOfPGOICallsites << CB <<
"\n");
829 const size_t CandidateSize = Candidates.
size();
830 for (
size_t I = 0;
I < CandidateSize;
I++) {
831 auto &Candidate = Candidates[
I];
832 auto &VTableGUIDAndCounts = Candidate.VTableGUIDAndCounts;
835 dbgs() <<
" Candidate " <<
I <<
" FunctionCount: " << Candidate.Count
836 <<
", VTableCounts:";
837 for (
const auto &[GUID,
Count] : VTableGUIDAndCounts)
845 for (
auto &[GUID,
Count] : VTableGUIDAndCounts) {
846 CandidateVTableCount +=
Count;
848 if (shouldSkipVTable(GUID))
852 if (CandidateVTableCount <
853 Candidate.Count * Opts.icp_vtable_percentage_threshold) {
855 dbgs() <<
" function count " << Candidate.Count
856 <<
" and its vtable sum count " << CandidateVTableCount
857 <<
" have discrepancies. Bail out vtable comparison.\n");
867 int MaxNumVTable = 1;
868 if (
I == CandidateSize - 1)
869 MaxNumVTable = Opts.icp_max_num_vtable_last_candidate;
871 if ((
int)Candidate.AddressPoints.size() > MaxNumVTable) {
872 LLVM_DEBUG(
dbgs() <<
" allow at most " << MaxNumVTable <<
" and got "
873 << Candidate.AddressPoints.size()
874 <<
" vtables. Bail out for vtable comparison.\n");
882bool IndirectCallPromoter::shouldSkipVTable(
uint64_t VTableGUID) {
883 if (IgnoredBaseTypes.empty())
888 assert(VTableVar &&
"VTableVar must exist for GUID in VTableGUIDAndCounts");
891 VTableVar->
getMetadata(LLVMContext::MD_type, Types);
893 for (
auto *
Type : Types)
895 if (IgnoredBaseTypes.contains(TypeId->getString())) {
897 "out of vtable comparison.");
911 VirtualCallSiteTypeInfoMap &VirtualCSInfo) {
922 if (!TypeTestFunc || TypeTestFunc->
use_empty())
938 if (!CompatibleTypeId)
945 auto &DT = LookupDomTree(*CI->getFunction());
948 for (
auto &DevirtCall : DevirtCalls) {
956 VirtualCSInfo[&CB] = {DevirtCall.Offset, VTablePtr,
957 CompatibleTypeId->getString()};
966 if (Opts.disable_icp)
970 std::string SymtabFailure =
toString(std::move(
E));
971 M.getContext().emitError(
"Failed to create symtab: " + SymtabFailure);
975 VirtualCallSiteTypeInfoMap VirtualCSInfo;
982 IgnoredBaseTypes.
insert_range(Opts.icp_ignored_base_types);
992 VTableAddressPointOffsetValMap VTableAddressPointOffsetVal;
995 if (
F.isDeclaration() ||
F.hasOptNone())
1002 IndirectCallPromoter CallPromoter(
1003 Opts,
F, M, &Symtab, SamplePGO, VirtualCSInfo,
1004 VTableAddressPointOffsetVal, IgnoredBaseTypes, ORE);
1005 bool FuncChanged = CallPromoter.processFunction(PSI);
1006 if (Opts.icp_dumpafter && FuncChanged) {
1011 if (Opts.icp_cutoff != 0 && NumOfPGOICallPromotion >= Opts.icp_cutoff) {
1023 const InstrumentationOptions &Opts = InstrumentationOptions::Global;
1025 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 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.
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.
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.
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 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)