diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/include/llvm/Target/TargetSelectionDAG.td | 12 | ||||
| -rw-r--r-- | llvm/utils/TableGen/CodeGenDAGPatterns.cpp | 111 | ||||
| -rw-r--r-- | llvm/utils/TableGen/CodeGenDAGPatterns.h | 16 | 
3 files changed, 138 insertions, 1 deletions
diff --git a/llvm/include/llvm/Target/TargetSelectionDAG.td b/llvm/include/llvm/Target/TargetSelectionDAG.td index 2ecd900d34b..5388962fb68 100644 --- a/llvm/include/llvm/Target/TargetSelectionDAG.td +++ b/llvm/include/llvm/Target/TargetSelectionDAG.td @@ -68,6 +68,18 @@ class SDTCisSubVecOfVec<int ThisOp, int OtherOp>    int OtherOpNum = OtherOp;  } +// SDTCVecEltisVT - The specified operand is vector type with element type +// of VT. +class SDTCVecEltisVT<int OpNum, ValueType vt> : SDTypeConstraint<OpNum> { +  ValueType VT = vt; +} + +// SDTCisSameNumEltsAs - The two specified operands have identical number +// of elements. +class SDTCisSameNumEltsAs<int OpNum, int OtherOp> : SDTypeConstraint<OpNum> { +  int OtherOperandNum = OtherOp; +} +  //===----------------------------------------------------------------------===//  // Selection DAG Type Profile definitions.  // 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!");  } diff --git a/llvm/utils/TableGen/CodeGenDAGPatterns.h b/llvm/utils/TableGen/CodeGenDAGPatterns.h index c0812cf0553..9ce3cdfd7bc 100644 --- a/llvm/utils/TableGen/CodeGenDAGPatterns.h +++ b/llvm/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  | 

