X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FRegisterCoalescer.cpp;h=9b414d6212c73aebb99957c63eb3c7d21450ece2;hb=df234353fb396e84e7a3a1cdd94f73681e65bd88;hp=d2087f9beea7cd8119964cf6754edf63d63ea839;hpb=c19e6dd64fe4fa825c8d79e1d097e301c66eaf72;p=oota-llvm.git diff --git a/lib/CodeGen/RegisterCoalescer.cpp b/lib/CodeGen/RegisterCoalescer.cpp index d2087f9beea..9b414d6212c 100644 --- a/lib/CodeGen/RegisterCoalescer.cpp +++ b/lib/CodeGen/RegisterCoalescer.cpp @@ -55,6 +55,7 @@ STATISTIC(numExtends , "Number of copies extended"); STATISTIC(NumReMats , "Number of instructions re-materialized"); STATISTIC(numPeep , "Number of identity moves eliminated after coalescing"); STATISTIC(numAborts , "Number of times interval joining aborted"); +STATISTIC(NumInflated , "Number of register classes inflated"); static cl::opt EnableJoining("join-liveintervals", @@ -143,8 +144,7 @@ namespace { /// trivial computation, replace the copy by rematerialize the definition. /// If PreserveSrcInt is true, make sure SrcInt is valid after the call. bool ReMaterializeTrivialDef(LiveInterval &SrcInt, bool PreserveSrcInt, - unsigned DstReg, unsigned DstSubIdx, - MachineInstr *CopyMI); + unsigned DstReg, MachineInstr *CopyMI); /// shouldJoinPhys - Return true if a physreg copy should be joined. bool shouldJoinPhys(CoalescerPair &CP); @@ -288,7 +288,7 @@ bool CoalescerPair::setRegisters(const MachineInstr *MI) { return false; const TargetRegisterClass *SrcRC = MRI.getRegClass(Src); const TargetRegisterClass *DstRC = MRI.getRegClass(Dst); - if (!getCommonSubClass(DstRC, SrcRC)) + if (!TRI.getCommonSubClass(DstRC, SrcRC)) return false; SrcSub = DstSub = 0; } @@ -308,7 +308,7 @@ bool CoalescerPair::setRegisters(const MachineInstr *MI) { if (DstSub) NewRC = TRI.getMatchingSuperRegClass(DstRC, SrcRC, DstSub); else - NewRC = getCommonSubClass(DstRC, SrcRC); + NewRC = TRI.getCommonSubClass(DstRC, SrcRC); if (!NewRC) return false; CrossClass = NewRC != DstRC || NewRC != SrcRC; @@ -691,7 +691,7 @@ bool RegisterCoalescer::RemoveCopyByCommutingDef(const CoalescerPair &CP, // If some of the uses of IntA.reg is already coalesced away, return false. // It's not possible to determine whether it's safe to perform the coalescing. - for (MachineRegisterInfo::use_nodbg_iterator UI = + for (MachineRegisterInfo::use_nodbg_iterator UI = MRI->use_nodbg_begin(IntA.reg), UE = MRI->use_nodbg_end(); UI != UE; ++UI) { MachineInstr *UseMI = &*UI; @@ -798,15 +798,12 @@ bool RegisterCoalescer::RemoveCopyByCommutingDef(const CoalescerPair &CP, bool RegisterCoalescer::ReMaterializeTrivialDef(LiveInterval &SrcInt, bool preserveSrcInt, unsigned DstReg, - unsigned DstSubIdx, MachineInstr *CopyMI) { SlotIndex CopyIdx = LIS->getInstructionIndex(CopyMI).getUseIndex(); LiveInterval::iterator SrcLR = SrcInt.FindLiveRangeContaining(CopyIdx); assert(SrcLR != SrcInt.end() && "Live range not found!"); VNInfo *ValNo = SrcLR->valno; - // If other defs can reach uses of this def, then it's not safe to perform - // the optimization. - if (ValNo->isPHIDef() || ValNo->isUnused() || ValNo->hasPHIKill()) + if (ValNo->isPHIDef() || ValNo->isUnused()) return false; MachineInstr *DefMI = LIS->getInstructionFromIndex(ValNo->def); if (!DefMI) @@ -834,28 +831,12 @@ bool RegisterCoalescer::ReMaterializeTrivialDef(LiveInterval &SrcInt, return false; } - // If destination register has a sub-register index on it, make sure it - // matches the instruction register class. - if (DstSubIdx) { - const MCInstrDesc &MCID = DefMI->getDesc(); - if (MCID.getNumDefs() != 1) - return false; - const TargetRegisterClass *DstRC = MRI->getRegClass(DstReg); - const TargetRegisterClass *DstSubRC = - DstRC->getSubRegisterRegClass(DstSubIdx); - const TargetRegisterClass *DefRC = TII->getRegClass(MCID, 0, TRI); - if (DefRC == DstRC) - DstSubIdx = 0; - else if (DefRC != DstSubRC) - return false; - } - RemoveCopyFlag(DstReg, CopyMI); MachineBasicBlock *MBB = CopyMI->getParent(); MachineBasicBlock::iterator MII = llvm::next(MachineBasicBlock::iterator(CopyMI)); - TII->reMaterialize(*MBB, MII, DstReg, DstSubIdx, DefMI, *TRI); + TII->reMaterialize(*MBB, MII, DstReg, 0, DefMI, *TRI); MachineInstr *NewMI = prior(MII); // CopyMI may have implicit operands, transfer them over to the newly @@ -947,15 +928,13 @@ RegisterCoalescer::UpdateRegDefsUses(const CoalescerPair &CP) { // A PhysReg copy that won't be coalesced can perhaps be rematerialized // instead. if (DstIsPhys) { - if (UseMI->isCopy() && - !UseMI->getOperand(1).getSubReg() && - !UseMI->getOperand(0).getSubReg() && + if (UseMI->isFullCopy() && UseMI->getOperand(1).getReg() == SrcReg && UseMI->getOperand(0).getReg() != SrcReg && UseMI->getOperand(0).getReg() != DstReg && !JoinedCopies.count(UseMI) && ReMaterializeTrivialDef(LIS->getInterval(SrcReg), false, - UseMI->getOperand(0).getReg(), 0, UseMI)) + UseMI->getOperand(0).getReg(), UseMI)) continue; } @@ -970,6 +949,14 @@ RegisterCoalescer::UpdateRegDefsUses(const CoalescerPair &CP) { Kills |= MO.isKill(); Deads |= MO.isDead(); + // Make sure we don't create read-modify-write defs accidentally. We + // assume here that a SrcReg def cannot be joined into a live DstReg. If + // RegisterCoalescer starts tracking partially live registers, we will + // need to check the actual LiveInterval to determine if DstReg is live + // here. + if (SubIdx && !Reads) + MO.setIsUndef(); + if (DstIsPhys) MO.substPhysReg(DstReg, *TRI); else @@ -1203,7 +1190,7 @@ bool RegisterCoalescer::JoinCopy(MachineInstr *CopyMI, bool &Again) { // trivial computation, try rematerializing it. if (!CP.isFlipped() && ReMaterializeTrivialDef(LIS->getInterval(CP.getSrcReg()), true, - CP.getDstReg(), 0, CopyMI)) + CP.getDstReg(), CopyMI)) return true; return false; } @@ -1242,7 +1229,7 @@ bool RegisterCoalescer::JoinCopy(MachineInstr *CopyMI, bool &Again) { // rematerializing it. if (!CP.isFlipped() && ReMaterializeTrivialDef(LIS->getInterval(CP.getSrcReg()), true, - CP.getDstReg(), 0, CopyMI)) + CP.getDstReg(), CopyMI)) return true; // If we can eliminate the copy without merging the live ranges, do so now. @@ -1371,6 +1358,7 @@ static unsigned ComputeUltimateVN(VNInfo *VNI, // which allows us to coalesce A and B. // VNI is the definition of B. LR is the life range of A that includes // the slot just before B. If we return true, we add "B = X" to DupCopies. +// This implies that A dominates B. static bool RegistersDefinedFromSameValue(LiveIntervals &li, const TargetRegisterInfo &tri, CoalescerPair &CP, @@ -1422,7 +1410,9 @@ static bool RegistersDefinedFromSameValue(LiveIntervals &li, // If the copies use two different value numbers of X, we cannot merge // A and B. LiveInterval &SrcInt = li.getInterval(Src); - if (SrcInt.getVNInfoAt(Other->def) != SrcInt.getVNInfoAt(VNI->def)) + // getVNInfoBefore returns NULL for undef copies. In this case, the + // optimization is still safe. + if (SrcInt.getVNInfoBefore(Other->def) != SrcInt.getVNInfoBefore(VNI->def)) return false; DupCopies.push_back(MI); @@ -1852,7 +1842,7 @@ bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) { // Perform a final pass over the instructions and compute spill weights // and remove identity moves. - SmallVector DeadDefs; + SmallVector DeadDefs, InflateRegs; for (MachineFunction::iterator mbbi = MF->begin(), mbbe = MF->end(); mbbi != mbbe; ++mbbi) { MachineBasicBlock* mbb = mbbi; @@ -1864,6 +1854,16 @@ bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) { bool DoDelete = true; assert(MI->isCopyLike() && "Unrecognized copy instruction"); unsigned SrcReg = MI->getOperand(MI->isSubregToReg() ? 2 : 1).getReg(); + unsigned DstReg = MI->getOperand(0).getReg(); + + // Collect candidates for register class inflation. + if (TargetRegisterInfo::isVirtualRegister(SrcReg) && + RegClassInfo.isProperSubClass(MRI->getRegClass(SrcReg))) + InflateRegs.push_back(SrcReg); + if (TargetRegisterInfo::isVirtualRegister(DstReg) && + RegClassInfo.isProperSubClass(MRI->getRegClass(DstReg))) + InflateRegs.push_back(DstReg); + if (TargetRegisterInfo::isPhysicalRegister(SrcReg) && MI->getNumOperands() > 2) // Do not delete extract_subreg, insert_subreg of physical @@ -1905,8 +1905,12 @@ bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) { unsigned Reg = MO.getReg(); if (!Reg) continue; - if (TargetRegisterInfo::isVirtualRegister(Reg)) + if (TargetRegisterInfo::isVirtualRegister(Reg)) { DeadDefs.push_back(Reg); + // Remat may also enable register class inflation. + if (RegClassInfo.isProperSubClass(MRI->getRegClass(Reg))) + InflateRegs.push_back(Reg); + } if (MO.isDead()) continue; if (TargetRegisterInfo::isPhysicalRegister(Reg) || @@ -1954,6 +1958,24 @@ bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) { } } + // After deleting a lot of copies, register classes may be less constrained. + // Removing sub-register opreands may alow GR32_ABCD -> GR32 and DPR_VFP2 -> + // DPR inflation. + array_pod_sort(InflateRegs.begin(), InflateRegs.end()); + InflateRegs.erase(std::unique(InflateRegs.begin(), InflateRegs.end()), + InflateRegs.end()); + DEBUG(dbgs() << "Trying to inflate " << InflateRegs.size() << " regs.\n"); + for (unsigned i = 0, e = InflateRegs.size(); i != e; ++i) { + unsigned Reg = InflateRegs[i]; + if (MRI->reg_nodbg_empty(Reg)) + continue; + if (MRI->recomputeRegClass(Reg, *TM)) { + DEBUG(dbgs() << PrintReg(Reg) << " inflated to " + << MRI->getRegClass(Reg)->getName() << '\n'); + ++NumInflated; + } + } + DEBUG(dump()); DEBUG(LDV->dump()); if (VerifyCoalescing)