14
14
#define MLIR_DIALECT_EMITC_IR_EMITC
15
15
16
16
include "mlir/Dialect/EmitC/IR/EmitCAttributes.td"
17
+ include "mlir/Dialect/EmitC/IR/EmitCInterfaces.td"
17
18
include "mlir/Dialect/EmitC/IR/EmitCTypes.td"
18
19
19
20
include "mlir/Interfaces/CallInterfaces.td"
@@ -35,22 +36,31 @@ class EmitC_Op<string mnemonic, list<Trait> traits = []>
35
36
36
37
// Base class for unary operations.
37
38
class EmitC_UnaryOp<string mnemonic, list<Trait> traits = []> :
38
- EmitC_Op<mnemonic, traits> {
39
+ EmitC_Op<mnemonic, !listconcat( traits, [CExpressionInterface]) > {
39
40
let arguments = (ins EmitCType);
40
41
let results = (outs EmitCType);
41
42
let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
43
+
44
+ let extraClassDeclaration = [{
45
+ bool hasSideEffects() {
46
+ return false;
47
+ }
48
+ }];
42
49
}
43
50
44
51
// Base class for binary operations.
45
52
class EmitC_BinaryOp<string mnemonic, list<Trait> traits = []> :
46
- EmitC_Op<mnemonic, traits> {
53
+ EmitC_Op<mnemonic, !listconcat( traits, [CExpressionInterface]) > {
47
54
let arguments = (ins EmitCType:$lhs, EmitCType:$rhs);
48
55
let results = (outs EmitCType);
49
56
let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
50
- }
51
57
52
- // EmitC OpTrait
53
- def CExpression : NativeOpTrait<"emitc::CExpression">;
58
+ let extraClassDeclaration = [{
59
+ bool hasSideEffects() {
60
+ return false;
61
+ }
62
+ }];
63
+ }
54
64
55
65
// Types only used in binary arithmetic operations.
56
66
def IntegerIndexOrOpaqueType : Type<CPred<"emitc::isIntegerIndexOrOpaqueType($_self)">,
@@ -103,7 +113,7 @@ def EmitC_FileOp
103
113
let skipDefaultBuilders = 1;
104
114
}
105
115
106
- def EmitC_AddOp : EmitC_BinaryOp<"add", [CExpression ]> {
116
+ def EmitC_AddOp : EmitC_BinaryOp<"add", []> {
107
117
let summary = "Addition operation";
108
118
let description = [{
109
119
With the `emitc.add` operation the arithmetic operator + (addition) can
@@ -126,7 +136,7 @@ def EmitC_AddOp : EmitC_BinaryOp<"add", [CExpression]> {
126
136
let hasVerifier = 1;
127
137
}
128
138
129
- def EmitC_ApplyOp : EmitC_Op<"apply", [CExpression ]> {
139
+ def EmitC_ApplyOp : EmitC_Op<"apply", [CExpressionInterface ]> {
130
140
let summary = "Apply operation";
131
141
let description = [{
132
142
With the `emitc.apply` operation the operators & (address of) and * (contents of)
@@ -152,10 +162,17 @@ def EmitC_ApplyOp : EmitC_Op<"apply", [CExpression]> {
152
162
let assemblyFormat = [{
153
163
$applicableOperator `(` $operand `)` attr-dict `:` functional-type($operand, results)
154
164
}];
165
+
166
+ let extraClassDeclaration = [{
167
+ bool hasSideEffects() {
168
+ return getApplicableOperator() == "*";
169
+ }
170
+ }];
171
+
155
172
let hasVerifier = 1;
156
173
}
157
174
158
- def EmitC_BitwiseAndOp : EmitC_BinaryOp<"bitwise_and", [CExpression ]> {
175
+ def EmitC_BitwiseAndOp : EmitC_BinaryOp<"bitwise_and", []> {
159
176
let summary = "Bitwise and operation";
160
177
let description = [{
161
178
With the `emitc.bitwise_and` operation the bitwise operator & (and) can
@@ -173,8 +190,7 @@ def EmitC_BitwiseAndOp : EmitC_BinaryOp<"bitwise_and", [CExpression]> {
173
190
}];
174
191
}
175
192
176
- def EmitC_BitwiseLeftShiftOp : EmitC_BinaryOp<"bitwise_left_shift",
177
- [CExpression]> {
193
+ def EmitC_BitwiseLeftShiftOp : EmitC_BinaryOp<"bitwise_left_shift", []> {
178
194
let summary = "Bitwise left shift operation";
179
195
let description = [{
180
196
With the `emitc.bitwise_left_shift` operation the bitwise operator <<
@@ -192,7 +208,7 @@ def EmitC_BitwiseLeftShiftOp : EmitC_BinaryOp<"bitwise_left_shift",
192
208
}];
193
209
}
194
210
195
- def EmitC_BitwiseNotOp : EmitC_UnaryOp<"bitwise_not", [CExpression ]> {
211
+ def EmitC_BitwiseNotOp : EmitC_UnaryOp<"bitwise_not", []> {
196
212
let summary = "Bitwise not operation";
197
213
let description = [{
198
214
With the `emitc.bitwise_not` operation the bitwise operator ~ (not) can
@@ -210,7 +226,7 @@ def EmitC_BitwiseNotOp : EmitC_UnaryOp<"bitwise_not", [CExpression]> {
210
226
}];
211
227
}
212
228
213
- def EmitC_BitwiseOrOp : EmitC_BinaryOp<"bitwise_or", [CExpression ]> {
229
+ def EmitC_BitwiseOrOp : EmitC_BinaryOp<"bitwise_or", []> {
214
230
let summary = "Bitwise or operation";
215
231
let description = [{
216
232
With the `emitc.bitwise_or` operation the bitwise operator | (or)
@@ -228,8 +244,7 @@ def EmitC_BitwiseOrOp : EmitC_BinaryOp<"bitwise_or", [CExpression]> {
228
244
}];
229
245
}
230
246
231
- def EmitC_BitwiseRightShiftOp : EmitC_BinaryOp<"bitwise_right_shift",
232
- [CExpression]> {
247
+ def EmitC_BitwiseRightShiftOp : EmitC_BinaryOp<"bitwise_right_shift", []> {
233
248
let summary = "Bitwise right shift operation";
234
249
let description = [{
235
250
With the `emitc.bitwise_right_shift` operation the bitwise operator >>
@@ -247,7 +262,7 @@ def EmitC_BitwiseRightShiftOp : EmitC_BinaryOp<"bitwise_right_shift",
247
262
}];
248
263
}
249
264
250
- def EmitC_BitwiseXorOp : EmitC_BinaryOp<"bitwise_xor", [CExpression ]> {
265
+ def EmitC_BitwiseXorOp : EmitC_BinaryOp<"bitwise_xor", []> {
251
266
let summary = "Bitwise xor operation";
252
267
let description = [{
253
268
With the `emitc.bitwise_xor` operation the bitwise operator ^ (xor)
@@ -265,7 +280,7 @@ def EmitC_BitwiseXorOp : EmitC_BinaryOp<"bitwise_xor", [CExpression]> {
265
280
}];
266
281
}
267
282
268
- def EmitC_CallOpaqueOp : EmitC_Op<"call_opaque", [CExpression ]> {
283
+ def EmitC_CallOpaqueOp : EmitC_Op<"call_opaque", [CExpressionInterface ]> {
269
284
let summary = "Opaque call operation";
270
285
let description = [{
271
286
The `emitc.call_opaque` operation represents a C++ function call. The callee
@@ -312,7 +327,7 @@ def EmitC_CallOpaqueOp : EmitC_Op<"call_opaque", [CExpression]> {
312
327
}
313
328
314
329
def EmitC_CastOp : EmitC_Op<"cast",
315
- [CExpression ,
330
+ [CExpressionInterface ,
316
331
DeclareOpInterfaceMethods<CastOpInterface>]> {
317
332
let summary = "Cast operation";
318
333
let description = [{
@@ -335,9 +350,15 @@ def EmitC_CastOp : EmitC_Op<"cast",
335
350
let arguments = (ins EmitCType:$source);
336
351
let results = (outs EmitCType:$dest);
337
352
let assemblyFormat = "$source attr-dict `:` type($source) `to` type($dest)";
353
+
354
+ let extraClassDeclaration = [{
355
+ bool hasSideEffects() {
356
+ return false;
357
+ }
358
+ }];
338
359
}
339
360
340
- def EmitC_CmpOp : EmitC_BinaryOp<"cmp", [CExpression ]> {
361
+ def EmitC_CmpOp : EmitC_BinaryOp<"cmp", []> {
341
362
let summary = "Comparison operation";
342
363
let description = [{
343
364
With the `emitc.cmp` operation the comparison operators ==, !=, <, <=, >, >=, <=>
@@ -407,7 +428,7 @@ def EmitC_ConstantOp : EmitC_Op<"constant", [ConstantLike]> {
407
428
let hasVerifier = 1;
408
429
}
409
430
410
- def EmitC_DivOp : EmitC_BinaryOp<"div", [CExpression ]> {
431
+ def EmitC_DivOp : EmitC_BinaryOp<"div", []> {
411
432
let summary = "Division operation";
412
433
let description = [{
413
434
With the `emitc.div` operation the arithmetic operator / (division) can
@@ -462,7 +483,7 @@ def EmitC_ExpressionOp : EmitC_Op<"expression",
462
483
```
463
484
464
485
The operations allowed within expression body are EmitC operations with the
465
- CExpression trait .
486
+ CExpressionInterface interface .
466
487
467
488
When specified, the optional `do_not_inline` indicates that the expression is
468
489
to be emitted as seen above, i.e. as the rhs of an EmitC SSA value
@@ -480,18 +501,8 @@ def EmitC_ExpressionOp : EmitC_Op<"expression",
480
501
let extraClassDeclaration = [{
481
502
bool hasSideEffects() {
482
503
auto predicate = [](Operation &op) {
483
- assert(op.hasTrait<OpTrait::emitc::CExpression>() && "Expected a C expression");
484
- // Conservatively assume calls to read and write memory.
485
- if (isa<emitc::CallOpaqueOp>(op))
486
- return true;
487
- // De-referencing reads modifiable memory, address-taking has no
488
- // side-effect.
489
- auto applyOp = dyn_cast<emitc::ApplyOp>(op);
490
- if (applyOp)
491
- return applyOp.getApplicableOperator() == "*";
492
- // Any load operation is assumed to read from memory and thus perform
493
- // a side effect.
494
- return isa<emitc::LoadOp>(op);
504
+ assert(isa<emitc::CExpressionInterface>(op) && "Expected a C expression");
505
+ return cast<emitc::CExpressionInterface>(op).hasSideEffects();
495
506
};
496
507
return llvm::any_of(getRegion().front().without_terminator(), predicate);
497
508
};
@@ -579,7 +590,7 @@ def EmitC_ForOp : EmitC_Op<"for",
579
590
}
580
591
581
592
def EmitC_CallOp : EmitC_Op<"call",
582
- [CallOpInterface, CExpression ,
593
+ [CallOpInterface, CExpressionInterface ,
583
594
DeclareOpInterfaceMethods<SymbolUserOpInterface>]> {
584
595
let summary = "Call operation";
585
596
let description = [{
@@ -649,6 +660,10 @@ def EmitC_CallOp : EmitC_Op<"call",
649
660
void setCalleeFromCallable(CallInterfaceCallable callee) {
650
661
(*this)->setAttr("callee", cast<SymbolRefAttr>(callee));
651
662
}
663
+
664
+ bool hasSideEffects() {
665
+ return false;
666
+ }
652
667
}];
653
668
654
669
let assemblyFormat = [{
@@ -861,7 +876,7 @@ def EmitC_LiteralOp : EmitC_Op<"literal", [Pure]> {
861
876
let assemblyFormat = "$value attr-dict `:` type($result)";
862
877
}
863
878
864
- def EmitC_LogicalAndOp : EmitC_BinaryOp<"logical_and", [CExpression ]> {
879
+ def EmitC_LogicalAndOp : EmitC_BinaryOp<"logical_and", []> {
865
880
let summary = "Logical and operation";
866
881
let description = [{
867
882
With the `emitc.logical_and` operation the logical operator && (and) can
@@ -882,7 +897,7 @@ def EmitC_LogicalAndOp : EmitC_BinaryOp<"logical_and", [CExpression]> {
882
897
let assemblyFormat = "operands attr-dict `:` type(operands)";
883
898
}
884
899
885
- def EmitC_LogicalNotOp : EmitC_UnaryOp<"logical_not", [CExpression ]> {
900
+ def EmitC_LogicalNotOp : EmitC_UnaryOp<"logical_not", []> {
886
901
let summary = "Logical not operation";
887
902
let description = [{
888
903
With the `emitc.logical_not` operation the logical operator ! (negation) can
@@ -903,7 +918,7 @@ def EmitC_LogicalNotOp : EmitC_UnaryOp<"logical_not", [CExpression]> {
903
918
let assemblyFormat = "operands attr-dict `:` type(operands)";
904
919
}
905
920
906
- def EmitC_LogicalOrOp : EmitC_BinaryOp<"logical_or", [CExpression ]> {
921
+ def EmitC_LogicalOrOp : EmitC_BinaryOp<"logical_or", []> {
907
922
let summary = "Logical or operation";
908
923
let description = [{
909
924
With the `emitc.logical_or` operation the logical operator || (inclusive or)
@@ -924,7 +939,7 @@ def EmitC_LogicalOrOp : EmitC_BinaryOp<"logical_or", [CExpression]> {
924
939
let assemblyFormat = "operands attr-dict `:` type(operands)";
925
940
}
926
941
927
- def EmitC_LoadOp : EmitC_Op<"load", [CExpression ,
942
+ def EmitC_LoadOp : EmitC_Op<"load", [CExpressionInterface ,
928
943
TypesMatchWith<"result type matches value type of 'operand'",
929
944
"operand", "result",
930
945
"::llvm::cast<LValueType>($_self).getValueType()">
@@ -953,7 +968,7 @@ def EmitC_LoadOp : EmitC_Op<"load", [CExpression,
953
968
let assemblyFormat = "$operand attr-dict `:` type($operand)";
954
969
}
955
970
956
- def EmitC_MulOp : EmitC_BinaryOp<"mul", [CExpression ]> {
971
+ def EmitC_MulOp : EmitC_BinaryOp<"mul", []> {
957
972
let summary = "Multiplication operation";
958
973
let description = [{
959
974
With the `emitc.mul` operation the arithmetic operator * (multiplication) can
@@ -977,7 +992,7 @@ def EmitC_MulOp : EmitC_BinaryOp<"mul", [CExpression]> {
977
992
let results = (outs FloatIntegerIndexOrOpaqueType);
978
993
}
979
994
980
- def EmitC_RemOp : EmitC_BinaryOp<"rem", [CExpression ]> {
995
+ def EmitC_RemOp : EmitC_BinaryOp<"rem", []> {
981
996
let summary = "Remainder operation";
982
997
let description = [{
983
998
With the `emitc.rem` operation the arithmetic operator % (remainder) can
@@ -999,7 +1014,7 @@ def EmitC_RemOp : EmitC_BinaryOp<"rem", [CExpression]> {
999
1014
let results = (outs IntegerIndexOrOpaqueType);
1000
1015
}
1001
1016
1002
- def EmitC_SubOp : EmitC_BinaryOp<"sub", [CExpression ]> {
1017
+ def EmitC_SubOp : EmitC_BinaryOp<"sub", []> {
1003
1018
let summary = "Subtraction operation";
1004
1019
let description = [{
1005
1020
With the `emitc.sub` operation the arithmetic operator - (subtraction) can
@@ -1069,7 +1084,7 @@ def EmitC_MemberOfPtrOp : EmitC_Op<"member_of_ptr"> {
1069
1084
}
1070
1085
1071
1086
def EmitC_ConditionalOp : EmitC_Op<"conditional",
1072
- [AllTypesMatch<["true_value", "false_value", "result"]>, CExpression ]> {
1087
+ [AllTypesMatch<["true_value", "false_value", "result"]>, CExpressionInterface ]> {
1073
1088
let summary = "Conditional (ternary) operation";
1074
1089
let description = [{
1075
1090
With the `emitc.conditional` operation the ternary conditional operator can
@@ -1096,9 +1111,15 @@ def EmitC_ConditionalOp : EmitC_Op<"conditional",
1096
1111
let arguments = (ins I1:$condition, EmitCType:$true_value, EmitCType:$false_value);
1097
1112
let results = (outs EmitCType:$result);
1098
1113
let assemblyFormat = "operands attr-dict `:` type($result)";
1114
+
1115
+ let extraClassDeclaration = [{
1116
+ bool hasSideEffects() {
1117
+ return false;
1118
+ }
1119
+ }];
1099
1120
}
1100
1121
1101
- def EmitC_UnaryMinusOp : EmitC_UnaryOp<"unary_minus", [CExpression ]> {
1122
+ def EmitC_UnaryMinusOp : EmitC_UnaryOp<"unary_minus", []> {
1102
1123
let summary = "Unary minus operation";
1103
1124
let description = [{
1104
1125
With the `emitc.unary_minus` operation the unary operator - (minus) can be
@@ -1116,7 +1137,7 @@ def EmitC_UnaryMinusOp : EmitC_UnaryOp<"unary_minus", [CExpression]> {
1116
1137
}];
1117
1138
}
1118
1139
1119
- def EmitC_UnaryPlusOp : EmitC_UnaryOp<"unary_plus", [CExpression ]> {
1140
+ def EmitC_UnaryPlusOp : EmitC_UnaryOp<"unary_plus", []> {
1120
1141
let summary = "Unary plus operation";
1121
1142
let description = [{
1122
1143
With the `emitc.unary_plus` operation the unary operator + (plus) can be
0 commit comments