X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=utils%2FTableGen%2FCodeGenDAGPatterns.cpp;h=3f74a9999c9821234ecc99b5560eabbbf1866898;hb=b51ae5ef110e8cee43a28e207ffdbd1c681699ac;hp=35b6bf4416b50d6b8c575da48f9e8c153ced98f7;hpb=194e5aef9cbdd5ec76535da7d871767018214181;p=oota-llvm.git diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index 35b6bf4416b..3f74a9999c9 100644 --- a/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/utils/TableGen/CodeGenDAGPatterns.cpp @@ -14,6 +14,7 @@ #include "CodeGenDAGPatterns.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/Debug.h" @@ -385,55 +386,55 @@ bool EEVT::TypeSet::EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP) { // type size is smaller than the scalar size of the smallest type. For // vectors, we also need to make sure that the total size is no larger than // the size of the smallest type. - TypeSet InputSet(Other); - MVT Smallest = TypeVec[0]; - for (unsigned i = 0; i != Other.TypeVec.size(); ++i) { - MVT OtherVT = Other.TypeVec[i]; - // Don't compare vector and non-vector types. - if (OtherVT.isVector() != Smallest.isVector()) - continue; - // The getSizeInBits() check here is only needed for vectors, but is - // a subset of the scalar check for scalars so no need to qualify. - if (OtherVT.getScalarSizeInBits() <= Smallest.getScalarSizeInBits() || - OtherVT.getSizeInBits() < Smallest.getSizeInBits()) { - Other.TypeVec.erase(Other.TypeVec.begin()+i--); - MadeChange = true; + { + TypeSet InputSet(Other); + MVT Smallest = TypeVec[0]; + auto I = std::remove_if(Other.TypeVec.begin(), Other.TypeVec.end(), + [Smallest](MVT OtherVT) { + // Don't compare vector and non-vector types. + if (OtherVT.isVector() != Smallest.isVector()) + return false; + // The getSizeInBits() check here is only needed for vectors, but is + // a subset of the scalar check for scalars so no need to qualify. + return OtherVT.getScalarSizeInBits() <= Smallest.getScalarSizeInBits()|| + OtherVT.getSizeInBits() < Smallest.getSizeInBits(); + }); + MadeChange |= I != Other.TypeVec.end(); // If we're about to remove types. + Other.TypeVec.erase(I, Other.TypeVec.end()); + + if (Other.TypeVec.empty()) { + TP.error("Type inference contradiction found, '" + InputSet.getName() + + "' has nothing larger than '" + getName() +"'!"); + return false; } } - if (Other.TypeVec.empty()) { - TP.error("Type inference contradiction found, '" + InputSet.getName() + - "' has nothing larger than '" + getName() +"'!"); - return false; - } - // Okay, find the largest type from the other set and remove anything the // same or smaller from the current set. We need to ensure that the scalar // type size is larger than the scalar size of the largest type. For // vectors, we also need to make sure that the total size is no smaller than // the size of the largest type. - InputSet = TypeSet(*this); - MVT Largest = Other.TypeVec[Other.TypeVec.size()-1]; - for (unsigned i = 0; i != TypeVec.size(); ++i) { - MVT OtherVT = TypeVec[i]; - // Don't compare vector and non-vector types. - if (OtherVT.isVector() != Largest.isVector()) - continue; - // The getSizeInBits() check here is only needed for vectors, but is - // a subset of the scalar check for scalars so no need to qualify. - if (OtherVT.getScalarSizeInBits() >= Largest.getScalarSizeInBits() || - OtherVT.getSizeInBits() > Largest.getSizeInBits()) { - TypeVec.erase(TypeVec.begin()+i--); - MadeChange = true; + { + TypeSet InputSet(*this); + MVT Largest = Other.TypeVec[Other.TypeVec.size()-1]; + auto I = std::remove_if(TypeVec.begin(), TypeVec.end(), + [Largest](MVT OtherVT) { + // Don't compare vector and non-vector types. + if (OtherVT.isVector() != Largest.isVector()) + return false; + return OtherVT.getScalarSizeInBits() >= Largest.getScalarSizeInBits() || + OtherVT.getSizeInBits() > Largest.getSizeInBits(); + }); + MadeChange |= I != TypeVec.end(); // If we're about to remove types. + TypeVec.erase(I, TypeVec.end()); + + if (TypeVec.empty()) { + TP.error("Type inference contradiction found, '" + InputSet.getName() + + "' has nothing smaller than '" + Other.getName() +"'!"); + return false; } } - if (TypeVec.empty()) { - TP.error("Type inference contradiction found, '" + InputSet.getName() + - "' has nothing smaller than '" + Other.getName() +"'!"); - return false; - } - return MadeChange; } @@ -448,17 +449,17 @@ bool EEVT::TypeSet::EnforceVectorEltTypeIs(MVT::SimpleValueType VT, TypeSet InputSet(*this); // Filter out all the types which don't have the right element type. - for (unsigned i = 0; i != TypeVec.size(); ++i) { - assert(isVector(TypeVec[i]) && "EnforceVector didn't work"); - if (MVT(TypeVec[i]).getVectorElementType().SimpleTy != VT) { - TypeVec.erase(TypeVec.begin()+i--); - MadeChange = true; - } - } + auto I = std::remove_if(TypeVec.begin(), TypeVec.end(), + [VT](MVT VVT) { + return VVT.getVectorElementType().SimpleTy != VT; + }); + MadeChange |= I != TypeVec.end(); + TypeVec.erase(I, TypeVec.end()); if (TypeVec.empty()) { // FIXME: Really want an SMLoc here! TP.error("Type inference contradiction found, forcing '" + - InputSet.getName() + "' to have a vector element"); + InputSet.getName() + "' to have a vector element of type " + + getEnumName(VT)); return false; } @@ -481,8 +482,7 @@ bool EEVT::TypeSet::EnforceVectorEltTypeIs(EEVT::TypeSet &VTOperand, if (isConcrete()) { MVT IVT = getConcrete(); IVT = IVT.getVectorElementType(); - return MadeChange | - VTOperand.MergeInTypeInfo(IVT.SimpleTy, TP); + return MadeChange || VTOperand.MergeInTypeInfo(IVT.SimpleTy, TP); } // If the scalar type is known, filter out vector types whose element types @@ -492,22 +492,8 @@ bool EEVT::TypeSet::EnforceVectorEltTypeIs(EEVT::TypeSet &VTOperand, MVT::SimpleValueType VT = VTOperand.getConcrete(); - TypeSet InputSet(*this); + MadeChange |= EnforceVectorEltTypeIs(VT, TP); - // Filter out all the types which don't have the right element type. - for (unsigned i = 0; i != TypeVec.size(); ++i) { - assert(isVector(TypeVec[i]) && "EnforceVector didn't work"); - if (MVT(TypeVec[i]).getVectorElementType().SimpleTy != VT) { - TypeVec.erase(TypeVec.begin()+i--); - MadeChange = true; - } - } - - if (TypeVec.empty()) { // FIXME: Really want an SMLoc here! - TP.error("Type inference contradiction found, forcing '" + - InputSet.getName() + "' to have a vector element"); - return false; - } return MadeChange; } @@ -550,13 +536,13 @@ bool EEVT::TypeSet::EnforceVectorSubVectorTypeIs(EEVT::TypeSet &VTOperand, // Only keep types that have less elements than VTOperand. TypeSet InputSet(VTOperand); - for (unsigned i = 0; i != VTOperand.TypeVec.size(); ++i) { - assert(isVector(VTOperand.TypeVec[i]) && "EnforceVector didn't work"); - if (MVT(VTOperand.TypeVec[i]).getVectorNumElements() >= NumElems) { - VTOperand.TypeVec.erase(VTOperand.TypeVec.begin()+i--); - MadeChange = true; - } - } + auto I = std::remove_if(VTOperand.TypeVec.begin(), VTOperand.TypeVec.end(), + [NumElems](MVT VVT) { + return VVT.getVectorNumElements() >= NumElems; + }); + MadeChange |= I != VTOperand.TypeVec.end(); + VTOperand.TypeVec.erase(I, VTOperand.TypeVec.end()); + if (VTOperand.TypeVec.empty()) { // FIXME: Really want an SMLoc here! TP.error("Type inference contradiction found, forcing '" + InputSet.getName() + "' to have less vector elements than '" + @@ -574,13 +560,13 @@ bool EEVT::TypeSet::EnforceVectorSubVectorTypeIs(EEVT::TypeSet &VTOperand, // Only keep types that have more elements than 'this'. TypeSet InputSet(*this); - for (unsigned i = 0; i != TypeVec.size(); ++i) { - assert(isVector(TypeVec[i]) && "EnforceVector didn't work"); - if (MVT(TypeVec[i]).getVectorNumElements() <= NumElems) { - TypeVec.erase(TypeVec.begin()+i--); - MadeChange = true; - } - } + auto I = std::remove_if(TypeVec.begin(), TypeVec.end(), + [NumElems](MVT VVT) { + return VVT.getVectorNumElements() <= NumElems; + }); + MadeChange |= I != TypeVec.end(); + TypeVec.erase(I, TypeVec.end()); + if (TypeVec.empty()) { // FIXME: Really want an SMLoc here! TP.error("Type inference contradiction found, forcing '" + InputSet.getName() + "' to have more vector elements than '" + @@ -609,16 +595,16 @@ bool EEVT::TypeSet::EnforceVectorSameNumElts(EEVT::TypeSet &VTOperand, MVT IVT = getConcrete(); unsigned NumElems = IVT.getVectorNumElements(); - // Only keep types that have same elements as VTOperand. + // Only keep types that have same elements as 'this'. TypeSet InputSet(VTOperand); - for (unsigned i = 0; i != VTOperand.TypeVec.size(); ++i) { - assert(isVector(VTOperand.TypeVec[i]) && "EnforceVector didn't work"); - if (MVT(VTOperand.TypeVec[i]).getVectorNumElements() != NumElems) { - VTOperand.TypeVec.erase(VTOperand.TypeVec.begin()+i--); - MadeChange = true; - } - } + auto I = std::remove_if(VTOperand.TypeVec.begin(), VTOperand.TypeVec.end(), + [NumElems](MVT VVT) { + return VVT.getVectorNumElements() != NumElems; + }); + MadeChange |= I != VTOperand.TypeVec.end(); + VTOperand.TypeVec.erase(I, VTOperand.TypeVec.end()); + if (VTOperand.TypeVec.empty()) { // FIXME: Really want an SMLoc here! TP.error("Type inference contradiction found, forcing '" + InputSet.getName() + "' to have same number elements as '" + @@ -629,16 +615,16 @@ bool EEVT::TypeSet::EnforceVectorSameNumElts(EEVT::TypeSet &VTOperand, MVT IVT = VTOperand.getConcrete(); unsigned NumElems = IVT.getVectorNumElements(); - // Only keep types that have same elements as 'this'. + // Only keep types that have same elements as VTOperand. TypeSet InputSet(*this); - for (unsigned i = 0; i != TypeVec.size(); ++i) { - assert(isVector(TypeVec[i]) && "EnforceVector didn't work"); - if (MVT(TypeVec[i]).getVectorNumElements() != NumElems) { - TypeVec.erase(TypeVec.begin()+i--); - MadeChange = true; - } - } + auto I = std::remove_if(TypeVec.begin(), TypeVec.end(), + [NumElems](MVT VVT) { + return VVT.getVectorNumElements() != NumElems; + }); + MadeChange |= I != TypeVec.end(); + TypeVec.erase(I, TypeVec.end()); + if (TypeVec.empty()) { // FIXME: Really want an SMLoc here! TP.error("Type inference contradiction found, forcing '" + InputSet.getName() + "' to have same number elements than '" + @@ -650,6 +636,60 @@ bool EEVT::TypeSet::EnforceVectorSameNumElts(EEVT::TypeSet &VTOperand, return MadeChange; } +/// EnforceSameSize - 'this' is now constrained to be same size as VTOperand. +bool EEVT::TypeSet::EnforceSameSize(EEVT::TypeSet &VTOperand, + TreePattern &TP) { + if (TP.hasError()) + return false; + + bool MadeChange = false; + + // If we know one of the types, it forces the other type agree. + if (isConcrete()) { + MVT IVT = getConcrete(); + unsigned Size = IVT.getSizeInBits(); + + // Only keep types that have the same size as 'this'. + TypeSet InputSet(VTOperand); + + auto I = std::remove_if(VTOperand.TypeVec.begin(), VTOperand.TypeVec.end(), + [&](MVT VT) { + return VT.getSizeInBits() != Size; + }); + MadeChange |= I != VTOperand.TypeVec.end(); + VTOperand.TypeVec.erase(I, VTOperand.TypeVec.end()); + + if (VTOperand.TypeVec.empty()) { // FIXME: Really want an SMLoc here! + TP.error("Type inference contradiction found, forcing '" + + InputSet.getName() + "' to have same size as '" + + getName() + "'"); + return false; + } + } else if (VTOperand.isConcrete()) { + MVT IVT = VTOperand.getConcrete(); + unsigned Size = IVT.getSizeInBits(); + + // Only keep types that have the same size as VTOperand. + TypeSet InputSet(*this); + + auto I = std::remove_if(TypeVec.begin(), TypeVec.end(), + [&](MVT VT) { + return VT.getSizeInBits() != Size; + }); + MadeChange |= I != TypeVec.end(); + TypeVec.erase(I, TypeVec.end()); + + if (TypeVec.empty()) { // FIXME: Really want an SMLoc here! + TP.error("Type inference contradiction found, forcing '" + + InputSet.getName() + "' to have same size as '" + + VTOperand.getName() + "'"); + return false; + } + } + + return MadeChange; +} + //===----------------------------------------------------------------------===// // Helpers for working with extended types. @@ -818,7 +858,7 @@ getPatternComplexity(const CodeGenDAGPatterns &CGP) const { /// pattern's predicates concatenated with "&&" operators. /// std::string PatternToMatch::getPredicateCheck() const { - std::string PredicateCheck; + SmallVector PredicateRecs; for (Init *I : Predicates->getValues()) { if (DefInit *Pred = dyn_cast(I)) { Record *Def = Pred->getDef(); @@ -828,13 +868,20 @@ std::string PatternToMatch::getPredicateCheck() const { #endif llvm_unreachable("Unknown predicate type!"); } - if (!PredicateCheck.empty()) - PredicateCheck += " && "; - PredicateCheck += "(" + Def->getValueAsString("CondString") + ")"; + PredicateRecs.push_back(Def); } } + // Sort so that different orders get canonicalized to the same string. + std::sort(PredicateRecs.begin(), PredicateRecs.end(), LessRecord()); - return PredicateCheck; + SmallString<128> PredicateCheck; + for (Record *Pred : PredicateRecs) { + if (!PredicateCheck.empty()) + PredicateCheck += " && "; + PredicateCheck += "(" + Pred->getValueAsString("CondString") + ")"; + } + + return PredicateCheck.str(); } //===----------------------------------------------------------------------===// @@ -889,6 +936,10 @@ SDTypeConstraint::SDTypeConstraint(Record *R) { ConstraintType = SDTCisSameNumEltsAs; x.SDTCisSameNumEltsAs_Info.OtherOperandNum = R->getValueAsInt("OtherOperandNum"); + } else if (R->isSubClassOf("SDTCisSameSizeAs")) { + ConstraintType = SDTCisSameSizeAs; + x.SDTCisSameSizeAs_Info.OtherOperandNum = + R->getValueAsInt("OtherOperandNum"); } else { PrintFatalError("Unrecognized SDTypeConstraint '" + R->getName() + "'!\n"); } @@ -1018,6 +1069,14 @@ bool SDTypeConstraint::ApplyTypeConstraint(TreePatternNode *N, return OtherNode->getExtType(OResNo). EnforceVectorSameNumElts(NodeToApply->getExtType(ResNo), TP); } + case SDTCisSameSizeAs: { + unsigned OResNo = 0; + TreePatternNode *OtherNode = + getOperandNum(x.SDTCisSameSizeAs_Info.OtherOperandNum, + N, NodeInfo, OResNo); + return OtherNode->getExtType(OResNo). + EnforceSameSize(NodeToApply->getExtType(ResNo), TP); + } } llvm_unreachable("Invalid ConstraintType!"); }