[TableGen] Share the same predicate implementation between tablegen code literal and cpp files?

Hi,
An example use case is described below

  1. ImmLeaf pattern use code literals to describe the constraints on immediate operands (code)
def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{
  return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
}]> {
  let EncoderMethod = "getVecShiftR16OpValue";
  let DecoderMethod = "DecodeVecShiftR16ImmNarrow";
  let ParserMatchClass = Imm1_8Operand;
}
  1. The code literal is return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
  2. The use case is to do similar checks (in CodeGenPrepare.cpp) (e.g., before sinking an operand in order to help ISel). And sharing the predicate implementation prevents out-of-sync issues and minimize maintenance work to keep them in-sync in the future.

Is there a way (without advanced changes in llvm/utils/TableGen/ to change the interpretation of the ImmLeaf pattern) to share the same C++ predicate implementation between tablegen code literal and cpp files? Please advise what i miss, thanks!

  • By “advanced changes”, I’m imagining something like
    1. Adding another matcher field in ImmLeaf pattern (e.g. string fn) and points string fn to a C++ function name
    2. The C++ function pointed by string fn is used in cpp files.
    3. In order to interpret the added matcher field, some changes in llvm/utils/TableGen/ are needed.
  • My understanding is that ComplexPattern won’t work since it’s used to match DAG node, while CodeGenPrepare.cpp sees IR in this use case.

Hi,

why not put a function with the condition e.g. in a header file

bool IsCodeLiteral(uint32_t Imm) {
  return ((Imm) > 0) && ((Imm) < 9);
}

and call this function in the .td file:

def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{
  return IsCodeLiteral(uint32_t)Imm);
}]> {
  let EncoderMethod = "getVecShiftR16OpValue";
  let DecoderMethod = "DecodeVecShiftR16ImmNarrow";
  let ParserMatchClass = Imm1_8Operand;
}

?

Regards,
Kai

1 Like

This is a neat solution and exactly what I’m looking for!

I wasn’t aware a cpp function could be used directly in a tablegen pattern like this until now. Many thanks!