// 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<BitVector> MatchedPredicates(NumOriginalPatterns,
+ BitVector(NumOriginalPatterns));
+
+ typedef std::pair<MultipleUseVarSet, std::vector<TreePatternNodePtr>>
+ DepsAndVariants;
+ std::map<unsigned, DepsAndVariants> PatternsWithVariants;
+
+ // Collect patterns with more than one variant.
+ for (unsigned i = 0; i != NumOriginalPatterns; ++i) {
+ MultipleUseVarSet DepVars;
std::vector<TreePatternNodePtr> Variants;
FindDepVars(PatternsToMatch[i].getSrcPattern(), DepVars);
LLVM_DEBUG(errs() << "Dependent/multiply used variables: ");
*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<Predicate> &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<TreePatternNodePtr> &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");
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(),
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");