aboutsummaryrefslogtreecommitdiff
path: root/llvm/utils/TableGen/CodeGenDAGPatterns.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/utils/TableGen/CodeGenDAGPatterns.cpp')
-rw-r--r--llvm/utils/TableGen/CodeGenDAGPatterns.cpp336
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");