blob: e5adeeb465e12631032cc66b7e12b5838c8f1fa6 [file] [log] [blame]
Matt Arsenaultd82c1832013-11-10 01:03:59 +00001//===-- AMDGPUAsmPrinter.h - Print AMDGPU assembly code ---------*- C++ -*-===//
Tom Stellard75aadc22012-12-11 21:25:42 +00002//
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/// \brief AMDGPU Assembly printer class.
12//
13//===----------------------------------------------------------------------===//
14
Matt Arsenault6b6a2c32016-03-11 08:00:27 +000015#ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUASMPRINTER_H
16#define LLVM_LIB_TARGET_AMDGPU_AMDGPUASMPRINTER_H
Tom Stellard75aadc22012-12-11 21:25:42 +000017
Konstantin Zhuravlyovca0e7f62017-03-22 22:54:39 +000018#include "AMDKernelCodeT.h"
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000019#include "AMDGPU.h"
Eugene Zelenko734bb7b2017-01-20 17:52:16 +000020#include "llvm/ADT/StringRef.h"
Tom Stellard75aadc22012-12-11 21:25:42 +000021#include "llvm/CodeGen/AsmPrinter.h"
Eugene Zelenko734bb7b2017-01-20 17:52:16 +000022#include <cstddef>
23#include <cstdint>
24#include <limits>
25#include <memory>
26#include <string>
Tom Stellarded699252013-10-12 05:02:51 +000027#include <vector>
Tom Stellard75aadc22012-12-11 21:25:42 +000028
29namespace llvm {
Eugene Zelenko734bb7b2017-01-20 17:52:16 +000030
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000031class AMDGPUTargetStreamer;
Matt Arsenault11f74022016-10-06 17:19:11 +000032class MCOperand;
Matt Arsenaultb03dd8d2017-05-02 17:14:00 +000033class SISubtarget;
Tom Stellard75aadc22012-12-11 21:25:42 +000034
Matt Arsenault6b6a2c32016-03-11 08:00:27 +000035class AMDGPUAsmPrinter final : public AsmPrinter {
Matt Arsenault89cc49f2013-12-05 05:15:35 +000036private:
Matt Arsenaultb03dd8d2017-05-02 17:14:00 +000037 // Track resource usage for callee functions.
38 struct SIFunctionResourceInfo {
39 // Track the number of explicitly used VGPRs. Special registers reserved at
40 // the end are tracked separately.
41 int32_t NumVGPR = 0;
42 int32_t NumExplicitSGPR = 0;
43 uint32_t PrivateSegmentSize = 0;
44 bool UsesVCC = false;
45 bool UsesFlatScratch = false;
46 bool HasDynamicallySizedStack = false;
47 bool HasRecursion = false;
48
49 int32_t getTotalNumSGPRs(const SISubtarget &ST) const;
50 };
51
52 // Track resource usage for kernels / entry functions.
Matt Arsenault89cc49f2013-12-05 05:15:35 +000053 struct SIProgramInfo {
Matt Arsenault0989d512014-06-26 17:22:30 +000054 // Fields set in PGM_RSRC1 pm4 packet.
Eugene Zelenko734bb7b2017-01-20 17:52:16 +000055 uint32_t VGPRBlocks = 0;
56 uint32_t SGPRBlocks = 0;
57 uint32_t Priority = 0;
58 uint32_t FloatMode = 0;
59 uint32_t Priv = 0;
60 uint32_t DX10Clamp = 0;
61 uint32_t DebugMode = 0;
62 uint32_t IEEEMode = 0;
63 uint32_t ScratchSize = 0;
Matt Arsenault0989d512014-06-26 17:22:30 +000064
Eugene Zelenko734bb7b2017-01-20 17:52:16 +000065 uint64_t ComputePGMRSrc1 = 0;
Tom Stellard4df465b2014-12-02 21:28:53 +000066
67 // Fields set in PGM_RSRC2 pm4 packet.
Eugene Zelenko734bb7b2017-01-20 17:52:16 +000068 uint32_t LDSBlocks = 0;
69 uint32_t ScratchBlocks = 0;
Tom Stellard4df465b2014-12-02 21:28:53 +000070
Eugene Zelenko734bb7b2017-01-20 17:52:16 +000071 uint64_t ComputePGMRSrc2 = 0;
Tom Stellard4df465b2014-12-02 21:28:53 +000072
Eugene Zelenko734bb7b2017-01-20 17:52:16 +000073 uint32_t NumVGPR = 0;
74 uint32_t NumSGPR = 0;
Matt Arsenaulta3566f22017-04-17 19:48:30 +000075 uint32_t LDSSize = 0;
Eugene Zelenko734bb7b2017-01-20 17:52:16 +000076 bool FlatUsed = false;
Matt Arsenault3f981402014-09-15 15:41:53 +000077
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +000078 // Number of SGPRs that meets number of waves per execution unit request.
Eugene Zelenko734bb7b2017-01-20 17:52:16 +000079 uint32_t NumSGPRsForWavesPerEU = 0;
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +000080
81 // Number of VGPRs that meets number of waves per execution unit request.
Eugene Zelenko734bb7b2017-01-20 17:52:16 +000082 uint32_t NumVGPRsForWavesPerEU = 0;
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +000083
Konstantin Zhuravlyov71515e52016-04-26 17:24:40 +000084 // If ReservedVGPRCount is 0 then must be 0. Otherwise, this is the first
85 // fixed VGPR number reserved.
Eugene Zelenko734bb7b2017-01-20 17:52:16 +000086 uint16_t ReservedVGPRFirst = 0;
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +000087
Konstantin Zhuravlyov71515e52016-04-26 17:24:40 +000088 // The number of consecutive VGPRs reserved.
Eugene Zelenko734bb7b2017-01-20 17:52:16 +000089 uint16_t ReservedVGPRCount = 0;
Konstantin Zhuravlyov1d99c4d2016-04-26 15:43:14 +000090
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +000091 // Fixed SGPR number used to hold wave scratch offset for entire kernel
Eugene Zelenkoa63528c2017-01-23 23:41:16 +000092 // execution, or std::numeric_limits<uint16_t>::max() if the register is not
93 // used or not known.
Eugene Zelenko734bb7b2017-01-20 17:52:16 +000094 uint16_t DebuggerWavefrontPrivateSegmentOffsetSGPR =
95 std::numeric_limits<uint16_t>::max();
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +000096
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +000097 // Fixed SGPR number of the first 4 SGPRs used to hold scratch V# for entire
Eugene Zelenkoa63528c2017-01-23 23:41:16 +000098 // kernel execution, or std::numeric_limits<uint16_t>::max() if the register
99 // is not used or not known.
Eugene Zelenko734bb7b2017-01-20 17:52:16 +0000100 uint16_t DebuggerPrivateSegmentBufferSGPR =
101 std::numeric_limits<uint16_t>::max();
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000102
Matt Arsenaultb03dd8d2017-05-02 17:14:00 +0000103 // Whether there is recursion, dynamic allocas, indirect calls or some other
104 // reason there may be statically unknown stack usage.
105 bool DynamicCallStack = false;
106
Matt Arsenault0989d512014-06-26 17:22:30 +0000107 // Bonus information for debugging.
Eugene Zelenko734bb7b2017-01-20 17:52:16 +0000108 bool VCCUsed = false;
Eugene Zelenko734bb7b2017-01-20 17:52:16 +0000109
110 SIProgramInfo() = default;
Matt Arsenault89cc49f2013-12-05 05:15:35 +0000111 };
112
Matt Arsenaultb03dd8d2017-05-02 17:14:00 +0000113 SIProgramInfo CurrentProgramInfo;
114 DenseMap<const Function *, SIFunctionResourceInfo> CallGraphResourceInfo;
115
Matt Arsenaulta3566f22017-04-17 19:48:30 +0000116 uint64_t getFunctionCodeSize(const MachineFunction &MF) const;
Matt Arsenaultb03dd8d2017-05-02 17:14:00 +0000117 SIFunctionResourceInfo analyzeResourceUsage(const MachineFunction &MF) const;
118
119 void getSIProgramInfo(SIProgramInfo &Out, const MachineFunction &MF);
Konstantin Zhuravlyovca0e7f62017-03-22 22:54:39 +0000120 void getAmdKernelCode(amd_kernel_code_t &Out, const SIProgramInfo &KernelInfo,
121 const MachineFunction &MF) const;
Matt Arsenaultd32dbb62014-07-13 03:06:43 +0000122 void findNumUsedRegistersSI(const MachineFunction &MF,
Matt Arsenault89cc49f2013-12-05 05:15:35 +0000123 unsigned &NumSGPR,
124 unsigned &NumVGPR) const;
125
126 /// \brief Emit register usage information so that the GPU driver
127 /// can correctly setup the GPU state.
Matt Arsenaultd32dbb62014-07-13 03:06:43 +0000128 void EmitProgramInfoR600(const MachineFunction &MF);
129 void EmitProgramInfoSI(const MachineFunction &MF, const SIProgramInfo &KernelInfo);
Matt Arsenaultb03dd8d2017-05-02 17:14:00 +0000130 void emitCommonFunctionComments(uint32_t NumVGPR,
131 uint32_t NumSGPR,
132 uint32_t ScratchSize,
133 uint64_t CodeSize);
Tom Stellard75aadc22012-12-11 21:25:42 +0000134
135public:
David Blaikie94598322015-01-18 20:29:04 +0000136 explicit AMDGPUAsmPrinter(TargetMachine &TM,
137 std::unique_ptr<MCStreamer> Streamer);
Tom Stellard75aadc22012-12-11 21:25:42 +0000138
Mehdi Amini117296c2016-10-01 02:56:57 +0000139 StringRef getPassName() const override;
Tom Stellard75aadc22012-12-11 21:25:42 +0000140
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000141 const MCSubtargetInfo* getSTI() const;
142
143 AMDGPUTargetStreamer& getTargetStreamer() const;
144
Matt Arsenaultb03dd8d2017-05-02 17:14:00 +0000145 bool doFinalization(Module &M) override;
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000146 bool runOnMachineFunction(MachineFunction &MF) override;
147
Matt Arsenault11f74022016-10-06 17:19:11 +0000148 /// \brief Wrapper for MCInstLowering.lowerOperand() for the tblgen'erated
149 /// pseudo lowering.
150 bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const;
151
Yaxun Liu8f844f32017-02-07 00:43:21 +0000152 /// \brief Lower the specified LLVM Constant to an MCExpr.
153 /// The AsmPrinter::lowerConstantof does not know how to lower
154 /// addrspacecast, therefore they should be lowered by this function.
155 const MCExpr *lowerConstant(const Constant *CV) override;
156
Matt Arsenault11f74022016-10-06 17:19:11 +0000157 /// \brief tblgen'erated driver function for lowering simple MI->MC pseudo
158 /// instructions.
159 bool emitPseudoExpansionLowering(MCStreamer &OutStreamer,
160 const MachineInstr *MI);
161
Tom Stellard75aadc22012-12-11 21:25:42 +0000162 /// Implemented in AMDGPUMCInstLower.cpp
Craig Topper5656db42014-04-29 07:57:24 +0000163 void EmitInstruction(const MachineInstr *MI) override;
Tom Stellarded699252013-10-12 05:02:51 +0000164
Tom Stellardf151a452015-06-26 21:14:58 +0000165 void EmitFunctionBodyStart() override;
166
Tom Stellard1e1b05d2015-11-06 11:45:14 +0000167 void EmitFunctionEntryLabel() override;
168
Tom Stellarde3b5aea2015-12-02 17:00:42 +0000169 void EmitGlobalVariable(const GlobalVariable *GV) override;
170
Tom Stellardf4218372016-01-12 17:18:17 +0000171 void EmitStartOfAsmFile(Module &M) override;
172
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000173 void EmitEndOfAsmFile(Module &M) override;
174
Matt Arsenault6bc43d82016-10-06 16:20:41 +0000175 bool isBlockOnlyReachableByFallthrough(
176 const MachineBasicBlock *MBB) const override;
177
Tom Stellardd7e6f132015-04-08 01:09:26 +0000178 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
179 unsigned AsmVariant, const char *ExtraCode,
Tom Stellard80e169a2015-04-08 02:07:05 +0000180 raw_ostream &O) override;
Tom Stellardd7e6f132015-04-08 01:09:26 +0000181
Tom Stellarded699252013-10-12 05:02:51 +0000182protected:
Tom Stellarded699252013-10-12 05:02:51 +0000183 std::vector<std::string> DisasmLines, HexLines;
184 size_t DisasmLineMaxLen;
Yaxun Liu1a14bfa2017-03-27 14:04:01 +0000185 AMDGPUAS AMDGPUASI;
Tom Stellard75aadc22012-12-11 21:25:42 +0000186};
187
Eugene Zelenko734bb7b2017-01-20 17:52:16 +0000188} // end namespace llvm
Tom Stellard75aadc22012-12-11 21:25:42 +0000189
Eugene Zelenko734bb7b2017-01-20 17:52:16 +0000190#endif // LLVM_LIB_TARGET_AMDGPU_AMDGPUASMPRINTER_H