diff options
Diffstat (limited to 'llvm/utils/TableGen/CodeGenDAGPatterns.cpp')
-rw-r--r-- | llvm/utils/TableGen/CodeGenDAGPatterns.cpp | 336 |
1 files changed, 164 insertions, 172 deletions
diff --git a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp index 1ca4a68eb155..c1a3a34d928b 100644 --- a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp @@ -12,7 +12,6 @@ //===----------------------------------------------------------------------===// #include "CodeGenDAGPatterns.h" -#include "llvm/ADT/BitVector.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/STLExtras.h" @@ -111,10 +110,8 @@ bool TypeSetByHwMode::insert(const ValueTypeByHwMode &VVT) { bool ContainsDefault = false; MVT DT = MVT::Other; - SmallDenseSet<unsigned, 4> Modes; for (const auto &P : VVT) { unsigned M = P.first; - Modes.insert(M); // Make sure there exists a set for each specific mode from VVT. Changed |= getOrCreate(M).insert(P.second).second; // Cache VVT's default mode. @@ -128,7 +125,7 @@ bool TypeSetByHwMode::insert(const ValueTypeByHwMode &VVT) { // modes in "this" that do not exist in VVT. if (ContainsDefault) for (auto &I : *this) - if (!Modes.count(I.first)) + if (!VVT.hasMode(I.first)) Changed |= I.second.insert(DT).second; return Changed; @@ -205,11 +202,9 @@ void TypeSetByHwMode::writeToStream(const SetType &S, raw_ostream &OS) { array_pod_sort(Types.begin(), Types.end()); OS << '['; - for (unsigned i = 0, e = Types.size(); i != e; ++i) { - OS << ValueTypeByHwMode::getMVTName(Types[i]); - if (i != e-1) - OS << ' '; - } + ListSeparator LS(" "); + for (const MVT &T : Types) + OS << LS << ValueTypeByHwMode::getMVTName(T); OS << ']'; } @@ -226,7 +221,7 @@ bool TypeSetByHwMode::operator==(const TypeSetByHwMode &VTS) const { if (HaveDefault != VTSHaveDefault) return false; - SmallDenseSet<unsigned, 4> Modes; + SmallSet<unsigned, 4> Modes; for (auto &I : *this) Modes.insert(I.first); for (const auto &I : VTS) @@ -470,7 +465,8 @@ bool TypeInfer::EnforceSmallerThan(TypeSetByHwMode &Small, assert(Small.hasDefault() && Big.hasDefault()); - std::vector<unsigned> Modes = union_modes(Small, Big); + SmallVector<unsigned, 4> Modes; + union_modes(Small, Big, Modes); // 1. Only allow integer or floating point types and make sure that // both sides are both integer or both floating point. @@ -577,7 +573,9 @@ bool TypeInfer::EnforceVectorEltTypeIs(TypeSetByHwMode &Vec, if (Elem.empty()) Changed |= EnforceScalar(Elem); - for (unsigned M : union_modes(Vec, Elem)) { + SmallVector<unsigned, 4> Modes; + union_modes(Vec, Elem, Modes); + for (unsigned M : Modes) { TypeSetByHwMode::SetType &V = Vec.get(M); TypeSetByHwMode::SetType &E = Elem.get(M); @@ -585,7 +583,7 @@ bool TypeInfer::EnforceVectorEltTypeIs(TypeSetByHwMode &Vec, Changed |= berase_if(E, isVector); // Vector = !scalar assert(!V.empty() && !E.empty()); - SmallSet<MVT,4> VT, ST; + MachineValueTypeSet VT, ST; // Collect element types from the "vector" set. for (MVT T : V) VT.insert(T.getVectorElementType()); @@ -632,7 +630,7 @@ bool TypeInfer::EnforceVectorSubVectorTypeIs(TypeSetByHwMode &Vec, return false; if (B.getVectorElementType() != P.getVectorElementType()) return false; - return B.getVectorNumElements() < P.getVectorNumElements(); + return B.getVectorMinNumElements() < P.getVectorMinNumElements(); }; /// Return true if S has no element (vector type) that T is a sub-vector of, @@ -660,7 +658,9 @@ bool TypeInfer::EnforceVectorSubVectorTypeIs(TypeSetByHwMode &Vec, if (Sub.empty()) Changed |= EnforceVector(Sub); - for (unsigned M : union_modes(Vec, Sub)) { + SmallVector<unsigned, 4> Modes; + union_modes(Vec, Sub, Modes); + for (unsigned M : Modes) { TypeSetByHwMode::SetType &S = Sub.get(M); TypeSetByHwMode::SetType &V = Vec.get(M); @@ -696,19 +696,25 @@ bool TypeInfer::EnforceSameNumElts(TypeSetByHwMode &V, TypeSetByHwMode &W) { // An actual vector type cannot have 0 elements, so we can treat scalars // as zero-length vectors. This way both vectors and scalars can be // processed identically. - auto NoLength = [](const SmallSet<unsigned,2> &Lengths, MVT T) -> bool { - return !Lengths.count(T.isVector() ? T.getVectorNumElements() : 0); + auto NoLength = [](const SmallDenseSet<ElementCount> &Lengths, + MVT T) -> bool { + return !Lengths.count(T.isVector() ? T.getVectorElementCount() + : ElementCount::getNull()); }; - for (unsigned M : union_modes(V, W)) { + SmallVector<unsigned, 4> Modes; + union_modes(V, W, Modes); + for (unsigned M : Modes) { TypeSetByHwMode::SetType &VS = V.get(M); TypeSetByHwMode::SetType &WS = W.get(M); - SmallSet<unsigned,2> VN, WN; + SmallDenseSet<ElementCount> VN, WN; for (MVT T : VS) - VN.insert(T.isVector() ? T.getVectorNumElements() : 0); + VN.insert(T.isVector() ? T.getVectorElementCount() + : ElementCount::getNull()); for (MVT T : WS) - WN.insert(T.isVector() ? T.getVectorNumElements() : 0); + WN.insert(T.isVector() ? T.getVectorElementCount() + : ElementCount::getNull()); Changed |= berase_if(VS, std::bind(NoLength, WN, std::placeholders::_1)); Changed |= berase_if(WS, std::bind(NoLength, VN, std::placeholders::_1)); @@ -716,6 +722,15 @@ bool TypeInfer::EnforceSameNumElts(TypeSetByHwMode &V, TypeSetByHwMode &W) { return Changed; } +namespace { +struct TypeSizeComparator { + bool operator()(const TypeSize &LHS, const TypeSize &RHS) const { + return std::make_tuple(LHS.isScalable(), LHS.getKnownMinValue()) < + std::make_tuple(RHS.isScalable(), RHS.getKnownMinValue()); + } +}; +} // end anonymous namespace + /// 1. Ensure that for each type T in A, there exists a type U in B, /// such that T and U have equal size in bits. /// 2. Ensure that for each type U in B, there exists a type T in A @@ -730,14 +745,18 @@ bool TypeInfer::EnforceSameSize(TypeSetByHwMode &A, TypeSetByHwMode &B) { if (B.empty()) Changed |= EnforceAny(B); - auto NoSize = [](const SmallSet<TypeSize, 2> &Sizes, MVT T) -> bool { + typedef SmallSet<TypeSize, 2, TypeSizeComparator> TypeSizeSet; + + auto NoSize = [](const TypeSizeSet &Sizes, MVT T) -> bool { return !Sizes.count(T.getSizeInBits()); }; - for (unsigned M : union_modes(A, B)) { + SmallVector<unsigned, 4> Modes; + union_modes(A, B, Modes); + for (unsigned M : Modes) { TypeSetByHwMode::SetType &AS = A.get(M); TypeSetByHwMode::SetType &BS = B.get(M); - SmallSet<TypeSize, 2> AN, BN; + TypeSizeSet AN, BN; for (MVT T : AS) AN.insert(T.getSizeInBits()); @@ -837,7 +856,11 @@ TypeInfer::ValidateOnExit::~ValidateOnExit() { "(use -print-records with llvm-tblgen to see all " "expanded records).\n"; Infer.TP.dump(); - llvm_unreachable(nullptr); + dbgs() << "Generated from record:\n"; + Infer.TP.getRecord()->dump(); + PrintFatalError(Infer.TP.getRecord()->getLoc(), + "Type set is empty for each HW mode in '" + + Infer.TP.getRecord()->getName() + "'"); } } #endif @@ -980,12 +1003,9 @@ std::string TreePredicateFn::getPredCode() const { Code += "unsigned AddrSpace = cast<MemSDNode>(N)->getAddressSpace();\n" " if ("; - bool First = true; + ListSeparator LS(" && "); for (Init *Val : AddressSpaces->getValues()) { - if (First) - First = false; - else - Code += " && "; + Code += LS; IntInit *IntVal = dyn_cast<IntInit>(Val); if (!IntVal) { @@ -1015,33 +1035,33 @@ std::string TreePredicateFn::getPredCode() const { } if (isAtomic() && isAtomicOrderingMonotonic()) - Code += "if (cast<AtomicSDNode>(N)->getOrdering() != " + Code += "if (cast<AtomicSDNode>(N)->getMergedOrdering() != " "AtomicOrdering::Monotonic) return false;\n"; if (isAtomic() && isAtomicOrderingAcquire()) - Code += "if (cast<AtomicSDNode>(N)->getOrdering() != " + Code += "if (cast<AtomicSDNode>(N)->getMergedOrdering() != " "AtomicOrdering::Acquire) return false;\n"; if (isAtomic() && isAtomicOrderingRelease()) - Code += "if (cast<AtomicSDNode>(N)->getOrdering() != " + Code += "if (cast<AtomicSDNode>(N)->getMergedOrdering() != " "AtomicOrdering::Release) return false;\n"; if (isAtomic() && isAtomicOrderingAcquireRelease()) - Code += "if (cast<AtomicSDNode>(N)->getOrdering() != " + Code += "if (cast<AtomicSDNode>(N)->getMergedOrdering() != " "AtomicOrdering::AcquireRelease) return false;\n"; if (isAtomic() && isAtomicOrderingSequentiallyConsistent()) - Code += "if (cast<AtomicSDNode>(N)->getOrdering() != " + Code += "if (cast<AtomicSDNode>(N)->getMergedOrdering() != " "AtomicOrdering::SequentiallyConsistent) return false;\n"; if (isAtomic() && isAtomicOrderingAcquireOrStronger()) - Code += "if (!isAcquireOrStronger(cast<AtomicSDNode>(N)->getOrdering())) " + Code += "if (!isAcquireOrStronger(cast<AtomicSDNode>(N)->getMergedOrdering())) " "return false;\n"; if (isAtomic() && isAtomicOrderingWeakerThanAcquire()) - Code += "if (isAcquireOrStronger(cast<AtomicSDNode>(N)->getOrdering())) " + Code += "if (isAcquireOrStronger(cast<AtomicSDNode>(N)->getMergedOrdering())) " "return false;\n"; if (isAtomic() && isAtomicOrderingReleaseOrStronger()) - Code += "if (!isReleaseOrStronger(cast<AtomicSDNode>(N)->getOrdering())) " + Code += "if (!isReleaseOrStronger(cast<AtomicSDNode>(N)->getMergedOrdering())) " "return false;\n"; if (isAtomic() && isAtomicOrderingWeakerThanRelease()) - Code += "if (isReleaseOrStronger(cast<AtomicSDNode>(N)->getOrdering())) " + Code += "if (isReleaseOrStronger(cast<AtomicSDNode>(N)->getMergedOrdering())) " "return false;\n"; if (isLoad() || isStore()) { @@ -1242,7 +1262,7 @@ StringRef TreePredicateFn::getImmType() const { StringRef TreePredicateFn::getImmTypeIdentifier() const { if (immCodeUsesAPInt()) return "APInt"; - else if (immCodeUsesAPFloat()) + if (immCodeUsesAPFloat()) return "APFloat"; return "I64"; } @@ -1423,24 +1443,50 @@ getPatternComplexity(const CodeGenDAGPatterns &CGP) const { return getPatternSize(getSrcPattern(), CGP) + getAddedComplexity(); } +void PatternToMatch::getPredicateRecords( + SmallVectorImpl<Record *> &PredicateRecs) const { + for (Init *I : Predicates->getValues()) { + if (DefInit *Pred = dyn_cast<DefInit>(I)) { + Record *Def = Pred->getDef(); + if (!Def->isSubClassOf("Predicate")) { +#ifndef NDEBUG + Def->dump(); +#endif + llvm_unreachable("Unknown predicate type!"); + } + PredicateRecs.push_back(Def); + } + } + // Sort so that different orders get canonicalized to the same string. + llvm::sort(PredicateRecs, LessRecord()); +} + /// getPredicateCheck - Return a single string containing all of this /// pattern's predicates concatenated with "&&" operators. /// std::string PatternToMatch::getPredicateCheck() const { - SmallVector<const Predicate*,4> PredList; - for (const Predicate &P : Predicates) { - if (!P.getCondString().empty()) - PredList.push_back(&P); + SmallVector<Record *, 4> PredicateRecs; + getPredicateRecords(PredicateRecs); + + SmallString<128> PredicateCheck; + for (Record *Pred : PredicateRecs) { + StringRef CondString = Pred->getValueAsString("CondString"); + if (CondString.empty()) + continue; + if (!PredicateCheck.empty()) + PredicateCheck += " && "; + PredicateCheck += "("; + PredicateCheck += CondString; + PredicateCheck += ")"; } - llvm::sort(PredList, deref<std::less<>>()); - std::string Check; - for (unsigned i = 0, e = PredList.size(); i != e; ++i) { - if (i != 0) - Check += " && "; - Check += '(' + PredList[i]->getCondString() + ')'; + if (!HwModeFeatures.empty()) { + if (!PredicateCheck.empty()) + PredicateCheck += " && "; + PredicateCheck += HwModeFeatures; } - return Check; + + return std::string(PredicateCheck); } //===----------------------------------------------------------------------===// @@ -1791,7 +1837,7 @@ static unsigned GetNumNodeResults(Record *Operator, CodeGenDAGPatterns &CDP) { // The number of results of a fragment with alternative records is the // maximum number of results across all alternatives. unsigned NumResults = 0; - for (auto T : PFRec->getTrees()) + for (const auto &T : PFRec->getTrees()) NumResults = std::max(NumResults, T->getNumTypes()); return NumResults; } @@ -1857,9 +1903,9 @@ void TreePatternNode::print(raw_ostream &OS) const { if (!isLeaf()) { if (getNumChildren() != 0) { OS << " "; - getChild(0)->print(OS); - for (unsigned i = 1, e = getNumChildren(); i != e; ++i) { - OS << ", "; + ListSeparator LS; + for (unsigned i = 0, e = getNumChildren(); i != e; ++i) { + OS << LS; getChild(i)->print(OS); } } @@ -2013,10 +2059,13 @@ void TreePatternNode::InlinePatternFragments( if (ChildAlternatives[i].empty()) return; - for (auto NewChild : ChildAlternatives[i]) - assert((Child->getPredicateCalls().empty() || - NewChild->getPredicateCalls() == Child->getPredicateCalls()) && - "Non-empty child predicate clobbered!"); + assert((Child->getPredicateCalls().empty() || + llvm::all_of(ChildAlternatives[i], + [&](const TreePatternNodePtr &NewChild) { + return NewChild->getPredicateCalls() == + Child->getPredicateCalls(); + })) && + "Non-empty child predicate clobbered!"); } // The end result is an all-pairs construction of the resultant pattern. @@ -2088,7 +2137,7 @@ void TreePatternNode::InlinePatternFragments( } // Loop over all fragment alternatives. - for (auto Alternative : Frag->getTrees()) { + for (const auto &Alternative : Frag->getTrees()) { TreePatternNodePtr FragTree = Alternative->clone(); if (!PredFn.isAlwaysTrue()) @@ -2637,6 +2686,8 @@ static bool OnlyOnRHSOfCommutative(TreePatternNode *N) { return true; if (N->isLeaf() && isa<IntInit>(N->getLeafValue())) return true; + if (isImmAllOnesAllZerosMatch(N)) + return true; return false; } @@ -2802,7 +2853,8 @@ TreePatternNodePtr TreePattern::ParseTreePattern(Init *TheInit, ParseTreePattern(Dag->getArg(0), Dag->getArgNameStr(0)); // Apply the type cast. - assert(New->getNumTypes() == 1 && "FIXME: Unhandled"); + if (New->getNumTypes() != 1) + error("Type cast can only have one type!"); const CodeGenHwModes &CGH = getDAGPatterns().getTargetInfo().getHwModes(); New->UpdateNodeType(0, getValueTypeByHwMode(Operator, CGH), *this); @@ -3030,9 +3082,10 @@ InferAllTypes(const StringMap<SmallVector<TreePatternNode*,1> > *InNamedTypes) { void TreePattern::print(raw_ostream &OS) const { OS << getRecord()->getName(); if (!Args.empty()) { - OS << "(" << Args[0]; - for (unsigned i = 1, e = Args.size(); i != e; ++i) - OS << ", " << Args[i]; + OS << "("; + ListSeparator LS; + for (const std::string &Arg : Args) + OS << LS << Arg; OS << ")"; } OS << ": "; @@ -3070,15 +3123,15 @@ CodeGenDAGPatterns::CodeGenDAGPatterns(RecordKeeper &R, ParsePatternFragments(/*OutFrags*/true); ParsePatterns(); + // Generate variants. For example, commutative patterns can match + // multiple ways. Add them to PatternsToMatch as well. + GenerateVariants(); + // Break patterns with parameterized types into a series of patterns, // where each one has a fixed type and is predicated on the conditions // of the associated HW mode. ExpandHwModeBasedTypes(); - // Generate variants. For example, commutative patterns can match - // multiple ways. Add them to PatternsToMatch as well. - GenerateVariants(); - // Infer instruction flags. For example, we can detect loads, // stores, and side effects in many cases by examining an // instruction's pattern. @@ -3201,7 +3254,7 @@ void CodeGenDAGPatterns::ParsePatternFragments(bool OutFrags) { // it. Record *Transform = Frag->getValueAsDef("OperandTransform"); if (!getSDNodeTransform(Transform).second.empty()) // not noop xform? - for (auto T : P->getTrees()) + for (const auto &T : P->getTrees()) T->setTransformFn(Transform); } @@ -3470,6 +3523,9 @@ private: if (N->getNumChildren() != 1 || !N->getChild(0)->isLeaf()) return false; + if (N->getOperator()->isSubClassOf("ComplexPattern")) + return false; + const SDNodeInfo &OpInfo = CDP.getSDNodeInfo(N->getOperator()); if (OpInfo.getNumResults() != 1 || OpInfo.getNumOperands() != 1) return false; @@ -3671,9 +3727,9 @@ void CodeGenDAGPatterns::parseInstructionPattern( TreePatternNodePtr Pat = I.getTree(j); if (Pat->getNumTypes() != 0) { raw_svector_ostream OS(TypesString); + ListSeparator LS; for (unsigned k = 0, ke = Pat->getNumTypes(); k != ke; ++k) { - if (k > 0) - OS << ", "; + OS << LS; Pat->getExtType(k).writeToStream(OS); } I.error("Top-level forms in instruction pattern should have" @@ -3904,20 +3960,6 @@ static void FindNames(TreePatternNode *P, } } -std::vector<Predicate> CodeGenDAGPatterns::makePredList(ListInit *L) { - std::vector<Predicate> Preds; - for (Init *I : L->getValues()) { - if (DefInit *Pred = dyn_cast<DefInit>(I)) - Preds.push_back(Pred->getDef()); - else - llvm_unreachable("Non-def on the list"); - } - - // Sort so that different orders get canonicalized to the same string. - llvm::sort(Preds); - return Preds; -} - void CodeGenDAGPatterns::AddPatternToMatch(TreePattern *Pattern, PatternToMatch &&PTM) { // Do some sanity checking on the pattern we're about to match. @@ -3958,7 +4000,7 @@ void CodeGenDAGPatterns::AddPatternToMatch(TreePattern *Pattern, SrcNames[Entry.first].second == 1) Pattern->error("Pattern has dead named input: $" + Entry.first); - PatternsToMatch.push_back(PTM); + PatternsToMatch.push_back(std::move(PTM)); } void CodeGenDAGPatterns::InferInstructionFlags() { @@ -4030,8 +4072,7 @@ void CodeGenDAGPatterns::InferInstructionFlags() { /// Verify instruction flags against pattern node properties. void CodeGenDAGPatterns::VerifyInstructionFlags() { unsigned Errors = 0; - for (ptm_iterator I = ptm_begin(), E = ptm_end(); I != E; ++I) { - const PatternToMatch &PTM = *I; + for (const PatternToMatch &PTM : ptms()) { SmallVector<Record*, 8> Instrs; getInstructionsInTree(PTM.getDstPattern(), Instrs); if (Instrs.empty()) @@ -4172,7 +4213,7 @@ void CodeGenDAGPatterns::ParseOnePattern(Record *TheDef, // resolve cases where the input type is known to be a pointer type (which // is considered resolved), but the result knows it needs to be 32- or // 64-bits. Infer the other way for good measure. - for (auto T : Pattern.getTrees()) + for (const auto &T : Pattern.getTrees()) for (unsigned i = 0, e = std::min(Result.getOnlyTree()->getNumTypes(), T->getNumTypes()); i != e; ++i) { @@ -4226,11 +4267,10 @@ void CodeGenDAGPatterns::ParseOnePattern(Record *TheDef, // will lead to a contradiction, which is not an error however, but // a sign that this pattern will simply never match. if (Temp.getOnlyTree()->hasPossibleType()) - for (auto T : Pattern.getTrees()) + for (const auto &T : Pattern.getTrees()) if (T->hasPossibleType()) AddPatternToMatch(&Pattern, - PatternToMatch(TheDef, makePredList(Preds), - T, Temp.getOnlyTree(), + PatternToMatch(TheDef, Preds, T, Temp.getOnlyTree(), InstImpResults, Complexity, TheDef->getID())); } @@ -4281,32 +4321,29 @@ static void collectModes(std::set<unsigned> &Modes, const TreePatternNode *N) { void CodeGenDAGPatterns::ExpandHwModeBasedTypes() { const CodeGenHwModes &CGH = getTargetInfo().getHwModes(); - std::map<unsigned,std::vector<Predicate>> ModeChecks; - std::vector<PatternToMatch> Copy = PatternsToMatch; - PatternsToMatch.clear(); + std::vector<PatternToMatch> Copy; + PatternsToMatch.swap(Copy); - auto AppendPattern = [this, &ModeChecks](PatternToMatch &P, unsigned Mode) { - TreePatternNodePtr NewSrc = P.SrcPattern->clone(); - TreePatternNodePtr NewDst = P.DstPattern->clone(); + auto AppendPattern = [this](PatternToMatch &P, unsigned Mode, + StringRef Check) { + TreePatternNodePtr NewSrc = P.getSrcPattern()->clone(); + TreePatternNodePtr NewDst = P.getDstPattern()->clone(); if (!NewSrc->setDefaultMode(Mode) || !NewDst->setDefaultMode(Mode)) { return; } - std::vector<Predicate> Preds = P.Predicates; - const std::vector<Predicate> &MC = ModeChecks[Mode]; - llvm::append_range(Preds, MC); - PatternsToMatch.emplace_back(P.getSrcRecord(), Preds, std::move(NewSrc), - std::move(NewDst), P.getDstRegs(), - P.getAddedComplexity(), Record::getNewUID(), - Mode); + PatternsToMatch.emplace_back(P.getSrcRecord(), P.getPredicates(), + std::move(NewSrc), std::move(NewDst), + P.getDstRegs(), P.getAddedComplexity(), + Record::getNewUID(), Mode, Check); }; for (PatternToMatch &P : Copy) { TreePatternNodePtr SrcP = nullptr, DstP = nullptr; - if (P.SrcPattern->hasProperTypeByHwMode()) - SrcP = P.SrcPattern; - if (P.DstPattern->hasProperTypeByHwMode()) - DstP = P.DstPattern; + if (P.getSrcPattern()->hasProperTypeByHwMode()) + SrcP = P.getSrcPatternShared(); + if (P.getDstPattern()->hasProperTypeByHwMode()) + DstP = P.getDstPatternShared(); if (!SrcP && !DstP) { PatternsToMatch.push_back(P); continue; @@ -4329,31 +4366,27 @@ void CodeGenDAGPatterns::ExpandHwModeBasedTypes() { // duplicated patterns with different predicate checks, construct the // default check as a negation of all predicates that are actually present // in the source/destination patterns. - std::vector<Predicate> DefaultPred; + SmallString<128> DefaultCheck; for (unsigned M : Modes) { if (M == DefaultMode) continue; - if (ModeChecks.find(M) != ModeChecks.end()) - continue; // Fill the map entry for this mode. const HwMode &HM = CGH.getMode(M); - ModeChecks[M].emplace_back(Predicate(HM.Features, true)); + AppendPattern(P, M, "(MF->getSubtarget().checkFeatures(\"" + HM.Features + "\"))"); // Add negations of the HM's predicates to the default predicate. - DefaultPred.emplace_back(Predicate(HM.Features, false)); - } - - for (unsigned M : Modes) { - if (M == DefaultMode) - continue; - AppendPattern(P, M); + if (!DefaultCheck.empty()) + DefaultCheck += " && "; + DefaultCheck += "(!(MF->getSubtarget().checkFeatures(\""; + DefaultCheck += HM.Features; + DefaultCheck += "\")))"; } bool HasDefault = Modes.count(DefaultMode); if (HasDefault) - AppendPattern(P, DefaultMode); + AppendPattern(P, DefaultMode, DefaultCheck); } } @@ -4635,17 +4668,7 @@ void CodeGenDAGPatterns::GenerateVariants() { // intentionally do not reconsider these. Any variants of added patterns have // already been added. // - 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) { + for (unsigned i = 0, e = PatternsToMatch.size(); i != e; ++i) { MultipleUseVarSet DepVars; std::vector<TreePatternNodePtr> Variants; FindDepVars(PatternsToMatch[i].getSrcPattern(), DepVars); @@ -4655,6 +4678,9 @@ void CodeGenDAGPatterns::GenerateVariants() { GenerateVariantsOf(PatternsToMatch[i].getSrcPatternShared(), Variants, *this, DepVars); + assert(PatternsToMatch[i].getHwModeFeatures().empty() && + "HwModes should not have been expanded yet!"); + assert(!Variants.empty() && "Must create at least original variant!"); if (Variants.size() == 1) // No additional variants for this pattern. continue; @@ -4662,40 +4688,8 @@ void CodeGenDAGPatterns::GenerateVariants() { LLVM_DEBUG(errs() << "FOUND VARIANTS OF: "; PatternsToMatch[i].getSrcPattern()->dump(); errs() << "\n"); - PatternsWithVariants[i] = std::make_pair(DepVars, Variants); - - // Cache matching predicates. - if (MatchedPatterns[i]) - continue; - - const std::vector<Predicate> &Predicates = - PatternsToMatch[i].getPredicates(); - - BitVector &Matches = MatchedPredicates[i]; - MatchedPatterns.set(i); - Matches.set(i); - - // 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 != (int)i) { - MatchedPatterns.set(p); - 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"); @@ -4704,7 +4698,8 @@ void CodeGenDAGPatterns::GenerateVariants() { bool AlreadyExists = false; for (unsigned p = 0, e = PatternsToMatch.size(); p != e; ++p) { // Skip if the top level predicates do not match. - if (!Matches[p]) + if ((i != p) && (PatternsToMatch[i].getPredicates() != + PatternsToMatch[p].getPredicates())) continue; // Check to see if this variant already exists. if (Variant->isIsomorphicTo(PatternsToMatch[p].getSrcPattern(), @@ -4718,16 +4713,13 @@ void CodeGenDAGPatterns::GenerateVariants() { if (AlreadyExists) continue; // Otherwise, add it to the list of patterns we have. - PatternsToMatch.push_back(PatternToMatch( + PatternsToMatch.emplace_back( PatternsToMatch[i].getSrcRecord(), PatternsToMatch[i].getPredicates(), Variant, PatternsToMatch[i].getDstPatternShared(), PatternsToMatch[i].getDstRegs(), - PatternsToMatch[i].getAddedComplexity(), Record::getNewUID())); - MatchedPredicates.push_back(Matches); - - // Add a new match the same as this pattern. - for (auto &P : MatchedPredicates) - P.push_back(P[i]); + PatternsToMatch[i].getAddedComplexity(), Record::getNewUID(), + PatternsToMatch[i].getForceMode(), + PatternsToMatch[i].getHwModeFeatures()); } LLVM_DEBUG(errs() << "\n"); |