[llvm-commits] [llvm] r69810 - in /llvm/trunk: docs/TableGenFundamentals.html test/TableGen/MultiClassInherit.td utils/TableGen/TGParser.cpp utils/TableGen/TGParser.h

Bob Wilson bob.wilson at apple.com
Thu Apr 30 11:37:31 PDT 2009


Hi David,

I'm looking forward to using this new feature, so I volunteered to  
review it.  I found a few very superficial problems, which I have gone  
ahead and fixed.  Otherwise, it looks great, especially from the  
perspective of the syntax and behavior of the new multiclass  
inheritance feature -- the internal details of TableGen are still a  
bit murky to me, but your change looks OK as far as I understand it.

One thing I noticed is that the new AddSubMultiClass method has a  
formal parameter that is always the same as the  
TGParser::CurMultiClass instance variable.  I renamed the formal  
parameter so it doesn't shadow the instance variable, but another  
option would be to remove the formal parameter altogether.  It seems  
like there are several other methods in this class with the same  
issue, so I'm guessing that this is intentional.  There is certainly  
something to be said for being explicit with the parameter -- getting  
rid of the instance variable would be nicer in some ways, but I have  
no idea how difficult that would be.  Anyway, I think it's OK the way  
it is but thought I would raise the issue in case you or someone else  
wants to make further changes.

On Apr 22, 2009, at 9:42 AM, David Greene wrote:

