Skip to content

Commit 66bef38

Browse files
committed
[mlir][EmitC] Introduce a CExpression trait
This adds a `CExpression` trait and replaces the `isCExpression()` function.
1 parent df267fe commit 66bef38

File tree

6 files changed

+66
-34
lines changed

6 files changed

+66
-34
lines changed

mlir/include/mlir/Dialect/EmitC/IR/EmitC.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#define MLIR_DIALECT_EMITC_IR_EMITC_H
1515

1616
#include "mlir/Bytecode/BytecodeOpInterface.h"
17+
#include "mlir/Dialect/EmitC/IR/EmitCTraits.h"
1718
#include "mlir/IR/Builders.h"
1819
#include "mlir/IR/BuiltinOps.h"
1920
#include "mlir/IR/BuiltinTypes.h"

mlir/include/mlir/Dialect/EmitC/IR/EmitC.td

Lines changed: 30 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,14 @@ class EmitC_BinaryOp<string mnemonic, list<Trait> traits = []> :
4747
let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
4848
}
4949

50+
// EmitC OpTrait
51+
def CExpression : NativeOpTrait<"emitc::CExpression">;
52+
5053
// Types only used in binary arithmetic operations.
5154
def IntegerIndexOrOpaqueType : AnyTypeOf<[AnyInteger, Index, EmitC_OpaqueType]>;
5255
def FloatIntegerIndexOrOpaqueType : AnyTypeOf<[AnyFloat, IntegerIndexOrOpaqueType]>;
5356

