[llvm-commits] CVS: llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
Evan Cheng
evan.cheng at apple.com
Tue Mar 6 13:59:37 PST 2007
Changes in directory llvm/lib/Target/ARM:
ARMLoadStoreOptimizer.cpp updated: 1.2 -> 1.3
---
Log message:
Make load / store optimizer use register scavenger.
---
Diffs of the changes: (+58 -21)
ARMLoadStoreOptimizer.cpp | 79 +++++++++++++++++++++++++++++++++-------------
1 files changed, 58 insertions(+), 21 deletions(-)
Index: llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
diff -u llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp:1.2 llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp:1.3
--- llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp:1.2 Tue Mar 6 12:02:41 2007
+++ llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp Tue Mar 6 15:59:20 2007
@@ -59,6 +59,8 @@
typedef SmallVector<MemOpQueueEntry,8> MemOpQueue;
typedef MemOpQueue::iterator MemOpQueueIter;
+ void AdvanceRS(MachineBasicBlock *MBB, MemOpQueue &MemOps);
+
SmallVector<MachineBasicBlock::iterator, 4>
MergeLDR_STR(MachineBasicBlock &MBB, unsigned SIndex, unsigned Base,
int Opcode, unsigned Size, MemOpQueue &MemOps);
@@ -103,8 +105,9 @@
/// registers in Regs as the register operands that would be loaded / stored.
/// It returns true if the transformation is done.
static bool mergeOps(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
- int Offset, unsigned Base, int Opcode,
- SmallVector<unsigned, 8> &Regs,
+ int Offset, unsigned Base, bool BaseKill, int Opcode,
+ SmallVector<std::pair<unsigned, bool>, 8> &Regs,
+ RegScavenger *RS,
const TargetInstrInfo *TII) {
// Only a single register to load / store. Don't bother.
unsigned NumRegs = Regs.size();
@@ -130,10 +133,12 @@
if (Opcode == ARM::LDR)
// If it is a load, then just use one of the destination register to
// use as the new base.
- NewBase = Regs[NumRegs-1];
+ NewBase = Regs[NumRegs-1].first;
else {
- // FIXME: Try scavenging a register to use as a new base.
- NewBase = ARM::R12;
+ // Try to find a free register to use as a new base.
+ NewBase = RS ? RS->FindUnusedReg(&ARM::GPRRegClass) : (unsigned)ARM::R12;
+ if (NewBase == 0)
+ return false;
}
int BaseOpc = ARM::ADDri;
if (Offset < 0) {
@@ -143,52 +148,78 @@
int ImmedOffset = ARM_AM::getSOImmVal(Offset);
if (ImmedOffset == -1)
return false; // Probably not worth it then.
- BuildMI(MBB, MBBI, TII->get(BaseOpc), NewBase).addReg(Base).addImm(ImmedOffset);
+
+ BuildMI(MBB, MBBI, TII->get(BaseOpc), NewBase)
+ .addReg(Base, false, false, BaseKill).addImm(ImmedOffset);
Base = NewBase;
+ BaseKill = true; // New base is always killed right its use.
}
bool isDPR = Opcode == ARM::FLDD || Opcode == ARM::FSTD;
bool isDef = Opcode == ARM::LDR || Opcode == ARM::FLDS || Opcode == ARM::FLDD;
Opcode = getLoadStoreMultipleOpcode(Opcode);
MachineInstrBuilder MIB = (isAM4)
- ? BuildMI(MBB, MBBI, TII->get(Opcode)).addReg(Base)
+ ? BuildMI(MBB, MBBI, TII->get(Opcode)).addReg(Base, false, false, BaseKill)
.addImm(ARM_AM::getAM4ModeImm(Mode))
- : BuildMI(MBB, MBBI, TII->get(Opcode)).addReg(Base)
+ : BuildMI(MBB, MBBI, TII->get(Opcode)).addReg(Base, false, false, BaseKill)
.addImm(ARM_AM::getAM5Opc(Mode, false, isDPR ? NumRegs<<1 : NumRegs));
for (unsigned i = 0; i != NumRegs; ++i)
- MIB = MIB.addReg(Regs[i], Opcode == isDef);
+ MIB = MIB.addReg(Regs[i].first, isDef, false, Regs[i].second);
return true;
}
+/// AdvanceRS - Advance register scavenger to just before the earliest memory
+/// op that is being merged.
+void ARMLoadStoreOpt::AdvanceRS(MachineBasicBlock *MBB, MemOpQueue &MemOps) {
+ MachineBasicBlock::iterator Loc = MemOps[0].MBBI;
+ unsigned Position = MemOps[0].Position;
+ for (unsigned i = 1, e = MemOps.size(); i != e; ++i) {
+ if (MemOps[i].Position < Position) {
+ Position = MemOps[i].Position;
+ Loc = MemOps[i].MBBI;
+ }
+ }
+
+ if (Loc != MBB->begin())
+ RS->forward(prior(Loc));
+}
+
+/// MergeLDR_STR - Merge a number of load / store instructions into one or more
+/// load / store multiple instructions.
SmallVector<MachineBasicBlock::iterator, 4>
ARMLoadStoreOpt::MergeLDR_STR(MachineBasicBlock &MBB,
unsigned SIndex, unsigned Base, int Opcode,
unsigned Size, MemOpQueue &MemOps) {
- bool isAM4 = Opcode == ARM::LDR || Opcode == ARM::STR;
+ if (RS && SIndex == 0)
+ AdvanceRS(&MBB, MemOps);
+
SmallVector<MachineBasicBlock::iterator, 4> Merges;
+ SmallVector<std::pair<unsigned,bool>, 8> Regs;
+ bool isAM4 = Opcode == ARM::LDR || Opcode == ARM::STR;
int Offset = MemOps[SIndex].Offset;
int SOffset = Offset;
unsigned Pos = MemOps[SIndex].Position;
MachineBasicBlock::iterator Loc = MemOps[SIndex].MBBI;
- SmallVector<unsigned, 8> Regs;
unsigned PReg = MemOps[SIndex].MBBI->getOperand(0).getReg();
unsigned PRegNum = ARMRegisterInfo::getRegisterNumbering(PReg);
- Regs.push_back(PReg);
+ bool isKill = MemOps[SIndex].MBBI->getOperand(0).isKill();
+ Regs.push_back(std::make_pair(PReg, isKill));
for (unsigned i = SIndex+1, e = MemOps.size(); i != e; ++i) {
int NewOffset = MemOps[i].Offset;
unsigned Reg = MemOps[i].MBBI->getOperand(0).getReg();
unsigned RegNum = ARMRegisterInfo::getRegisterNumbering(Reg);
+ isKill = MemOps[i].MBBI->getOperand(0).isKill();
// AM4 - register numbers in ascending order.
// AM5 - consecutive register numbers in ascending order.
if (NewOffset == Offset + (int)Size &&
((isAM4 && RegNum > PRegNum) || RegNum == PRegNum+1)) {
Offset += Size;
- Regs.push_back(Reg);
+ Regs.push_back(std::make_pair(Reg, isKill));
PRegNum = RegNum;
} else {
// Can't merge this in. Try merge the earlier ones first.
- if (mergeOps(MBB, ++Loc, SOffset, Base, Opcode, Regs, TII)) {
+ if (mergeOps(MBB, ++Loc, SOffset, Base, false, Opcode, Regs, RS, TII)) {
Merges.push_back(prior(Loc));
for (unsigned j = SIndex; j < i; ++j) {
MBB.erase(MemOps[j].MBBI);
@@ -207,7 +238,8 @@
}
}
- if (mergeOps(MBB, ++Loc, SOffset, Base, Opcode, Regs, TII)) {
+ bool BaseKill = Loc->findRegisterUseOperand(Base, true) != NULL;
+ if (mergeOps(MBB, ++Loc, SOffset, Base, BaseKill, Opcode, Regs, RS, TII)) {
Merges.push_back(prior(Loc));
for (unsigned i = SIndex, e = MemOps.size(); i != e; ++i) {
MBB.erase(MemOps[i].MBBI);
@@ -381,6 +413,7 @@
const TargetInstrInfo *TII) {
MachineInstr *MI = MBBI;
unsigned Base = MI->getOperand(1).getReg();
+ bool BaseKill = MI->getOperand(1).isKill();
unsigned Bytes = getLSMultipleTransferSize(MI);
int Opcode = MI->getOpcode();
bool isAM2 = Opcode == ARM::LDR || Opcode == ARM::STR;
@@ -434,18 +467,23 @@
true, isDPR ? 2 : 1);
if (isLd) {
if (isAM2)
+ // LDR_PRE, LDR_POST;
BuildMI(MBB, MBBI, TII->get(NewOpc), MI->getOperand(0).getReg())
- .addReg(Base, true).addReg(Base).addReg(0).addImm(Offset);
+ .addReg(Base, true)
+ .addReg(Base).addReg(0).addImm(Offset);
else
- BuildMI(MBB, MBBI, TII->get(NewOpc)).addReg(Base)
+ BuildMI(MBB, MBBI, TII->get(NewOpc)).addReg(Base, false, false, BaseKill)
.addImm(Offset).addReg(MI->getOperand(0).getReg(), true);
} else {
+ MachineOperand &MO = MI->getOperand(0);
if (isAM2)
- BuildMI(MBB, MBBI, TII->get(NewOpc), Base).addReg(MI->getOperand(0).getReg())
+ // STR_PRE, STR_POST;
+ BuildMI(MBB, MBBI, TII->get(NewOpc), Base)
+ .addReg(MO.getReg(), false, false, MO.isKill())
.addReg(Base).addReg(0).addImm(Offset);
else
BuildMI(MBB, MBBI, TII->get(NewOpc)).addReg(Base)
- .addImm(Offset).addReg(MI->getOperand(0).getReg(), false);
+ .addImm(Offset).addReg(MO.getReg(), false, false, MO.isKill());
}
MBB.erase(MBBI);
@@ -494,7 +532,6 @@
int Opcode = MBBI->getOpcode();
bool isAM2 = Opcode == ARM::LDR || Opcode == ARM::STR;
unsigned Size = getLSMultipleTransferSize(MBBI);
-
unsigned Base = MBBI->getOperand(1).getReg();
unsigned OffIdx = MBBI->getNumOperands()-1;
unsigned OffField = MBBI->getOperand(OffIdx).getImm();
@@ -564,7 +601,7 @@
if (TryMerge) {
if (NumMemOps > 1) {
SmallVector<MachineBasicBlock::iterator,4> MBBII =
- MergeLDR_STR(MBB, 0, CurrBase, CurrOpc, CurrSize,MemOps);
+ MergeLDR_STR(MBB, 0, CurrBase, CurrOpc, CurrSize, MemOps);
// Try folding preceeding/trailing base inc/dec into the generated
// LDM/STM ops.
for (unsigned i = 0, e = MBBII.size(); i < e; ++i)
More information about the llvm-commits
mailing list