[m_Constant] Check #operands/results before hasTrait()

We know that all ConstantLike operations have one result and no operands,
so check this first before doing the trait check.  This change speeds up
Canonicalize on a CIRCT testcase by ~5%.

Differential Revision: https://reviews.llvm.org/D98615
This commit is contained in:
Chris Lattner 2021-03-14 18:41:13 -07:00
parent a81dff1e58
commit 91a6ad5ad8
2 changed files with 20 additions and 9 deletions

View File

@ -48,14 +48,22 @@ struct attr_value_binder {
}
};
/// Check to see if the specified operation is ConstantLike. This includes some
/// quick filters to avoid a semi-expensive test in the common case.
static bool isConstantLike(Operation *op) {
return op->getNumOperands() == 0 && op->getNumResults() == 1 &&
op->hasTrait<OpTrait::ConstantLike>();
}
/// The matcher that matches operations that have the `ConstantLike` trait.
struct constant_op_matcher {
bool match(Operation *op) { return op->hasTrait<OpTrait::ConstantLike>(); }
bool match(Operation *op) { return isConstantLike(op); }
};
/// The matcher that matches operations that have the `ConstantLike` trait, and
/// binds the folded attribute value.
template <typename AttrT> struct constant_op_binder {
template <typename AttrT>
struct constant_op_binder {
AttrT *bind_value;
/// Creates a matcher instance that binds the constant attribute value to
@ -65,7 +73,7 @@ template <typename AttrT> struct constant_op_binder {
constant_op_binder() : bind_value(nullptr) {}
bool match(Operation *op) {
if (!op->hasTrait<OpTrait::ConstantLike>())
if (!isConstantLike(op))
return false;
// Fold the constant to an attribute.
@ -111,7 +119,8 @@ struct constant_int_op_binder {
/// The matcher that matches a given target constant scalar / vector splat /
/// tensor splat integer value.
template <int64_t TargetValue> struct constant_int_value_matcher {
template <int64_t TargetValue>
struct constant_int_value_matcher {
bool match(Operation *op) {
APInt value;
return constant_int_op_binder(&value).match(op) && TargetValue == value;
@ -120,7 +129,8 @@ template <int64_t TargetValue> struct constant_int_value_matcher {
/// The matcher that matches anything except the given target constant scalar /
/// vector splat / tensor splat integer value.
template <int64_t TargetNotValue> struct constant_int_not_value_matcher {
template <int64_t TargetNotValue>
struct constant_int_not_value_matcher {
bool match(Operation *op) {
APInt value;
return constant_int_op_binder(&value).match(op) && TargetNotValue != value;
@ -128,7 +138,8 @@ template <int64_t TargetNotValue> struct constant_int_not_value_matcher {
};
/// The matcher that matches a certain kind of op.
template <typename OpClass> struct op_matcher {
template <typename OpClass>
struct op_matcher {
bool match(Operation *op) { return isa<OpClass>(op); }
};
@ -224,7 +235,8 @@ inline detail::constant_int_value_matcher<1> m_One() {
}
/// Matches the given OpClass.
template <typename OpClass> inline detail::op_matcher<OpClass> m_Op() {
template <typename OpClass>
inline detail::op_matcher<OpClass> m_Op() {
return detail::op_matcher<OpClass>();
}

View File

@ -130,8 +130,7 @@ void OperationFolder::processExistingConstants(Region &region) {
region.walk<WalkOrder::PreOrder>([&](Operation *op) {
// If this is a constant, process it.
Attribute value;
if (op->getNumOperands() == 0 && op->getNumResults() == 1 &&
matchPattern(op, m_Constant(&value))) {
if (matchPattern(op, m_Constant(&value))) {
processConstant(op, value);
// We may have deleted the operation, don't check it for regions.
return WalkResult::advance();