X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FTwoAddressInstructionPass.cpp;h=3c404046f15e49e875ccde2756fb780bd8b33bce;hb=626742231863db0e9aeef1be1fd48e9f4b7e22f8;hp=8a18dc0fc79dfae4beb784f6ca1ef1e56c8af666;hpb=3005ed604835834534b61ea4a8f8be29f6868627;p=oota-llvm.git diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp index 8a18dc0fc79..3c404046f15 100644 --- a/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -88,6 +88,9 @@ namespace { bool NoUseAfterLastDef(unsigned Reg, MachineBasicBlock *MBB, unsigned Dist, unsigned &LastDef); + MachineInstr *FindLastUseInMBB(unsigned Reg, MachineBasicBlock *MBB, + unsigned Dist); + bool isProfitableToCommute(unsigned regB, unsigned regC, MachineInstr *MI, MachineBasicBlock *MBB, unsigned Dist); @@ -310,6 +313,31 @@ bool TwoAddressInstructionPass::NoUseAfterLastDef(unsigned Reg, return !(LastUse > LastDef && LastUse < Dist); } +MachineInstr *TwoAddressInstructionPass::FindLastUseInMBB(unsigned Reg, + MachineBasicBlock *MBB, + unsigned Dist) { + unsigned LastUseDist = 0; + MachineInstr *LastUse = 0; + for (MachineRegisterInfo::reg_iterator I = MRI->reg_begin(Reg), + E = MRI->reg_end(); I != E; ++I) { + MachineOperand &MO = I.getOperand(); + MachineInstr *MI = MO.getParent(); + if (MI->getParent() != MBB) + continue; + DenseMap::iterator DI = DistanceMap.find(MI); + if (DI == DistanceMap.end()) + continue; + if (DI->second >= Dist) + continue; + + if (MO.isUse() && DI->second > LastUseDist) { + LastUse = DI->first; + LastUseDist = DI->second; + } + } + return LastUse; +} + /// isCopyToReg - Return true if the specified MI is a copy instruction or /// a extract_subreg instruction. It also returns the source and destination /// registers and whether they are physical registers by reference. @@ -405,7 +433,7 @@ static MachineInstr *findOnlyInterestingUse(unsigned Reg, MachineBasicBlock *MBB, MachineRegisterInfo *MRI, const TargetInstrInfo *TII, - bool &isCopy, + bool &IsCopy, unsigned &DstReg, bool &IsDstPhys) { MachineRegisterInfo::use_iterator UI = MRI->use_begin(Reg); if (UI == MRI->use_end()) @@ -418,11 +446,15 @@ MachineInstr *findOnlyInterestingUse(unsigned Reg, MachineBasicBlock *MBB, return 0; unsigned SrcReg; bool IsSrcPhys; - if (isCopyToReg(UseMI, TII, SrcReg, DstReg, IsSrcPhys, IsDstPhys)) + if (isCopyToReg(UseMI, TII, SrcReg, DstReg, IsSrcPhys, IsDstPhys)) { + IsCopy = true; return &UseMI; + } IsDstPhys = false; - if (isTwoAddrUse(UseMI, Reg, DstReg)) + if (isTwoAddrUse(UseMI, Reg, DstReg)) { + IsDstPhys = TargetRegisterInfo::isPhysicalRegister(DstReg); return &UseMI; + } return 0; } @@ -634,12 +666,12 @@ void TwoAddressInstructionPass::ProcessCopy(MachineInstr *MI, "Can't map to two src physical registers!"); SmallVector VirtRegPairs; - bool isCopy = false; + bool IsCopy = false; unsigned NewReg = 0; while (MachineInstr *UseMI = findOnlyInterestingUse(DstReg, MBB, MRI,TII, - isCopy, NewReg, IsDstPhys)) { - if (isCopy) { - if (Processed.insert(UseMI)) + IsCopy, NewReg, IsDstPhys)) { + if (IsCopy) { + if (!Processed.insert(UseMI)) break; } @@ -654,8 +686,8 @@ void TwoAddressInstructionPass::ProcessCopy(MachineInstr *MI, } bool isNew = SrcRegMap.insert(std::make_pair(NewReg, DstReg)).second; if (!isNew) - assert(SrcRegMap[NewReg] == DstReg && - "Can't map to two src physical registers!"); + assert(SrcRegMap[NewReg] == DstReg && + "Can't map to two src physical registers!"); VirtRegPairs.push_back(NewReg); DstReg = NewReg; } @@ -680,7 +712,9 @@ void TwoAddressInstructionPass::ProcessCopy(MachineInstr *MI, /// isSafeToDelete - If the specified instruction does not produce any side /// effects and all of its defs are dead, then it's safe to delete. -static bool isSafeToDelete(MachineInstr *MI, const TargetInstrInfo *TII) { +static bool isSafeToDelete(MachineInstr *MI, unsigned Reg, + const TargetInstrInfo *TII, + SmallVector &Kills) { const TargetInstrDesc &TID = MI->getDesc(); if (TID.mayStore() || TID.isCall()) return false; @@ -689,10 +723,12 @@ static bool isSafeToDelete(MachineInstr *MI, const TargetInstrInfo *TII) { for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { MachineOperand &MO = MI->getOperand(i); - if (!MO.isReg() || !MO.isDef()) + if (!MO.isReg()) continue; - if (!MO.isDead()) + if (MO.isDef() && !MO.isDead()) return false; + if (MO.isUse() && MO.getReg() != Reg && MO.isKill()) + Kills.push_back(MO.getReg()); } return true; @@ -783,11 +819,59 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) { if (!isKilled(*mi, regB, MRI, TII)) { // If regA is dead and the instruction can be deleted, just delete // it so it doesn't clobber regB. - if (mi->getOperand(ti).isDead() && isSafeToDelete(mi, TII)) { - mbbi->erase(mi); // Nuke the old inst. - mi = nmi; - ++NumDeletes; - break; // Done with this instruction. + SmallVector Kills; + if (mi->getOperand(ti).isDead() && + isSafeToDelete(mi, regB, TII, Kills)) { + SmallVector + ,MachineInstr*>, 4> NewKills; + bool ReallySafe = true; + // If this instruction kills some virtual registers, we need + // update the kill information. If it's not possible to do so, + // then bail out. + while (!Kills.empty()) { + unsigned Kill = Kills.back(); + Kills.pop_back(); + if (TargetRegisterInfo::isPhysicalRegister(Kill)) { + ReallySafe = false; + break; + } + MachineInstr *LastKill = FindLastUseInMBB(Kill, &*mbbi, Dist); + if (LastKill) { + bool isModRef = LastKill->modifiesRegister(Kill); + NewKills.push_back(std::make_pair(std::make_pair(Kill,isModRef), + LastKill)); + } else { + ReallySafe = false; + break; + } + } + + if (ReallySafe) { + if (LV) { + while (!NewKills.empty()) { + MachineInstr *NewKill = NewKills.back().second; + unsigned Kill = NewKills.back().first.first; + bool isDead = NewKills.back().first.second; + NewKills.pop_back(); + if (LV->removeVirtualRegisterKilled(Kill, mi)) { + if (isDead) + LV->addVirtualRegisterDead(Kill, NewKill); + else + LV->addVirtualRegisterKilled(Kill, NewKill); + } + } + } + + // We're really going to nuke the old inst. If regB was marked + // as a kill we need to update its Kills list. + if (mi->getOperand(si).isKill()) + LV->removeVirtualRegisterKilled(regB, mi); + + mbbi->erase(mi); // Nuke the old inst. + mi = nmi; + ++NumDeletes; + break; // Done with this instruction. + } } // If this instruction is commutative, check to see if C dies. If @@ -860,6 +944,7 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) { ++NumReMats; } else { bool Emitted = TII->copyRegToReg(*mbbi, mi, regA, regB, rc, rc); + (void)Emitted; assert(Emitted && "Unable to issue a copy instruction!\n"); } @@ -870,11 +955,6 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) { // Update live variables for regB. if (LV) { - LiveVariables::VarInfo& varInfoB = LV->getVarInfo(regB); - - // regB is used in this BB. - varInfoB.UsedBlocks[mbbi->getNumber()] = true; - if (LV->removeVirtualRegisterKilled(regB, mi)) LV->addVirtualRegisterKilled(regB, prevMI);