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"
16
17using namespace llvm;
18
20 std::optional<unsigned int> OpIdx, int64_t Imm) const {
21
22 switch (MI.getOpcode()) {
23 case AMDGPU::S_DELAY_ALU:
24 assert(OpIdx == 0);
25 printSDelayAluImm(Imm, OS);
26 break;
27 default:
28 MIRFormatter::printImm(OS, MI, OpIdx, Imm);
29 break;
30 }
31}
32
33/// Implement target specific parsing of immediate mnemonics. The mnemonic is
34/// a string with a leading dot.
35bool AMDGPUMIRFormatter::parseImmMnemonic(const unsigned OpCode,
36 const unsigned OpIdx,
37 StringRef Src, int64_t &Imm,
38 ErrorCallbackType ErrorCallback) const
39{
40
41 switch (OpCode) {
42 case AMDGPU::S_DELAY_ALU:
43 return parseSDelayAluImmMnemonic(OpIdx, Imm, Src, ErrorCallback);
44 default:
45 break;
46 }
47 return true; // Don't know what this is
48}
49
50void AMDGPUMIRFormatter::printSDelayAluImm(int64_t Imm,
51 llvm::raw_ostream &OS) const {
52 // Construct an immediate string to represent the information encoded in the
53 // s_delay_alu immediate.
54 // .id0_<dep>[_skip_<count>_id1<dep>]
55 constexpr int64_t None = 0;
56 constexpr int64_t Same = 0;
57
58 uint64_t Id0 = (Imm & 0xF);
59 uint64_t Skip = ((Imm >> 4) & 0x7);
60 uint64_t Id1 = ((Imm >> 7) & 0xF);
61 auto Outdep = [&](uint64_t Id) {
62 if (Id == None)
63 OS << "NONE";
64 else if (Id < 5)
65 OS << "VALU_DEP_" << Id;
66 else if (Id < 8)
67 OS << "TRANS32_DEP_" << Id - 4;
68 else
69 OS << "SALU_CYCLE_" << Id - 8;
70 };
71
72 OS << ".id0_";
73 Outdep(Id0);
74
75 // If the second inst is "same" and "none", no need to print the rest of the
76 // string.
77 if (Skip == Same && Id1 == None)
78 return;
79
80 // Encode the second delay specification.
81 OS << "_skip_";
82 if (Skip == 0)
83 OS << "SAME";
84 else if (Skip == 1)
85 OS << "NEXT";
86 else
87 OS << "SKIP_" << Skip - 1;
88
89 OS << "_id1_";
90 Outdep(Id1);
91}
92
93bool AMDGPUMIRFormatter::parseSDelayAluImmMnemonic(
94 const unsigned int OpIdx, int64_t &Imm, llvm::StringRef &Src,
95 llvm::MIRFormatter::ErrorCallbackType &ErrorCallback) const
96{
97 assert(OpIdx == 0);
98
99 Imm = 0;
100 bool Expected = Src.consume_front(".id0_");
101 if (!Expected)
102 return ErrorCallback(Src.begin(), "Expected .id0_");
103
104 auto ExpectInt = [&](StringRef &Src, int64_t Offset) -> int64_t {
105 int64_t Dep;
106 if (!Src.consumeInteger(10, Dep))
107 return Dep + Offset;
108
109 return -1;
110 };
111
112 auto DecodeDelay = [&](StringRef &Src) -> int64_t {
113 if (Src.consume_front("NONE"))
114 return 0;
115 if (Src.consume_front("VALU_DEP_"))
116 return ExpectInt(Src, 0);
117 if (Src.consume_front("TRANS32_DEP_"))
118 return ExpectInt(Src, 4);
119 if (Src.consume_front("SALU_CYCLE_"))
120 return ExpectInt(Src, 8);
121
122 return -1;
123 };
124
125 int64_t Delay0 = DecodeDelay(Src);
126 int64_t Skip = 0;
127 int64_t Delay1 = 0;
128 if (Delay0 == -1)
129 return ErrorCallback(Src.begin(), "Could not decode delay0");
130
131
132 // Set the Imm so far, to that early return has the correct value.
133 Imm = Delay0;
134
135 // If that was the end of the string, the second instruction is "same" and
136 // "none"
137 if (Src.begin() == Src.end())
138 return false;
139
140 Expected = Src.consume_front("_skip_");
141 if (!Expected)
142 return ErrorCallback(Src.begin(), "Expected _skip_");
143
144
145 if (Src.consume_front("SAME")) {
146 Skip = 0;
147 } else if (Src.consume_front("NEXT")) {
148 Skip = 1;
149 } else if (Src.consume_front("SKIP_")) {
150 if (Src.consumeInteger(10, Skip)) {
151 return ErrorCallback(Src.begin(), "Expected integer Skip value");
152 }
153 Skip += 1;
154 } else {
155 ErrorCallback(Src.begin(), "Unexpected Skip Value");
156 }
157
158 Expected = Src.consume_front("_id1_");
159 if (!Expected)
160 return ErrorCallback(Src.begin(), "Expected _id1_");
161
162 Delay1 = DecodeDelay(Src);
163 if (Delay1 == -1)
164 return ErrorCallback(Src.begin(), "Could not decode delay1");
165
166 Imm = Imm | (Skip << 4) | (Delay1 << 7);
167 return false;
168}
169
172 const PseudoSourceValue *&PSV, ErrorCallbackType ErrorCallback) const {
174 const AMDGPUTargetMachine &TM =
175 static_cast<const AMDGPUTargetMachine &>(MF.getTarget());
176 if (Src == "GWSResource") {
177 PSV = MFI->getGWSPSV(TM);
178 return false;
179 }
180 llvm_unreachable("unknown MIR custom pseudo source value");
181}
AMDGPU specific overrides of MIRFormatter.
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
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
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:51
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:106