1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 11:02:59 +02:00

[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.

llvm-svn: 124145
This commit is contained in:
David Greene 2011-01-24 20:53:18 +00:00
parent 431a9b9c2f
commit 1c4fa5e643
2 changed files with 54 additions and 1 deletions

View File

@ -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;
}

View File

@ -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