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");
151 UserBB = getUserBasicBlock(
Use, UserInst);
154 if (UserBB != DestBB)
157 return UserBB !=
nullptr;
165 if (!isDestBBSuitableForSink(
I, DestBlock))
176 if (
C->isInlineAsm() ||
C->cannotMerge() ||
C->isConvergent())
180 if (
I->mayWriteToMemory())
185 if (
I->mayReadFromMemory()) {
188 E =
I->getParent()->end();
193 if (Scan->mayWriteToMemory())
199 I->moveBefore(*DestBlock, InsertPos);
210static int tryToSinkInstructions(
BasicBlock *OriginalBB,
219 if (tryToSinkInstruction(&
I, IndirectCallBB))
227class IndirectCallPromoter {
229 const InstrumentationOptions &Opts;
235 InstrProfSymtab *
const Symtab;
237 const bool SamplePGO;
240 const VirtualCallSiteTypeInfoMap &VirtualCSInfo;
242 VTableAddressPointOffsetValMap &VTableAddressPointOffsetVal;
244 OptimizationRemarkEmitter &ORE;
246 const DenseSet<StringRef> &IgnoredBaseTypes;
249 struct PromotionCandidate {
252 const uint32_t Index;
261 VTableGUIDCountsMap VTableGUIDAndCounts;
265 : TargetFunction(
F), Count(
C), Index(
I) {}
273 std::vector<PromotionCandidate> getPromotionCandidatesForCallSite(
275 uint64_t TotalCount, uint32_t NumCandidates);
280 bool tryToPromoteWithFuncCmp(
283 uint32_t NumCandidates, VTableGUIDCountsMap &VTableGUIDCounts);
288 bool tryToPromoteWithVTableCmp(
290 uint64_t TotalFuncCount, uint32_t NumCandidates,
292 VTableGUIDCountsMap &VTableGUIDCounts);
295 bool isProfitableToCompareVTables(
const CallBase &CB,
300 bool shouldSkipVTable(
uint64_t VTableGUID);
309 Instruction *computeVTableInfos(
const CallBase *CB,
310 VTableGUIDCountsMap &VTableGUIDCounts,
311 std::vector<PromotionCandidate> &Candidates);
313 Constant *getOrCreateVTableAddressPointVar(GlobalVariable *GV,
316 void updateFuncValueProfiles(CallBase &CB,
320 void updateVPtrValueProfiles(Instruction *VPtr,
321 VTableGUIDCountsMap &VTableGUIDCounts);
326 IndirectCallPromoter(
328 InstrProfSymtab *Symtab,
bool SamplePGO,
329 const VirtualCallSiteTypeInfoMap &VirtualCSInfo,
330 VTableAddressPointOffsetValMap &VTableAddressPointOffsetVal,
331 const DenseSet<StringRef> &IgnoredBaseTypes,
332 OptimizationRemarkEmitter &ORE)
333 : Opts(Opts), F(
Func), M(M), Symtab(Symtab), SamplePGO(SamplePGO),
334 VirtualCSInfo(VirtualCSInfo),
335 VTableAddressPointOffsetVal(VTableAddressPointOffsetVal), ORE(ORE),
336 IgnoredBaseTypes(IgnoredBaseTypes) {}
337 IndirectCallPromoter(
const IndirectCallPromoter &) =
delete;
338 IndirectCallPromoter &operator=(
const IndirectCallPromoter &) =
delete;
356 if (TargetFunction ==
nullptr) {
359 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnableToFindTarget", &CB)
360 <<
"Cannot promote indirect call: target with md5sum "
361 <<
NV(
"target md5sum", Target)
362 <<
" not found (count=" <<
NV(
"Count",
Count) <<
")";
366 if (!Opts.icp_allow_decls && TargetFunction->
isDeclaration()) {
367 LLVM_DEBUG(
dbgs() <<
" Not promote: target definition is not available\n");
369 return OptimizationRemarkMissed(
DEBUG_TYPE,
"NoTargetDef", &CB)
370 <<
"Do not promote indirect call: target with md5sum "
371 <<
NV(
"target md5sum", Target)
372 <<
" definition not available (count=" <<
ore::NV(
"Count",
Count)
378 const char *Reason =
nullptr;
382 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnableToPromote", &CB)
383 <<
"Cannot promote indirect call to "
384 <<
NV(
"TargetFunction", TargetFunction)
385 <<
" (count=" <<
NV(
"Count",
Count) <<
"): " << Reason;
394std::vector<IndirectCallPromoter::PromotionCandidate>
395IndirectCallPromoter::getPromotionCandidatesForCallSite(
397 uint64_t TotalCount, uint32_t NumCandidates) {
398 std::vector<PromotionCandidate> Ret;
400 LLVM_DEBUG(
dbgs() <<
" \nWork on callsite #" << NumOfPGOICallsites << CB
401 <<
" Num_targets: " << ValueDataRef.
size()
402 <<
" Num_candidates: " << NumCandidates <<
"\n");
403 NumOfPGOICallsites++;
404 if (Opts.icp_csskip != 0 && NumOfPGOICallsites <= Opts.icp_csskip) {
409 for (uint32_t
I = 0;
I < NumCandidates;
I++) {
415 <<
" Target_func: " << Target <<
"\n");
420 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UserOptions", &CB)
421 <<
" Not promote: User options";
428 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UserOptions", &CB)
429 <<
" Not promote: User options";
433 if (Opts.icp_cutoff != 0 && NumOfPGOICallPromotion >= Opts.icp_cutoff) {
436 return OptimizationRemarkMissed(
DEBUG_TYPE,
"CutOffReached", &CB)
437 <<
" Not promote: Cutoff reached";
443 if (!isValidTarget(Target, TargetFunction, CB,
Count)) {
444 if (Opts.icp_allow_candidate_skip)
450 Ret.push_back(PromotionCandidate(TargetFunction,
Count,
I));
456Constant *IndirectCallPromoter::getOrCreateVTableAddressPointVar(
457 GlobalVariable *GV,
uint64_t AddressPointOffset) {
459 VTableAddressPointOffsetVal[GV].try_emplace(AddressPointOffset,
nullptr);
461 Iter->second = getVTableAddressPointOffset(GV, AddressPointOffset);
465Instruction *IndirectCallPromoter::computeVTableInfos(
466 const CallBase *CB, VTableGUIDCountsMap &GUIDCountsMap,
467 std::vector<PromotionCandidate> &Candidates) {
495 auto Iter = VirtualCSInfo.find(CB);
496 if (Iter == VirtualCSInfo.end())
500 << NumOfPGOICallsites <<
"\n");
502 const auto &VirtualCallInfo = Iter->second;
505 SmallDenseMap<Function *, int, 4> CalleeIndexMap;
506 for (
size_t I = 0;
I < Candidates.size();
I++)
507 CalleeIndexMap[Candidates[
I].TargetFunction] =
I;
510 auto VTableValueDataArray =
513 if (VTableValueDataArray.empty())
517 for (
const auto &V : VTableValueDataArray) {
519 GUIDCountsMap[VTableVal] =
V.Count;
522 LLVM_DEBUG(
dbgs() <<
" Cannot find vtable definition for " << VTableVal
523 <<
"; maybe the vtable isn't imported\n");
527 std::optional<uint64_t> MaybeAddressPointOffset =
528 getAddressPointOffset(*VTableVar, VirtualCallInfo.CompatibleTypeStr);
529 if (!MaybeAddressPointOffset)
532 const uint64_t AddressPointOffset = *MaybeAddressPointOffset;
536 VTableVar, AddressPointOffset + VirtualCallInfo.FunctionOffset, M);
539 auto CalleeIndexIter = CalleeIndexMap.
find(Callee);
540 if (CalleeIndexIter == CalleeIndexMap.
end())
543 auto &Candidate = Candidates[CalleeIndexIter->second];
547 Candidate.VTableGUIDAndCounts[VTableVal] =
V.Count;
548 Candidate.AddressPoints.push_back(
549 getOrCreateVTableAddressPointVar(VTableVar, AddressPointOffset));
566 uint64_t
Count, uint64_t TotalCount,
567 bool AttachProfToDirectCall,
573 if (AttachProfToDirectCall)
582 <<
"Promote indirect call to " << NV(
"DirectCallee", DirectCallee)
583 <<
" with count " << NV(
"Count",
Count) <<
" out of "
584 << NV(
"TotalCount", TotalCount);
590bool IndirectCallPromoter::tryToPromoteWithFuncCmp(
593 uint32_t NumCandidates, VTableGUIDCountsMap &VTableGUIDCounts) {
596 for (
const auto &
C : Candidates) {
597 uint64_t FuncCount =
C.Count;
600 assert(TotalCount >= FuncCount);
601 TotalCount -= FuncCount;
602 NumOfPGOICallPromotion++;
606 ICallProfDataRef[
C.Index].Count = 0;
614 uint64_t SumVTableCount = 0;
615 for (
const auto &[GUID, VTableCount] :
C.VTableGUIDAndCounts)
616 SumVTableCount += VTableCount;
618 for (
const auto &[GUID, VTableCount] :
C.VTableGUIDAndCounts) {
619 APInt APFuncCount((
unsigned)128, FuncCount,
false );
620 APFuncCount *= VTableCount;
621 VTableGUIDCounts[GUID] -= APFuncCount.udiv(SumVTableCount).getZExtValue();
624 if (NumPromoted == 0)
627 assert(NumPromoted <= ICallProfDataRef.
size() &&
628 "Number of promoted functions should not be greater than the number "
629 "of values in profile metadata");
631 updateFuncValueProfiles(CB, ICallProfDataRef, TotalCount, NumCandidates);
632 updateVPtrValueProfiles(VPtr, VTableGUIDCounts);
636void IndirectCallPromoter::updateFuncValueProfiles(
638 uint64_t TotalCount, uint32_t MaxMDCount) {
644 const InstrProfValueData &
RHS) {
645 return LHS.Count >
RHS.Count;
652 return ProfData.Count <= Count;
661void IndirectCallPromoter::updateVPtrValueProfiles(
662 Instruction *VPtr, VTableGUIDCountsMap &VTableGUIDCounts) {
667 std::vector<InstrProfValueData> VTableValueProfiles;
669 for (
auto [GUID,
Count] : VTableGUIDCounts) {
673 VTableValueProfiles.push_back({
GUID,
Count});
674 TotalVTableCount +=
Count;
677 [](
const InstrProfValueData &
LHS,
const InstrProfValueData &
RHS) {
678 return LHS.Count >
RHS.Count;
682 IPVK_VTableTarget, VTableValueProfiles.size());
685bool IndirectCallPromoter::tryToPromoteWithVTableCmp(
687 uint64_t TotalFuncCount, uint32_t NumCandidates,
689 VTableGUIDCountsMap &VTableGUIDCounts) {
692 for (
const auto &Candidate : Candidates) {
693 for (
auto &[GUID,
Count] : Candidate.VTableGUIDAndCounts)
701 CB, VPtr, Candidate.TargetFunction, Candidate.AddressPoints,
703 TotalFuncCount - Candidate.Count));
705 int SinkCount = tryToSinkInstructions(OriginalBB, CB.
getParent());
710 const auto &VTableGUIDAndCounts = Candidate.VTableGUIDAndCounts;
711 Remark <<
"Promote indirect call to "
712 <<
ore::NV(
"DirectCallee", Candidate.TargetFunction)
713 <<
" with count " <<
ore::NV(
"Count", Candidate.Count)
714 <<
" out of " <<
ore::NV(
"TotalCount", TotalFuncCount) <<
", sink "
715 <<
ore::NV(
"SinkCount", SinkCount)
716 <<
" instruction(s) and compare "
717 <<
ore::NV(
"VTable", VTableGUIDAndCounts.size())
721 std::set<uint64_t> GUIDSet;
722 for (
auto [GUID,
Count] : VTableGUIDAndCounts)
723 GUIDSet.insert(GUID);
724 for (
auto Iter = GUIDSet.begin(); Iter != GUIDSet.end(); Iter++) {
725 if (Iter != GUIDSet.begin())
735 PromotedFuncCount.
push_back({Candidate.Index, Candidate.Count});
737 assert(TotalFuncCount >= Candidate.Count &&
738 "Within one prof metadata, total count is the sum of counts from "
739 "individual <target, count> pairs");
743 TotalFuncCount -= std::min(TotalFuncCount, Candidate.Count);
744 NumOfPGOICallPromotion++;
747 if (PromotedFuncCount.
empty())
756 for (
size_t I = 0;
I < PromotedFuncCount.
size();
I++) {
757 uint32_t
Index = PromotedFuncCount[
I].first;
758 ICallProfDataRef[
Index].Count -=
759 std::max(PromotedFuncCount[
I].second, ICallProfDataRef[Index].
Count);
761 updateFuncValueProfiles(CB, ICallProfDataRef, TotalFuncCount, NumCandidates);
762 updateVPtrValueProfiles(VPtr, VTableGUIDCounts);
768bool IndirectCallPromoter::processFunction(ProfileSummaryInfo *PSI) {
770 ICallPromotionAnalysis ICallAnalysis;
772 uint32_t NumCandidates;
775 CB, TotalCount, NumCandidates);
781 LLVM_DEBUG(
dbgs() <<
"Don't promote the cold candidate: TotalCount="
782 << TotalCount <<
"\n");
788 if (Opts.icp_allow_hot_only &&
791 : Opts.hot_func_cutoff_for_icp,
793 LLVM_DEBUG(
dbgs() <<
"Don't promote the non-hot candidate: TotalCount="
794 << TotalCount <<
"\n");
799 auto PromotionCandidates = getPromotionCandidatesForCallSite(
800 *CB, ICallProfDataRef, TotalCount, NumCandidates);
802 VTableGUIDCountsMap VTableGUIDCounts;
804 computeVTableInfos(CB, VTableGUIDCounts, PromotionCandidates);
806 if (isProfitableToCompareVTables(*CB, PromotionCandidates))
807 Changed |= tryToPromoteWithVTableCmp(*CB, VPtr, PromotionCandidates,
808 TotalCount, NumCandidates,
809 ICallProfDataRef, VTableGUIDCounts);
811 Changed |= tryToPromoteWithFuncCmp(*CB, VPtr, PromotionCandidates,
812 TotalCount, ICallProfDataRef,
813 NumCandidates, VTableGUIDCounts);
820bool IndirectCallPromoter::isProfitableToCompareVTables(
824 LLVM_DEBUG(
dbgs() <<
"\nEvaluating vtable profitability for callsite #"
825 << NumOfPGOICallsites << CB <<
"\n");
826 const size_t CandidateSize = Candidates.
size();
827 for (
size_t I = 0;
I < CandidateSize;
I++) {
828 auto &Candidate = Candidates[
I];
829 auto &VTableGUIDAndCounts = Candidate.VTableGUIDAndCounts;
832 dbgs() <<
" Candidate " <<
I <<
" FunctionCount: " << Candidate.Count
833 <<
", VTableCounts:";
834 for (
const auto &[GUID,
Count] : VTableGUIDAndCounts)
842 for (
auto &[GUID,
Count] : VTableGUIDAndCounts) {
843 CandidateVTableCount +=
Count;
845 if (shouldSkipVTable(GUID))
849 if (CandidateVTableCount <
850 Candidate.Count * Opts.icp_vtable_percentage_threshold) {
852 dbgs() <<
" function count " << Candidate.Count
853 <<
" and its vtable sum count " << CandidateVTableCount
854 <<
" have discrepancies. Bail out vtable comparison.\n");
864 int MaxNumVTable = 1;
865 if (
I == CandidateSize - 1)
866 MaxNumVTable = Opts.icp_max_num_vtable_last_candidate;
868 if ((
int)Candidate.AddressPoints.size() > MaxNumVTable) {
869 LLVM_DEBUG(
dbgs() <<
" allow at most " << MaxNumVTable <<
" and got "
870 << Candidate.AddressPoints.size()
871 <<
" vtables. Bail out for vtable comparison.\n");
879bool IndirectCallPromoter::shouldSkipVTable(
uint64_t VTableGUID) {
880 if (IgnoredBaseTypes.empty())
885 assert(VTableVar &&
"VTableVar must exist for GUID in VTableGUIDAndCounts");
888 VTableVar->
getMetadata(LLVMContext::MD_type, Types);
890 for (
auto *
Type : Types)
892 if (IgnoredBaseTypes.contains(TypeId->getString())) {
894 "out of vtable comparison.");
908 VirtualCallSiteTypeInfoMap &VirtualCSInfo) {
919 if (!TypeTestFunc || TypeTestFunc->
use_empty())
935 if (!CompatibleTypeId)
942 auto &DT = LookupDomTree(*CI->getFunction());
945 for (
auto &DevirtCall : DevirtCalls) {
953 VirtualCSInfo[&CB] = {DevirtCall.Offset, VTablePtr,
954 CompatibleTypeId->getString()};
963 if (Opts.disable_icp)
967 std::string SymtabFailure =
toString(std::move(
E));
968 M.getContext().emitError(
"Failed to create symtab: " + SymtabFailure);
972 VirtualCallSiteTypeInfoMap VirtualCSInfo;
979 IgnoredBaseTypes.
insert_range(Opts.icp_ignored_base_types);
989 VTableAddressPointOffsetValMap VTableAddressPointOffsetVal;
992 if (
F.isDeclaration() ||
F.hasOptNone())
999 IndirectCallPromoter CallPromoter(
1000 Opts,
F, M, &Symtab, SamplePGO, VirtualCSInfo,
1001 VTableAddressPointOffsetVal, IgnoredBaseTypes, ORE);
1002 bool FuncChanged = CallPromoter.processFunction(PSI);
1003 if (Opts.icp_dumpafter && FuncChanged) {
1008 if (Opts.icp_cutoff != 0 && NumOfPGOICallPromotion >= Opts.icp_cutoff) {
1020 const InstrumentationOptions &Opts = InstrumentationOptions::Global;
1022 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.
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)