forked from OSchip/llvm-project
Preserve implicit defs in ARMLoadStoreOptimizer.
When a number of sub-register VLRDS instructions are combined into a VLDM, preserve any super-register implicit defs. This is required to keep the register scavenger and machine code verifier happy. Enable machine code verification after ARMLoadStoreOptimizer. ARM/2012-01-26-CopyPropKills.ll was failing because of this. llvm-svn: 153610
This commit is contained in:
parent
4970c304e1
commit
cdee326ab6
|
@ -93,7 +93,9 @@ namespace {
|
||||||
bool MergeOps(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
|
bool MergeOps(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
|
||||||
int Offset, unsigned Base, bool BaseKill, int Opcode,
|
int Offset, unsigned Base, bool BaseKill, int Opcode,
|
||||||
ARMCC::CondCodes Pred, unsigned PredReg, unsigned Scratch,
|
ARMCC::CondCodes Pred, unsigned PredReg, unsigned Scratch,
|
||||||
DebugLoc dl, SmallVector<std::pair<unsigned, bool>, 8> &Regs);
|
DebugLoc dl,
|
||||||
|
ArrayRef<std::pair<unsigned, bool> > Regs,
|
||||||
|
ArrayRef<unsigned> ImpDefs);
|
||||||
void MergeOpsUpdate(MachineBasicBlock &MBB,
|
void MergeOpsUpdate(MachineBasicBlock &MBB,
|
||||||
MemOpQueue &MemOps,
|
MemOpQueue &MemOps,
|
||||||
unsigned memOpsBegin,
|
unsigned memOpsBegin,
|
||||||
|
@ -282,7 +284,8 @@ ARMLoadStoreOpt::MergeOps(MachineBasicBlock &MBB,
|
||||||
int Offset, unsigned Base, bool BaseKill,
|
int Offset, unsigned Base, bool BaseKill,
|
||||||
int Opcode, ARMCC::CondCodes Pred,
|
int Opcode, ARMCC::CondCodes Pred,
|
||||||
unsigned PredReg, unsigned Scratch, DebugLoc dl,
|
unsigned PredReg, unsigned Scratch, DebugLoc dl,
|
||||||
SmallVector<std::pair<unsigned, bool>, 8> &Regs) {
|
ArrayRef<std::pair<unsigned, bool> > Regs,
|
||||||
|
ArrayRef<unsigned> ImpDefs) {
|
||||||
// Only a single register to load / store. Don't bother.
|
// Only a single register to load / store. Don't bother.
|
||||||
unsigned NumRegs = Regs.size();
|
unsigned NumRegs = Regs.size();
|
||||||
if (NumRegs <= 1)
|
if (NumRegs <= 1)
|
||||||
|
@ -350,6 +353,10 @@ ARMLoadStoreOpt::MergeOps(MachineBasicBlock &MBB,
|
||||||
MIB = MIB.addReg(Regs[i].first, getDefRegState(isDef)
|
MIB = MIB.addReg(Regs[i].first, getDefRegState(isDef)
|
||||||
| getKillRegState(Regs[i].second));
|
| getKillRegState(Regs[i].second));
|
||||||
|
|
||||||
|
// Add implicit defs for super-registers.
|
||||||
|
for (unsigned i = 0, e = ImpDefs.size(); i != e; ++i)
|
||||||
|
MIB.addReg(ImpDefs[i], RegState::ImplicitDefine);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -384,19 +391,29 @@ void ARMLoadStoreOpt::MergeOpsUpdate(MachineBasicBlock &MBB,
|
||||||
}
|
}
|
||||||
|
|
||||||
SmallVector<std::pair<unsigned, bool>, 8> Regs;
|
SmallVector<std::pair<unsigned, bool>, 8> Regs;
|
||||||
|
SmallVector<unsigned, 8> ImpDefs;
|
||||||
for (unsigned i = memOpsBegin; i < memOpsEnd; ++i) {
|
for (unsigned i = memOpsBegin; i < memOpsEnd; ++i) {
|
||||||
unsigned Reg = memOps[i].Reg;
|
unsigned Reg = memOps[i].Reg;
|
||||||
// If we are inserting the merged operation after an operation that
|
// If we are inserting the merged operation after an operation that
|
||||||
// uses the same register, make sure to transfer any kill flag.
|
// uses the same register, make sure to transfer any kill flag.
|
||||||
bool isKill = memOps[i].isKill || KilledRegs.count(Reg);
|
bool isKill = memOps[i].isKill || KilledRegs.count(Reg);
|
||||||
Regs.push_back(std::make_pair(Reg, isKill));
|
Regs.push_back(std::make_pair(Reg, isKill));
|
||||||
|
|
||||||
|
// Collect any implicit defs of super-registers. They must be preserved.
|
||||||
|
for (MIOperands MO(memOps[i].MBBI); MO.isValid(); ++MO) {
|
||||||
|
if (!MO->isReg() || !MO->isDef() || !MO->isImplicit() || MO->isDead())
|
||||||
|
continue;
|
||||||
|
unsigned DefReg = MO->getReg();
|
||||||
|
if (std::find(ImpDefs.begin(), ImpDefs.end(), DefReg) == ImpDefs.end())
|
||||||
|
ImpDefs.push_back(DefReg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to do the merge.
|
// Try to do the merge.
|
||||||
MachineBasicBlock::iterator Loc = memOps[insertAfter].MBBI;
|
MachineBasicBlock::iterator Loc = memOps[insertAfter].MBBI;
|
||||||
++Loc;
|
++Loc;
|
||||||
if (!MergeOps(MBB, Loc, Offset, Base, BaseKill, Opcode,
|
if (!MergeOps(MBB, Loc, Offset, Base, BaseKill, Opcode,
|
||||||
Pred, PredReg, Scratch, dl, Regs))
|
Pred, PredReg, Scratch, dl, Regs, ImpDefs))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Merge succeeded, update records.
|
// Merge succeeded, update records.
|
||||||
|
|
|
@ -158,8 +158,10 @@ bool ARMPassConfig::addPreRegAlloc() {
|
||||||
bool ARMPassConfig::addPreSched2() {
|
bool ARMPassConfig::addPreSched2() {
|
||||||
// FIXME: temporarily disabling load / store optimization pass for Thumb1.
|
// FIXME: temporarily disabling load / store optimization pass for Thumb1.
|
||||||
if (getOptLevel() != CodeGenOpt::None) {
|
if (getOptLevel() != CodeGenOpt::None) {
|
||||||
if (!getARMSubtarget().isThumb1Only())
|
if (!getARMSubtarget().isThumb1Only()) {
|
||||||
PM.add(createARMLoadStoreOptimizationPass());
|
PM.add(createARMLoadStoreOptimizationPass());
|
||||||
|
printAndVerify("After ARM load / store optimizer");
|
||||||
|
}
|
||||||
if (getARMSubtarget().hasNEON())
|
if (getARMSubtarget().hasNEON())
|
||||||
PM.add(createExecutionDependencyFixPass(&ARM::DPRRegClass));
|
PM.add(createExecutionDependencyFixPass(&ARM::DPRRegClass));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue