diff options
author | Chris Lattner <sabre@nondot.org> | 2005-09-23 21:33:23 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2005-09-23 21:33:23 +0000 |
commit | d1ff35a49d1a8bfbcbaaec259ea368848d599a03 (patch) | |
tree | e0043916098b9e2ba5e3cef29d5a42432801655d /utils | |
parent | 3f7e91477e8cd7b8cae8b3b3d2c5e01d4848cf2b (diff) | |
download | external_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.cpp | 66 | ||||
-rw-r--r-- | utils/TableGen/DAGISelEmitter.h | 2 |
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); }; |