aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/llvm/CodeGen/DAGISelHeader.h20
-rw-r--r--utils/TableGen/DAGISelMatcher.cpp7
-rw-r--r--utils/TableGen/DAGISelMatcher.h21
-rw-r--r--utils/TableGen/DAGISelMatcherEmitter.cpp8
-rw-r--r--utils/TableGen/DAGISelMatcherOpt.cpp15
5 files changed, 66 insertions, 5 deletions
diff --git a/include/llvm/CodeGen/DAGISelHeader.h b/include/llvm/CodeGen/DAGISelHeader.h
index 88c1a66..4babed8 100644
--- a/include/llvm/CodeGen/DAGISelHeader.h
+++ b/include/llvm/CodeGen/DAGISelHeader.h
@@ -233,6 +233,9 @@ enum BuiltinOpcodes {
OPC_CheckOpcode,
OPC_CheckMultiOpcode,
OPC_CheckType,
+ OPC_CheckChild0Type, OPC_CheckChild1Type, OPC_CheckChild2Type,
+ OPC_CheckChild3Type, OPC_CheckChild4Type, OPC_CheckChild5Type,
+ OPC_CheckChild6Type, OPC_CheckChild7Type,
OPC_CheckInteger1, OPC_CheckInteger2, OPC_CheckInteger4, OPC_CheckInteger8,
OPC_CheckCondCode,
OPC_CheckValueType,
@@ -481,6 +484,23 @@ SDNode *SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
}
continue;
}
+ case OPC_CheckChild0Type: case OPC_CheckChild1Type:
+ case OPC_CheckChild2Type: case OPC_CheckChild3Type:
+ case OPC_CheckChild4Type: case OPC_CheckChild5Type:
+ case OPC_CheckChild6Type: case OPC_CheckChild7Type: {
+ unsigned ChildNo = Opcode-OPC_CheckChild0Type;
+ if (ChildNo >= N.getNumOperands())
+ break; // Match fails if out of range child #.
+
+ MVT::SimpleValueType VT =
+ (MVT::SimpleValueType)MatcherTable[MatcherIndex++];
+ if (N.getOperand(ChildNo).getValueType() != VT) {
+ // Handle the case when VT is iPTR.
+ if (VT != MVT::iPTR || N.getValueType() != TLI.getPointerTy())
+ break;
+ }
+ continue;
+ }
case OPC_CheckCondCode:
if (cast<CondCodeSDNode>(N)->get() !=
(ISD::CondCode)MatcherTable[MatcherIndex++]) break;
diff --git a/utils/TableGen/DAGISelMatcher.cpp b/utils/TableGen/DAGISelMatcher.cpp
index 9bb8fd5..0b0a1be 100644
--- a/utils/TableGen/DAGISelMatcher.cpp
+++ b/utils/TableGen/DAGISelMatcher.cpp
@@ -91,6 +91,13 @@ void CheckTypeMatcherNode::print(raw_ostream &OS, unsigned indent) const {
printNext(OS, indent);
}
+void CheckChildTypeMatcherNode::print(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "CheckChildType " << ChildNo << " "
+ << getEnumName(Type) << '\n';
+ printNext(OS, indent);
+}
+
+
void CheckIntegerMatcherNode::print(raw_ostream &OS, unsigned indent) const {
OS.indent(indent) << "CheckInteger " << Value << '\n';
printNext(OS, indent);
diff --git a/utils/TableGen/DAGISelMatcher.h b/utils/TableGen/DAGISelMatcher.h
index ab84168..3505bb8 100644
--- a/utils/TableGen/DAGISelMatcher.h
+++ b/utils/TableGen/DAGISelMatcher.h
@@ -54,6 +54,7 @@ public:
CheckOpcode, // Fail if not opcode.
CheckMultiOpcode, // Fail if not in opcode list.
CheckType, // Fail if not correct type.
+ CheckChildType, // Fail if child has wrong type.
CheckInteger, // Fail if wrong val.
CheckCondCode, // Fail if not condcode.
CheckValueType,
@@ -328,6 +329,26 @@ public:
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
};
+
+/// CheckChildTypeMatcherNode - This checks to see if a child node has the
+/// specified type, if not it fails to match.
+class CheckChildTypeMatcherNode : public MatcherNode {
+ unsigned ChildNo;
+ MVT::SimpleValueType Type;
+public:
+ CheckChildTypeMatcherNode(unsigned childno, MVT::SimpleValueType type)
+ : MatcherNode(CheckChildType), ChildNo(childno), Type(type) {}
+
+ unsigned getChildNo() const { return ChildNo; }
+ MVT::SimpleValueType getType() const { return Type; }
+
+ static inline bool classof(const MatcherNode *N) {
+ return N->getKind() == CheckChildType;
+ }
+
+ virtual void print(raw_ostream &OS, unsigned indent = 0) const;
+};
+
/// CheckIntegerMatcherNode - This checks to see if the current node is a
/// ConstantSDNode with the specified integer value, if not it fails to match.
diff --git a/utils/TableGen/DAGISelMatcherEmitter.cpp b/utils/TableGen/DAGISelMatcherEmitter.cpp
index 0efab15..4c5686f 100644
--- a/utils/TableGen/DAGISelMatcherEmitter.cpp
+++ b/utils/TableGen/DAGISelMatcherEmitter.cpp
@@ -222,7 +222,12 @@ EmitMatcher(const MatcherNode *N, unsigned Indent, formatted_raw_ostream &OS) {
OS << "OPC_CheckType, "
<< getEnumName(cast<CheckTypeMatcherNode>(N)->getType()) << ",\n";
return 2;
-
+ case MatcherNode::CheckChildType:
+ OS << "OPC_CheckChild"
+ << cast<CheckChildTypeMatcherNode>(N)->getChildNo() << "Type, "
+ << getEnumName(cast<CheckChildTypeMatcherNode>(N)->getType()) << ",\n";
+ return 2;
+
case MatcherNode::CheckInteger: {
int64_t Val = cast<CheckIntegerMatcherNode>(N)->getValue();
OS << "OPC_CheckInteger" << ClassifyInt(Val) << ", ";
@@ -523,6 +528,7 @@ void MatcherTableEmitter::EmitHistogram(formatted_raw_ostream &OS) {
case MatcherNode::CheckOpcode: OS << "OPC_CheckOpcode"; break;
case MatcherNode::CheckMultiOpcode: OS << "OPC_CheckMultiOpcode"; break;
case MatcherNode::CheckType: OS << "OPC_CheckType"; break;
+ case MatcherNode::CheckChildType: OS << "OPC_CheckChildType"; break;
case MatcherNode::CheckInteger: OS << "OPC_CheckInteger"; break;
case MatcherNode::CheckCondCode: OS << "OPC_CheckCondCode"; break;
case MatcherNode::CheckValueType: OS << "OPC_CheckValueType"; break;
diff --git a/utils/TableGen/DAGISelMatcherOpt.cpp b/utils/TableGen/DAGISelMatcherOpt.cpp
index 408bd63..796b815 100644
--- a/utils/TableGen/DAGISelMatcherOpt.cpp
+++ b/utils/TableGen/DAGISelMatcherOpt.cpp
@@ -26,12 +26,19 @@ static void ContractNodes(OwningPtr<MatcherNode> &Matcher) {
// If we found a movechild node with a node that comes in a 'foochild' form,
// transform it.
if (MoveChildMatcherNode *MC = dyn_cast<MoveChildMatcherNode>(N)) {
- if (RecordMatcherNode *RM = dyn_cast<RecordMatcherNode>(MC->getNext())) {
- MatcherNode *New
- = new RecordChildMatcherNode(MC->getChildNo(), RM->getWhatFor());
+ MatcherNode *New = 0;
+ if (RecordMatcherNode *RM = dyn_cast<RecordMatcherNode>(MC->getNext()))
+ New = new RecordChildMatcherNode(MC->getChildNo(), RM->getWhatFor());
+
+ if (CheckTypeMatcherNode *CT= dyn_cast<CheckTypeMatcherNode>(MC->getNext()))
+ New = new CheckChildTypeMatcherNode(MC->getChildNo(), CT->getType());
+
+ if (New) {
+ // Insert the new node.
New->setNext(Matcher.take());
Matcher.reset(New);
- MC->setNext(RM->takeNext());
+ // Remove the old one.
+ MC->setNext(MC->getNext()->takeNext());
return ContractNodes(Matcher);
}
}