1 //===-- AMDGPUAsmPrinter.h - Print AMDGPU assembly code ---------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 /// \brief AMDGPU Assembly printer class.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUASMPRINTER_H
16 #define LLVM_LIB_TARGET_AMDGPU_AMDGPUASMPRINTER_H
19 #include "AMDKernelCodeT.h"
20 #include "MCTargetDesc/AMDGPUHSAMetadataStreamer.h"
21 #include "llvm/ADT/StringRef.h"
22 #include "llvm/CodeGen/AsmPrinter.h"
32 class AMDGPUTargetStreamer;
36 class AMDGPUAsmPrinter final : public AsmPrinter {
38 // Track resource usage for callee functions.
39 struct SIFunctionResourceInfo {
40 // Track the number of explicitly used VGPRs. Special registers reserved at
41 // the end are tracked separately.
43 int32_t NumExplicitSGPR = 0;
44 uint64_t PrivateSegmentSize = 0;
46 bool UsesFlatScratch = false;
47 bool HasDynamicallySizedStack = false;
48 bool HasRecursion = false;
50 int32_t getTotalNumSGPRs(const SISubtarget &ST) const;
53 // Track resource usage for kernels / entry functions.
54 struct SIProgramInfo {
55 // Fields set in PGM_RSRC1 pm4 packet.
56 uint32_t VGPRBlocks = 0;
57 uint32_t SGPRBlocks = 0;
58 uint32_t Priority = 0;
59 uint32_t FloatMode = 0;
61 uint32_t DX10Clamp = 0;
62 uint32_t DebugMode = 0;
63 uint32_t IEEEMode = 0;
64 uint64_t ScratchSize = 0;
66 uint64_t ComputePGMRSrc1 = 0;
68 // Fields set in PGM_RSRC2 pm4 packet.
69 uint32_t LDSBlocks = 0;
70 uint32_t ScratchBlocks = 0;
72 uint64_t ComputePGMRSrc2 = 0;
77 bool FlatUsed = false;
79 // Number of SGPRs that meets number of waves per execution unit request.
80 uint32_t NumSGPRsForWavesPerEU = 0;
82 // Number of VGPRs that meets number of waves per execution unit request.
83 uint32_t NumVGPRsForWavesPerEU = 0;
85 // If ReservedVGPRCount is 0 then must be 0. Otherwise, this is the first
86 // fixed VGPR number reserved.
87 uint16_t ReservedVGPRFirst = 0;
89 // The number of consecutive VGPRs reserved.
90 uint16_t ReservedVGPRCount = 0;
92 // Fixed SGPR number used to hold wave scratch offset for entire kernel
93 // execution, or std::numeric_limits<uint16_t>::max() if the register is not
95 uint16_t DebuggerWavefrontPrivateSegmentOffsetSGPR =
96 std::numeric_limits<uint16_t>::max();
98 // Fixed SGPR number of the first 4 SGPRs used to hold scratch V# for entire
99 // kernel execution, or std::numeric_limits<uint16_t>::max() if the register
100 // is not used or not known.
101 uint16_t DebuggerPrivateSegmentBufferSGPR =
102 std::numeric_limits<uint16_t>::max();
104 // Whether there is recursion, dynamic allocas, indirect calls or some other
105 // reason there may be statically unknown stack usage.
106 bool DynamicCallStack = false;
108 // Bonus information for debugging.
109 bool VCCUsed = false;
111 SIProgramInfo() = default;
114 SIProgramInfo CurrentProgramInfo;
115 DenseMap<const Function *, SIFunctionResourceInfo> CallGraphResourceInfo;
117 AMDGPU::HSAMD::MetadataStreamer HSAMetadataStream;
118 std::map<uint32_t, uint32_t> PALMetadataMap;
120 uint64_t getFunctionCodeSize(const MachineFunction &MF) const;
121 SIFunctionResourceInfo analyzeResourceUsage(const MachineFunction &MF) const;
123 void readPALMetadata(Module &M);
124 void getSIProgramInfo(SIProgramInfo &Out, const MachineFunction &MF);
125 void getAmdKernelCode(amd_kernel_code_t &Out, const SIProgramInfo &KernelInfo,
126 const MachineFunction &MF) const;
127 void findNumUsedRegistersSI(const MachineFunction &MF,
129 unsigned &NumVGPR) const;
131 AMDGPU::HSAMD::Kernel::CodeProps::Metadata getHSACodeProps(
132 const MachineFunction &MF,
133 const SIProgramInfo &ProgramInfo) const;
134 AMDGPU::HSAMD::Kernel::DebugProps::Metadata getHSADebugProps(
135 const MachineFunction &MF,
136 const SIProgramInfo &ProgramInfo) const;
138 /// \brief Emit register usage information so that the GPU driver
139 /// can correctly setup the GPU state.
140 void EmitProgramInfoR600(const MachineFunction &MF);
141 void EmitProgramInfoSI(const MachineFunction &MF,
142 const SIProgramInfo &KernelInfo);
143 void EmitPALMetadata(const MachineFunction &MF,
144 const SIProgramInfo &KernelInfo);
145 void emitCommonFunctionComments(uint32_t NumVGPR,
147 uint64_t ScratchSize,
151 explicit AMDGPUAsmPrinter(TargetMachine &TM,
152 std::unique_ptr<MCStreamer> Streamer);
154 StringRef getPassName() const override;
156 const MCSubtargetInfo* getSTI() const;
158 AMDGPUTargetStreamer* getTargetStreamer() const;
160 bool doFinalization(Module &M) override;
161 bool runOnMachineFunction(MachineFunction &MF) override;
163 /// \brief Wrapper for MCInstLowering.lowerOperand() for the tblgen'erated
165 bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const;
167 /// \brief Lower the specified LLVM Constant to an MCExpr.
168 /// The AsmPrinter::lowerConstantof does not know how to lower
169 /// addrspacecast, therefore they should be lowered by this function.
170 const MCExpr *lowerConstant(const Constant *CV) override;
172 /// \brief tblgen'erated driver function for lowering simple MI->MC pseudo
174 bool emitPseudoExpansionLowering(MCStreamer &OutStreamer,
175 const MachineInstr *MI);
177 /// Implemented in AMDGPUMCInstLower.cpp
178 void EmitInstruction(const MachineInstr *MI) override;
180 void EmitFunctionBodyStart() override;
182 void EmitFunctionEntryLabel() override;
184 void EmitBasicBlockStart(const MachineBasicBlock &MBB) const override;
186 void EmitGlobalVariable(const GlobalVariable *GV) override;
188 void EmitStartOfAsmFile(Module &M) override;
190 void EmitEndOfAsmFile(Module &M) override;
192 bool isBlockOnlyReachableByFallthrough(
193 const MachineBasicBlock *MBB) const override;
195 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
196 unsigned AsmVariant, const char *ExtraCode,
197 raw_ostream &O) override;
200 mutable std::vector<std::string> DisasmLines, HexLines;
201 mutable size_t DisasmLineMaxLen;
205 } // end namespace llvm
207 #endif // LLVM_LIB_TARGET_AMDGPU_AMDGPUASMPRINTER_H