summaryrefslogtreecommitdiff
path: root/support/tools/TableGen/InstrSelectorEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'support/tools/TableGen/InstrSelectorEmitter.cpp')
-rw-r--r--support/tools/TableGen/InstrSelectorEmitter.cpp144
1 files changed, 141 insertions, 3 deletions
diff --git a/support/tools/TableGen/InstrSelectorEmitter.cpp b/support/tools/TableGen/InstrSelectorEmitter.cpp
index 3e30a52b6c..b947536037 100644
--- a/support/tools/TableGen/InstrSelectorEmitter.cpp
+++ b/support/tools/TableGen/InstrSelectorEmitter.cpp
@@ -318,6 +318,41 @@ std::ostream &operator<<(std::ostream &OS, const Pattern &P) {
//===----------------------------------------------------------------------===//
+// PatternOrganizer implementation
+//
+
+/// addPattern - Add the specified pattern to the appropriate location in the
+/// collection.
+void PatternOrganizer::addPattern(Pattern *P) {
+ std::string ValueName;
+ if (P->getPatternType() == Pattern::Nonterminal) {
+ // Just use the nonterminal name, which will already include the type if
+ // it has been cloned.
+ ValueName = P->getRecord()->getName();
+ } else {
+ if (P->getResult())
+ ValueName += P->getResult()->getName()+"_";
+ else
+ ValueName += "Void_";
+ ValueName += getName(P->getTree()->getType());
+ }
+
+ NodesForSlot &Nodes = AllPatterns[ValueName];
+ if (!P->getTree()->isLeaf())
+ Nodes[P->getTree()->getOperator()].push_back(P);
+ else {
+ // Right now we only support DefInit's with node types...
+ DefInit *Val = dynamic_cast<DefInit*>(P->getTree()->getValue());
+ if (!Val)
+ throw std::string("We only support def inits in PatternOrganizer"
+ "::addPattern so far!");
+ Nodes[Val->getDef()].push_back(P);
+ }
+}
+
+
+
+//===----------------------------------------------------------------------===//
// InstrSelectorEmitter implementation
//
@@ -432,11 +467,12 @@ Record *InstrSelectorEmitter::InstantiateNonterminal(Pattern *NT,
Record* &Slot = InstantiatedNTs[std::make_pair(NT, ResultTy)];
if (Slot) return Slot;
- DEBUG(std::cerr << " Nonterminal '" << NT->getRecord()->getName()
- << "' for type '" << getName(ResultTy) << "'\n");
-
Record *New = new Record(NT->getRecord()->getName()+"_"+getName(ResultTy));
+ DEBUG(std::cerr << " Nonterminal '" << NT->getRecord()->getName()
+ << "' for type '" << getName(ResultTy) << "', producing '"
+ << New->getName() << "'\n");
+
// Copy the pattern...
Pattern *NewPat = NT->clone(New);
@@ -457,6 +493,15 @@ Record *InstrSelectorEmitter::InstantiateNonterminal(Pattern *NT,
return Slot = New;
}
+// CalculateComputableValues - Fill in the ComputableValues map through
+// analysis of the patterns we are playing with.
+void InstrSelectorEmitter::CalculateComputableValues() {
+ // Loop over all of the patterns, adding them to the ComputableValues map
+ for (std::map<Record*, Pattern*>::iterator I = Patterns.begin(),
+ E = Patterns.end(); I != E; ++I)
+ if (I->second->isResolved())
+ ComputableValues.addPattern(I->second);
+}
void InstrSelectorEmitter::run(std::ostream &OS) {
// Type-check all of the node types to ensure we "understand" them.
@@ -471,10 +516,103 @@ void InstrSelectorEmitter::run(std::ostream &OS) {
// that they are used in.
InstantiateNonterminals();
+ // Clear InstantiatedNTs, we don't need it anymore...
+ InstantiatedNTs.clear();
std::cerr << "Patterns aquired:\n";
for (std::map<Record*, Pattern*>::iterator I = Patterns.begin(),
E = Patterns.end(); I != E; ++I)
if (I->second->isResolved())
std::cerr << " " << *I->second << "\n";
+
+ CalculateComputableValues();
+
+ // Output the slot number enums...
+ OS << "\n\nenum { // Slot numbers...\n"
+ << " LastBuiltinSlot = ISD::NumBuiltinSlots-1, // Start numbering here\n";
+ for (PatternOrganizer::iterator I = ComputableValues.begin(),
+ E = ComputableValues.end(); I != E; ++I)
+ OS << " " << I->first << "_Slot,\n";
+ OS << " NumSlots\n};\n\n// Reduction value typedefs...\n";
+
+ // Output the reduction value typedefs...
+ for (PatternOrganizer::iterator I = ComputableValues.begin(),
+ E = ComputableValues.end(); I != E; ++I)
+ OS << "typedef ReduceValue<unsigned, " << I->first
+ << "_Slot> ReducedValue_" << I->first << ";\n";
+
+ // Output the pattern enums...
+ OS << "\n\n"
+ << "enum { // Patterns...\n"
+ << " NotComputed = 0,\n"
+ << " NoMatchPattern, \n";
+ for (PatternOrganizer::iterator I = ComputableValues.begin(),
+ E = ComputableValues.end(); I != E; ++I) {
+ OS << " // " << I->first << " patterns...\n";
+ for (PatternOrganizer::NodesForSlot::iterator J = I->second.begin(),
+ E = I->second.end(); J != E; ++J)
+ for (unsigned i = 0, e = J->second.size(); i != e; ++i)
+ OS << " " << J->second[i]->getRecord()->getName() << "_Pattern,\n";
+ }
+ OS << "};\n\n";
+
+ // Start emitting the class...
+ OS << "namespace {\n"
+ << " class " << Target.getName() << "ISel {\n"
+ << " SelectionDAG &DAG;\n"
+ << " public:\n"
+ << " X86ISel(SelectionDag &D) : DAG(D) {}\n"
+ << " void generateCode();\n"
+ << " private:\n"
+ << " unsigned makeAnotherReg(const TargetRegisterClass *RC) {\n"
+ << " return DAG.getMachineFunction().getSSARegMap()->createVirt"
+ "ualRegister(RC);\n"
+ << " }\n\n"
+ << " // DAG matching methods for classes... all of these methods"
+ " return the cost\n"
+ <<" // of producing a value of the specified class and type, which"
+ " also gets\n"
+ << " // added to the DAG node.\n";
+
+ // Output all of the matching prototypes for slots...
+ for (PatternOrganizer::iterator I = ComputableValues.begin(),
+ E = ComputableValues.end(); I != E; ++I)
+ OS << " unsigned Match_" << I->first << "(SelectionDAGNode *N);\n";
+ OS << "\n // DAG matching methods for DAG nodes...\n";
+
+ // Output all of the matching prototypes for slot/node pairs
+ for (PatternOrganizer::iterator I = ComputableValues.begin(),
+ E = ComputableValues.end(); I != E; ++I)
+ for (PatternOrganizer::NodesForSlot::iterator J = I->second.begin(),
+ E = I->second.end(); J != E; ++J)
+ OS << " unsigned Match_" << I->first << "_" << J->first->getName()
+ << "(SelectionDAGNode *N);\n";
+
+ // Output all of the dag reduction methods prototypes...
+ OS << "\n // DAG reduction methods...\n";
+ for (PatternOrganizer::iterator I = ComputableValues.begin(),
+ E = ComputableValues.end(); I != E; ++I)
+ OS << " ReducedValue_" << I->first << " *Reduce_" << I->first
+ << "(SelectionDAGNode *N,\n" << std::string(25+2*I->first.size(), ' ')
+ << "MachineBasicBlock *MBB);\n";
+ OS << " };\n}\n\n";
+
+ OS << "void X86ISel::generateCode() {\n"
+ << " SelectionDAGNode *Root = DAG.getRoot();\n"
+ << " assert(Root->getValueType() == ISD::Void && "
+ "\"Root of DAG produces value??\");\n\n"
+ << " std::cerr << \"\\n\";\n"
+ << " unsigned Cost = Match_Void_Void(Root);\n"
+ << " if (Cost >= ~0U >> 1) {\n"
+ << " std::cerr << \"Match failed!\\n\";\n"
+ << " Root->dump();\n"
+ << " abort();\n"
+ << " }\n\n"
+ << " std::cerr << \"Total DAG Cost: \" << Cost << \"\\n\\n\";\n\n"
+ << " Reduce_Void_Void(Root, 0);\n"
+ << "}\n\n"
+ << "//===" << std::string(70, '-') << "===//\n"
+ << "// Matching methods...\n"
+ << "//\n";
}
+