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);
187 OS <<
"\nFlat Profile:\n";
188 auto Flat =
C.flatten();
200 if (
auto *IPC = dyn_cast<InstrProfCallsite>(Prev))
207 if (
auto *Incr = dyn_cast<InstrProfIncrementInst>(&
I))
216 [&](
const auto &Ctx) {
218 for (
const auto &[
_, SubCtxSet] : Ctx.callsites())
219 for (
const auto &[__, Subctx] : SubCtxSet)
222 for (
const auto &[
_,
P] : Profiles)
227 assert(Profiles.has_value());
230 auto [It, Ins] = Flat.
insert({Ctx.
guid(), {}});
236 "All contexts corresponding to a function should have the exact "
237 "same number of counters.");
238 for (
size_t I = 0, E = It->second.size();
I < E; ++
I)
cl::opt< std::string > UseCtxProfile("use-ctx-profile", cl::init(""), cl::Hidden, cl::desc("Use the specified contextual profile file"))
static void preorderVisit(const PGOCtxProfContext::CallTargetMapTy &Profiles, function_ref< void(const PGOCtxProfContext &)> Visitor)
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.
LLVM Basic Block Representation.
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)
static InstrProfIncrementInst * getBBInstrumentation(BasicBlock &BB)
Get the instruction instrumenting a BB, or nullptr if not present.
CtxProfAnalysis(StringRef Profile="")
static InstrProfCallsite * getCallsiteInstrumentation(CallBase &CB)
Get the instruction instrumenting a callsite, or nullptr if that cannot be found.
PGOContextualProfile Result
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
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.
This represents the llvm.instrprof.increment 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.
const CtxProfFlatProfile flatten() const
A node (context) in the loaded contextual profile, suitable for mutation during IPO passes.
GlobalValue::GUID guid() const
const SmallVectorImpl< uint64_t > & counters() const
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 efficient, type-erasing, non-owning reference to a callable.
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))...))>
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
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...