diff options
author | David Greene <greened@obbligato.org> | 2011-01-24 20:53:18 +0000 |
---|---|---|
committer | David Greene <greened@obbligato.org> | 2011-01-24 20:53:18 +0000 |
commit | 6032269837c08a94b70b0e36f8e473c293ff5fd4 (patch) | |
tree | 19bf5453b9f4aef6ced71752121c6133ab6091b4 /utils | |
parent | a3ee3ef71b025de982cdda123bbfed44278b011a (diff) |
[AVX] Add type checking support for vector/subvector type constraints.
This will be used to check patterns referencing a forthcoming
INSERT_SUBVECTOR SDNode. INSERT_SUBVECTOR in turn is very useful for
matching to VINSERTF128 instructions and complements the already
existing EXTRACT_SUBVECTOR SDNode.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@124145 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r-- | utils/TableGen/CodeGenDAGPatterns.cpp | 45 | ||||
-rw-r--r-- | utils/TableGen/CodeGenDAGPatterns.h | 10 |
2 files changed, 54 insertions, 1 deletions
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index 3f4367cfa0..5e1d3ae9dc 100644 --- a/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/utils/TableGen/CodeGenDAGPatterns.cpp @@ -434,6 +434,36 @@ bool EEVT::TypeSet::EnforceVectorEltTypeIs(EEVT::TypeSet &VTOperand, return MadeChange; } +/// EnforceVectorSubVectorTypeIs - 'this' is now constrainted to be a +/// vector type specified by VTOperand. +bool EEVT::TypeSet::EnforceVectorSubVectorTypeIs(EEVT::TypeSet &VTOperand, + TreePattern &TP) { + // "This" must be a vector and "VTOperand" must be a vector. + bool MadeChange = false; + MadeChange |= EnforceVector(TP); + MadeChange |= VTOperand.EnforceVector(TP); + + // "This" must be larger than "VTOperand." + MadeChange |= VTOperand.EnforceSmallerThan(*this, TP); + + // If we know the vector type, it forces the scalar types to agree. + if (isConcrete()) { + EVT IVT = getConcrete(); + IVT = IVT.getVectorElementType(); + + EEVT::TypeSet EltTypeSet(IVT.getSimpleVT().SimpleTy, TP); + MadeChange |= VTOperand.EnforceVectorEltTypeIs(EltTypeSet, TP); + } else if (VTOperand.isConcrete()) { + EVT IVT = VTOperand.getConcrete(); + IVT = IVT.getVectorElementType(); + + EEVT::TypeSet EltTypeSet(IVT.getSimpleVT().SimpleTy, TP); + MadeChange |= EnforceVectorEltTypeIs(EltTypeSet, TP); + } + + return MadeChange; +} + //===----------------------------------------------------------------------===// // Helpers for working with extended types. @@ -605,6 +635,10 @@ SDTypeConstraint::SDTypeConstraint(Record *R) { } else if (R->isSubClassOf("SDTCisEltOfVec")) { ConstraintType = SDTCisEltOfVec; x.SDTCisEltOfVec_Info.OtherOperandNum = R->getValueAsInt("OtherOpNum"); + } else if (R->isSubClassOf("SDTCisSubVecOfVec")) { + ConstraintType = SDTCisSubVecOfVec; + x.SDTCisSubVecOfVec_Info.OtherOperandNum = + R->getValueAsInt("OtherOpNum"); } else { errs() << "Unrecognized SDTypeConstraint '" << R->getName() << "'!\n"; exit(1); @@ -708,6 +742,17 @@ bool SDTypeConstraint::ApplyTypeConstraint(TreePatternNode *N, return VecOperand->getExtType(VResNo). EnforceVectorEltTypeIs(NodeToApply->getExtType(ResNo), TP); } + case SDTCisSubVecOfVec: { + unsigned VResNo = 0; + TreePatternNode *BigVecOperand = + getOperandNum(x.SDTCisSubVecOfVec_Info.OtherOperandNum, N, NodeInfo, + VResNo); + + // Filter vector types out of BigVecOperand that don't have the + // right subvector type. + return BigVecOperand->getExtType(VResNo). + EnforceVectorSubVectorTypeIs(NodeToApply->getExtType(ResNo), TP); + } } return false; } diff --git a/utils/TableGen/CodeGenDAGPatterns.h b/utils/TableGen/CodeGenDAGPatterns.h index 7a3f705a5e..946dceed66 100644 --- a/utils/TableGen/CodeGenDAGPatterns.h +++ b/utils/TableGen/CodeGenDAGPatterns.h @@ -131,6 +131,10 @@ namespace EEVT { /// whose element is VT. bool EnforceVectorEltTypeIs(EEVT::TypeSet &VT, TreePattern &TP); + /// EnforceVectorSubVectorTypeIs - 'this' is now constrainted to + /// be a vector type VT. + bool EnforceVectorSubVectorTypeIs(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; } @@ -155,7 +159,8 @@ struct SDTypeConstraint { unsigned OperandNo; // The operand # this constraint applies to. enum { SDTCisVT, SDTCisPtrTy, SDTCisInt, SDTCisFP, SDTCisVec, SDTCisSameAs, - SDTCisVTSmallerThanOp, SDTCisOpSmallerThanOp, SDTCisEltOfVec + SDTCisVTSmallerThanOp, SDTCisOpSmallerThanOp, SDTCisEltOfVec, + SDTCisSubVecOfVec } ConstraintType; union { // The discriminated union. @@ -174,6 +179,9 @@ struct SDTypeConstraint { struct { unsigned OtherOperandNum; } SDTCisEltOfVec_Info; + struct { + unsigned OtherOperandNum; + } SDTCisSubVecOfVec_Info; } x; /// ApplyTypeConstraint - Given a node in a pattern, apply this type |