1 //===-- AMDGPUAsmPrinter.h - Print AMDGPU assembly code ---------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 /// \file 11 /// AMDGPU Assembly printer class. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUASMPRINTER_H 16 #define LLVM_LIB_TARGET_AMDGPU_AMDGPUASMPRINTER_H 17 18 #include "AMDGPU.h" 19 #include "AMDKernelCodeT.h" 20 #include "MCTargetDesc/AMDGPUHSAMetadataStreamer.h" 21 #include "llvm/ADT/StringRef.h" 22 #include "llvm/CodeGen/AsmPrinter.h" 23 #include "llvm/Support/AMDHSAKernelDescriptor.h" 24 #include <cstddef> 25 #include <cstdint> 26 #include <limits> 27 #include <memory> 28 #include <string> 29 #include <vector> 30 31 namespace llvm { 32 33 class AMDGPUMachineFunction; 34 class AMDGPUTargetStreamer; 35 class MCOperand; 36 class SISubtarget; 37 38 class AMDGPUAsmPrinter final : public AsmPrinter { 39 private: 40 // Track resource usage for callee functions. 41 struct SIFunctionResourceInfo { 42 // Track the number of explicitly used VGPRs. Special registers reserved at 43 // the end are tracked separately. 44 int32_t NumVGPR = 0; 45 int32_t NumExplicitSGPR = 0; 46 uint64_t PrivateSegmentSize = 0; 47 bool UsesVCC = false; 48 bool UsesFlatScratch = false; 49 bool HasDynamicallySizedStack = false; 50 bool HasRecursion = false; 51 52 int32_t getTotalNumSGPRs(const SISubtarget &ST) const; 53 }; 54 55 // Track resource usage for kernels / entry functions. 56 struct SIProgramInfo { 57 // Fields set in PGM_RSRC1 pm4 packet. 58 uint32_t VGPRBlocks = 0; 59 uint32_t SGPRBlocks = 0; 60 uint32_t Priority = 0; 61 uint32_t FloatMode = 0; 62 uint32_t Priv = 0; 63 uint32_t DX10Clamp = 0; 64 uint32_t DebugMode = 0; 65 uint32_t IEEEMode = 0; 66 uint64_t ScratchSize = 0; 67 68 uint64_t ComputePGMRSrc1 = 0; 69 70 // Fields set in PGM_RSRC2 pm4 packet. 71 uint32_t LDSBlocks = 0; 72 uint32_t ScratchBlocks = 0; 73 74 uint64_t ComputePGMRSrc2 = 0; 75 76 uint32_t NumVGPR = 0; 77 uint32_t NumSGPR = 0; 78 uint32_t LDSSize = 0; 79 bool FlatUsed = false; 80 81 // Number of SGPRs that meets number of waves per execution unit request. 82 uint32_t NumSGPRsForWavesPerEU = 0; 83 84 // Number of VGPRs that meets number of waves per execution unit request. 85 uint32_t NumVGPRsForWavesPerEU = 0; 86 87 // Fixed SGPR number used to hold wave scratch offset for entire kernel 88 // execution, or std::numeric_limits<uint16_t>::max() if the register is not 89 // used or not known. 90 uint16_t DebuggerWavefrontPrivateSegmentOffsetSGPR = 91 std::numeric_limits<uint16_t>::max(); 92 93 // Fixed SGPR number of the first 4 SGPRs used to hold scratch V# for entire 94 // kernel execution, or std::numeric_limits<uint16_t>::max() if the register 95 // is not used or not known. 96 uint16_t DebuggerPrivateSegmentBufferSGPR = 97 std::numeric_limits<uint16_t>::max(); 98 99 // Whether there is recursion, dynamic allocas, indirect calls or some other 100 // reason there may be statically unknown stack usage. 101 bool DynamicCallStack = false; 102 103 // Bonus information for debugging. 104 bool VCCUsed = false; 105 106 SIProgramInfo() = default; 107 }; 108 109 SIProgramInfo CurrentProgramInfo; 110 DenseMap<const Function *, SIFunctionResourceInfo> CallGraphResourceInfo; 111 112 AMDGPU::HSAMD::MetadataStreamer HSAMetadataStream; 113 std::map<uint32_t, uint32_t> PALMetadataMap; 114 115 uint64_t getFunctionCodeSize(const MachineFunction &MF) const; 116 SIFunctionResourceInfo analyzeResourceUsage(const MachineFunction &MF) const; 117 118 void readPALMetadata(Module &M); 119 void getSIProgramInfo(SIProgramInfo &Out, const MachineFunction &MF); 120 void getAmdKernelCode(amd_kernel_code_t &Out, const SIProgramInfo &KernelInfo, 121 const MachineFunction &MF) const; 122 void findNumUsedRegistersSI(const MachineFunction &MF, 123 unsigned &NumSGPR, 124 unsigned &NumVGPR) const; 125 126 AMDGPU::HSAMD::Kernel::CodeProps::Metadata getHSACodeProps( 127 const MachineFunction &MF, 128 const SIProgramInfo &ProgramInfo) const; 129 AMDGPU::HSAMD::Kernel::DebugProps::Metadata getHSADebugProps( 130 const MachineFunction &MF, 131 const SIProgramInfo &ProgramInfo) const; 132 133 /// Emit register usage information so that the GPU driver 134 /// can correctly setup the GPU state. 135 void EmitProgramInfoSI(const MachineFunction &MF, 136 const SIProgramInfo &KernelInfo); 137 void EmitPALMetadata(const MachineFunction &MF, 138 const SIProgramInfo &KernelInfo); 139 void emitCommonFunctionComments(uint32_t NumVGPR, 140 uint32_t NumSGPR, 141 uint64_t ScratchSize, 142 uint64_t CodeSize, 143 const AMDGPUMachineFunction* MFI); 144 145 uint16_t getAmdhsaKernelCodeProperties( 146 const MachineFunction &MF) const; 147 148 amdhsa::kernel_descriptor_t getAmdhsaKernelDescriptor( 149 const MachineFunction &MF, 150 const SIProgramInfo &PI) const; 151 152 public: 153 explicit AMDGPUAsmPrinter(TargetMachine &TM, 154 std::unique_ptr<MCStreamer> Streamer); 155 156 StringRef getPassName() const override; 157 158 const MCSubtargetInfo* getSTI() const; 159 160 AMDGPUTargetStreamer* getTargetStreamer() const; 161 162 bool doFinalization(Module &M) override; 163 bool runOnMachineFunction(MachineFunction &MF) override; 164 165 /// Wrapper for MCInstLowering.lowerOperand() for the tblgen'erated 166 /// pseudo lowering. 167 bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const; 168 169 /// Lower the specified LLVM Constant to an MCExpr. 170 /// The AsmPrinter::lowerConstantof does not know how to lower 171 /// addrspacecast, therefore they should be lowered by this function. 172 const MCExpr *lowerConstant(const Constant *CV) override; 173 174 /// tblgen'erated driver function for lowering simple MI->MC pseudo 175 /// instructions. 176 bool emitPseudoExpansionLowering(MCStreamer &OutStreamer, 177 const MachineInstr *MI); 178 179 /// Implemented in AMDGPUMCInstLower.cpp 180 void EmitInstruction(const MachineInstr *MI) override; 181 182 void EmitFunctionBodyStart() override; 183 184 void EmitFunctionBodyEnd() override; 185 186 void EmitFunctionEntryLabel() override; 187 188 void EmitBasicBlockStart(const MachineBasicBlock &MBB) const override; 189 190 void EmitGlobalVariable(const GlobalVariable *GV) override; 191 192 void EmitStartOfAsmFile(Module &M) override; 193 194 void EmitEndOfAsmFile(Module &M) override; 195 196 bool isBlockOnlyReachableByFallthrough( 197 const MachineBasicBlock *MBB) const override; 198 199 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 200 unsigned AsmVariant, const char *ExtraCode, 201 raw_ostream &O) override; 202 203 protected: 204 mutable std::vector<std::string> DisasmLines, HexLines; 205 mutable size_t DisasmLineMaxLen; 206 AMDGPUAS AMDGPUASI; 207 }; 208 209 } // end namespace llvm 210 211 #endif // LLVM_LIB_TARGET_AMDGPU_AMDGPUASMPRINTER_H 212