From 8ad519fd3c5998d977d4f63bc9fc9ec5a95580b6 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Thu, 5 Mar 2015 07:11:34 +0000 Subject: [PATCH] [TableGen] Add support constraining a vector type in a pattern to have a specific element type and for constraining a vector type to have the same number of elements as another vector type. This is useful for AVX512 mask operations so we relate the mask type to the type of the other arguments. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@231356 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Target/TargetSelectionDAG.td | 12 +++ utils/TableGen/CodeGenDAGPatterns.cpp | 111 ++++++++++++++++++++++ utils/TableGen/CodeGenDAGPatterns.h | 16 +++- 3 files changed, 138 insertions(+), 1 deletion(-) diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td index 2ecd900d34b..5388962fb68 100644 --- a/include/llvm/Target/TargetSelectionDAG.td +++ b/include/llvm/Target/TargetSelectionDAG.td @@ -68,6 +68,18 @@ class SDTCisSubVecOfVec int OtherOpNum = OtherOp; } +// SDTCVecEltisVT - The specified operand is vector type with element type +// of VT. +class SDTCVecEltisVT : SDTypeConstraint { + ValueType VT = vt; +} + +// SDTCisSameNumEltsAs - The two specified operands have identical number +// of elements. +class SDTCisSameNumEltsAs : SDTypeConstraint { + int OtherOperandNum = OtherOp; +} + //===----------------------------------------------------------------------===// // Selection DAG Type Profile definitions. // diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index 0853d05d2b5..2ebcd80147c 100644 --- a/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/utils/TableGen/CodeGenDAGPatterns.cpp @@ -482,6 +482,34 @@ bool EEVT::TypeSet::EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP) { return MadeChange; } +/// EnforceVectorEltTypeIs - 'this' is now constrainted to be a vector type +/// whose element is specified by VTOperand. +bool EEVT::TypeSet::EnforceVectorEltTypeIs(MVT::SimpleValueType VT, + TreePattern &TP) { + bool MadeChange = false; + + MadeChange |= EnforceVector(TP); + + 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; + } + } + + 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; +} + /// EnforceVectorEltTypeIs - 'this' is now constrainted to be a vector type /// whose element is specified by VTOperand. bool EEVT::TypeSet::EnforceVectorEltTypeIs(EEVT::TypeSet &VTOperand, @@ -609,6 +637,64 @@ bool EEVT::TypeSet::EnforceVectorSubVectorTypeIs(EEVT::TypeSet &VTOperand, return MadeChange; } +/// EnforceVectorSameNumElts - 'this' is now constrainted to +/// be a vector with same num elements as VTOperand. +bool EEVT::TypeSet::EnforceVectorSameNumElts(EEVT::TypeSet &VTOperand, + TreePattern &TP) { + if (TP.hasError()) + return false; + + // "This" must be a vector and "VTOperand" must be a vector. + bool MadeChange = false; + MadeChange |= EnforceVector(TP); + MadeChange |= VTOperand.EnforceVector(TP); + + // If we know one of the vector types, it forces the other type to agree. + if (isConcrete()) { + MVT IVT = getConcrete(); + unsigned NumElems = IVT.getVectorNumElements(); + + // Only keep types that have same elements as 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; + } + } + 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 '" + + getName() + "'"); + return false; + } + } else if (VTOperand.isConcrete()) { + MVT IVT = VTOperand.getConcrete(); + unsigned NumElems = IVT.getVectorNumElements(); + + // Only keep types that have same elements as '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; + } + } + if (TypeVec.empty()) { // FIXME: Really want an SMLoc here! + TP.error("Type inference contradiction found, forcing '" + + InputSet.getName() + "' to have same number elements than '" + + VTOperand.getName() + "'"); + return false; + } + } + + return MadeChange; +} + //===----------------------------------------------------------------------===// // Helpers for working with extended types. @@ -839,6 +925,19 @@ SDTypeConstraint::SDTypeConstraint(Record *R) { ConstraintType = SDTCisSubVecOfVec; x.SDTCisSubVecOfVec_Info.OtherOperandNum = R->getValueAsInt("OtherOpNum"); + } else if (R->isSubClassOf("SDTCVecEltisVT")) { + ConstraintType = SDTCVecEltisVT; + x.SDTCVecEltisVT_Info.VT = getValueType(R->getValueAsDef("VT")); + if (MVT(x.SDTCVecEltisVT_Info.VT).isVector()) + PrintFatalError(R->getLoc(), "Cannot use vector type as SDTCVecEltisVT"); + if (!MVT(x.SDTCVecEltisVT_Info.VT).isInteger() && + !MVT(x.SDTCVecEltisVT_Info.VT).isFloatingPoint()) + PrintFatalError(R->getLoc(), "Must use integer or floating point type " + "as SDTCVecEltisVT"); + } else if (R->isSubClassOf("SDTCisSameNumEltsAs")) { + ConstraintType = SDTCisSameNumEltsAs; + x.SDTCisSameNumEltsAs_Info.OtherOperandNum = + R->getValueAsInt("OtherOperandNum"); } else { errs() << "Unrecognized SDTypeConstraint '" << R->getName() << "'!\n"; exit(1); @@ -956,6 +1055,18 @@ bool SDTypeConstraint::ApplyTypeConstraint(TreePatternNode *N, return BigVecOperand->getExtType(VResNo). EnforceVectorSubVectorTypeIs(NodeToApply->getExtType(ResNo), TP); } + case SDTCVecEltisVT: { + return NodeToApply->getExtType(ResNo). + EnforceVectorEltTypeIs(x.SDTCVecEltisVT_Info.VT, TP); + } + case SDTCisSameNumEltsAs: { + unsigned OResNo = 0; + TreePatternNode *OtherNode = + getOperandNum(x.SDTCisSameNumEltsAs_Info.OtherOperandNum, + N, NodeInfo, OResNo); + return OtherNode->getExtType(OResNo). + EnforceVectorSameNumElts(NodeToApply->getExtType(ResNo), TP); + } } llvm_unreachable("Invalid ConstraintType!"); } diff --git a/utils/TableGen/CodeGenDAGPatterns.h b/utils/TableGen/CodeGenDAGPatterns.h index c0812cf0553..9ce3cdfd7bc 100644 --- a/utils/TableGen/CodeGenDAGPatterns.h +++ b/utils/TableGen/CodeGenDAGPatterns.h @@ -136,10 +136,18 @@ namespace EEVT { /// whose element is VT. bool EnforceVectorEltTypeIs(EEVT::TypeSet &VT, TreePattern &TP); + /// EnforceVectorEltTypeIs - 'this' is now constrainted to be a vector type + /// whose element is VT. + bool EnforceVectorEltTypeIs(MVT::SimpleValueType VT, TreePattern &TP); + /// EnforceVectorSubVectorTypeIs - 'this' is now constrainted to /// be a vector type VT. bool EnforceVectorSubVectorTypeIs(EEVT::TypeSet &VT, TreePattern &TP); + /// EnforceVectorSameNumElts - 'this' is now constrainted to + /// be a vector with same num elements as VT. + bool EnforceVectorSameNumElts(EEVT::TypeSet &VT, TreePattern &TP); + bool operator!=(const TypeSet &RHS) const { return TypeVec != RHS.TypeVec; } bool operator==(const TypeSet &RHS) const { return TypeVec == RHS.TypeVec; } @@ -165,7 +173,7 @@ struct SDTypeConstraint { enum { SDTCisVT, SDTCisPtrTy, SDTCisInt, SDTCisFP, SDTCisVec, SDTCisSameAs, SDTCisVTSmallerThanOp, SDTCisOpSmallerThanOp, SDTCisEltOfVec, - SDTCisSubVecOfVec + SDTCisSubVecOfVec, SDTCVecEltisVT, SDTCisSameNumEltsAs } ConstraintType; union { // The discriminated union. @@ -187,6 +195,12 @@ struct SDTypeConstraint { struct { unsigned OtherOperandNum; } SDTCisSubVecOfVec_Info; + struct { + MVT::SimpleValueType VT; + } SDTCVecEltisVT_Info; + struct { + unsigned OtherOperandNum; + } SDTCisSameNumEltsAs_Info; } x; /// ApplyTypeConstraint - Given a node in a pattern, apply this type