Hi, guys
I often feel that TableGen’s error messages are not very user-friendly.
I would suggest adding more helpful hints, such as explanations for why certain types could not be inferred. There are quite a few similar requests for help online as well.
I think I know what you’re talking about. But I believe it’s not TableGen the language’s issue but the infrastructure (e.g. utils/TableGen/Common/CodeGenInstruction.h) for various of TableGen backends for CodeGen.
That said, I agree that some of the error messages w.r.t ValueType inferring is not helpful at all. It has been a while since I ran into one so I don’t have any examples handy at this moment, could you provide some examples?
The type inference in TableGen is a strong source of difficult to fix error messages. I’ve been meaning to add tracing to it, that would show the individual steps that lead to the failure, but I never found time to do that. I think that it’s still something that would be very helpful.
We also have to solve another more fundamental problem first: there is no SMLoc attached on Init. I think it’s simply an oversight rather than a technical challenge (granted, we have to merge SMLoc when simplifying some of the expressions) and it just so happened that no one tried to fix it.
The type information is indexed by the so called “hardware mode”. HwMode is something like an enum that indicates the hardware configuration. It could be something like “32-bit mode” or “64-bit mode”. The assumption here is that the instructions are essentially the same for both modes, and only the register size is different (plus the data types that the register can hold).
Most targets don’t use HwModes, but even then there is an implicit one—the default HwMode. This one is present for all targets.
The way to read xxx:{ *:[] m1:[i64] } is that it’s a map that for each HwMode lists all the types that xxx can have. HwModes (the keys in the map) are ‘*’ (aka m0), m1,etc.The * indicates the default HwMode (which internally has the value of 0).
For each key, the value is the list of types for this particular HwMode. The list can be empty, which means that no types are available. This may or may not be a problem, depending on what TableGen is trying to do at that time. In your case this is an issue, since TableGen is trying to infer all types, and wasn’t able to do that for the default mode. Type inference mostly works by first assuming all possible types, then eliminating those that don’t meet given requirements or constraints. It can happen that it will eliminate all types, and that can be an indication of a problem.
Further to @kparzysz’s guidance, I think the specific problem here is that for hwmode m1, the inference process has not reduced operand 0 on the second line to a single type - which it would prefer to do. If you can, wrap this part of the pattern in an explicit type, using (<type> <operand>) rather than just <operand>. You’ll likely want <type> to be a ValueTypeByHWMode, so that operand can have different types for different modes (this is what XLenVT does in the RISC-V backend, and it commonly appears on both the match and the result side of a Pattern).