[llvm] r182872 - Teach ReMaterialization to be more cunning about subregisters
Evan Cheng
evan.cheng at apple.com
Wed May 29 13:26:18 PDT 2013
Nice. Is there measurable benefit for any specific target / benchmark?
Evan
On May 29, 2013, at 12:32 PM, Tim Northover <tnorthover at apple.com> wrote:
> Author: tnorthover
> Date: Wed May 29 14:32:06 2013
> New Revision: 182872
>
> URL: http://llvm.org/viewvc/llvm-project?rev=182872&view=rev
> Log:
> Teach ReMaterialization to be more cunning about subregisters
>
> This allows rematerialization during register coalescing to handle
> more cases involving operations like SUBREG_TO_REG which might need to
> be rematerialized using sub-register indices.
>
> For example, code like:
> v1(GPR64):sub_32 = MOVZ something
> v2(GPR64) = COPY v1(GPR64)
> should be convertable to:
> v2(GPR64):sub_32 = MOVZ something
>
> but previously we just gave up in places like this
>
> Modified:
> llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp
> llvm/trunk/test/CodeGen/AArch64/sibling-call.ll
> llvm/trunk/test/DebugInfo/AArch64/variable-loc.ll
>
> Modified: llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp?rev=182872&r1=182871&r2=182872&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp (original)
> +++ llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp Wed May 29 14:32:06 2013
> @@ -733,7 +733,9 @@ bool RegisterCoalescer::removeCopyByComm
> bool RegisterCoalescer::reMaterializeTrivialDef(CoalescerPair &CP,
> MachineInstr *CopyMI) {
> unsigned SrcReg = CP.isFlipped() ? CP.getDstReg() : CP.getSrcReg();
> + unsigned SrcIdx = CP.isFlipped() ? CP.getDstIdx() : CP.getSrcIdx();
> unsigned DstReg = CP.isFlipped() ? CP.getSrcReg() : CP.getDstReg();
> + unsigned DstIdx = CP.isFlipped() ? CP.getSrcIdx() : CP.getDstIdx();
> if (TargetRegisterInfo::isPhysicalRegister(SrcReg))
> return false;
>
> @@ -762,29 +764,38 @@ bool RegisterCoalescer::reMaterializeTri
> MachineOperand &DstOperand = CopyMI->getOperand(0);
> if (DstOperand.getSubReg() && !DstOperand.isUndef())
> return false;
> +
> + const TargetRegisterClass *DefRC = TII->getRegClass(MCID, 0, TRI, *MF);
> if (!DefMI->isImplicitDef()) {
> - // Make sure the copy destination register class fits the instruction
> - // definition register class. The mismatch can happen as a result of earlier
> - // extract_subreg, insert_subreg, subreg_to_reg coalescing.
> - const TargetRegisterClass *RC = TII->getRegClass(MCID, 0, TRI, *MF);
> - if (TargetRegisterInfo::isVirtualRegister(DstReg)) {
> - if (!MRI->constrainRegClass(DstReg, RC))
> + if (TargetRegisterInfo::isPhysicalRegister(DstReg)) {
> + unsigned NewDstReg = DstReg;
> +
> + unsigned NewDstIdx = TRI->composeSubRegIndices(CP.getSrcIdx(),
> + DefMI->getOperand(0).getSubReg());
> + if (NewDstIdx)
> + NewDstReg = TRI->getSubReg(DstReg, NewDstIdx);
> +
> + // Finally, make sure that the physical subregister that will be
> + // constructed later is permitted for the instruction.
> + if (!DefRC->contains(NewDstReg))
> return false;
> - } else if (!RC->contains(DstReg))
> - return false;
> + } else {
> + // Theoretically, some stack frame reference could exist. Just make sure
> + // it hasn't actually happened.
> + assert(TargetRegisterInfo::isVirtualRegister(DstReg) &&
> + "Only expect to deal with virtual or physical registers");
> + }
> }
>
> MachineBasicBlock *MBB = CopyMI->getParent();
> MachineBasicBlock::iterator MII =
> llvm::next(MachineBasicBlock::iterator(CopyMI));
> - TII->reMaterialize(*MBB, MII, DstReg, 0, DefMI, *TRI);
> + TII->reMaterialize(*MBB, MII, DstReg, SrcIdx, DefMI, *TRI);
> MachineInstr *NewMI = prior(MII);
>
> - // The original DefMI may have been a subregister def, but the full register
> - // class of its destination matches the destination of CopyMI, and CopyMI is
> - // either a full register def or is read-undef. Therefore we can clear the
> - // subregister index on the rematerialized instruction.
> - NewMI->getOperand(0).setSubReg(0);
> + LIS->ReplaceMachineInstrInMaps(CopyMI, NewMI);
> + CopyMI->eraseFromParent();
> + ErasedInstrs.insert(CopyMI);
>
> // NewMI may have dead implicit defs (E.g. EFLAGS for MOV<bits>r0 on X86).
> // We need to remember these so we can add intervals once we insert
> @@ -800,6 +811,46 @@ bool RegisterCoalescer::reMaterializeTri
> }
> }
>
> + if (TargetRegisterInfo::isVirtualRegister(DstReg)) {
> + unsigned NewIdx = NewMI->getOperand(0).getSubReg();
> + const TargetRegisterClass *RCForInst;
> + if (NewIdx)
> + RCForInst = TRI->getMatchingSuperRegClass(MRI->getRegClass(DstReg), DefRC,
> + NewIdx);
> +
> + if (MRI->constrainRegClass(DstReg, DefRC)) {
> + // The materialized instruction is quite capable of setting DstReg
> + // directly, but it may still have a now-trivial subregister index which
> + // we should clear.
> + NewMI->getOperand(0).setSubReg(0);
> + } else if (NewIdx && RCForInst) {
> + // The subreg index on NewMI is essential; we still have to make sure
> + // DstReg:idx is in a class that NewMI can use.
> + MRI->constrainRegClass(DstReg, RCForInst);
> + } else {
> + // DstReg is actually incompatible with NewMI, we have to move to a
> + // super-reg's class. This could come from a sequence like:
> + // GR32 = MOV32r0
> + // GR8 = COPY GR32:sub_8
> + MRI->setRegClass(DstReg, CP.getNewRC());
> + updateRegDefsUses(DstReg, DstReg, DstIdx);
> + NewMI->getOperand(0).setSubReg(
> + TRI->composeSubRegIndices(SrcIdx, DefMI->getOperand(0).getSubReg()));
> + }
> + } else if (NewMI->getOperand(0).getReg() != DstReg) {
> + // The New instruction may be defining a sub-register of what's actually
> + // been asked for. If so it must implicitly define the whole thing.
> + assert(TargetRegisterInfo::isPhysicalRegister(DstReg) &&
> + "Only expect virtual or physical registers in remat");
> + NewMI->addOperand(MachineOperand::CreateReg(DstReg,
> + true /*IsDef*/,
> + true /*IsImp*/,
> + false /*IsKill*/));
> + }
> +
> + if (NewMI->getOperand(0).getSubReg())
> + NewMI->getOperand(0).setIsUndef();
> +
> // CopyMI may have implicit operands, transfer them over to the newly
> // rematerialized instruction. And update implicit def interval valnos.
> for (unsigned i = CopyMI->getDesc().getNumOperands(),
> @@ -814,8 +865,6 @@ bool RegisterCoalescer::reMaterializeTri
> }
> }
>
> - LIS->ReplaceMachineInstrInMaps(CopyMI, NewMI);
> -
> SlotIndex NewMIIdx = LIS->getInstructionIndex(NewMI);
> for (unsigned i = 0, e = NewMIImplDefs.size(); i != e; ++i) {
> unsigned Reg = NewMIImplDefs[i];
> @@ -824,8 +873,6 @@ bool RegisterCoalescer::reMaterializeTri
> LI->createDeadDef(NewMIIdx.getRegSlot(), LIS->getVNInfoAllocator());
> }
>
> - CopyMI->eraseFromParent();
> - ErasedInstrs.insert(CopyMI);
> DEBUG(dbgs() << "Remat: " << *NewMI);
> ++NumReMats;
>
>
> Modified: llvm/trunk/test/CodeGen/AArch64/sibling-call.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/sibling-call.ll?rev=182872&r1=182871&r2=182872&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/AArch64/sibling-call.ll (original)
> +++ llvm/trunk/test/CodeGen/AArch64/sibling-call.ll Wed May 29 14:32:06 2013
> @@ -91,7 +91,7 @@ define void @indirect_tail() {
> %fptr = load void(i32)** @func
> tail call void %fptr(i32 42)
> ret void
> -; CHECK: movz w0, #42
> ; CHECK: ldr [[FPTR:x[1-9]+]], [{{x[0-9]+}}, #:lo12:func]
> +; CHECK: movz w0, #42
> ; CHECK: br [[FPTR]]
> -}
> \ No newline at end of file
> +}
>
> Modified: llvm/trunk/test/DebugInfo/AArch64/variable-loc.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/AArch64/variable-loc.ll?rev=182872&r1=182871&r2=182872&view=diff
> ==============================================================================
> --- llvm/trunk/test/DebugInfo/AArch64/variable-loc.ll (original)
> +++ llvm/trunk/test/DebugInfo/AArch64/variable-loc.ll Wed May 29 14:32:06 2013
> @@ -16,21 +16,21 @@
> ; return 0;
> ; }
>
> - ; First make sure main_arr is where we expect it: sp + 12 == x29 - 420:
> + ; First make sure main_arr is where we expect it: sp + 4 == x29 - 412:
> ; CHECK: main:
> -; CHECK: sub sp, sp, #448
> -; CHECK: stp x29, x30, [sp, #432]
> -; CHECK: add x29, sp, #432
> -; CHECK: add {{x[0-9]+}}, sp, #12
> +; CHECK: sub sp, sp, #432
> +; CHECK: stp x29, x30, [sp, #416]
> +; CHECK: add x29, sp, #416
> +; CHECK: add {{x[0-9]+}}, sp, #4
>
> ; Now check the debugging information reflects this:
> ; CHECK: DW_TAG_variable
> ; CHECK-NEXT: .word .Linfo_string7
>
> - ; Rather hard-coded, but 145 => DW_OP_fbreg and the .ascii is LEB128 encoded -420.
> + ; Rather hard-coded, but 145 => DW_OP_fbreg and the .ascii is LEB128 encoded -412.
> ; CHECK: DW_AT_location
> ; CHECK-NEXT: .byte 145
> -; CHECK-NEXT: .ascii "\334|"
> +; CHECK-NEXT: .ascii "\344|"
>
> ; CHECK: .Linfo_string7:
> ; CHECK-NEXT: main_arr
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list