From: Chris Lattner Date: Mon, 22 Feb 2010 22:30:37 +0000 (+0000) Subject: add a new CheckMultiOpcode opcode for checking that a node X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=12a667c1e8fa57a13ae751164b6dd4412a62dc5d;p=oota-llvm.git add a new CheckMultiOpcode opcode for checking that a node has one of the list of acceptable opcodes for a complex pattern. This fixes 4 regtest failures. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96814 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/CodeGen/DAGISelHeader.h b/include/llvm/CodeGen/DAGISelHeader.h index 63d15cda6c8..d60940ff1f8 100644 --- a/include/llvm/CodeGen/DAGISelHeader.h +++ b/include/llvm/CodeGen/DAGISelHeader.h @@ -211,6 +211,7 @@ enum BuiltinOpcodes { OPC_CheckPatternPredicate, OPC_CheckPredicate, OPC_CheckOpcode, + OPC_CheckMultiOpcode, OPC_CheckType, OPC_CheckInteger1, OPC_CheckInteger2, OPC_CheckInteger4, OPC_CheckInteger8, OPC_CheckCondCode, @@ -410,6 +411,16 @@ SDNode *SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable, case OPC_CheckOpcode: if (N->getOpcode() != MatcherTable[MatcherIndex++]) break; continue; + + case OPC_CheckMultiOpcode: { + unsigned NumOps = MatcherTable[MatcherIndex++]; + bool OpcodeEquals = false; + for (unsigned i = 0; i != NumOps; ++i) + OpcodeEquals |= N->getOpcode() == MatcherTable[MatcherIndex++]; + if (!OpcodeEquals) break; + continue; + } + case OPC_CheckType: { MVT::SimpleValueType VT = (MVT::SimpleValueType)MatcherTable[MatcherIndex++]; diff --git a/utils/TableGen/DAGISelMatcher.cpp b/utils/TableGen/DAGISelMatcher.cpp index b3c846c9cef..102b0e99696 100644 --- a/utils/TableGen/DAGISelMatcher.cpp +++ b/utils/TableGen/DAGISelMatcher.cpp @@ -76,6 +76,11 @@ void CheckOpcodeMatcherNode::print(raw_ostream &OS, unsigned indent) const { printNext(OS, indent); } +void CheckMultiOpcodeMatcherNode::print(raw_ostream &OS, unsigned indent) const { + OS.indent(indent) << "CheckMultiOpcode \n"; + printNext(OS, indent); +} + void CheckTypeMatcherNode::print(raw_ostream &OS, unsigned indent) const { OS.indent(indent) << "CheckType " << getEnumName(Type) << '\n'; printNext(OS, indent); diff --git a/utils/TableGen/DAGISelMatcher.h b/utils/TableGen/DAGISelMatcher.h index c162a0cbaa5..2379a218fa9 100644 --- a/utils/TableGen/DAGISelMatcher.h +++ b/utils/TableGen/DAGISelMatcher.h @@ -51,6 +51,7 @@ public: CheckPatternPredicate, CheckPredicate, // Fail if node predicate fails. CheckOpcode, // Fail if not opcode. + CheckMultiOpcode, // Fail if not in opcode list. CheckType, // Fail if not correct type. CheckInteger, // Fail if wrong val. CheckCondCode, // Fail if not condcode. @@ -262,6 +263,26 @@ public: virtual void print(raw_ostream &OS, unsigned indent = 0) const; }; +/// CheckMultiOpcodeMatcherNode - This checks to see if the current node has one +/// of the specified opcode, if not it fails to match. +class CheckMultiOpcodeMatcherNode : public MatcherNode { + SmallVector OpcodeNames; +public: + CheckMultiOpcodeMatcherNode(const StringRef *opcodes, unsigned numops) + : MatcherNode(CheckMultiOpcode), OpcodeNames(opcodes, opcodes+numops) {} + + unsigned getNumOpcodeNames() const { return OpcodeNames.size(); } + StringRef getOpcodeName(unsigned i) const { return OpcodeNames[i]; } + + static inline bool classof(const MatcherNode *N) { + return N->getKind() == CheckMultiOpcode; + } + + virtual void print(raw_ostream &OS, unsigned indent = 0) const; +}; + + + /// CheckTypeMatcherNode - This checks to see if the current node has the /// specified type, if not it fails to match. class CheckTypeMatcherNode : public MatcherNode { diff --git a/utils/TableGen/DAGISelMatcherEmitter.cpp b/utils/TableGen/DAGISelMatcherEmitter.cpp index 2c835cc462f..82d852e379f 100644 --- a/utils/TableGen/DAGISelMatcherEmitter.cpp +++ b/utils/TableGen/DAGISelMatcherEmitter.cpp @@ -181,6 +181,15 @@ EmitMatcher(const MatcherNode *N, unsigned Indent, formatted_raw_ostream &OS) { << cast(N)->getOpcodeName() << ",\n"; return 2; + case MatcherNode::CheckMultiOpcode: { + const CheckMultiOpcodeMatcherNode *CMO=cast(N); + OS << "OPC_CheckMultiOpcode, " << CMO->getNumOpcodeNames() << ", "; + for (unsigned i = 0, e = CMO->getNumOpcodeNames(); i != e; ++i) + OS << CMO->getOpcodeName(i) << ", "; + OS << '\n'; + return 2 + CMO->getNumOpcodeNames(); + } + case MatcherNode::CheckType: OS << "OPC_CheckType, " << getEnumName(cast(N)->getType()) << ",\n"; diff --git a/utils/TableGen/DAGISelMatcherGen.cpp b/utils/TableGen/DAGISelMatcherGen.cpp index c9138538cad..0ea165cdfd4 100644 --- a/utils/TableGen/DAGISelMatcherGen.cpp +++ b/utils/TableGen/DAGISelMatcherGen.cpp @@ -251,9 +251,11 @@ void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) { StringRef OpName = CGP.getSDNodeInfo(OpNodes[0]).getEnumName(); AddMatcherNode(new CheckOpcodeMatcherNode(OpName)); } else if (!OpNodes.empty()) { - for (unsigned j = 0, e = OpNodes.size(); j != e; j++) { - // .getOpcodeName(OpNodes[j], CGP) - } + SmallVector OpNames; + for (unsigned i = 0, e = OpNodes.size(); i != e; i++) + OpNames.push_back(CGP.getSDNodeInfo(OpNodes[i]).getEnumName()); + AddMatcherNode(new CheckMultiOpcodeMatcherNode(OpNames.data(), + OpNames.size())); } }