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"
@@ -39,6 +40,12 @@ class EmitC_UnaryOp<string mnemonic, list<Trait> traits = []> :
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.
@@ -47,10 +54,13 @@ class EmitC_BinaryOp<string mnemonic, list<Trait> traits = []> :
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", [CExpressionInterface ]> {
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", [CExpressionInterface ]> {
159
176
let summary = "Bitwise and operation";
160
177
let description = [{
161
178
With the `emitc.bitwise_and` operation the bitwise operator & (and) can
@@ -174,7 +191,7 @@ def EmitC_BitwiseAndOp : EmitC_BinaryOp<"bitwise_and", [CExpression]> {
174
191
}
175
192
176
193
def EmitC_BitwiseLeftShiftOp : EmitC_BinaryOp<"bitwise_left_shift",
177
- [CExpression ]> {
194
+ [CExpressionInterface ]> {
178
195
let summary = "Bitwise left shift operation";
179
196
let description = [{
180
197
With the `emitc.bitwise_left_shift` operation the bitwise operator <<
@@ -192,7 +209,7 @@ def EmitC_BitwiseLeftShiftOp : EmitC_BinaryOp<"bitwise_left_shift",
192
209
}];
193
210
}
194
211
195
- def EmitC_BitwiseNotOp : EmitC_UnaryOp<"bitwise_not", [CExpression ]> {
212
+ def EmitC_BitwiseNotOp : EmitC_UnaryOp<"bitwise_not", [CExpressionInterface ]> {
196
213
let summary = "Bitwise not operation";
197
214
let description = [{
198
215
With the `emitc.bitwise_not` operation the bitwise operator ~ (not) can
@@ -210,7 +227,7 @@ def EmitC_BitwiseNotOp : EmitC_UnaryOp<"bitwise_not", [CExpression]> {
210
227
}];
211
228
}
212
229
213
- def EmitC_BitwiseOrOp : EmitC_BinaryOp<"bitwise_or", [CExpression ]> {
230
+ def EmitC_BitwiseOrOp : EmitC_BinaryOp<"bitwise_or", [CExpressionInterface ]> {
214
231
let summary = "Bitwise or operation";
215
232
let description = [{
216
233
With the `emitc.bitwise_or` operation the bitwise operator | (or)
@@ -229,7 +246,7 @@ def EmitC_BitwiseOrOp : EmitC_BinaryOp<"bitwise_or", [CExpression]> {
229
246
}
230
247
231
248
def EmitC_BitwiseRightShiftOp : EmitC_BinaryOp<"bitwise_right_shift",
232
- [CExpression ]> {
249
+ [CExpressionInterface ]> {
233
250
let summary = "Bitwise right shift operation";
234
251
let description = [{
235
252
With the `emitc.bitwise_right_shift` operation the bitwise operator >>
@@ -247,7 +264,7 @@ def EmitC_BitwiseRightShiftOp : EmitC_BinaryOp<"bitwise_right_shift",
247
264
}];
248
265
}
249
266
250
- def EmitC_BitwiseXorOp : EmitC_BinaryOp<"bitwise_xor", [CExpression ]> {
267
+ def EmitC_BitwiseXorOp : EmitC_BinaryOp<"bitwise_xor", [CExpressionInterface ]> {
251
268
let summary = "Bitwise xor operation";
252
269
let description = [{
253
270
With the `emitc.bitwise_xor` operation the bitwise operator ^ (xor)
@@ -265,7 +282,7 @@ def EmitC_BitwiseXorOp : EmitC_BinaryOp<"bitwise_xor", [CExpression]> {
265
282
}];
266
283
}
267
284
268
- def EmitC_CallOpaqueOp : EmitC_Op<"call_opaque", [CExpression ]> {
285
+ def EmitC_CallOpaqueOp : EmitC_Op<"call_opaque", [CExpressionInterface ]> {
269
286
let summary = "Opaque call operation";
270
287
let description = [{
271
288
The `emitc.call_opaque` operation represents a C++ function call. The callee
@@ -308,11 +325,12 @@ def EmitC_CallOpaqueOp : EmitC_Op<"call_opaque", [CExpression]> {
308
325
let assemblyFormat = [{
309
326
$callee `(` $operands `)` attr-dict `:` functional-type($operands, results)
310
327
}];
328
+
311
329
let hasVerifier = 1;
312
330
}
313
331
314
332
def EmitC_CastOp : EmitC_Op<"cast",
315
- [CExpression ,
333
+ [CExpressionInterface ,
316
334
DeclareOpInterfaceMethods<CastOpInterface>]> {
317
335
let summary = "Cast operation";
318
336
let description = [{
@@ -335,9 +353,15 @@ def EmitC_CastOp : EmitC_Op<"cast",
335
353
let arguments = (ins EmitCType:$source);
336
354
let results = (outs EmitCType:$dest);
337
355
let assemblyFormat = "$source attr-dict `:` type($source) `to` type($dest)";
356
+
357
+ let extraClassDeclaration = [{
358
+ bool hasSideEffects() {
359
+ return false;
360
+ }
361
+ }];
338
362
}
339
363
340
- def EmitC_CmpOp : EmitC_BinaryOp<"cmp", [CExpression ]> {
364
+ def EmitC_CmpOp : EmitC_BinaryOp<"cmp", [CExpressionInterface ]> {
341
365
let summary = "Comparison operation";
342
366
let description = [{
343
367
With the `emitc.cmp` operation the comparison operators ==, !=, <, <=, >, >=, <=>
@@ -407,7 +431,7 @@ def EmitC_ConstantOp : EmitC_Op<"constant", [ConstantLike]> {
407
431
let hasVerifier = 1;
408
432
}
409
433
410
- def EmitC_DivOp : EmitC_BinaryOp<"div", [CExpression ]> {
434
+ def EmitC_DivOp : EmitC_BinaryOp<"div", [CExpressionInterface ]> {
411
435
let summary = "Division operation";
412
436
let description = [{
413
437
With the `emitc.div` operation the arithmetic operator / (division) can
@@ -462,7 +486,7 @@ def EmitC_ExpressionOp : EmitC_Op<"expression",
462
486
```
463
487
464
488
The operations allowed within expression body are EmitC operations with the
465
- CExpression trait .
489
+ CExpressionInterface interface .
466
490
467
491
When specified, the optional `do_not_inline` indicates that the expression is
468
492
to be emitted as seen above, i.e. as the rhs of an EmitC SSA value
@@ -480,18 +504,8 @@ def EmitC_ExpressionOp : EmitC_Op<"expression",
480
504
let extraClassDeclaration = [{
481
505
bool hasSideEffects() {
482
506
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);
507
+ assert(isa<emitc::CExpressionInterface>(op) && "Expected a C expression");
508
+ return cast<emitc::CExpressionInterface>(op).hasSideEffects();
495
509
};
496
510
return llvm::any_of(getRegion().front().without_terminator(), predicate);
497
511
};
@@ -579,7 +593,7 @@ def EmitC_ForOp : EmitC_Op<"for",
579
593
}
580
594
581
595
def EmitC_CallOp : EmitC_Op<"call",
582
- [CallOpInterface, CExpression ,
596
+ [CallOpInterface, CExpressionInterface ,
583
597
DeclareOpInterfaceMethods<SymbolUserOpInterface>]> {
584
598
let summary = "Call operation";
585
599
let description = [{
@@ -649,6 +663,10 @@ def EmitC_CallOp : EmitC_Op<"call",
649
663
void setCalleeFromCallable(CallInterfaceCallable callee) {
650
664
(*this)->setAttr("callee", cast<SymbolRefAttr>(callee));
651
665
}
666
+
667
+ bool hasSideEffects() {
668
+ return false;
669
+ }
652
670
}];
653
671
654
672
let assemblyFormat = [{
@@ -861,7 +879,7 @@ def EmitC_LiteralOp : EmitC_Op<"literal", [Pure]> {
861
879
let assemblyFormat = "$value attr-dict `:` type($result)";
862
880
}
863
881
864
- def EmitC_LogicalAndOp : EmitC_BinaryOp<"logical_and", [CExpression ]> {
882
+ def EmitC_LogicalAndOp : EmitC_BinaryOp<"logical_and", [CExpressionInterface ]> {
865
883
let summary = "Logical and operation";
866
884
let description = [{
867
885
With the `emitc.logical_and` operation the logical operator && (and) can
@@ -882,7 +900,7 @@ def EmitC_LogicalAndOp : EmitC_BinaryOp<"logical_and", [CExpression]> {
882
900
let assemblyFormat = "operands attr-dict `:` type(operands)";
883
901
}
884
902
885
- def EmitC_LogicalNotOp : EmitC_UnaryOp<"logical_not", [CExpression ]> {
903
+ def EmitC_LogicalNotOp : EmitC_UnaryOp<"logical_not", [CExpressionInterface ]> {
886
904
let summary = "Logical not operation";
887
905
let description = [{
888
906
With the `emitc.logical_not` operation the logical operator ! (negation) can
@@ -903,7 +921,7 @@ def EmitC_LogicalNotOp : EmitC_UnaryOp<"logical_not", [CExpression]> {
903
921
let assemblyFormat = "operands attr-dict `:` type(operands)";
904
922
}
905
923
906
- def EmitC_LogicalOrOp : EmitC_BinaryOp<"logical_or", [CExpression ]> {
924
+ def EmitC_LogicalOrOp : EmitC_BinaryOp<"logical_or", [CExpressionInterface ]> {
907
925
let summary = "Logical or operation";
908
926
let description = [{
909
927
With the `emitc.logical_or` operation the logical operator || (inclusive or)
@@ -924,7 +942,7 @@ def EmitC_LogicalOrOp : EmitC_BinaryOp<"logical_or", [CExpression]> {
924
942
let assemblyFormat = "operands attr-dict `:` type(operands)";
925
943
}
926
944
927
- def EmitC_LoadOp : EmitC_Op<"load", [CExpression ,
945
+ def EmitC_LoadOp : EmitC_Op<"load", [CExpressionInterface ,
928
946
TypesMatchWith<"result type matches value type of 'operand'",
929
947
"operand", "result",
930
948
"::llvm::cast<LValueType>($_self).getValueType()">
@@ -953,7 +971,7 @@ def EmitC_LoadOp : EmitC_Op<"load", [CExpression,
953
971
let assemblyFormat = "$operand attr-dict `:` type($operand)";
954
972
}
955
973
956
- def EmitC_MulOp : EmitC_BinaryOp<"mul", [CExpression ]> {
974
+ def EmitC_MulOp : EmitC_BinaryOp<"mul", [CExpressionInterface ]> {
957
975
let summary = "Multiplication operation";
958
976
let description = [{
959
977
With the `emitc.mul` operation the arithmetic operator * (multiplication) can
@@ -977,7 +995,7 @@ def EmitC_MulOp : EmitC_BinaryOp<"mul", [CExpression]> {
977
995
let results = (outs FloatIntegerIndexOrOpaqueType);
978
996
}
979
997
980
- def EmitC_RemOp : EmitC_BinaryOp<"rem", [CExpression ]> {
998
+ def EmitC_RemOp : EmitC_BinaryOp<"rem", [CExpressionInterface ]> {
981
999
let summary = "Remainder operation";
982
1000
let description = [{
983
1001
With the `emitc.rem` operation the arithmetic operator % (remainder) can
@@ -999,7 +1017,7 @@ def EmitC_RemOp : EmitC_BinaryOp<"rem", [CExpression]> {
999
1017
let results = (outs IntegerIndexOrOpaqueType);
1000
1018
}
1001
1019
1002
- def EmitC_SubOp : EmitC_BinaryOp<"sub", [CExpression ]> {
1020
+ def EmitC_SubOp : EmitC_BinaryOp<"sub", [CExpressionInterface ]> {
1003
1021
let summary = "Subtraction operation";
1004
1022
let description = [{
1005
1023
With the `emitc.sub` operation the arithmetic operator - (subtraction) can
@@ -1069,7 +1087,7 @@ def EmitC_MemberOfPtrOp : EmitC_Op<"member_of_ptr"> {
1069
1087
}
1070
1088
1071
1089
def EmitC_ConditionalOp : EmitC_Op<"conditional",
1072
- [AllTypesMatch<["true_value", "false_value", "result"]>, CExpression ]> {
1090
+ [AllTypesMatch<["true_value", "false_value", "result"]>, CExpressionInterface ]> {
1073
1091
let summary = "Conditional (ternary) operation";
1074
1092
let description = [{
1075
1093
With the `emitc.conditional` operation the ternary conditional operator can
@@ -1096,9 +1114,15 @@ def EmitC_ConditionalOp : EmitC_Op<"conditional",
1096
1114
let arguments = (ins I1:$condition, EmitCType:$true_value, EmitCType:$false_value);
1097
1115
let results = (outs EmitCType:$result);
1098
1116
let assemblyFormat = "operands attr-dict `:` type($result)";
1117
+
1118
+ let extraClassDeclaration = [{
1119
+ bool hasSideEffects() {
1120
+ return false;
1121
+ }
1122
+ }];
1099
1123
}
1100
1124
1101
- def EmitC_UnaryMinusOp : EmitC_UnaryOp<"unary_minus", [CExpression ]> {
1125
+ def EmitC_UnaryMinusOp : EmitC_UnaryOp<"unary_minus", [CExpressionInterface ]> {
1102
1126
let summary = "Unary minus operation";
1103
1127
let description = [{
1104
1128
With the `emitc.unary_minus` operation the unary operator - (minus) can be
@@ -1116,7 +1140,7 @@ def EmitC_UnaryMinusOp : EmitC_UnaryOp<"unary_minus", [CExpression]> {
1116
1140
}];
1117
1141
}
1118
1142
1119
- def EmitC_UnaryPlusOp : EmitC_UnaryOp<"unary_plus", [CExpression ]> {
1143
+ def EmitC_UnaryPlusOp : EmitC_UnaryOp<"unary_plus", [CExpressionInterface ]> {
1120
1144
let summary = "Unary plus operation";
1121
1145
let description = [{
1122
1146
With the `emitc.unary_plus` operation the unary operator + (plus) can be
0 commit comments