summaryrefslogtreecommitdiff
path: root/support/tools
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2003-08-07 21:02:56 +0000
committerChris Lattner <sabre@nondot.org>2003-08-07 21:02:56 +0000
commit5709e512b19b9b97f3011197bda04ab8e1fe191b (patch)
treeee98cc73c09a9794ef52243b342c57966455b1f5 /support/tools
parentee858d2a8357e6773553fa11f3502f72a0372f06 (diff)
downloadllvm-5709e512b19b9b97f3011197bda04ab8e1fe191b.tar.gz
llvm-5709e512b19b9b97f3011197bda04ab8e1fe191b.tar.bz2
llvm-5709e512b19b9b97f3011197bda04ab8e1fe191b.tar.xz
Implement type-inference/checking for non-terminal references
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@7686 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'support/tools')
-rw-r--r--support/tools/TableGen/InstrSelectorEmitter.cpp53
-rw-r--r--support/tools/TableGen/InstrSelectorEmitter.h18
2 files changed, 53 insertions, 18 deletions
diff --git a/support/tools/TableGen/InstrSelectorEmitter.cpp b/support/tools/TableGen/InstrSelectorEmitter.cpp
index d7d91f03b9..250c8975c1 100644
--- a/support/tools/TableGen/InstrSelectorEmitter.cpp
+++ b/support/tools/TableGen/InstrSelectorEmitter.cpp
@@ -99,7 +99,7 @@ Pattern::Pattern(PatternType pty, DagInit *RawPat, Record *TheRec,
Resolved = !AnyUnset;
}
-void Pattern::error(const std::string &Msg) {
+void Pattern::error(const std::string &Msg) const {
std::string M = "In ";
switch (PTy) {
case Nonterminal: M += "nonterminal "; break;
@@ -109,17 +109,19 @@ void Pattern::error(const std::string &Msg) {
throw M + TheRecord->getName() + ": " + Msg;
}
-static MVT::ValueType getIntrinsicType(Record *R) {
+/// getIntrinsicType - Check to see if the specified record has an intrinsic
+/// type which should be applied to it. This infer the type of register
+/// references from the register file information, for example.
+///
+MVT::ValueType Pattern::getIntrinsicType(Record *R) const {
// Check to see if this is a register or a register class...
- if (R->isSubClassOf("RegisterClass")) {
+ if (R->isSubClassOf("RegisterClass"))
return getValueType(R->getValueAsDef("RegType"));
- } else if (R->isSubClassOf("Register")) {
+ else if (R->isSubClassOf("Nonterminal"))
+ return ISE.ReadNonterminal(R)->getTree()->getType();
+ else if (R->isSubClassOf("Register")) {
std::cerr << "WARNING: Explicit registers not handled yet!\n";
return MVT::Other;
- } else if (R->isSubClassOf("Nonterminal")) {
- //std::cerr << "Warning nonterminal type not handled yet:" << R->getName()
- // << "\n";
- return MVT::Other;
}
throw "Error: Unknown value used: " + R->getName();
@@ -238,6 +240,15 @@ bool Pattern::InferTypes(TreePatternNode *N, bool &MadeChange) {
return AnyUnset | N->getType() == MVT::Other;
}
+/// InstantiateNonterminalsReferenced - If this pattern refers to any
+/// nonterminals which are not themselves completely resolved, clone the
+/// nonterminal and resolve it with the using context we provide.
+///
+void Pattern::InstantiateNonterminalsReferenced() {
+
+}
+
+
std::ostream &operator<<(std::ostream &OS, const Pattern &P) {
switch (P.getPatternType()) {
case Pattern::Nonterminal: OS << "Nonterminal pattern "; break;
@@ -300,16 +311,23 @@ void InstrSelectorEmitter::ReadNodeTypes() {
DEBUG(std::cerr << "DONE!\n");
}
+Pattern *InstrSelectorEmitter::ReadNonterminal(Record *R) {
+ Pattern *&P = Patterns[R];
+ if (P) return P; // Don't reread it!
+
+ DagInit *DI = R->getValueAsDag("Pattern");
+ P = new Pattern(Pattern::Nonterminal, DI, R, *this);
+ DEBUG(std::cerr << "Parsed " << *P << "\n");
+ return P;
+}
+
+
// ReadNonTerminals - Read in all nonterminals and incorporate them into our
// pattern database.
void InstrSelectorEmitter::ReadNonterminals() {
std::vector<Record*> NTs = Records.getAllDerivedDefinitions("Nonterminal");
- for (unsigned i = 0, e = NTs.size(); i != e; ++i) {
- DagInit *DI = NTs[i]->getValueAsDag("Pattern");
-
- Patterns[NTs[i]] = new Pattern(Pattern::Nonterminal, DI, NTs[i], *this);
- DEBUG(std::cerr << "Parsed " << *Patterns[NTs[i]] << "\n");
- }
+ for (unsigned i = 0, e = NTs.size(); i != e; ++i)
+ ReadNonterminal(NTs[i]);
}
@@ -342,11 +360,12 @@ void InstrSelectorEmitter::ReadExpanderPatterns() {
// InstantiateNonterminals - Instantiate any unresolved nonterminals with
// information from the context that they are used in.
+//
void InstrSelectorEmitter::InstantiateNonterminals() {
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())
+ I->second->InstantiateNonterminalsReferenced();
}
diff --git a/support/tools/TableGen/InstrSelectorEmitter.h b/support/tools/TableGen/InstrSelectorEmitter.h
index 8a8734b934..e8c8fad33f 100644
--- a/support/tools/TableGen/InstrSelectorEmitter.h
+++ b/support/tools/TableGen/InstrSelectorEmitter.h
@@ -162,10 +162,15 @@ public:
bool isResolved() const { return Resolved; }
+ /// InstantiateNonterminalsReferenced - If this pattern refers to any
+ /// nonterminals which are not themselves completely resolved, clone the
+ /// nonterminal and resolve it with the using context we provide.
+ void InstantiateNonterminalsReferenced();
private:
+ MVT::ValueType getIntrinsicType(Record *R) const;
TreePatternNode *ParseTreePattern(DagInit *DI);
bool InferTypes(TreePatternNode *N, bool &MadeChange);
- void error(const std::string &Msg);
+ void error(const std::string &Msg) const;
};
std::ostream &operator<<(std::ostream &OS, const Pattern &P);
@@ -193,6 +198,17 @@ public:
const CodeGenTarget &getTarget() const { return Target; }
std::map<Record*, NodeType> &getNodeTypes() { return NodeTypes; }
+ /// getPattern - return the pattern corresponding to the specified record, or
+ /// null if there is none.
+ Pattern *getPattern(Record *R) const {
+ std::map<Record*, Pattern*>::const_iterator I = Patterns.find(R);
+ return I != Patterns.end() ? I->second : 0;
+ }
+
+ /// ReadNonterminal - This method parses the specified record as a
+ /// nonterminal, but only if it hasn't been read in already.
+ Pattern *ReadNonterminal(Record *R);
+
private:
// ReadNodeTypes - Read in all of the node types in the current RecordKeeper,
// turning them into the more accessible NodeTypes data structure.