throw "Unknown DagNodeValType '" + Name + "'!";
}
+
+//===----------------------------------------------------------------------===//
+// TreePatternNode implementation
+//
+
+// updateNodeType - Set the node type of N to VT if VT contains information. If
+// N already contains a conflicting type, then throw an exception
+//
+bool TreePatternNode::updateNodeType(MVT::ValueType VT,
+ const std::string &RecName) {
+ if (VT == MVT::Other || getType() == VT) return false;
+ if (getType() == MVT::Other) {
+ setType(VT);
+ return true;
+ }
+
+ throw "Type inferfence contradiction found for pattern " + RecName;
+}
+
std::ostream &operator<<(std::ostream &OS, const TreePatternNode &N) {
if (N.isLeaf())
return OS << N.getType() << ":" << *N.getValue();
}
void TreePatternNode::dump() const { std::cerr << *this; }
+//===----------------------------------------------------------------------===//
+// Pattern implementation
+//
-/// ProcessNodeTypes - Process all of the node types in the current
-/// RecordKeeper, turning them into the more accessible NodeTypes data
-/// structure.
-///
-void InstrSelectorEmitter::ProcessNodeTypes() {
- std::vector<Record*> Nodes = Records.getAllDerivedDefinitions("DagNode");
- for (unsigned i = 0, e = Nodes.size(); i != e; ++i) {
- Record *Node = Nodes[i];
-
- // Translate the return type...
- NodeType::ArgResultTypes RetTy =
- NodeType::Translate(Node->getValueAsDef("RetType"));
+// Parse the specified DagInit into a TreePattern which we can use.
+//
+Pattern::Pattern(PatternType pty, DagInit *RawPat, Record *TheRec,
+ InstrSelectorEmitter &ise)
+ : PTy(pty), TheRecord(TheRec), ISE(ise) {
- // Translate the arguments...
- ListInit *Args = Node->getValueAsListInit("ArgTypes");
- std::vector<NodeType::ArgResultTypes> ArgTypes;
+ // First, parse the pattern...
+ Tree = ParseTreePattern(RawPat);
+
+ bool MadeChange, AnyUnset;
+ do {
+ MadeChange = false;
+ AnyUnset = InferTypes(Tree, MadeChange);
+ } while ((AnyUnset || MadeChange) && !(AnyUnset && !MadeChange));
+
+ if (PTy == Instruction || PTy == Expander) {
+ // Check to make sure there is not any unset types in the tree pattern...
+ if (AnyUnset) {
+ std::cerr << "In pattern: " << *Tree << "\n";
+ error("Could not infer all types!");
+ }
- for (unsigned a = 0, e = Args->getSize(); a != e; ++a) {
- if (DefInit *DI = dynamic_cast<DefInit*>(Args->getElement(a)))
- ArgTypes.push_back(NodeType::Translate(DI->getDef()));
- else
- throw "In node " + Node->getName() + ", argument is not a Def!";
+ // Check to see if we have a top-level (set) of a register.
+ if (Tree->getOperator()->getName() == "set") {
+ assert(Tree->getChildren().size() == 2 && "Set with != 2 arguments?");
+ if (!Tree->getChild(0)->isLeaf())
+ error("Arg #0 of set should be a register or register class!");
+ DefInit *RegInit = dynamic_cast<DefInit*>(Tree->getChild(0)->getValue());
+ if (RegInit == 0)
+ error("LHS of 'set' expected to be a register or register class!");
+
+ Result = RegInit->getDef();
+ Tree = Tree->getChild(1);
- if (a == 0 && ArgTypes.back() == NodeType::Arg0)
- throw "In node " + Node->getName() + ", arg 0 cannot have type 'arg0'!";
- if (ArgTypes.back() == NodeType::Void)
- throw "In node " + Node->getName() + ", args cannot be void type!";
}
- if (RetTy == NodeType::Arg0 && Args->getSize() == 0)
- throw "In node " + Node->getName() +
- ", invalid return type for nullary node!";
+ }
- // Add the node type mapping now...
- NodeTypes[Node] = NodeType(RetTy, ArgTypes);
- DEBUG(std::cerr << "Got node type '" << Node->getName() << "'\n");
+ Resolved = !AnyUnset;
+}
+
+void Pattern::error(const std::string &Msg) {
+ std::string M = "In ";
+ switch (PTy) {
+ case Nonterminal: M += "nonterminal "; break;
+ case Instruction: M += "instruction "; break;
+ case Expander : M += "expander "; break;
}
+ throw M + TheRecord->getName() + ": " + Msg;
}
static MVT::ValueType getIntrinsicType(Record *R) {
// Check to see if this is a register or a register class...
- const std::vector<Record*> &SuperClasses = R->getSuperClasses();
- for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i)
- if (SuperClasses[i]->getName() == "RegisterClass") {
- return getValueType(R->getValueAsDef("RegType"));
- } else if (SuperClasses[i]->getName() == "Register") {
- std::cerr << "WARNING: Explicit registers not handled yet!\n";
- } else if (SuperClasses[i]->getName() == "Nonterminal") {
- }
- //throw "Error: Unknown value used: " + R->getName();
+ if (R->isSubClassOf("RegisterClass")) {
+ return getValueType(R->getValueAsDef("RegType"));
+ } 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;
+ }
- return MVT::Other;
+ throw "Error: Unknown value used: " + R->getName();
}
-// Parse the specified DagInit into a TreePattern which we can use.
-//
-TreePatternNode *InstrSelectorEmitter::ParseTreePattern(DagInit *DI,
- const std::string &RecName) {
+TreePatternNode *Pattern::ParseTreePattern(DagInit *DI) {
Record *Operator = DI->getNodeType();
- if (!NodeTypes.count(Operator))
- throw "Illegal node for instruction pattern: '" + Operator->getName() +"'!";
+ if (!ISE.getNodeTypes().count(Operator))
+ error("Unrecognized node '" + Operator->getName() + "'!");
const std::vector<Init*> &Args = DI->getArgs();
std::vector<TreePatternNode*> Children;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
Init *Arg = Args[i];
if (DagInit *DI = dynamic_cast<DagInit*>(Arg)) {
- Children.push_back(ParseTreePattern(DI, RecName));
+ Children.push_back(ParseTreePattern(DI));
} else if (DefInit *DI = dynamic_cast<DefInit*>(Arg)) {
Children.push_back(new TreePatternNode(DI));
// If it's a regclass or something else known, set the type.
Children.back()->setType(getIntrinsicType(DI->getDef()));
} else {
Arg->dump();
- throw "Unknown value for tree pattern in '" + RecName + "'!";
+ error("Unknown leaf value for tree pattern!");
}
}
return new TreePatternNode(Operator, Children);
}
-// UpdateNodeType - Set the node type of N to VT if VT contains information. If
-// N already contains a conflicting type, then throw an exception
-//
-static bool UpdateNodeType(TreePatternNode *N, MVT::ValueType VT,
- const std::string &RecName) {
- if (VT == MVT::Other || N->getType() == VT) return false;
-
- if (N->getType() == MVT::Other) {
- N->setType(VT);
- return true;
- }
-
- throw "Type inferfence contradiction found for pattern " + RecName;
-}
// InferTypes - Perform type inference on the tree, returning true if there
// are any remaining untyped nodes and setting MadeChange if any changes were
// made.
-bool InstrSelectorEmitter::InferTypes(TreePatternNode *N,
- const std::string &RecName,
- bool &MadeChange) {
+bool Pattern::InferTypes(TreePatternNode *N, bool &MadeChange) {
if (N->isLeaf()) return N->getType() == MVT::Other;
bool AnyUnset = false;
Record *Operator = N->getOperator();
- assert(NodeTypes.count(Operator) && "No node info for node!");
- const NodeType &NT = NodeTypes[Operator];
+ assert(ISE.getNodeTypes().count(Operator) && "No node info for node!");
+ const NodeType &NT = ISE.getNodeTypes()[Operator];
// Check to see if we can infer anything about the argument types from the
// return types...
const std::vector<TreePatternNode*> &Children = N->getChildren();
if (Children.size() != NT.ArgTypes.size())
- throw "In record " + RecName + " incorrect number of children for " +
- Operator->getName() + " node!";
+ error("Incorrect number of children for " + Operator->getName() + " node!");
for (unsigned i = 0, e = Children.size(); i != e; ++i) {
- AnyUnset |= InferTypes(Children[i], RecName, MadeChange);
-
+ TreePatternNode *Child = Children[i];
+ AnyUnset |= InferTypes(Child, MadeChange);
switch (NT.ArgTypes[i]) {
case NodeType::Arg0:
- MadeChange |=UpdateNodeType(Children[i], Children[0]->getType(), RecName);
+ MadeChange |= Child->updateNodeType(Children[0]->getType(),
+ TheRecord->getName());
break;
case NodeType::Val:
- if (Children[i]->getType() == MVT::isVoid)
- throw "In pattern for " + RecName + " should not get a void node!";
+ if (Child->getType() == MVT::isVoid)
+ error("Inferred a void node in an illegal place!");
+ break;
+ case NodeType::Ptr:
+ MadeChange |= Child->updateNodeType(ISE.getTarget().getPointerType(),
+ TheRecord->getName());
break;
- case NodeType::Ptr: // FIXME
default: assert(0 && "Invalid argument ArgType!");
}
}
// See if we can infer anything about the return type now...
switch (NT.ResultType) {
case NodeType::Void:
- MadeChange |= UpdateNodeType(N, MVT::isVoid, RecName);
+ MadeChange |= N->updateNodeType(MVT::isVoid, TheRecord->getName());
break;
case NodeType::Arg0:
- MadeChange |= UpdateNodeType(N, Children[0]->getType(), RecName);
+ MadeChange |= N->updateNodeType(Children[0]->getType(),
+ TheRecord->getName());
break;
- case NodeType::Ptr: // FIXME: get from target
+ case NodeType::Ptr:
+ MadeChange |= N->updateNodeType(ISE.getTarget().getPointerType(),
+ TheRecord->getName());
+ break;
case NodeType::Val:
+ if (N->getType() == MVT::isVoid)
+ error("Inferred a void node in an illegal place!");
+ break;
+ default:
assert(0 && "Unhandled type constraint!");
break;
}
return AnyUnset | N->getType() == MVT::Other;
}
+std::ostream &operator<<(std::ostream &OS, const Pattern &P) {
+ switch (P.getPatternType()) {
+ case Pattern::Nonterminal: OS << "Nonterminal pattern "; break;
+ case Pattern::Instruction: OS << "Instruction pattern "; break;
+ case Pattern::Expander: OS << "Expander pattern "; break;
+ }
+
+ OS << P.getRecord()->getName() << ":\t";
+
+ if (Record *Result = P.getResult())
+ OS << Result->getName() << " = ";
+ OS << *P.getTree();
-// ReadAndCheckPattern - Parse the specified DagInit into a pattern and then
-// perform full type inference.
+ if (!P.isResolved())
+ OS << " [not completely resolved]";
+ return OS;
+}
+
+
+//===----------------------------------------------------------------------===//
+// InstrSelectorEmitter implementation
//
-TreePatternNode *InstrSelectorEmitter::ReadAndCheckPattern(DagInit *DI,
- const std::string &RecName) {
- // First, parse the pattern...
- TreePatternNode *Pattern = ParseTreePattern(DI, RecName);
-
- bool MadeChange, AnyUnset;
- do {
- MadeChange = false;
- AnyUnset = InferTypes(Pattern, RecName, MadeChange);
- if (AnyUnset && !MadeChange) {
- std::cerr << "In pattern: " << *Pattern << "\n";
- throw "Cannot infer types for " + RecName;
+
+/// ProcessNodeTypes - Process all of the node types in the current
+/// RecordKeeper, turning them into the more accessible NodeTypes data
+/// structure.
+///
+void InstrSelectorEmitter::ProcessNodeTypes() {
+ std::vector<Record*> Nodes = Records.getAllDerivedDefinitions("DagNode");
+ DEBUG(std::cerr << "Getting node types: ");
+ for (unsigned i = 0, e = Nodes.size(); i != e; ++i) {
+ Record *Node = Nodes[i];
+
+ // Translate the return type...
+ NodeType::ArgResultTypes RetTy =
+ NodeType::Translate(Node->getValueAsDef("RetType"));
+
+ // Translate the arguments...
+ ListInit *Args = Node->getValueAsListInit("ArgTypes");
+ std::vector<NodeType::ArgResultTypes> ArgTypes;
+
+ for (unsigned a = 0, e = Args->getSize(); a != e; ++a) {
+ if (DefInit *DI = dynamic_cast<DefInit*>(Args->getElement(a)))
+ ArgTypes.push_back(NodeType::Translate(DI->getDef()));
+ else
+ throw "In node " + Node->getName() + ", argument is not a Def!";
+
+ if (a == 0 && ArgTypes.back() == NodeType::Arg0)
+ throw "In node " + Node->getName() + ", arg 0 cannot have type 'arg0'!";
+ if (ArgTypes.back() == NodeType::Void)
+ throw "In node " + Node->getName() + ", args cannot be void type!";
}
- } while (AnyUnset || MadeChange);
+ if (RetTy == NodeType::Arg0 && Args->getSize() == 0)
+ throw "In node " + Node->getName() +
+ ", invalid return type for nullary node!";
- return Pattern;
+ // Add the node type mapping now...
+ NodeTypes[Node] = NodeType(RetTy, ArgTypes);
+ DEBUG(std::cerr << Node->getName() << ", ");
+ }
+ DEBUG(std::cerr << "DONE!\n");
}
+// ProcessNonTerminals - Read in all nonterminals and incorporate them into
+// our pattern database.
+void InstrSelectorEmitter::ProcessNonterminals() {
+ std::vector<Record*> NTs = Records.getAllDerivedDefinitions("Nonterminal");
+ for (unsigned i = 0, e = NTs.size(); i != e; ++i) {
+ DagInit *DI = NTs[i]->getValueAsDag("Pattern");
+
+ Pattern *P = new Pattern(Pattern::Nonterminal, DI, NTs[i], *this);
+
+
+ DEBUG(std::cerr << "Parsed " << *P << "\n");
+ }
+}
/// ProcessInstructionPatterns - Read in all subclasses of Instruction, and
for (unsigned i = 0, e = Insts.size(); i != e; ++i) {
Record *Inst = Insts[i];
if (DagInit *DI = dynamic_cast<DagInit*>(Inst->getValueInit("Pattern"))) {
- TreePatternNode *Pattern = ReadAndCheckPattern(DI, Inst->getName());
+ Pattern *P = new Pattern(Pattern::Instruction, DI, Inst, *this);
-
- DEBUG(std::cerr << "Parsed inst pattern " << Inst->getName() << "\t= "
- << *Pattern << "\n");
+ DEBUG(std::cerr << "Parsed " << *P << "\n");
}
}
}
+/// ProcessExpanderPatterns - Read in all expander patterns...
+///
+void InstrSelectorEmitter::ProcessExpanderPatterns() {
+ std::vector<Record*> Expanders = Records.getAllDerivedDefinitions("Expander");
+ for (unsigned i = 0, e = Expanders.size(); i != e; ++i) {
+ Record *Expander = Expanders[i];
+ DagInit *DI = Expanders[i]->getValueAsDag("Pattern");
+
+ Pattern *P = new Pattern(Pattern::Expander, DI, Expanders[i], *this);
+
+ DEBUG(std::cerr << "Parsed " << *P << "\n");
+ }
+}
+
void InstrSelectorEmitter::run(std::ostream &OS) {
// Type-check all of the node types to ensure we "understand" them.
ProcessNodeTypes();
// Read in all of the nonterminals...
+ ProcessNonterminals();
// Read all of the instruction patterns in...
ProcessInstructionPatterns();
// Read all of the Expander patterns in...
-
+ ProcessExpanderPatterns();
}