summaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/utils/TableGen/CodeGenDAGPatterns.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/utils/TableGen/CodeGenDAGPatterns.cpp')
-rw-r--r--contrib/llvm-project/llvm/utils/TableGen/CodeGenDAGPatterns.cpp122
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 = [&LT](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();