diff --git a/mlir/lib/Conversion/PDLToPDLInterp/PredicateTree.cpp b/mlir/lib/Conversion/PDLToPDLInterp/PredicateTree.cpp --- a/mlir/lib/Conversion/PDLToPDLInterp/PredicateTree.cpp +++ b/mlir/lib/Conversion/PDLToPDLInterp/PredicateTree.cpp @@ -720,6 +720,11 @@ /// opposed to those shared across patterns. unsigned secondary = 0; + /// The tie breaking ID, used to preserve a deterministic (insertion) order + /// among all the predicates with the same priority, depth, and position / + /// predicate dependency. + unsigned id = 0; + /// A map between a pattern operation and the answer to the predicate question /// within that pattern. DenseMap patternToAnswer; @@ -732,12 +737,13 @@ // * lower depth // * lower position dependency // * lower predicate dependency + // * lower tie breaking ID auto *rhsPos = rhs.position; return std::make_tuple(primary, secondary, rhsPos->getOperationDepth(), - rhsPos->getKind(), rhs.question->getKind()) > + rhsPos->getKind(), rhs.question->getKind(), rhs.id) > std::make_tuple(rhs.primary, rhs.secondary, position->getOperationDepth(), position->getKind(), - question->getKind()); + question->getKind(), id); } }; @@ -902,6 +908,9 @@ auto it = uniqued.insert(predicate); it.first->patternToAnswer.try_emplace(patternAndPredList.pattern, predicate.answer); + // Mark the insertion order. + if (it.second) + it.first->id = uniqued.size(); } } @@ -938,9 +947,9 @@ ordered.reserve(uniqued.size()); for (auto &ip : uniqued) ordered.push_back(&ip); - std::stable_sort( - ordered.begin(), ordered.end(), - [](OrderedPredicate *lhs, OrderedPredicate *rhs) { return *lhs < *rhs; }); + llvm::sort(ordered, [](OrderedPredicate *lhs, OrderedPredicate *rhs) { + return *lhs < *rhs; + }); // Build the matchers for each of the pattern predicate lists. std::unique_ptr root;