diff options
Diffstat (limited to 'contrib/llvm-project/llvm/utils/TableGen/CodeGenDAGPatterns.cpp')
| -rw-r--r-- | contrib/llvm-project/llvm/utils/TableGen/CodeGenDAGPatterns.cpp | 122 |
1 files changed, 87 insertions, 35 deletions
diff --git a/contrib/llvm-project/llvm/utils/TableGen/CodeGenDAGPatterns.cpp b/contrib/llvm-project/llvm/utils/TableGen/CodeGenDAGPatterns.cpp index c8f710d66a03..7e0ba98da94a 100644 --- a/contrib/llvm-project/llvm/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/contrib/llvm-project/llvm/utils/TableGen/CodeGenDAGPatterns.cpp @@ -23,6 +23,7 @@ #include "llvm/ADT/Twine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/TypeSize.h" #include "llvm/TableGen/Error.h" #include "llvm/TableGen/Record.h" #include <algorithm> @@ -481,12 +482,12 @@ bool TypeInfer::EnforceSmallerThan(TypeSetByHwMode &Small, if (any_of(S, isIntegerOrPtr) && any_of(S, isIntegerOrPtr)) { auto NotInt = [](MVT VT) { return !isIntegerOrPtr(VT); }; - Changed |= berase_if(S, NotInt) | - berase_if(B, NotInt); + Changed |= berase_if(S, NotInt); + Changed |= berase_if(B, NotInt); } else if (any_of(S, isFloatingPoint) && any_of(B, isFloatingPoint)) { auto NotFP = [](MVT VT) { return !isFloatingPoint(VT); }; - Changed |= berase_if(S, NotFP) | - berase_if(B, NotFP); + Changed |= berase_if(S, NotFP); + Changed |= berase_if(B, NotFP); } else if (S.empty() || B.empty()) { Changed = !S.empty() || !B.empty(); S.clear(); @@ -497,24 +498,30 @@ bool TypeInfer::EnforceSmallerThan(TypeSetByHwMode &Small, } if (none_of(S, isVector) || none_of(B, isVector)) { - Changed |= berase_if(S, isVector) | - berase_if(B, isVector); + Changed |= berase_if(S, isVector); + Changed |= berase_if(B, isVector); } } auto LT = [](MVT A, MVT B) -> bool { - return A.getScalarSizeInBits() < B.getScalarSizeInBits() || - (A.getScalarSizeInBits() == B.getScalarSizeInBits() && - A.getSizeInBits() < B.getSizeInBits()); + // Always treat non-scalable MVTs as smaller than scalable MVTs for the + // purposes of ordering. + auto ASize = std::make_tuple(A.isScalableVector(), A.getScalarSizeInBits(), + A.getSizeInBits()); + auto BSize = std::make_tuple(B.isScalableVector(), B.getScalarSizeInBits(), + B.getSizeInBits()); + return ASize < BSize; }; - auto LE = [<](MVT A, MVT B) -> bool { + auto SameKindLE = [](MVT A, MVT B) -> bool { // This function is used when removing elements: when a vector is compared - // to a non-vector, it should return false (to avoid removal). - if (A.isVector() != B.isVector()) + // to a non-vector or a scalable vector to any non-scalable MVT, it should + // return false (to avoid removal). + if (std::make_tuple(A.isVector(), A.isScalableVector()) != + std::make_tuple(B.isVector(), B.isScalableVector())) return false; - return LT(A, B) || (A.getScalarSizeInBits() == B.getScalarSizeInBits() && - A.getSizeInBits() == B.getSizeInBits()); + return std::make_tuple(A.getScalarSizeInBits(), A.getSizeInBits()) <= + std::make_tuple(B.getScalarSizeInBits(), B.getSizeInBits()); }; for (unsigned M : Modes) { @@ -524,25 +531,29 @@ bool TypeInfer::EnforceSmallerThan(TypeSetByHwMode &Small, // smaller-or-equal than MinS. auto MinS = min_if(S.begin(), S.end(), isScalar, LT); if (MinS != S.end()) - Changed |= berase_if(B, std::bind(LE, std::placeholders::_1, *MinS)); + Changed |= berase_if(B, std::bind(SameKindLE, + std::placeholders::_1, *MinS)); // MaxS = max scalar in Big, remove all scalars from Small that are // larger than MaxS. auto MaxS = max_if(B.begin(), B.end(), isScalar, LT); if (MaxS != B.end()) - Changed |= berase_if(S, std::bind(LE, *MaxS, std::placeholders::_1)); + Changed |= berase_if(S, std::bind(SameKindLE, + *MaxS, std::placeholders::_1)); // MinV = min vector in Small, remove all vectors from Big that are // smaller-or-equal than MinV. auto MinV = min_if(S.begin(), S.end(), isVector, LT); if (MinV != S.end()) - Changed |= berase_if(B, std::bind(LE, std::placeholders::_1, *MinV)); + Changed |= berase_if(B, std::bind(SameKindLE, + std::placeholders::_1, *MinV)); // MaxV = max vector in Big, remove all vectors from Small that are // larger than MaxV. auto MaxV = max_if(B.begin(), B.end(), isVector, LT); if (MaxV != B.end()) - Changed |= berase_if(S, std::bind(LE, *MaxV, std::placeholders::_1)); + Changed |= berase_if(S, std::bind(SameKindLE, + *MaxV, std::placeholders::_1)); } return Changed; @@ -625,7 +636,7 @@ bool TypeInfer::EnforceVectorSubVectorTypeIs(TypeSetByHwMode &Vec, /// Return true if S has no element (vector type) that T is a sub-vector of, /// i.e. has the same element type as T and more elements. auto NoSubV = [&IsSubVec](const TypeSetByHwMode::SetType &S, MVT T) -> bool { - for (const auto &I : S) + for (auto I : S) if (IsSubVec(T, I)) return false; return true; @@ -634,7 +645,7 @@ bool TypeInfer::EnforceVectorSubVectorTypeIs(TypeSetByHwMode &Vec, /// Return true if S has no element (vector type) that T is a super-vector /// of, i.e. has the same element type as T and fewer elements. auto NoSupV = [&IsSubVec](const TypeSetByHwMode::SetType &S, MVT T) -> bool { - for (const auto &I : S) + for (auto I : S) if (IsSubVec(I, T)) return false; return true; @@ -769,7 +780,10 @@ void TypeInfer::expandOverloads(TypeSetByHwMode::SetType &Out, for (MVT T : MVT::integer_valuetypes()) if (Legal.count(T)) Out.insert(T); - for (MVT T : MVT::integer_vector_valuetypes()) + for (MVT T : MVT::integer_fixedlen_vector_valuetypes()) + if (Legal.count(T)) + Out.insert(T); + for (MVT T : MVT::integer_scalable_vector_valuetypes()) if (Legal.count(T)) Out.insert(T); return; @@ -777,7 +791,10 @@ void TypeInfer::expandOverloads(TypeSetByHwMode::SetType &Out, for (MVT T : MVT::fp_valuetypes()) if (Legal.count(T)) Out.insert(T); - for (MVT T : MVT::fp_vector_valuetypes()) + for (MVT T : MVT::fp_fixedlen_vector_valuetypes()) + if (Legal.count(T)) + Out.insert(T); + for (MVT T : MVT::fp_scalable_vector_valuetypes()) if (Legal.count(T)) Out.insert(T); return; @@ -883,7 +900,8 @@ std::string TreePredicateFn::getPredCode() const { if (isLoad()) { if (!isUnindexed() && !isNonExtLoad() && !isAnyExtLoad() && !isSignExtLoad() && !isZeroExtLoad() && getMemoryVT() == nullptr && - getScalarMemoryVT() == nullptr) + getScalarMemoryVT() == nullptr && getAddressSpaces() == nullptr && + getMinAlignment() < 1) PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(), "IsLoad cannot be used by itself"); } else { @@ -903,7 +921,8 @@ std::string TreePredicateFn::getPredCode() const { if (isStore()) { if (!isUnindexed() && !isTruncStore() && !isNonTruncStore() && - getMemoryVT() == nullptr && getScalarMemoryVT() == nullptr) + getMemoryVT() == nullptr && getScalarMemoryVT() == nullptr && + getAddressSpaces() == nullptr && getMinAlignment() < 1) PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(), "IsStore cannot be used by itself"); } else { @@ -917,6 +936,7 @@ std::string TreePredicateFn::getPredCode() const { if (isAtomic()) { if (getMemoryVT() == nullptr && !isAtomicOrderingMonotonic() && + getAddressSpaces() == nullptr && !isAtomicOrderingAcquire() && !isAtomicOrderingRelease() && !isAtomicOrderingAcquireRelease() && !isAtomicOrderingSequentiallyConsistent() && @@ -977,6 +997,13 @@ std::string TreePredicateFn::getPredCode() const { Code += ")\nreturn false;\n"; } + int64_t MinAlign = getMinAlignment(); + if (MinAlign > 0) { + Code += "if (cast<MemSDNode>(N)->getAlignment() < "; + Code += utostr(MinAlign); + Code += ")\nreturn false;\n"; + } + Record *MemoryVT = getMemoryVT(); if (MemoryVT) @@ -1177,6 +1204,13 @@ ListInit *TreePredicateFn::getAddressSpaces() const { return R->getValueAsListInit("AddressSpaces"); } +int64_t TreePredicateFn::getMinAlignment() const { + Record *R = getOrigPatFragRecord()->getRecord(); + if (R->isValueUnset("MinAlignment")) + return 0; + return R->getValueAsInt("MinAlignment"); +} + Record *TreePredicateFn::getScalarMemoryVT() const { Record *R = getOrigPatFragRecord()->getRecord(); if (R->isValueUnset("ScalarMemoryVT")) @@ -1281,13 +1315,29 @@ std::string TreePredicateFn::getCodeToRunOnSDNode() const { // Handle arbitrary node predicates. assert(hasPredCode() && "Don't have any predicate code!"); + + // If this is using PatFrags, there are multiple trees to search. They should + // all have the same class. FIXME: Is there a way to find a common + // superclass? StringRef ClassName; - if (PatFragRec->getOnlyTree()->isLeaf()) - ClassName = "SDNode"; - else { - Record *Op = PatFragRec->getOnlyTree()->getOperator(); - ClassName = PatFragRec->getDAGPatterns().getSDNodeInfo(Op).getSDClassName(); + for (const auto &Tree : PatFragRec->getTrees()) { + StringRef TreeClassName; + if (Tree->isLeaf()) + TreeClassName = "SDNode"; + else { + Record *Op = Tree->getOperator(); + const SDNodeInfo &Info = PatFragRec->getDAGPatterns().getSDNodeInfo(Op); + TreeClassName = Info.getSDClassName(); + } + + if (ClassName.empty()) + ClassName = TreeClassName; + else if (ClassName != TreeClassName) { + PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(), + "PatFrags trees do not have consistent class"); + } } + std::string Result; if (ClassName == "SDNode") Result = " SDNode *N = Node;\n"; @@ -1373,9 +1423,11 @@ getPatternComplexity(const CodeGenDAGPatterns &CGP) const { /// std::string PatternToMatch::getPredicateCheck() const { SmallVector<const Predicate*,4> PredList; - for (const Predicate &P : Predicates) - PredList.push_back(&P); - llvm::sort(PredList, deref<llvm::less>()); + for (const Predicate &P : Predicates) { + if (!P.getCondString().empty()) + PredList.push_back(&P); + } + llvm::sort(PredList, deref<std::less<>>()); std::string Check; for (unsigned i = 0, e = PredList.size(); i != e; ++i) { @@ -2772,6 +2824,7 @@ TreePatternNodePtr TreePattern::ParseTreePattern(Init *TheInit, if (Operator->isSubClassOf("SDNode") && Operator->getName() != "imm" && + Operator->getName() != "timm" && Operator->getName() != "fpimm" && Operator->getName() != "tglobaltlsaddr" && Operator->getName() != "tconstpool" && @@ -2991,8 +3044,7 @@ CodeGenDAGPatterns::CodeGenDAGPatterns(RecordKeeper &R, : Records(R), Target(R), LegalVTS(Target.getLegalValueTypes()), PatternRewriter(PatternRewriter) { - Intrinsics = CodeGenIntrinsicTable(Records, false); - TgtIntrinsics = CodeGenIntrinsicTable(Records, true); + Intrinsics = CodeGenIntrinsicTable(Records); ParseNodeInfo(); ParseNodeTransforms(); ParseComplexPatterns(); @@ -3083,7 +3135,7 @@ void CodeGenDAGPatterns::ParsePatternFragments(bool OutFrags) { ListInit *LI = Frag->getValueAsListInit("Fragments"); TreePattern *P = - (PatternFragments[Frag] = llvm::make_unique<TreePattern>( + (PatternFragments[Frag] = std::make_unique<TreePattern>( Frag, LI, !Frag->isSubClassOf("OutPatFrag"), *this)).get(); |
