I'm working on an out-of-tree target and am having some problems with rematerialization and spilling. The target's load and store instructions affect the condition code register (CCR). Describing this in the InstrInfo.td file using Defs = [CCR] certainly prevents spills and fills from being inserted where they might clobber CCR but it also prevents the load instruction from being rematerialized because it defines a physical register (TargetInstrInfo::isReallyTriviallyReMaterializableGeneric()). I've tried to take the approach that's used by the X86 target, in which instructions _are_ trivially rematerializable even if they implicitly define the condition code (EFLAGS) but must take care not to clobber EFLAGS if it's live at the point where the instruction is rematerialized. However, because my original load instruction implicitly defines CCR, and this isn't marked as dead, the instruction can't be deleted so the destination register is spilled anyway. I thought maybe I should pretend that load and store don't implicitly define CCR but then I'd need to prevent spill / fill when CCR is live, e.g. between compare instructions and conditional branch instructions. Would machine instruction bundles be the right way to do this? I'd be grateful for any advice.
On Jun 3, 2013, at 6:05 AM, Steve Montgomery <stephen.montgomery3 at btinternet.com> wrote:> I'm working on an out-of-tree target and am having some problems with rematerialization and spilling. > > The target's load and store instructions affect the condition code register (CCR). Describing this in the InstrInfo.td file using Defs = [CCR] certainly prevents spills and fills from being inserted where they might clobber CCR but it also prevents the load instruction from being rematerialized because it defines a physical register (TargetInstrInfo::isReallyTriviallyReMaterializableGeneric()). > > I've tried to take the approach that's used by the X86 target, in which instructions _are_ trivially rematerializable even if they implicitly define the condition code (EFLAGS) but must take care not to clobber EFLAGS if it's live at the point where the instruction is rematerialized. However, because my original load instruction implicitly defines CCR, and this isn't marked as dead, the instruction can't be deleted so the destination register is spilled anyway. > > I thought maybe I should pretend that load and store don't implicitly define CCR but then I'd need to prevent spill / fill when CCR is live, e.g. between compare instructions and conditional branch instructions. Would machine instruction bundles be the right way to do this?Hi Steve, LLVM’s register allocators assume that spills, fills, and copies can be safely inserted anywhere (except after terminator instructions). The register allocators simply can’t work without that assumption. As far as I know, your only option is to make sure that CCR is never live anywhere. This means that you need to create pseudo-instructions that bundle cmp+jump so the register allocator will never attempt to insert spill code between them. /jakob
Hi Jakob, thanks for the advice. I'll do as you suggest and make sure that CCR is never live. I can use pseudo-instructions to bundle cmp+jump but it's not ideal because I might also have to bundle cmp+jump+jump+... into a pseudo. Also, there are several flavours of cmp instruction so I might need a lot of pseudos. That's what led me to wonder whether MachineInstrBundles might be a neater solution but I wasn't sure whether they were really intended, or suitable, for this purpose. Steve On 3 Jun 2013, at 17:30, Jakob Stoklund Olesen <stoklund at 2pi.dk> wrote:> > On Jun 3, 2013, at 6:05 AM, Steve Montgomery <stephen.montgomery3 at btinternet.com> wrote: > >> I'm working on an out-of-tree target and am having some problems with rematerialization and spilling. >> >> The target's load and store instructions affect the condition code register (CCR). Describing this in the InstrInfo.td file using Defs = [CCR] certainly prevents spills and fills from being inserted where they might clobber CCR but it also prevents the load instruction from being rematerialized because it defines a physical register (TargetInstrInfo::isReallyTriviallyReMaterializableGeneric()). >> >> I've tried to take the approach that's used by the X86 target, in which instructions _are_ trivially rematerializable even if they implicitly define the condition code (EFLAGS) but must take care not to clobber EFLAGS if it's live at the point where the instruction is rematerialized. However, because my original load instruction implicitly defines CCR, and this isn't marked as dead, the instruction can't be deleted so the destination register is spilled anyway. >> >> I thought maybe I should pretend that load and store don't implicitly define CCR but then I'd need to prevent spill / fill when CCR is live, e.g. between compare instructions and conditional branch instructions. Would machine instruction bundles be the right way to do this? > > Hi Steve, > > LLVM’s register allocators assume that spills, fills, and copies can be safely inserted anywhere (except after terminator instructions). The register allocators simply can’t work without that assumption. > > As far as I know, your only option is to make sure that CCR is never live anywhere. This means that you need to create pseudo-instructions that bundle cmp+jump so the register allocator will never attempt to insert spill code between them. > > /jakob >
Maybe Matching Threads
- [LLVMdev] Rematerialization and spilling
- [LLVMdev] Rematerialization and spilling
- [LLVMdev] Rematerialization and spilling
- [LLVMdev] Rematerialization and spilling
- [LLVMdev] [Target] Custom Lowering expansion of 32-bit ISD::SHL, ISD::SHR without barrel shifter