diff options
author | Chris Lattner <sabre@nondot.org> | 2005-09-23 23:16:51 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2005-09-23 23:16:51 +0000 |
commit | 8fc3568d98834c73528e57f365c658ea7084361e (patch) | |
tree | ae6c7ef718098e08b940eb00976451c89f6b97d7 | |
parent | 547394ca38d75d9784498afa6963efc0f9818f7d (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.cpp | 32 | ||||
-rw-r--r-- | utils/TableGen/DAGISelEmitter.h | 1 |
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); |