Index: utils/TableGen/CodeGenDAGPatterns.cpp =================================================================== --- utils/TableGen/CodeGenDAGPatterns.cpp +++ utils/TableGen/CodeGenDAGPatterns.cpp @@ -4461,8 +4461,18 @@ // intentionally do not reconsider these. Any variants of added patterns have // already been added. // - for (unsigned i = 0, e = PatternsToMatch.size(); i != e; ++i) { - MultipleUseVarSet DepVars; + const unsigned NumOriginalPatterns = PatternsToMatch.size(); + BitVector MatchedPatterns(NumOriginalPatterns); + std::vector MatchedPredicates(NumOriginalPatterns, + BitVector(NumOriginalPatterns)); + + typedef std::pair> + DepsAndVariants; + std::map PatternsWithVariants; + + // Collect patterns with more than one variant. + for (unsigned i = 0; i != NumOriginalPatterns; ++i) { + MultipleUseVarSet DepVars; std::vector Variants; FindDepVars(PatternsToMatch[i].getSrcPattern(), DepVars); LLVM_DEBUG(errs() << "Dependent/multiply used variables: "); @@ -4472,21 +4482,46 @@ *this, DepVars); assert(!Variants.empty() && "Must create at least original variant!"); - if (Variants.size() == 1) // No additional variants for this pattern. + if (Variants.size() == 1) // No additional variants for this pattern. continue; LLVM_DEBUG(errs() << "FOUND VARIANTS OF: "; PatternsToMatch[i].getSrcPattern()->dump(); errs() << "\n"); + PatternsWithVariants[i] = std::make_pair(DepVars, Variants); + // Cache matching predicates. - // TODO: Is it performant to pull this out of the loop entirely? - BitVector MatchedPredicates(PatternsToMatch.size(), false); - for (unsigned p = 0, e = PatternsToMatch.size(); p != e; ++p) - MatchedPredicates[p] = (i == p) || (PatternsToMatch[i].getPredicates() == - PatternsToMatch[p].getPredicates()); + if (MatchedPatterns[i]) + continue; + + const std::vector &Predicates = + PatternsToMatch[i].getPredicates(); + + BitVector &Matches = MatchedPredicates[i]; + MatchedPatterns[i] = true; + Matches[i] = true; + + // Don't test patterns that have already been cached - it won't match. + for (unsigned p = 0; p != NumOriginalPatterns; ++p) + if (!MatchedPatterns[p]) + Matches[p] = (Predicates == PatternsToMatch[p].getPredicates()); + + // Copy this to all the matching patterns. + for (int p = Matches.find_first(); p != -1; p = Matches.find_next(p)) + if (p != i) { + MatchedPatterns[p] = true; + MatchedPredicates[p] = Matches; + } + } + + for (auto it : PatternsWithVariants) { + unsigned i = it.first; + const MultipleUseVarSet &DepVars = it.second.first; + const std::vector &Variants = it.second.second; for (unsigned v = 0, e = Variants.size(); v != e; ++v) { TreePatternNodePtr Variant = Variants[v]; + BitVector &Matches = MatchedPredicates[i]; LLVM_DEBUG(errs() << " VAR#" << v << ": "; Variant->dump(); errs() << "\n"); @@ -4495,7 +4530,7 @@ bool AlreadyExists = false; for (unsigned p = 0, e = PatternsToMatch.size(); p != e; ++p) { // Skip if the top level predicates do not match. - if (!MatchedPredicates[p]) + if (!Matches[p]) continue; // Check to see if this variant already exists. if (Variant->isIsomorphicTo(PatternsToMatch[p].getSrcPattern(), @@ -4514,8 +4549,11 @@ Variant, PatternsToMatch[i].getDstPatternShared(), PatternsToMatch[i].getDstRegs(), PatternsToMatch[i].getAddedComplexity(), Record::getNewUID())); - MatchedPredicates.resize(PatternsToMatch.size()); - MatchedPredicates[PatternsToMatch.size() - 1] = true; + MatchedPredicates.push_back(Matches); + + unsigned NumPatterns = PatternsToMatch.size(); + for (unsigned p = 0; p != NumPatterns; ++p) + MatchedPredicates[p].resize(NumPatterns, MatchedPredicates[p][i]); } LLVM_DEBUG(errs() << "\n");