-/// findSuperReg - Find the SubReg's super-register of given register class
-/// where its SubIdx sub-register is SubReg.
-static unsigned findSuperReg(const TargetRegisterClass *RC, unsigned SubReg,
- unsigned SubIdx, const TargetRegisterInfo *TRI) {
- for (TargetRegisterClass::iterator I = RC->begin(), E = RC->end();
- I != E; ++I) {
- unsigned Reg = *I;
- if (TRI->getSubReg(Reg, SubIdx) == SubReg)
- return Reg;
- }
- return 0;
-}
-
-/// SpillRegToStackSlot - Spill a register to a specified stack slot. Check if
-/// the last store to the same slot is now dead. If so, remove the last store.
-void LocalSpiller::SpillRegToStackSlot(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator &MII,
- int Idx, unsigned PhysReg, int StackSlot,
- const TargetRegisterClass *RC,
- bool isAvailable, MachineInstr *&LastStore,
- AvailableSpills &Spills,
- SmallSet<MachineInstr*, 4> &ReMatDefs,
- BitVector &RegKills,
- std::vector<MachineOperand*> &KillOps,
- VirtRegMap &VRM) {
- TII->storeRegToStackSlot(MBB, next(MII), PhysReg, true, StackSlot, RC);
- MachineInstr *StoreMI = next(MII);
- VRM.addSpillSlotUse(StackSlot, StoreMI);
- DOUT << "Store:\t" << *StoreMI;
-
- // If there is a dead store to this stack slot, nuke it now.
- if (LastStore) {
- DOUT << "Removed dead store:\t" << *LastStore;
- ++NumDSE;
- SmallVector<unsigned, 2> KillRegs;
- InvalidateKills(*LastStore, RegKills, KillOps, &KillRegs);
- MachineBasicBlock::iterator PrevMII = LastStore;
- bool CheckDef = PrevMII != MBB.begin();
- if (CheckDef)
- --PrevMII;
- VRM.RemoveMachineInstrFromMaps(LastStore);
- MBB.erase(LastStore);
- if (CheckDef) {
- // Look at defs of killed registers on the store. Mark the defs
- // as dead since the store has been deleted and they aren't
- // being reused.
- for (unsigned j = 0, ee = KillRegs.size(); j != ee; ++j) {
- bool HasOtherDef = false;
- if (InvalidateRegDef(PrevMII, *MII, KillRegs[j], HasOtherDef)) {
- MachineInstr *DeadDef = PrevMII;
- if (ReMatDefs.count(DeadDef) && !HasOtherDef) {
- // FIXME: This assumes a remat def does not have side
- // effects.
- VRM.RemoveMachineInstrFromMaps(DeadDef);
- MBB.erase(DeadDef);
- ++NumDRM;
- }
- }
- }
- }
- }
-
- LastStore = next(MII);
-
- // If the stack slot value was previously available in some other
- // register, change it now. Otherwise, make the register available,
- // in PhysReg.
- Spills.ModifyStackSlotOrReMat(StackSlot);
- Spills.ClobberPhysReg(PhysReg);
- Spills.addAvailable(StackSlot, LastStore, PhysReg, isAvailable);
- ++NumStores;
-}
-
-/// rewriteMBB - Keep track of which spills are available even after the
-/// register allocator is done with them. If possible, avid reloading vregs.
-void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
- DOUT << MBB.getBasicBlock()->getName() << ":\n";
-
- MachineFunction &MF = *MBB.getParent();
-
- // Spills - Keep track of which spilled values are available in physregs so
- // that we can choose to reuse the physregs instead of emitting reloads.
- AvailableSpills Spills(TRI, TII);
-
- // MaybeDeadStores - When we need to write a value back into a stack slot,
- // keep track of the inserted store. If the stack slot value is never read
- // (because the value was used from some available register, for example), and
- // subsequently stored to, the original store is dead. This map keeps track
- // of inserted stores that are not used. If we see a subsequent store to the
- // same stack slot, the original store is deleted.
- std::vector<MachineInstr*> MaybeDeadStores;
- MaybeDeadStores.resize(MF.getFrameInfo()->getObjectIndexEnd(), NULL);
-
- // ReMatDefs - These are rematerializable def MIs which are not deleted.
- SmallSet<MachineInstr*, 4> ReMatDefs;
-
- // Keep track of kill information.
- BitVector RegKills(TRI->getNumRegs());
- std::vector<MachineOperand*> KillOps;
- KillOps.resize(TRI->getNumRegs(), NULL);
-
- for (MachineBasicBlock::iterator MII = MBB.begin(), E = MBB.end();
- MII != E; ) {
- MachineBasicBlock::iterator NextMII = MII; ++NextMII;
-
- VirtRegMap::MI2VirtMapTy::const_iterator I, End;
- bool Erased = false;
- bool BackTracked = false;
- if (PrepForUnfoldOpti(MBB, MII,
- MaybeDeadStores, Spills, RegKills, KillOps, VRM))
- NextMII = next(MII);
-
- MachineInstr &MI = *MII;
- const TargetInstrDesc &TID = MI.getDesc();
-
- if (VRM.hasEmergencySpills(&MI)) {
- // Spill physical register(s) in the rare case the allocator has run out
- // of registers to allocate.
- SmallSet<int, 4> UsedSS;
- std::vector<unsigned> &EmSpills = VRM.getEmergencySpills(&MI);
- for (unsigned i = 0, e = EmSpills.size(); i != e; ++i) {
- unsigned PhysReg = EmSpills[i];
- const TargetRegisterClass *RC =
- TRI->getPhysicalRegisterRegClass(PhysReg);
- assert(RC && "Unable to determine register class!");
- int SS = VRM.getEmergencySpillSlot(RC);
- if (UsedSS.count(SS))
- assert(0 && "Need to spill more than one physical registers!");
- UsedSS.insert(SS);
- TII->storeRegToStackSlot(MBB, MII, PhysReg, true, SS, RC);
- MachineInstr *StoreMI = prior(MII);
- VRM.addSpillSlotUse(SS, StoreMI);
- TII->loadRegFromStackSlot(MBB, next(MII), PhysReg, SS, RC);
- MachineInstr *LoadMI = next(MII);
- VRM.addSpillSlotUse(SS, LoadMI);
- ++NumPSpills;
- }
- }
-
- // Insert restores here if asked to.
- if (VRM.isRestorePt(&MI)) {
- std::vector<unsigned> &RestoreRegs = VRM.getRestorePtRestores(&MI);
- for (unsigned i = 0, e = RestoreRegs.size(); i != e; ++i) {
- unsigned VirtReg = RestoreRegs[e-i-1]; // Reverse order.
- if (!VRM.getPreSplitReg(VirtReg))
- continue; // Split interval spilled again.
- unsigned Phys = VRM.getPhys(VirtReg);
- RegInfo->setPhysRegUsed(Phys);
- if (VRM.isReMaterialized(VirtReg)) {
- ReMaterialize(MBB, MII, Phys, VirtReg, TRI, VRM);
- } else {
- const TargetRegisterClass* RC = RegInfo->getRegClass(VirtReg);
- int SS = VRM.getStackSlot(VirtReg);
- TII->loadRegFromStackSlot(MBB, &MI, Phys, SS, RC);
- MachineInstr *LoadMI = prior(MII);
- VRM.addSpillSlotUse(SS, LoadMI);
- ++NumLoads;
- }
- // This invalidates Phys.
- Spills.ClobberPhysReg(Phys);
- UpdateKills(*prior(MII), RegKills, KillOps);
- DOUT << '\t' << *prior(MII);
- }
- }
-
- // Insert spills here if asked to.
- if (VRM.isSpillPt(&MI)) {
- std::vector<std::pair<unsigned,bool> > &SpillRegs =
- VRM.getSpillPtSpills(&MI);
- for (unsigned i = 0, e = SpillRegs.size(); i != e; ++i) {
- unsigned VirtReg = SpillRegs[i].first;
- bool isKill = SpillRegs[i].second;
- if (!VRM.getPreSplitReg(VirtReg))
- continue; // Split interval spilled again.
- 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);
- VRM.addSpillSlotUse(StackSlot, StoreMI);
- DOUT << "Store:\t" << StoreMI;
- VRM.virtFolded(VirtReg, StoreMI, VirtRegMap::isMod);
- }
- NextMII = next(MII);
- }
-
- /// ReusedOperands - Keep track of operand reuse in case we need to undo
- /// reuse.
- ReuseInfo ReusedOperands(MI, TRI);
- SmallVector<unsigned, 4> VirtUseOps;
- for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
- MachineOperand &MO = MI.getOperand(i);
- if (!MO.isRegister() || MO.getReg() == 0)
- continue; // Ignore non-register operands.
-
- unsigned VirtReg = MO.getReg();
- if (TargetRegisterInfo::isPhysicalRegister(VirtReg)) {
- // Ignore physregs for spilling, but remember that it is used by this
- // function.
- RegInfo->setPhysRegUsed(VirtReg);
- continue;
- }