DEBUG(MF.dump());
MachineRegisterInfo *mri = &MF.getRegInfo();
+ const TargetRegisterInfo *tri = MF.getTarget().getRegisterInfo();
bool changed = false;
for (LiveIntervals::iterator liItr = LIs->begin(), liEnd = LIs->end();
liItr != liEnd; ++liItr) {
- if (TargetRegisterInfo::isVirtualRegister(liItr->first)) {
- if (VRM.hasPhys(liItr->first)) {
- unsigned preg = VRM.getPhys(liItr->first);
- mri->replaceRegWith(liItr->first, preg);
- mri->setPhysRegUsed(preg);
- changed = true;
- }
+ const LiveInterval *li = liItr->second;
+ unsigned reg = li->reg;
+
+ if (TargetRegisterInfo::isPhysicalRegister(reg)) {
+ if (!li->empty())
+ mri->setPhysRegUsed(reg);
}
else {
- if (!liItr->second->empty()) {
- mri->setPhysRegUsed(liItr->first);
+ if (!VRM.hasPhys(reg))
+ continue;
+ unsigned pReg = VRM.getPhys(reg);
+ mri->setPhysRegUsed(pReg);
+ for (MachineRegisterInfo::reg_iterator regItr = mri->reg_begin(reg),
+ regEnd = mri->reg_end(); regItr != regEnd;) {
+ MachineOperand &mop = regItr.getOperand();
+ assert(mop.isReg() && mop.getReg() == reg && "reg_iterator broken?");
+ ++regItr;
+ unsigned subRegIdx = mop.getSubReg();
+ unsigned pRegOp = subRegIdx ? tri->getSubReg(pReg, subRegIdx) : pReg;
+ mop.setReg(pRegOp);
+ mop.setSubReg(0);
+ changed = true;
}
}
}
-
DEBUG(errs() << "**** Post Machine Instrs ****\n");
DEBUG(MF.dump());
}
/// InvalidateRegDef - If the def operand of the specified def MI is now dead
-/// (since it's spill instruction is removed), mark it isDead. Also checks if
+/// (since its spill instruction is removed), mark it isDead. Also checks if
/// the def MI has other definition operands that are not dead. Returns it by
/// reference.
static bool InvalidateRegDef(MachineBasicBlock::iterator I,
MachineInstr &NewDef, unsigned Reg,
- bool &HasLiveDef) {
+ bool &HasLiveDef,
+ const TargetRegisterInfo *TRI) {
// Due to remat, it's possible this reg isn't being reused. That is,
// the def of this reg (by prev MI) is now dead.
MachineInstr *DefMI = I;
MachineOperand *DefOp = NULL;
for (unsigned i = 0, e = DefMI->getNumOperands(); i != e; ++i) {
MachineOperand &MO = DefMI->getOperand(i);
- if (!MO.isReg() || MO.isUse() || !MO.isKill() || MO.isUndef())
+ if (!MO.isReg() || !MO.isDef() || !MO.isKill() || MO.isUndef())
continue;
if (MO.getReg() == Reg)
DefOp = &MO;
MachineInstr *NMI = I;
for (unsigned j = 0, ee = NMI->getNumOperands(); j != ee; ++j) {
MachineOperand &MO = NMI->getOperand(j);
- if (!MO.isReg() || MO.getReg() != Reg)
+ if (!MO.isReg() || MO.getReg() == 0 ||
+ (MO.getReg() != Reg && !TRI->isSubRegister(Reg, MO.getReg())))
continue;
if (MO.isUse())
FoundUse = true;
KillOps[*SR] = NULL;
RegKills.reset(*SR);
}
-
- if (!MI.isRegTiedToDefOperand(i))
- // Unless it's a two-address operand, this is the new kill.
- MO.setIsKill();
+ } else {
+ // Check for subreg kills as well.
+ // d4 =
+ // store d4, fi#0
+ // ...
+ // = s8<kill>
+ // ...
+ // = d4 <avoiding reload>
+ for (const unsigned *SR = TRI->getSubRegisters(Reg); *SR; ++SR) {
+ unsigned SReg = *SR;
+ if (RegKills[SReg] && KillOps[SReg]->getParent() != &MI) {
+ KillOps[SReg]->setIsKill(false);
+ unsigned KReg = KillOps[SReg]->getReg();
+ KillOps[KReg] = NULL;
+ RegKills.reset(KReg);
+
+ for (const unsigned *SSR = TRI->getSubRegisters(KReg); *SSR; ++SSR) {
+ KillOps[*SSR] = NULL;
+ RegKills.reset(*SSR);
+ }
+ }
+ }
}
+
if (MO.isKill()) {
RegKills.set(Reg);
KillOps[Reg] = &MO;
for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
const MachineOperand &MO = MI.getOperand(i);
- if (!MO.isReg() || !MO.isDef())
+ if (!MO.isReg() || !MO.getReg() || !MO.isDef())
continue;
unsigned Reg = MO.getReg();
RegKills.reset(Reg);
RegKills.reset(*SR);
KillOps[*SR] = NULL;
}
+ for (const unsigned *SR = TRI->getSuperRegisters(Reg); *SR; ++SR) {
+ RegKills.reset(*SR);
+ KillOps[*SR] = NULL;
+ }
}
}
"Don't know how to remat instructions that define > 1 values!");
#endif
TII->reMaterialize(MBB, MII, DestReg,
- ReMatDefMI->getOperand(0).getSubReg(), ReMatDefMI);
+ ReMatDefMI->getOperand(0).getSubReg(), ReMatDefMI, TRI);
MachineInstr *NewMI = prior(MII);
for (unsigned i = 0, e = NewMI->getNumOperands(); i != e; ++i) {
MachineOperand &MO = NewMI->getOperand(i);
}
// Skip over the same register.
- std::multimap<unsigned, int>::iterator NI = next(I);
+ std::multimap<unsigned, int>::iterator NI = llvm::next(I);
while (NI != E && NI->first == Reg) {
++I;
++NI;
"A reuse cannot be a virtual register");
if (PRRU != RealPhysRegUsed) {
// What was the sub-register index?
- unsigned SubReg;
- for (SubIdx = 1; (SubReg = TRI->getSubReg(PRRU, SubIdx)); SubIdx++)
- if (SubReg == RealPhysRegUsed)
- break;
- assert(SubReg == RealPhysRegUsed &&
+ SubIdx = TRI->getSubRegIndex(PRRU, RealPhysRegUsed);
+ assert(SubIdx &&
"Operand physreg is not a sub-register of PhysRegUsed");
}
std::vector<MachineOperand*> &KillOps,
VirtRegMap &VRM) {
- MachineBasicBlock::iterator NextMII = next(MII);
+ MachineBasicBlock::iterator NextMII = llvm::next(MII);
if (NextMII == MBB.end())
return false;
// Unfold next instructions that fold the same SS.
do {
MachineInstr &NextMI = *NextMII;
- NextMII = next(NextMII);
+ NextMII = llvm::next(NextMII);
NewMIs.clear();
if (!TII->unfoldMemoryOperand(MF, &NextMI, VirtReg, false, false, NewMIs))
llvm_unreachable("Unable unfold the load / store folding instruction!");
std::vector<MachineOperand*> &KillOps,
VirtRegMap &VRM) {
- TII->storeRegToStackSlot(MBB, next(MII), PhysReg, true, StackSlot, RC);
- MachineInstr *StoreMI = next(MII);
+ MachineBasicBlock::iterator oldNextMII = llvm::next(MII);
+ TII->storeRegToStackSlot(MBB, llvm::next(MII), PhysReg, true, StackSlot, RC);
+ MachineInstr *StoreMI = prior(oldNextMII);
VRM.addSpillSlotUse(StackSlot, StoreMI);
DEBUG(errs() << "Store:\t" << *StoreMI);
// being reused.
for (unsigned j = 0, ee = KillRegs.size(); j != ee; ++j) {
bool HasOtherDef = false;
- if (InvalidateRegDef(PrevMII, *MII, KillRegs[j], HasOtherDef)) {
+ if (InvalidateRegDef(PrevMII, *MII, KillRegs[j], HasOtherDef, TRI)) {
MachineInstr *DeadDef = PrevMII;
if (ReMatDefs.count(DeadDef) && !HasOtherDef) {
// FIXME: This assumes a remat def does not have side effects.
}
}
- LastStore = next(MII);
+ // Allow for multi-instruction spill sequences, as on PPC Altivec. Presume
+ // the last of multiple instructions is the actual store.
+ LastStore = prior(oldNextMII);
// If the stack slot value was previously available in some other
// register, change it now. Otherwise, make the register available,
std::vector<MachineOperand*> &KillOps) {
DEBUG(errs() << "\n**** Local spiller rewriting MBB '"
- << MBB.getBasicBlock()->getName() << "':\n");
+ << MBB.getName() << "':\n");
MachineFunction &MF = *MBB.getParent();
DistanceMap.clear();
for (MachineBasicBlock::iterator MII = MBB.begin(), E = MBB.end();
MII != E; ) {
- MachineBasicBlock::iterator NextMII = next(MII);
+ MachineBasicBlock::iterator NextMII = llvm::next(MII);
VirtRegMap::MI2VirtMapTy::const_iterator I, End;
bool Erased = false;
bool BackTracked = false;
if (OptimizeByUnfold(MBB, MII,
MaybeDeadStores, Spills, RegKills, KillOps, VRM))
- NextMII = next(MII);
+ NextMII = llvm::next(MII);
MachineInstr &MI = *MII;
// Back-schedule reloads and remats.
MachineBasicBlock::iterator InsertLoc =
- ComputeReloadLoc(next(MII), MBB.begin(), PhysReg, TRI, false,
+ ComputeReloadLoc(llvm::next(MII), MBB.begin(), PhysReg, TRI, false,
SS, TII, MF);
TII->loadRegFromStackSlot(MBB, InsertLoc, PhysReg, SS, RC);
++NumPSpills;
DistanceMap.insert(std::make_pair(LoadMI, Dist++));
}
- NextMII = next(MII);
+ NextMII = llvm::next(MII);
}
// Insert restores here if asked to.
// Mark is killed.
MachineInstr *CopyMI = prior(InsertLoc);
+ CopyMI->setAsmPrinterFlag(AsmPrinter::ReloadReuse);
MachineOperand *KillOpnd = CopyMI->findRegisterUseOperand(InReg);
KillOpnd->setIsKill();
UpdateKills(*CopyMI, TRI, RegKills, KillOps);
const TargetRegisterClass *RC = RegInfo->getRegClass(VirtReg);
unsigned Phys = VRM.getPhys(VirtReg);
int StackSlot = VRM.getStackSlot(VirtReg);
- TII->storeRegToStackSlot(MBB, next(MII), Phys, isKill, StackSlot, RC);
- MachineInstr *StoreMI = next(MII);
+ MachineBasicBlock::iterator oldNextMII = llvm::next(MII);
+ TII->storeRegToStackSlot(MBB, llvm::next(MII), Phys, isKill, StackSlot, RC);
+ MachineInstr *StoreMI = prior(oldNextMII);
VRM.addSpillSlotUse(StackSlot, StoreMI);
DEBUG(errs() << "Store:\t" << *StoreMI);
VRM.virtFolded(VirtReg, StoreMI, VirtRegMap::isMod);
}
- NextMII = next(MII);
+ NextMII = llvm::next(MII);
}
/// ReusedOperands - Keep track of operand reuse in case we need to undo
TII->copyRegToReg(MBB, InsertLoc, DesignatedReg, PhysReg, RC, RC);
MachineInstr *CopyMI = prior(InsertLoc);
+ CopyMI->setAsmPrinterFlag(AsmPrinter::ReloadReuse);
UpdateKills(*CopyMI, TRI, RegKills, KillOps);
// This invalidates DesignatedReg.
// virtual or needing to clobber any values if it's physical).
NextMII = &MI;
--NextMII; // backtrack to the copy.
+ NextMII->setAsmPrinterFlag(AsmPrinter::ReloadReuse);
// Propagate the sub-register index over.
if (SubIdx) {
DefMO = NextMII->findRegisterDefOperand(DestReg);
if (CommuteToFoldReload(MBB, MII, VirtReg, SrcReg, StackSlot,
Spills, RegKills, KillOps, TRI, VRM)) {
- NextMII = next(MII);
+ NextMII = llvm::next(MII);
BackTracked = true;
goto ProcessNextInst;
}
// eliminate this or else the undef marker is lost and it will
// confuses the scavenger. This is extremely rare.
unsigned Src, Dst, SrcSR, DstSR;
- if (TII->isIdentityCopy(MI, Src, Dst, SrcSR, DstSR) &&
+ if (TII->isMoveInstr(MI, Src, Dst, SrcSR, DstSR) && Src == Dst &&
!MI.findRegisterUseOperand(Src)->isUndef()) {
++NumDCE;
DEBUG(errs() << "Removing now-noop copy: " << MI);
MachineInstr *&LastStore = MaybeDeadStores[StackSlot];
SpillRegToStackSlot(MBB, MII, -1, PhysReg, StackSlot, RC, true,
LastStore, Spills, ReMatDefs, RegKills, KillOps, VRM);
- NextMII = next(MII);
+ NextMII = llvm::next(MII);
// Check to see if this is a noop copy. If so, eliminate the
// instruction before considering the dest reg to be changed.
{
unsigned Src, Dst, SrcSR, DstSR;
- if (TII->isIdentityCopy(MI, Src, Dst, SrcSR, DstSR)) {
+ if (TII->isMoveInstr(MI, Src, Dst, SrcSR, DstSR) && Src == Dst) {
++NumDCE;
DEBUG(errs() << "Removing now-noop copy: " << MI);
InvalidateKills(MI, TRI, RegKills, KillOps);