[mlir][pdl] Fix bug when ordering predicates

We should be ordering predicates with higher primary/secondary sums first, but we are currently ordering them last. This allows for predicates more frequently encountered to be checked first.

Differential Revision: https://reviews.llvm.org/D95715
This commit is contained in:
River Riddle 2021-02-22 19:00:54 -08:00
parent 4125cabce1
commit ddd556f10e
2 changed files with 40 additions and 12 deletions

View File

@ -214,20 +214,20 @@ struct OrderedPredicate {
/// within that pattern. /// within that pattern.
DenseMap<Operation *, Qualifier *> patternToAnswer; DenseMap<Operation *, Qualifier *> patternToAnswer;
/// Returns true if this predicate is ordered before `other`, based on the /// Returns true if this predicate is ordered before `rhs`, based on the cost
/// cost model. /// model.
bool operator<(const OrderedPredicate &other) const { bool operator<(const OrderedPredicate &rhs) const {
// Sort by: // Sort by:
// * first and secondary order sums // * higher first and secondary order sums
// * lower depth // * lower depth
// * position dependency // * lower position dependency
// * predicate dependency. // * lower predicate dependency
auto *otherPos = other.position; auto *rhsPos = rhs.position;
return std::make_tuple(other.primary, other.secondary, return std::make_tuple(primary, secondary, rhsPos->getIndex().size(),
otherPos->getIndex().size(), otherPos->getKind(), rhsPos->getKind(), rhs.question->getKind()) >
other.question->getKind()) > std::make_tuple(rhs.primary, rhs.secondary,
std::make_tuple(primary, secondary, position->getIndex().size(), position->getIndex().size(), position->getKind(),
position->getKind(), question->getKind()); question->getKind());
} }
}; };

View File

@ -143,3 +143,31 @@ module @switch_result_types {
pdl.rewrite %root with "rewriter" pdl.rewrite %root with "rewriter"
} }
} }
// -----
// CHECK-LABEL: module @predicate_ordering
module @predicate_ordering {
// Check that the result is checked for null first, before applying the
// constraint. The null check is prevalent in both patterns, so should be
// prioritized first.
// CHECK: func @matcher(%[[ROOT:.*]]: !pdl.operation)
// CHECK: %[[RESULT:.*]] = pdl_interp.get_result 0 of %[[ROOT]]
// CHECK-NEXT: pdl_interp.is_not_null %[[RESULT]]
// CHECK: %[[RESULT_TYPE:.*]] = pdl_interp.get_value_type of %[[RESULT]]
// CHECK: pdl_interp.apply_constraint "typeConstraint" [](%[[RESULT_TYPE]]
pdl.pattern : benefit(1) {
%resultType = pdl.type
pdl.apply_constraint "typeConstraint"[](%resultType : !pdl.type)
%root, %result = pdl.operation -> %resultType
pdl.rewrite %root with "rewriter"
}
pdl.pattern : benefit(1) {
%resultType = pdl.type
%apply, %applyRes = pdl.operation -> %resultType
pdl.rewrite %apply with "rewriter"
}
}