Skip to content

[mlir][emitc] make CExpression trait into interface #142771

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions mlir/include/mlir/Dialect/EmitC/IR/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
add_mlir_dialect(EmitC emitc)
add_mlir_doc(EmitC EmitC Dialects/ -gen-dialect-doc -dialect emitc)

set(LLVM_TARGET_DEFINITIONS EmitCInterfaces.td)
mlir_tablegen(EmitCInterfaces.h.inc -gen-op-interface-decls)
mlir_tablegen(EmitCInterfaces.cpp.inc -gen-op-interface-defs)
add_public_tablegen_target(MLIREmitCInterfacesIncGen)
add_dependencies(mlir-generic-headers MLIREmitCInterfacesIncGen)

set(LLVM_TARGET_DEFINITIONS EmitCAttributes.td)
mlir_tablegen(EmitCEnums.h.inc -gen-enum-decls)
mlir_tablegen(EmitCEnums.cpp.inc -gen-enum-defs)
Expand Down
2 changes: 1 addition & 1 deletion mlir/include/mlir/Dialect/EmitC/IR/EmitC.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#define MLIR_DIALECT_EMITC_IR_EMITC_H

#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/Dialect/EmitC/IR/EmitCTraits.h"
#include "mlir/Dialect/EmitC/IR/EmitCInterfaces.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/BuiltinTypes.h"
Expand Down
86 changes: 47 additions & 39 deletions mlir/include/mlir/Dialect/EmitC/IR/EmitC.td
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#define MLIR_DIALECT_EMITC_IR_EMITC

include "mlir/Dialect/EmitC/IR/EmitCAttributes.td"
include "mlir/Dialect/EmitC/IR/EmitCInterfaces.td"
include "mlir/Dialect/EmitC/IR/EmitCTypes.td"

include "mlir/Interfaces/CallInterfaces.td"
Expand Down Expand Up @@ -49,9 +50,6 @@ class EmitC_BinaryOp<string mnemonic, list<Trait> traits = []> :
let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
}

// EmitC OpTrait
def CExpression : NativeOpTrait<"emitc::CExpression">;

// Types only used in binary arithmetic operations.
def IntegerIndexOrOpaqueType : Type<CPred<"emitc::isIntegerIndexOrOpaqueType($_self)">,
"integer, index or opaque type supported by EmitC">;
Expand Down Expand Up @@ -103,7 +101,7 @@ def EmitC_FileOp
let skipDefaultBuilders = 1;
}

