summaryrefslogtreecommitdiffstats
path: root/llvm/utils/TableGen/CodeGenDAGPatterns.cpp
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@gmail.com>2015-03-05 07:11:34 +0000
committerCraig Topper <craig.topper@gmail.com>2015-03-05 07:11:34 +0000
commit0be34580061d8e406507a3832e39f90405ebc209 (patch)
tree1a621604691c54dd8b23e21354cf1c5691239292 /llvm/utils/TableGen/CodeGenDAGPatterns.cpp
parent1fa434992ba447ca9ce0e77ceaca7cb889c75ccf (diff)
downloadbcm5719-llvm-0be34580061d8e406507a3832e39f90405ebc209.tar.gz
bcm5719-llvm-0be34580061d8e406507a3832e39f90405ebc209.zip
[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.
llvm-svn: 231356
Diffstat (limited to 'llvm/utils/TableGen/CodeGenDAGPatterns.cpp')
-rw-r--r--llvm/utils/TableGen/CodeGenDAGPatterns.cpp111
1 files changed, 111 insertions, 0 deletions
diff --git a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp
index 0853d05d2b5..2ebcd80147c 100644
--- a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -484,6 +484,34 @@ bool EEVT::TypeSet::EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP) {
/// 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,
TreePattern &TP) {
if (TP.hasError())
@@ -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!");
}
OpenPOWER on IntegriCloud