From 90790c3217c6be295004623590273529e04fe72a Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Tue, 28 Jan 2014 04:49:01 +0000 Subject: [PATCH] Improve handling of EnforceSmallerThan. Remove all types that are smaller from the larger set not just the smallest type from the smaller set. Ensure 'smaller' vectors have the same or fewer total bits. Similar for 'larger' vectors. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@200287 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/CodeGenDAGPatterns.cpp | 224 ++++++++++---------------- utils/TableGen/CodeGenDAGPatterns.h | 4 + 2 files changed, 91 insertions(+), 137 deletions(-) diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index 358334f0622..04332300957 100644 --- a/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/utils/TableGen/CodeGenDAGPatterns.cpp @@ -120,6 +120,14 @@ bool EEVT::TypeSet::hasFloatingPointTypes() const { return false; } +/// hasScalarTypes - Return true if this TypeSet contains a scalar value type. +bool EEVT::TypeSet::hasScalarTypes() const { + for (unsigned i = 0, e = TypeVec.size(); i != e; ++i) + if (isScalar(TypeVec[i])) + return true; + return false; +} + /// hasVectorTypes - Return true if this TypeSet contains a vAny or a vector /// value type. bool EEVT::TypeSet::hasVectorTypes() const { @@ -339,8 +347,9 @@ bool EEVT::TypeSet::EnforceVector(TreePattern &TP) { -/// EnforceSmallerThan - 'this' must be a smaller VT than Other. Update -/// this an other based on this information. +/// EnforceSmallerThan - 'this' must be a smaller VT than Other. For vectors +/// this shoud be based on the element type. Update this and other based on +/// this information. bool EEVT::TypeSet::EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP) { if (TP.hasError()) return false; @@ -371,159 +380,100 @@ bool EEVT::TypeSet::EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP) { // If one contains vectors but the other doesn't pull vectors out. if (!hasVectorTypes()) MadeChange |= Other.EnforceScalar(TP); + else if (!hasScalarTypes()) + MadeChange |= Other.EnforceVector(TP); if (!Other.hasVectorTypes()) MadeChange |= EnforceScalar(TP); + else if (!Other.hasScalarTypes()) + MadeChange |= EnforceVector(TP); - if (isConcrete() && Other.isConcrete()) { - // If we are down to concrete types, 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!"); - - // Otherwise, if these are both vector types, either this vector - // must have a larger bitsize than the other, or this element type - // must be larger than the other. - MVT Type(getConcrete()); - MVT OtherType(Other.getConcrete()); - - if (hasVectorTypes() && Other.hasVectorTypes()) { - if (Type.getSizeInBits() >= OtherType.getSizeInBits()) - if (Type.getVectorElementType().getSizeInBits() - >= OtherType.getVectorElementType().getSizeInBits()) { - TP.error("Type inference contradiction found, '" + - getName() + "' element type not smaller than '" + - Other.getName() +"'!"); - return false; - } - } else - // For scalar types, the bitsize of this type must be larger - // than that of the other. - if (Type.getSizeInBits() >= OtherType.getSizeInBits()) { - TP.error("Type inference contradiction found, '" + - getName() + "' is not smaller than '" + - Other.getName() +"'!"); - return false; - } - } - - - // Handle int and fp as disjoint sets. This won't work for patterns - // that have mixed fp/int types but those are likely rare and would - // not have been accepted by this code previously. + // For vectors we need to ensure that smaller size doesn't produce larger + // vector and vice versa. + if (isConcrete() && isVector(getConcrete())) { + MVT IVT = getConcrete(); + unsigned Size = IVT.getSizeInBits(); - // Okay, find the smallest type from the current set and remove it from the - // largest set. - MVT::SimpleValueType SmallestInt = MVT::LAST_VALUETYPE; - for (unsigned i = 0, e = TypeVec.size(); i != e; ++i) - if (isInteger(TypeVec[i])) { - SmallestInt = TypeVec[i]; - break; - } - for (unsigned i = 1, e = TypeVec.size(); i != e; ++i) - if (isInteger(TypeVec[i]) && TypeVec[i] < SmallestInt) - SmallestInt = TypeVec[i]; + // Only keep types that have at least as many bits. + TypeSet InputSet(Other); - MVT::SimpleValueType SmallestFP = MVT::LAST_VALUETYPE; - for (unsigned i = 0, e = TypeVec.size(); i != e; ++i) - if (isFloatingPoint(TypeVec[i])) { - SmallestFP = TypeVec[i]; - break; - } - for (unsigned i = 1, e = TypeVec.size(); i != e; ++i) - if (isFloatingPoint(TypeVec[i]) && TypeVec[i] < SmallestFP) - SmallestFP = TypeVec[i]; - - int OtherIntSize = 0; - int OtherFPSize = 0; - for (SmallVectorImpl::iterator TVI = - Other.TypeVec.begin(); - TVI != Other.TypeVec.end(); - /* NULL */) { - if (isInteger(*TVI)) { - ++OtherIntSize; - if (*TVI == SmallestInt) { - TVI = Other.TypeVec.erase(TVI); - --OtherIntSize; + for (unsigned i = 0; i != Other.TypeVec.size(); ++i) { + assert(isVector(Other.TypeVec[i]) && "EnforceVector didn't work"); + if (MVT(Other.TypeVec[i]).getSizeInBits() < Size) { + Other.TypeVec.erase(Other.TypeVec.begin()+i--); MadeChange = true; - continue; } - } else if (isFloatingPoint(*TVI)) { - ++OtherFPSize; - if (*TVI == SmallestFP) { - TVI = Other.TypeVec.erase(TVI); - --OtherFPSize; + } + + if (Other.TypeVec.empty()) { // FIXME: Really want an SMLoc here! + TP.error("Type inference contradiction found, forcing '" + + InputSet.getName() + "' to have at least as many bits as " + + getName() + "'"); + return false; + } + } else if (Other.isConcrete() && isVector(Other.getConcrete())) { + MVT IVT = Other.getConcrete(); + unsigned Size = IVT.getSizeInBits(); + + // Only keep types with the same or fewer total bits + TypeSet InputSet(*this); + + for (unsigned i = 0; i != TypeVec.size(); ++i) { + assert(isVector(TypeVec[i]) && "EnforceVector didn't work"); + if (MVT(TypeVec[i]).getSizeInBits() > Size) { + TypeVec.erase(TypeVec.begin()+i--); MadeChange = true; - continue; } } - ++TVI; + + if (TypeVec.empty()) { // FIXME: Really want an SMLoc here! + TP.error("Type inference contradiction found, forcing '" + + InputSet.getName() + "' to have the same or fewer bits than " + + Other.getName() + "'"); + return false; + } } - // If this is the only type in the large set, the constraint can never be - // satisfied. - if ((Other.hasIntegerTypes() && OtherIntSize == 0) || - (Other.hasFloatingPointTypes() && OtherFPSize == 0)) { - TP.error("Type inference contradiction found, '" + - Other.getName() + "' has nothing larger than '" + getName() +"'!"); + // 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 (TP.hasError()) return false; + + // Okay, find the smallest scalar type from the other set and remove + // anything the same or smaller from the current set. + TypeSet InputSet(Other); + MVT::SimpleValueType Smallest = TypeVec[0]; + for (unsigned i = 0; i != Other.TypeVec.size(); ++i) { + if (Other.TypeVec[i] <= Smallest) { + Other.TypeVec.erase(Other.TypeVec.begin()+i--); + MadeChange = true; + } } - // Okay, find the largest type in the Other set and remove it from the - // current set. - MVT::SimpleValueType LargestInt = MVT::Other; - for (unsigned i = 0, e = Other.TypeVec.size(); i != e; ++i) - if (isInteger(Other.TypeVec[i])) { - LargestInt = Other.TypeVec[i]; - break; - } - for (unsigned i = 1, e = Other.TypeVec.size(); i != e; ++i) - if (isInteger(Other.TypeVec[i]) && Other.TypeVec[i] > LargestInt) - LargestInt = Other.TypeVec[i]; - - MVT::SimpleValueType LargestFP = MVT::Other; - for (unsigned i = 0, e = Other.TypeVec.size(); i != e; ++i) - if (isFloatingPoint(Other.TypeVec[i])) { - LargestFP = Other.TypeVec[i]; - break; - } - for (unsigned i = 1, e = Other.TypeVec.size(); i != e; ++i) - if (isFloatingPoint(Other.TypeVec[i]) && Other.TypeVec[i] > LargestFP) - LargestFP = Other.TypeVec[i]; - - int IntSize = 0; - int FPSize = 0; - for (SmallVectorImpl::iterator TVI = - TypeVec.begin(); - TVI != TypeVec.end(); - /* NULL */) { - if (isInteger(*TVI)) { - ++IntSize; - if (*TVI == LargestInt) { - TVI = TypeVec.erase(TVI); - --IntSize; - MadeChange = true; - continue; - } - } else if (isFloatingPoint(*TVI)) { - ++FPSize; - if (*TVI == LargestFP) { - TVI = TypeVec.erase(TVI); - --FPSize; - MadeChange = true; - continue; - } + if (Other.TypeVec.empty()) { + TP.error("Type inference contradiction found, '" + InputSet.getName() + + "' has nothing larger than '" + getName() +"'!"); + return false; + } + + // Okay, find the largest scalar type from the other set and remove + // anything the same or larger from the current set. + InputSet = TypeSet(*this); + MVT::SimpleValueType Largest = Other.TypeVec[Other.TypeVec.size()-1]; + for (unsigned i = 0; i != TypeVec.size(); ++i) { + if (TypeVec[i] >= Largest) { + TypeVec.erase(TypeVec.begin()+i--); + MadeChange = true; } - ++TVI; } - // If this is the only type in the small set, the constraint can never be - // satisfied. - if ((hasIntegerTypes() && IntSize == 0) || - (hasFloatingPointTypes() && FPSize == 0)) { - TP.error("Type inference contradiction found, '" + - getName() + "' has nothing smaller than '" + Other.getName()+"'!"); + if (TypeVec.empty()) { + TP.error("Type inference contradiction found, '" + InputSet.getName() + + "' has nothing smaller than '" + Other.getName() +"'!"); return false; } diff --git a/utils/TableGen/CodeGenDAGPatterns.h b/utils/TableGen/CodeGenDAGPatterns.h index 6fbdd4f9a85..0533bb8bb5b 100644 --- a/utils/TableGen/CodeGenDAGPatterns.h +++ b/utils/TableGen/CodeGenDAGPatterns.h @@ -96,6 +96,10 @@ namespace EEVT { /// a floating point value type. bool hasFloatingPointTypes() const; + /// hasScalarTypes - Return true if this TypeSet contains a scalar value + /// type. + bool hasScalarTypes() const; + /// hasVectorTypes - Return true if this TypeSet contains a vector value /// type. bool hasVectorTypes() const; -- 2.34.1