summaryrefslogtreecommitdiffstats
path: root/utils
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-09-23 21:33:23 +0000
committerChris Lattner <sabre@nondot.org>2005-09-23 21:33:23 +0000
commitd1ff35a49d1a8bfbcbaaec259ea368848d599a03 (patch)
treee0043916098b9e2ba5e3cef29d5a42432801655d /utils
parent3f7e91477e8cd7b8cae8b3b3d2c5e01d4848cf2b (diff)
downloadexternal_llvm-d1ff35a49d1a8bfbcbaaec259ea368848d599a03.zip
external_llvm-d1ff35a49d1a8bfbcbaaec259ea368848d599a03.tar.gz
external_llvm-d1ff35a49d1a8bfbcbaaec259ea368848d599a03.tar.bz2
Emit code that matches the incoming DAG pattern and checks predicates.
This does not check that types match yet, but PPC only has one integer type ;-). This also doesn't have the code to build the resultant dag. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23414 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/DAGISelEmitter.cpp66
-rw-r--r--utils/TableGen/DAGISelEmitter.h2
2 files changed, 64 insertions, 4 deletions
diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp
index 3836a23..d888c90 100644
--- a/utils/TableGen/DAGISelEmitter.cpp
+++ b/utils/TableGen/DAGISelEmitter.cpp
@@ -985,14 +985,71 @@ void DAGISelEmitter::ParsePatterns() {
});
}
+/// EmitMatchForPattern - Emit a matcher for N, going to the label for PatternNo
+/// if the match fails. At this point, we already know that the opcode for N
+/// matches, and the SDNode for the result has the RootName specified name.
+void DAGISelEmitter::EmitMatchForPattern(TreePatternNode *N,
+ const std::string &RootName,
+ unsigned PatternNo, std::ostream &OS) {
+ assert(!N->isLeaf() && "Cannot match against a leaf!");
+ // Emit code to load the child nodes and match their contents recursively.
+ for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) {
+ OS << " SDNode *" << RootName << i <<" = " << RootName
+ << "->getOperand(" << i << ").Val;\n";
+ TreePatternNode *Child = N->getChild(i);
+ if (!Child->isLeaf()) {
+ // If it's not a leaf, recursively match.
+ const SDNodeInfo &CInfo = getSDNodeInfo(Child->getOperator());
+ OS << " if (" << RootName << i << "->getOpcode() != "
+ << CInfo.getEnumName() << ") goto P" << PatternNo << "Fail;\n";
+ EmitMatchForPattern(Child, RootName + utostr(i), PatternNo, OS);
+ } else {
+ // Handle leaves of various types.
+ Init *LeafVal = Child->getLeafValue();
+ Record *LeafRec = dynamic_cast<DefInit*>(LeafVal)->getDef();
+ if (LeafRec->isSubClassOf("RegisterClass")) {
+ // Handle register references. Nothing to do here.
+ } else if (LeafRec->isSubClassOf("ValueType")) {
+ // Make sure this is the specified value type.
+ OS << " if (cast<VTSDNode>(" << RootName << i << ")->getVT() != "
+ << "MVT::" << LeafRec->getName() << ") goto P" << PatternNo
+ << "Fail;\n";
+ } else {
+ Child->dump();
+ assert(0 && "Unknown leaf type!");
+ }
+ }
+
+ // If this child has a name associated with it, capture it as a variable.
+ if (!Child->getName().empty())
+ OS << " SDOperand op" << Child->getName() << "(" << RootName
+ << i << ", 0 /*FIXME*/);\n";
+ }
+
+ // If there is a node predicate for this, emit the call.
+ if (!N->getPredicateFn().empty())
+ OS << " if (!" << N->getPredicateFn() << "(" << RootName
+ << ")) goto P" << PatternNo << "Fail;\n";
+}
+
+/// EmitCodeForPattern - Given a pattern to match, emit code to the specified
+/// stream to match the pattern, and generate the code for the match if it
+/// succeeds.
void DAGISelEmitter::EmitCodeForPattern(PatternToMatch &Pattern,
std::ostream &OS) {
- OS << " // ";
+ static unsigned PatternCount = 0;
+ unsigned PatternNo = PatternCount++;
+ OS << " { // Pattern #" << PatternNo << ": ";
Pattern.first->print(OS);
OS << "\n";
+
+ EmitMatchForPattern(Pattern.first, "N", PatternNo, OS);
+ OS << " // Emit: ";
+ Pattern.second->print(OS);
+ OS << "\n";
-
+ OS << " }\n P" << PatternNo << "Fail:\n";
}
/// getPatternSize - Return the 'size' of this pattern. We want to match large
@@ -1064,11 +1121,12 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
// We want to emit all of the matching code now. However, we want to emit
// the matches in order of minimal cost. Sort the patterns so the least
// cost one is at the start.
- std::sort(Patterns.begin(), Patterns.end(), PatternSortingPredicate());
+ std::stable_sort(Patterns.begin(), Patterns.end(),
+ PatternSortingPredicate());
for (unsigned i = 0, e = Patterns.size(); i != e; ++i)
EmitCodeForPattern(*Patterns[i], OS);
- OS << " break;\n";
+ OS << " break;\n\n";
}
diff --git a/utils/TableGen/DAGISelEmitter.h b/utils/TableGen/DAGISelEmitter.h
index 64c5c4f..7695f26 100644
--- a/utils/TableGen/DAGISelEmitter.h
+++ b/utils/TableGen/DAGISelEmitter.h
@@ -365,6 +365,8 @@ private:
std::map<std::string,
TreePatternNode*> &InstInputs,
std::map<std::string, Record*> &InstResults);
+ void EmitMatchForPattern(TreePatternNode *N, const std::string &RootName,
+ unsigned PatternNo, std::ostream &OS);
void EmitCodeForPattern(PatternToMatch &Pattern, std::ostream &OS);
void EmitInstructionSelector(std::ostream &OS);
};