forked from OSchip/llvm-project
Do not form ldrd / strd if the two dests / srcs are the same. Code clean up.
llvm-svn: 73413
This commit is contained in:
parent
bd6a213725
commit
eba57e41b3
|
@ -937,7 +937,11 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool SatisfyLdStDWordlignment(MachineInstr *MI);
|
bool CanFormLdStDWord(MachineInstr *Op0, MachineInstr *Op1, DebugLoc &dl,
|
||||||
|
unsigned &NewOpc, unsigned &EvenReg,
|
||||||
|
unsigned &OddReg, unsigned &BaseReg,
|
||||||
|
unsigned &OffReg, unsigned &Offset,
|
||||||
|
unsigned &PredReg, ARMCC::CondCodes &Pred);
|
||||||
bool RescheduleOps(MachineBasicBlock *MBB,
|
bool RescheduleOps(MachineBasicBlock *MBB,
|
||||||
SmallVector<MachineInstr*, 4> &Ops,
|
SmallVector<MachineInstr*, 4> &Ops,
|
||||||
unsigned Base, bool isLd,
|
unsigned Base, bool isLd,
|
||||||
|
@ -995,16 +999,55 @@ static bool IsSafeToMove(bool isLd, unsigned Base,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ARMPreAllocLoadStoreOpt::SatisfyLdStDWordlignment(MachineInstr *MI) {
|
bool
|
||||||
if (!MI->hasOneMemOperand() ||
|
ARMPreAllocLoadStoreOpt::CanFormLdStDWord(MachineInstr *Op0, MachineInstr *Op1,
|
||||||
!MI->memoperands_begin()->getValue() ||
|
DebugLoc &dl,
|
||||||
MI->memoperands_begin()->isVolatile())
|
unsigned &NewOpc, unsigned &EvenReg,
|
||||||
|
unsigned &OddReg, unsigned &BaseReg,
|
||||||
|
unsigned &OffReg, unsigned &Offset,
|
||||||
|
unsigned &PredReg,
|
||||||
|
ARMCC::CondCodes &Pred) {
|
||||||
|
// FIXME: FLDS / FSTS -> FLDD / FSTD
|
||||||
|
unsigned Opcode = Op0->getOpcode();
|
||||||
|
if (Opcode == ARM::LDR)
|
||||||
|
NewOpc = ARM::LDRD;
|
||||||
|
else if (Opcode == ARM::STR)
|
||||||
|
NewOpc = ARM::STRD;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Must sure the base address satisfies i64 ld / st alignment requirement.
|
||||||
|
if (!Op0->hasOneMemOperand() ||
|
||||||
|
!Op0->memoperands_begin()->getValue() ||
|
||||||
|
Op0->memoperands_begin()->isVolatile())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
unsigned Align = MI->memoperands_begin()->getAlignment();
|
unsigned Align = Op0->memoperands_begin()->getAlignment();
|
||||||
unsigned ReqAlign = STI->hasV6Ops()
|
unsigned ReqAlign = STI->hasV6Ops()
|
||||||
? TD->getPrefTypeAlignment(Type::Int64Ty) : 8; // Pre-v6 need 8-byte align
|
? TD->getPrefTypeAlignment(Type::Int64Ty) : 8; // Pre-v6 need 8-byte align
|
||||||
return Align >= ReqAlign;
|
if (Align < ReqAlign)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Then make sure the immediate offset fits.
|
||||||
|
int OffImm = getMemoryOpOffset(Op0);
|
||||||
|
ARM_AM::AddrOpc AddSub = ARM_AM::add;
|
||||||
|
if (OffImm < 0) {
|
||||||
|
AddSub = ARM_AM::sub;
|
||||||
|
OffImm = - OffImm;
|
||||||
|
}
|
||||||
|
if (OffImm >= 256) // 8 bits
|
||||||
|
return false;
|
||||||
|
Offset = ARM_AM::getAM3Opc(AddSub, OffImm);
|
||||||
|
|
||||||
|
EvenReg = Op0->getOperand(0).getReg();
|
||||||
|
OddReg = Op0->getOperand(1).getReg();
|
||||||
|
if (EvenReg == OddReg)
|
||||||
|
return false;
|
||||||
|
BaseReg = Op0->getOperand(1).getReg();
|
||||||
|
OffReg = Op0->getOperand(2).getReg();
|
||||||
|
Pred = getInstrPredicate(Op0, PredReg);
|
||||||
|
dl = Op0->getDebugLoc();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ARMPreAllocLoadStoreOpt::RescheduleOps(MachineBasicBlock *MBB,
|
bool ARMPreAllocLoadStoreOpt::RescheduleOps(MachineBasicBlock *MBB,
|
||||||
|
@ -1075,66 +1118,31 @@ bool ARMPreAllocLoadStoreOpt::RescheduleOps(MachineBasicBlock *MBB,
|
||||||
|
|
||||||
// If we are moving a pair of loads / stores, see if it makes sense
|
// If we are moving a pair of loads / stores, see if it makes sense
|
||||||
// to try to allocate a pair of registers that can form register pairs.
|
// to try to allocate a pair of registers that can form register pairs.
|
||||||
unsigned PairOpcode = 0;
|
MachineInstr *Op0 = Ops.back();
|
||||||
unsigned Offset = 0;
|
MachineInstr *Op1 = Ops[Ops.size()-2];
|
||||||
|
|
||||||
// Make sure the alignment requirement is met.
|
|
||||||
if (NumMove == 2 && SatisfyLdStDWordlignment(Ops.back())) {
|
|
||||||
int Opcode = Ops.back()->getOpcode();
|
|
||||||
// FIXME: FLDS / FSTS -> FLDD / FSTD
|
|
||||||
if (Opcode == ARM::LDR)
|
|
||||||
PairOpcode = ARM::LDRD;
|
|
||||||
else if (Opcode == ARM::STR)
|
|
||||||
PairOpcode = ARM::STRD;
|
|
||||||
}
|
|
||||||
// Then make sure the immediate offset fits.
|
|
||||||
if (PairOpcode) {
|
|
||||||
int OffImm = getMemoryOpOffset(Ops.back());
|
|
||||||
ARM_AM::AddrOpc AddSub = ARM_AM::add;
|
|
||||||
if (OffImm < 0) {
|
|
||||||
AddSub = ARM_AM::sub;
|
|
||||||
OffImm = - OffImm;
|
|
||||||
}
|
|
||||||
if (OffImm >= 256) // 8 bits
|
|
||||||
PairOpcode = 0;
|
|
||||||
else
|
|
||||||
Offset = ARM_AM::getAM3Opc(AddSub, OffImm);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!PairOpcode) {
|
|
||||||
for (unsigned i = 0; i != NumMove; ++i) {
|
|
||||||
MachineInstr *Op = Ops.back();
|
|
||||||
Ops.pop_back();
|
|
||||||
MBB->splice(InsertPos, MBB, Op);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Form the pair instruction instead.
|
|
||||||
unsigned EvenReg = 0, OddReg = 0;
|
unsigned EvenReg = 0, OddReg = 0;
|
||||||
unsigned BaseReg = 0, OffReg = 0, PredReg = 0;
|
unsigned BaseReg = 0, OffReg = 0, PredReg = 0;
|
||||||
ARMCC::CondCodes Pred = ARMCC::AL;
|
ARMCC::CondCodes Pred = ARMCC::AL;
|
||||||
|
unsigned NewOpc = 0;
|
||||||
|
unsigned Offset = 0;
|
||||||
DebugLoc dl;
|
DebugLoc dl;
|
||||||
for (unsigned i = 0; i != NumMove; ++i) {
|
if (NumMove == 2 && CanFormLdStDWord(Op0, Op1, dl, NewOpc,
|
||||||
MachineInstr *Op = Ops.back();
|
EvenReg, OddReg, BaseReg, OffReg,
|
||||||
|
Offset, PredReg, Pred)) {
|
||||||
Ops.pop_back();
|
Ops.pop_back();
|
||||||
unsigned Reg = Op->getOperand(0).getReg();
|
Ops.pop_back();
|
||||||
if (i == 0) {
|
MBB->erase(Op0);
|
||||||
EvenReg = Reg;
|
MBB->erase(Op1);
|
||||||
BaseReg = Op->getOperand(1).getReg();
|
|
||||||
OffReg = Op->getOperand(2).getReg();
|
// Form the pair instruction.
|
||||||
Pred = getInstrPredicate(Op, PredReg);
|
|
||||||
dl = Op->getDebugLoc();
|
|
||||||
} else
|
|
||||||
OddReg = Reg;
|
|
||||||
MBB->erase(Op);
|
|
||||||
}
|
|
||||||
if (isLd)
|
if (isLd)
|
||||||
BuildMI(*MBB, InsertPos, dl, TII->get(PairOpcode))
|
BuildMI(*MBB, InsertPos, dl, TII->get(NewOpc))
|
||||||
.addReg(EvenReg, RegState::Define)
|
.addReg(EvenReg, RegState::Define)
|
||||||
.addReg(OddReg, RegState::Define)
|
.addReg(OddReg, RegState::Define)
|
||||||
.addReg(BaseReg).addReg(0).addImm(Offset)
|
.addReg(BaseReg).addReg(0).addImm(Offset)
|
||||||
.addImm(Pred).addReg(PredReg);
|
.addImm(Pred).addReg(PredReg);
|
||||||
else
|
else
|
||||||
BuildMI(*MBB, InsertPos, dl, TII->get(PairOpcode))
|
BuildMI(*MBB, InsertPos, dl, TII->get(NewOpc))
|
||||||
.addReg(EvenReg)
|
.addReg(EvenReg)
|
||||||
.addReg(OddReg)
|
.addReg(OddReg)
|
||||||
.addReg(BaseReg).addReg(0).addImm(Offset)
|
.addReg(BaseReg).addReg(0).addImm(Offset)
|
||||||
|
@ -1143,6 +1151,12 @@ bool ARMPreAllocLoadStoreOpt::RescheduleOps(MachineBasicBlock *MBB,
|
||||||
// Add register allocation hints to form register pairs.
|
// Add register allocation hints to form register pairs.
|
||||||
MRI->setRegAllocationHint(EvenReg, ARMRI::RegPairEven, OddReg);
|
MRI->setRegAllocationHint(EvenReg, ARMRI::RegPairEven, OddReg);
|
||||||
MRI->setRegAllocationHint(OddReg, ARMRI::RegPairOdd, EvenReg);
|
MRI->setRegAllocationHint(OddReg, ARMRI::RegPairOdd, EvenReg);
|
||||||
|
} else {
|
||||||
|
for (unsigned i = 0; i != NumMove; ++i) {
|
||||||
|
MachineInstr *Op = Ops.back();
|
||||||
|
Ops.pop_back();
|
||||||
|
MBB->splice(InsertPos, MBB, Op);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NumLdStMoved += NumMove;
|
NumLdStMoved += NumMove;
|
||||||
|
|
Loading…
Reference in New Issue