summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/Target/TargetSelectionDAG.td5
-rw-r--r--llvm/utils/TableGen/CodeGenDAGPatterns.cpp66
-rw-r--r--llvm/utils/TableGen/CodeGenDAGPatterns.h8
3 files changed, 78 insertions, 1 deletions
diff --git a/llvm/include/llvm/Target/TargetSelectionDAG.td b/llvm/include/llvm/Target/TargetSelectionDAG.td
index fd0e0491330..905b1cf78c4 100644
--- a/llvm/include/llvm/Target/TargetSelectionDAG.td
+++ b/llvm/include/llvm/Target/TargetSelectionDAG.td
@@ -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.
//
diff --git a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp
index 025e4197ad2..38a8653535e 100644
--- a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -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!");
}
diff --git a/llvm/utils/TableGen/CodeGenDAGPatterns.h b/llvm/utils/TableGen/CodeGenDAGPatterns.h
index f330e558f56..76c9cefea50 100644
--- a/llvm/utils/TableGen/CodeGenDAGPatterns.h
+++ b/llvm/utils/TableGen/CodeGenDAGPatterns.h
@@ -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
OpenPOWER on IntegriCloud