How to define macros in a tablegen file?

Hi,

I was wondering if there is a way to specify macros to help shorten
rewriting patterns like these:

def : Pat <(v4i8 (mul (v4i8 IntRegs:$a), (v4i8 IntRegs:$b))),
  (v4i8
   (VTRUNEHB
    (v4i16
     (VTRUNEWH
      (v2i32
       (VMPYH
        (v2i16
         (EXTRACT_SUBREG (v4i16 (VSXTBH (v4i8 IntRegs:$a))), subreg_hireg)),
        (v2i16
         (EXTRACT_SUBREG (v4i16 (VSXTBH (v4i8 IntRegs:$b))), subreg_hireg)))),
      (v2i32
       (VMPYH
        (v2i16
         (EXTRACT_SUBREG (v4i16 (VSXTBH (v4i8 IntRegs:$a))), subreg_loreg)),
        (v2i16
         (EXTRACT_SUBREG (v4i16 (VSXTBH (v4i8 IntRegs:$b))), subreg_loreg)))))))
  )>;

Basically if we have a way to name a dag foo to be this:
(EXTRACT_SUBREG (v4i16 (VSXTBH $X)), $Y)

and bar to stand for this:
(v2i32 (VMPYH (v2i16 (foo $X, $Z)), (v2i16 (foo $Y, $Z))))

then, I could write the same pattern in a shorter format:
def : Pat <(v4i8 (mul (v4i8 IntRegs:$a), (v4i8 IntRegs:$b))),
  (v4i8
   (VTRUNEHB
    (v4i16
     (VTRUNEWH (bar IntRegs:$a, IntRegs:$b, subreg_hireg),
               (bar IntRegs:$a, IntRegs:$b, subreg_loreg)))))
  >;

Thanks,
Sebastian

If the patterns only include SDNodes, then pattern fragments will work.

I might be wrong, but I've yet to find a way to do it with machine instructions, which is what you seem to have here.

Micah

Hi Micah,

For reference, here is how the SPU port is using code and pattern fragments:

// Holder of code fragments (you'd think this'd already be in
// a td file somewhere... :slight_smile:

class CodeFrag<dag frag> {
  dag Fragment = frag;
}

class I64SETCCNegCond<PatFrag cond, CodeFrag compare>:
  Pat<(cond R64C:$rA, R64C:$rB),
      (XORIr32 compare.Fragment, -1)>;

def : I64SETCCNegCond<setne, I64EQr64>;
def : I64SELECTNegCond<setne, I64EQr64>;

Sebastian

Interesting, I'll have to look into that. I have some pretty big pattern files I would love to refactor into simpler patterns.

Micah

And this comment makes me think, shouldn't this class CodeFrag be
included in the same place where PatFrag is declared:

./include/llvm/Target/TargetSelectionDAG.td:544:class PatFrag<dag ops,
dag frag, code pred = [{}],

such that we get it included through "llvm/Target/Target.td"?

I will prepare a patch for this.

Sebastian

Please see the attached patch. Ok to commit?

Thanks,
Sebastian

0001-move-CodeFrag-from-CellSPU-to-generic-code.patch (1.69 KB)

Possible to add a test case?

Micah

I am not really sure what I would check.

At first, I thought to add a testcase to test/TableGen; as this patch
does not modify tablegen, it doesn't make sense.

What kind of test should I write for this? The test should be a
tablegen file that includes "llvm/Target/TargetSelectionDAG.td" or
"llvm/Target/Target.td", and I haven't seen any of these in the
testsuite.

Sebastian

Ok, I was thinking there might be a test similar to PatFrag that could be created, but I noticed there are no tests for PatFrag either.

So that patch looks fine to me.

Micah

Sebastian,

If not a test, how about a patch in the documentation for TableGen about this new feature that you're making available?

That's a good point. I will prepare a patch for the docs.

Thanks for your review!
Sebastian

Make sure to pull from the repo because the TableGen docs have been moved from HTML to reStructuredText very, very recently; it would be unfortunate if you did your work on the now-nonexistent HTML version, only to find that that file no longer exists.

–Sean Silva

Ok, thanks for the heads up: I haven't started yet.

Sebastian