54-
def EmitC_AddOp : EmitC_BinaryOp<"add", []> {
57+
def EmitC_AddOp : EmitC_BinaryOp<"add", [CExpression]> {
5558
let summary = "Addition operation";
5659
let description = [{
5760
With the `add` operation the arithmetic operator + (addition) can
@@ -74,7 +77,7 @@ def EmitC_AddOp : EmitC_BinaryOp<"add", []> {
7477
let hasVerifier = 1;
7578
}
7679

77-
def EmitC_ApplyOp : EmitC_Op<"apply", []> {
80+
def EmitC_ApplyOp : EmitC_Op<"apply", [CExpression]> {
7881
let summary = "Apply operation";
7982
let description = [{
8083
With the `apply` operation the operators & (address of) and * (contents of)
@@ -103,7 +106,7 @@ def EmitC_ApplyOp : EmitC_Op<"apply", []> {
103106
let hasVerifier = 1;
104107
}
105108

106-
def EmitC_BitwiseAndOp : EmitC_BinaryOp<"bitwise_and", []> {
109+
def EmitC_BitwiseAndOp : EmitC_BinaryOp<"bitwise_and", [CExpression]> {
107110
let summary = "Bitwise and operation";
108111
let description = [{
109112
With the `bitwise_and` operation the bitwise operator & (and) can
@@ -121,7 +124,8 @@ def EmitC_BitwiseAndOp : EmitC_BinaryOp<"bitwise_and", []> {
121124
}];
122125
}
123126

124-
def EmitC_BitwiseLeftShiftOp : EmitC_BinaryOp<"bitwise_left_shift", []> {
127+
def EmitC_BitwiseLeftShiftOp : EmitC_BinaryOp<"bitwise_left_shift",
128+
[CExpression]> {
125129
let summary = "Bitwise left shift operation";
126130
let description = [{
127131
With the `bitwise_left_shift` operation the bitwise operator <<
@@ -139,7 +143,7 @@ def EmitC_BitwiseLeftShiftOp : EmitC_BinaryOp<"bitwise_left_shift", []> {
139143
}];
140144
}
141145

142-
def EmitC_BitwiseNotOp : EmitC_UnaryOp<"bitwise_not", []> {
146+
def EmitC_BitwiseNotOp : EmitC_UnaryOp<"bitwise_not", [CExpression]> {
143147
let summary = "Bitwise not operation";
144148
let description = [{
145149
With the `bitwise_not` operation the bitwise operator ~ (not) can
@@ -157,7 +161,7 @@ def EmitC_BitwiseNotOp : EmitC_UnaryOp<"bitwise_not", []> {
157161
}];
158162
}
159163

160-
def EmitC_BitwiseOrOp : EmitC_BinaryOp<"bitwise_or", []> {
164+
def EmitC_BitwiseOrOp : EmitC_BinaryOp<"bitwise_or", [CExpression]> {
161165
let summary = "Bitwise or operation";
162166
let description = [{
163167
With the `bitwise_or` operation the bitwise operator | (or)
@@ -175,7 +179,8 @@ def EmitC_BitwiseOrOp : EmitC_BinaryOp<"bitwise_or", []> {
175179
}];
176180
}
177181

178-
def EmitC_BitwiseRightShiftOp : EmitC_BinaryOp<"bitwise_right_shift", []> {
182+
def EmitC_BitwiseRightShiftOp : EmitC_BinaryOp<"bitwise_right_shift",
183+
[CExpression]> {
179184
let summary = "Bitwise right shift operation";
180185
let description = [{
181186
With the `bitwise_right_shift` operation the bitwise operator >>
@@ -193,7 +198,7 @@ def EmitC_BitwiseRightShiftOp : EmitC_BinaryOp<"bitwise_right_shift", []> {
193198
}];
194199
}
195200

196-
def EmitC_BitwiseXorOp : EmitC_BinaryOp<"bitwise_xor", []> {
201+
def EmitC_BitwiseXorOp : EmitC_BinaryOp<"bitwise_xor", [CExpression]> {
197202
let summary = "Bitwise xor operation";
198203
let description = [{
199204
With the `bitwise_xor` operation the bitwise operator ^ (xor)
@@ -211,7 +216,7 @@ def EmitC_BitwiseXorOp : EmitC_BinaryOp<"bitwise_xor", []> {
211216
}];
212217
}
213218

214-
def EmitC_CallOpaqueOp : EmitC_Op<"call_opaque", []> {
219+
def EmitC_CallOpaqueOp : EmitC_Op<"call_opaque", [CExpression]> {
215220
let summary = "Opaque call operation";
216221
let description = [{
217222
The `call_opaque` operation represents a C++ function call. The callee
@@ -257,10 +262,10 @@ def EmitC_CallOpaqueOp : EmitC_Op<"call_opaque", []> {
257262
let hasVerifier = 1;
258263
}
259264

260-
def EmitC_CastOp : EmitC_Op<"cast", [
261-
DeclareOpInterfaceMethods<CastOpInterface>,
262-
SameOperandsAndResultShape
263-
]> {
265+
def EmitC_CastOp : EmitC_Op<"cast",
266+
[CExpression,
267+
DeclareOpInterfaceMethods<CastOpInterface>,
268+
SameOperandsAndResultShape]> {
264269
let summary = "Cast operation";
265270
let description = [{
266271
The `cast` operation performs an explicit type conversion and is emitted
@@ -284,7 +289,7 @@ def EmitC_CastOp : EmitC_Op<"cast", [
284289
let assemblyFormat = "$source attr-dict `:` type($source) `to` type($dest)";
285290
}
286291

287-
def EmitC_CmpOp : EmitC_BinaryOp<"cmp", []> {
292+
def EmitC_CmpOp : EmitC_BinaryOp<"cmp", [CExpression]> {
288293
let summary = "Comparison operation";
289294
let description = [{
290295
With the `cmp` operation the comparison operators ==, !=, <, <=, >, >=, <=>
@@ -355,7 +360,7 @@ def EmitC_ConstantOp : EmitC_Op<"constant", [ConstantLike]> {
355360
let hasVerifier = 1;
356361
}
357362

358-
def EmitC_DivOp : EmitC_BinaryOp<"div", []> {
363+
def EmitC_DivOp : EmitC_BinaryOp<"div", [CExpression]> {
359364
let summary = "Division operation";
360365
let description = [{
361366
With the `div` operation the arithmetic operator / (division) can
@@ -409,9 +414,8 @@ def EmitC_ExpressionOp : EmitC_Op<"expression",
409414
int32_t v7 = foo(v1 + v2) * (v3 + v4);
410415
```
411416

412-
The operations allowed within expression body are `emitc.add`,
413-
`emitc.apply`, `emitc.call_opaque`, `emitc.cast`, `emitc.cmp`, `emitc.div`,
414-
`emitc.mul`, `emitc.rem`, and `emitc.sub`.
417+
The operations allowed within expression body are EmitC operations with the
418+
CExpression trait.
415419

416420
When specified, the optional `do_not_inline` indicates that the expression is
417421
to be emitted as seen above, i.e. as the rhs of an EmitC SSA value
@@ -427,14 +431,9 @@ def EmitC_ExpressionOp : EmitC_Op<"expression",
427431
let assemblyFormat = "attr-dict (`noinline` $do_not_inline^)? `:` type($result) $region";
428432

429433
let extraClassDeclaration = [{
430-
static bool isCExpression(Operation &op) {
431-
return isa<emitc::AddOp, emitc::ApplyOp, emitc::CallOpaqueOp,
432-
emitc::CastOp, emitc::CmpOp, emitc::DivOp, emitc::MulOp,
433-
emitc::RemOp, emitc::SubOp>(op);
434-
}
435434
bool hasSideEffects() {
436435
auto predicate = [](Operation &op) {
437-
assert(isCExpression(op) && "Expected a C expression");
436+
assert(op.hasTrait<OpTrait::emitc::CExpression>() && "Expected a C expression");
438437
// Conservatively assume calls to read and write memory.
439438
if (isa<emitc::CallOpaqueOp>(op))
440439
return true;
@@ -518,7 +517,7 @@ def EmitC_ForOp : EmitC_Op<"for",
518517
}
519518

520519
def EmitC_CallOp : EmitC_Op<"call",
521-
[CallOpInterface,
520+
[CallOpInterface, CExpression,
522521
DeclareOpInterfaceMethods<SymbolUserOpInterface>]> {
523522
let summary = "call operation";
524523
let description = [{
@@ -774,7 +773,7 @@ def EmitC_LiteralOp : EmitC_Op<"literal", [Pure]> {
774773
let assemblyFormat = "$value attr-dict `:` type($result)";
775774
}
776775

777-
def EmitC_LogicalAndOp : EmitC_BinaryOp<"logical_and", []> {
776+
def EmitC_LogicalAndOp : EmitC_BinaryOp<"logical_and", [CExpression]> {
778777
let summary = "Logical and operation";
779778
let description = [{
780779
With the `logical_and` operation the logical operator && (and) can
@@ -795,7 +794,7 @@ def EmitC_LogicalAndOp : EmitC_BinaryOp<"logical_and", []> {
795794
let assemblyFormat = "operands attr-dict `:` type(operands)";
796795
}
797796

798-
def EmitC_LogicalNotOp : EmitC_UnaryOp<"logical_not", []> {
797+
def EmitC_LogicalNotOp : EmitC_UnaryOp<"logical_not", [CExpression]> {
799798
let summary = "Logical not operation";
800799
let description = [{
801800
With the `logical_not` operation the logical operator ! (negation) can
@@ -816,7 +815,7 @@ def EmitC_LogicalNotOp : EmitC_UnaryOp<"logical_not", []> {
816815
let assemblyFormat = "operands attr-dict `:` type(operands)";
817816
}
818817

819-
def EmitC_LogicalOrOp : EmitC_BinaryOp<"logical_or", []> {
818+
def EmitC_LogicalOrOp : EmitC_BinaryOp<"logical_or", [CExpression]> {
820819
let summary = "Logical or operation";
821820
let description = [{
822821
With the `logical_or` operation the logical operator || (inclusive or)
@@ -837,7 +836,7 @@ def EmitC_LogicalOrOp : EmitC_BinaryOp<"logical_or", []> {
837836
let assemblyFormat = "operands attr-dict `:` type(operands)";
838837
}
839838

840-
def EmitC_MulOp : EmitC_BinaryOp<"mul", []> {
839+
def EmitC_MulOp : EmitC_BinaryOp<"mul", [CExpression]> {
841840
let summary = "Multiplication operation";
842841
let description = [{
843842
With the `mul` operation the arithmetic operator * (multiplication) can
@@ -861,7 +860,7 @@ def EmitC_MulOp : EmitC_BinaryOp<"mul", []> {
861860
let results = (outs FloatIntegerIndexOrOpaqueType);
862861
}
863862

864-
def EmitC_RemOp : EmitC_BinaryOp<"rem", []> {
863+
def EmitC_RemOp : EmitC_BinaryOp<"rem", [CExpression]> {
865864
let summary = "Remainder operation";
866865
let description = [{
867866
With the `rem` operation the arithmetic operator % (remainder) can
@@ -883,7 +882,7 @@ def EmitC_RemOp : EmitC_BinaryOp<"rem", []> {
883882
let results = (outs IntegerIndexOrOpaqueType);
884883
}
885884

886-
def EmitC_SubOp : EmitC_BinaryOp<"sub", []> {
885+
def EmitC_SubOp : EmitC_BinaryOp<"sub", [CExpression]> {
887886
let summary = "Subtraction operation";
888887
let description = [{
889888
With the `sub` operation the arithmetic operator - (subtraction) can
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//===- EmitCTraits.h - EmitC trait definitions ------------------*- C++ -*-===//
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 declares C++ classes for some of the traits used in the EmitC
10+
// dialect.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef MLIR_DIALECT_EMITC_IR_EMITCTRAITS_H
15+
#define MLIR_DIALECT_EMITC_IR_EMITCTRAITS_H
16+
17+
#include "mlir/IR/OpDefinition.h"
18+
19+
namespace mlir {
20+
namespace OpTrait {
21+
namespace emitc {
22+
23+
template <typename ConcreteType>
24+
class CExpression : public TraitBase<ConcreteType, CExpression> {};
25+
26+
} // namespace emitc
27+
} // namespace OpTrait
28+
} // namespace mlir
29+
30+
#endif // MLIR_DIALECT_EMITC_IR_EMITCTRAITS_H

mlir/lib/Dialect/EmitC/IR/EmitC.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "mlir/Dialect/EmitC/IR/EmitC.h"
10+
#include "mlir/Dialect/EmitC/IR/EmitCTraits.h"
1011
#include "mlir/IR/Builders.h"
1112
#include "mlir/IR/BuiltinAttributes.h"
1213
#include "mlir/IR/DialectImplementation.h"
@@ -244,7 +245,7 @@ LogicalResult ExpressionOp::verify() {
244245
return emitOpError("requires yielded type to match return type");
245246

246247
for (Operation &op : region.front().without_terminator()) {
247-
if (!isCExpression(op))
248+
if (!op.hasTrait<OpTrait::emitc::CExpression>())
248249
return emitOpError("contains an unsupported operation");
249250
if (op.getNumResults() != 1)
250251
return emitOpError("requires exactly one result for each operation");

mlir/lib/Dialect/EmitC/Transforms/FormExpressions.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ struct FormExpressionsPass
3636
// Wrap each C operator op with an expression op.
3737
OpBuilder builder(context);
3838
auto matchFun = [&](Operation *op) {
39-
if (emitc::ExpressionOp::isCExpression(*op))
39+
if (op->hasTrait<OpTrait::emitc::CExpression>())
4040
createExpression(op, builder);
4141
};
4242
rootOp->walk(matchFun);

mlir/lib/Dialect/EmitC/Transforms/Transforms.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ namespace mlir {
1616
namespace emitc {
1717

1818
ExpressionOp createExpression(Operation *op, OpBuilder &builder) {
19-
assert(ExpressionOp::isCExpression(*op) && "Expected a C expression");
19+
assert(op->hasTrait<OpTrait::emitc::CExpression>() &&
20+
"Expected a C expression");
2021

2122
// Create an expression yielding the value returned by op.
2223
assert(op->getNumResults() == 1 && "Expected exactly one result");

0 commit comments

Comments
 (0)