diff options
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/Spiller.cpp | 93 | ||||
-rw-r--r-- | lib/CodeGen/Spiller.h | 9 | ||||
-rw-r--r-- | lib/CodeGen/VirtRegMap.cpp | 23 | ||||
-rw-r--r-- | lib/CodeGen/VirtRegMap.h | 2 |
4 files changed, 95 insertions, 32 deletions
diff --git a/lib/CodeGen/Spiller.cpp b/lib/CodeGen/Spiller.cpp index 7b2a32f1c7..4bfae39c42 100644 --- a/lib/CodeGen/Spiller.cpp +++ b/lib/CodeGen/Spiller.cpp @@ -578,6 +578,20 @@ bool LocalSpiller::runOnMachineFunction(MachineFunction &MF, VirtRegMap &VRM) { DOUT << "**** Post Machine Instrs ****\n"; DEBUG(MF.dump()); + // See if any of the spills we added are actually dead and can be deleted. + for (std::vector<MachineInstr*> >::iterator + I = AddedSpills.begin(), E = AddedSpills.end(); I != E; ++I) { + MachineInstr *MI = *I; + + if (VRM.OnlyUseOfStackSlot(MI)) { + MachineBasicBlock *MBB = MI->getParent(); + DOUT << "Removed dead store:\t" << *MI; + VRM.RemoveMachineInstrFromMaps(MI); + MBB->erase(MI); + ++NumDSE; + } + } + // Mark unused spill slots. MachineFrameInfo *MFI = MF.getFrameInfo(); int SS = VRM.getLowSpillSlot(); @@ -588,6 +602,7 @@ bool LocalSpiller::runOnMachineFunction(MachineFunction &MF, VirtRegMap &VRM) { ++NumDSS; } + AddedSpills.clear(); return true; } @@ -798,9 +813,50 @@ bool LocalSpiller::CommuteToFoldReload(MachineBasicBlock &MBB, return false; } +void LocalSpiller::RemoveDeadStore(MachineInstr *Store, + MachineBasicBlock &MBB, + MachineBasicBlock::iterator &MII, + SmallSet<MachineInstr*, 4> &ReMatDefs, + BitVector &RegKills, + std::vector<MachineOperand*> &KillOps, + VirtRegMap &VRM) { + // If there is a dead store to this stack slot, nuke it now. + DOUT << "Removed dead store:\t" << *Store; + ++NumDSE; + SmallVector<unsigned, 2> KillRegs; + InvalidateKills(*Store, RegKills, KillOps, &KillRegs); + + MachineBasicBlock::iterator PrevMII = Store; + bool CheckDef = PrevMII != MBB.begin(); + if (CheckDef) --PrevMII; + + VRM.RemoveMachineInstrFromMaps(Store); + MBB.erase(Store); + + 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; + } + } + } + } +} + /// 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, +void +LocalSpiller::SpillRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MII, int Idx, unsigned PhysReg, int StackSlot, const TargetRegisterClass *RC, @@ -816,36 +872,8 @@ void LocalSpiller::SpillRegToStackSlot(MachineBasicBlock &MBB, 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; - } - } - } - } - } + if (LastStore) + RemoveDeadStore(LastStore, MBB, MII, ReMatDefs, RegKills, KillOps, VRM); LastStore = next(MII); @@ -1060,6 +1088,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM, 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; @@ -1073,7 +1102,9 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM, VRM.addSpillSlotUse(StackSlot, StoreMI); DOUT << "Store:\t" << *StoreMI; VRM.virtFolded(VirtReg, StoreMI, VirtRegMap::isMod); + AddedSpills.push_back(StoreMI); } + NextMII = next(MII); } diff --git a/lib/CodeGen/Spiller.h b/lib/CodeGen/Spiller.h index 5a42a8279d..0ac6fa0db6 100644 --- a/lib/CodeGen/Spiller.h +++ b/lib/CodeGen/Spiller.h @@ -285,6 +285,7 @@ namespace llvm { const TargetRegisterInfo *TRI; const TargetInstrInfo *TII; DenseMap<MachineInstr*, unsigned> DistanceMap; + std::vector<MachineInstr*> AddedSpills; public: bool runOnMachineFunction(MachineFunction &MF, VirtRegMap &VRM); private: @@ -305,6 +306,14 @@ namespace llvm { std::vector<MachineOperand*> &KillOps, const TargetRegisterInfo *TRI, VirtRegMap &VRM); + void RemoveDeadStore(MachineInstr *Store, + MachineBasicBlock &MBB, + MachineBasicBlock::iterator &MII, + SmallSet<MachineInstr*, 4> &ReMatDefs, + BitVector &RegKills, + std::vector<MachineOperand*> &KillOps, + VirtRegMap &VRM); + void SpillRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MII, int Idx, unsigned PhysReg, int StackSlot, diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp index cb0f764343..c5bfcfd301 100644 --- a/lib/CodeGen/VirtRegMap.cpp +++ b/lib/CodeGen/VirtRegMap.cpp @@ -188,7 +188,7 @@ void VirtRegMap::RemoveMachineInstrFromMaps(MachineInstr *MI) { if (MF->getFrameInfo()->isFixedObjectIndex(FI)) continue; // This stack reference was produced by instruction selection and - // is not a spill + // is not a spill. if (FI < LowSpillSlot) continue; assert((unsigned)FI-LowSpillSlot < SpillSlotToUsesMap.size() @@ -201,6 +201,27 @@ void VirtRegMap::RemoveMachineInstrFromMaps(MachineInstr *MI) { EmergencySpillMap.erase(MI); } +bool VirtRegMap::OnlyUseOfStackSlot(const MachineInstr *MI) const { + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + const MachineOperand &MO = MI->getOperand(i); + if (!MO.isFI()) + continue; + int FI = MO.getIndex(); + if (MF->getFrameInfo()->isFixedObjectIndex(FI)) + continue; + // This stack reference was produced by instruction selection and + // is not a spill. + if (FI < LowSpillSlot) + continue; + assert((unsigned)FI-LowSpillSlot < SpillSlotToUsesMap.size() + && "Invalid spill slot"); + if (SpillSlotToUsesMap[FI - LowSpillSlot].size() != 1) + return false; + } + + return true; +} + void VirtRegMap::print(std::ostream &OS, const Module* M) const { const TargetRegisterInfo* TRI = MF->getTarget().getRegisterInfo(); diff --git a/lib/CodeGen/VirtRegMap.h b/lib/CodeGen/VirtRegMap.h index 2e9c899baa..962c9dea3e 100644 --- a/lib/CodeGen/VirtRegMap.h +++ b/lib/CodeGen/VirtRegMap.h @@ -430,6 +430,8 @@ namespace llvm { /// the folded instruction map and spill point map. void RemoveMachineInstrFromMaps(MachineInstr *MI); + bool OnlyUseOfStackSlot(const MachineInstr *MI) const; + void print(std::ostream &OS, const Module* M = 0) const; void print(std::ostream *OS) const { if (OS) print(*OS); } void dump() const; |