llvm.org GIT mirror llvm / 5654613
Allow defm to inherit from multiple multiclasses. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@69832 91177308-0d34-0410-b5e6-96231b3b80d8 David Greene 10 years ago
3 changed file(s) with 112 addition(s) and 71 deletion(s). Raw diff Collapse all Expand all
631631
632632

The name of the resultant definitions has the multidef fragment names

633633 appended to them, so this defines ADD_rr, ADD_ri,
634 SUB_rr, etc. Using a multiclass this way is exactly
635 equivalent to instantiating the classes multiple times yourself,
636 e.g. by writing:

634 SUB_rr, etc. A defm may inherit from multiple multiclasses,
635 instantiating definitions from each multiclass. Using a multiclass
636 this way is exactly equivalent to instantiating the classes multiple
637 times yourself, e.g. by writing:

637638
638639
639640

                  
                
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 {
19 def S3 : C1 {
20 int moo = 3;
21 let bar = 1;
22 }
23 def S4 : C1;
24 }
25
26 defm FOO : t<42>, s<24>;
27
28 def T4 : C1<6, "foo">;
29
30 let zing = 4 in
31 defm BAZ : t<3>, s<4>;
14811481
14821482 TGLoc SubClassLoc = Lex.getLoc();
14831483 SubClassReference Ref = ParseSubClassReference(0, true);
1484 if (Ref.Rec == 0) return true;
1485
1484
1485 while (1) {
1486 if (Ref.Rec == 0) return true;
1487
1488 // To instantiate a multiclass, we need to first get the multiclass, then
1489 // instantiate each def contained in the multiclass with the SubClassRef
1490 // template parameters.
1491 MultiClass *MC = MultiClasses[Ref.Rec->getName()];
1492 assert(MC && "Didn't lookup multiclass correctly?");
1493 std::vector &TemplateVals = Ref.TemplateArgs;
1494
1495 // Verify that the correct number of template arguments were specified.
1496 const std::vector &TArgs = MC->Rec.getTemplateArgs();
1497 if (TArgs.size() < TemplateVals.size())
1498 return Error(SubClassLoc,
1499 "more template args specified than multiclass expects");
1500
1501 // Loop over all the def's in the multiclass, instantiating each one.
1502 for (unsigned i = 0, e = MC->DefPrototypes.size(); i != e; ++i) {
1503 Record *DefProto = MC->DefPrototypes[i];
1504
1505 // Add the suffix to the defm name to get the new name.
1506 Record *CurRec = new Record(DefmPrefix + DefProto->getName(), DefmPrefixLoc);
1507
1508 SubClassReference Ref;
1509 Ref.RefLoc = DefmPrefixLoc;
1510 Ref.Rec = DefProto;
1511 AddSubClass(CurRec, Ref);
1512
1513 // Loop over all of the template arguments, setting them to the specified
1514 // value or leaving them as the default if necessary.
1515 for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
1516 if (i < TemplateVals.size()) { // A value is specified for this temp-arg?
1517 // Set it now.
1518 if (SetValue(CurRec, DefmPrefixLoc, TArgs[i], std::vector(),
1519 TemplateVals[i]))
1520 return true;
1521
1522 // Resolve it next.
1523 CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i]));
1524
1525 // Now remove it.
1526 CurRec->removeValue(TArgs[i]);
1527
1528 } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) {
1529 return Error(SubClassLoc, "value not specified for template argument #"+
1530 utostr(i) + " (" + TArgs[i] + ") of multiclassclass '" +
1531 MC->Rec.getName() + "'");
1532 }
1533 }
1534
1535 // If the mdef is inside a 'let' expression, add to each def.
1536 for (unsigned i = 0, e = LetStack.size(); i != e; ++i)
1537 for (unsigned j = 0, e = LetStack[i].size(); j != e; ++j)
1538 if (SetValue(CurRec, LetStack[i][j].Loc, LetStack[i][j].Name,
1539 LetStack[i][j].Bits, LetStack[i][j].Value)) {
1540 Error(DefmPrefixLoc, "when instantiating this defm");
1541 return true;
1542 }
1543
1544 // Ensure redefinition doesn't happen.
1545 if (Records.getDef(CurRec->getName()))
1546 return Error(DefmPrefixLoc, "def '" + CurRec->getName() +
1547 "' already defined, instantiating defm with subdef '" +
1548 DefProto->getName() + "'");
1549 Records.addDef(CurRec);
1550 CurRec->resolveReferences();
1551 }
1552
1553 if (Lex.getCode() != tgtok::comma) break;
1554 Lex.Lex(); // eat ','.
1555
1556 SubClassLoc = Lex.getLoc();
1557 Ref = ParseSubClassReference(0, true);
1558 }
1559
14861560 if (Lex.getCode() != tgtok::semi)
14871561 return TokError("expected ';' at end of defm");
14881562 Lex.Lex();
1489
1490 // To instantiate a multiclass, we need to first get the multiclass, then
1491 // instantiate each def contained in the multiclass with the SubClassRef
1492 // template parameters.
1493 MultiClass *MC = MultiClasses[Ref.Rec->getName()];
1494 assert(MC && "Didn't lookup multiclass correctly?");
1495 std::vector &TemplateVals = Ref.TemplateArgs;
1496
1497 // Verify that the correct number of template arguments were specified.
1498 const std::vector &TArgs = MC->Rec.getTemplateArgs();
1499 if (TArgs.size() < TemplateVals.size())
1500 return Error(SubClassLoc,
1501 "more template args specified than multiclass expects");
1502
1503 // Loop over all the def's in the multiclass, instantiating each one.
1504 for (unsigned i = 0, e = MC->DefPrototypes.size(); i != e; ++i) {
1505 Record *DefProto = MC->DefPrototypes[i];
1506
1507 // Add the suffix to the defm name to get the new name.
1508 Record *CurRec = new Record(DefmPrefix + DefProto->getName(),DefmPrefixLoc);
1509
1510 SubClassReference Ref;
1511 Ref.RefLoc = DefmPrefixLoc;
1512 Ref.Rec = DefProto;
1513 AddSubClass(CurRec, Ref);
1514
1515 // Loop over all of the template arguments, setting them to the specified
1516 // value or leaving them as the default if necessary.
1517 for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
1518 if (i < TemplateVals.size()) { // A value is specified for this temp-arg?
1519 // Set it now.
1520 if (SetValue(CurRec, DefmPrefixLoc, TArgs[i], std::vector(),
1521 TemplateVals[i]))
1522 return true;
1523
1524 // Resolve it next.
1525 CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i]));
1526
1527 // Now remove it.
1528 CurRec->removeValue(TArgs[i]);
1529
1530 } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) {
1531 return Error(SubClassLoc, "value not specified for template argument #"+
1532 utostr(i) + " (" + TArgs[i] + ") of multiclassclass '" +
1533 MC->Rec.getName() + "'");
1534 }
1535 }
1536
1537 // If the mdef is inside a 'let' expression, add to each def.
1538 for (unsigned i = 0, e = LetStack.size(); i != e; ++i)
1539 for (unsigned j = 0, e = LetStack[i].size(); j != e; ++j)
1540 if (SetValue(CurRec, LetStack[i][j].Loc, LetStack[i][j].Name,
1541 LetStack[i][j].Bits, LetStack[i][j].Value)) {
1542 Error(DefmPrefixLoc, "when instantiating this defm");
1543 return true;
1544 }
1545
1546
1547 // Ensure redefinition doesn't happen.
1548 if (Records.getDef(CurRec->getName()))
1549 return Error(DefmPrefixLoc, "def '" + CurRec->getName() +
1550 "' already defined, instantiating defm with subdef '" +
1551 DefProto->getName() + "'");
1552 Records.addDef(CurRec);
1553 CurRec->resolveReferences();
1554 }
15551563
15561564 return false;
15571565 }