aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-09-23 23:16:51 +0000
committerChris Lattner <sabre@nondot.org>2005-09-23 23:16:51 +0000
commit8fc3568d98834c73528e57f365c658ea7084361e (patch)
treeae6c7ef718098e08b940eb00976451c89f6b97d7
parent547394ca38d75d9784498afa6963efc0f9818f7d (diff)
Emit better code (no more copies for var references), and support DAG patterns
(e.g. things like rotates). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23416 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--utils/TableGen/DAGISelEmitter.cpp32
-rw-r--r--utils/TableGen/DAGISelEmitter.h1
2 files changed, 25 insertions, 8 deletions
diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp
index 5c664edbb9..6ea5d9604c 100644
--- a/utils/TableGen/DAGISelEmitter.cpp
+++ b/utils/TableGen/DAGISelEmitter.cpp
@@ -989,7 +989,8 @@ void DAGISelEmitter::ParsePatterns() {
/// 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,
+ const std::string &RootName,
+ std::map<std::string,std::string> &VarMap,
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.
@@ -997,12 +998,30 @@ void DAGISelEmitter::EmitMatchForPattern(TreePatternNode *N,
OS << " SDOperand " << RootName << i <<" = " << RootName
<< ".getOperand(" << i << ");\n";
TreePatternNode *Child = N->getChild(i);
+
+ // If this child has a name associated with it, capture it in VarMap. If
+ // we already saw this in the pattern, emit code to verify dagness.
+ if (!Child->getName().empty()) {
+ std::string &VarMapEntry = VarMap[Child->getName()];
+ if (VarMapEntry.empty()) {
+ VarMapEntry = RootName + utostr(i);
+ } else {
+ // If we get here, this is a second reference to a specific name. Since
+ // we already have checked that the first reference is valid, we don't
+ // have to recursively match it, just check that it's the same as the
+ // previously named thing.
+ OS << " if (" << VarMapEntry << " != " << RootName << i
+ << ") goto P" << PatternNo << "Fail;\n";
+ continue;
+ }
+ }
+
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);
+ EmitMatchForPattern(Child, RootName + utostr(i), VarMap, PatternNo, OS);
} else {
// Handle leaves of various types.
Init *LeafVal = Child->getLeafValue();
@@ -1019,11 +1038,6 @@ void DAGISelEmitter::EmitMatchForPattern(TreePatternNode *N,
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 << ";\n";
}
// If there is a node predicate for this, emit the call.
@@ -1043,7 +1057,9 @@ void DAGISelEmitter::EmitCodeForPattern(PatternToMatch &Pattern,
Pattern.first->print(OS);
OS << "\n";
- EmitMatchForPattern(Pattern.first, "N", PatternNo, OS);
+ // Emit the matcher, capturing named arguments in VariableMap.
+ std::map<std::string,std::string> VariableMap;
+ EmitMatchForPattern(Pattern.first, "N", VariableMap, PatternNo, OS);
OS << " // Emit: ";
Pattern.second->print(OS);
diff --git a/utils/TableGen/DAGISelEmitter.h b/utils/TableGen/DAGISelEmitter.h
index 7695f26d73..5cfab18626 100644
--- a/utils/TableGen/DAGISelEmitter.h
+++ b/utils/TableGen/DAGISelEmitter.h
@@ -366,6 +366,7 @@ private:
TreePatternNode*> &InstInputs,
std::map<std::string, Record*> &InstResults);
void EmitMatchForPattern(TreePatternNode *N, const std::string &RootName,
+ std::map<std::string,std::string> &VarMap,
unsigned PatternNo, std::ostream &OS);
void EmitCodeForPattern(PatternToMatch &Pattern, std::ostream &OS);
void EmitInstructionSelector(std::ostream &OS);