mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
ARM load/store optimizer: Don't materialize a new base register with
ADDS/SUBS unless it's safe to clobber the condition flags. If the merged instructions are in a range where the CPSR is live, e.g. between a CMP -> Bcc, we can't safely materialize a new base register. This problem is quite rare, I couldn't come up with a test case and I've never actually seen this happen in the tests I'm running - there is a potential trigger for this in LNT/oggenc (spills being inserted between a CMP/Bcc), but at the moment this isn't being merged. I'll try to reduce that into a small test case once I've committed my upcoming patch to make merging less conservative. llvm-svn: 217881
This commit is contained in:
parent
52a36b272a
commit
735d692499
@ -323,6 +323,12 @@ ARMLoadStoreOpt::MergeOps(MachineBasicBlock &MBB,
|
|||||||
if (NumRegs <= 1)
|
if (NumRegs <= 1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// For Thumb1 targets, it might be necessary to clobber the CPSR to merge.
|
||||||
|
// Compute liveness information for that register to make the decision.
|
||||||
|
bool SafeToClobberCPSR = !isThumb1 ||
|
||||||
|
(MBB.computeRegisterLiveness(TRI, ARM::CPSR, std::prev(MBBI), 15) ==
|
||||||
|
MachineBasicBlock::LQR_Dead);
|
||||||
|
|
||||||
ARM_AM::AMSubMode Mode = ARM_AM::ia;
|
ARM_AM::AMSubMode Mode = ARM_AM::ia;
|
||||||
// VFP and Thumb2 do not support IB or DA modes. Thumb1 only supports IA.
|
// VFP and Thumb2 do not support IB or DA modes. Thumb1 only supports IA.
|
||||||
bool isNotVFP = isi32Load(Opcode) || isi32Store(Opcode);
|
bool isNotVFP = isi32Load(Opcode) || isi32Store(Opcode);
|
||||||
@ -346,6 +352,11 @@ ARMLoadStoreOpt::MergeOps(MachineBasicBlock &MBB,
|
|||||||
if (NumRegs <= 2)
|
if (NumRegs <= 2)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// On Thumb1, it's not worth materializing a new base register without
|
||||||
|
// clobbering the CPSR (i.e. not using ADDS/SUBS).
|
||||||
|
if (!SafeToClobberCPSR)
|
||||||
|
return false;
|
||||||
|
|
||||||
unsigned NewBase;
|
unsigned NewBase;
|
||||||
if (isi32Load(Opcode)) {
|
if (isi32Load(Opcode)) {
|
||||||
// If it is a load, then just use one of the destination register to
|
// If it is a load, then just use one of the destination register to
|
||||||
@ -377,10 +388,10 @@ ARMLoadStoreOpt::MergeOps(MachineBasicBlock &MBB,
|
|||||||
|
|
||||||
if (isThumb1) {
|
if (isThumb1) {
|
||||||
// Thumb1: depending on immediate size, use either
|
// Thumb1: depending on immediate size, use either
|
||||||
// ADD NewBase, Base, #imm3
|
// ADDS NewBase, Base, #imm3
|
||||||
// or
|
// or
|
||||||
// MOV NewBase, Base
|
// MOV NewBase, Base
|
||||||
// ADD NewBase, #imm8.
|
// ADDS NewBase, #imm8.
|
||||||
if (Base != NewBase && Offset >= 8) {
|
if (Base != NewBase && Offset >= 8) {
|
||||||
// Need to insert a MOV to the new base first.
|
// Need to insert a MOV to the new base first.
|
||||||
BuildMI(MBB, MBBI, dl, TII->get(ARM::tMOVr), NewBase)
|
BuildMI(MBB, MBBI, dl, TII->get(ARM::tMOVr), NewBase)
|
||||||
@ -390,7 +401,7 @@ ARMLoadStoreOpt::MergeOps(MachineBasicBlock &MBB,
|
|||||||
Base = NewBase;
|
Base = NewBase;
|
||||||
BaseKill = false;
|
BaseKill = false;
|
||||||
}
|
}
|
||||||
AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII->get(BaseOpc), NewBase))
|
AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII->get(BaseOpc), NewBase), true)
|
||||||
.addReg(Base, getKillRegState(BaseKill)).addImm(Offset)
|
.addReg(Base, getKillRegState(BaseKill)).addImm(Offset)
|
||||||
.addImm(Pred).addReg(PredReg);
|
.addImm(Pred).addReg(PredReg);
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user