[PATCH][TableGen] Fully resolve class-instance values before defs in multiclasses

Tom Stellard tom at stellard.net
Thu Sep 11 12:56:11 PDT 2014


On Wed, Sep 10, 2014 at 05:56:57PM -0700, Adam Nemet wrote:
> By class-instance values I mean 'Class<Arg>' in 'Class<Arg>.Field' or in
> 'Other<Class<Arg>>' (syntactically a SimpleValue).  This is to differentiate
> from unnamed/anonymous record definitions (syntactically an ObjectBody) which
> are not affected by this change.
> 
> Consider the testcase:
> 
>     class Struct<int i> {
>       int I = !shl(i, 1);
>       int J = !shl(I, 1);
>     }
> 
>     class Class<Struct s> {
>         int Class_J = s.J;
>     }
> 
>     multiclass MultiClass<int i> {
>       def Def : Class<Struct<i>>;
>     }
> 
>     defm Defm : MultiClass<2>;
> 
> Before this fix, DefmDef.Class_J yields !shl(I, 1) instead of 8.
> 
> This is the sequence of events.  We start with this:
> 
>     multiclass MultiClass<int i> {
>       def Def : Class<Struct<i>>;
>     }
> 
> During ParseDef the anonymous object for the class-instance value is created:
> 
>     multiclass Multiclass<int i> {
>       def anonymous_0 : Struct<i>;
> 
>       def Def : Class<NAME#anonymous_0>;
>     }
> 
> Then class Struct<i> is added to anonymous_0.  Also Class<NAME#anonymous_0> is
> added to Def:
> 
>     multiclass Multiclass<int i> {
>       def anonymous_0 {
>         int I = !shl(i, 1);
>         int J = !shl(I, 1);
>       }
> 
>       def Def {
>         int Class_J = NAME#anonymous_0.J;
>       }
>     }
> 
> So far so good but then we move on to instantiating this in the defm
> by substituting the template arg 'i'.
> 
> This is how the anonymous prototype looks after fully instantiating.
> 
>     defm Defm = {
>       def Defmanonymous_0 {
>          int I = 4;
>          int J = !shl(I, 1);
>       }
> 
> Note that we only resolved the reference to the template arg.  The
> non-template-arg reference in 'J' has not been resolved yet.
> 
> Then we go on to instantiating the Def prototype:
> 
>       def DefmDef {
>          int Class_J = NAME#anonymous_0.J;
>       }
> 
> Which is resolved to Defmanonymous_0.J and then to !shl(I, 1).
> 
> When we fully resolve each record in a defm, Defmanonymous_0.J does get set to 8
> but that's too late for its use.
> 
> The patch adds a new attribute to the Record class that indicates that this
> def is actually a class-instance value that may be *used* by other defs
> in a multiclass.  (This is unlike regular defs which don't reference each
> other and thus can be resolved independently.)  These are then fully resolved before the
> other defs while the multiclass is instantiated.
> 

Hi Adam,

Is there any reason why your patch works on defs inside multiclasses and not all
defs?  I'm running into a similar problem with this example:

class A <bits<2> op> {
  field bits<2> OP = op;
}

class B <bits <2> op> {
  field A OP = A<op>;
}

def : B <0>;

As you can see, the value of B.OP.OP fails to resolve:

------------- Classes -----------------
class A<bits<2> A:op = { ?, ? }> {
  field bits<2> OP = { A:op{1}, A:op{0} };
  string NAME = ?;
}
class B<bits<2> B:op = { ?, ? }> {
  field A OP = anonymous_0;
  string NAME = ?;
}
------------- Defs -----------------
def anonymous_0 {       // A
  field bits<2> OP = { B:op{1}, B:op{0} };
  string NAME = ?;
}
def anonymous_1 {       // B
  field A OP = anonymous_0;
  string NAME = ?;
}

I'm wondering if modifying your patch to work everywhere and not just
in multiclasses will fix this.  Do you think this might work?

Thanks,
Tom



> I added vg_leak to the new test.  I am not sure if this is necessary but I
> don't think I have a way to test it.  I can also check in without the XFAIL
> and let the bots test this part.
> 
> Also tested that X86.td.expanded and AAarch64.td.expanded were unchange before
> and after this change.  (This issue triggering this problem is a WIP patch.)
> 
> Part of <rdar://problem/17688758>
> 
> Please let me know if it looks good.
> 
> Thanks,
> Adam
> 


> _______________________________________________
> 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