I'm looking at an issue where we want a particular pseudo-instruction to
choose from a set of registers that is not included in the existing set of
RegisterClass definitions. More concretely, there is a RegisterClass in
ARMRegisterInfo.td defined as
def rGPR : RegisterClass<"ARM", [i32], 32, (sub GPR, SP, PC)> {
let AltOrders = [(add LR, rGPR), (trunc rGPR, 8)];
let AltOrderSelect = [{
return 1 +
MF.getTarget().getSubtarget<ARMSubtarget>().isThumb1Only();
}];
}
However, I'd like the instruction NOT to use the LR. I don't see an
existing
RegisterClass defined with R0_R12; something like:
def newGPR : RegisterClass<"ARM", [i32], 32, (add (sequence
"R%u", 0, 12))>;
I can add this new RegisterClass myself and then modify the
pseudo-instruction definition to simply use my new RegisterClass. However,
TableGen creates a set of dynamically created classes for GPRPairs that hold
all the various incarnations of GPRPair sets that correspond to various
RegisterClass definitions (like GPR pairs just for R0-R7, another for rGPR
that doesn't contain the SP, .).
If I add a new RegisterClass however, the dynamically created GPRPair class
corresponding to this new RegisterClass overlaps with the dynamically
created class for rGPR. In Thumb2InstrInfo.cpp, the dynamically created
TargetRegisterClass GPRPair_with_gsub_1_in_rGPRRegClass is explicitly called
out. If I add my new class, the class GPRPair_with_gsub_1_in_rGPRRegClass is
never created, instead the class GPRPair_with_gsub_1_in_newGPRRegClass is
created. Compilation therefore fails. I could simply rename the
RegisterClass so that it is alphabetically sorted after rGPR, but that seems
to simply be avoiding the real issue.
So, since I'm fairly new to LLVM, my question is, am I approaching this
correctly? Is adding a new RegisterClass something that is highly
discouraged? Is it better to force certain instructions to avoid certain
registers in the register allocation process? Should explicit references to
dynamically generated classes be done?
Thanks,
Daniel
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20130625/3cbb43de/attachment.html>
Hi Daniel,> So, since I’m fairly new to LLVM, my question is, am I approaching this > correctly? Is adding a new RegisterClass something that is highly > discouraged?I'd say it's OK. There are often good reasons to add a register class and that's far better than hacking regalloc for particular instructions. We don't want to do it frivolously, but that applies to anything really.> Should explicit references to dynamically generated classes be done?I'm neutral on that, personally. I'd say that if the dynamically generated name makes sense it's OK. But perhaps the best solution to this particular problem *would* be adding an rGPRPair RegisterClass and using that instead. It would probably make the code clearer and the class exists anyway. Cheers. Tim.
On Jun 25, 2013, at 7:10 AM, Daniel Stewart <stewartd at codeaurora.org> wrote:> If I add a new RegisterClass however, the dynamically created GPRPair class corresponding to this new RegisterClass overlaps with the dynamically created class for rGPR. In Thumb2InstrInfo.cpp, the dynamically created TargetRegisterClass GPRPair_with_gsub_1_in_rGPRRegClass is explicitly called out. If I add my new class, the class GPRPair_with_gsub_1_in_rGPRRegClass is never created, instead the class GPRPair_with_gsub_1_in_newGPRRegClass is created. Compilation therefore fails. I could simply rename the RegisterClass so that it is alphabetically sorted after rGPR, but that seems to simply be avoiding the real issue. > > Should explicit references to dynamically generated classes be done?In my opinion, no. If source code needs to refer to a register class by name, that class should be defined explicitly in the .td files. The present case is easy, though: if (ARM::GPRPairRegClass.hasSubClassEq(RC)) { // Thumb2 STRD expects its dest-registers to be in rGPR. Not a problem for // gsub_0, but needs an extra constraint for gsub_1 (which could be sp // otherwise). MachineRegisterInfo *MRI = &MF.getRegInfo(); MRI->constrainRegClass(SrcReg, &ARM::GPRPair_with_gsub_1_in_rGPRRegClass); The function TRI->getMatchingSuperRegClass(RC, ARM::rGPR, ARM::gsub1) provides the right register class whether it is named or synthetic. Alternatively, we could add API: MRI->constrainRegClassForSubReg(SrcReg, ARM::rGPR, ARM::gsub1). But defining an rGPRPair register class as Tim suggested would also work. /jakob
Reasonably Related Threads
- [LLVMdev] Definition of RegisterClass for load instruction in Thumb2
- [LLVMdev] Definition of RegisterClass for load instruction in Thumb2
- [LLVMdev] [RFC] Conditional RegClass membership
- [LLVMdev] Definition of RegisterClass for load instruction in Thumb2
- [LLVMdev] Tying an instruction to a specific set of registers