mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-13 09:33:50 +00:00
Emit the first half of the instruction selector.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@7701 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
249d64a14c
commit
6dafd3921d
@ -317,6 +317,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
|
// InstrSelectorEmitter implementation
|
||||||
//
|
//
|
||||||
@ -432,11 +467,12 @@ Record *InstrSelectorEmitter::InstantiateNonterminal(Pattern *NT,
|
|||||||
Record* &Slot = InstantiatedNTs[std::make_pair(NT, ResultTy)];
|
Record* &Slot = InstantiatedNTs[std::make_pair(NT, ResultTy)];
|
||||||
if (Slot) return Slot;
|
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));
|
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...
|
// Copy the pattern...
|
||||||
Pattern *NewPat = NT->clone(New);
|
Pattern *NewPat = NT->clone(New);
|
||||||
|
|
||||||
@ -457,6 +493,15 @@ Record *InstrSelectorEmitter::InstantiateNonterminal(Pattern *NT,
|
|||||||
return Slot = New;
|
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) {
|
void InstrSelectorEmitter::run(std::ostream &OS) {
|
||||||
// Type-check all of the node types to ensure we "understand" them.
|
// 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.
|
// that they are used in.
|
||||||
InstantiateNonterminals();
|
InstantiateNonterminals();
|
||||||
|
|
||||||
|
// Clear InstantiatedNTs, we don't need it anymore...
|
||||||
|
InstantiatedNTs.clear();
|
||||||
|
|
||||||
std::cerr << "Patterns aquired:\n";
|
std::cerr << "Patterns aquired:\n";
|
||||||
for (std::map<Record*, Pattern*>::iterator I = Patterns.begin(),
|
for (std::map<Record*, Pattern*>::iterator I = Patterns.begin(),
|
||||||
E = Patterns.end(); I != E; ++I)
|
E = Patterns.end(); I != E; ++I)
|
||||||
if (I->second->isResolved())
|
if (I->second->isResolved())
|
||||||
std::cerr << " " << *I->second << "\n";
|
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";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +67,10 @@ public:
|
|||||||
: Operator(o), Type(MVT::Other), Children(c), Value(0) {}
|
: Operator(o), Type(MVT::Other), Children(c), Value(0) {}
|
||||||
TreePatternNode(Init *V) : Operator(0), Type(MVT::Other), Value(V) {}
|
TreePatternNode(Init *V) : Operator(0), Type(MVT::Other), Value(V) {}
|
||||||
|
|
||||||
Record *getOperator() const { return Operator; }
|
Record *getOperator() const {
|
||||||
|
assert(Operator && "This is a leaf node!");
|
||||||
|
return Operator;
|
||||||
|
}
|
||||||
MVT::ValueType getType() const { return Type; }
|
MVT::ValueType getType() const { return Type; }
|
||||||
void setType(MVT::ValueType T) { Type = T; }
|
void setType(MVT::ValueType T) { Type = T; }
|
||||||
|
|
||||||
@ -204,6 +207,36 @@ private:
|
|||||||
std::ostream &operator<<(std::ostream &OS, const Pattern &P);
|
std::ostream &operator<<(std::ostream &OS, const Pattern &P);
|
||||||
|
|
||||||
|
|
||||||
|
/// PatternOrganizer - This class represents all of the patterns which are
|
||||||
|
/// useful for the instruction selector, neatly catagorized in a hierarchical
|
||||||
|
/// structure.
|
||||||
|
struct PatternOrganizer {
|
||||||
|
/// PatternsForNode - The list of patterns which can produce a value of a
|
||||||
|
/// particular slot type, given a particular root node in the tree. All of
|
||||||
|
/// the patterns in this vector produce the same value type and have the same
|
||||||
|
/// root DAG node.
|
||||||
|
typedef std::vector<Pattern*> PatternsForNode;
|
||||||
|
|
||||||
|
/// NodesForSlot - This map keeps track of all of the root DAG nodes which can
|
||||||
|
/// lead to the production of a value for this slot. All of the patterns in
|
||||||
|
/// this data structure produces values of the same slot.
|
||||||
|
typedef std::map<Record*, PatternsForNode> NodesForSlot;
|
||||||
|
|
||||||
|
/// AllPatterns - This data structure contains all patterns in the instruction
|
||||||
|
/// selector.
|
||||||
|
std::map<std::string, NodesForSlot> AllPatterns;
|
||||||
|
|
||||||
|
// Forwarding functions...
|
||||||
|
typedef std::map<std::string, NodesForSlot>::iterator iterator;
|
||||||
|
iterator begin() { return AllPatterns.begin(); }
|
||||||
|
iterator end() { return AllPatterns.end(); }
|
||||||
|
|
||||||
|
|
||||||
|
/// addPattern - Add the specified pattern to the appropriate location in the
|
||||||
|
/// collection.
|
||||||
|
void addPattern(Pattern *P);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/// InstrSelectorEmitter - The top-level class which coordinates construction
|
/// InstrSelectorEmitter - The top-level class which coordinates construction
|
||||||
/// and emission of the instruction selector.
|
/// and emission of the instruction selector.
|
||||||
@ -222,6 +255,13 @@ class InstrSelectorEmitter : public TableGenBackend {
|
|||||||
/// have been instantiated already...
|
/// have been instantiated already...
|
||||||
///
|
///
|
||||||
std::map<std::pair<Pattern*,MVT::ValueType>, Record*> InstantiatedNTs;
|
std::map<std::pair<Pattern*,MVT::ValueType>, Record*> InstantiatedNTs;
|
||||||
|
|
||||||
|
/// ComputableValues - This map indicates which patterns can be used to
|
||||||
|
/// generate a value that is used by the selector. The keys of this map
|
||||||
|
/// implicitly define the values that are used by the selector.
|
||||||
|
///
|
||||||
|
PatternOrganizer ComputableValues;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
InstrSelectorEmitter(RecordKeeper &R) : Records(R) {}
|
InstrSelectorEmitter(RecordKeeper &R) : Records(R) {}
|
||||||
|
|
||||||
@ -269,6 +309,10 @@ private:
|
|||||||
// InstantiateNonterminals - Instantiate any unresolved nonterminals with
|
// InstantiateNonterminals - Instantiate any unresolved nonterminals with
|
||||||
// information from the context that they are used in.
|
// information from the context that they are used in.
|
||||||
void InstantiateNonterminals();
|
void InstantiateNonterminals();
|
||||||
|
|
||||||
|
// CalculateComputableValues - Fill in the ComputableValues map through
|
||||||
|
// analysis of the patterns we are playing with.
|
||||||
|
void CalculateComputableValues();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -317,6 +317,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
|
// InstrSelectorEmitter implementation
|
||||||
//
|
//
|
||||||
@ -432,11 +467,12 @@ Record *InstrSelectorEmitter::InstantiateNonterminal(Pattern *NT,
|
|||||||
Record* &Slot = InstantiatedNTs[std::make_pair(NT, ResultTy)];
|
Record* &Slot = InstantiatedNTs[std::make_pair(NT, ResultTy)];
|
||||||
if (Slot) return Slot;
|
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));
|
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...
|
// Copy the pattern...
|
||||||
Pattern *NewPat = NT->clone(New);
|
Pattern *NewPat = NT->clone(New);
|
||||||
|
|
||||||
@ -457,6 +493,15 @@ Record *InstrSelectorEmitter::InstantiateNonterminal(Pattern *NT,
|
|||||||
return Slot = New;
|
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) {
|
void InstrSelectorEmitter::run(std::ostream &OS) {
|
||||||
// Type-check all of the node types to ensure we "understand" them.
|
// 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.
|
// that they are used in.
|
||||||
InstantiateNonterminals();
|
InstantiateNonterminals();
|
||||||
|
|
||||||
|
// Clear InstantiatedNTs, we don't need it anymore...
|
||||||
|
InstantiatedNTs.clear();
|
||||||
|
|
||||||
std::cerr << "Patterns aquired:\n";
|
std::cerr << "Patterns aquired:\n";
|
||||||
for (std::map<Record*, Pattern*>::iterator I = Patterns.begin(),
|
for (std::map<Record*, Pattern*>::iterator I = Patterns.begin(),
|
||||||
E = Patterns.end(); I != E; ++I)
|
E = Patterns.end(); I != E; ++I)
|
||||||
if (I->second->isResolved())
|
if (I->second->isResolved())
|
||||||
std::cerr << " " << *I->second << "\n";
|
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";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +67,10 @@ public:
|
|||||||
: Operator(o), Type(MVT::Other), Children(c), Value(0) {}
|
: Operator(o), Type(MVT::Other), Children(c), Value(0) {}
|
||||||
TreePatternNode(Init *V) : Operator(0), Type(MVT::Other), Value(V) {}
|
TreePatternNode(Init *V) : Operator(0), Type(MVT::Other), Value(V) {}
|
||||||
|
|
||||||
Record *getOperator() const { return Operator; }
|
Record *getOperator() const {
|
||||||
|
assert(Operator && "This is a leaf node!");
|
||||||
|
return Operator;
|
||||||
|
}
|
||||||
MVT::ValueType getType() const { return Type; }
|
MVT::ValueType getType() const { return Type; }
|
||||||
void setType(MVT::ValueType T) { Type = T; }
|
void setType(MVT::ValueType T) { Type = T; }
|
||||||
|
|
||||||
@ -204,6 +207,36 @@ private:
|
|||||||
std::ostream &operator<<(std::ostream &OS, const Pattern &P);
|
std::ostream &operator<<(std::ostream &OS, const Pattern &P);
|
||||||
|
|
||||||
|
|
||||||
|
/// PatternOrganizer - This class represents all of the patterns which are
|
||||||
|
/// useful for the instruction selector, neatly catagorized in a hierarchical
|
||||||
|
/// structure.
|
||||||
|
struct PatternOrganizer {
|
||||||
|
/// PatternsForNode - The list of patterns which can produce a value of a
|
||||||
|
/// particular slot type, given a particular root node in the tree. All of
|
||||||
|
/// the patterns in this vector produce the same value type and have the same
|
||||||
|
/// root DAG node.
|
||||||
|
typedef std::vector<Pattern*> PatternsForNode;
|
||||||
|
|
||||||
|
/// NodesForSlot - This map keeps track of all of the root DAG nodes which can
|
||||||
|
/// lead to the production of a value for this slot. All of the patterns in
|
||||||
|
/// this data structure produces values of the same slot.
|
||||||
|
typedef std::map<Record*, PatternsForNode> NodesForSlot;
|
||||||
|
|
||||||
|
/// AllPatterns - This data structure contains all patterns in the instruction
|
||||||
|
/// selector.
|
||||||
|
std::map<std::string, NodesForSlot> AllPatterns;
|
||||||
|
|
||||||
|
// Forwarding functions...
|
||||||
|
typedef std::map<std::string, NodesForSlot>::iterator iterator;
|
||||||
|
iterator begin() { return AllPatterns.begin(); }
|
||||||
|
iterator end() { return AllPatterns.end(); }
|
||||||
|
|
||||||
|
|
||||||
|
/// addPattern - Add the specified pattern to the appropriate location in the
|
||||||
|
/// collection.
|
||||||
|
void addPattern(Pattern *P);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/// InstrSelectorEmitter - The top-level class which coordinates construction
|
/// InstrSelectorEmitter - The top-level class which coordinates construction
|
||||||
/// and emission of the instruction selector.
|
/// and emission of the instruction selector.
|
||||||
@ -222,6 +255,13 @@ class InstrSelectorEmitter : public TableGenBackend {
|
|||||||
/// have been instantiated already...
|
/// have been instantiated already...
|
||||||
///
|
///
|
||||||
std::map<std::pair<Pattern*,MVT::ValueType>, Record*> InstantiatedNTs;
|
std::map<std::pair<Pattern*,MVT::ValueType>, Record*> InstantiatedNTs;
|
||||||
|
|
||||||
|
/// ComputableValues - This map indicates which patterns can be used to
|
||||||
|
/// generate a value that is used by the selector. The keys of this map
|
||||||
|
/// implicitly define the values that are used by the selector.
|
||||||
|
///
|
||||||
|
PatternOrganizer ComputableValues;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
InstrSelectorEmitter(RecordKeeper &R) : Records(R) {}
|
InstrSelectorEmitter(RecordKeeper &R) : Records(R) {}
|
||||||
|
|
||||||
@ -269,6 +309,10 @@ private:
|
|||||||
// InstantiateNonterminals - Instantiate any unresolved nonterminals with
|
// InstantiateNonterminals - Instantiate any unresolved nonterminals with
|
||||||
// information from the context that they are used in.
|
// information from the context that they are used in.
|
||||||
void InstantiateNonterminals();
|
void InstantiateNonterminals();
|
||||||
|
|
||||||
|
// CalculateComputableValues - Fill in the ComputableValues map through
|
||||||
|
// analysis of the patterns we are playing with.
|
||||||
|
void CalculateComputableValues();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user