[LLVMdev] Reducing .td redundancy

David Greene dag at cray.com
Tue Mar 24 13:15:17 PDT 2009


On Tuesday 24 March 2009 12:04, David Greene wrote:

> multiclass myintrinsics<bits<8> opc, string OpcodeStr, Intrinsic Intr> {
>    // Scalar intrinsics
>   def SSrr_Int SSI<opc, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src1, FR32:
> $src2),
>                  !strconcat(OpcodeStr, "ss\t{$src2, $dst|$dst, $src2}"),
>                  [(set FR32:$dst, (SOME_CONCAT(Intr, _ss) FR32:$src1, FR32:
> $src2))]> {
>
>   def SDrr_Int SSI<opc, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src1, FR64:
> $src2),
>                  !strconcat(OpcodeStr, "ss\t{$src2, $dst|$dst, $src2}"),
>                  [(set FR32:$dst, (SOME_CONCAT(Intr, _sd) FR32:$src1, FR32:
> $src2))]> {
> }
>
> defm ADD : myintrinsics<0x58, "add",  int_x86_sse2_add>;
>
> I want the single ADD defm to generate patterns for both the "ss" and "sd"
> intrinsic variants.  I need a way to append "_ss" or "_sd" to the intrinsic
> name in the pattern.
>
> I don't believe there's any way to do this right now but I'm looking into
> it. I'm currently stepping through TableGen to figure out when pattern
> fragments (which get instantiated as CodeInits if I understand correctly)
> have their arguments substituted.  At that point I want to scan the pattern
> and look for special concat operations and munge the resulting strings /
> names / whatever to do the right thing.  Any hints on where to look?

So I figured out the magic happens in VarInit::resolveReferences as called
by TGParser::ParseDefm.  Now I have to figure out how to substitute a
different Init for the one returned by R:

/// resolveReferences - This method is used by classes that refer to other
/// variables which may not be defined at the time they expression is formed.
/// If a value is set for the variable later, this method will be called on
/// users of the value to allow the value to propagate out.
///
Init *VarInit::resolveReferences(Record &R, const RecordVal *RV) {
  if (RecordVal *Val = R.getValue(VarName))
    if (RV == Val || (RV == 0 && !dynamic_cast<UnsetInit*>(Val->getValue())))
       /******* Do some trickiness here to munge the result ********/
      return Val->getValue();
  return this;
}

I was thinking about using a ## paste operator to indicate that names should 
be glued together.  Let's say as in our example, the value for Intr is 
int_x86_sse2_add.  That will be the value returned by 
VarInit::resolveReferences.  How do I get a pointer to the Init for, say, 
int_x86_sse2_add_ss (the value I want after concatenation) so I can return 
that instead?  Can I just create one?  My assumption is that Inits are unique 
objects and that creating duplicates would be a bad idea.

                                                 -Dave




More information about the llvm-dev mailing list