aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/llvm/CodeGen/SelectionDAGISel.h1
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp9
-rw-r--r--utils/TableGen/DAGISelEmitter.cpp13
-rw-r--r--utils/TableGen/DAGISelMatcher.cpp13
-rw-r--r--utils/TableGen/DAGISelMatcher.h29
-rw-r--r--utils/TableGen/DAGISelMatcherEmitter.cpp12
-rw-r--r--utils/TableGen/DAGISelMatcherGen.cpp54
-rw-r--r--utils/TableGen/DAGISelMatcherOpt.cpp3
8 files changed, 46 insertions, 88 deletions
diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h
index 0e856a1..fa3b08f 100644
--- a/include/llvm/CodeGen/SelectionDAGISel.h
+++ b/include/llvm/CodeGen/SelectionDAGISel.h
@@ -113,7 +113,6 @@ public:
OPC_CheckPredicate,
OPC_CheckOpcode,
OPC_SwitchOpcode,
- OPC_CheckMultiOpcode,
OPC_CheckType,
OPC_CheckChild0Type, OPC_CheckChild1Type, OPC_CheckChild2Type,
OPC_CheckChild3Type, OPC_CheckChild4Type, OPC_CheckChild5Type,
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 1e3550c..f1e6b96 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -1787,15 +1787,6 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
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/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp
index 2854e4f..5336646 100644
--- a/utils/TableGen/DAGISelEmitter.cpp
+++ b/utils/TableGen/DAGISelEmitter.cpp
@@ -1959,10 +1959,17 @@ void DAGISelEmitter::run(raw_ostream &OS) {
PatternSortingPredicate2(CGP));
- // Convert each pattern into Matcher's.
+ // Convert each variant of each pattern into a Matcher.
std::vector<Matcher*> PatternMatchers;
- for (unsigned i = 0, e = Patterns.size(); i != e; ++i)
- PatternMatchers.push_back(ConvertPatternToMatcher(*Patterns[i], CGP));
+ for (unsigned i = 0, e = Patterns.size(); i != e; ++i) {
+ for (unsigned Variant = 0; ; ++Variant) {
+ if (Matcher *M = ConvertPatternToMatcher(*Patterns[i], Variant, CGP))
+ PatternMatchers.push_back(M);
+ else
+ break;
+ }
+ }
+
Matcher *TheMatcher = new ScopeMatcher(&PatternMatchers[0],
PatternMatchers.size());
diff --git a/utils/TableGen/DAGISelMatcher.cpp b/utils/TableGen/DAGISelMatcher.cpp
index c88f260..860165f 100644
--- a/utils/TableGen/DAGISelMatcher.cpp
+++ b/utils/TableGen/DAGISelMatcher.cpp
@@ -98,10 +98,6 @@ void SwitchOpcodeMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
}
-void CheckMultiOpcodeMatcher::printImpl(raw_ostream &OS, unsigned indent) const{
- OS.indent(indent) << "CheckMultiOpcode <todo args>\n";
-}
-
void CheckTypeMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
OS.indent(indent) << "CheckType " << getEnumName(Type) << '\n';
}
@@ -221,13 +217,6 @@ unsigned CheckOpcodeMatcher::getHashImpl() const {
return HashString(Opcode.getEnumName());
}
-unsigned CheckMultiOpcodeMatcher::getHashImpl() const {
- unsigned Result = 0;
- for (unsigned i = 0, e = Opcodes.size(); i != e; ++i)
- Result |= HashString(Opcodes[i]->getEnumName());
- return Result;
-}
-
unsigned CheckCondCodeMatcher::getHashImpl() const {
return HashString(CondCodeName);
}
@@ -311,8 +300,6 @@ bool CheckOpcodeMatcher::isContradictoryImpl(const Matcher *M) const {
return COM->getOpcode().getEnumName() != getOpcode().getEnumName();
}
- // TODO: CheckMultiOpcodeMatcher?
-
// If the node has a known type, and if the type we're checking for is
// different, then we know they contradict. For example, a check for
// ISD::STORE will never be true at the same time a check for Type i32 is.
diff --git a/utils/TableGen/DAGISelMatcher.h b/utils/TableGen/DAGISelMatcher.h
index 9992c79..8b6b322 100644
--- a/utils/TableGen/DAGISelMatcher.h
+++ b/utils/TableGen/DAGISelMatcher.h
@@ -25,7 +25,7 @@ namespace llvm {
class Record;
class SDNodeInfo;
-Matcher *ConvertPatternToMatcher(const PatternToMatch &Pattern,
+Matcher *ConvertPatternToMatcher(const PatternToMatch &Pattern,unsigned Variant,
const CodeGenDAGPatterns &CGP);
Matcher *OptimizeMatcher(Matcher *Matcher, const CodeGenDAGPatterns &CGP);
void EmitMatcherTable(const Matcher *Matcher, const CodeGenDAGPatterns &CGP,
@@ -449,33 +449,6 @@ private:
virtual unsigned getHashImpl() const { return 4123; }
};
-/// CheckMultiOpcodeMatcher - This checks to see if the current node has one
-/// of the specified opcode, if not it fails to match.
-class CheckMultiOpcodeMatcher : public Matcher {
- SmallVector<const SDNodeInfo*, 4> Opcodes;
-public:
- CheckMultiOpcodeMatcher(const SDNodeInfo * const *opcodes, unsigned numops)
- : Matcher(CheckMultiOpcode), Opcodes(opcodes, opcodes+numops) {}
-
- unsigned getNumOpcodes() const { return Opcodes.size(); }
- const SDNodeInfo &getOpcode(unsigned i) const { return *Opcodes[i]; }
-
- static inline bool classof(const Matcher *N) {
- return N->getKind() == CheckMultiOpcode;
- }
-
- virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
-
-private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const {
- return cast<CheckMultiOpcodeMatcher>(M)->Opcodes == Opcodes;
- }
- virtual unsigned getHashImpl() const;
-};
-
-
-
/// CheckTypeMatcher - This checks to see if the current node has the
/// specified type, if not it fails to match.
class CheckTypeMatcher : public Matcher {
diff --git a/utils/TableGen/DAGISelMatcherEmitter.cpp b/utils/TableGen/DAGISelMatcherEmitter.cpp
index a828db3..279f036 100644
--- a/utils/TableGen/DAGISelMatcherEmitter.cpp
+++ b/utils/TableGen/DAGISelMatcherEmitter.cpp
@@ -282,16 +282,7 @@ EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
return CurrentIdx-StartIdx;
}
- case Matcher::CheckMultiOpcode: {
- const CheckMultiOpcodeMatcher *CMO = cast<CheckMultiOpcodeMatcher>(N);
- OS << "OPC_CheckMultiOpcode, " << CMO->getNumOpcodes() << ", ";
- for (unsigned i = 0, e = CMO->getNumOpcodes(); i != e; ++i)
- OS << CMO->getOpcode(i).getEnumName() << ", ";
- OS << '\n';
- return 2 + CMO->getNumOpcodes();
- }
-
- case Matcher::CheckType:
+ case Matcher::CheckType:
OS << "OPC_CheckType, "
<< getEnumName(cast<CheckTypeMatcher>(N)->getType()) << ",\n";
return 2;
@@ -623,7 +614,6 @@ void MatcherTableEmitter::EmitHistogram(formatted_raw_ostream &OS) {
case Matcher::CheckPredicate: OS << "OPC_CheckPredicate"; break;
case Matcher::CheckOpcode: OS << "OPC_CheckOpcode"; break;
case Matcher::SwitchOpcode: OS << "OPC_SwitchOpcode"; break;
- case Matcher::CheckMultiOpcode: OS << "OPC_CheckMultiOpcode"; break;
case Matcher::CheckType: OS << "OPC_CheckType"; break;
case Matcher::CheckChildType: OS << "OPC_CheckChildType"; break;
case Matcher::CheckInteger: OS << "OPC_CheckInteger"; break;
diff --git a/utils/TableGen/DAGISelMatcherGen.cpp b/utils/TableGen/DAGISelMatcherGen.cpp
index 5a253e8..95cfa5b 100644
--- a/utils/TableGen/DAGISelMatcherGen.cpp
+++ b/utils/TableGen/DAGISelMatcherGen.cpp
@@ -97,7 +97,7 @@ namespace {
delete PatWithNoTypes;
}
- void EmitMatcherCode();
+ bool EmitMatcherCode(unsigned Variant);
void EmitResultCode();
Matcher *GetMatcher() const { return TheMatcher; }
@@ -247,20 +247,6 @@ void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) {
// Handle complex pattern.
const ComplexPattern &CP = CGP.getComplexPattern(LeafRec);
-
- // If we're at the root of the pattern, we have to check that the opcode
- // is a one of the ones requested to be matched.
- if (N == Pattern.getSrcPattern()) {
- const std::vector<Record*> &OpNodes = CP.getRootNodes();
- if (OpNodes.size() == 1) {
- AddMatcher(new CheckOpcodeMatcher(CGP.getSDNodeInfo(OpNodes[0])));
- } else if (!OpNodes.empty()) {
- SmallVector<const SDNodeInfo*, 4> OpNames;
- for (unsigned i = 0, e = OpNodes.size(); i != e; i++)
- OpNames.push_back(&CGP.getSDNodeInfo(OpNodes[i]));
- AddMatcher(new CheckMultiOpcodeMatcher(OpNames.data(), OpNames.size()));
- }
- }
// Emit a CheckComplexPat operation, which does the match (aborting if it
// fails) and pushes the matched operands onto the recorded nodes list.
@@ -495,7 +481,30 @@ void MatcherGen::EmitMatchCode(const TreePatternNode *N,
EmitOperatorMatchCode(N, NodeNoTypes);
}
-void MatcherGen::EmitMatcherCode() {
+/// EmitMatcherCode - Generate the code that matches the predicate of this
+/// pattern for the specified Variant. If the variant is invalid this returns
+/// true and does not generate code, if it is valid, it returns false.
+bool MatcherGen::EmitMatcherCode(unsigned Variant) {
+ // If the root of the pattern is a ComplexPattern and if it is specified to
+ // match some number of root opcodes, these are considered to be our variants.
+ // Depending on which variant we're generating code for, emit the root opcode
+ // check.
+ if (const ComplexPattern *CP =
+ Pattern.getSrcPattern()->getComplexPatternInfo(CGP)) {
+
+ const std::vector<Record*> &OpNodes = CP->getRootNodes();
+ if (OpNodes.empty()) {
+ // FIXME: Empty OpNodes runs on everything, is this even valid?
+ if (Variant != 0) return true;
+ } else {
+ if (Variant >= OpNodes.size()) return true;
+
+ AddMatcher(new CheckOpcodeMatcher(CGP.getSDNodeInfo(OpNodes[Variant])));
+ }
+ } else {
+ if (Variant != 0) return true;
+ }
+
// If the pattern has a predicate on it (e.g. only enabled when a subtarget
// feature is around, do the check).
// FIXME: This should get emitted after the match code below to encourage
@@ -503,11 +512,11 @@ void MatcherGen::EmitMatcherCode() {
// dag combine, eliminating the horrible side-effect-full stuff from
// X86's MatchAddress.
if (!Pattern.getPredicateCheck().empty())
- AddMatcher(new
- CheckPatternPredicateMatcher(Pattern.getPredicateCheck()));
-
+ AddMatcher(new CheckPatternPredicateMatcher(Pattern.getPredicateCheck()));
+
// Emit the matcher for the pattern structure and types.
EmitMatchCode(Pattern.getSrcPattern(), PatWithNoTypes);
+ return false;
}
@@ -849,13 +858,16 @@ void MatcherGen::EmitResultCode() {
}
+/// ConvertPatternToMatcher - Create the matcher for the specified pattern with
+/// the specified variant. If the variant number is invalid, this returns null.
Matcher *llvm::ConvertPatternToMatcher(const PatternToMatch &Pattern,
+ unsigned Variant,
const CodeGenDAGPatterns &CGP) {
MatcherGen Gen(Pattern, CGP);
// Generate the code for the matcher.
- Gen.EmitMatcherCode();
-
+ if (Gen.EmitMatcherCode(Variant))
+ return 0;
// FIXME2: Kill extra MoveParent commands at the end of the matcher sequence.
// FIXME2: Split result code out to another table, and make the matcher end
diff --git a/utils/TableGen/DAGISelMatcherOpt.cpp b/utils/TableGen/DAGISelMatcherOpt.cpp
index 41ce6ae..0e89fa0 100644
--- a/utils/TableGen/DAGISelMatcherOpt.cpp
+++ b/utils/TableGen/DAGISelMatcherOpt.cpp
@@ -153,8 +153,7 @@ static void ContractNodes(OwningPtr<Matcher> &MatcherPtr,
// like X86 where many operations are valid on multiple types.
if ((isa<CheckTypeMatcher>(N) || isa<CheckChildTypeMatcher>(N) ||
isa<RecordMatcher>(N)) &&
- (isa<CheckOpcodeMatcher>(N->getNext()) ||
- isa<CheckMultiOpcodeMatcher>(N->getNext()))) {
+ isa<CheckOpcodeMatcher>(N->getNext())) {
// Unlink the two nodes from the list.
Matcher *CheckType = MatcherPtr.take();
Matcher *CheckOpcode = CheckType->takeNext();