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

[SelectionDAG] Add a SDTCisSameSizeAs type constraint that can be used to ensure vector widths match even if the element size and count don't.

llvm-svn: 254138
This commit is contained in:
Craig Topper 2015-11-26 07:02:18 +00:00
parent 4b764921f1
commit e404cbe233
3 changed files with 78 additions and 1 deletions

View File

@ -80,6 +80,11 @@ class SDTCisSameNumEltsAs<int OpNum, int OtherOp> : SDTypeConstraint<OpNum> {
int OtherOperandNum = OtherOp;
}
// SDTCisSameSizeAs - The two specified operands have identical size.
class SDTCisSameSizeAs<int OpNum, int OtherOp> : SDTypeConstraint<OpNum> {
int OtherOperandNum = OtherOp;
}
//===----------------------------------------------------------------------===//
// Selection DAG Type Profile definitions.
//

View File

@ -635,6 +635,60 @@ bool EEVT::TypeSet::EnforceVectorSameNumElts(EEVT::TypeSet &VTOperand,
return MadeChange;
}
/// EnforceSameSize - 'this' is now constrained to be same size as VTOperand.
bool EEVT::TypeSet::EnforceSameSize(EEVT::TypeSet &VTOperand,
TreePattern &TP) {
if (TP.hasError())
return false;
bool MadeChange = false;
// If we know one of the types, it forces the other type agree.
if (isConcrete()) {
MVT IVT = getConcrete();
unsigned Size = IVT.getSizeInBits();
// Only keep types that have the same size as 'this'.
TypeSet InputSet(VTOperand);
auto I = std::remove_if(VTOperand.TypeVec.begin(), VTOperand.TypeVec.end(),
[&](MVT VT) {
return VT.getSizeInBits() != Size;
});
MadeChange |= I != VTOperand.TypeVec.end();
VTOperand.TypeVec.erase(I, VTOperand.TypeVec.end());
if (VTOperand.TypeVec.empty()) { // FIXME: Really want an SMLoc here!
TP.error("Type inference contradiction found, forcing '" +
InputSet.getName() + "' to have same size as '" +
getName() + "'");
return false;
}
} else if (VTOperand.isConcrete()) {
MVT IVT = VTOperand.getConcrete();
unsigned Size = IVT.getSizeInBits();
// Only keep types that have the same size as VTOperand.
TypeSet InputSet(*this);
auto I = std::remove_if(TypeVec.begin(), TypeVec.end(),
[&](MVT VT) {
return VT.getSizeInBits() != Size;
});
MadeChange |= I != TypeVec.end();
TypeVec.erase(I, TypeVec.end());
if (TypeVec.empty()) { // FIXME: Really want an SMLoc here!
TP.error("Type inference contradiction found, forcing '" +
InputSet.getName() + "' to have same size as '" +
VTOperand.getName() + "'");
return false;
}
}
return MadeChange;
}
//===----------------------------------------------------------------------===//
// Helpers for working with extended types.
@ -874,6 +928,10 @@ SDTypeConstraint::SDTypeConstraint(Record *R) {
ConstraintType = SDTCisSameNumEltsAs;
x.SDTCisSameNumEltsAs_Info.OtherOperandNum =
R->getValueAsInt("OtherOperandNum");
} else if (R->isSubClassOf("SDTCisSameSizeAs")) {
ConstraintType = SDTCisSameSizeAs;
x.SDTCisSameSizeAs_Info.OtherOperandNum =
R->getValueAsInt("OtherOperandNum");
} else {
PrintFatalError("Unrecognized SDTypeConstraint '" + R->getName() + "'!\n");
}
@ -1003,6 +1061,14 @@ bool SDTypeConstraint::ApplyTypeConstraint(TreePatternNode *N,
return OtherNode->getExtType(OResNo).
EnforceVectorSameNumElts(NodeToApply->getExtType(ResNo), TP);
}
case SDTCisSameSizeAs: {
unsigned OResNo = 0;
TreePatternNode *OtherNode =
getOperandNum(x.SDTCisSameSizeAs_Info.OtherOperandNum,
N, NodeInfo, OResNo);
return OtherNode->getExtType(OResNo).
EnforceSameSize(NodeToApply->getExtType(ResNo), TP);
}
}
llvm_unreachable("Invalid ConstraintType!");
}

View File

@ -148,6 +148,9 @@ namespace EEVT {
/// be a vector with same num elements as VT.
bool EnforceVectorSameNumElts(EEVT::TypeSet &VT, TreePattern &TP);
/// EnforceSameSize - 'this' is now constrained to be the same size as VT.
bool EnforceSameSize(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; }
@ -173,7 +176,7 @@ struct SDTypeConstraint {
enum {
SDTCisVT, SDTCisPtrTy, SDTCisInt, SDTCisFP, SDTCisVec, SDTCisSameAs,
SDTCisVTSmallerThanOp, SDTCisOpSmallerThanOp, SDTCisEltOfVec,
SDTCisSubVecOfVec, SDTCVecEltisVT, SDTCisSameNumEltsAs
SDTCisSubVecOfVec, SDTCVecEltisVT, SDTCisSameNumEltsAs, SDTCisSameSizeAs
} ConstraintType;
union { // The discriminated union.
@ -201,6 +204,9 @@ struct SDTypeConstraint {
struct {
unsigned OtherOperandNum;
} SDTCisSameNumEltsAs_Info;
struct {
unsigned OtherOperandNum;
} SDTCisSameSizeAs_Info;
} x;
/// ApplyTypeConstraint - Given a node in a pattern, apply this type