def EmitC_AddOp : EmitC_BinaryOp<"add", [CExpression]> {
def EmitC_AddOp : EmitC_BinaryOp<"add", [CExpressionInterface]> {
let summary = "Addition operation";
let description = [{
With the `emitc.add` operation the arithmetic operator + (addition) can
Expand All @@ -126,7 +124,7 @@ def EmitC_AddOp : EmitC_BinaryOp<"add", [CExpression]> {
let hasVerifier = 1;
}

def EmitC_ApplyOp : EmitC_Op<"apply", [CExpression]> {
def EmitC_ApplyOp : EmitC_Op<"apply", [CExpressionInterface]> {
let summary = "Apply operation";
let description = [{
With the `emitc.apply` operation the operators & (address of) and * (contents of)
Expand All @@ -152,10 +150,17 @@ def EmitC_ApplyOp : EmitC_Op<"apply", [CExpression]> {
let assemblyFormat = [{
$applicableOperator `(` $operand `)` attr-dict `:` functional-type($operand, results)
}];

let extraClassDeclaration = [{
bool hasSideEffects() {
return getApplicableOperator() == "*";
}
}];

let hasVerifier = 1;
}

def EmitC_BitwiseAndOp : EmitC_BinaryOp<"bitwise_and", [CExpression]> {
def EmitC_BitwiseAndOp : EmitC_BinaryOp<"bitwise_and", [CExpressionInterface]> {
let summary = "Bitwise and operation";
let description = [{
With the `emitc.bitwise_and` operation the bitwise operator & (and) can
Expand All @@ -174,7 +179,7 @@ def EmitC_BitwiseAndOp : EmitC_BinaryOp<"bitwise_and", [CExpression]> {
}

def EmitC_BitwiseLeftShiftOp : EmitC_BinaryOp<"bitwise_left_shift",
[CExpression]> {
[CExpressionInterface]> {
let summary = "Bitwise left shift operation";
let description = [{
With the `emitc.bitwise_left_shift` operation the bitwise operator <<
Expand All @@ -192,7 +197,7 @@ def EmitC_BitwiseLeftShiftOp : EmitC_BinaryOp<"bitwise_left_shift",
}];
}

def EmitC_BitwiseNotOp : EmitC_UnaryOp<"bitwise_not", [CExpression]> {
def EmitC_BitwiseNotOp : EmitC_UnaryOp<"bitwise_not", [CExpressionInterface]> {
let summary = "Bitwise not operation";
let description = [{
With the `emitc.bitwise_not` operation the bitwise operator ~ (not) can
Expand All @@ -210,7 +215,7 @@ def EmitC_BitwiseNotOp : EmitC_UnaryOp<"bitwise_not", [CExpression]> {
}];
}

def EmitC_BitwiseOrOp : EmitC_BinaryOp<"bitwise_or", [CExpression]> {
def EmitC_BitwiseOrOp : EmitC_BinaryOp<"bitwise_or", [CExpressionInterface]> {
let summary = "Bitwise or operation";
let description = [{
With the `emitc.bitwise_or` operation the bitwise operator | (or)
Expand All @@ -229,7 +234,7 @@ def EmitC_BitwiseOrOp : EmitC_BinaryOp<"bitwise_or", [CExpression]> {
}

def EmitC_BitwiseRightShiftOp : EmitC_BinaryOp<"bitwise_right_shift",
[CExpression]> {
[CExpressionInterface]> {
let summary = "Bitwise right shift operation";
let description = [{
With the `emitc.bitwise_right_shift` operation the bitwise operator >>
Expand All @@ -247,7 +252,7 @@ def EmitC_BitwiseRightShiftOp : EmitC_BinaryOp<"bitwise_right_shift",
}];
}

def EmitC_BitwiseXorOp : EmitC_BinaryOp<"bitwise_xor", [CExpression]> {
def EmitC_BitwiseXorOp : EmitC_BinaryOp<"bitwise_xor", [CExpressionInterface]> {
let summary = "Bitwise xor operation";
let description = [{
With the `emitc.bitwise_xor` operation the bitwise operator ^ (xor)
Expand All @@ -265,7 +270,7 @@ def EmitC_BitwiseXorOp : EmitC_BinaryOp<"bitwise_xor", [CExpression]> {
}];
}

def EmitC_CallOpaqueOp : EmitC_Op<"call_opaque", [CExpression]> {
def EmitC_CallOpaqueOp : EmitC_Op<"call_opaque", [CExpressionInterface]> {
let summary = "Opaque call operation";
let description = [{
The `emitc.call_opaque` operation represents a C++ function call. The callee
Expand Down Expand Up @@ -308,11 +313,18 @@ def EmitC_CallOpaqueOp : EmitC_Op<"call_opaque", [CExpression]> {
let assemblyFormat = [{
$callee `(` $operands `)` attr-dict `:` functional-type($operands, results)
}];

let extraClassDeclaration = [{
bool hasSideEffects() {
return true;
}
}];

let hasVerifier = 1;
}

def EmitC_CastOp : EmitC_Op<"cast",
[CExpression,
[CExpressionInterface,
DeclareOpInterfaceMethods<CastOpInterface>]> {
let summary = "Cast operation";
let description = [{
Expand All @@ -337,7 +349,7 @@ def EmitC_CastOp : EmitC_Op<"cast",
let assemblyFormat = "$source attr-dict `:` type($source) `to` type($dest)";
}

def EmitC_CmpOp : EmitC_BinaryOp<"cmp", [CExpression]> {
def EmitC_CmpOp : EmitC_BinaryOp<"cmp", [CExpressionInterface]> {
let summary = "Comparison operation";
let description = [{
With the `emitc.cmp` operation the comparison operators ==, !=, <, <=, >, >=, <=>
Expand Down Expand Up @@ -407,7 +419,7 @@ def EmitC_ConstantOp : EmitC_Op<"constant", [ConstantLike]> {
let hasVerifier = 1;
}

def EmitC_DivOp : EmitC_BinaryOp<"div", [CExpression]> {
def EmitC_DivOp : EmitC_BinaryOp<"div", [CExpressionInterface]> {
let summary = "Division operation";
let description = [{
With the `emitc.div` operation the arithmetic operator / (division) can
Expand Down Expand Up @@ -462,7 +474,7 @@ def EmitC_ExpressionOp : EmitC_Op<"expression",
```

The operations allowed within expression body are EmitC operations with the
CExpression trait.
CExpressionInterface trait.

When specified, the optional `do_not_inline` indicates that the expression is
to be emitted as seen above, i.e. as the rhs of an EmitC SSA value
Expand All @@ -480,18 +492,8 @@ def EmitC_ExpressionOp : EmitC_Op<"expression",
let extraClassDeclaration = [{
bool hasSideEffects() {
auto predicate = [](Operation &op) {
assert(op.hasTrait<OpTrait::emitc::CExpression>() && "Expected a C expression");
// Conservatively assume calls to read and write memory.
if (isa<emitc::CallOpaqueOp>(op))
return true;
// De-referencing reads modifiable memory, address-taking has no
// side-effect.
auto applyOp = dyn_cast<emitc::ApplyOp>(op);
if (applyOp)
return applyOp.getApplicableOperator() == "*";
// Any load operation is assumed to read from memory and thus perform
// a side effect.
return isa<emitc::LoadOp>(op);
assert(isa<emitc::CExpressionInterface>(op) && "Expected a C expression");
return cast<emitc::CExpressionInterface>(op).hasSideEffects();
};
return llvm::any_of(getRegion().front().without_terminator(), predicate);
};
Expand Down Expand Up @@ -579,7 +581,7 @@ def EmitC_ForOp : EmitC_Op<"for",
}

def EmitC_CallOp : EmitC_Op<"call",
[CallOpInterface, CExpression,
[CallOpInterface, CExpressionInterface,
DeclareOpInterfaceMethods<SymbolUserOpInterface>]> {
let summary = "Call operation";
let description = [{
Expand Down Expand Up @@ -861,7 +863,7 @@ def EmitC_LiteralOp : EmitC_Op<"literal", [Pure]> {
let assemblyFormat = "$value attr-dict `:` type($result)";
}

def EmitC_LogicalAndOp : EmitC_BinaryOp<"logical_and", [CExpression]> {
def EmitC_LogicalAndOp : EmitC_BinaryOp<"logical_and", [CExpressionInterface]> {
let summary = "Logical and operation";
let description = [{
With the `emitc.logical_and` operation the logical operator && (and) can
Expand All @@ -882,7 +884,7 @@ def EmitC_LogicalAndOp : EmitC_BinaryOp<"logical_and", [CExpression]> {
let assemblyFormat = "operands attr-dict `:` type(operands)";
}

def EmitC_LogicalNotOp : EmitC_UnaryOp<"logical_not", [CExpression]> {
def EmitC_LogicalNotOp : EmitC_UnaryOp<"logical_not", [CExpressionInterface]> {
let summary = "Logical not operation";
let description = [{
With the `emitc.logical_not` operation the logical operator ! (negation) can
Expand All @@ -903,7 +905,7 @@ def EmitC_LogicalNotOp : EmitC_UnaryOp<"logical_not", [CExpression]> {
let assemblyFormat = "operands attr-dict `:` type(operands)";
}

def EmitC_LogicalOrOp : EmitC_BinaryOp<"logical_or", [CExpression]> {
def EmitC_LogicalOrOp : EmitC_BinaryOp<"logical_or", [CExpressionInterface]> {
let summary = "Logical or operation";
let description = [{
With the `emitc.logical_or` operation the logical operator || (inclusive or)
Expand All @@ -924,7 +926,7 @@ def EmitC_LogicalOrOp : EmitC_BinaryOp<"logical_or", [CExpression]> {
let assemblyFormat = "operands attr-dict `:` type(operands)";
}

def EmitC_LoadOp : EmitC_Op<"load", [CExpression,
def EmitC_LoadOp : EmitC_Op<"load", [CExpressionInterface,
TypesMatchWith<"result type matches value type of 'operand'",
"operand", "result",
"::llvm::cast<LValueType>($_self).getValueType()">
Expand All @@ -950,10 +952,16 @@ def EmitC_LoadOp : EmitC_Op<"load", [CExpression,
Res<EmitC_LValueType, "", [MemRead<DefaultResource, 0, FullEffect>]>:$operand);
let results = (outs AnyType:$result);

let extraClassDeclaration = [{
bool hasSideEffects() {
return true;
}
}];

let assemblyFormat = "$operand attr-dict `:` type($operand)";
}

def EmitC_MulOp : EmitC_BinaryOp<"mul", [CExpression]> {
def EmitC_MulOp : EmitC_BinaryOp<"mul", [CExpressionInterface]> {
let summary = "Multiplication operation";
let description = [{
With the `emitc.mul` operation the arithmetic operator * (multiplication) can
Expand All @@ -977,7 +985,7 @@ def EmitC_MulOp : EmitC_BinaryOp<"mul", [CExpression]> {
let results = (outs FloatIntegerIndexOrOpaqueType);
}

def EmitC_RemOp : EmitC_BinaryOp<"rem", [CExpression]> {
def EmitC_RemOp : EmitC_BinaryOp<"rem", [CExpressionInterface]> {
let summary = "Remainder operation";
let description = [{
With the `emitc.rem` operation the arithmetic operator % (remainder) can
Expand All @@ -999,7 +1007,7 @@ def EmitC_RemOp : EmitC_BinaryOp<"rem", [CExpression]> {
let results = (outs IntegerIndexOrOpaqueType);
}

def EmitC_SubOp : EmitC_BinaryOp<"sub", [CExpression]> {
def EmitC_SubOp : EmitC_BinaryOp<"sub", [CExpressionInterface]> {
let summary = "Subtraction operation";
let description = [{
With the `emitc.sub` operation the arithmetic operator - (subtraction) can
Expand Down Expand Up @@ -1069,7 +1077,7 @@ def EmitC_MemberOfPtrOp : EmitC_Op<"member_of_ptr"> {
}

def EmitC_ConditionalOp : EmitC_Op<"conditional",
[AllTypesMatch<["true_value", "false_value", "result"]>, CExpression]> {
[AllTypesMatch<["true_value", "false_value", "result"]>, CExpressionInterface]> {
let summary = "Conditional (ternary) operation";
let description = [{
With the `emitc.conditional` operation the ternary conditional operator can
Expand Down Expand Up @@ -1098,7 +1106,7 @@ def EmitC_ConditionalOp : EmitC_Op<"conditional",
let assemblyFormat = "operands attr-dict `:` type($result)";
}

def EmitC_UnaryMinusOp : EmitC_UnaryOp<"unary_minus", [CExpression]> {
def EmitC_UnaryMinusOp : EmitC_UnaryOp<"unary_minus", [CExpressionInterface]> {
let summary = "Unary minus operation";
let description = [{
With the `emitc.unary_minus` operation the unary operator - (minus) can be
Expand All @@ -1116,7 +1124,7 @@ def EmitC_UnaryMinusOp : EmitC_UnaryOp<"unary_minus", [CExpression]> {
}];
}

def EmitC_UnaryPlusOp : EmitC_UnaryOp<"unary_plus", [CExpression]> {
def EmitC_UnaryPlusOp : EmitC_UnaryOp<"unary_plus", [CExpressionInterface]> {
let summary = "Unary plus operation";
let description = [{
With the `emitc.unary_plus` operation the unary operator + (plus) can be
Expand Down
31 changes: 31 additions & 0 deletions mlir/include/mlir/Dialect/EmitC/IR/EmitCInterfaces.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//===- EmitCInterfaces.h - EmitC interfaces definitions ---------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file declares C++ classes for some of the interfaces used in the EmitC
// dialect.
//
//===----------------------------------------------------------------------===//

#ifndef MLIR_DIALECT_EMITC_IR_EMITCINTERFACES_H
#define MLIR_DIALECT_EMITC_IR_EMITCINTERFACES_H

#include "mlir/IR/OpDefinition.h"

namespace mlir {
namespace emitc {
//
} // namespace emitc
} // namespace mlir

//===----------------------------------------------------------------------===//
// EmitC Dialect Interfaces
//===----------------------------------------------------------------------===//

#include "mlir/Dialect/EmitC/IR/EmitCInterfaces.h.inc"

#endif // MLIR_DIALECT_EMITC_IR_EMITCINTERFACES_H
48 changes: 48 additions & 0 deletions mlir/include/mlir/Dialect/EmitC/IR/EmitCInterfaces.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//===- EmitCInterfaces.td - EmitC Interfaces ---------------*- tablegen -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file declares the interfaces used by EmitC.
//
//===----------------------------------------------------------------------===//

#ifndef MLIR_DIALECT_EMITC_IR_EMITCINTERFACES
#define MLIR_DIALECT_EMITC_IR_EMITCINTERFACES

include "mlir/IR/OpBase.td"

def CExpressionInterface : OpInterface<"CExpressionInterface"> {
let description = [{
Interface to mark operations that can be part of the CExpression.
}];

let cppNamespace = "::mlir::emitc";
let methods = [
InterfaceMethod<[{
Check whether operation has side effects that may affect the expression
evaluation.

By default operation is marked as not having any side effects.

```c++
class ConcreteOp ... {
public:
bool hasSideEffects() {
// That way we can override the default implementation.
return true;
}
};
```
}],
"bool", "hasSideEffects", (ins), /*methodBody=*/[{}],
/*defaultImplementation=*/[{
return false;
}]>,
];
}

#endif // MLIR_DIALECT_EMITC_IR_EMITCINTERFACES
Loading
Loading