diff --git a/mlir/docs/OpDefinitions.md b/mlir/docs/OpDefinitions.md --- a/mlir/docs/OpDefinitions.md +++ b/mlir/docs/OpDefinitions.md @@ -442,7 +442,7 @@ // Provide only a default definition of the method. // Note: `ConcreteOp` corresponds to the derived operation typename. InterfaceMethod<"/*insert doc here*/", - "unsigned", "getNumWithDefault", (ins), /*methodBody=*/[{}], [{ + "unsigned", "getNumInputsAndOutputs", (ins), /*methodBody=*/[{}], [{ ConcreteOp op = cast(getOperation()); return op.getNumInputs() + op.getNumOutputs(); }]>, @@ -455,13 +455,6 @@ // declaration but instead handled by the op interface trait directly. def OpWithInferTypeInterfaceOp : Op<... [DeclareOpInterfaceMethods]> { ... } - -// Methods that have a default implementation do not have declarations -// generated. If an operation wishes to override the default behavior, it can -// explicitly specify the method that it wishes to override. This will force -// the generation of a declaration for those methods. -def OpWithOverrideInferTypeInterfaceOp : Op<... - [DeclareOpInterfaceMethods]> { ... } ``` A verification method can also be specified on the `OpInterface` by setting diff --git a/mlir/include/mlir/Dialect/StandardOps/IR/Ops.td b/mlir/include/mlir/Dialect/StandardOps/IR/Ops.td --- a/mlir/include/mlir/Dialect/StandardOps/IR/Ops.td +++ b/mlir/include/mlir/Dialect/StandardOps/IR/Ops.td @@ -560,8 +560,7 @@ //===----------------------------------------------------------------------===// def BranchOp : Std_Op<"br", - [DeclareOpInterfaceMethods, - NoSideEffect, Terminator]> { + [DeclareOpInterfaceMethods, NoSideEffect, Terminator]> { let summary = "branch operation"; let description = [{ The `br` operation represents a branch operation in a function. @@ -597,6 +596,10 @@ /// Erase the operand at 'index' from the operand list. void eraseOperand(unsigned index); + + /// Returns the successor that would be chosen with the given constant + /// operands. Returns nullptr if a single successor could not be chosen. + Block *getSuccessorForOperands(ArrayRef); }]; let hasCanonicalizer = 1; @@ -986,8 +989,7 @@ //===----------------------------------------------------------------------===// def CondBranchOp : Std_Op<"cond_br", - [AttrSizedOperandSegments, - DeclareOpInterfaceMethods, + [AttrSizedOperandSegments, DeclareOpInterfaceMethods, NoSideEffect, Terminator]> { let summary = "conditional branch operation"; let description = [{ @@ -1094,6 +1096,10 @@ eraseSuccessorOperand(falseIndex, index); } + /// Returns the successor that would be chosen with the given constant + /// operands. Returns nullptr if a single successor could not be chosen. + Block *getSuccessorForOperands(ArrayRef operands); + private: /// Get the index of the first true destination operand. unsigned getTrueDestOperandIndex() { return 1; } diff --git a/mlir/include/mlir/IR/OpBase.td b/mlir/include/mlir/IR/OpBase.td --- a/mlir/include/mlir/IR/OpBase.td +++ b/mlir/include/mlir/IR/OpBase.td @@ -1780,20 +1780,12 @@ // Whether to declare the op interface methods in the op's header. This class // simply wraps an OpInterface but is used to indicate that the method -// declarations should be generated. This class takes an optional set of methods -// that should have declarations generated even if the method has a default -// implementation. -class DeclareOpInterfaceMethods overridenMethods = []> - : OpInterface { +// declarations should be generated. +class DeclareOpInterfaceMethods : + OpInterface { let description = interface.description; let cppClassName = interface.cppClassName; let methods = interface.methods; - - // This field contains a set of method names that should always have their - // declarations generated. This allows for generating declarations for - // methods with default implementations that need to be overridden. - list alwaysOverriddenMethods = overridenMethods; } //===----------------------------------------------------------------------===// diff --git a/mlir/include/mlir/TableGen/OpTrait.h b/mlir/include/mlir/TableGen/OpTrait.h --- a/mlir/include/mlir/TableGen/OpTrait.h +++ b/mlir/include/mlir/TableGen/OpTrait.h @@ -15,7 +15,6 @@ #include "mlir/Support/LLVM.h" #include "llvm/ADT/StringRef.h" -#include namespace llvm { class Init; @@ -106,10 +105,6 @@ // Whether the declaration of methods for this trait should be emitted. bool shouldDeclareMethods() const; - - // Returns the methods that should always be declared if this interface is - // emitting declarations. - std::vector getAlwaysDeclaredMethods() const; }; } // end namespace tblgen diff --git a/mlir/lib/TableGen/OpTrait.cpp b/mlir/lib/TableGen/OpTrait.cpp --- a/mlir/lib/TableGen/OpTrait.cpp +++ b/mlir/lib/TableGen/OpTrait.cpp @@ -63,7 +63,3 @@ bool InterfaceOpTrait::shouldDeclareMethods() const { return def->isSubClassOf("DeclareOpInterfaceMethods"); } - -std::vector InterfaceOpTrait::getAlwaysDeclaredMethods() const { - return def->getValueAsListOfStrings("alwaysOverriddenMethods"); -} diff --git a/mlir/test/mlir-tblgen/op-interface.td b/mlir/test/mlir-tblgen/op-interface.td --- a/mlir/test/mlir-tblgen/op-interface.td +++ b/mlir/test/mlir-tblgen/op-interface.td @@ -1,5 +1,4 @@ // RUN: mlir-tblgen -gen-op-interface-decls -I %S/../../include %s | FileCheck %s --check-prefix=DECL --dump-input-on-failure -// RUN: mlir-tblgen -gen-op-decls -I %S/../../include %s | FileCheck %s --check-prefix=OP_DECL --dump-input-on-failure include "mlir/IR/OpBase.td" @@ -13,14 +12,6 @@ /*methodName=*/"foo", /*args=*/(ins "int":$input) >, - InterfaceMethod< - /*desc=*/[{some function comment}], - /*retTy=*/"int", - /*methodName=*/"default_foo", - /*args=*/(ins "int":$input), - /*body=*/[{}], - /*defaultBody=*/[{ return 0; }] - >, ]; } @@ -36,19 +27,8 @@ def DeclareMethodsOp : Op]>; -def DeclareMethodsWithDefaultOp : Op]>; - // DECL-LABEL: TestOpInterfaceInterfaceTraits // DECL: class TestOpInterface : public OpInterface // DECL: int foo(int input); // DECL-NOT: TestOpInterface - -// OP_DECL-LABEL: class DeclareMethodsOp : public -// OP_DECL: int foo(int input); -// OP_DECL-NOT: int default_foo(int input); - -// OP_DECL-LABEL: class DeclareMethodsWithDefaultOp : public -// OP_DECL: int foo(int input); -// OP_DECL: int default_foo(int input); diff --git a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp --- a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp +++ b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp @@ -1282,23 +1282,10 @@ if (!opTrait || !opTrait->shouldDeclareMethods()) continue; auto interface = opTrait->getOpInterface(); - - // Get the set of methods that should always be declared. - auto alwaysDeclaredMethodsVec = opTrait->getAlwaysDeclaredMethods(); - llvm::StringSet<> alwaysDeclaredMethods; - alwaysDeclaredMethods.insert(alwaysDeclaredMethodsVec.begin(), - alwaysDeclaredMethodsVec.end()); - - for (const OpInterfaceMethod &method : interface.getMethods()) { - // Don't declare if the method has a body. - if (method.getBody()) + for (auto method : interface.getMethods()) { + // Don't declare if the method has a body or a default implementation. + if (method.getBody() || method.getDefaultImplementation()) continue; - // Don't declare if the method has a default implementation and the op - // didn't request that it always be declared. - if (method.getDefaultImplementation() && - !alwaysDeclaredMethods.count(method.getName())) - continue; - std::string args; llvm::raw_string_ostream os(args); interleaveComma(method.getArguments(), os,