> Author: greened
> Date: Wed Apr 22 11:42:54 2009
> New Revision: 69810
>
> URL: http://llvm.org/viewvc/llvm-project?rev=69810&view=rev
> Log:
> Implement multiclass inheritance.
>
>
> Added:
>    llvm/trunk/test/TableGen/MultiClassInherit.td
> Modified:
>    llvm/trunk/docs/TableGenFundamentals.html
>    llvm/trunk/utils/TableGen/TGParser.cpp
>    llvm/trunk/utils/TableGen/TGParser.h
>
> Modified: llvm/trunk/docs/TableGenFundamentals.html
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/TableGenFundamentals.html?rev=69810&r1=69809&r2=69810&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/docs/TableGenFundamentals.html (original)
> +++ llvm/trunk/docs/TableGenFundamentals.html Wed Apr 22 11:42:54 2009
> @@ -104,8 +104,10 @@
> as "Instruction".</p>
>
> <p><b>TableGen multiclasses</b> are groups of abstract records that  
> are
> -instantiated all at once.  Each instantiation can result in  
> multiple TableGen
> -definitions.</p>
> +instantiated all at once.  Each instantiation can result in multiple
> +TableGen definitions.  If a multiclass inherits from another  
> multiclass,
> +the definitions in the sub-multiclass become part of the current
> +multiclass, as if they were declared in the current multiclass.</p>
>
> </div>
>
>
> Added: llvm/trunk/test/TableGen/MultiClassInherit.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/MultiClassInherit.td?rev=69810&view=auto
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/test/TableGen/MultiClassInherit.td (added)
> +++ llvm/trunk/test/TableGen/MultiClassInherit.td Wed Apr 22  
> 11:42:54 2009
> @@ -0,0 +1,32 @@
> +// RUN: tblgen %s | grep {zing = 4} | count 4
> +
> +class C1<int A, string B> {
> +  int bar = A;
> +  string thestr = B;
> +  int zing;
> +}
> +
> +def T : C1<4, "blah">;
> +
> +multiclass t<int a> {
> +  def S1 : C1<a, "foo"> {
> +    int foo = 4;
> +    let bar = 1;
> +  }
> +  def S2 : C1<a, "bar">;
> +}
> +
> +multiclass s<int a, int b> : t<a> {
> +  def S3 : C1<b, "moo"> {
> +    int moo = 3;
> +    let bar = 1;
> +  }
> +  def S4 : C1<b, "baz">;
> +}
> +
> +defm FOO : s<42, 24>;
> +
> +def T4 : C1<6, "foo">;
> +
> +let zing = 4 in
> +  defm BAZ : s<3, 4>;
>
> Modified: llvm/trunk/utils/TableGen/TGParser.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGParser.cpp?rev=69810&r1=69809&r2=69810&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/utils/TableGen/TGParser.cpp (original)
> +++ llvm/trunk/utils/TableGen/TGParser.cpp Wed Apr 22 11:42:54 2009
> @@ -25,7 +25,8 @@
> namespace llvm {
> struct MultiClass {
>   Record Rec;  // Placeholder for template args and Name.
> -  std::vector<Record*> DefPrototypes;
> +  typedef std::vector<Record*> RecordVector;
> +  RecordVector DefPrototypes;
>
>   MultiClass(const std::string &Name, TGLoc Loc) : Rec(Name, Loc) {}
> };
> @@ -38,6 +39,15 @@
>
>   bool isInvalid() const { return Rec == 0; }
> };
> +
> +struct SubMultiClassReference {
> +  TGLoc RefLoc;
> +  MultiClass *MC;
> +  std::vector<Init*> TemplateArgs;
> +  SubMultiClassReference() : MC(0) {}
> +
> +  bool isInvalid() const { return MC == 0; }
> +};
>
> } // end namespace llvm
>
> @@ -177,6 +187,85 @@
>   return false;
> }
>
> +/// AddSubMultiClass - Add SubMultiClass as a subclass to
> +/// CurMultiClass, resolving its template args as SubMultiClass's
> +/// template arguments.
> +bool TGParser::AddSubMultiClass(MultiClass *CurMultiClass, class  
> SubMultiClassReference &SubMultiClass) {
> +  MultiClass *SMC = SubMultiClass.MC;
> +  Record *CurRec = &CurMultiClass->Rec;
> +
> +  const std::vector<RecordVal> &MCVals = CurMultiClass- 
> >Rec.getValues();
> +
> +  // Add all of the values in the subclass into the current class.
> +  const std::vector<RecordVal> &SMCVals = SMC->Rec.getValues();
> +  for (unsigned i = 0, e = SMCVals.size(); i != e; ++i)
> +    if (AddValue(CurRec, SubMultiClass.RefLoc, SMCVals[i]))
> +      return true;
> +
> +  // Add all of the defs in the subclass into the current multiclass.
> +  for (MultiClass::RecordVector::const_iterator i = SMC- 
> >DefPrototypes.begin(),
> +         iend = SMC->DefPrototypes.end();
> +       i != iend;
> +       ++i) {
> +    // Clone the def and add it to the current multiclass
> +    Record *NewDef = new Record(**i);
> +
> +    // Add all of the values in the superclass into the current def.
> +    for (unsigned i = 0, e = MCVals.size(); i != e; ++i)
> +      if (AddValue(NewDef, SubMultiClass.RefLoc, MCVals[i]))
> +        return true;
> +
> +    CurMultiClass->DefPrototypes.push_back(NewDef);
> +  }
> +
> +  const std::vector<std::string> &SMCTArgs = SMC- 
> >Rec.getTemplateArgs();
> +
> +  // Ensure that an appropriate number of template arguments are  
> specified.
> +  if (SMCTArgs.size() < SubMultiClass.TemplateArgs.size())
> +    return Error(SubMultiClass.RefLoc, "More template args  
> specified than expected");
> +
> +  // Loop over all of the template arguments, setting them to the  
> specified
> +  // value or leaving them as the default if necessary.
> +  for (unsigned i = 0, e = SMCTArgs.size(); i != e; ++i) {
> +    if (i < SubMultiClass.TemplateArgs.size()) {
> +      // If a value is specified for this template arg, set it in  
> the superclass now.
> +      if (SetValue(CurRec, SubMultiClass.RefLoc, SMCTArgs[i],  
> std::vector<unsigned>(),
> +                   SubMultiClass.TemplateArgs[i]))
> +        return true;
> +
> +      // Resolve it next.
> +      CurRec->resolveReferencesTo(CurRec->getValue(SMCTArgs[i]));
> +
> +      // Now remove it.
> +      CurRec->removeValue(SMCTArgs[i]);
> +
> +      // If a value is specified for this template arg, set it in  
> the defs now.
> +      for (MultiClass::RecordVector::iterator j = CurMultiClass- 
> >DefPrototypes.begin(),
> +             jend = CurMultiClass->DefPrototypes.end();
> +           j != jend;
> +           ++j) {
> +        Record *Def = *j;
> +
> +        if (SetValue(Def, SubMultiClass.RefLoc, SMCTArgs[i],  
> std::vector<unsigned>(),
> +                     SubMultiClass.TemplateArgs[i]))
> +          return true;
> +
> +        // Resolve it next.
> +        Def->resolveReferencesTo(Def->getValue(SMCTArgs[i]));
> +
> +        // Now remove it
> +        Def->removeValue(SMCTArgs[i]);
> +      }
> +    } else if (!CurRec->getValue(SMCTArgs[i])->getValue()- 
> >isComplete()) {
> +      return Error(SubMultiClass.RefLoc,"Value not specified for  
> template argument #"
> +                   + utostr(i) + " (" + SMCTArgs[i] + ") of  
> subclass '" +
> +                   SMC->Rec.getName() + "'!");
> +    }
> +  }
> +
> +  return false;
> +}
> +
> // 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> // Parser Code
> // 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> @@ -223,6 +312,25 @@
>   return Result;
> }
>
> +/// ParseMultiClassID - Parse and resolve a reference to a  
> multiclass name.  This returns
> +/// null on error.
> +///
> +///    MultiClassID ::= ID
> +///
> +MultiClass *TGParser::ParseMultiClassID() {
> +  if (Lex.getCode() != tgtok::Id) {
> +    TokError("expected name for ClassID");
> +    return 0;
> +  }
> +
> +  MultiClass *Result = MultiClasses[Lex.getCurStrVal()];
> +  if (Result == 0)
> +    TokError("Couldn't find class '" + Lex.getCurStrVal() + "'");
> +
> +  Lex.Lex();
> +  return Result;
> +}
> +
> Record *TGParser::ParseDefmID() {
>   if (Lex.getCode() != tgtok::Id) {
>     TokError("expected multiclass name");
> @@ -285,6 +393,47 @@
>   return Result;
> }
>
> +/// ParseSubMultiClassReference - Parse a reference to a subclass  
> or to a templated
> +/// submulticlass.  This returns a SubMultiClassRefTy with a null  
> Record* on error.
> +///
> +///  SubMultiClassRef ::= MultiClassID
> +///  SubMultiClassRef ::= MultiClassID '<' ValueList '>'
> +///
> +SubMultiClassReference TGParser::
> +ParseSubMultiClassReference(MultiClass *CurMC) {
> +  SubMultiClassReference Result;
> +  Result.RefLoc = Lex.getLoc();
> +
> +  Result.MC = ParseMultiClassID();
> +  if (Result.MC == 0) return Result;
> +
> +  // If there is no template arg list, we're done.
> +  if (Lex.getCode() != tgtok::less)
> +    return Result;
> +  Lex.Lex();  // Eat the '<'
> +
> +  if (Lex.getCode() == tgtok::greater) {
> +    TokError("subclass reference requires a non-empty list of  
> template values");
> +    Result.MC = 0;
> +    return Result;
> +  }
> +
> +  Result.TemplateArgs = ParseValueList(&CurMC->Rec);
> +  if (Result.TemplateArgs.empty()) {
> +    Result.MC = 0;   // Error parsing value list.
> +    return Result;
> +  }
> +
> +  if (Lex.getCode() != tgtok::greater) {
> +    TokError("expected '>' in template value list");
> +    Result.MC = 0;
> +    return Result;
> +  }
> +  Lex.Lex();
> +
> +  return Result;
> +}
> +
> /// ParseRangePiece - Parse a bit/value range.
> ///   RangePiece ::= INTVAL
> ///   RangePiece ::= INTVAL '-' INTVAL
> @@ -1231,7 +1380,7 @@
>
> /// ParseMultiClass - Parse a multiclass definition.
> ///
> -///  MultiClassInst ::= MULTICLASS ID TemplateArgList? '{'  
> MultiClassDef+ '}'
> +///  MultiClassInst ::= MULTICLASS ID TemplateArgList? ':'  
> BaseMultiClassList '{' MultiClassDef+ '}'
> ///
> bool TGParser::ParseMultiClass() {
>   assert(Lex.getCode() == tgtok::MultiClass && "Unexpected token");
> @@ -1252,6 +1401,26 @@
>     if (ParseTemplateArgList(0))
>       return true;
>
> +  // If there are submulticlasses, parse them.
> +  if (Lex.getCode() == tgtok::colon) {
> +    Lex.Lex();
> +
> +    // Read all of the submulticlasses.
> +    SubMultiClassReference SubMultiClass =  
> ParseSubMultiClassReference(CurMultiClass);
> +    while (1) {
> +      // Check for error.
> +      if (SubMultiClass.MC == 0) return true;
> +
> +      // Add it.
> +      if (AddSubMultiClass(CurMultiClass, SubMultiClass))
> +        return true;
> +
> +      if (Lex.getCode() != tgtok::comma) break;
> +      Lex.Lex(); // eat ','.
> +      SubMultiClass = ParseSubMultiClassReference(CurMultiClass);
> +    }
> +  }
> +
>   if (Lex.getCode() != tgtok::l_brace)
>     return TokError("expected '{' in multiclass definition");
>
>
> Modified: llvm/trunk/utils/TableGen/TGParser.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGParser.h?rev=69810&r1=69809&r2=69810&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/utils/TableGen/TGParser.h (original)
> +++ llvm/trunk/utils/TableGen/TGParser.h Wed Apr 22 11:42:54 2009
> @@ -25,6 +25,7 @@
>   struct Init;
>   struct MultiClass;
>   struct SubClassReference;
> +  struct SubMultiClassReference;
>
>   struct LetRecord {
>     std::string Name;
> @@ -46,7 +47,6 @@
>   /// current value.
>   MultiClass *CurMultiClass;
> public:
> -
>   TGParser(TGSourceMgr &SrcMgr) : Lex(SrcMgr), CurMultiClass(0) {}
>
>   void setIncludeDirs(const std::vector<std::string> &D) 
> {Lex.setIncludeDirs(D);}
> @@ -67,6 +67,7 @@
>   bool SetValue(Record *TheRec, TGLoc Loc, const std::string &ValName,
>                 const std::vector<unsigned> &BitList, Init *V);
>   bool AddSubClass(Record *Rec, SubClassReference &SubClass);
> +  bool AddSubMultiClass(MultiClass *MV, class  
> SubMultiClassReference &SubMultiClass);
>
> private:  // Parser methods.
>   bool ParseObjectList();
> @@ -87,6 +88,7 @@
>   std::string ParseDeclaration(Record *CurRec, bool  
> ParsingTemplateArgs);
>
>   SubClassReference ParseSubClassReference(Record *CurRec, bool  
> isDefm);
> +  SubMultiClassReference ParseSubMultiClassReference(MultiClass  
> *CurMultiClass);
>
>   Init *ParseIDValue(Record *CurRec);
>   Init *ParseIDValue(Record *CurRec, const std::string &Name, TGLoc  
> NameLoc);
> @@ -101,6 +103,7 @@
>   RecTy *ParseType();
>   std::string ParseObjectName();
>   Record *ParseClassID();
> +  MultiClass *ParseMultiClassID();
>   Record *ParseDefmID();
> };
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list