diff options
| author | Chris Lattner <sabre@nondot.org> | 2006-01-04 00:25:00 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2006-01-04 00:25:00 +0000 |
| commit | c29793a077a111cd1ac19b0e500f44099987c110 (patch) | |
| tree | e6d377b2a3d0aba14583fb96bb4d82a136ed1df0 | |
| parent | 81e4dbc6a1d6d100463c3e5f132e7dde26c24a3e (diff) | |
| download | bcm5719-llvm-c29793a077a111cd1ac19b0e500f44099987c110.tar.gz bcm5719-llvm-c29793a077a111cd1ac19b0e500f44099987c110.zip | |
reduce stack usage of the recursive SelectCode function by out-lining each
case of the switch statement into its own method.
llvm-svn: 25069
| -rw-r--r-- | llvm/utils/TableGen/DAGISelEmitter.cpp | 105 |
1 files changed, 61 insertions, 44 deletions
diff --git a/llvm/utils/TableGen/DAGISelEmitter.cpp b/llvm/utils/TableGen/DAGISelEmitter.cpp index f6a09d82bfd..82819489674 100644 --- a/llvm/utils/TableGen/DAGISelEmitter.cpp +++ b/llvm/utils/TableGen/DAGISelEmitter.cpp @@ -2466,6 +2466,62 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) { std::string InstNS = Target.inst_begin()->second.Namespace; if (!InstNS.empty()) InstNS += "::"; + // Group the patterns by their top-level opcodes. + std::map<Record*, std::vector<PatternToMatch*>, + CompareByRecordName> PatternsByOpcode; + for (unsigned i = 0, e = PatternsToMatch.size(); i != e; ++i) { + TreePatternNode *Node = PatternsToMatch[i].getSrcPattern(); + if (!Node->isLeaf()) { + PatternsByOpcode[Node->getOperator()].push_back(&PatternsToMatch[i]); + } else { + const ComplexPattern *CP; + if (IntInit *II = + dynamic_cast<IntInit*>(Node->getLeafValue())) { + PatternsByOpcode[getSDNodeNamed("imm")].push_back(&PatternsToMatch[i]); + } else if ((CP = NodeGetComplexPattern(Node, *this))) { + std::vector<Record*> OpNodes = CP->getRootNodes(); + for (unsigned j = 0, e = OpNodes.size(); j != e; j++) { + PatternsByOpcode[OpNodes[j]].insert(PatternsByOpcode[OpNodes[j]].begin(), + &PatternsToMatch[i]); + } + } else { + std::cerr << "Unrecognized opcode '"; + Node->dump(); + std::cerr << "' on tree pattern '"; + std::cerr << PatternsToMatch[i].getDstPattern()->getOperator()->getName(); + std::cerr << "'!\n"; + exit(1); + } + } + } + + // Emit one Select_* method for each top-level opcode. We do this instead of + // emitting one giant switch statement to support compilers where this will + // result in the recursive functions taking less stack space. + for (std::map<Record*, std::vector<PatternToMatch*>, + CompareByRecordName>::iterator PBOI = PatternsByOpcode.begin(), + E = PatternsByOpcode.end(); PBOI != E; ++PBOI) { + OS << "SDOperand Select_" << PBOI->first->getName() << "(SDOperand N) {\n"; + + const SDNodeInfo &OpcodeInfo = getSDNodeInfo(PBOI->first); + std::vector<PatternToMatch*> &Patterns = PBOI->second; + + // 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::stable_sort(Patterns.begin(), Patterns.end(), + PatternSortingPredicate(*this)); + + for (unsigned i = 0, e = Patterns.size(); i != e; ++i) + EmitCodeForPattern(*Patterns[i], OS); + + OS << " std::cerr << \"Cannot yet select: \";\n" + << " N.Val->dump(CurDAG);\n" + << " std::cerr << '\\n';\n" + << " abort();\n" + << "}\n\n"; + } + // Emit boilerplate. OS << "// The main instruction selector code.\n" << "SDOperand SelectCode(SDOperand N) {\n" @@ -2544,55 +2600,16 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) { << " }\n" << " }\n"; - // Group the patterns by their top-level opcodes. - std::map<Record*, std::vector<PatternToMatch*>, - CompareByRecordName> PatternsByOpcode; - for (unsigned i = 0, e = PatternsToMatch.size(); i != e; ++i) { - TreePatternNode *Node = PatternsToMatch[i].getSrcPattern(); - if (!Node->isLeaf()) { - PatternsByOpcode[Node->getOperator()].push_back(&PatternsToMatch[i]); - } else { - const ComplexPattern *CP; - if (IntInit *II = - dynamic_cast<IntInit*>(Node->getLeafValue())) { - PatternsByOpcode[getSDNodeNamed("imm")].push_back(&PatternsToMatch[i]); - } else if ((CP = NodeGetComplexPattern(Node, *this))) { - std::vector<Record*> OpNodes = CP->getRootNodes(); - for (unsigned j = 0, e = OpNodes.size(); j != e; j++) { - PatternsByOpcode[OpNodes[j]].insert(PatternsByOpcode[OpNodes[j]].begin(), - &PatternsToMatch[i]); - } - } else { - std::cerr << "Unrecognized opcode '"; - Node->dump(); - std::cerr << "' on tree pattern '"; - std::cerr << PatternsToMatch[i].getDstPattern()->getOperator()->getName(); - std::cerr << "'!\n"; - exit(1); - } - } - } - - // Loop over all of the case statements. + // Loop over all of the case statements, emiting a call to each method we + // emitted above. for (std::map<Record*, std::vector<PatternToMatch*>, CompareByRecordName>::iterator PBOI = PatternsByOpcode.begin(), E = PatternsByOpcode.end(); PBOI != E; ++PBOI) { const SDNodeInfo &OpcodeInfo = getSDNodeInfo(PBOI->first); - std::vector<PatternToMatch*> &Patterns = PBOI->second; - - OS << " case " << OpcodeInfo.getEnumName() << ":\n"; - - // 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::stable_sort(Patterns.begin(), Patterns.end(), - PatternSortingPredicate(*this)); - - for (unsigned i = 0, e = Patterns.size(); i != e; ++i) - EmitCodeForPattern(*Patterns[i], OS); - OS << " break;\n\n"; + OS << " case " << OpcodeInfo.getEnumName() << ": " + << std::string(std::max(0, int(16-OpcodeInfo.getEnumName().size())), ' ') + << "return Select_" << PBOI->first->getName() << "(N);\n"; } - OS << " } // end of big switch.\n\n" << " std::cerr << \"Cannot yet select: \";\n" |

