MLIR  22.0.0git
ROCDLDialect.cpp
Go to the documentation of this file.
1 //===- ROCDLDialect.cpp - ROCDL IR Ops and Dialect registration -----------===//
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 // This file defines the types and operation details for the ROCDL IR dialect in
10 // MLIR, and the LLVM IR dialect. It also registers the dialect.
11 //
12 // The ROCDL dialect only contains GPU specific additions on top of the general
13 // LLVM dialect.
14 //
15 //===----------------------------------------------------------------------===//
16 
18 
21 #include "mlir/IR/Builders.h"
22 #include "mlir/IR/BuiltinTypes.h"
24 #include "mlir/IR/MLIRContext.h"
25 #include "mlir/IR/Operation.h"
26 #include "llvm/ADT/TypeSwitch.h"
27 
28 using namespace mlir;
29 using namespace ROCDL;
30 
31 #include "mlir/Dialect/LLVMIR/ROCDLOpsDialect.cpp.inc"
32 
33 //===----------------------------------------------------------------------===//
34 // Parsing for ROCDL ops
35 //===----------------------------------------------------------------------===//
36 
37 // <operation> ::=
38 // `llvm.amdgcn.raw.buffer.load.* %rsrc, %offset, %soffset, %aux
39 // : result_type`
40 ParseResult RawBufferLoadOp::parse(OpAsmParser &parser,
41  OperationState &result) {
43  Type type;
44  if (parser.parseOperandList(ops, 4) || parser.parseColonType(type) ||
45  parser.addTypeToList(type, result.types))
46  return failure();
47 
48  auto bldr = parser.getBuilder();
49  auto int32Ty = bldr.getI32Type();
50  auto i32x4Ty = VectorType::get({4}, int32Ty);
51  return parser.resolveOperands(ops, {i32x4Ty, int32Ty, int32Ty, int32Ty},
52  parser.getNameLoc(), result.operands);
53 }
54 
56  p << " " << getOperands() << " : " << getRes().getType();
57 }
58 
59 // <operation> ::=
60 // `llvm.amdgcn.raw.buffer.store.* %vdata, %rsrc, %offset,
61 // %soffset, %aux : result_type`
62 ParseResult RawBufferStoreOp::parse(OpAsmParser &parser,
63  OperationState &result) {
65  Type type;
66  if (parser.parseOperandList(ops, 5) || parser.parseColonType(type))
67  return failure();
68 
69  auto bldr = parser.getBuilder();
70  auto int32Ty = bldr.getI32Type();
71  auto i32x4Ty = VectorType::get({4}, int32Ty);
72 
73  if (parser.resolveOperands(ops, {type, i32x4Ty, int32Ty, int32Ty, int32Ty},
74  parser.getNameLoc(), result.operands))
75  return failure();
76  return success();
77 }
78 
80  p << " " << getOperands() << " : " << getVdata().getType();
81 }
82 
83 // <operation> ::=
84 // `llvm.amdgcn.raw.buffer.atomic.fadd.* %vdata, %rsrc, %offset,
85 // %soffset, %aux : result_type`
86 ParseResult RawBufferAtomicFAddOp::parse(OpAsmParser &parser,
87  OperationState &result) {
89  Type type;
90  if (parser.parseOperandList(ops, 5) || parser.parseColonType(type))
91  return failure();
92 
93  auto bldr = parser.getBuilder();
94  auto int32Ty = bldr.getI32Type();
95  auto i32x4Ty = VectorType::get({4}, int32Ty);
96 
97  if (parser.resolveOperands(ops, {type, i32x4Ty, int32Ty, int32Ty, int32Ty},
98  parser.getNameLoc(), result.operands))
99  return failure();
100  return success();
101 }
102 
104  p << " " << getOperands() << " : " << getVdata().getType();
105 }
106 
107 // <operation> ::=
108 // `llvm.amdgcn.raw.buffer.atomic.fmax.* %vdata, %rsrc, %offset,
109 // %soffset, %aux : result_type`
110 ParseResult RawBufferAtomicFMaxOp::parse(OpAsmParser &parser,
111  OperationState &result) {
113  Type type;
114  if (parser.parseOperandList(ops, 5) || parser.parseColonType(type))
115  return failure();
116 
117  auto bldr = parser.getBuilder();
118  auto int32Ty = bldr.getI32Type();
119  auto i32x4Ty = VectorType::get({4}, int32Ty);
120 
121  if (parser.resolveOperands(ops, {type, i32x4Ty, int32Ty, int32Ty, int32Ty},
122  parser.getNameLoc(), result.operands))
123  return failure();
124  return success();
125 }
126 
128  p << " " << getOperands() << " : " << getVdata().getType();
129 }
130 
131 // <operation> ::=
132 // `llvm.amdgcn.raw.buffer.atomic.smax.* %vdata, %rsrc, %offset,
133 // %soffset, %aux : result_type`
134 ParseResult RawBufferAtomicSMaxOp::parse(OpAsmParser &parser,
135  OperationState &result) {
137  Type type;
138  if (parser.parseOperandList(ops, 5) || parser.parseColonType(type))
139  return failure();
140 
141  auto bldr = parser.getBuilder();
142  auto int32Ty = bldr.getI32Type();
143  auto i32x4Ty = VectorType::get({4}, int32Ty);
144 
145  if (parser.resolveOperands(ops, {type, i32x4Ty, int32Ty, int32Ty, int32Ty},
146  parser.getNameLoc(), result.operands))
147  return failure();
148  return success();
149 }
150 
152  p << " " << getOperands() << " : " << getVdata().getType();
153 }
154 
155 // <operation> ::=
156 // `llvm.amdgcn.raw.buffer.atomic.umin.* %vdata, %rsrc, %offset,
157 // %soffset, %aux : result_type`
158 ParseResult RawBufferAtomicUMinOp::parse(OpAsmParser &parser,
159  OperationState &result) {
161  Type type;
162  if (parser.parseOperandList(ops, 5) || parser.parseColonType(type))
163  return failure();
164 
165  auto bldr = parser.getBuilder();
166  auto int32Ty = bldr.getI32Type();
167  auto i32x4Ty = VectorType::get({4}, int32Ty);
168 
169  if (parser.resolveOperands(ops, {type, i32x4Ty, int32Ty, int32Ty, int32Ty},
170  parser.getNameLoc(), result.operands))
171  return failure();
172  return success();
173 }
174 
176  p << " " << getOperands() << " : " << getVdata().getType();
177 }
178 
179 //===----------------------------------------------------------------------===//
180 // ROCDLDialect initialization, type parsing, and registration.
181 //===----------------------------------------------------------------------===//
182 
183 // TODO: This should be the llvm.rocdl dialect once this is supported.
184 void ROCDLDialect::initialize() {
185  addOperations<
186 #define GET_OP_LIST
187 #include "mlir/Dialect/LLVMIR/ROCDLOps.cpp.inc"
188  >();
189 
190  addAttributes<
191 #define GET_ATTRDEF_LIST
192 #include "mlir/Dialect/LLVMIR/ROCDLOpsAttributes.cpp.inc"
193  >();
194 
195  // Support unknown operations because not all ROCDL operations are registered.
196  allowUnknownOperations();
197  declarePromisedInterface<gpu::TargetAttrInterface, ROCDLTargetAttr>();
198 }
199 
200 LogicalResult ROCDLDialect::verifyOperationAttribute(Operation *op,
201  NamedAttribute attr) {
202  // Kernel function attribute should be attached to functions.
203  if (kernelAttrName.getName() == attr.getName()) {
204  if (!isa<LLVM::LLVMFuncOp>(op)) {
205  return op->emitError() << "'" << kernelAttrName.getName()
206  << "' attribute attached to unexpected op";
207  }
208  }
209  return success();
210 }
211 
212 //===----------------------------------------------------------------------===//
213 // ROCDL target attribute.
214 //===----------------------------------------------------------------------===//
215 LogicalResult
217  int optLevel, StringRef triple, StringRef chip,
218  StringRef features, StringRef abiVersion,
219  DictionaryAttr flags, ArrayAttr files) {
220  if (optLevel < 0 || optLevel > 3) {
221  emitError() << "The optimization level must be a number between 0 and 3.";
222  return failure();
223  }
224  if (triple.empty()) {
225  emitError() << "The target triple cannot be empty.";
226  return failure();
227  }
228  if (chip.empty()) {
229  emitError() << "The target chip cannot be empty.";
230  return failure();
231  }
232  if (abiVersion != "400" && abiVersion != "500" && abiVersion != "600") {
233  emitError() << "Invalid ABI version, it must be `400`, `500` or '600'.";
234  return failure();
235  }
236  if (files && !llvm::all_of(files, [](::mlir::Attribute attr) {
237  return attr && mlir::isa<StringAttr>(attr);
238  })) {
239  emitError() << "All the elements in the `link` array must be strings.";
240  return failure();
241  }
242  return success();
243 }
244 
245 #define GET_OP_CLASSES
246 #include "mlir/Dialect/LLVMIR/ROCDLOps.cpp.inc"
247 
248 #define GET_ATTRDEF_CLASSES
249 #include "mlir/Dialect/LLVMIR/ROCDLOpsAttributes.cpp.inc"
static void print(spirv::VerCapExtAttr triple, DialectAsmPrinter &printer)
virtual Builder & getBuilder() const =0
Return a builder which provides useful access to MLIRContext, global objects like types and attribute...
ParseResult addTypeToList(Type type, SmallVectorImpl< Type > &result)
Add the specified type to the end of the specified type list and return success.
virtual ParseResult parseColonType(Type &result)=0
Parse a colon followed by a type.
virtual SMLoc getNameLoc() const =0
Return the location of the original name token.
Attributes are known-constant values of operations.
Definition: Attributes.h:25
IntegerType getI32Type()
Definition: Builders.cpp:62
This class represents a diagnostic that is inflight and set to be reported.
Definition: Diagnostics.h:314
NamedAttribute represents a combination of a name and an Attribute value.
Definition: Attributes.h:164
StringAttr getName() const
Return the name of the attribute.
Definition: Attributes.cpp:55
The OpAsmParser has methods for interacting with the asm parser: parsing things from it,...
ParseResult resolveOperands(Operands &&operands, Type type, SmallVectorImpl< Value > &result)
Resolve a list of operands to SSA values, emitting an error on failure, or appending the results to t...
virtual ParseResult parseOperandList(SmallVectorImpl< UnresolvedOperand > &result, Delimiter delimiter=Delimiter::None, bool allowResultNumber=true, int requiredOperandCount=-1)=0
Parse zero or more SSA comma-separated operand references with a specified surrounding delimiter,...
This is a pure-virtual base class that exposes the asmprinter hooks necessary to implement a custom p...
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:88
InFlightDiagnostic emitError(const Twine &message={})
Emit an error about fatal conditions with this operation, reporting up to any diagnostic handlers tha...
Definition: Operation.cpp:267
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:74
QueryRef parse(llvm::StringRef line, const QuerySession &qs)
Definition: Query.cpp:21
Include the generated interface declarations.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
LogicalResult verify(Operation *op, bool verifyRecursively=true)
Perform (potentially expensive) checks of invariants, used to detect compiler bugs,...
Definition: Verifier.cpp:423
This represents an operation in an abstracted form, suitable for use with the builder APIs.
SmallVector< Value, 4 > operands
SmallVector< Type, 4 > types
Types of the results of this operation.