}
}
-/// SinkPatternPredicates - Pattern predicates can be checked at any level of
-/// the matching tree. The generator dumps them at the top level of the pattern
-/// though, which prevents factoring from being able to see past them. This
-/// optimization sinks them as far down into the pattern as possible.
-///
-/// Conceptually, we'd like to sink these predicates all the way to the last
-/// matcher predicate in the series. However, it turns out that some
-/// ComplexPatterns have side effects on the graph, so we really don't want to
-/// run a complex pattern if the pattern predicate will fail. For this
-/// reason, we refuse to sink the pattern predicate past a ComplexPattern.
-///
-static void SinkPatternPredicates(std::unique_ptr<Matcher> &MatcherPtr) {
- // Recursively scan for a PatternPredicate.
- // If we reached the end of the chain, we're done.
- Matcher *N = MatcherPtr.get();
- if (!N) return;
-
- // Walk down all members of a scope node.
- if (ScopeMatcher *Scope = dyn_cast<ScopeMatcher>(N)) {
- for (unsigned i = 0, e = Scope->getNumChildren(); i != e; ++i) {
- std::unique_ptr<Matcher> Child(Scope->takeChild(i));
- SinkPatternPredicates(Child);
- Scope->resetChild(i, Child.release());
- }
- return;
- }
-
- // If this node isn't a CheckPatternPredicateMatcher we keep scanning until
- // we find one.
- CheckPatternPredicateMatcher *CPPM =dyn_cast<CheckPatternPredicateMatcher>(N);
- if (!CPPM)
- return SinkPatternPredicates(N->getNextPtr());
-
- // Ok, we found one, lets try to sink it. Check if we can sink it past the
- // next node in the chain. If not, we won't be able to change anything and
- // might as well bail.
- if (!CPPM->getNext()->isSafeToReorderWithPatternPredicate())
- return;
-
- // Okay, we know we can sink it past at least one node. Unlink it from the
- // chain and scan for the new insertion point.
- MatcherPtr.release(); // Don't delete CPPM.
- MatcherPtr.reset(CPPM->takeNext());
-
- N = MatcherPtr.get();
- while (N->getNext()->isSafeToReorderWithPatternPredicate())
- N = N->getNext();
-
- // At this point, we want to insert CPPM after N.
- CPPM->setNext(N->takeNext());
- N->setNext(CPPM);
-}
-
/// FindNodeWithKind - Scan a series of matchers looking for a matcher with a
/// specified kind. Return null if we didn't find one otherwise return the
/// matcher.
llvm::OptimizeMatcher(std::unique_ptr<Matcher> &MatcherPtr,
const CodeGenDAGPatterns &CGP) {
ContractNodes(MatcherPtr, CGP);
- SinkPatternPredicates(MatcherPtr);
FactorNodes(MatcherPtr);
}