diff options
Diffstat (limited to 'contrib/llvm/lib/CodeGen/VirtRegRewriter.cpp')
-rw-r--r-- | contrib/llvm/lib/CodeGen/VirtRegRewriter.cpp | 103 |
1 files changed, 34 insertions, 69 deletions
diff --git a/contrib/llvm/lib/CodeGen/VirtRegRewriter.cpp b/contrib/llvm/lib/CodeGen/VirtRegRewriter.cpp index 57a1500..240d28c 100644 --- a/contrib/llvm/lib/CodeGen/VirtRegRewriter.cpp +++ b/contrib/llvm/lib/CodeGen/VirtRegRewriter.cpp @@ -67,23 +67,16 @@ VirtRegRewriter::~VirtRegRewriter() {} /// Note that operands may be added, so the MO reference is no longer valid. static void substitutePhysReg(MachineOperand &MO, unsigned Reg, const TargetRegisterInfo &TRI) { - if (unsigned SubIdx = MO.getSubReg()) { - // Insert the physical subreg and reset the subreg field. - MO.setReg(TRI.getSubReg(Reg, SubIdx)); - MO.setSubReg(0); - - // Any def, dead, and kill flags apply to the full virtual register, so they - // also apply to the full physical register. Add imp-def/dead and imp-kill - // as needed. + if (MO.getSubReg()) { + MO.substPhysReg(Reg, TRI); + + // Any kill flags apply to the full virtual register, so they also apply to + // the full physical register. + // We assume that partial defs have already been decorated with a super-reg + // <imp-def> operand by LiveIntervals. MachineInstr &MI = *MO.getParent(); - if (MO.isDef()) - if (MO.isDead()) - MI.addRegisterDead(Reg, &TRI, /*AddIfNotFound=*/ true); - else - MI.addRegisterDefined(Reg, &TRI); - else if (!MO.isUndef() && - (MO.isKill() || - MI.isRegTiedToDefOperand(&MO-&MI.getOperand(0)))) + if (MO.isUse() && !MO.isUndef() && + (MO.isKill() || MI.isRegTiedToDefOperand(&MO-&MI.getOperand(0)))) MI.addRegisterKilled(Reg, &TRI, /*AddIfNotFound=*/ true); } else { MO.setReg(Reg); @@ -460,7 +453,7 @@ public: /// blocks each of which is a successor of the specified BB and has no other /// predecessor. static void findSinglePredSuccessor(MachineBasicBlock *MBB, - SmallVectorImpl<MachineBasicBlock *> &Succs) { + SmallVectorImpl<MachineBasicBlock *> &Succs){ for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(), SE = MBB->succ_end(); SI != SE; ++SI) { MachineBasicBlock *SuccMBB = *SI; @@ -852,8 +845,8 @@ unsigned ReuseInfo::GetRegForReload(const TargetRegisterClass *RC, // Yup, use the reload register that we didn't use before. unsigned NewReg = Op.AssignedPhysReg; Rejected.insert(PhysReg); - return GetRegForReload(RC, NewReg, MF, MI, Spills, MaybeDeadStores, Rejected, - RegKills, KillOps, VRM); + return GetRegForReload(RC, NewReg, MF, MI, Spills, MaybeDeadStores, + Rejected, RegKills, KillOps, VRM); } else { // Otherwise, we might also have a problem if a previously reused // value aliases the new register. If so, codegen the previous reload @@ -1864,7 +1857,7 @@ bool LocalRewriter::InsertSpills(MachineInstr *MI) { /// rewriteMBB - Keep track of which spills are available even after the -/// register allocator is done with them. If possible, avid reloading vregs. +/// register allocator is done with them. If possible, avoid reloading vregs. void LocalRewriter::RewriteMBB(LiveIntervals *LIs, AvailableSpills &Spills, BitVector &RegKills, @@ -1914,7 +1907,6 @@ LocalRewriter::RewriteMBB(LiveIntervals *LIs, if (InsertSpills(MII)) NextMII = llvm::next(MII); - VirtRegMap::MI2VirtMapTy::const_iterator I, End; bool Erased = false; bool BackTracked = false; MachineInstr &MI = *MII; @@ -2028,14 +2020,16 @@ LocalRewriter::RewriteMBB(LiveIntervals *LIs, CanReuse = !ReusedOperands.isClobbered(PhysReg) && Spills.canClobberPhysReg(PhysReg); } - // If this is an asm, and PhysReg is used elsewhere as an earlyclobber - // operand, we can't also use it as an input. (Outputs always come - // before inputs, so we can stop looking at i.) + // If this is an asm, and a PhysReg alias is used elsewhere as an + // earlyclobber operand, we can't also use it as an input. if (MI.isInlineAsm()) { - for (unsigned k=0; k<i; ++k) { + for (unsigned k = 0, e = MI.getNumOperands(); k != e; ++k) { MachineOperand &MOk = MI.getOperand(k); - if (MOk.isReg() && MOk.getReg()==PhysReg && MOk.isEarlyClobber()) { + if (MOk.isReg() && MOk.isEarlyClobber() && + TRI->regsOverlap(MOk.getReg(), PhysReg)) { CanReuse = false; + DEBUG(dbgs() << "Not reusing physreg " << TRI->getName(PhysReg) + << " for vreg" << VirtReg << ": " << MOk << '\n'); break; } } @@ -2248,15 +2242,22 @@ LocalRewriter::RewriteMBB(LiveIntervals *LIs, // If we have folded references to memory operands, make sure we clear all // physical registers that may contain the value of the spilled virtual // register + + // Copy the folded virts to a small vector, we may change MI2VirtMap. + SmallVector<std::pair<unsigned, VirtRegMap::ModRef>, 4> FoldedVirts; + // C++0x FTW! + for (std::pair<VirtRegMap::MI2VirtMapTy::const_iterator, + VirtRegMap::MI2VirtMapTy::const_iterator> FVRange = + VRM->getFoldedVirts(&MI); + FVRange.first != FVRange.second; ++FVRange.first) + FoldedVirts.push_back(FVRange.first->second); + SmallSet<int, 2> FoldedSS; - for (tie(I, End) = VRM->getFoldedVirts(&MI); I != End; ) { - unsigned VirtReg = I->second.first; - VirtRegMap::ModRef MR = I->second.second; + for (unsigned FVI = 0, FVE = FoldedVirts.size(); FVI != FVE; ++FVI) { + unsigned VirtReg = FoldedVirts[FVI].first; + VirtRegMap::ModRef MR = FoldedVirts[FVI].second; DEBUG(dbgs() << "Folded vreg: " << VirtReg << " MR: " << MR); - // MI2VirtMap be can updated which invalidate the iterator. - // Increment the iterator first. - ++I; int SS = VRM->getStackSlot(VirtReg); if (SS == VirtRegMap::NO_STACK_SLOT) continue; @@ -2302,7 +2303,7 @@ LocalRewriter::RewriteMBB(LiveIntervals *LIs, unsigned PhysReg = Spills.getSpillSlotOrReMatPhysReg(SS); SmallVector<MachineInstr*, 4> NewMIs; if (PhysReg && - TII->unfoldMemoryOperand(MF, &MI, PhysReg, false, false, NewMIs)) { + TII->unfoldMemoryOperand(MF, &MI, PhysReg, false, false, NewMIs)){ MBB->insert(MII, NewMIs[0]); InvalidateKills(MI, TRI, RegKills, KillOps); VRM->RemoveMachineInstrFromMaps(&MI); @@ -2442,28 +2443,6 @@ LocalRewriter::RewriteMBB(LiveIntervals *LIs, Spills.disallowClobberPhysReg(VirtReg); goto ProcessNextInst; } - unsigned Src, Dst, SrcSR, DstSR; - if (TII->isMoveInstr(MI, Src, Dst, SrcSR, DstSR) && - Src == Dst && SrcSR == DstSR && - !MI.findRegisterUseOperand(Src)->isUndef()) { - ++NumDCE; - DEBUG(dbgs() << "Removing now-noop copy: " << MI); - SmallVector<unsigned, 2> KillRegs; - InvalidateKills(MI, TRI, RegKills, KillOps, &KillRegs); - if (MO.isDead() && !KillRegs.empty()) { - // Source register or an implicit super/sub-register use is killed. - assert(KillRegs[0] == Dst || - TRI->isSubRegister(KillRegs[0], Dst) || - TRI->isSuperRegister(KillRegs[0], Dst)); - // Last def is now dead. - TransferDeadness(Src, RegKills, KillOps); - } - VRM->RemoveMachineInstrFromMaps(&MI); - MBB->erase(&MI); - Erased = true; - Spills.disallowClobberPhysReg(VirtReg); - goto ProcessNextInst; - } // If it's not a no-op copy, it clobbers the value in the destreg. Spills.ClobberPhysReg(VirtReg); @@ -2541,20 +2520,6 @@ LocalRewriter::RewriteMBB(LiveIntervals *LIs, UpdateKills(*LastStore, TRI, RegKills, KillOps); goto ProcessNextInst; } - { - unsigned Src, Dst, SrcSR, DstSR; - if (TII->isMoveInstr(MI, Src, Dst, SrcSR, DstSR) && - Src == Dst && SrcSR == DstSR) { - ++NumDCE; - DEBUG(dbgs() << "Removing now-noop copy: " << MI); - InvalidateKills(MI, TRI, RegKills, KillOps); - VRM->RemoveMachineInstrFromMaps(&MI); - MBB->erase(&MI); - Erased = true; - UpdateKills(*LastStore, TRI, RegKills, KillOps); - goto ProcessNextInst; - } - } } } ProcessNextInst: |