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
This commit is contained in:
Chris Lattner 2010-02-22 22:30:37 +00:00
parent 1f2ed5fe7e
commit 12a667c1e8
5 changed files with 51 additions and 3 deletions

View File

@ -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++];

View File

@ -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 <todo args>\n";
printNext(OS, indent);
}
void CheckTypeMatcherNode::print(raw_ostream &OS, unsigned indent) const {
OS.indent(indent) << "CheckType " << getEnumName(Type) << '\n';
printNext(OS, indent);

View File

@ -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<StringRef, 4> 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 {

View File

@ -181,6 +181,15 @@ EmitMatcher(const MatcherNode *N, unsigned Indent, formatted_raw_ostream &OS) {
<< cast<CheckOpcodeMatcherNode>(N)->getOpcodeName() << ",\n";
return 2;
case MatcherNode::CheckMultiOpcode: {
const CheckMultiOpcodeMatcherNode *CMO=cast<CheckMultiOpcodeMatcherNode>(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<CheckTypeMatcherNode>(N)->getType()) << ",\n";

View File

@ -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<StringRef, 4> 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()));
}
}