mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-02 09:33:59 +00:00
Permit remat of partial register defs when it is safe.
An instruction may define part of a register where the other bits are undefined. In that case, it is safe to rematerialize the instruction. For example: %vreg2:ssub_0<def> = VLDRS <cp#0>, 0, pred:14, pred:%noreg, %vreg2<imp-def> The extra <imp-def> operand indicates that the instruction does not read the other parts of the virtual register, so a remat is safe. This patch simply allows multiple def operands for the virtual register. It is MI->readsVirtualRegister() that determines if we depend on a previous value so remat is impossible. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@138953 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
2f25d9b933
commit
4a0a18af4a
@ -362,13 +362,17 @@ isReallyTriviallyReMaterializableGeneric(const MachineInstr *MI,
|
|||||||
const TargetInstrInfo &TII = *TM.getInstrInfo();
|
const TargetInstrInfo &TII = *TM.getInstrInfo();
|
||||||
const TargetRegisterInfo &TRI = *TM.getRegisterInfo();
|
const TargetRegisterInfo &TRI = *TM.getRegisterInfo();
|
||||||
|
|
||||||
|
// Remat clients assume operand 0 is the defined register.
|
||||||
|
if (!MI->getNumOperands() || !MI->getOperand(0).isReg())
|
||||||
|
return false;
|
||||||
|
unsigned DefReg = MI->getOperand(0).getReg();
|
||||||
|
|
||||||
// A sub-register definition can only be rematerialized if the instruction
|
// A sub-register definition can only be rematerialized if the instruction
|
||||||
// doesn't read the other parts of the register. Otherwise it is really a
|
// doesn't read the other parts of the register. Otherwise it is really a
|
||||||
// read-modify-write operation on the full virtual register which cannot be
|
// read-modify-write operation on the full virtual register which cannot be
|
||||||
// moved safely.
|
// moved safely.
|
||||||
unsigned Reg = MI->getOperand(0).getReg();
|
if (TargetRegisterInfo::isVirtualRegister(DefReg) &&
|
||||||
if (TargetRegisterInfo::isVirtualRegister(Reg) &&
|
MI->getOperand(0).getSubReg() && MI->readsVirtualRegister(DefReg))
|
||||||
MI->getOperand(0).getSubReg() && MI->readsVirtualRegister(Reg))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// A load from a fixed stack slot can be rematerialized. This may be
|
// A load from a fixed stack slot can be rematerialized. This may be
|
||||||
@ -430,8 +434,9 @@ isReallyTriviallyReMaterializableGeneric(const MachineInstr *MI,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only allow one virtual-register def, and that in the first operand.
|
// Only allow one virtual-register def. There may be multiple defs of the
|
||||||
if (MO.isDef() != (i == 0))
|
// same virtual register, though.
|
||||||
|
if (MO.isDef() && Reg != DefReg)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Don't allow any virtual-register uses. Rematting an instruction with
|
// Don't allow any virtual-register uses. Rematting an instruction with
|
||||||
|
@ -26,3 +26,27 @@ define void @f1(float %x, <2 x float>* %p) {
|
|||||||
store <2 x float> %v2, <2 x float>* %p, align 8
|
store <2 x float> %v2, <2 x float>* %p, align 8
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; On the other hand, when the partial redef doesn't read the full register
|
||||||
|
; because the bits are undef, we should rematerialize. The vector is now built
|
||||||
|
; like this:
|
||||||
|
;
|
||||||
|
; %vreg2:ssub_0<def> = VLDRS <cp#0>, 0, pred:14, pred:%noreg, %vreg2<imp-def>; mem:LD4[ConstantPool]
|
||||||
|
;
|
||||||
|
; The extra <imp-def> operand indicates that the instruction fully defines the
|
||||||
|
; virtual register. It doesn't read the old value.
|
||||||
|
;
|
||||||
|
; CHECK: f2
|
||||||
|
; CHECK: vldr.32 s0, LCPI
|
||||||
|
; The vector must not be spilled:
|
||||||
|
; CHECK-NOT: vstr.64
|
||||||
|
; CHECK: asm clobber d0
|
||||||
|
; But instead rematerialize after the asm:
|
||||||
|
; CHECK: vldr.32 [[S0:s[0-9]+]], LCPI
|
||||||
|
; CHECK: vstr.64 [[D0:d[0-9]+]], [r0]
|
||||||
|
define void @f2(<2 x float>* %p) {
|
||||||
|
%v2 = insertelement <2 x float> undef, float 0x400921FB60000000, i32 0
|
||||||
|
%y = call double asm sideeffect "asm clobber $0", "=w,0,~{d1},~{d2},~{d3},~{d4},~{d5},~{d6},~{d7},~{d8},~{d9},~{d10},~{d11},~{d12},~{d13},~{d14},~{d15},~{d16},~{d17},~{d18},~{d19},~{d20},~{d21},~{d22},~{d23},~{d24},~{d25},~{d26},~{d27},~{d28},~{d29},~{d30},~{d31}"(<2 x float> %v2) nounwind
|
||||||
|
store <2 x float> %v2, <2 x float>* %p, align 8
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user