forked from OSchip/llvm-project
[MLIR] Modify HasParent trait to allow one of several op's as a parent
- Modify HasParent trait to allow one of several op's as a parent - - Expose this trait in the ODS framework using the ParentOneOf<> trait. Differential Revision: https://reviews.llvm.org/D81880
This commit is contained in:
parent
388afd8406
commit
e81bf67e8c
|
@ -1684,6 +1684,9 @@ class SingleBlockImplicitTerminator<string op>
|
|||
class HasParent<string op>
|
||||
: ParamNativeOpTrait<"HasParent", op>;
|
||||
|
||||
class ParentOneOf<list<string> ops>
|
||||
: ParamNativeOpTrait<"HasParent", StrJoin<ops>.result>;
|
||||
|
||||
// Op result type is derived from the first attribute. If the attribute is an
|
||||
// subclass of `TypeAttrBase`, its value is used, otherwise, the type of the
|
||||
// attribute content is used.
|
||||
|
|
|
@ -1145,16 +1145,22 @@ template <typename TerminatorOpType> struct SingleBlockImplicitTerminator {
|
|||
};
|
||||
};
|
||||
|
||||
/// This class provides a verifier for ops that are expecting a specific parent.
|
||||
template <typename ParentOpType> struct HasParent {
|
||||
/// This class provides a verifier for ops that are expecting their parent
|
||||
/// to be one of the given parent ops
|
||||
template <typename... ParentOpTypes>
|
||||
struct HasParent {
|
||||
template <typename ConcreteType>
|
||||
class Impl : public TraitBase<ConcreteType, Impl> {
|
||||
public:
|
||||
static LogicalResult verifyTrait(Operation *op) {
|
||||
if (isa<ParentOpType>(op->getParentOp()))
|
||||
if (llvm::isa<ParentOpTypes...>(op->getParentOp()))
|
||||
return success();
|
||||
return op->emitOpError() << "expects parent op '"
|
||||
<< ParentOpType::getOperationName() << "'";
|
||||
|
||||
return op->emitOpError()
|
||||
<< "expects parent op "
|
||||
<< (sizeof...(ParentOpTypes) != 1 ? "to be one of '" : "'")
|
||||
<< llvm::makeArrayRef({ParentOpTypes::getOperationName()...})
|
||||
<< "'";
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
@ -173,6 +173,39 @@ func @failedHasParent_wrong_parent() {
|
|||
}) : () -> ()
|
||||
}
|
||||
|
||||
// -----
|
||||
|
||||
// CHECK: succeededParentOneOf
|
||||
func @succeededParentOneOf() {
|
||||
"test.parent"() ({
|
||||
"test.child_with_parent_one_of"() : () -> ()
|
||||
"test.finish"() : () -> ()
|
||||
}) : () -> ()
|
||||
return
|
||||
}
|
||||
|
||||
// -----
|
||||
|
||||
// CHECK: succeededParent1OneOf
|
||||
func @succeededParent1OneOf() {
|
||||
"test.parent1"() ({
|
||||
"test.child_with_parent_one_of"() : () -> ()
|
||||
"test.finish"() : () -> ()
|
||||
}) : () -> ()
|
||||
return
|
||||
}
|
||||
|
||||
// -----
|
||||
|
||||
func @failedParentOneOf_wrong_parent1() {
|
||||
"some.otherop"() ({
|
||||
// expected-error@+1 {{'test.child_with_parent_one_of' op expects parent op to be one of 'test.parent, test.parent1'}}
|
||||
"test.child_with_parent_one_of"() : () -> ()
|
||||
"test.finish"() : () -> ()
|
||||
}) : () -> ()
|
||||
}
|
||||
|
||||
|
||||
// -----
|
||||
|
||||
func @failedSingleBlockImplicitTerminator_empty_block() {
|
||||
|
|
|
@ -439,10 +439,18 @@ def BroadcastableOp : TEST_Op<"broadcastable", [ResultsBroadcastableShape]> {
|
|||
let results = (outs AnyTensor);
|
||||
}
|
||||
|
||||
// There the "HasParent" trait.
|
||||
def ParentOp : TEST_Op<"parent">;
|
||||
// HasParent trait
|
||||
def ParentOp : TEST_Op<"parent"> {
|
||||
let regions = (region AnyRegion);
|
||||
}
|
||||
def ChildOp : TEST_Op<"child", [HasParent<"ParentOp">]>;
|
||||
|
||||
// ParentOneOf trait
|
||||
def ParentOp1 : TEST_Op<"parent1"> {
|
||||
let regions = (region AnyRegion);
|
||||
}
|
||||
def ChildWithParentOneOf : TEST_Op<"child_with_parent_one_of",
|
||||
[ParentOneOf<["ParentOp", "ParentOp1"]>]>;
|
||||
|
||||
def TerminatorOp : TEST_Op<"finish", [Terminator]>;
|
||||
def SingleBlockImplicitTerminatorOp : TEST_Op<"SingleBlockImplicitTerminator",
|
||||
|
|
Loading…
Reference in New Issue