1
+ //===- CompigraInterfaces.td - cgra interfaces -------------*- tablegen -*-===//
2
+ //
3
+ // Compigra 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 is the definition file for the structured interface for Handshake ops.
10
+ //
11
+ //===----------------------------------------------------------------------===//
12
+
13
+ #ifndef CGRA_OP_INTERFACES
14
+ #define CGRA_OP_INTERFACES
15
+
16
+ include "mlir/IR/OpBase.td"
17
+
18
+ def SOSTInterface : OpInterface<"SOSTInterface"> {
19
+ let cppNamespace = "::compigra::cgra";
20
+ let description = [{
21
+ Sized Operation with Single Type (SOST).
22
+
23
+ These are operations whose operands all have the same type and which have
24
+ an integer size property, be it the number of operation operands (e.g.,
25
+ for a merge) or the number of operation results (e.g., for a fork).
26
+ }];
27
+
28
+ let methods = [
29
+ InterfaceMethod<[{
30
+ Get the data type associated to the operation.
31
+ The default implementation of this method simply returns the type of
32
+ the first operation operand.
33
+ }],
34
+ "mlir::Type", "getDataType", (ins), "",
35
+ [{
36
+ auto concreteOp = mlir::cast<ConcreteOp>($_op);
37
+ return concreteOp->getOperands().front().getType();
38
+ }]
39
+ >,
40
+ InterfaceMethod<[{
41
+ Get the size associated to the operation.
42
+ The default implementation of this method simply returns the number of
43
+ operation operands.
44
+ }],
45
+ "unsigned", "getSize", (ins), "",
46
+ [{
47
+ auto concreteOp = mlir::cast<ConcreteOp>($_op);
48
+ return concreteOp->getNumOperands();
49
+ }]
50
+ >,
51
+ InterfaceMethod<[{
52
+ Determine whether the operation is a control operation.
53
+ The default implementation of this method assumes that the operation
54
+ is a control operation if and only if its associated data type is a
55
+ NoneType.
56
+ }],
57
+ "bool", "sostIsControl", (ins), "",
58
+ [{
59
+ auto concreteOp = mlir::cast<ConcreteOp>($_op);
60
+ // The operation is a control operation if its single data type is a
61
+ // NoneType.
62
+ return concreteOp.getDataType().template isa<mlir::NoneType>();
63
+ }]
64
+ >,
65
+ InterfaceMethod<[{
66
+ Print the "SOST characteristics" of an operation.
67
+ If the `explicitSize` parameter is set to true, then the method prints
68
+ the operation's size (in the SOST sense) between square brackets before
69
+ printing the operation's operands, attributes, and data type.
70
+ }],
71
+ "void", "sostPrint", (ins
72
+ "mlir::OpAsmPrinter &": $printer, "bool": $explicitSize
73
+ ), "",
74
+ [{
75
+ auto concreteOp = mlir::cast<ConcreteOp>($_op);
76
+
77
+ if (explicitSize) {
78
+ printer << " [" << concreteOp.getSize() << "]";
79
+ }
80
+ printer << " " << concreteOp->getOperands();
81
+ printer.printOptionalAttrDict(concreteOp->getAttrs());
82
+ printer << " : " << concreteOp.getDataType();
83
+ }]
84
+ >
85
+ ];
86
+
87
+ let verify = [{
88
+ auto concreteOp = mlir::cast<ConcreteOp>($_op);
89
+
90
+ // SOST operation's size must be at least one
91
+ if (concreteOp.getSize() < 1) {
92
+ return concreteOp.emitOpError(
93
+ "SOST operation's size must be at least 1, but has size ")
94
+ << concreteOp.getSize();
95
+ }
96
+
97
+ // SOST operation's operands must all have the same type
98
+ auto dataType = concreteOp.getDataType();
99
+ for (auto operand : concreteOp->getOperands())
100
+ if (operand.getType() != dataType)
101
+ return concreteOp.emitOpError("SOST operation reports having data type ")
102
+ << dataType << ", but one operand has type " << operand.getType();
103
+
104
+ return mlir::success();
105
+ }];
106
+ }
107
+
108
+ def MergeLikeOpInterface : OpInterface<"MergeLikeOpInterface"> {
109
+ let cppNamespace = "::compigra::cgra";
110
+ let description = [{
111
+ Some handshake operations can have predecessors in other
112
+ blocks. This is primarily useful for verification purposes during
113
+ lowering from other dialect, such as the standard CDFG dialect.
114
+ }];
115
+
116
+ let methods = [
117
+ InterfaceMethod<[{
118
+ Returns an operand range over the data signals being merged.
119
+ }],
120
+ "mlir::OperandRange", "getDataOperands", (ins)
121
+ >,
122
+ ];
123
+
124
+ let verify = [{
125
+ auto concreteOp = mlir::cast<ConcreteOp>($_op);
126
+
127
+ auto operands = concreteOp.getDataOperands();
128
+
129
+ if (!operands.size())
130
+ return concreteOp.emitOpError("must have at least one data operand");
131
+
132
+ mlir::Type resultType = $_op->getResult(0).getType();
133
+
134
+ for (auto operand : operands)
135
+ if (operand.getType() != resultType)
136
+ return concreteOp.emitOpError("operand has type ") << operand.getType()
137
+ << ", but result has type " << resultType;
138
+
139
+ return mlir::success();
140
+ }];
141
+ }
142
+
143
+ def GeneralOpInterface : OpInterface<"GeneralOpInterface"> {
144
+ let cppNamespace = "::compigra::cgra";
145
+ let description =
146
+ [{"Simulate the Execution of ops. The op takes a set of input values and "
147
+ "returns the corresponding outputs assuming the precondition to "
148
+ "execute holds."}];
149
+
150
+ let methods = [
151
+ InterfaceMethod<
152
+ "Simulate the Execution of the general op with given inputs", "void",
153
+ "execute",
154
+ (ins "std::vector<llvm::Any> &" : $ins,
155
+ "std::vector<llvm::Any> &" : $outs)>,
156
+ ];
157
+ }
158
+
159
+ #endif // CGRA_OP_INTERFACES
0 commit comments