When generating matching tables for GlobalISel, TableGen would output
"::zero_reg" whenever encountering the zero_reg, which in turn would
result in compilation error. This patch fixes that by instead outputting
NoRegister (== 0), which is the same result that TableGen produces when
generating matching tables for ISelDAG.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
llvm/utils/TableGen/GlobalISelEmitter.cpp | ||
---|---|---|
2652 | Could this use TargetNamespace::NoRegister? |
llvm/utils/TableGen/GlobalISelEmitter.cpp | ||
---|---|---|
2652 | I suppose that works. I checked for our target and NoRegister is indeed assigned value 0, so the semantics would be the same. But I am not sure whether that would work for all targets. If it does, I do believe your suggestion to be a better solution than to simply output value 0. Perhaps someone more knowledgeable regarding TableGen could comment on this? |
llvm/utils/TableGen/GlobalISelEmitter.cpp | ||
---|---|---|
2652 | That's generated for all targets. 0 is always $noreg, with an added NoRegister entry. I also think zero_reg should really be renamed to $noreg or something closer to what it really is |
llvm/utils/TableGen/GlobalISelEmitter.cpp | ||
---|---|---|
2652 | Agree zero_reg is not a good name if this refers to NoRegister (register number zero in the internal representation). I would have guessed that it mapped to a register always being read as zero (if the target got such a register). Changing the name is perhaps outside the scope of this patch. But we better (make sure) clarify that zero_reg is NoRegister (holding an undefined value, rather than holding the value zero). |
llvm/utils/TableGen/GlobalISelEmitter.cpp | ||
---|---|---|
2652 | Looking into the Target/Target.td file where zero_reg is defined, it says the following: /// zero_reg definition - Special node to stand for the zero register. /// def zero_reg; Is "zero register" and "NoRegister" really the same thing? If not, what should then be output? |
llvm/utils/TableGen/GlobalISelEmitter.cpp | ||
---|---|---|
2652 | MIRLangRef also talks about "The null registers". I think that TargetNamespace::NoRegister, zero_reg, null registers, _ (in MIR and dumps) and $noreg more or less all refer to the same thing - register number zero. But perhaps some targets could map a register always being read as zero to $noreg, e.g. translating that specifier to register number 31 in the asm printer. It is confusing to have that many different names for the same thing. And to me zero_reg and null register is most confusing as there are targets that have registers always being read as zero (and the register number for such a register could be any number). So unless zero_reg actually is supposed to refer to a register being read as zero, it would be better to for example call it noreg or reg_null. Looks like SystemZ got one use of zero_reg, and the rest belongs to ARM. |
llvm/utils/TableGen/GlobalISelEmitter.cpp | ||
---|---|---|
2652 | Then I suppose we will continue outputting "NoRegister"; I just need to figure out how to retrieve the "NameSpace" from the zero_reg directive, since that's not immediately available... |
llvm/utils/TableGen/GlobalISelEmitter.cpp | ||
---|---|---|
2652 | Actually I think the code would work as is for this. If you look at CopyOrAddZeroRegRenderer, << MatchTable::NamedValue( (ZeroRegisterDef->getValue("Namespace") ? ZeroRegisterDef->getValueAsString("Namespace") : ""), |
llvm/utils/TableGen/GlobalISelEmitter.cpp | ||
---|---|---|
2652 | I have looked into that but RegisterDef does not have "Namespace" in the case of zero_reg, so I need to retrieve the namespace information elsewhere. |
llvm/utils/TableGen/GlobalISelEmitter.cpp | ||
---|---|---|
2652 | So this check for the namespace is pointless and should be removed? |
[TableGen][GlobalISel] Fix handling of zero_reg
When generating matching tables for GlobalISel, TableGen would output
"::zero_reg" whenever encountering the zero_reg, which in turn would
result in compilation error. This patch fixes that by instead outputting
NoRegister (== 0), which is the same result that TableGen produces when
generating matching tables for ISelDAG.
llvm/utils/TableGen/GlobalISelEmitter.cpp | ||
---|---|---|
2652 | In the case of ZeroRegisterDef it seems to be a different story, as ZeroRegisterDef takes the value of GIZeroRegister whenever it is used, which could be any kind of register which may or may not have a Namespace. In the case of zero_reg, however, it always does not have a Namespace. I have now updated the patch to look over the defs present in the target in search of a valid Namespace, so now we can use NoRegister (although the fix for this feels hacky, to me). |
llvm/utils/TableGen/GlobalISelEmitter.cpp | ||
---|---|---|
2665 | Maybe one can add something like this to CodeGenTaget (putting the code close to the getInstNamespace support): StringRef CodeGenTarget::getRegNamespace() const { auto &RegClasses = RegBank.getRegClasses(); return RegClasses.size() > 0 ? RegClasses.front().Namespace : ""; } and then use Target.getRegNamespace() to get it. |
llvm/utils/TableGen/CodeGenTarget.cpp | ||
---|---|---|
554 | Is using a different namespace from the overall target actually supported? Can't you just take the namespace from CodeGenTarget directly? |
llvm/utils/TableGen/CodeGenTarget.cpp | ||
---|---|---|
552 | Just like in the header file. I'd rather put this next to getInstNamespace. This would also show more clearly that we currently fetch the namespaces in different ways, and by that we perhaps support different namespaces for regs and instructions etc. I have no idea if that is used (or useful) in reality. I figure that we at least wouldn't break anything as long as we follow what CodeGenRegisters is using when defining the enum with NoRegister, when fetching the getRegNamespace. | |
llvm/utils/TableGen/CodeGenTarget.h | ||
197 | I'd put this next to getInstNamespace(). Or if for some reason it would be better to keep "inst" helpers and "reg" helpers separated, then I'd put it next to something related to registers such as getRegBank or getRegRegisterByName. But I can't see any logic in the current order of methods (it's even mixing public and private declarations), so that's why I'd got for keeping the namespace-related functions close to each other. |
clang-format not found in user's PATH; not linting file.