llvm.org GIT mirror llvm / de444af
Implement multiclass inheritance. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@69810 91177308-0d34-0410-b5e6-96231b3b80d8 David Greene 10 years ago
4 changed file(s) with 211 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
103103 as "Instruction".

104104
105105

TableGen multiclasses are groups of abstract records that are

106 instantiated all at once. Each instantiation can result in multiple TableGen
107 definitions.

106 instantiated all at once. Each instantiation can result in multiple
107 TableGen definitions. If a multiclass inherits from another multiclass,
108 the definitions in the sub-multiclass become part of the current
109 multiclass, as if they were declared in the current multiclass.

108110
109111
110112
0 // RUN: tblgen %s | grep {zing = 4} | count 4
1
2 class C1 {
3 int bar = A;
4 string thestr = B;
5 int zing;
6 }
7
8 def T : C1<4, "blah">;
9
10 multiclass t {
11 def S1 : C1 {
12 int foo = 4;
13 let bar = 1;
14 }
15 def S2 : C1;
16 }
17
18 multiclass s : t {
19 def S3 : C1 {
20 int moo = 3;
21 let bar = 1;
22 }
23 def S4 : C1;
24 }
25
26 defm FOO : s<42, 24>;
27
28 def T4 : C1<6, "foo">;
29
30 let zing = 4 in
31 defm BAZ : s<3, 4>;
2424 namespace llvm {
2525 struct MultiClass {
2626 Record Rec; // Placeholder for template args and Name.
27 std::vector DefPrototypes;
27 typedef std::vector RecordVector;
28 RecordVector DefPrototypes;
2829
2930 MultiClass(const std::string &Name, TGLoc Loc) : Rec(Name, Loc) {}
3031 };
3637 SubClassReference() : Rec(0) {}
3738
3839 bool isInvalid() const { return Rec == 0; }
40 };
41
42 struct SubMultiClassReference {
43 TGLoc RefLoc;
44 MultiClass *MC;
45 std::vector TemplateArgs;
46 SubMultiClassReference() : MC(0) {}
47
48 bool isInvalid() const { return MC == 0; }
3949 };
4050
4151 } // end namespace llvm
176186 return false;
177187 }
178188
189 /// AddSubMultiClass - Add SubMultiClass as a subclass to
190 /// CurMultiClass, resolving its template args as SubMultiClass's
191 /// template arguments.
192 bool TGParser::AddSubMultiClass(MultiClass *CurMultiClass, class SubMultiClassReference &SubMultiClass) {
193 MultiClass *SMC = SubMultiClass.MC;
194 Record *CurRec = &CurMultiClass->Rec;
195
196 const std::vector &MCVals = CurMultiClass->Rec.getValues();
197
198 // Add all of the values in the subclass into the current class.
199 const std::vector &SMCVals = SMC->Rec.getValues();
200 for (unsigned i = 0, e = SMCVals.size(); i != e; ++i)
201 if (AddValue(CurRec, SubMultiClass.RefLoc, SMCVals[i]))
202 return true;
203
204 // Add all of the defs in the subclass into the current multiclass.
205 for (MultiClass::RecordVector::const_iterator i = SMC->DefPrototypes.begin(),
206 iend = SMC->DefPrototypes.end();
207 i != iend;
208 ++i) {
209 // Clone the def and add it to the current multiclass
210 Record *NewDef = new Record(**i);
211
212 // Add all of the values in the superclass into the current def.
213 for (unsigned i = 0, e = MCVals.size(); i != e; ++i)
214 if (AddValue(NewDef, SubMultiClass.RefLoc, MCVals[i]))
215 return true;
216
217 CurMultiClass->DefPrototypes.push_back(NewDef);
218 }
219
220 const std::vector &SMCTArgs = SMC->Rec.getTemplateArgs();
221
222 // Ensure that an appropriate number of template arguments are specified.
223 if (SMCTArgs.size() < SubMultiClass.TemplateArgs.size())
224 return Error(SubMultiClass.RefLoc, "More template args specified than expected");
225
226 // Loop over all of the template arguments, setting them to the specified
227 // value or leaving them as the default if necessary.
228 for (unsigned i = 0, e = SMCTArgs.size(); i != e; ++i) {
229 if (i < SubMultiClass.TemplateArgs.size()) {
230 // If a value is specified for this template arg, set it in the superclass now.
231 if (SetValue(CurRec, SubMultiClass.RefLoc, SMCTArgs[i], std::vector(),
232 SubMultiClass.TemplateArgs[i]))
233 return true;
234
235 // Resolve it next.
236 CurRec->resolveReferencesTo(CurRec->getValue(SMCTArgs[i]));
237
238 // Now remove it.
239 CurRec->removeValue(SMCTArgs[i]);
240
241 // If a value is specified for this template arg, set it in the defs now.
242 for (MultiClass::RecordVector::iterator j = CurMultiClass->DefPrototypes.begin(),
243 jend = CurMultiClass->DefPrototypes.end();
244 j != jend;
245 ++j) {
246 Record *Def = *j;
247
248 if (SetValue(Def, SubMultiClass.RefLoc, SMCTArgs[i], std::vector(),
249 SubMultiClass.TemplateArgs[i]))
250 return true;
251
252 // Resolve it next.
253 Def->resolveReferencesTo(Def->getValue(SMCTArgs[i]));
254
255 // Now remove it
256 Def->removeValue(SMCTArgs[i]);
257 }
258 } else if (!CurRec->getValue(SMCTArgs[i])->getValue()->isComplete()) {
259 return Error(SubMultiClass.RefLoc,"Value not specified for template argument #"
260 + utostr(i) + " (" + SMCTArgs[i] + ") of subclass '" +
261 SMC->Rec.getName() + "'!");
262 }
263 }
264
265 return false;
266 }
267
179268 //===----------------------------------------------------------------------===//
180269 // Parser Code
181270 //===----------------------------------------------------------------------===//
222311 return Result;
223312 }
224313
314 /// ParseMultiClassID - Parse and resolve a reference to a multiclass name. This returns
315 /// null on error.
316 ///
317 /// MultiClassID ::= ID
318 ///
319 MultiClass *TGParser::ParseMultiClassID() {
320 if (Lex.getCode() != tgtok::Id) {
321 TokError("expected name for ClassID");
322 return 0;
323 }
324
325 MultiClass *Result = MultiClasses[Lex.getCurStrVal()];
326 if (Result == 0)
327 TokError("Couldn't find class '" + Lex.getCurStrVal() + "'");
328
329 Lex.Lex();
330 return Result;
331 }
332
225333 Record *TGParser::ParseDefmID() {
226334 if (Lex.getCode() != tgtok::Id) {
227335 TokError("expected multiclass name");
281389 }
282390 Lex.Lex();
283391
392 return Result;
393 }
394
395 /// ParseSubMultiClassReference - Parse a reference to a subclass or to a templated
396 /// submulticlass. This returns a SubMultiClassRefTy with a null Record* on error.
397 ///
398 /// SubMultiClassRef ::= MultiClassID
399 /// SubMultiClassRef ::= MultiClassID '<' ValueList '>'
400 ///
401 SubMultiClassReference TGParser::
402 ParseSubMultiClassReference(MultiClass *CurMC) {
403 SubMultiClassReference Result;
404 Result.RefLoc = Lex.getLoc();
405
406 Result.MC = ParseMultiClassID();
407 if (Result.MC == 0) return Result;
408
409 // If there is no template arg list, we're done.
410 if (Lex.getCode() != tgtok::less)
411 return Result;
412 Lex.Lex(); // Eat the '<'
413
414 if (Lex.getCode() == tgtok::greater) {
415 TokError("subclass reference requires a non-empty list of template values");
416 Result.MC = 0;
417 return Result;
418 }
419
420 Result.TemplateArgs = ParseValueList(&CurMC->Rec);
421 if (Result.TemplateArgs.empty()) {
422 Result.MC = 0; // Error parsing value list.
423 return Result;
424 }
425
426 if (Lex.getCode() != tgtok::greater) {
427 TokError("expected '>' in template value list");
428 Result.MC = 0;
429 return Result;
430 }
431 Lex.Lex();
432
284433 return Result;
285434 }
286435
12301379
12311380 /// ParseMultiClass - Parse a multiclass definition.
12321381 ///
1233 /// MultiClassInst ::= MULTICLASS ID TemplateArgList? '{' MultiClassDef+ '}'
1382 /// MultiClassInst ::= MULTICLASS ID TemplateArgList? ':' BaseMultiClassList '{' MultiClassDef+ '}'
12341383 ///
12351384 bool TGParser::ParseMultiClass() {
12361385 assert(Lex.getCode() == tgtok::MultiClass && "Unexpected token");
12501399 if (Lex.getCode() == tgtok::less)
12511400 if (ParseTemplateArgList(0))
12521401 return true;
1402
1403 // If there are submulticlasses, parse them.
1404 if (Lex.getCode() == tgtok::colon) {
1405 Lex.Lex();
1406
1407 // Read all of the submulticlasses.
1408 SubMultiClassReference SubMultiClass = ParseSubMultiClassReference(CurMultiClass);
1409 while (1) {
1410 // Check for error.
1411 if (SubMultiClass.MC == 0) return true;
1412
1413 // Add it.
1414 if (AddSubMultiClass(CurMultiClass, SubMultiClass))
1415 return true;
1416
1417 if (Lex.getCode() != tgtok::comma) break;
1418 Lex.Lex(); // eat ','.
1419 SubMultiClass = ParseSubMultiClassReference(CurMultiClass);
1420 }
1421 }
12531422
12541423 if (Lex.getCode() != tgtok::l_brace)
12551424 return TokError("expected '{' in multiclass definition");
2424 struct Init;
2525 struct MultiClass;
2626 struct SubClassReference;
27 struct SubMultiClassReference;
2728
2829 struct LetRecord {
2930 std::string Name;
4546 /// current value.
4647 MultiClass *CurMultiClass;
4748 public:
48
4949 TGParser(TGSourceMgr &SrcMgr) : Lex(SrcMgr), CurMultiClass(0) {}
5050
5151 void setIncludeDirs(const std::vector &D){Lex.setIncludeDirs(D);}
6666 bool SetValue(Record *TheRec, TGLoc Loc, const std::string &ValName,
6767 const std::vector &BitList, Init *V);
6868 bool AddSubClass(Record *Rec, SubClassReference &SubClass);
69 bool AddSubMultiClass(MultiClass *MV, class SubMultiClassReference &SubMultiClass);
6970
7071 private: // Parser methods.
7172 bool ParseObjectList();
8687 std::string ParseDeclaration(Record *CurRec, bool ParsingTemplateArgs);
8788
8889 SubClassReference ParseSubClassReference(Record *CurRec, bool isDefm);
90 SubMultiClassReference ParseSubMultiClassReference(MultiClass *CurMultiClass);
8991
9092 Init *ParseIDValue(Record *CurRec);
9193 Init *ParseIDValue(Record *CurRec, const std::string &Name, TGLoc NameLoc);
100102 RecTy *ParseType();
101103 std::string ParseObjectName();
102104 Record *ParseClassID();
105 MultiClass *ParseMultiClassID();
103106 Record *ParseDefmID();
104107 };
105108