diff options
author | Chris Lattner <sabre@nondot.org> | 2010-03-19 04:54:36 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-03-19 04:54:36 +0000 |
commit | 5a9b8fb95c9a4c6fd5e06c1e89fa9263d39cd252 (patch) | |
tree | eb4a6ececd5b82c2258845a559e65fd8d32e1f81 | |
parent | e9eda0f85d8727b2f109d42752cd7f1bf6ef95e0 (diff) | |
download | external_llvm-5a9b8fb95c9a4c6fd5e06c1e89fa9263d39cd252.zip external_llvm-5a9b8fb95c9a4c6fd5e06c1e89fa9263d39cd252.tar.gz external_llvm-5a9b8fb95c9a4c6fd5e06c1e89fa9263d39cd252.tar.bz2 |
rewrite EnforceSmallerThan to be less bone headed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@98933 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | utils/TableGen/CodeGenDAGPatterns.cpp | 139 | ||||
-rw-r--r-- | utils/TableGen/CodeGenDAGPatterns.h | 5 |
2 files changed, 80 insertions, 64 deletions
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index 851dd8e..98f86f8 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 404cb35..caf0532 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); }; } |