blob: a2bd08c7948c996ff9e734861aa42746769ad0b4 [file] [log] [blame]
Chris Lattnerfaca5ab2003-08-06 05:42:05 +00001//===- InstrInfoEmitter.cpp - Generate a Instruction Set Desc. ------------===//
2//
3// This tablegen backend is responsible for emitting a description of the target
4// instruction set for the code generator.
5//
6//===----------------------------------------------------------------------===//
7
8#include "InstrSelectorEmitter.h"
Chris Lattner018c9e42003-08-07 05:40:14 +00009#include "CodeGenWrappers.h"
Chris Lattnerfaca5ab2003-08-06 05:42:05 +000010#include "Record.h"
Chris Lattner018c9e42003-08-07 05:40:14 +000011#include "Support/Debug.h"
Chris Lattnerfaca5ab2003-08-06 05:42:05 +000012
13NodeType::ArgResultTypes NodeType::Translate(Record *R) {
14 const std::string &Name = R->getName();
Chris Lattner38aa5422003-08-06 21:47:14 +000015 if (Name == "DNVT_void") return Void;
16 if (Name == "DNVT_val" ) return Val;
17 if (Name == "DNVT_arg0") return Arg0;
18 if (Name == "DNVT_ptr" ) return Ptr;
19 throw "Unknown DagNodeValType '" + Name + "'!";
Chris Lattnerfaca5ab2003-08-06 05:42:05 +000020}
21
Chris Lattner018c9e42003-08-07 05:40:14 +000022std::ostream &operator<<(std::ostream &OS, const TreePatternNode &N) {
23 if (N.isLeaf())
24 return OS << N.getType() << ":" << *N.getValue();
25 OS << "(" << N.getType() << ":";
26 OS << N.getOperator()->getName();
27
28 const std::vector<TreePatternNode*> &Children = N.getChildren();
29 if (!Children.empty()) {
30 OS << " " << *Children[0];
31 for (unsigned i = 1, e = Children.size(); i != e; ++i)
32 OS << ", " << *Children[i];
33 }
34 return OS << ")";
35}
36void TreePatternNode::dump() const { std::cerr << *this; }
37
Chris Lattnerfaca5ab2003-08-06 05:42:05 +000038
39/// ProcessNodeTypes - Process all of the node types in the current
40/// RecordKeeper, turning them into the more accessible NodeTypes data
41/// structure.
42///
43void InstrSelectorEmitter::ProcessNodeTypes() {
44 std::vector<Record*> Nodes = Records.getAllDerivedDefinitions("DagNode");
Chris Lattnerfaca5ab2003-08-06 05:42:05 +000045 for (unsigned i = 0, e = Nodes.size(); i != e; ++i) {
46 Record *Node = Nodes[i];
47
48 // Translate the return type...
49 NodeType::ArgResultTypes RetTy =
50 NodeType::Translate(Node->getValueAsDef("RetType"));
51
52 // Translate the arguments...
53 ListInit *Args = Node->getValueAsListInit("ArgTypes");
54 std::vector<NodeType::ArgResultTypes> ArgTypes;
55
Chris Lattner2787d1a2003-08-06 06:16:35 +000056 for (unsigned a = 0, e = Args->getSize(); a != e; ++a) {
Chris Lattnerfaca5ab2003-08-06 05:42:05 +000057 if (DefInit *DI = dynamic_cast<DefInit*>(Args->getElement(a)))
58 ArgTypes.push_back(NodeType::Translate(DI->getDef()));
59 else
60 throw "In node " + Node->getName() + ", argument is not a Def!";
61
Chris Lattner2787d1a2003-08-06 06:16:35 +000062 if (a == 0 && ArgTypes.back() == NodeType::Arg0)
63 throw "In node " + Node->getName() + ", arg 0 cannot have type 'arg0'!";
64 if (ArgTypes.back() == NodeType::Void)
65 throw "In node " + Node->getName() + ", args cannot be void type!";
66 }
67 if (RetTy == NodeType::Arg0 && Args->getSize() == 0)
68 throw "In node " + Node->getName() +
69 ", invalid return type for nullary node!";
70
Chris Lattnerfaca5ab2003-08-06 05:42:05 +000071 // Add the node type mapping now...
72 NodeTypes[Node] = NodeType(RetTy, ArgTypes);
Chris Lattner018c9e42003-08-07 05:40:14 +000073 DEBUG(std::cerr << "Got node type '" << Node->getName() << "'\n");
74 }
Chris Lattnerfaca5ab2003-08-06 05:42:05 +000075}
76
Chris Lattner018c9e42003-08-07 05:40:14 +000077static MVT::ValueType getIntrinsicType(Record *R) {
78 // Check to see if this is a register or a register class...
79 const std::vector<Record*> &SuperClasses = R->getSuperClasses();
80 for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i)
81 if (SuperClasses[i]->getName() == "RegisterClass") {
82 return getValueType(R->getValueAsDef("RegType"));
83 } else if (SuperClasses[i]->getName() == "Register") {
84 std::cerr << "WARNING: Explicit registers not handled yet!\n";
85 } else if (SuperClasses[i]->getName() == "Nonterminal") {
86 }
87 //throw "Error: Unknown value used: " + R->getName();
88
89 return MVT::Other;
90}
91
92// Parse the specified DagInit into a TreePattern which we can use.
93//
94TreePatternNode *InstrSelectorEmitter::ParseTreePattern(DagInit *DI,
95 const std::string &RecName) {
96 Record *Operator = DI->getNodeType();
97
98 if (!NodeTypes.count(Operator))
99 throw "Illegal node for instruction pattern: '" + Operator->getName() +"'!";
100
101 const std::vector<Init*> &Args = DI->getArgs();
102 std::vector<TreePatternNode*> Children;
103
104 for (unsigned i = 0, e = Args.size(); i != e; ++i) {
105 Init *Arg = Args[i];
106 if (DagInit *DI = dynamic_cast<DagInit*>(Arg)) {
107 Children.push_back(ParseTreePattern(DI, RecName));
108 } else if (DefInit *DI = dynamic_cast<DefInit*>(Arg)) {
109 Children.push_back(new TreePatternNode(DI));
110 // If it's a regclass or something else known, set the type.
111 Children.back()->setType(getIntrinsicType(DI->getDef()));
112 } else {
113 Arg->dump();
114 throw "Unknown value for tree pattern in '" + RecName + "'!";
115 }
116 }
117
118 return new TreePatternNode(Operator, Children);
119}
120
121// UpdateNodeType - Set the node type of N to VT if VT contains information. If
122// N already contains a conflicting type, then throw an exception
123//
124static bool UpdateNodeType(TreePatternNode *N, MVT::ValueType VT,
125 const std::string &RecName) {
126 if (VT == MVT::Other || N->getType() == VT) return false;
127
128 if (N->getType() == MVT::Other) {
129 N->setType(VT);
130 return true;
131 }
132
133 throw "Type inferfence contradiction found for pattern " + RecName;
134}
135
136// InferTypes - Perform type inference on the tree, returning true if there
137// are any remaining untyped nodes and setting MadeChange if any changes were
138// made.
139bool InstrSelectorEmitter::InferTypes(TreePatternNode *N,
140 const std::string &RecName,
141 bool &MadeChange) {
142 if (N->isLeaf()) return N->getType() == MVT::Other;
143
144 bool AnyUnset = false;
145 Record *Operator = N->getOperator();
146 assert(NodeTypes.count(Operator) && "No node info for node!");
147 const NodeType &NT = NodeTypes[Operator];
148
149 // Check to see if we can infer anything about the argument types from the
150 // return types...
151 const std::vector<TreePatternNode*> &Children = N->getChildren();
152 if (Children.size() != NT.ArgTypes.size())
153 throw "In record " + RecName + " incorrect number of children for " +
154 Operator->getName() + " node!";
155
156 for (unsigned i = 0, e = Children.size(); i != e; ++i) {
157 AnyUnset |= InferTypes(Children[i], RecName, MadeChange);
158
159
160 switch (NT.ArgTypes[i]) {
161 case NodeType::Arg0:
162 MadeChange |=UpdateNodeType(Children[i], Children[0]->getType(), RecName);
163 break;
164 case NodeType::Val:
165 if (Children[i]->getType() == MVT::isVoid)
166 throw "In pattern for " + RecName + " should not get a void node!";
167 break;
168 case NodeType::Ptr: // FIXME
169 default: assert(0 && "Invalid argument ArgType!");
170 }
171 }
172
173 // See if we can infer anything about the return type now...
174 switch (NT.ResultType) {
175 case NodeType::Void:
176 MadeChange |= UpdateNodeType(N, MVT::isVoid, RecName);
177 break;
178 case NodeType::Arg0:
179 MadeChange |= UpdateNodeType(N, Children[0]->getType(), RecName);
180 break;
181
182 case NodeType::Ptr: // FIXME: get from target
183 case NodeType::Val:
184 assert(0 && "Unhandled type constraint!");
185 break;
186 }
187
188 return AnyUnset | N->getType() == MVT::Other;
189}
190
191
192// ReadAndCheckPattern - Parse the specified DagInit into a pattern and then
193// perform full type inference.
194//
195TreePatternNode *InstrSelectorEmitter::ReadAndCheckPattern(DagInit *DI,
196 const std::string &RecName) {
197 // First, parse the pattern...
198 TreePatternNode *Pattern = ParseTreePattern(DI, RecName);
199
200 bool MadeChange, AnyUnset;
201 do {
202 MadeChange = false;
203 AnyUnset = InferTypes(Pattern, RecName, MadeChange);
204 if (AnyUnset && !MadeChange) {
205 std::cerr << "In pattern: " << *Pattern << "\n";
206 throw "Cannot infer types for " + RecName;
207 }
208 } while (AnyUnset || MadeChange);
209
210 return Pattern;
211}
212
213
214
Chris Lattner2787d1a2003-08-06 06:16:35 +0000215/// ProcessInstructionPatterns - Read in all subclasses of Instruction, and
216/// process those with a useful Pattern field.
217///
218void InstrSelectorEmitter::ProcessInstructionPatterns() {
219 std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
220 for (unsigned i = 0, e = Insts.size(); i != e; ++i) {
221 Record *Inst = Insts[i];
Chris Lattner018c9e42003-08-07 05:40:14 +0000222 if (DagInit *DI = dynamic_cast<DagInit*>(Inst->getValueInit("Pattern"))) {
223 TreePatternNode *Pattern = ReadAndCheckPattern(DI, Inst->getName());
Chris Lattner2787d1a2003-08-06 06:16:35 +0000224
Chris Lattner018c9e42003-08-07 05:40:14 +0000225
226 DEBUG(std::cerr << "Parsed inst pattern " << Inst->getName() << "\t= "
227 << *Pattern << "\n");
Chris Lattner2787d1a2003-08-06 06:16:35 +0000228 }
229 }
230}
231
232
Chris Lattnerfaca5ab2003-08-06 05:42:05 +0000233void InstrSelectorEmitter::run(std::ostream &OS) {
234 // Type-check all of the node types to ensure we "understand" them.
235 ProcessNodeTypes();
236
Chris Lattner018c9e42003-08-07 05:40:14 +0000237 // Read in all of the nonterminals...
238
Chris Lattner2787d1a2003-08-06 06:16:35 +0000239 // Read all of the instruction patterns in...
240 ProcessInstructionPatterns();
241
242 // Read all of the Expander patterns in...
Chris Lattnerfaca5ab2003-08-06 05:42:05 +0000243
244}