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
@@ -312,7 +329,7 @@ def EmitC_CallOpaqueOp : EmitC_Op<"call_opaque", [CExpression]> {
312
329
}
313
330
314
331
def EmitC_CastOp : EmitC_Op<"cast",
315
- [CExpression ,
332
+ [CExpressionInterface ,
316
333
DeclareOpInterfaceMethods<CastOpInterface>]> {
317
334
let summary = "Cast operation";
318
335
let description = [{
@@ -335,9 +352,15 @@ def EmitC_CastOp : EmitC_Op<"cast",
335
352
let arguments = (ins EmitCType:$source);
336
353
let results = (outs EmitCType:$dest);
337
354
let assemblyFormat = "$source attr-dict `:` type($source) `to` type($dest)";
355
+
356
+ let extraClassDeclaration = [{
357
+ bool hasSideEffects() {
358
+ return false;
359
+ }
360
+ }];
338
361
}
339
362
340
- def EmitC_CmpOp : EmitC_BinaryOp<"cmp", [CExpression ]> {
363
+ def EmitC_CmpOp : EmitC_BinaryOp<"cmp", [CExpressionInterface ]> {
341
364
let summary = "Comparison operation";
342
365
let description = [{
343
366
With the `emitc.cmp` operation the comparison operators ==, !=, <, <=, >, >=, <=>
@@ -407,7 +430,7 @@ def EmitC_ConstantOp : EmitC_Op<"constant", [ConstantLike]> {
407
430
let hasVerifier = 1;
408
431
}
409
432
410
- def EmitC_DivOp : EmitC_BinaryOp<"div", [CExpression ]> {
433
+ def EmitC_DivOp : EmitC_BinaryOp<"div", [CExpressionInterface ]> {
411
434
let summary = "Division operation";
412
435
let description = [{
413
436
With the `emitc.div` operation the arithmetic operator / (division) can
@@ -462,7 +485,7 @@ def EmitC_ExpressionOp : EmitC_Op<"expression",
462
485
```
463
486
464
487
The operations allowed within expression body are EmitC operations with the
465
- CExpression trait .
488
+ CExpressionInterface interface .
466
489
467
490
When specified, the optional `do_not_inline` indicates that the expression is
468
491
to be emitted as seen above, i.e. as the rhs of an EmitC SSA value
@@ -480,18 +503,8 @@ def EmitC_ExpressionOp : EmitC_Op<"expression",
480
503
let extraClassDeclaration = [{
481
504
bool hasSideEffects() {
482
505
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);
506
+ assert(isa<emitc::CExpressionInterface>(op) && "Expected a C expression");
507
+ return cast<emitc::CExpressionInterface>(op).hasSideEffects();
495
508
};
496
509
return llvm::any_of(getRegion().front().without_terminator(), predicate);
497
510
};
@@ -579,7 +592,7 @@ def EmitC_ForOp : EmitC_Op<"for",
579
592
}
580
593
581
594
def EmitC_CallOp : EmitC_Op<"call",
582
- [CallOpInterface, CExpression ,
595
+ [CallOpInterface, CExpressionInterface ,
583
596
DeclareOpInterfaceMethods<SymbolUserOpInterface>]> {
584
597
let summary = "Call operation";
585
598
let description = [{
@@ -649,6 +662,10 @@ def EmitC_CallOp : EmitC_Op<"call",
649
662
void setCalleeFromCallable(CallInterfaceCallable callee) {
650
663
(*this)->setAttr("callee", cast<SymbolRefAttr>(callee));
651
664
}
665
+
666
+ bool hasSideEffects() {
667
+ return false;
668
+ }
652
669
}];
653
670
654
671
let assemblyFormat = [{
@@ -861,7 +878,7 @@ def EmitC_LiteralOp : EmitC_Op<"literal", [Pure]> {
861
878
let assemblyFormat = "$value attr-dict `:` type($result)";
862
879
}
863
880
864
- def EmitC_LogicalAndOp : EmitC_BinaryOp<"logical_and", [CExpression ]> {
881
+ def EmitC_LogicalAndOp : EmitC_BinaryOp<"logical_and", [CExpressionInterface ]> {
865
882
let summary = "Logical and operation";
866
883
let description = [{
867
884
With the `emitc.logical_and` operation the logical operator && (and) can
@@ -882,7 +899,7 @@ def EmitC_LogicalAndOp : EmitC_BinaryOp<"logical_and", [CExpression]> {
882
899
let assemblyFormat = "operands attr-dict `:` type(operands)";
883
900
}
884
901
885
- def EmitC_LogicalNotOp : EmitC_UnaryOp<"logical_not", [CExpression ]> {
902
+ def EmitC_LogicalNotOp : EmitC_UnaryOp<"logical_not", [CExpressionInterface ]> {
886
903
let summary = "Logical not operation";
887
904
let description = [{
888
905
With the `emitc.logical_not` operation the logical operator ! (negation) can
@@ -903,7 +920,7 @@ def EmitC_LogicalNotOp : EmitC_UnaryOp<"logical_not", [CExpression]> {
903
920
let assemblyFormat = "operands attr-dict `:` type(operands)";
904
921
}
905
922
906
- def EmitC_LogicalOrOp : EmitC_BinaryOp<"logical_or", [CExpression ]> {
923
+ def EmitC_LogicalOrOp : EmitC_BinaryOp<"logical_or", [CExpressionInterface ]> {
907
924
let summary = "Logical or operation";
908
925
let description = [{
909
926
With the `emitc.logical_or` operation the logical operator || (inclusive or)
@@ -924,7 +941,7 @@ def EmitC_LogicalOrOp : EmitC_BinaryOp<"logical_or", [CExpression]> {
924
941
let assemblyFormat = "operands attr-dict `:` type(operands)";
925
942
}
926
943
927
- def EmitC_LoadOp : EmitC_Op<"load", [CExpression ,
944
+ def EmitC_LoadOp : EmitC_Op<"load", [CExpressionInterface ,
928
945
TypesMatchWith<"result type matches value type of 'operand'",
929
946
"operand", "result",
930
947
"::llvm::cast<LValueType>($_self).getValueType()">
@@ -953,7 +970,7 @@ def EmitC_LoadOp : EmitC_Op<"load", [CExpression,
953
970
let assemblyFormat = "$operand attr-dict `:` type($operand)";
954
971
}
955
972
956
- def EmitC_MulOp : EmitC_BinaryOp<"mul", [CExpression ]> {
973
+ def EmitC_MulOp : EmitC_BinaryOp<"mul", [CExpressionInterface ]> {
957
974
let summary = "Multiplication operation";
958
975
let description = [{
959
976
With the `emitc.mul` operation the arithmetic operator * (multiplication) can
@@ -977,7 +994,7 @@ def EmitC_MulOp : EmitC_BinaryOp<"mul", [CExpression]> {
977
994
let results = (outs FloatIntegerIndexOrOpaqueType);
978
995
}
979
996
980
- def EmitC_RemOp : EmitC_BinaryOp<"rem", [CExpression ]> {
997
+ def EmitC_RemOp : EmitC_BinaryOp<"rem", [CExpressionInterface ]> {
981
998
let summary = "Remainder operation";
982
999
let description = [{
983
1000
With the `emitc.rem` operation the arithmetic operator % (remainder) can
@@ -999,7 +1016,7 @@ def EmitC_RemOp : EmitC_BinaryOp<"rem", [CExpression]> {
999
1016
let results = (outs IntegerIndexOrOpaqueType);
1000
1017
}
1001
1018
1002
- def EmitC_SubOp : EmitC_BinaryOp<"sub", [CExpression ]> {
1019
+ def EmitC_SubOp : EmitC_BinaryOp<"sub", [CExpressionInterface ]> {
1003
1020
let summary = "Subtraction operation";
1004
1021
let description = [{
1005
1022
With the `emitc.sub` operation the arithmetic operator - (subtraction) can
@@ -1069,7 +1086,7 @@ def EmitC_MemberOfPtrOp : EmitC_Op<"member_of_ptr"> {
1069
1086
}
1070
1087
1071
1088
def EmitC_ConditionalOp : EmitC_Op<"conditional",
1072
- [AllTypesMatch<["true_value", "false_value", "result"]>, CExpression ]> {
1089
+ [AllTypesMatch<["true_value", "false_value", "result"]>, CExpressionInterface ]> {
1073
1090
let summary = "Conditional (ternary) operation";
1074
1091
let description = [{
1075
1092
With the `emitc.conditional` operation the ternary conditional operator can
@@ -1096,9 +1113,15 @@ def EmitC_ConditionalOp : EmitC_Op<"conditional",
1096
1113
let arguments = (ins I1:$condition, EmitCType:$true_value, EmitCType:$false_value);
1097
1114
let results = (outs EmitCType:$result);
1098
1115
let assemblyFormat = "operands attr-dict `:` type($result)";
1116
+
1117
+ let extraClassDeclaration = [{
1118
+ bool hasSideEffects() {
1119
+ return false;
1120
+ }
1121
+ }];
1099
1122
}
1100
1123
1101
- def EmitC_UnaryMinusOp : EmitC_UnaryOp<"unary_minus", [CExpression ]> {
1124
+ def EmitC_UnaryMinusOp : EmitC_UnaryOp<"unary_minus", [CExpressionInterface ]> {
1102
1125
let summary = "Unary minus operation";
1103
1126
let description = [{
1104
1127
With the `emitc.unary_minus` operation the unary operator - (minus) can be
@@ -1116,7 +1139,7 @@ def EmitC_UnaryMinusOp : EmitC_UnaryOp<"unary_minus", [CExpression]> {
1116
1139
}];
1117
1140
}
1118
1141
1119
- def EmitC_UnaryPlusOp : EmitC_UnaryOp<"unary_plus", [CExpression ]> {
1142
+ def EmitC_UnaryPlusOp : EmitC_UnaryOp<"unary_plus", [CExpressionInterface ]> {
1120
1143
let summary = "Unary plus operation";
1121
1144
let description = [{
1122
1145
With the `emitc.unary_plus` operation the unary operator + (plus) can be
0 commit comments