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 
17 #include "mlir/Dialect/LLVMIR/ROCDLDialect.h"
18 
19 #include "mlir/Dialect/LLVMIR/LLVMDialect.h"
20 #include "mlir/IR/Builders.h"
21 #include "mlir/IR/BuiltinTypes.h"
22 #include "mlir/IR/MLIRContext.h"
23 #include "mlir/IR/Operation.h"
24 #include "llvm/AsmParser/Parser.h"
25 #include "llvm/IR/Attributes.h"
26 #include "llvm/IR/Function.h"
27 #include "llvm/IR/Type.h"
28 #include "llvm/Support/SourceMgr.h"
29 
30 using namespace mlir;
31 using namespace ROCDL;
32 
33 #include "mlir/Dialect/LLVMIR/ROCDLOpsDialect.cpp.inc"
34 
35 //===----------------------------------------------------------------------===//
36 // Parsing for ROCDL ops
37 //===----------------------------------------------------------------------===//
38 
39 // <operation> ::=
40 //     `llvm.amdgcn.buffer.load.* %rsrc, %vindex, %offset, %glc, %slc :
41 //     result_type`
42 static ParseResult parseROCDLMubufLoadOp(OpAsmParser &parser,
43                                          OperationState &result) {
44   SmallVector<OpAsmParser::OperandType, 8> ops;
45   Type type;
46   if (parser.parseOperandList(ops, 5) || parser.parseColonType(type) ||
47       parser.addTypeToList(type, result.types))
48     return failure();
49 
50   MLIRContext *context = parser.getContext();
51   auto int32Ty = IntegerType::get(context, 32);
52   auto int1Ty = IntegerType::get(context, 1);
53   auto i32x4Ty = LLVM::getFixedVectorType(int32Ty, 4);
54   return parser.resolveOperands(ops,
55                                 {i32x4Ty, int32Ty, int32Ty, int1Ty, int1Ty},
56                                 parser.getNameLoc(), result.operands);
57 }
58 
59 // <operation> ::=
60 //     `llvm.amdgcn.buffer.store.* %vdata, %rsrc, %vindex, %offset, %glc, %slc :
61 //     result_type`
62 static ParseResult parseROCDLMubufStoreOp(OpAsmParser &parser,
63                                           OperationState &result) {
64   SmallVector<OpAsmParser::OperandType, 8> ops;
65   Type type;
66   if (parser.parseOperandList(ops, 6) || parser.parseColonType(type))
67     return failure();
68 
69   MLIRContext *context = parser.getContext();
70   auto int32Ty = IntegerType::get(context, 32);
71   auto int1Ty = IntegerType::get(context, 1);
72   auto i32x4Ty = LLVM::getFixedVectorType(int32Ty, 4);
73 
74   if (parser.resolveOperands(ops,
75                              {type, i32x4Ty, int32Ty, int32Ty, int1Ty, int1Ty},
76                              parser.getNameLoc(), result.operands))
77     return failure();
78   return success();
79 }
80 
81 //===----------------------------------------------------------------------===//
82 // ROCDLDialect initialization, type parsing, and registration.
83 //===----------------------------------------------------------------------===//
84 
85 // TODO: This should be the llvm.rocdl dialect once this is supported.
86 void ROCDLDialect::initialize() {
87   addOperations<
88 #define GET_OP_LIST
89 #include "mlir/Dialect/LLVMIR/ROCDLOps.cpp.inc"
90       >();
91 
92   // Support unknown operations because not all ROCDL operations are registered.
93   allowUnknownOperations();
94 }
95 
96 LogicalResult ROCDLDialect::verifyOperationAttribute(Operation *op,
97                                                      NamedAttribute attr) {
98   // Kernel function attribute should be attached to functions.
99   if (attr.getName() == ROCDLDialect::getKernelFuncAttrName()) {
100     if (!isa<LLVM::LLVMFuncOp>(op)) {
101       return op->emitError() << "'" << ROCDLDialect::getKernelFuncAttrName()
102                              << "' attribute attached to unexpected op";
103     }
104   }
105   return success();
106 }
107 
108 #define GET_OP_CLASSES
109 #include "mlir/Dialect/LLVMIR/ROCDLOps.cpp.inc"
110