[PATCH] D127739: [TableGen] Check if input string of !isa is an instance of record type

Wang Pengcheng via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 14 22:28:02 PDT 2022


pcwang-thead added a comment.

In D127739#3582408 <https://reviews.llvm.org/D127739#3582408>, @tra wrote:

> Do you have a practical use case where this feature would be needed?

Yes.
In RISCV backend, we have defined some pseudos for Vector extension, and we construct a table which maps pseudos to real instructions. These mappings are constructed by pseudos' name (see https://github.com/llvm/llvm-project/blob/06c6758a98161262ac97fad42248139d78d39581/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td#L429). For example, we have a Pseudo named `PseudoVADD_VV_M1` and an Instruction named `VADD_VV`, we can connect them together with string substitutions of pseudo name, that is, `!subst("_M1", "", !subst("Pseudo", "", PseudoName))` (see also https://github.com/llvm/llvm-project/blob/06c6758a98161262ac97fad42248139d78d39581/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td#L49), and then, a `!cast` will cast instruction name to real Instruction record. The casting works because corresponding instruction always exists.
Our downstream would like to map these pseudos to other instructions, but not all pseudos have corresponding instructions. We use almost the same substitutions to map pseudo name to new instruction name, that is, `!subst("_M1", "", !subst("Pseudo", "New_", PseudoName))`. So `PseudoVADD_VV_M1` will be mapped to `NEW_VADD_VV`. The key point is that pseudos may have no corresponding new instruction and `!cast` may be failed. So we wanna check if `!cast` would success and set a default noop instruction (like KILL instruction) if failed.

>> TableGen will raise an error if failed to cast
>
> This may be considered to be a feature. If you attempt to cast to a record that does not exist, then arguably something went wrong.
>
> While I generally do agree that we don't have a good way to handle non-existing casts, I'm not convinced that `!isa` is the right place to deal with the issue.
> If we want/need to check whether a record with a given name exists, then we'll probably need a new operator.

I have considered adding a new operator `!instanceof<T>(s)` to check if whether a record with type `T` and name `s` exists, but I think `!isa` have the same semantic meaning with `!instanceof`, just like what we have in C++ code (https://llvm.org/docs/ProgrammersManual.html#the-isa-cast-and-dyn-cast-templates):

> isa<>:
> The isa<> operator works exactly like the Java “instanceof” operator. It returns true or false depending on whether a reference or pointer points to an instance of the specified class. This can be very useful for constraint checking of various sorts (example below).

So I tried to extend `!isa` first.

> E.g. I may want `!isa<R>(x)` to be false for any 'x' that's not an instance of `R`, even if `x` is a string with a value that matches the name of an existing record of `R`?

I don't know if this feature is needed, I haven't found any usage like this in upstream. The most common scenario where we need a `!isa` is, we pass a record of superclass and then check if it is an instance of some subclasses.

> Or, perhaps, we should consider extending `!cast` to accept an additional value to be returned if the cast has failed.

Agree, this can be feasible. I will have a try, but I still think we need something like `!instanceof`. :-)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D127739/new/

https://reviews.llvm.org/D127739



More information about the llvm-commits mailing list