summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-03-19 04:54:36 +0000
committerChris Lattner <sabre@nondot.org>2010-03-19 04:54:36 +0000
commit5a9b8fb95c9a4c6fd5e06c1e89fa9263d39cd252 (patch)
treeeb4a6ececd5b82c2258845a559e65fd8d32e1f81 /utils
parente9eda0f85d8727b2f109d42752cd7f1bf6ef95e0 (diff)
downloadllvm-5a9b8fb95c9a4c6fd5e06c1e89fa9263d39cd252.tar.gz
llvm-5a9b8fb95c9a4c6fd5e06c1e89fa9263d39cd252.tar.bz2
llvm-5a9b8fb95c9a4c6fd5e06c1e89fa9263d39cd252.tar.xz
rewrite EnforceSmallerThan to be less bone headed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@98933 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.cpp139
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.h5
2 files changed, 80 insertions, 64 deletions
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index 851dd8e833..98f86f8246 100644
--- a/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -65,6 +65,13 @@ EEVT::TypeSet::TypeSet(const std::vector<MVT::SimpleValueType> &VTList) {
TypeVec.erase(std::unique(TypeVec.begin(), TypeVec.end()), TypeVec.end());
}
+/// FillWithPossibleTypes - Set to all legal types and return true, only valid
+/// on completely unknown type sets.
+bool EEVT::TypeSet::FillWithPossibleTypes(TreePattern &TP) {
+ assert(isCompletelyUnknown());
+ *this = TP.getDAGPatterns().getTargetInfo().getLegalValueTypes();
+ return true;
+}
/// hasIntegerTypes - Return true if this TypeSet contains iAny or an
/// integer value type.
@@ -202,10 +209,8 @@ bool EEVT::TypeSet::EnforceInteger(TreePattern &TP) {
bool MadeChange = false;
// If we know nothing, then get the full set.
- if (TypeVec.empty()) {
- *this = TP.getDAGPatterns().getTargetInfo().getLegalValueTypes();
- MadeChange = true;
- }
+ if (TypeVec.empty())
+ MadeChange = FillWithPossibleTypes(TP);
if (!hasFloatingPointTypes())
return MadeChange;
@@ -227,10 +232,8 @@ bool EEVT::TypeSet::EnforceFloatingPoint(TreePattern &TP) {
bool MadeChange = false;
// If we know nothing, then get the full set.
- if (TypeVec.empty()) {
- *this = TP.getDAGPatterns().getTargetInfo().getLegalValueTypes();
- MadeChange = true;
- }
+ if (TypeVec.empty())
+ MadeChange = FillWithPossibleTypes(TP);
if (!hasIntegerTypes())
return MadeChange;
@@ -252,10 +255,8 @@ bool EEVT::TypeSet::EnforceScalar(TreePattern &TP) {
bool MadeChange = false;
// If we know nothing, then get the full set.
- if (TypeVec.empty()) {
- *this = TP.getDAGPatterns().getTargetInfo().getLegalValueTypes();
- MadeChange = true;
- }
+ if (TypeVec.empty())
+ MadeChange = FillWithPossibleTypes(TP);
if (!hasVectorTypes())
return MadeChange;
@@ -277,10 +278,8 @@ bool EEVT::TypeSet::EnforceVector(TreePattern &TP) {
bool MadeChange = false;
// If we know nothing, then get the full set.
- if (TypeVec.empty()) {
- *this = TP.getDAGPatterns().getTargetInfo().getLegalValueTypes();
- MadeChange = true;
- }
+ if (TypeVec.empty())
+ MadeChange = FillWithPossibleTypes(TP);
// Filter out all the scalar types.
for (unsigned i = 0; i != TypeVec.size(); ++i)
@@ -294,72 +293,86 @@ bool EEVT::TypeSet::EnforceVector(TreePattern &TP) {
}
+
/// EnforceSmallerThan - 'this' must be a smaller VT than Other. Update
/// this an other based on this information.
bool EEVT::TypeSet::EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP) {
// Both operands must be integer or FP, but we don't care which.
bool MadeChange = false;
- // This code does not currently handle nodes which have multiple types,
- // where some types are integer, and some are fp. Assert that this is not
- // the case.
- assert(!(hasIntegerTypes() && hasFloatingPointTypes()) &&
- !(Other.hasIntegerTypes() && Other.hasFloatingPointTypes()) &&
- "SDTCisOpSmallerThanOp does not handle mixed int/fp types!");
+ if (isCompletelyUnknown())
+ MadeChange = FillWithPossibleTypes(TP);
+
+ if (Other.isCompletelyUnknown())
+ MadeChange = Other.FillWithPossibleTypes(TP);
+
// If one side is known to be integer or known to be FP but the other side has
// no information, get at least the type integrality info in there.
- if (hasIntegerTypes())
+ if (!hasFloatingPointTypes())
MadeChange |= Other.EnforceInteger(TP);
- else if (hasFloatingPointTypes())
+ else if (!hasIntegerTypes())
MadeChange |= Other.EnforceFloatingPoint(TP);
- if (Other.hasIntegerTypes())
+ if (!Other.hasFloatingPointTypes())
MadeChange |= EnforceInteger(TP);
- else if (Other.hasFloatingPointTypes())
+ else if (!Other.hasIntegerTypes())
MadeChange |= EnforceFloatingPoint(TP);
assert(!isCompletelyUnknown() && !Other.isCompletelyUnknown() &&
"Should have a type list now");
// If one contains vectors but the other doesn't pull vectors out.
- if (!hasVectorTypes() && Other.hasVectorTypes())
+ if (!hasVectorTypes())
MadeChange |= Other.EnforceScalar(TP);
- if (hasVectorTypes() && !Other.hasVectorTypes())
+ if (!hasVectorTypes())
MadeChange |= EnforceScalar(TP);
- // FIXME: This is a bone-headed way to do this.
+ // This code does not currently handle nodes which have multiple types,
+ // where some types are integer, and some are fp. Assert that this is not
+ // the case.
+ assert(!(hasIntegerTypes() && hasFloatingPointTypes()) &&
+ !(Other.hasIntegerTypes() && Other.hasFloatingPointTypes()) &&
+ "SDTCisOpSmallerThanOp does not handle mixed int/fp types!");
- // Get the set of legal VTs and filter it based on the known integrality.
- const CodeGenTarget &CGT = TP.getDAGPatterns().getTargetInfo();
- TypeSet LegalVTs = CGT.getLegalValueTypes();
-
- // TODO: If one or the other side is known to be a specific VT, we could prune
- // LegalVTs.
- if (hasIntegerTypes())
- LegalVTs.EnforceInteger(TP);
- else if (hasFloatingPointTypes())
- LegalVTs.EnforceFloatingPoint(TP);
- else
- return MadeChange;
+ // Okay, find the smallest type from the current set and remove it from the
+ // largest set.
+ MVT::SimpleValueType Smallest = TypeVec[0];
+ for (unsigned i = 1, e = TypeVec.size(); i != e; ++i)
+ if (TypeVec[i] < Smallest)
+ Smallest = TypeVec[i];
- switch (LegalVTs.TypeVec.size()) {
- case 0: assert(0 && "No legal VTs?");
- default: // Too many VT's to pick from.
- // TODO: If the biggest type in LegalVTs is in this set, we could remove it.
- // If one or the other side is known to be a specific VT, we could prune
- // LegalVTs.
- return MadeChange;
- case 1:
- // Only one VT of this flavor. Cannot ever satisfy the constraints.
- return MergeInTypeInfo(MVT::Other, TP); // throw
- case 2:
- // If we have exactly two possible types, the little operand must be the
- // small one, the big operand should be the big one. This is common with
- // float/double for example.
- assert(LegalVTs.TypeVec[0] < LegalVTs.TypeVec[1] && "Should be sorted!");
- MadeChange |= MergeInTypeInfo(LegalVTs.TypeVec[0], TP);
- MadeChange |= Other.MergeInTypeInfo(LegalVTs.TypeVec[1], TP);
- return MadeChange;
- }
+ // If this is the only type in the large set, the constraint can never be
+ // satisfied.
+ if (Other.TypeVec.size() == 1 && Other.TypeVec[0] == Smallest)
+ TP.error("Type inference contradiction found, '" +
+ Other.getName() + "' has nothing larger than '" + getName() +"'!");
+
+ SmallVector<MVT::SimpleValueType, 2>::iterator TVI =
+ std::find(Other.TypeVec.begin(), Other.TypeVec.end(), Smallest);
+ if (TVI != Other.TypeVec.end()) {
+ Other.TypeVec.erase(TVI);
+ MadeChange = true;
+ }
+
+ // Okay, find the largest type in the Other set and remove it from the
+ // current set.
+ MVT::SimpleValueType Largest = Other.TypeVec[0];
+ for (unsigned i = 1, e = Other.TypeVec.size(); i != e; ++i)
+ if (Other.TypeVec[i] > Largest)
+ Largest = Other.TypeVec[i];
+
+ // If this is the only type in the small set, the constraint can never be
+ // satisfied.
+ if (TypeVec.size() == 1 && TypeVec[0] == Largest)
+ TP.error("Type inference contradiction found, '" +
+ getName() + "' has nothing smaller than '" + Other.getName()+"'!");
+
+ TVI = std::find(TypeVec.begin(), TypeVec.end(), Largest);
+ if (TVI != TypeVec.end()) {
+ TypeVec.erase(TVI);
+ MadeChange = true;
+ }
+
+ return MadeChange;
}
/// EnforceVectorEltTypeIs - 'this' is now constrainted to be a vector type
@@ -370,10 +383,8 @@ bool EEVT::TypeSet::EnforceVectorEltTypeIs(MVT::SimpleValueType VT,
bool MadeChange = false;
// If we know nothing, then get the full set.
- if (TypeVec.empty()) {
- *this = TP.getDAGPatterns().getTargetInfo().getLegalValueTypes();
- MadeChange = true;
- }
+ if (TypeVec.empty())
+ MadeChange = FillWithPossibleTypes(TP);
// Filter out all the non-vector types and types which don't have the right
// element type.
diff --git a/utils/TableGen/CodeGenDAGPatterns.h b/utils/TableGen/CodeGenDAGPatterns.h
index 404cb35770..caf053285d 100644
--- a/utils/TableGen/CodeGenDAGPatterns.h
+++ b/utils/TableGen/CodeGenDAGPatterns.h
@@ -133,6 +133,11 @@ namespace EEVT {
bool operator!=(const TypeSet &RHS) const { return TypeVec != RHS.TypeVec; }
bool operator==(const TypeSet &RHS) const { return TypeVec == RHS.TypeVec; }
+
+ private:
+ /// FillWithPossibleTypes - Set to all legal types and return true, only
+ /// valid on completely unknown type sets
+ bool FillWithPossibleTypes(TreePattern &TP);
};
}