@@ -884,6 +884,19 @@ static void insertExitNode(std::unique_ptr<MatcherNode> *root) {
884
884
*root = std::make_unique<ExitNode>();
885
885
}
886
886
887
+ // / Sorts the range begin/end with the partial order given by cmp.
888
+ // / cmp must be a partial ordering.
889
+ template <typename Iterator, typename Compare>
890
+ void stableTopologicalSort (Iterator begin, Iterator end, Compare cmp) {
891
+ while (begin != end) {
892
+ auto const next = std::stable_partition (begin, end, [&](auto const &a) {
893
+ return std::none_of (begin, end, [&](auto const &b) { return cmp (b, a); });
894
+ });
895
+ assert (next != begin && " not a partial ordering" );
896
+ begin = next;
897
+ }
898
+ }
899
+
887
900
// / Given a module containing PDL pattern operations, generate a matcher tree
888
901
// / using the patterns within the given module and return the root matcher node.
889
902
std::unique_ptr<MatcherNode>
@@ -964,6 +977,24 @@ MatcherNode::generateMatcherTree(ModuleOp module, PredicateBuilder &builder,
964
977
return *lhs < *rhs;
965
978
});
966
979
980
+ // Mostly keep the now established order, but also ensure that
981
+ // ConstraintQuestions come after the results they use.
982
+ stableTopologicalSort (ordered.begin (), ordered.end (),
983
+ [](OrderedPredicate *a, OrderedPredicate *b) {
984
+ auto *cqa = dyn_cast<ConstraintQuestion>(a->question );
985
+ auto *cqb = dyn_cast<ConstraintQuestion>(b->question );
986
+ if (cqa && cqb) {
987
+ // Does any argument of b use a? Then b must be
988
+ // sorted after a.
989
+ return llvm::any_of (
990
+ cqb->getArgs (), [&](Position *p) {
991
+ auto *cp = dyn_cast<ConstraintPosition>(p);
992
+ return cp && cp->getQuestion () == cqa;
993
+ });
994
+ }
995
+ return false ;
996
+ });
997
+
967
998
// Build the matchers for each of the pattern predicate lists.
968
999
std::unique_ptr<MatcherNode> root;
969
1000
for (OrderedPredicateList &list : lists)
0 commit comments