llvm.org GIT mirror llvm / 9f2ffce
TableGen: Allow foreach in multiclass to depend on template args Summary: This also allows inner foreach loops to have a list that depends on the iteration variable of an outer foreach loop. The test cases show some very simple examples of how this can be used. This was perhaps the last remaining major non-orthogonality in the TableGen frontend. Change-Id: I79b92d41a5c0e7c03cc8af4000c5e1bda5ef464d Reviewers: tra, simon_tatham, craig.topper, MartinO, arsenm Subscribers: wdng, llvm-commits Differential Revision: https://reviews.llvm.org/D47431 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@335221 91177308-0d34-0410-b5e6-96231b3b80d8 Nicolai Haehnle 1 year, 3 months ago
6 changed file(s) with 372 addition(s) and 184 deletion(s). Raw diff Collapse all Expand all
15951595
15961596 raw_ostream &operator<<(raw_ostream &OS, const Record &R);
15971597
1598 struct MultiClass {
1599 Record Rec; // Placeholder for template args and Name.
1600 using RecordVector = std::vector>;
1601 RecordVector DefPrototypes;
1602
1603 void dump() const;
1604
1605 MultiClass(StringRef Name, SMLoc Loc, RecordKeeper &Records) :
1606 Rec(Name, Loc, Records) {}
1607 };
1608
16091598 class RecordKeeper {
16101599 friend class RecordRecTy;
16111600 using RecordMap = std::map>;
17751764
17761765 raw_ostream &operator<<(raw_ostream &OS, const RecordKeeper &RK);
17771766
1778 /// Return an Init with a qualifier prefix referring
1779 /// to CurRec's name.
1780 Init *QualifyName(Record &CurRec, MultiClass *CurMultiClass,
1781 Init *Name, StringRef Scoper);
1782
17831767 //===----------------------------------------------------------------------===//
17841768 // Resolvers
17851769 //===----------------------------------------------------------------------===//
21302130 }
21312131
21322132 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2133 LLVM_DUMP_METHOD void MultiClass::dump() const {
2134 errs() << "Record:\n";
2135 Rec.dump();
2136
2137 errs() << "Defs:\n";
2138 for (const auto &Proto : DefPrototypes)
2139 Proto->dump();
2140 }
2141
21422133 LLVM_DUMP_METHOD void RecordKeeper::dump() const { errs() << *this; }
21432134 #endif
21442135
21712162 Defs.push_back(D.second.get());
21722163
21732164 return Defs;
2174 }
2175
2176 Init *llvm::QualifyName(Record &CurRec, MultiClass *CurMultiClass,
2177 Init *Name, StringRef Scoper) {
2178 Init *NewName =
2179 BinOpInit::getStrConcat(CurRec.getNameInit(), StringInit::get(Scoper));
2180 NewName = BinOpInit::getStrConcat(NewName, Name);
2181 if (CurMultiClass && Scoper != "::") {
2182 Init *Prefix = BinOpInit::getStrConcat(CurMultiClass->Rec.getNameInit(),
2183 StringInit::get("::"));
2184 NewName = BinOpInit::getStrConcat(Prefix, NewName);
2185 }
2186
2187 if (BinOpInit *BinOp = dyn_cast(NewName))
2188 NewName = BinOp->Fold(&CurRec);
2189 return NewName;
21902165 }
21912166
21922167 Init *MapResolver::resolve(Init *VarName) {
109109 }
110110 }
111111
112 /// Return an Init with a qualifier prefix referring
113 /// to CurRec's name.
114 static Init *QualifyName(Record &CurRec, MultiClass *CurMultiClass,
115 Init *Name, StringRef Scoper) {
116 Init *NewName =
117 BinOpInit::getStrConcat(CurRec.getNameInit(), StringInit::get(Scoper));
118 NewName = BinOpInit::getStrConcat(NewName, Name);
119 if (CurMultiClass && Scoper != "::") {
120 Init *Prefix = BinOpInit::getStrConcat(CurMultiClass->Rec.getNameInit(),
121 StringInit::get("::"));
122 NewName = BinOpInit::getStrConcat(Prefix, NewName);
123 }
124
125 if (BinOpInit *BinOp = dyn_cast(NewName))
126 NewName = BinOp->Fold(&CurRec);
127 return NewName;
128 }
129
112130 /// Return the qualified version of the implicit 'NAME' template argument.
113131 static Init *QualifiedNameOfImplicitName(Record &Rec,
114132 MultiClass *MC = nullptr) {
270288 return false;
271289 }
272290
291 bool TGParser::AddSubClass(RecordsEntry &Entry, SubClassReference &SubClass) {
292 if (Entry.Rec)
293 return AddSubClass(Entry.Rec.get(), SubClass);
294
295 for (auto &E : Entry.Loop->Entries) {
296 if (AddSubClass(E, SubClass))
297 return true;
298 }
299
300 return false;
301 }
302
273303 /// AddSubMultiClass - Add SubMultiClass as a subclass to
274304 /// CurMC, resolving its template args as SubMultiClass's
275305 /// template arguments.
284314
285315 // Prepare the mapping of template argument name to value, filling in default
286316 // values if necessary.
287 SmallVector, 8> TemplateArgs;
317 SubstStack TemplateArgs;
288318 for (unsigned i = 0, e = SMCTArgs.size(); i != e; ++i) {
289319 if (i < SubMultiClass.TemplateArgs.size()) {
290320 TemplateArgs.emplace_back(SMCTArgs[i], SubMultiClass.TemplateArgs[i]);
306336 VarInit::get(QualifiedNameOfImplicitName(CurMC), StringRecTy::get()));
307337
308338 // Add all of the defs in the subclass into the current multiclass.
309 for (const std::unique_ptr &Rec : SMC->DefPrototypes) {
310 auto NewDef = make_unique(*Rec);
311
312 MapResolver R(NewDef.get());
313 for (const auto &TArg : TemplateArgs)
314 R.set(TArg.first, TArg.second);
315 NewDef->resolveReferences(R);
316
317 CurMC->DefPrototypes.push_back(std::move(NewDef));
318 }
319
320 return false;
321 }
322
323 /// Add a record that results from 'def' or 'defm', after template arguments
324 /// and the external let stack have been resolved.
325 ///
326 /// Apply foreach loops, resolve internal variable references, and add to the
327 /// current multi class or the global record keeper as appropriate.
328 bool TGParser::addDef(std::unique_ptr Rec) {
329 IterSet IterVals;
330
331 if (Loops.empty())
332 return addDefOne(std::move(Rec), IterVals);
333
334 return addDefForeach(Rec.get(), IterVals);
335 }
336
337 /// Recursive helper function for addDef/addDefOne to resolve references to
338 /// foreach variables.
339 bool TGParser::addDefForeach(Record *Rec, IterSet &IterVals) {
340 if (IterVals.size() != Loops.size()) {
341 assert(IterVals.size() < Loops.size());
342 ForeachLoop &CurLoop = Loops[IterVals.size()];
343 ListInit *List = CurLoop.ListValue;
344
345 // Process each value.
346 for (unsigned i = 0; i < List->size(); ++i) {
347 IterVals.push_back(IterRecord(CurLoop.IterVar, List->getElement(i)));
348 if (addDefForeach(Rec, IterVals))
349 return true;
350 IterVals.pop_back();
351 }
339 return resolve(SMC->Entries, TemplateArgs, false, &CurMC->Entries);
340 }
341
342 /// Add a record or foreach loop to the current context (global record keeper,
343 /// current inner-most foreach loop, or multiclass).
344 bool TGParser::addEntry(RecordsEntry E) {
345 assert(!E.Rec || !E.Loop);
346
347 if (!Loops.empty()) {
348 Loops.back()->Entries.push_back(std::move(E));
352349 return false;
353350 }
354351
355 // This is the bottom of the recursion. We have all of the iterator values
356 // for this point in the iteration space. Instantiate a new record to
357 // reflect this combination of values.
358 auto IterRec = make_unique(*Rec);
359 return addDefOne(std::move(IterRec), IterVals);
360 }
361
362 /// After resolving foreach loops, add the record as a prototype to the
363 /// current multiclass, or resolve fully and add to the record keeper.
364 bool TGParser::addDefOne(std::unique_ptr Rec, IterSet &IterVals) {
365 MapResolver R(Rec.get());
366
367 for (IterRecord &IR : IterVals)
368 R.set(IR.IterVar->getNameInit(), IR.IterValue);
369
370 Rec->resolveReferences(R);
352 if (E.Loop) {
353 SubstStack Stack;
354 return resolve(*E.Loop, Stack, CurMultiClass == nullptr,
355 CurMultiClass ? &CurMultiClass->Entries : nullptr);
356 }
371357
372358 if (CurMultiClass) {
373 if (!Rec->isAnonymous()) {
374 for (const auto &Proto : CurMultiClass->DefPrototypes) {
375 if (Proto->getNameInit() == Rec->getNameInit()) {
376 PrintError(Rec->getLoc(),
377 Twine("def '") + Rec->getNameInitAsString() +
378 "' already defined in this multiclass!");
379 PrintNote(Proto->getLoc(), "location of previous definition");
380 return true;
381 }
382 }
383 }
384 CurMultiClass->DefPrototypes.emplace_back(std::move(Rec));
359 CurMultiClass->Entries.push_back(std::move(E));
385360 return false;
386361 }
387362
363 return addDefOne(std::move(E.Rec));
364 }
365
366 /// Resolve the entries in \p Loop, going over inner loops recursively
367 /// and making the given subsitutions of (name, value) pairs.
368 ///
369 /// The resulting records are stored in \p Dest if non-null. Otherwise, they
370 /// are added to the global record keeper.
371 bool TGParser::resolve(const ForeachLoop &Loop, SubstStack &Substs,
372 bool Final, std::vector *Dest,
373 SMLoc *Loc) {
374 MapResolver R;
375 for (const auto &S : Substs)
376 R.set(S.first, S.second);
377 Init *List = Loop.ListValue->resolveReferences(R);
378 auto LI = dyn_cast(List);
379 if (!LI) {
380 if (!Final) {
381 Dest->emplace_back(make_unique(Loop.Loc, Loop.IterVar,
382 List));
383 return resolve(Loop.Entries, Substs, Final, &Dest->back().Loop->Entries,
384 Loc);
385 }
386
387 PrintError(Loop.Loc, Twine("attempting to loop over '") +
388 List->getAsString() + "', expected a list");
389 return true;
390 }
391
392 bool Error = false;
393 for (auto Elt : *LI) {
394 Substs.emplace_back(Loop.IterVar->getNameInit(), Elt);
395 Error = resolve(Loop.Entries, Substs, Final, Dest);
396 Substs.pop_back();
397 if (Error)
398 break;
399 }
400 return Error;
401 }
402
403 /// Resolve the entries in \p Source, going over loops recursively and
404 /// making the given substitutions of (name, value) pairs.
405 ///
406 /// The resulting records are stored in \p Dest if non-null. Otherwise, they
407 /// are added to the global record keeper.
408 bool TGParser::resolve(const std::vector &Source,
409 SubstStack &Substs, bool Final,
410 std::vector *Dest, SMLoc *Loc) {
411 bool Error = false;
412 for (auto &E : Source) {
413 if (E.Loop) {
414 Error = resolve(*E.Loop, Substs, Final, Dest);
415 } else {
416 auto Rec = make_unique(*E.Rec);
417 if (Loc)
418 Rec->appendLoc(*Loc);
419
420 MapResolver R(Rec.get());
421 for (const auto &S : Substs)
422 R.set(S.first, S.second);
423 Rec->resolveReferences(R);
424
425 if (Dest)
426 Dest->push_back(std::move(Rec));
427 else
428 Error = addDefOne(std::move(Rec));
429 }
430 if (Error)
431 break;
432 }
433 return Error;
434 }
435
436 /// Resolve the record fully and add it to the record keeper.
437 bool TGParser::addDefOne(std::unique_ptr Rec) {
388438 if (Record *Prev = Records.getDef(Rec->getNameInitAsString())) {
389439 if (!Rec->isAnonymous()) {
390440 PrintError(Rec->getLoc(),
803853
804854 // If this is in a foreach loop, make sure it's not a loop iterator
805855 for (const auto &L : Loops) {
806 VarInit *IterVar = dyn_cast(L.IterVar);
856 VarInit *IterVar = dyn_cast(L->IterVar);
807857 if (IterVar && IterVar->getNameInit() == Name)
808858 return IterVar;
809859 }
11571207
11581208 Init *LHS = StringInit::get(Lex.getCurStrVal());
11591209
1160 if (CurRec->getValue(LHS)) {
1210 if (CurRec && CurRec->getValue(LHS)) {
11611211 TokError((Twine("iteration variable '") + LHS->getAsString() +
11621212 "' already defined")
11631213 .str());
12161266 return nullptr;
12171267 }
12181268
1219 CurRec->addValue(RecordVal(LHS, InEltType, false));
1220 Init *RHS = ParseValue(CurRec, OutEltType);
1221 CurRec->removeValue(LHS);
1269 // We need to create a temporary record to provide a scope for the iteration
1270 // variable while parsing top-level foreach's.
1271 std::unique_ptr ParseRecTmp;
1272 Record *ParseRec = CurRec;
1273 if (!ParseRec) {
1274 ParseRecTmp = make_unique(".parse", ArrayRef{}, Records);
1275 ParseRec = ParseRecTmp.get();
1276 }
1277
1278 ParseRec->addValue(RecordVal(LHS, InEltType, false));
1279 Init *RHS = ParseValue(ParseRec, OutEltType);
1280 ParseRec->removeValue(LHS);
12221281 if (!RHS)
12231282 return nullptr;
12241283
14401499 }
14411500
14421501 Init *A = StringInit::get(Lex.getCurStrVal());
1443 if (CurRec->getValue(A)) {
1502 if (CurRec && CurRec->getValue(A)) {
14441503 TokError((Twine("left !foldl variable '") + A->getAsString() +
14451504 "' already defined")
14461505 .str());
14581517 }
14591518
14601519 Init *B = StringInit::get(Lex.getCurStrVal());
1461 if (CurRec->getValue(B)) {
1520 if (CurRec && CurRec->getValue(B)) {
14621521 TokError((Twine("right !foldl variable '") + B->getAsString() +
14631522 "' already defined")
14641523 .str());
14711530 }
14721531 Lex.Lex(); // eat the ','
14731532
1474 CurRec->addValue(RecordVal(A, Start->getType(), false));
1475 CurRec->addValue(RecordVal(B, ListType->getElementType(), false));
1476 Init *ExprUntyped = ParseValue(CurRec);
1477 CurRec->removeValue(A);
1478 CurRec->removeValue(B);
1533 // We need to create a temporary record to provide a scope for the iteration
1534 // variable while parsing top-level foreach's.
1535 std::unique_ptr ParseRecTmp;
1536 Record *ParseRec = CurRec;
1537 if (!ParseRec) {
1538 ParseRecTmp = make_unique(".parse", ArrayRef{}, Records);
1539 ParseRec = ParseRecTmp.get();
1540 }
1541
1542 ParseRec->addValue(RecordVal(A, Start->getType(), false));
1543 ParseRec->addValue(RecordVal(B, ListType->getElementType(), false));
1544 Init *ExprUntyped = ParseValue(ParseRec);
1545 ParseRec->removeValue(A);
1546 ParseRec->removeValue(B);
14791547 if (!ExprUntyped)
14801548 return nullptr;
14811549
21902258 /// ForeachDeclaration ::= ID '=' RangePiece
21912259 /// ForeachDeclaration ::= ID '=' Value
21922260 ///
2193 VarInit *TGParser::ParseForeachDeclaration(ListInit *&ForeachListValue) {
2261 VarInit *TGParser::ParseForeachDeclaration(Init *&ForeachListValue) {
21942262 if (Lex.getCode() != tgtok::Id) {
21952263 TokError("Expected identifier in foreach declaration");
21962264 return nullptr;
22302298 default: {
22312299 SMLoc ValueLoc = Lex.getLoc();
22322300 Init *I = ParseValue(nullptr);
2233 if (!isa(I)) {
2301 TypedInit *TI = dyn_cast(I);
2302 if (!TI || !isa(TI->getType())) {
22342303 std::string Type;
2235 if (TypedInit *TI = dyn_cast(I))
2304 if (TI)
22362305 Type = (Twine("' of type '") + TI->getType()->getAsString()).str();
22372306 Error(ValueLoc, "expected a list, got '" + I->getAsString() + Type + "'");
22382307 if (CurMultiClass)
22402309 "resolved at this time");
22412310 return nullptr;
22422311 }
2243 ForeachListValue = dyn_cast(I);
2244 IterType = ForeachListValue->getElementType();
2312 ForeachListValue = I;
2313 IterType = cast(TI->getType())->getElementType();
22452314 break;
22462315 }
22472316 }
23892458 return false;
23902459 }
23912460
2461 bool TGParser::ApplyLetStack(RecordsEntry &Entry) {
2462 if (Entry.Rec)
2463 return ApplyLetStack(Entry.Rec.get());
2464
2465 for (auto &E : Entry.Loop->Entries) {
2466 if (ApplyLetStack(E))
2467 return true;
2468 }
2469
2470 return false;
2471 }
2472
23922473 /// ParseObjectBody - Parse the body of a def or class. This consists of an
23932474 /// optional ClassList followed by a Body. CurRec is the current def or class
23942475 /// that is being parsed.
24502531 if (ParseObjectBody(CurRec.get()))
24512532 return true;
24522533
2453 return addDef(std::move(CurRec));
2534 return addEntry(std::move(CurRec));
24542535 }
24552536
24562537 /// ParseDefset - Parse a defset statement.
25072588 /// Foreach ::= FOREACH Declaration IN Object
25082589 ///
25092590 bool TGParser::ParseForeach(MultiClass *CurMultiClass) {
2591 SMLoc Loc = Lex.getLoc();
25102592 assert(Lex.getCode() == tgtok::Foreach && "Unknown tok");
25112593 Lex.Lex(); // Eat the 'for' token.
25122594
25132595 // Make a temporary object to record items associated with the for
25142596 // loop.
2515 ListInit *ListValue = nullptr;
2597 Init *ListValue = nullptr;
25162598 VarInit *IterName = ParseForeachDeclaration(ListValue);
25172599 if (!IterName)
25182600 return TokError("expected declaration in for");
25222604 Lex.Lex(); // Eat the in
25232605
25242606 // Create a loop object and remember it.
2525 Loops.push_back(ForeachLoop(IterName, ListValue));
2607 Loops.push_back(llvm::make_unique(Loc, IterName, ListValue));
25262608
25272609 if (Lex.getCode() != tgtok::l_brace) {
25282610 // FOREACH Declaration IN Object
25442626 Lex.Lex(); // Eat the }
25452627 }
25462628
2547 // We've processed everything in this loop.
2629 // Resolve the loop or store it for later resolution.
2630 std::unique_ptr Loop = std::move(Loops.back());
25482631 Loops.pop_back();
25492632
2550 return false;
2633 return addEntry(std::move(Loop));
25512634 }
25522635
25532636 /// ParseClass - Parse a tblgen class definition.
27942877 return TokError("expected ':' after defm identifier");
27952878
27962879 // Keep track of the new generated record definitions.
2797 SmallVector, 8> NewRecDefs;
2880 std::vector NewEntries;
27982881
27992882 // This record also inherits from a regular class (non-multiclass)?
28002883 bool InheritFromClass = false;
28212904 return Error(SubClassLoc,
28222905 "more template args specified than multiclass expects");
28232906
2824 SmallVector, 8> TemplateArgs;
2907 SubstStack Substs;
28252908 for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
28262909 if (i < TemplateVals.size()) {
2827 TemplateArgs.emplace_back(TArgs[i], TemplateVals[i]);
2910 Substs.emplace_back(TArgs[i], TemplateVals[i]);
28282911 } else {
28292912 Init *Default = MC->Rec.getValue(TArgs[i])->getValue();
28302913 if (!Default->isComplete()) {
28342917 ") of multiclass '" + MC->Rec.getNameInitAsString() +
28352918 "'");
28362919 }
2837 TemplateArgs.emplace_back(TArgs[i], Default);
2838 }
2839 }
2840
2841 TemplateArgs.emplace_back(QualifiedNameOfImplicitName(MC), DefmName);
2842
2843 // Loop over all the def's in the multiclass, instantiating each one.
2844 for (const std::unique_ptr &DefProto : MC->DefPrototypes) {
2845 auto CurRec = make_unique(*DefProto);
2846 CurRec->appendLoc(SubClassLoc);
2847
2848 MapResolver R(CurRec.get());
2849 for (const auto &TArg : TemplateArgs)
2850 R.set(TArg.first, TArg.second);
2851 CurRec->resolveReferences(R);
2852
2853 NewRecDefs.emplace_back(std::move(CurRec));
2854 }
2920 Substs.emplace_back(TArgs[i], Default);
2921 }
2922 }
2923
2924 Substs.emplace_back(QualifiedNameOfImplicitName(MC), DefmName);
2925
2926 if (resolve(MC->Entries, Substs, CurMultiClass == nullptr, &NewEntries,
2927 &SubClassLoc))
2928 return true;
28552929
28562930 if (Lex.getCode() != tgtok::comma) break;
28572931 Lex.Lex(); // eat ','.
28812955
28822956 // Get the expanded definition prototypes and teach them about
28832957 // the record values the current class to inherit has
2884 for (const auto &CurRec : NewRecDefs) {
2958 for (auto &E : NewEntries) {
28852959 // Add it.
2886 if (AddSubClass(CurRec.get(), SubClass))
2960 if (AddSubClass(E, SubClass))
28872961 return true;
28882962 }
28892963
28932967 }
28942968 }
28952969
2896 for (auto &CurRec : NewRecDefs) {
2897 if (ApplyLetStack(CurRec.get()))
2970 for (auto &E : NewEntries) {
2971 if (ApplyLetStack(E))
28982972 return true;
28992973
2900 addDef(std::move(CurRec));
2974 addEntry(std::move(E));
29012975 }
29022976
29032977 if (Lex.getCode() != tgtok::semi)
29603034
29613035 return TokError("Unexpected input at top level");
29623036 }
3037
3038 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3039 LLVM_DUMP_METHOD void RecordsEntry::dump() const {
3040 if (Loop)
3041 Loop->dump();
3042 if (Rec)
3043 Rec->dump();
3044 }
3045
3046 LLVM_DUMP_METHOD void ForeachLoop::dump() const {
3047 errs() << "foreach " << IterVar->getAsString() << " = "
3048 << ListValue->getAsString() << " in {\n";
3049
3050 for (const auto &E : Entries)
3051 E.dump();
3052
3053 errs() << "}\n";
3054 }
3055
3056 LLVM_DUMP_METHOD void MultiClass::dump() const {
3057 errs() << "Record:\n";
3058 Rec.dump();
3059
3060 errs() << "Defs:\n";
3061 for (const auto &E : Entries)
3062 E.dump();
3063 }
3064 #endif
2626 class RecordKeeper;
2727 class RecTy;
2828 class Init;
29 struct ForeachLoop;
2930 struct MultiClass;
3031 struct SubClassReference;
3132 struct SubMultiClassReference;
4041 }
4142 };
4243
44 /// RecordsEntry - Can be either a record or a foreach loop.
45 struct RecordsEntry {
46 std::unique_ptr Rec;
47 std::unique_ptr Loop;
48
49 void dump() const;
50
51 RecordsEntry() {}
52 RecordsEntry(std::unique_ptr Rec) : Rec(std::move(Rec)) {}
53 RecordsEntry(std::unique_ptr Loop)
54 : Loop(std::move(Loop)) {}
55 };
56
4357 /// ForeachLoop - Record the iteration state associated with a for loop.
4458 /// This is used to instantiate items in the loop body.
4559 struct ForeachLoop {
60 SMLoc Loc;
4661 VarInit *IterVar;
47 ListInit *ListValue;
48
49 ForeachLoop(VarInit *IVar, ListInit *LValue)
50 : IterVar(IVar), ListValue(LValue) {}
62 Init *ListValue;
63 std::vector Entries;
64
65 void dump() const;
66
67 ForeachLoop(SMLoc Loc, VarInit *IVar, Init *LValue)
68 : Loc(Loc), IterVar(IVar), ListValue(LValue) {}
5169 };
5270
5371 struct DefsetRecord {
5674 SmallVector Elements;
5775 };
5876
77 struct MultiClass {
78 Record Rec; // Placeholder for template args and Name.
79 std::vector Entries;
80
81 void dump() const;
82
83 MultiClass(StringRef Name, SMLoc Loc, RecordKeeper &Records) :
84 Rec(Name, Loc, Records) {}
85 };
86
5987 class TGParser {
6088 TGLexer Lex;
6189 std::vector> LetStack;
6391
6492 /// Loops - Keep track of any foreach loops we are within.
6593 ///
66 typedef std::vector LoopVector;
67 LoopVector Loops;
94 std::vector> Loops;
6895
6996 SmallVector Defsets;
7097
111138 ArrayRef BitList, Init *V,
112139 bool AllowSelfAssignment = false);
113140 bool AddSubClass(Record *Rec, SubClassReference &SubClass);
141 bool AddSubClass(RecordsEntry &Entry, SubClassReference &SubClass);
114142 bool AddSubMultiClass(MultiClass *CurMC,
115143 SubMultiClassReference &SubMultiClass);
116144
117 // IterRecord: Map an iterator name to a value.
118 struct IterRecord {
119 VarInit *IterVar;
120 Init *IterValue;
121 IterRecord(VarInit *Var, Init *Val) : IterVar(Var), IterValue(Val) {}
122 };
123
124 // IterSet: The set of all iterator values at some point in the
125 // iteration space.
126 typedef std::vector IterSet;
127
128 bool addDefOne(std::unique_ptr Rec, IterSet &IterVals);
129 bool addDefForeach(Record *Rec, IterSet &IterVals);
130 bool addDef(std::unique_ptr Rec);
145 using SubstStack = SmallVector, 8>;
146
147 bool addEntry(RecordsEntry E);
148 bool resolve(const ForeachLoop &Loop, SubstStack &Stack, bool Final,
149 std::vector *Dest, SMLoc *Loc = nullptr);
150 bool resolve(const std::vector &Source, SubstStack &Substs,
151 bool Final, std::vector *Dest,
152 SMLoc *Loc = nullptr);
153 bool addDefOne(std::unique_ptr Rec);
131154
132155 private: // Parser methods.
133156 bool ParseObjectList(MultiClass *MC = nullptr);
147170
148171 bool ParseTemplateArgList(Record *CurRec);
149172 Init *ParseDeclaration(Record *CurRec, bool ParsingTemplateArgs);
150 VarInit *ParseForeachDeclaration(ListInit *&ForeachListValue);
173 VarInit *ParseForeachDeclaration(Init *&ForeachListValue);
151174
152175 SubClassReference ParseSubClassReference(Record *CurRec, bool isDefm);
153176 SubMultiClassReference ParseSubMultiClassReference(MultiClass *CurMC);
174197 Record *ParseClassID();
175198 MultiClass *ParseMultiClassID();
176199 bool ApplyLetStack(Record *CurRec);
200 bool ApplyLetStack(RecordsEntry &Entry);
177201 };
178202
179203 } // end namespace llvm
1515 }
1616 }
1717 }
18
19 foreach i = [0, 1] in
20 foreach j = !foreach(x, [0, 2], !add(i, x)) in
21 def Z#i#_#j;
1822
1923 // CHECK: def C2D0
2024 // CHECK: def C2D2
7074 // CHECK: def R4Q0
7175 // CHECK: def R4Q2
7276 // CHECK: def R4Q4
77
78 // CHECK: def Z0_0
79 // CHECK: def Z0_2
80 // CHECK: def Z1_1
81 // CHECK: def Z1_3
1010 // CHECK: int sum = 8;
1111 // CHECK: }
1212
13 // CHECK-NOT: def B0
14
15 // CHECK: def B12 {
16 // CHECK: int val = 9;
17 // CHECK: }
18
19 // CHECK: def B20 {
20 // CHECK: int val = 7;
21 // CHECK: }
22
23 // CHECK: def B24 {
24 // CHECK: int val = 11;
25 // CHECK: }
26
27 // CHECK: def B25 {
28 // CHECK: int val = 12;
29 // CHECK: }
30
31 // CHECK: def C04
32 // CHECK: def C05
33
34 // CHECK: def D0A
35 // CHECK-NOT: def D0B
36 // CHECK: def D1A
37 // CHECK: def D1B
38
39 // CHECK: def E01
40 // CHECK: def E02
41 // CHECK-NOT: def E0C
42
43 // CHECK: def E18
44 // CHECK: def E19
45 // CHECK: def E1C33
46 // CHECK: def E1C34
47 // CHECK: def E1C55
48 // CHECK: def E1C56
49
50 // CHECK-NOT: def F0
51 // CHECK-NOT: def F1
52 // CHECK-NOT: def F2_0_0
53 // CHECK: def F2_1_0
54 // CHECK-NOT: def F2_1_2
55 // CHECK: def F2_2_0
56 // CHECK: def F2_2_1
57 // CHECK-NOT: def F2_2_2
58
1359 multiclass A {
14 // Allow foreach in multiclass as long as the list does not depend on
15 // template args.
1660 foreach i = [0, 1] in {
1761 def NAME#i {
1862 int sum = !add(x, i);
2165 }
2266
2367 defm A0 : A<7>;
68
69 multiclass B lst> {
70 foreach i = lst in {
71 def NAME#i {
72 int val = !add(x, i);
73 }
74 }
75 }
76
77 defm B0 : B<7, []>;
78 defm B1 : B<7, [2]>;
79 defm B2 : B<7, [0, 4, 5]>;
80
81 multiclass C {
82 foreach i = [x, !add(x, 1)] in {
83 def NAME#i;
84 }
85 }
86
87 defm C0 : C<4>;
88
89 multiclass D {
90 def A;
91
92 foreach _ = !if(b, [0], []) in
93 def B;
94 }
95
96 defm D0 : D<0>;
97 defm D1 : D<1>;
98
99 multiclass E lst, int x>
100 : C {
101 foreach i = lst in
102 defm C#i : C;
103 }
104
105 defm E0 : E<[], 1>;
106 defm E1 : E<[3, 5], 8>;
107
108 multiclass F lst> {
109 foreach i = lst in
110 foreach j = !foldl([], lst, lhs, x,
111 !if(!lt(x, i), !listconcat(lhs, [x]), lhs)) in
112 def _#i#_#j;
113 }
114
115 defm F0 : F<[]>;
116 defm F1 : F<[0]>;
117 defm F2 : F<[0, 1, 2]>;