From 91a6ad5ad887a16e361338303d4ff3d29dba5e10 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 14 Mar 2021 18:41:13 -0700 Subject: [PATCH] [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 --- mlir/include/mlir/IR/Matchers.h | 26 ++++++++++++++++++------- mlir/lib/Transforms/Utils/FoldUtils.cpp | 3 +-- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/mlir/include/mlir/IR/Matchers.h b/mlir/include/mlir/IR/Matchers.h index bbf117e5c8bd..548cbe3208c9 100644 --- a/mlir/include/mlir/IR/Matchers.h +++ b/mlir/include/mlir/IR/Matchers.h @@ -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(); +} + /// The matcher that matches operations that have the `ConstantLike` trait. struct constant_op_matcher { - bool match(Operation *op) { return op->hasTrait(); } + bool match(Operation *op) { return isConstantLike(op); } }; /// The matcher that matches operations that have the `ConstantLike` trait, and /// binds the folded attribute value. -template struct constant_op_binder { +template +struct constant_op_binder { AttrT *bind_value; /// Creates a matcher instance that binds the constant attribute value to @@ -65,7 +73,7 @@ template struct constant_op_binder { constant_op_binder() : bind_value(nullptr) {} bool match(Operation *op) { - if (!op->hasTrait()) + 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 struct constant_int_value_matcher { +template +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 struct constant_int_value_matcher { /// The matcher that matches anything except the given target constant scalar / /// vector splat / tensor splat integer value. -template struct constant_int_not_value_matcher { +template +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 struct constant_int_not_value_matcher { }; /// The matcher that matches a certain kind of op. -template struct op_matcher { +template +struct op_matcher { bool match(Operation *op) { return isa(op); } }; @@ -224,7 +235,8 @@ inline detail::constant_int_value_matcher<1> m_One() { } /// Matches the given OpClass. -template inline detail::op_matcher m_Op() { +template +inline detail::op_matcher m_Op() { return detail::op_matcher(); } diff --git a/mlir/lib/Transforms/Utils/FoldUtils.cpp b/mlir/lib/Transforms/Utils/FoldUtils.cpp index 0dfd301f3f3e..5597ad6023ef 100644 --- a/mlir/lib/Transforms/Utils/FoldUtils.cpp +++ b/mlir/lib/Transforms/Utils/FoldUtils.cpp @@ -130,8 +130,7 @@ void OperationFolder::processExistingConstants(Region ®ion) { region.walk([&](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();