LLVM 20.0.0git
AMDGPUMIRFormatter.cpp
Go to the documentation of this file.
1//===- AMDGPUMIRFormatter.cpp ---------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9/// \file
10/// Implementation of AMDGPU overrides of MIRFormatter.
11//
12//===----------------------------------------------------------------------===//
13
14#include "AMDGPUMIRFormatter.h"
15#include "GCNSubtarget.h"
17
18using namespace llvm;
19
21 std::optional<unsigned int> OpIdx, int64_t Imm) const {
22
23 switch (MI.getOpcode()) {
24 case AMDGPU::S_DELAY_ALU:
25 assert(OpIdx == 0);
26 printSDelayAluImm(Imm, OS);
27 break;
28 default:
29 MIRFormatter::printImm(OS, MI, OpIdx, Imm);
30 break;
31 }
32}
33
34/// Implement target specific parsing of immediate mnemonics. The mnemonic is
35/// a string with a leading dot.
36bool AMDGPUMIRFormatter::parseImmMnemonic(const unsigned OpCode,
37 const unsigned OpIdx,
38 StringRef Src, int64_t &Imm,
39 ErrorCallbackType ErrorCallback) const
40{
41
42 switch (OpCode) {
43 case AMDGPU::S_DELAY_ALU:
44 return parseSDelayAluImmMnemonic(OpIdx, Imm, Src, ErrorCallback);
45 default:
46 break;
47 }
48 return true; // Don't know what this is
49}
50
51void AMDGPUMIRFormatter::printSDelayAluImm(int64_t Imm,
52 llvm::raw_ostream &OS) const {
53 // Construct an immediate string to represent the information encoded in the
54 // s_delay_alu immediate.
55 // .id0_<dep>[_skip_<count>_id1<dep>]
56 constexpr int64_t None = 0;
57 constexpr int64_t Same = 0;
58
59 uint64_t Id0 = (Imm & 0xF);
60 uint64_t Skip = ((Imm >> 4) & 0x7);
61 uint64_t Id1 = ((Imm >> 7) & 0xF);
62 auto Outdep = [&](uint64_t Id) {
63 if (Id == None)
64 OS << "NONE";
65 else if (Id < 5)
66 OS << "VALU_DEP_" << Id;
67 else if (Id < 8)
68 OS << "TRANS32_DEP_" << Id - 4;
69 else
70 OS << "SALU_CYCLE_" << Id - 8;
71 };
72
73 OS << ".id0_";
74 Outdep(Id0);
75
76 // If the second inst is "same" and "none", no need to print the rest of the
77 // string.
78 if (Skip == Same && Id1 == None)
79 return;
80
81 // Encode the second delay specification.
82 OS << "_skip_";
83 if (Skip == 0)
84 OS << "SAME";
85 else if (Skip == 1)
86 OS << "NEXT";
87 else
88 OS << "SKIP_" << Skip - 1;
89
90 OS << "_id1_";
91 Outdep(Id1);
92}
93
94bool AMDGPUMIRFormatter::parseSDelayAluImmMnemonic(
95 const unsigned int OpIdx, int64_t &Imm, llvm::StringRef &Src,
96 llvm::MIRFormatter::ErrorCallbackType &ErrorCallback) const
97{
98 assert(OpIdx == 0);
99
100 Imm = 0;
101 bool Expected = Src.consume_front(".id0_");
102 if (!Expected)
103 return ErrorCallback(Src.begin(), "Expected .id0_");
104
105 auto ExpectInt = [&](StringRef &Src, int64_t Offset) -> int64_t {
106 int64_t Dep;
107 if (!Src.consumeInteger(10, Dep))
108 return Dep + Offset;
109
110 return -1;
111 };
112
113 auto DecodeDelay = [&](StringRef &Src) -> int64_t {
114 if (Src.consume_front("NONE"))
115 return 0;
116 if (Src.consume_front("VALU_DEP_"))
117 return ExpectInt(Src, 0);
118 if (Src.consume_front("TRANS32_DEP_"))
119 return ExpectInt(Src, 4);
120 if (Src.consume_front("SALU_CYCLE_"))
121 return ExpectInt(Src, 8);
122
123 return -1;
124 };
125
126 int64_t Delay0 = DecodeDelay(Src);
127 int64_t Skip = 0;
128 int64_t Delay1 = 0;
129 if (Delay0 == -1)
130 return ErrorCallback(Src.begin(), "Could not decode delay0");
131
132
133 // Set the Imm so far, to that early return has the correct value.
134 Imm = Delay0;
135
136 // If that was the end of the string, the second instruction is "same" and
137 // "none"
138 if (Src.begin() == Src.end())
139 return false;
140
141 Expected = Src.consume_front("_skip_");
142 if (!Expected)
143 return ErrorCallback(Src.begin(), "Expected _skip_");
144
145
146 if (Src.consume_front("SAME")) {
147 Skip = 0;
148 } else if (Src.consume_front("NEXT")) {
149 Skip = 1;
150 } else if (Src.consume_front("SKIP_")) {
151 if (Src.consumeInteger(10, Skip)) {
152 return ErrorCallback(Src.begin(), "Expected integer Skip value");
153 }
154 Skip += 1;
155 } else {
156 ErrorCallback(Src.begin(), "Unexpected Skip Value");
157 }
158
159 Expected = Src.consume_front("_id1_");
160 if (!Expected)
161 return ErrorCallback(Src.begin(), "Expected _id1_");
162
163 Delay1 = DecodeDelay(Src);
164 if (Delay1 == -1)
165 return ErrorCallback(Src.begin(), "Could not decode delay1");
166
167 Imm = Imm | (Skip << 4) | (Delay1 << 7);
168 return false;
169}
170
173 const PseudoSourceValue *&PSV, ErrorCallbackType ErrorCallback) const {
175 const AMDGPUTargetMachine &TM =
176 static_cast<const AMDGPUTargetMachine &>(MF.getTarget());
177 if (Src == "GWSResource") {
178 PSV = MFI->getGWSPSV(TM);
179 return false;
180 }
181 llvm_unreachable("unknown MIR custom pseudo source value");
182}
AMDGPU specific overrides of MIRFormatter.
AMD GCN specific subclass of TargetSubtarget.
IRTranslator LLVM IR MI
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
bool parseCustomPseudoSourceValue(StringRef Src, MachineFunction &MF, PerFunctionMIParsingState &PFS, const PseudoSourceValue *&PSV, ErrorCallbackType ErrorCallback) const override
Implement target specific parsing of target custom pseudo source value.
virtual void printImm(raw_ostream &OS, const MachineInstr &MI, std::optional< unsigned > OpIdx, int64_t Imm) const override
Implement target specific printing for machine operand immediate value, so that we can have more mean...
virtual bool parseImmMnemonic(const unsigned OpCode, const unsigned OpIdx, StringRef Src, int64_t &Imm, ErrorCallbackType ErrorCallback) const override
Implement target specific parsing of immediate mnemonics.
Tagged union holding either a T or a Error.
Definition: Error.h:481
virtual void printImm(raw_ostream &OS, const MachineInstr &MI, std::optional< unsigned > OpIdx, int64_t Imm) const
Implement target specific printing for machine operand immediate value, so that we can have more mean...
Definition: MIRFormatter.h:43
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Representation of each machine instruction.
Definition: MachineInstr.h:69
Special value supplied for machine level alias analysis.
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
const AMDGPUGWSResourcePseudoSourceValue * getGWSPSV(const AMDGPUTargetMachine &TM)
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
An efficient, type-erasing, non-owning reference to a callable.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
@ None
Definition: CodeGenData.h:101