diff options
author | Chris Lattner <sabre@nondot.org> | 2004-10-01 23:15:36 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2004-10-01 23:15:36 +0000 |
commit | bec6a9ea1281a0b3b37aece91ab0df21e086af61 (patch) | |
tree | 55f40e7c3db388537506cb8cc7964e67b0e307ae | |
parent | c2a5730118acf727032271221398ea1cb903dd3f (diff) | |
download | external_llvm-bec6a9ea1281a0b3b37aece91ab0df21e086af61.zip external_llvm-bec6a9ea1281a0b3b37aece91ab0df21e086af61.tar.gz external_llvm-bec6a9ea1281a0b3b37aece91ab0df21e086af61.tar.bz2 |
When a virtual register is folded into an instruction, keep track of whether
it was a use, def, or both. This allows us to be less pessimistic in our
analysis of them. In practice, this doesn't make a big difference, but it
doesn't hurt either.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16632 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/LiveIntervalAnalysis.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/VirtRegMap.cpp | 64 | ||||
-rw-r--r-- | lib/CodeGen/VirtRegMap.h | 13 |
3 files changed, 52 insertions, 27 deletions
diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index 40b11f1..6916e96 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -223,7 +223,7 @@ addIntervalsForSpills(const LiveInterval &li, VirtRegMap &vrm, int slot) { if (MachineInstr* fmi = mri_->foldMemoryOperand(mi, i, slot)) { if (lv_) lv_->instructionChanged(mi, fmi); - vrm.virtFolded(li.reg, mi, fmi); + vrm.virtFolded(li.reg, mi, i, fmi); mi2iMap_.erase(mi); i2miMap_[index/InstrSlots::NUM] = fmi; mi2iMap_[fmi] = index; diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp index 8e6ff02..bdea59b 100644 --- a/lib/CodeGen/VirtRegMap.cpp +++ b/lib/CodeGen/VirtRegMap.cpp @@ -77,23 +77,26 @@ void VirtRegMap::assignVirt2StackSlot(unsigned virtReg, int frameIndex) { Virt2StackSlotMap[virtReg] = frameIndex; } -void VirtRegMap::virtFolded(unsigned virtReg, - MachineInstr* oldMI, - MachineInstr* newMI) { - // move previous memory references folded to new instruction - std::vector<MI2VirtMapTy::mapped_type> regs; - for (MI2VirtMapTy::iterator I = MI2VirtMap.lower_bound(oldMI), - E = MI2VirtMap.end(); I != E && I->first == oldMI; ) { - regs.push_back(I->second); +void VirtRegMap::virtFolded(unsigned VirtReg, MachineInstr *OldMI, + unsigned OpNo, MachineInstr *NewMI) { + // Move previous memory references folded to new instruction. + MI2VirtMapTy::iterator IP = MI2VirtMap.lower_bound(NewMI); + for (MI2VirtMapTy::iterator I = MI2VirtMap.lower_bound(OldMI), + E = MI2VirtMap.end(); I != E && I->first == OldMI; ) { + MI2VirtMap.insert(IP, std::make_pair(NewMI, I->second)); MI2VirtMap.erase(I++); } - MI2VirtMapTy::iterator IP = MI2VirtMap.lower_bound(newMI); - for (unsigned i = 0, e = regs.size(); i != e; ++i) - MI2VirtMap.insert(IP, std::make_pair(newMI, regs[i])); + ModRef MRInfo; + if (!OldMI->getOperand(OpNo).isDef()) { + assert(OldMI->getOperand(OpNo).isUse() && "Operand is not use or def?"); + MRInfo = isRef; + } else { + MRInfo = OldMI->getOperand(OpNo).isUse() ? isModRef : isMod; + } // add new memory reference - MI2VirtMap.insert(IP, std::make_pair(newMI, virtReg)); + MI2VirtMap.insert(IP, std::make_pair(NewMI, std::make_pair(VirtReg, MRInfo))); } void VirtRegMap::print(std::ostream &OS) const { @@ -433,18 +436,37 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, const VirtRegMap &VRM) { // register VirtRegMap::MI2VirtMapTy::const_iterator I, E; for (tie(I, E) = VRM.getFoldedVirts(&MI); I != E; ++I) { - DEBUG(std::cerr << "Folded vreg: " << I->second); - if (VRM.hasStackSlot(I->second)) { - int SS = VRM.getStackSlot(I->second); + DEBUG(std::cerr << "Folded vreg: " << I->second.first << " MR: " + << I->second.second); + unsigned VirtReg = I->second.first; + VirtRegMap::ModRef MR = I->second.second; + if (VRM.hasStackSlot(VirtReg)) { + int SS = VRM.getStackSlot(VirtReg); DEBUG(std::cerr << " - StackSlot: " << SS << "\n"); - // Any stores to this stack slot are not dead anymore. - MaybeDeadStores.erase(SS); + // If this reference is not a use, any previous store is now dead. + // Otherwise, the store to this stack slot is not dead anymore. + std::map<int, MachineInstr*>::iterator MDSI = MaybeDeadStores.find(SS); + if (MDSI != MaybeDeadStores.end()) { + if (MR & VirtRegMap::isRef) // Previous store is not dead. + MaybeDeadStores.erase(SS); + else { + // If we get here, the store is dead, nuke it now. + assert(MR == VirtRegMap::isMod && "Can't be modref!"); + MBB.erase(MDSI->second); + MaybeDeadStores.erase(MDSI); + ++NumDSE; + } + } - std::map<int, unsigned>::iterator I = SpillSlotsAvailable.find(SS); - if (I != SpillSlotsAvailable.end()) { - PhysRegsAvailable.erase(I->second); - SpillSlotsAvailable.erase(I); + // If the spill slot value is available, and this is a new definition of + // the value, the value is not available anymore. + if (MR & VirtRegMap::isMod) { + std::map<int, unsigned>::iterator It = SpillSlotsAvailable.find(SS); + if (It != SpillSlotsAvailable.end()) { + PhysRegsAvailable.erase(It->second); + SpillSlotsAvailable.erase(It); + } } } else { DEBUG(std::cerr << ": No stack slot!\n"); diff --git a/lib/CodeGen/VirtRegMap.h b/lib/CodeGen/VirtRegMap.h index c7792b0..abdf85d 100644 --- a/lib/CodeGen/VirtRegMap.h +++ b/lib/CodeGen/VirtRegMap.h @@ -26,7 +26,9 @@ namespace llvm { class VirtRegMap { public: - typedef std::multimap<MachineInstr*, unsigned> MI2VirtMapTy; + enum ModRef { isRef = 1, isMod = 2, isModRef = 3 }; + typedef std::multimap<MachineInstr*, + std::pair<unsigned, ModRef> > MI2VirtMapTy; private: MachineFunction &MF; @@ -122,10 +124,11 @@ namespace llvm { /// the specified stack slot void assignVirt2StackSlot(unsigned virtReg, int frameIndex); - /// @brief updates information about the specified virtual - /// register's value folded into newMI machine instruction - void virtFolded(unsigned virtReg, MachineInstr* oldMI, - MachineInstr* newMI); + /// @brief Updates information about the specified virtual register's value + /// folded into newMI machine instruction. The OpNum argument indicates the + /// operand number of OldMI that is folded. + void virtFolded(unsigned VirtReg, MachineInstr *OldMI, unsigned OpNum, + MachineInstr *NewMI); /// @brief returns the virtual registers' values folded in memory /// operands of this instruction |