diff options
Diffstat (limited to 'lib/CodeGen/RegAllocLocal.cpp')
-rw-r--r-- | lib/CodeGen/RegAllocLocal.cpp | 69 |
1 files changed, 56 insertions, 13 deletions
diff --git a/lib/CodeGen/RegAllocLocal.cpp b/lib/CodeGen/RegAllocLocal.cpp index 94456d1..321ae12 100644 --- a/lib/CodeGen/RegAllocLocal.cpp +++ b/lib/CodeGen/RegAllocLocal.cpp @@ -37,6 +37,7 @@ using namespace llvm; STATISTIC(NumStores, "Number of stores added"); STATISTIC(NumLoads , "Number of loads added"); +STATISTIC(NumCopies, "Number of copies coalesced"); static RegisterRegAlloc localRegAlloc("local", "local register allocator", @@ -50,6 +51,7 @@ namespace { private: const TargetMachine *TM; MachineFunction *MF; + MachineRegisterInfo *MRI; const TargetRegisterInfo *TRI; const TargetInstrInfo *TII; @@ -297,8 +299,18 @@ void RALocal::storeVirtReg(MachineBasicBlock &MBB, const TargetRegisterClass *RC = MF->getRegInfo().getRegClass(VirtReg); int FrameIndex = getStackSpaceFor(VirtReg, RC); DEBUG(dbgs() << " to stack slot #" << FrameIndex); - TII->storeRegToStackSlot(MBB, I, PhysReg, isKill, FrameIndex, RC); + TII->storeRegToStackSlot(MBB, I, PhysReg, isKill, FrameIndex, RC, TRI); ++NumStores; // Update statistics + + // Mark the spill instruction as last use if we're not killing the register. + if (!isKill) { + MachineInstr *Spill = llvm::prior(I); + int OpNum = Spill->findRegisterUseOperandIdx(PhysReg); + if (OpNum < 0) + getVirtRegLastUse(VirtReg) = std::make_pair((MachineInstr*)0, 0); + else + getVirtRegLastUse(VirtReg) = std::make_pair(Spill, OpNum); + } } /// spillVirtReg - This method spills the value specified by PhysReg into the @@ -506,10 +518,15 @@ MachineInstr *RALocal::reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI, SmallSet<unsigned, 4> &ReloadedRegs, unsigned PhysReg) { unsigned VirtReg = MI->getOperand(OpNum).getReg(); + unsigned SubIdx = MI->getOperand(OpNum).getSubReg(); // If the virtual register is already available, just update the instruction // and return. if (unsigned PR = getVirt2PhysRegMapSlot(VirtReg)) { + if (SubIdx) { + PR = TRI->getSubReg(PR, SubIdx); + MI->getOperand(OpNum).setSubReg(0); + } MI->getOperand(OpNum).setReg(PR); // Assign the input register if (!MI->isDebugValue()) { // Do not do these for DBG_VALUE as they can affect codegen. @@ -543,11 +560,16 @@ MachineInstr *RALocal::reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI, << TRI->getName(PhysReg) << "\n"); // Add move instruction(s) - TII->loadRegFromStackSlot(MBB, MI, PhysReg, FrameIndex, RC); + TII->loadRegFromStackSlot(MBB, MI, PhysReg, FrameIndex, RC, TRI); ++NumLoads; // Update statistics MF->getRegInfo().setPhysRegUsed(PhysReg); - MI->getOperand(OpNum).setReg(PhysReg); // Assign the input register + // Assign the input register. + if (SubIdx) { + MI->getOperand(OpNum).setSubReg(0); + MI->getOperand(OpNum).setReg(TRI->getSubReg(PhysReg, SubIdx)); + } else + MI->getOperand(OpNum).setReg(PhysReg); // Assign the input register getVirtRegLastUse(VirtReg) = std::make_pair(MI, OpNum); if (!ReloadedRegs.insert(PhysReg)) { @@ -626,7 +648,6 @@ static bool precedes(MachineBasicBlock::iterator A, /// ComputeLocalLiveness - Computes liveness of registers within a basic /// block, setting the killed/dead flags as appropriate. void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) { - MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); // Keep track of the most recently seen previous use or def of each reg, // so that we can update them with dead/kill markers. DenseMap<unsigned, std::pair<MachineInstr*, unsigned> > LastUseDef; @@ -672,18 +693,26 @@ void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) { // - A def followed by a def is dead // - A use followed by a def is a kill if (!MO.isReg() || !MO.getReg() || !MO.isDef()) continue; - + + unsigned SubIdx = MO.getSubReg(); DenseMap<unsigned, std::pair<MachineInstr*, unsigned> >::iterator last = LastUseDef.find(MO.getReg()); if (last != LastUseDef.end()) { // Check if this is a two address instruction. If so, then // the def does not kill the use. - if (last->second.first == I && - I->isRegTiedToUseOperand(i)) + if (last->second.first == I && I->isRegTiedToUseOperand(i)) continue; MachineOperand &lastUD = last->second.first->getOperand(last->second.second); + if (SubIdx && lastUD.getSubReg() != SubIdx) + // Partial re-def, the last def is not dead. + // %reg1024:5<def> = + // %reg1024:6<def> = + // or + // %reg1024:5<def> = op %reg1024, 5 + continue; + if (lastUD.isDef()) lastUD.setIsDead(true); else @@ -732,8 +761,8 @@ void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) { // it wouldn't have been otherwise. Nullify the DBG_VALUEs when that // happens. bool UsedByDebugValueOnly = false; - for (MachineRegisterInfo::reg_iterator UI = MRI.reg_begin(MO.getReg()), - UE = MRI.reg_end(); UI != UE; ++UI) { + for (MachineRegisterInfo::reg_iterator UI = MRI->reg_begin(MO.getReg()), + UE = MRI->reg_end(); UI != UE; ++UI) { // Two cases: // - used in another block // - used in the same block before it is defined (loop) @@ -755,8 +784,8 @@ void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) { } if (UsedByDebugValueOnly) - for (MachineRegisterInfo::reg_iterator UI = MRI.reg_begin(MO.getReg()), - UE = MRI.reg_end(); UI != UE; ++UI) + for (MachineRegisterInfo::reg_iterator UI = MRI->reg_begin(MO.getReg()), + UE = MRI->reg_end(); UI != UE; ++UI) if (UI->isDebugValue() && (UI->getParent() != &MBB || (MO.isDef() && precedes(&*UI, MI)))) @@ -828,7 +857,8 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) { unsigned SrcCopyReg, DstCopyReg, SrcCopySubReg, DstCopySubReg; unsigned SrcCopyPhysReg = 0U; bool isCopy = TII->isMoveInstr(*MI, SrcCopyReg, DstCopyReg, - SrcCopySubReg, DstCopySubReg); + SrcCopySubReg, DstCopySubReg) && + SrcCopySubReg == DstCopySubReg; if (isCopy && TargetRegisterInfo::isVirtualRegister(SrcCopyReg)) SrcCopyPhysReg = getVirt2PhysRegMapSlot(SrcCopyReg); @@ -878,6 +908,10 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) { std::make_pair((MachineInstr*)0, 0); DEBUG(dbgs() << " Assigning " << TRI->getName(DestPhysReg) << " to %reg" << DestVirtReg << "\n"); + if (unsigned DestSubIdx = MO.getSubReg()) { + MO.setSubReg(0); + DestPhysReg = TRI->getSubReg(DestPhysReg, DestSubIdx); + } MO.setReg(DestPhysReg); // Assign the earlyclobber register } else { unsigned Reg = MO.getReg(); @@ -1073,6 +1107,11 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) { getVirtRegLastUse(DestVirtReg) = std::make_pair((MachineInstr*)0, 0); DEBUG(dbgs() << " Assigning " << TRI->getName(DestPhysReg) << " to %reg" << DestVirtReg << "\n"); + + if (unsigned DestSubIdx = MO.getSubReg()) { + MO.setSubReg(0); + DestPhysReg = TRI->getSubReg(DestPhysReg, DestSubIdx); + } MO.setReg(DestPhysReg); // Assign the output register } @@ -1127,8 +1166,11 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) { // the register scavenger. See pr4100.) if (TII->isMoveInstr(*MI, SrcCopyReg, DstCopyReg, SrcCopySubReg, DstCopySubReg) && - SrcCopyReg == DstCopyReg && DeadDefs.empty()) + SrcCopyReg == DstCopyReg && SrcCopySubReg == DstCopySubReg && + DeadDefs.empty()) { + ++NumCopies; MBB.erase(MI); + } } MachineBasicBlock::iterator MI = MBB.getFirstTerminator(); @@ -1165,6 +1207,7 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) { bool RALocal::runOnMachineFunction(MachineFunction &Fn) { DEBUG(dbgs() << "Machine Function\n"); MF = &Fn; + MRI = &Fn.getRegInfo(); TM = &Fn.getTarget(); TRI = TM->getRegisterInfo(); TII = TM->getInstrInfo(); |