32#define DEBUG_TYPE "amdgpu-resource-usage"
39 "Function register usage analysis",
true,
true)
43 assert(Op.getImm() == 0);
52 if (!UseOp.isImplicit() || !
TII.isFLAT(*UseOp.getParent()))
70 const AMDGPUOptions &CLOpts = TM.getCLOpts();
74 uint32_t AssumedStackSizeForDynamicSizeObjects =
75 CLOpts.assume_dynamic_stack_object_size.value_or(MinScratch ? 0 : 4096);
76 uint32_t AssumedStackSizeForExternalCall =
77 CLOpts.assume_external_call_stack_size.value_or(MinScratch ? 0 : 16384);
80 MF, AssumedStackSizeForDynamicSizeObjects,
81 AssumedStackSizeForExternalCall);
94 const AMDGPUOptions &CLOpts = TM.getCLOpts();
98 uint32_t AssumedStackSizeForDynamicSizeObjects =
99 CLOpts.assume_dynamic_stack_object_size.value_or(MinScratch ? 0 : 4096);
100 uint32_t AssumedStackSizeForExternalCall =
101 CLOpts.assume_external_call_stack_size.value_or(MinScratch ? 0 : 16384);
104 MF, AssumedStackSizeForDynamicSizeObjects,
105 AssumedStackSizeForExternalCall);
111 uint32_t AssumedStackSizeForExternalCall)
const {
121 Info.UsesFlatScratch =
MRI.isPhysRegUsed(AMDGPU::FLAT_SCR_LO) ||
122 MRI.isPhysRegUsed(AMDGPU::FLAT_SCR_HI) ||
138 Info.UsesFlatScratch =
false;
141 Info.PrivateSegmentSize = FrameInfo.getStackSize();
144 Info.HasDynamicallySizedStack = FrameInfo.hasVarSizedObjects();
145 if (Info.HasDynamicallySizedStack)
146 Info.PrivateSegmentSize += AssumedStackSizeForDynamicSizeObjects;
149 Info.PrivateSegmentSize += FrameInfo.getMaxAlign().value();
152 MRI.isPhysRegUsed(AMDGPU::VCC_LO) ||
MRI.isPhysRegUsed(AMDGPU::VCC_HI);
153 Info.NumExplicitSGPR =
TRI.getNumUsedPhysRegs(
MRI, AMDGPU::SGPR_32RegClass,
155 if (ST.hasMAIInsts())
156 Info.NumAGPR =
TRI.getNumUsedPhysRegs(
MRI, AMDGPU::AGPR_32RegClass,
162 if (!FrameInfo.hasCalls() && !FrameInfo.hasTailCall()) {
163 Info.NumVGPR =
TRI.getNumUsedPhysRegs(
MRI, AMDGPU::VGPR_32RegClass,
168 int32_t MaxVGPR = -1;
169 Info.CalleeSegmentSize = 0;
173 for (
unsigned I = 0;
I <
MI.getNumOperands(); ++
I) {
181 case AMDGPU::NoRegister:
183 "Instruction uses invalid noreg register");
186 case AMDGPU::XNACK_MASK:
187 case AMDGPU::XNACK_MASK_LO:
188 case AMDGPU::XNACK_MASK_HI:
191 case AMDGPU::LDS_DIRECT:
202 case AMDGPU::SRC_VCCZ:
205 case AMDGPU::SRC_EXECZ:
208 case AMDGPU::SRC_SCC:
216 assert((!RC ||
TRI.isVGPRClass(RC) ||
TRI.isSGPRClass(RC) ||
217 TRI.isAGPRClass(RC) || AMDGPU::TTMP_32RegClass.contains(Reg) ||
218 AMDGPU::TTMP_64RegClass.contains(Reg) ||
219 AMDGPU::TTMP_128RegClass.contains(Reg) ||
220 AMDGPU::TTMP_256RegClass.contains(Reg) ||
221 AMDGPU::TTMP_512RegClass.contains(Reg)) &&
222 "Unknown register class");
224 if (!RC || !
TRI.isVGPRClass(RC))
227 if (
MI.isCall() ||
MI.isMetaInstruction())
231 unsigned HWReg =
TRI.getHWRegIndex(Reg);
232 int MaxUsed = HWReg + Width - 1;
233 MaxVGPR = std::max(MaxUsed, MaxVGPR);
243 TII->getNamedOperand(
MI, AMDGPU::OpName::callee);
246 CalleeOp ? getCalleeFunction(*CalleeOp) :
nullptr;
252 if (Callee && !isSameFunction(MF, Callee))
253 Info.Callees.push_back(Callee);
255 bool IsIndirect = !Callee || Callee->isDeclaration();
256 Info.HasIndirectCall |= IsIndirect;
258 bool IsChainCall =
MI.getOpcode() == AMDGPU::SI_TCRETURN_CHAIN;
259 Info.HasNonChainIndirectCall |= (!IsChainCall && IsIndirect);
270 if (!Callee || !Callee->doesNotRecurse()) {
271 Info.HasRecursion =
true;
275 if (!
MI.isReturn()) {
282 Info.CalleeSegmentSize = std::max(
283 Info.CalleeSegmentSize,
284 static_cast<uint64_t
>(AssumedStackSizeForExternalCall));
289 Info.CalleeSegmentSize =
290 std::max(Info.CalleeSegmentSize,
291 static_cast<uint64_t
>(AssumedStackSizeForExternalCall));
295 Info.UsesFlatScratch = ST.hasFlatAddressSpace();
296 Info.HasDynamicallySizedStack =
true;
302 Info.NumVGPR = MaxVGPR + 1;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool hasAnyNonFlatUseOfReg(const MachineRegisterInfo &MRI, const SIInstrInfo &TII, unsigned Reg)
Analyzes how many registers and other resources are used by functions.
The AMDGPU TargetMachine interface definition for hw codegen targets.
AMD GCN specific subclass of TargetSubtarget.
const HexagonInstrInfo * TII
Register const TargetRegisterInfo * TRI
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
MachineRegisterInfo & MRI
Target-Independent Code Generator Pass Configuration Options pass.
uint32_t getNumNamedBarriers() const
Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
AMDGPUResourceUsageAnalysisImpl::SIFunctionResourceInfo Result
static bool EnableObjectLinking
bool hasFlatScratchInit() const
Module * getParent()
Get the module that this global value is contained inside of...
Generic base class for all target subtargets.
const Triple & getTargetTriple() const
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
AnalysisType * getAnalysisIfAvailable() const
getAnalysisIfAvailable<AnalysisType>() - Subclasses use this function to get analysis information tha...
Wrapper class representing virtual and physical registers.
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
GCNUserSGPRUsageInfo & getUserSGPRInfo()
bool isStackRealigned() const
MCRegister getPreloadedReg(AMDGPUFunctionArgInfo::PreloadedValue Value) const
OSType getOS() const
Get the parsed operating system type of this triple.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned getAMDHSACodeObjectVersion(const Module &M)
This is an optimization pass for GlobalISel generic memory operations.
char & AMDGPUResourceUsageAnalysisID
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
MCRegisterClass TargetRegisterClass
SIFunctionResourceInfo analyzeResourceUsage(const MachineFunction &MF, uint32_t AssumedStackSizeForDynamicSizeObjects, uint32_t AssumedStackSizeForExternalCall) const
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
FunctionResourceInfo ResourceInfo
A special type used by analysis passes to provide an address that identifies that particular analysis...