25#define DEBUG_TYPE "ctx_prof"
30 cl::desc(
"Use the specified contextual profile file"));
36 Ret[
"Guid"] =
P.guid();
37 Ret[
"Counters"] =
Array(
P.counters());
38 if (
P.callsites().empty())
43 assert(MaxIt != AllCS.end() &&
"We should have a max value because the "
44 "callsites collection is not empty.");
47 for (
auto I = 0U, Max = *MaxIt;
I <= Max; ++
I) {
51 for (
const auto &[
_, Ctx] :
P.callsite(
I))
54 Ret[
"Callsites"] = std::move(CSites);
61 for (
const auto &[
_, Ctx] :
P)
62 Ret.push_back(
toJSON(Ctx));
71 for (
auto &
F : M.functions()) {
72 if (
F.isDeclaration())
79 {ConstantAsMetadata::get(ConstantInt::get(
80 Type::getInt64Ty(M.getContext()), GUID))}));
86 if (
F.isDeclaration()) {
91 assert(MD &&
"guid not found for defined function");
92 return cast<ConstantInt>(cast<ConstantAsMetadata>(MD->getOperand(0))
94 ->stripPointerCasts())
106 M.getContext().emitError(
"could not open contextual profile file: " +
113 M.getContext().emitError(
"contextual profile file is invalid: " +
120 for (
const auto &
F : M) {
121 if (
F.isDeclaration())
124 assert(GUID &&
"guid not found for defined function");
125 const auto &Entry =
F.begin();
127 for (
const auto &
I : *Entry)
128 if (
auto *
C = dyn_cast<InstrProfIncrementInst>(&
I)) {
130 static_cast<uint32_t>(
C->getNumCounters()->getZExtValue());
136 for (
const auto &BB :
F)
137 for (
const auto &
I : BB)
138 if (
auto *
C = dyn_cast<InstrProfCallsite>(&
I)) {
140 static_cast<uint32_t>(
C->getNumCounters()->getZExtValue());
143 auto [It, Ins] =
Result.FuncInfo.insert(
144 {GUID, PGOContextualProfile::FunctionInfo(
F.getName())});
147 It->second.NextCallsiteIndex = MaxCallsites;
148 It->second.NextCounterIndex = MaxCounters;
155 if (!
Result.FuncInfo.contains(RootGuid))
156 MaybeCtx->
erase(RootGuid);
157 Result.Profiles = std::move(*MaybeCtx);
162PGOContextualProfile::getDefinedFunctionGUID(
const Function &
F)
const {
172 M.getContext().emitError(
"Invalid CtxProfAnalysis");
176 OS <<
"Function Info:\n";
177 for (
const auto &[
Guid, FuncInfo] :
C.FuncInfo)
178 OS <<
Guid <<
" : " << FuncInfo.Name
179 <<
". MaxCounterID: " << FuncInfo.NextCounterIndex
180 <<
". MaxCallsiteID: " << FuncInfo.NextCallsiteIndex <<
"\n";
184 OS <<
"\nCurrent Profile:\n";
185 OS <<
formatv(
"{0:2}", JSONed);
192 if (
auto *IPC = dyn_cast<InstrProfCallsite>(Prev))
cl::opt< std::string > UseCtxProfile("use-ctx-profile", cl::init(""), cl::Hidden, cl::desc("Use the specified contextual profile file"))
This file supports working with JSON data.
Module.h This file contains the declarations for the Module class.
Reader for contextual iFDO profile, which comes in bitstream format.
ModuleAnalysisManager MAM
This header defines various interfaces for pass management in LLVM.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A container for analyses that lazily runs them and caches their results.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
static uint64_t getGUID(const Function &F)
static const char * GUIDMetadataName
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)
Assign a GUID if one is not already assign, as a function metadata named GUIDMetadataName.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)
PGOContextualProfile run(Module &M, ModuleAnalysisManager &MAM)
CtxProfAnalysis(StringRef Profile="")
static InstrProfCallsite * getCallsiteInstrumentation(CallBase &CB)
PGOContextualProfile Result
Implements a dense probed hash-table based set.
Represents either an error or a value T.
std::error_code getError() const
GUID getGUID() const
Return a 64-bit global unique ID constructed from global value name (i.e.
static bool isExternalLinkage(LinkageTypes Linkage)
This represents the llvm.instrprof.callsite intrinsic.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
A Module instance is used to store all the information related to an LLVM module.
The instrumented contextual profile, produced by the CtxProfAnalysis.
A node (context) in the loaded contextual profile, suitable for mutation during IPO passes.
std::map< GlobalValue::GUID, PGOCtxProfContext > CallTargetMapTy
Expected< std::map< GlobalValue::GUID, PGOCtxProfContext > > loadContexts()
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.
StringRef - Represent a constant reference to a string, i.e.
bool erase(const ValueT &V)
An Array is a JSON array, which contains heterogeneous JSON values.
void push_back(const Value &E)
An Object is a JSON object, which maps strings to heterogenous JSON values.
A Value is an JSON value of unknown type.
const json::Array * getAsArray() const
Pass manager infrastructure for declaring and invalidating analyses.
@ C
The default llvm calling convention, compatible with C.
initializer< Ty > init(const Ty &Val)
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
Value toJSON(const std::optional< T > &Opt)
This is an optimization pass for GlobalISel generic memory operations.
auto formatv(const char *Fmt, Ts &&...Vals) -> formatv_object< decltype(std::make_tuple(support::detail::build_format_adapter(std::forward< Ts >(Vals))...))>
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...
auto map_range(ContainerTy &&C, FuncTy F)
auto max_element(R &&Range)
Provide wrappers to std::max_element which take ranges instead of having to pass begin/end explicitly...
A special type used by analysis passes to provide an address that identifies that particular analysis...