1414#define MLIR_DIALECT_EMITC_IR_EMITC
1515
1616include "mlir/Dialect/EmitC/IR/EmitCAttributes.td"
17+ include "mlir/Dialect/EmitC/IR/EmitCInterfaces.td"
1718include "mlir/Dialect/EmitC/IR/EmitCTypes.td"
1819
1920include "mlir/Interfaces/CallInterfaces.td"
@@ -35,22 +36,31 @@ class EmitC_Op<string mnemonic, list<Trait> traits = []>
3536
3637// Base class for unary operations.
3738class EmitC_UnaryOp<string mnemonic, list<Trait> traits = []> :
38- EmitC_Op<mnemonic, traits> {
39+ EmitC_Op<mnemonic, !listconcat( traits, [CExpressionInterface]) > {
3940 let arguments = (ins EmitCType);
4041 let results = (outs EmitCType);
4142 let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
43+
44+ let extraClassDeclaration = [{
45+ bool hasSideEffects() {
46+ return false;
47+ }
48+ }];
4249}
4350
4451// Base class for binary operations.
4552class EmitC_BinaryOp<string mnemonic, list<Trait> traits = []> :
46- EmitC_Op<mnemonic, traits> {
53+ EmitC_Op<mnemonic, !listconcat( traits, [CExpressionInterface]) > {
4754 let arguments = (ins EmitCType:$lhs, EmitCType:$rhs);
4855 let results = (outs EmitCType);
4956 let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
50- }
5157
52- // EmitC OpTrait
53- def CExpression : NativeOpTrait<"emitc::CExpression">;
58+ let extraClassDeclaration = [{
59+ bool hasSideEffects() {
60+ return false;
61+ }
62+ }];
63+ }
5464
5565// Types only used in binary arithmetic operations.
5666def IntegerIndexOrOpaqueType : Type<CPred<"emitc::isIntegerIndexOrOpaqueType($_self)">,
@@ -103,7 +113,7 @@ def EmitC_FileOp
103113 let skipDefaultBuilders = 1;
104114}
105115
106- def EmitC_AddOp : EmitC_BinaryOp<"add", [CExpression ]> {
116+ def EmitC_AddOp : EmitC_BinaryOp<"add", []> {
107117 let summary = "Addition operation";
108118 let description = [{
109119 With the `emitc.add` operation the arithmetic operator + (addition) can
@@ -126,7 +136,7 @@ def EmitC_AddOp : EmitC_BinaryOp<"add", [CExpression]> {
126136 let hasVerifier = 1;
127137}
128138
129- def EmitC_ApplyOp : EmitC_Op<"apply", [CExpression ]> {
139+ def EmitC_ApplyOp : EmitC_Op<"apply", [CExpressionInterface ]> {
130140 let summary = "Apply operation";
131141 let description = [{
132142 With the `emitc.apply` operation the operators & (address of) and * (contents of)
@@ -152,10 +162,17 @@ def EmitC_ApplyOp : EmitC_Op<"apply", [CExpression]> {
152162 let assemblyFormat = [{
153163 $applicableOperator `(` $operand `)` attr-dict `:` functional-type($operand, results)
154164 }];
165+
166+ let extraClassDeclaration = [{
167+ bool hasSideEffects() {
168+ return getApplicableOperator() == "*";
169+ }
170+ }];
171+
155172 let hasVerifier = 1;
156173}
157174
158- def EmitC_BitwiseAndOp : EmitC_BinaryOp<"bitwise_and", [CExpression ]> {
175+ def EmitC_BitwiseAndOp : EmitC_BinaryOp<"bitwise_and", []> {
159176 let summary = "Bitwise and operation";
160177 let description = [{
161178 With the `emitc.bitwise_and` operation the bitwise operator & (and) can
@@ -173,8 +190,7 @@ def EmitC_BitwiseAndOp : EmitC_BinaryOp<"bitwise_and", [CExpression]> {
173190 }];
174191}
175192
176- def EmitC_BitwiseLeftShiftOp : EmitC_BinaryOp<"bitwise_left_shift",
177- [CExpression]> {
193+ def EmitC_BitwiseLeftShiftOp : EmitC_BinaryOp<"bitwise_left_shift", []> {
178194 let summary = "Bitwise left shift operation";
179195 let description = [{
180196 With the `emitc.bitwise_left_shift` operation the bitwise operator <<
@@ -192,7 +208,7 @@ def EmitC_BitwiseLeftShiftOp : EmitC_BinaryOp<"bitwise_left_shift",
192208 }];
193209}
194210
195- def EmitC_BitwiseNotOp : EmitC_UnaryOp<"bitwise_not", [CExpression ]> {
211+ def EmitC_BitwiseNotOp : EmitC_UnaryOp<"bitwise_not", []> {
196212 let summary = "Bitwise not operation";
197213 let description = [{
198214 With the `emitc.bitwise_not` operation the bitwise operator ~ (not) can
@@ -210,7 +226,7 @@ def EmitC_BitwiseNotOp : EmitC_UnaryOp<"bitwise_not", [CExpression]> {
210226 }];
211227}
212228
213- def EmitC_BitwiseOrOp : EmitC_BinaryOp<"bitwise_or", [CExpression ]> {
229+ def EmitC_BitwiseOrOp : EmitC_BinaryOp<"bitwise_or", []> {
214230 let summary = "Bitwise or operation";
215231 let description = [{
216232 With the `emitc.bitwise_or` operation the bitwise operator | (or)
@@ -228,8 +244,7 @@ def EmitC_BitwiseOrOp : EmitC_BinaryOp<"bitwise_or", [CExpression]> {
228244 }];
229245}
230246
231- def EmitC_BitwiseRightShiftOp : EmitC_BinaryOp<"bitwise_right_shift",
232- [CExpression]> {
247+ def EmitC_BitwiseRightShiftOp : EmitC_BinaryOp<"bitwise_right_shift", []> {
233248 let summary = "Bitwise right shift operation";
234249 let description = [{
235250 With the `emitc.bitwise_right_shift` operation the bitwise operator >>
@@ -247,7 +262,7 @@ def EmitC_BitwiseRightShiftOp : EmitC_BinaryOp<"bitwise_right_shift",
247262 }];
248263}
249264
250- def EmitC_BitwiseXorOp : EmitC_BinaryOp<"bitwise_xor", [CExpression ]> {
265+ def EmitC_BitwiseXorOp : EmitC_BinaryOp<"bitwise_xor", []> {
251266 let summary = "Bitwise xor operation";
252267 let description = [{
253268 With the `emitc.bitwise_xor` operation the bitwise operator ^ (xor)
@@ -265,7 +280,7 @@ def EmitC_BitwiseXorOp : EmitC_BinaryOp<"bitwise_xor", [CExpression]> {
265280 }];
266281}
267282
268- def EmitC_CallOpaqueOp : EmitC_Op<"call_opaque", [CExpression ]> {
283+ def EmitC_CallOpaqueOp : EmitC_Op<"call_opaque", [CExpressionInterface ]> {
269284 let summary = "Opaque call operation";
270285 let description = [{
271286 The `emitc.call_opaque` operation represents a C++ function call. The callee
@@ -312,7 +327,7 @@ def EmitC_CallOpaqueOp : EmitC_Op<"call_opaque", [CExpression]> {
312327}
313328
314329def EmitC_CastOp : EmitC_Op<"cast",
315- [CExpression ,
330+ [CExpressionInterface ,
316331 DeclareOpInterfaceMethods<CastOpInterface>]> {
317332 let summary = "Cast operation";
318333 let description = [{
@@ -335,9 +350,15 @@ def EmitC_CastOp : EmitC_Op<"cast",
335350 let arguments = (ins EmitCType:$source);
336351 let results = (outs EmitCType:$dest);
337352 let assemblyFormat = "$source attr-dict `:` type($source) `to` type($dest)";
353+
354+ let extraClassDeclaration = [{
355+ bool hasSideEffects() {
356+ return false;
357+ }
358+ }];
338359}
339360
340- def EmitC_CmpOp : EmitC_BinaryOp<"cmp", [CExpression ]> {
361+ def EmitC_CmpOp : EmitC_BinaryOp<"cmp", []> {
341362 let summary = "Comparison operation";
342363 let description = [{
343364 With the `emitc.cmp` operation the comparison operators ==, !=, <, <=, >, >=, <=>
@@ -407,7 +428,7 @@ def EmitC_ConstantOp : EmitC_Op<"constant", [ConstantLike]> {
407428 let hasVerifier = 1;
408429}
409430
410- def EmitC_DivOp : EmitC_BinaryOp<"div", [CExpression ]> {
431+ def EmitC_DivOp : EmitC_BinaryOp<"div", []> {
411432 let summary = "Division operation";
412433 let description = [{
413434 With the `emitc.div` operation the arithmetic operator / (division) can
@@ -462,7 +483,7 @@ def EmitC_ExpressionOp : EmitC_Op<"expression",
462483 ```
463484
464485 The operations allowed within expression body are EmitC operations with the
465- CExpression trait .
486+ CExpressionInterface interface .
466487
467488 When specified, the optional `do_not_inline` indicates that the expression is
468489 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",
480501 let extraClassDeclaration = [{
481502 bool hasSideEffects() {
482503 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();
495506 };
496507 return llvm::any_of(getRegion().front().without_terminator(), predicate);
497508 };
@@ -579,7 +590,7 @@ def EmitC_ForOp : EmitC_Op<"for",
579590}
580591
581592def EmitC_CallOp : EmitC_Op<"call",
582- [CallOpInterface, CExpression ,
593+ [CallOpInterface, CExpressionInterface ,
583594 DeclareOpInterfaceMethods<SymbolUserOpInterface>]> {
584595 let summary = "Call operation";
585596 let description = [{
@@ -649,6 +660,10 @@ def EmitC_CallOp : EmitC_Op<"call",
649660 void setCalleeFromCallable(CallInterfaceCallable callee) {
650661 (*this)->setAttr("callee", cast<SymbolRefAttr>(callee));
651662 }
663+
664+ bool hasSideEffects() {
665+ return false;
666+ }
652667 }];
653668
654669 let assemblyFormat = [{
@@ -861,7 +876,7 @@ def EmitC_LiteralOp : EmitC_Op<"literal", [Pure]> {
861876 let assemblyFormat = "$value attr-dict `:` type($result)";
862877}
863878
864- def EmitC_LogicalAndOp : EmitC_BinaryOp<"logical_and", [CExpression ]> {
879+ def EmitC_LogicalAndOp : EmitC_BinaryOp<"logical_and", []> {
865880 let summary = "Logical and operation";
866881 let description = [{
867882 With the `emitc.logical_and` operation the logical operator && (and) can
@@ -882,7 +897,7 @@ def EmitC_LogicalAndOp : EmitC_BinaryOp<"logical_and", [CExpression]> {
882897 let assemblyFormat = "operands attr-dict `:` type(operands)";
883898}
884899
885- def EmitC_LogicalNotOp : EmitC_UnaryOp<"logical_not", [CExpression ]> {
900+ def EmitC_LogicalNotOp : EmitC_UnaryOp<"logical_not", []> {
886901 let summary = "Logical not operation";
887902 let description = [{
888903 With the `emitc.logical_not` operation the logical operator ! (negation) can
@@ -903,7 +918,7 @@ def EmitC_LogicalNotOp : EmitC_UnaryOp<"logical_not", [CExpression]> {
903918 let assemblyFormat = "operands attr-dict `:` type(operands)";
904919}
905920
906- def EmitC_LogicalOrOp : EmitC_BinaryOp<"logical_or", [CExpression ]> {
921+ def EmitC_LogicalOrOp : EmitC_BinaryOp<"logical_or", []> {
907922 let summary = "Logical or operation";
908923 let description = [{
909924 With the `emitc.logical_or` operation the logical operator || (inclusive or)
@@ -924,7 +939,7 @@ def EmitC_LogicalOrOp : EmitC_BinaryOp<"logical_or", [CExpression]> {
924939 let assemblyFormat = "operands attr-dict `:` type(operands)";
925940}
926941
927- def EmitC_LoadOp : EmitC_Op<"load", [CExpression ,
942+ def EmitC_LoadOp : EmitC_Op<"load", [CExpressionInterface ,
928943 TypesMatchWith<"result type matches value type of 'operand'",
929944 "operand", "result",
930945 "::llvm::cast<LValueType>($_self).getValueType()">
@@ -953,7 +968,7 @@ def EmitC_LoadOp : EmitC_Op<"load", [CExpression,
953968 let assemblyFormat = "$operand attr-dict `:` type($operand)";
954969}
955970
956- def EmitC_MulOp : EmitC_BinaryOp<"mul", [CExpression ]> {
971+ def EmitC_MulOp : EmitC_BinaryOp<"mul", []> {
957972 let summary = "Multiplication operation";
958973 let description = [{
959974 With the `emitc.mul` operation the arithmetic operator * (multiplication) can
@@ -977,7 +992,7 @@ def EmitC_MulOp : EmitC_BinaryOp<"mul", [CExpression]> {
977992 let results = (outs FloatIntegerIndexOrOpaqueType);
978993}
979994
980- def EmitC_RemOp : EmitC_BinaryOp<"rem", [CExpression ]> {
995+ def EmitC_RemOp : EmitC_BinaryOp<"rem", []> {
981996 let summary = "Remainder operation";
982997 let description = [{
983998 With the `emitc.rem` operation the arithmetic operator % (remainder) can
@@ -999,7 +1014,7 @@ def EmitC_RemOp : EmitC_BinaryOp<"rem", [CExpression]> {
9991014 let results = (outs IntegerIndexOrOpaqueType);
10001015}
10011016
1002- def EmitC_SubOp : EmitC_BinaryOp<"sub", [CExpression ]> {
1017+ def EmitC_SubOp : EmitC_BinaryOp<"sub", []> {
10031018 let summary = "Subtraction operation";
10041019 let description = [{
10051020 With the `emitc.sub` operation the arithmetic operator - (subtraction) can
@@ -1069,7 +1084,7 @@ def EmitC_MemberOfPtrOp : EmitC_Op<"member_of_ptr"> {
10691084}
10701085
10711086def EmitC_ConditionalOp : EmitC_Op<"conditional",
1072- [AllTypesMatch<["true_value", "false_value", "result"]>, CExpression ]> {
1087+ [AllTypesMatch<["true_value", "false_value", "result"]>, CExpressionInterface ]> {
10731088 let summary = "Conditional (ternary) operation";
10741089 let description = [{
10751090 With the `emitc.conditional` operation the ternary conditional operator can
@@ -1096,9 +1111,15 @@ def EmitC_ConditionalOp : EmitC_Op<"conditional",
10961111 let arguments = (ins I1:$condition, EmitCType:$true_value, EmitCType:$false_value);
10971112 let results = (outs EmitCType:$result);
10981113 let assemblyFormat = "operands attr-dict `:` type($result)";
1114+
1115+ let extraClassDeclaration = [{
1116+ bool hasSideEffects() {
1117+ return false;
1118+ }
1119+ }];
10991120}
11001121
1101- def EmitC_UnaryMinusOp : EmitC_UnaryOp<"unary_minus", [CExpression ]> {
1122+ def EmitC_UnaryMinusOp : EmitC_UnaryOp<"unary_minus", []> {
11021123 let summary = "Unary minus operation";
11031124 let description = [{
11041125 With the `emitc.unary_minus` operation the unary operator - (minus) can be
@@ -1116,7 +1137,7 @@ def EmitC_UnaryMinusOp : EmitC_UnaryOp<"unary_minus", [CExpression]> {
11161137 }];
11171138}
11181139
1119- def EmitC_UnaryPlusOp : EmitC_UnaryOp<"unary_plus", [CExpression ]> {
1140+ def EmitC_UnaryPlusOp : EmitC_UnaryOp<"unary_plus", []> {
11201141 let summary = "Unary plus operation";
11211142 let description = [{
11221143 With the `emitc.unary_plus` operation the unary operator + (plus) can be
0 commit comments