From: Evan Cheng Date: Fri, 14 Mar 2008 00:14:55 +0000 (+0000) Subject: Livein copy scheduling fixes: do not coalesce physical register copies, correctly... X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=db2d773fe6e53995c49c11ba34271fc559e286a1;p=oota-llvm.git Livein copy scheduling fixes: do not coalesce physical register copies, correctly determine the safe location to insert the copies. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48348 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp index 2bf8d5dc3c8..45237756a8d 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp @@ -987,50 +987,14 @@ void ScheduleDAG::EmitCrossRCCopy(SUnit *SU, } } -/// regIsLive - Return true if the specified register is live due to a -/// live in copy. -static bool regIsLive(unsigned Reg, BitVector &LiveRegs, - const TargetRegisterInfo *TRI) { - if (LiveRegs[Reg]) - return true; - for (const unsigned *AS = TRI->getAliasSet(Reg); *AS; ++AS) - if (LiveRegs[*AS]) - return true; - return false; -} - -/// regIsClobbered - Return true if the specified register is defined in -/// between the two specific instructions. -static bool regIsClobbered(unsigned Reg, MachineBasicBlock *MBB, - MachineBasicBlock::iterator InsertPos, - MachineBasicBlock::iterator UsePos, - const TargetRegisterInfo *TRI) { - for (MachineBasicBlock::iterator I = InsertPos; I != UsePos; ++I) { - MachineInstr *MI = I; - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - const MachineOperand &MO = MI->getOperand(i); - if (!MO.isRegister() || !MO.isDef()) - continue; - unsigned DefReg = MO.getReg(); - if (TargetRegisterInfo::isVirtualRegister(DefReg)) - continue; - if (TRI->regsOverlap(DefReg, Reg)) - return true; - } - } - return false; -} - /// EmitLiveInCopy - Emit a copy for a live in physical register. If the /// physical register has only a single copy use, then coalesced the copy -/// if possible. It returns the destination register of the emitted copy -/// if it is a physical register; otherwise it returns zero. -unsigned ScheduleDAG::EmitLiveInCopy(MachineBasicBlock *MBB, - MachineBasicBlock::iterator &InsertPos, - unsigned VirtReg, unsigned PhysReg, - const TargetRegisterClass *RC, - BitVector &LiveRegsBefore, - BitVector &LiveRegsAfter) { +/// if possible. +void ScheduleDAG::EmitLiveInCopy(MachineBasicBlock *MBB, + MachineBasicBlock::iterator &InsertPos, + unsigned VirtReg, unsigned PhysReg, + const TargetRegisterClass *RC, + DenseMap &CopyRegMap){ unsigned NumUses = 0; MachineInstr *UseMI = NULL; for (MachineRegisterInfo::use_iterator UI = MRI.use_begin(VirtReg), @@ -1041,95 +1005,61 @@ unsigned ScheduleDAG::EmitLiveInCopy(MachineBasicBlock *MBB, } // If the number of uses is not one, or the use is not a move instruction, - // don't coalesce. + // don't coalesce. Also, only coalesce away a virtual register to virtual + // register copy. + bool Coalesced = false; unsigned SrcReg, DstReg; - if (NumUses != 1 || - !TII->isMoveInstr(*UseMI, SrcReg, DstReg)) { - TII->copyRegToReg(*MBB, InsertPos, VirtReg, PhysReg, RC, RC); - return 0; + if (NumUses == 1 && + TII->isMoveInstr(*UseMI, SrcReg, DstReg) && + TargetRegisterInfo::isVirtualRegister(DstReg)) { + VirtReg = DstReg; + Coalesced = true; } - // Coalesce away a virtual register to virtual register copy. - if (TargetRegisterInfo::isVirtualRegister(DstReg)) { - TII->copyRegToReg(*MBB, InsertPos, DstReg, PhysReg, RC, RC); - if (&*InsertPos == UseMI) ++InsertPos; - MBB->erase(UseMI); - return 0; - } - - // If the destination is a physical register, check if it's safe to - // coalesce. If there is a def of the register between the insertion point and - // the use, then it's not safe. - if (regIsClobbered(DstReg, MBB, InsertPos, UseMI, TRI)) { - TII->copyRegToReg(*MBB, InsertPos, VirtReg, PhysReg, RC, RC); - return 0; + // Now find an ideal location to insert the copy. + MachineBasicBlock::iterator Pos = InsertPos; + while (Pos != MBB->begin()) { + MachineInstr *PrevMI = prior(Pos); + DenseMap::iterator RI = CopyRegMap.find(PrevMI); + // copyRegToReg might emit multiple instructions to do a copy. + unsigned CopyDstReg = (RI == CopyRegMap.end()) ? 0 : RI->second; + if (CopyDstReg && !TRI->regsOverlap(CopyDstReg, PhysReg)) + // This is what the BB looks like right now: + // r1024 = mov r0 + // ... + // r1 = mov r1024 + // + // We want to insert "r1025 = mov r1". Inserting this copy below the + // move to r1024 makes it impossible for that move to be coalesced. + // + // r1025 = mov r1 + // r1024 = mov r0 + // ... + // r1 = mov 1024 + // r2 = mov 1025 + break; // Woot! Found a good location. + --Pos; } - // Also check already processed livein copies and determine the safe location - // to insert the copy. e.g. Suppose livein r0 is already processed and now - // we are inserting r1 copy to vr1025 which will be coalesced to r0. - // vr1024 = r0 - // - // ... - // It's safe to insert the copy from r1 to r0. - // vr1024 = r0 - // r0 = r1 - // - // However, if livein r0 copy is coalesced to r1: - // r1 = r0 - // - // ... - // Then it's not safe to insert the copy from r1 to r0 at the insertion pt. - // Nor is it safe to insert it at the start of the MBB. - // - // If livein r3 is already processed and it's coalesced to r1. - // -- safe to insert here - // r1 = r3 - // -- not safe - // Then it's safe to insert at the start of the MBB. - if (regIsLive(DstReg, LiveRegsAfter, TRI)) { - if (regIsLive(PhysReg, LiveRegsBefore, TRI)) { - // FIXME: Still possible to find a safe place to insert the copy. - TII->copyRegToReg(*MBB, InsertPos, VirtReg, PhysReg, RC, RC); - return 0; - } - TII->copyRegToReg(*MBB, MBB->begin(), DstReg, PhysReg, RC, RC); + TII->copyRegToReg(*MBB, Pos, VirtReg, PhysReg, RC, RC); + CopyRegMap.insert(std::make_pair(prior(Pos), VirtReg)); + if (Coalesced) { if (&*InsertPos == UseMI) ++InsertPos; MBB->erase(UseMI); - return DstReg; } - TII->copyRegToReg(*MBB, InsertPos, DstReg, PhysReg, RC, RC); - if (&*InsertPos == UseMI) ++InsertPos; - MBB->erase(UseMI); - return DstReg; } /// EmitLiveInCopies - If this is the first basic block in the function, /// and if it has live ins that need to be copied into vregs, emit the /// copies into the top of the block. void ScheduleDAG::EmitLiveInCopies(MachineBasicBlock *MBB) { - BitVector LiveRegsBefore; // Live registers before insertion pt. - BitVector LiveRegsAfter; // Live registers after insertion pt. - LiveRegsBefore.resize(TRI->getNumRegs()); - LiveRegsAfter.resize(TRI->getNumRegs()); - + DenseMap CopyRegMap; MachineBasicBlock::iterator InsertPos = MBB->begin(); for (MachineRegisterInfo::livein_iterator LI = MRI.livein_begin(), E = MRI.livein_end(); LI != E; ++LI) if (LI->second) { const TargetRegisterClass *RC = MRI.getRegClass(LI->second); - unsigned Reg = EmitLiveInCopy(MBB, InsertPos, LI->second, LI->first, RC, - LiveRegsBefore, LiveRegsAfter); - if (Reg) { - LiveRegsAfter.set(Reg); - for (const unsigned *SubRegs = TRI->getSubRegisters(Reg); - unsigned SubReg = *SubRegs; ++SubRegs) - LiveRegsAfter.set(SubReg); - } - LiveRegsBefore.set(LI->first); - for (const unsigned *SubRegs = TRI->getSubRegisters(LI->first); - unsigned SubReg = *SubRegs; ++SubRegs) - LiveRegsBefore.set(SubReg); + EmitLiveInCopy(MBB, InsertPos, LI->second, LI->first, RC, CopyRegMap); } }