Alex Bradbury via llvm-dev
2016-Oct-08 19:52 UTC
[llvm-dev] RFC: Implement variable-sized register classes
On 4 October 2016 at 19:50, Krzysztof Parzyszek via llvm-dev <llvm-dev at lists.llvm.org> wrote:> If there are no objections, I'd like to start working on this soon... > > For the AMDGPU target this implies that RC->getSize will no longer be > available in the MC layer.Another advantage of this work that hasn't been mentioned yet is it will reduce the number of uses of isCodeGenOnly. The comment in Target.td indicates the long-term plan is to remove the distinction between isPseudo and isCodeGenOnly. A closely related to variable-sized register classes is the case where you have multiple registers with the same AsmName. This crops up in the same kind of cases where you have multiple instructions with the same encoding. Without a workaround, an assert is tripped in llvm-tblgen when trying to produce a StringSwitch for MatchRegisterName. The solution in Mips, PPC and others seems to be involve the generation of MatchRegisterName. What has been discussed so far with regards to HwMode and variable-size register classes points to a solution, but I don't think it's quite enough. Options include: 1. Only have one set of register definitions, and have the variable sized register class determine the bit width. The problem is there are often some instructions where I think you need to have registers modelled as subregisters. e.g. SLLW, ADDW etc in 64-bit RISC-V. These operate on 32-bit values and write the results sign-extended to the target 64-bit register. 2. Define both the 64-bit registers and the 32-bit subregisters, but make MatchRegisterName's behaviour change based on the HwMode. This works around the fact there are multiple registers with the same AsmName. Although I doubt this would actually cause problems, this still isn't quite right. For an `SLLIW x1, x2, 5` I think the correct interpretation would have x1 as a 64-bit target register and x2 as the 32-bit subregister that happens to have the same AsmName as the 64-bit x2 register. Have you thought about how the HwMode/variable-sized register class proposal might interact with register AsmNames at all? This old patch that never landed <http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20141201/246835.html> is also I think related. Backends like Mips and PPC end up defining RegisterOperand with a ParserMatchClass (in the Mips case, this specified the 'parseAnyRegister' ParserMethod. Adding a ParserMatchClass field to RegisterClass would be a minor simplification. Best, Alex
Alex Bradbury via llvm-dev
2016-Oct-09 12:38 UTC
[llvm-dev] RFC: Implement variable-sized register classes
On 8 October 2016 at 20:52, Alex Bradbury <asb at asbradbury.org> wrote:> A closely related to variable-sized register classes is the case where > you have multiple registers with the same AsmName. This crops up in > the same kind of cases where you have multiple instructions with the > same encoding. Without a workaround, an assert is tripped in > llvm-tblgen when trying to produce a StringSwitch for > MatchRegisterName. The solution in Mips, PPC and others seems to be > involve the generation of MatchRegisterName. What has been discussed > so far with regards to HwMode and variable-size register classes > points to a solution, but I don't think it's quite enough. Options > include: > > 1. Only have one set of register definitions, and have the variable > sized register class determine the bit width. The problem is there are > often some instructions where I think you need to have registers > modelled as subregisters. e.g. SLLW, ADDW etc in 64-bit RISC-V. These > operate on 32-bit values and write the results sign-extended to the > target 64-bit register. > > 2. Define both the 64-bit registers and the 32-bit subregisters, but > make MatchRegisterName's behaviour change based on the HwMode. This > works around the fact there are multiple registers with the same > AsmName. Although I doubt this would actually cause problems, this > still isn't quite right. For an `SLLIW x1, x2, 5` I think the correct > interpretation would have x1 as a 64-bit target register and x2 as the > 32-bit subregister that happens to have the same AsmName as the 64-bit > x2 register. > > Have you thought about how the HwMode/variable-sized register class > proposal might interact with register AsmNames at all?I've thought about this some more. In a future world supporting variable-sized register classes, you'd define one main set of registers with AltNames and and AsmName. The auto-generated MatchRegisterName and MatchRegisterAltName can be used for these. You might define 32-bit subregisters as well as an associated GPR32 reg class for use in instructions that need it, but these have no AltNames or AsmName. The AsmParser can convert parsed register numbers when desired (e.g. for SLLIW). In my case, I would define Xnn_XLEN registers for RISC-V. These are included in the 'GPR' variable-sized register class which makes use of HwMode. I would also need to define these as having Xnn_32 subregisters and define a GPR32 regclass. I think something similar could be done for MIPS. Apologies for thinking out loud, I'm just trying to work through how everything would fit together should we go with this approach. Alex
Krzysztof Parzyszek via llvm-dev
2016-Oct-21 17:48 UTC
[llvm-dev] RFC: Implement variable-sized register classes
On 10/8/2016 2:52 PM, Alex Bradbury wrote:> Have you thought about how the HwMode/variable-sized register class > proposal might interact with register AsmNames at all?I just had some time to think about it. The issue with this is that the register names are of interest to the MC layer, while the variable register size is handled on the Target level (i.e. TargetRegisterInfo). Instructions like ADDW and SLLIW still take 64-bit registers in a 64-bit mode, but they only access the low 32 bits. In your example, "SLLIW x1, x2, 5", both x1 and x2 would be 64-bit registers, but only the low 32 bits of x2 would be used. In the assembly source, the names of the 64-bit registers would be used, and the instruction semantics (ADD vs ADDW) would be the determining factor whether the whole register, or only a part of it is used (at least this is how I read the RISC-V spec). -Krzysztof -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Alex Bradbury via llvm-dev
2016-Oct-25 10:30 UTC
[llvm-dev] RFC: Implement variable-sized register classes
On 21 October 2016 at 18:48, Krzysztof Parzyszek <kparzysz at codeaurora.org> wrote:> On 10/8/2016 2:52 PM, Alex Bradbury wrote: >> >> Have you thought about how the HwMode/variable-sized register class >> proposal might interact with register AsmNames at all? > > > I just had some time to think about it. The issue with this is that the > register names are of interest to the MC layer, while the variable register > size is handled on the Target level (i.e. TargetRegisterInfo). > > Instructions like ADDW and SLLIW still take 64-bit registers in a 64-bit > mode, but they only access the low 32 bits. In your example, "SLLIW x1, x2, > 5", both x1 and x2 would be 64-bit registers, but only the low 32 bits of x2 > would be used. In the assembly source, the names of the 64-bit registers > would be used, and the instruction semantics (ADD vs ADDW) would be the > determining factor whether the whole register, or only a part of it is used > (at least this is how I read the RISC-V spec).Everything you say makes sense, though the way this situation is modelled by current in-tree architectures is to have the GPR32 register class contain registers that are subregisters of the GPR64 regs. See the instructions in Mips64InstrInfo.td that take a GPR32Opnd, or in PPCInstr64Bit.td that take a gprc, It's possible that it's not really essential to model the distinction between the 64-bit register with AsmName 'x4' and its 32-bit subregister that also has AsmName 'x4'. If the distinction isn't important, then obviously solely relying on the 'HwMode' is sufficient. Alex