23#define DEBUG_TYPE "amdgpu-mc-resource-usage"
29 auto GOCS = [FuncName, &OutContext, IsLocal](
StringRef Suffix) {
37 return GOCS(
".num_vgpr");
39 return GOCS(
".num_agpr");
41 return GOCS(
".numbered_sgpr");
43 return GOCS(
".num_named_barrier");
45 return GOCS(
".private_seg_size");
47 return GOCS(
".uses_vcc");
49 return GOCS(
".uses_flat_scratch");
51 return GOCS(
".has_dyn_sized_stack");
53 return GOCS(
".has_recursion");
55 return GOCS(
".has_indirect_call");
66void MCResourceInfo::assignMaxRegs(
MCContext &OutContext) {
73 auto assignMaxRegSym = [&OutContext](
MCSymbol *
Sym, int32_t RegCount) {
75 Sym->setVariableValue(MaxExpr);
78 assignMaxRegSym(MaxVGPRSym, MaxVGPR);
79 assignMaxRegSym(MaxAGPRSym, MaxAGPR);
80 assignMaxRegSym(MaxSGPRSym, MaxSGPR);
81 assignMaxRegSym(MaxNamedBarrierSym, MaxNamedBarrier);
87 assert(!Finalized &&
"Cannot finalize ResourceInfo again.");
89 assignMaxRegs(OutContext);
116 ResourceInfoKind RIK,
125 while (!WorkList.
empty()) {
135 <<
": Recursion in unexpected sub-expression, using "
157 int64_t Val = cast<MCConstantExpr>(CurExpr)->getValue();
158 Maximum = std::max(Maximum, Val);
166 if (Seen.
insert(SymVal).second)
172 const AMDGPUMCExpr *TargetExpr = cast<AMDGPUMCExpr>(CurExpr);
174 for (
auto &Arg : TargetExpr->
getArgs())
183 <<
": Using flattened max: << " << Maximum <<
'\n');
188void MCResourceInfo::assignResourceInfoExpr(
197 const MCExpr *SymVal = LocalConstExpr;
200 << LocalValue <<
" as function local usage\n");
201 if (!Callees.
empty()) {
206 for (
const Function *Callee : Callees) {
207 if (!Seen.
insert(Callee).second)
210 bool IsCalleeLocal =
Callee->hasLocalLinkage();
221 << CalleeValSym->
getName() <<
" as callee\n");
225 <<
": Recursion found, attempt flattening of cycle "
226 "for resource usage\n");
236 ArgExprs.
push_back(flattenedCycleMax(CalleeValSym, RIK, OutContext));
245 if (ArgExprs.
size() > 1)
248 Sym->setVariableValue(SymVal);
272 LLVM_DEBUG(
dbgs() <<
"MCResUse: Gathering resource information for "
276 dbgs() <<
"MCResUse: Callees:\n";
277 for (const Function *Callee : FRI.Callees) {
278 MCSymbol *CalleeFnSym = TM.getSymbol(&Callee->getFunction());
279 dbgs() <<
"MCResUse: " << CalleeFnSym->getName() <<
'\n';
284 auto SetMaxReg = [&](
MCSymbol *MaxSym, int32_t numRegs,
285 ResourceInfoKind RIK) {
286 if (!FRI.HasIndirectCall) {
288 FRI.Callees, OutContext);
292 getSymbol(FnSym->
getName(), RIK, OutContext, IsLocal);
297 <<
": Indirect callee within, using module maximum\n");
302 SetMaxReg(MaxVGPRSym, FRI.NumVGPR, RIK_NumVGPR);
303 SetMaxReg(MaxAGPRSym, FRI.NumAGPR, RIK_NumAGPR);
304 SetMaxReg(MaxSGPRSym, FRI.NumExplicitSGPR, RIK_NumSGPR);
305 SetMaxReg(MaxNamedBarrierSym, FRI.NumNamedBarrier, RIK_NumNamedBarrier);
312 getSymbol(FnSym->
getName(), RIK_PrivateSegSize, OutContext, IsLocal);
313 if (FRI.CalleeSegmentSize) {
315 << FRI.CalleeSegmentSize
316 <<
" for indirect/recursive callees within\n");
323 for (
const Function *Callee : FRI.Callees) {
324 if (!Seen.
insert(Callee).second)
326 if (!
Callee->isDeclaration()) {
327 bool IsCalleeLocal =
Callee->hasLocalLinkage();
330 getSymbol(CalleeFnSym->
getName(), RIK_PrivateSegSize, OutContext,
339 << CalleeValSym->
getName() <<
" as callee\n");
344 const MCExpr *localConstExpr =
347 << FRI.PrivateSegmentSize
348 <<
" as function local usage\n");
349 if (!ArgExprs.
empty()) {
355 Sym->setVariableValue(localConstExpr);
358 auto SetToLocal = [&](int64_t LocalValue, ResourceInfoKind RIK) {
361 dbgs() <<
"MCResUse: " <<
Sym->getName() <<
": Adding " << LocalValue
362 <<
", no further propagation as indirect callee found within\n");
366 if (!FRI.HasIndirectCall) {
367 assignResourceInfoExpr(FRI.UsesVCC, ResourceInfoKind::RIK_UsesVCC,
369 assignResourceInfoExpr(FRI.UsesFlatScratch,
370 ResourceInfoKind::RIK_UsesFlatScratch,
372 assignResourceInfoExpr(FRI.HasDynamicallySizedStack,
373 ResourceInfoKind::RIK_HasDynSizedStack,
375 assignResourceInfoExpr(FRI.HasRecursion, ResourceInfoKind::RIK_HasRecursion,
377 assignResourceInfoExpr(FRI.HasIndirectCall,
378 ResourceInfoKind::RIK_HasIndirectCall,
381 SetToLocal(FRI.UsesVCC, ResourceInfoKind::RIK_UsesVCC);
382 SetToLocal(FRI.UsesFlatScratch, ResourceInfoKind::RIK_UsesFlatScratch);
383 SetToLocal(FRI.HasDynamicallySizedStack,
384 ResourceInfoKind::RIK_HasDynSizedStack);
385 SetToLocal(FRI.HasRecursion, ResourceInfoKind::RIK_HasRecursion);
386 SetToLocal(FRI.HasIndirectCall, ResourceInfoKind::RIK_HasIndirectCall);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MC infrastructure to propagate the function level resource usage info.
AMDGPU target specific MCExpr operations.
ArrayRef< const MCExpr * > getArgs() const
static const AMDGPUMCExpr * createMax(ArrayRef< const MCExpr * > Args, MCContext &Ctx)
static const AMDGPUMCExpr * createTotalNumVGPR(const MCExpr *NumAGPR, const MCExpr *NumVGPR, MCContext &Ctx)
static const AMDGPUMCExpr * create(VariantKind Kind, ArrayRef< const MCExpr * > Args, MCContext &Ctx)
static const AMDGPUMCExpr * createExtraSGPRs(const MCExpr *VCCUsed, const MCExpr *FlatScrUsed, bool XNACKUsed, MCContext &Ctx)
Allow delayed MCExpr resolve of ExtraSGPRs (in case VCCUsed or FlatScrUsed are unresolvable but neede...
VariantKind getKind() const
static bool isSymbolUsedInExpression(const MCSymbol *Sym, const MCExpr *E)
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
bool hasLocalLinkage() const
StringRef getPrivateGlobalPrefix() const
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
const MCAsmInfo * getAsmInfo() const
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Base class for the full range of assembler expressions which are needed for parsing.
@ Constant
Constant expressions.
@ SymbolRef
References to labels and assigned expressions.
@ Target
Target specific expression.
MCSymbol * getMaxNamedBarrierSymbol(MCContext &OutContext)
void addMaxSGPRCandidate(int32_t candidate)
MCSymbol * getMaxSGPRSymbol(MCContext &OutContext)
const MCExpr * getSymRefExpr(StringRef FuncName, ResourceInfoKind RIK, MCContext &Ctx, bool IsLocal)
void addMaxNamedBarrierCandidate(int32_t candidate)
MCSymbol * getMaxAGPRSymbol(MCContext &OutContext)
const MCExpr * createTotalNumVGPRs(const MachineFunction &MF, MCContext &Ctx)
void finalize(MCContext &OutContext)
MCSymbol * getSymbol(StringRef FuncName, ResourceInfoKind RIK, MCContext &OutContext, bool IsLocal)
void addMaxAGPRCandidate(int32_t candidate)
MCSymbol * getMaxVGPRSymbol(MCContext &OutContext)
const MCExpr * createTotalNumSGPRs(const MachineFunction &MF, bool hasXnack, MCContext &Ctx)
void addMaxVGPRCandidate(int32_t candidate)
void gatherResourceInfo(const MachineFunction &MF, const AMDGPUResourceUsageAnalysisWrapperPass::FunctionResourceInfo &FRI, MCContext &OutContext)
AMDGPUResourceUsageAnalysis gathers resource usage on a per-function granularity.
Represent a reference to a symbol from inside an expression.
const MCSymbol & getSymbol() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
StringRef getName() const
getName - Get the symbol name.
bool isVariable() const
isVariable - Check if this is a variable symbol.
LLVM_ABI void setVariableValue(const MCExpr *Value)
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
Function & getFunction()
Return the LLVM function that this machine code represents.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Primary interface to the complete machine description for the target machine.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_READNONE constexpr bool isEntryFunctionCC(CallingConv::ID CC)
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
SmallVector< const Function *, 16 > Callees