diff options
Diffstat (limited to 'llvm/lib/CodeGen/RegisterCoalescer.cpp')
| -rw-r--r-- | llvm/lib/CodeGen/RegisterCoalescer.cpp | 270 |
1 files changed, 174 insertions, 96 deletions
diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp index 17160a9f42cd..7fdc85a6e444 100644 --- a/llvm/lib/CodeGen/RegisterCoalescer.cpp +++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp @@ -137,13 +137,13 @@ namespace { /// ordered-by-slot-index set of DBG_VALUEs, to help quick /// identification of whether coalescing may change location validity. using DbgValueLoc = std::pair<SlotIndex, MachineInstr*>; - DenseMap<unsigned, std::vector<DbgValueLoc>> DbgVRegToValues; + DenseMap<Register, std::vector<DbgValueLoc>> DbgVRegToValues; /// VRegs may be repeatedly coalesced, and have many DBG_VALUEs attached. /// To avoid repeatedly merging sets of DbgValueLocs, instead record /// which vregs have been coalesced, and where to. This map is from /// vreg => {set of vregs merged in}. - DenseMap<unsigned, SmallVector<unsigned, 4>> DbgMergedVRegNums; + DenseMap<Register, SmallVector<Register, 4>> DbgMergedVRegNums; /// A LaneMask to remember on which subregister live ranges we need to call /// shrinkToUses() later. @@ -173,16 +173,16 @@ namespace { SmallVector<MachineInstr*, 8> DeadDefs; /// Virtual registers to be considered for register class inflation. - SmallVector<unsigned, 8> InflateRegs; + SmallVector<Register, 8> InflateRegs; /// The collection of live intervals which should have been updated /// immediately after rematerialiation but delayed until /// lateLiveIntervalUpdate is called. - DenseSet<unsigned> ToBeUpdated; + DenseSet<Register> ToBeUpdated; /// Record how many times the large live interval with many valnos /// has been tried to join with other live interval. - DenseMap<unsigned, unsigned long> LargeLIVisitCounter; + DenseMap<Register, unsigned long> LargeLIVisitCounter; /// Recursively eliminate dead defs in DeadDefs. void eliminateDeadDefs(); @@ -211,6 +211,18 @@ namespace { /// live interval update is costly. void lateLiveIntervalUpdate(); + /// Check if the incoming value defined by a COPY at \p SLRQ in the subrange + /// has no value defined in the predecessors. If the incoming value is the + /// same as defined by the copy itself, the value is considered undefined. + bool copyValueUndefInPredecessors(LiveRange &S, + const MachineBasicBlock *MBB, + LiveQueryResult SLRQ); + + /// Set necessary undef flags on subregister uses after pruning out undef + /// lane segments from the subrange. + void setUndefOnPrunedSubRegUses(LiveInterval &LI, Register Reg, + LaneBitmask PrunedLanes); + /// Attempt to join intervals corresponding to SrcReg/DstReg, which are the /// src/dst of the copy instruction CopyMI. This returns true if the copy /// was successfully coalesced away. If it is not currently possible to @@ -285,7 +297,7 @@ namespace { /// number if it is not zero. If DstReg is a physical register and the /// existing subregister number of the def / use being updated is not zero, /// make sure to set it to the correct physical subregister. - void updateRegDefsUses(unsigned SrcReg, unsigned DstReg, unsigned SubIdx); + void updateRegDefsUses(Register SrcReg, Register DstReg, unsigned SubIdx); /// If the given machine operand reads only undefined lanes add an undef /// flag. @@ -351,7 +363,7 @@ namespace { JoinVals &LHSVals, LiveRange &RHS, JoinVals &RHSVals); - void checkMergingChangesDbgValuesImpl(unsigned Reg, LiveRange &OtherRange, + void checkMergingChangesDbgValuesImpl(Register Reg, LiveRange &OtherRange, LiveRange &RegRange, JoinVals &Vals2); public: @@ -388,8 +400,8 @@ INITIALIZE_PASS_END(RegisterCoalescer, "simple-register-coalescing", "Simple Register Coalescing", false, false) LLVM_NODISCARD static bool isMoveInstr(const TargetRegisterInfo &tri, - const MachineInstr *MI, unsigned &Src, - unsigned &Dst, unsigned &SrcSub, + const MachineInstr *MI, Register &Src, + Register &Dst, unsigned &SrcSub, unsigned &DstSub) { if (MI->isCopy()) { Dst = MI->getOperand(0).getReg(); @@ -424,12 +436,13 @@ static bool isSplitEdge(const MachineBasicBlock *MBB) { } bool CoalescerPair::setRegisters(const MachineInstr *MI) { - SrcReg = DstReg = 0; + SrcReg = DstReg = Register(); SrcIdx = DstIdx = 0; NewRC = nullptr; Flipped = CrossClass = false; - unsigned Src, Dst, SrcSub, DstSub; + Register Src, Dst; + unsigned SrcSub = 0, DstSub = 0; if (!isMoveInstr(TRI, MI, Src, Dst, SrcSub, DstSub)) return false; Partial = SrcSub || DstSub; @@ -523,7 +536,8 @@ bool CoalescerPair::flip() { bool CoalescerPair::isCoalescable(const MachineInstr *MI) const { if (!MI) return false; - unsigned Src, Dst, SrcSub, DstSub; + Register Src, Dst; + unsigned SrcSub = 0, DstSub = 0; if (!isMoveInstr(TRI, MI, Src, Dst, SrcSub, DstSub)) return false; @@ -536,8 +550,8 @@ bool CoalescerPair::isCoalescable(const MachineInstr *MI) const { } // Now check that Dst matches DstReg. - if (Register::isPhysicalRegister(DstReg)) { - if (!Register::isPhysicalRegister(Dst)) + if (DstReg.isPhysical()) { + if (!Dst.isPhysical()) return false; assert(!DstIdx && !SrcIdx && "Inconsistent CoalescerPair state."); // DstSub could be set for a physreg from INSERT_SUBREG. @@ -547,7 +561,7 @@ bool CoalescerPair::isCoalescable(const MachineInstr *MI) const { if (!SrcSub) return DstReg == Dst; // This is a partial register copy. Check that the parts match. - return TRI.getSubReg(DstReg, SrcSub) == Dst; + return Register(TRI.getSubReg(DstReg, SrcSub)) == Dst; } else { // DstReg is virtual. if (DstReg != Dst) @@ -649,7 +663,7 @@ bool RegisterCoalescer::adjustCopiesBackFrom(const CoalescerPair &CP, // in IntB, we can merge them. if (ValS+1 != BS) return false; - LLVM_DEBUG(dbgs() << "Extending: " << printReg(IntB.reg, TRI)); + LLVM_DEBUG(dbgs() << "Extending: " << printReg(IntB.reg(), TRI)); SlotIndex FillerStart = ValS->end, FillerEnd = BS->start; // We are about to delete CopyMI, so need to remove it as the 'instruction @@ -692,13 +706,13 @@ bool RegisterCoalescer::adjustCopiesBackFrom(const CoalescerPair &CP, // If the source instruction was killing the source register before the // merge, unset the isKill marker given the live range has been extended. - int UIdx = ValSEndInst->findRegisterUseOperandIdx(IntB.reg, true); + int UIdx = ValSEndInst->findRegisterUseOperandIdx(IntB.reg(), true); if (UIdx != -1) { ValSEndInst->getOperand(UIdx).setIsKill(false); } // Rewrite the copy. - CopyMI->substituteRegister(IntA.reg, IntB.reg, 0, *TRI); + CopyMI->substituteRegister(IntA.reg(), IntB.reg(), 0, *TRI); // If the copy instruction was killing the destination register or any // subrange before the merge trim the live range. bool RecomputeLiveRange = AS->end == CopyIdx; @@ -817,7 +831,7 @@ RegisterCoalescer::removeCopyByCommutingDef(const CoalescerPair &CP, return { false, false }; // If DefMI is a two-address instruction then commuting it will change the // destination register. - int DefIdx = DefMI->findRegisterDefOperandIdx(IntA.reg); + int DefIdx = DefMI->findRegisterDefOperandIdx(IntA.reg()); assert(DefIdx != -1); unsigned UseOpIdx; if (!DefMI->isRegTiedToUseOperand(DefIdx, &UseOpIdx)) @@ -838,7 +852,7 @@ RegisterCoalescer::removeCopyByCommutingDef(const CoalescerPair &CP, MachineOperand &NewDstMO = DefMI->getOperand(NewDstIdx); Register NewReg = NewDstMO.getReg(); - if (NewReg != IntB.reg || !IntB.Query(AValNo->def).isKill()) + if (NewReg != IntB.reg() || !IntB.Query(AValNo->def).isKill()) return { false, false }; // Make sure there are no other definitions of IntB that would reach the @@ -848,7 +862,7 @@ 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 (MachineOperand &MO : MRI->use_nodbg_operands(IntA.reg)) { + for (MachineOperand &MO : MRI->use_nodbg_operands(IntA.reg())) { MachineInstr *UseMI = MO.getParent(); unsigned OpNo = &MO - &UseMI->getOperand(0); SlotIndex UseIdx = LIS->getInstructionIndex(*UseMI); @@ -870,9 +884,9 @@ RegisterCoalescer::removeCopyByCommutingDef(const CoalescerPair &CP, TII->commuteInstruction(*DefMI, false, UseOpIdx, NewDstIdx); if (!NewMI) return { false, false }; - if (Register::isVirtualRegister(IntA.reg) && - Register::isVirtualRegister(IntB.reg) && - !MRI->constrainRegClass(IntB.reg, MRI->getRegClass(IntA.reg))) + if (Register::isVirtualRegister(IntA.reg()) && + Register::isVirtualRegister(IntB.reg()) && + !MRI->constrainRegClass(IntB.reg(), MRI->getRegClass(IntA.reg()))) return { false, false }; if (NewMI != DefMI) { LIS->ReplaceMachineInstrInMaps(*DefMI, *NewMI); @@ -891,9 +905,10 @@ RegisterCoalescer::removeCopyByCommutingDef(const CoalescerPair &CP, // = B // Update uses of IntA of the specific Val# with IntB. - for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(IntA.reg), + for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(IntA.reg()), UE = MRI->use_end(); - UI != UE; /* ++UI is below because of possible MI removal */) { + UI != UE; + /* ++UI is below because of possible MI removal */) { MachineOperand &UseMO = *UI; ++UI; if (UseMO.isUndef()) @@ -920,7 +935,7 @@ RegisterCoalescer::removeCopyByCommutingDef(const CoalescerPair &CP, continue; if (!UseMI->isCopy()) continue; - if (UseMI->getOperand(0).getReg() != IntB.reg || + if (UseMI->getOperand(0).getReg() != IntB.reg() || UseMI->getOperand(0).getSubReg()) continue; @@ -951,10 +966,10 @@ RegisterCoalescer::removeCopyByCommutingDef(const CoalescerPair &CP, BumpPtrAllocator &Allocator = LIS->getVNInfoAllocator(); if (IntA.hasSubRanges() || IntB.hasSubRanges()) { if (!IntA.hasSubRanges()) { - LaneBitmask Mask = MRI->getMaxLaneMaskForVReg(IntA.reg); + LaneBitmask Mask = MRI->getMaxLaneMaskForVReg(IntA.reg()); IntA.createSubRangeFrom(Allocator, Mask, IntA); } else if (!IntB.hasSubRanges()) { - LaneBitmask Mask = MRI->getMaxLaneMaskForVReg(IntB.reg); + LaneBitmask Mask = MRI->getMaxLaneMaskForVReg(IntB.reg()); IntB.createSubRangeFrom(Allocator, Mask, IntB); } SlotIndex AIdx = CopyIdx.getRegSlot(true); @@ -1100,8 +1115,8 @@ bool RegisterCoalescer::removePartialRedundancy(const CoalescerPair &CP, continue; } // Check DefMI is a reverse copy and it is in BB Pred. - if (DefMI->getOperand(0).getReg() != IntA.reg || - DefMI->getOperand(1).getReg() != IntB.reg || + if (DefMI->getOperand(0).getReg() != IntA.reg() || + DefMI->getOperand(1).getReg() != IntB.reg() || DefMI->getParent() != Pred) { CopyLeftBB = Pred; continue; @@ -1158,8 +1173,8 @@ bool RegisterCoalescer::removePartialRedundancy(const CoalescerPair &CP, // Insert new copy to CopyLeftBB. MachineInstr *NewCopyMI = BuildMI(*CopyLeftBB, InsPos, CopyMI.getDebugLoc(), - TII->get(TargetOpcode::COPY), IntB.reg) - .addReg(IntA.reg); + TII->get(TargetOpcode::COPY), IntB.reg()) + .addReg(IntA.reg()); SlotIndex NewCopyIdx = LIS->InsertMachineInstrInMaps(*NewCopyMI).getRegSlot(); IntB.createDeadDef(NewCopyIdx, LIS->getVNInfoAllocator()); @@ -1212,7 +1227,10 @@ bool RegisterCoalescer::removePartialRedundancy(const CoalescerPair &CP, } ++I; } - LIS->extendToIndices(SR, EndPoints); + SmallVector<SlotIndex, 8> Undefs; + IntB.computeSubRangeUndefs(Undefs, SR.LaneMask, *MRI, + *LIS->getSlotIndexes()); + LIS->extendToIndices(SR, EndPoints, Undefs); } // If any dead defs were extended, truncate them. shrinkToUses(&IntB); @@ -1224,9 +1242,9 @@ bool RegisterCoalescer::removePartialRedundancy(const CoalescerPair &CP, /// Returns true if @p MI defines the full vreg @p Reg, as opposed to just /// defining a subregister. -static bool definesFullReg(const MachineInstr &MI, unsigned Reg) { - assert(!Register::isPhysicalRegister(Reg) && - "This code cannot handle physreg aliasing"); +static bool definesFullReg(const MachineInstr &MI, Register Reg) { + assert(!Reg.isPhysical() && "This code cannot handle physreg aliasing"); + for (const MachineOperand &Op : MI.operands()) { if (!Op.isReg() || !Op.isDef() || Op.getReg() != Reg) continue; @@ -1242,9 +1260,9 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP, MachineInstr *CopyMI, bool &IsDefCopy) { IsDefCopy = false; - unsigned SrcReg = CP.isFlipped() ? CP.getDstReg() : CP.getSrcReg(); + Register SrcReg = CP.isFlipped() ? CP.getDstReg() : CP.getSrcReg(); unsigned SrcIdx = CP.isFlipped() ? CP.getDstIdx() : CP.getSrcIdx(); - unsigned DstReg = CP.isFlipped() ? CP.getSrcReg() : CP.getDstReg(); + Register DstReg = CP.isFlipped() ? CP.getSrcReg() : CP.getDstReg(); unsigned DstIdx = CP.isFlipped() ? CP.getSrcIdx() : CP.getDstIdx(); if (Register::isPhysicalRegister(SrcReg)) return false; @@ -1291,8 +1309,8 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP, const TargetRegisterClass *DefRC = TII->getRegClass(MCID, 0, TRI, *MF); if (!DefMI->isImplicitDef()) { - if (Register::isPhysicalRegister(DstReg)) { - unsigned NewDstReg = DstReg; + if (DstReg.isPhysical()) { + Register NewDstReg = DstReg; unsigned NewDstIdx = TRI->composeSubRegIndices(CP.getSrcIdx(), DefMI->getOperand(0).getSubReg()); @@ -1366,7 +1384,7 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP, // NewMI may have dead implicit defs (E.g. EFLAGS for MOV<bits>r0 on X86). // We need to remember these so we can add intervals once we insert // NewMI into SlotIndexes. - SmallVector<unsigned, 4> NewMIImplDefs; + SmallVector<MCRegister, 4> NewMIImplDefs; for (unsigned i = NewMI.getDesc().getNumOperands(), e = NewMI.getNumOperands(); i != e; ++i) { @@ -1374,11 +1392,11 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP, if (MO.isReg() && MO.isDef()) { assert(MO.isImplicit() && MO.isDead() && Register::isPhysicalRegister(MO.getReg())); - NewMIImplDefs.push_back(MO.getReg()); + NewMIImplDefs.push_back(MO.getReg().asMCReg()); } } - if (Register::isVirtualRegister(DstReg)) { + if (DstReg.isVirtual()) { unsigned NewIdx = NewMI.getOperand(0).getSubReg(); if (DefRC != nullptr) { @@ -1513,7 +1531,7 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP, SlotIndex NewMIIdx = LIS->getInstructionIndex(NewMI); for (unsigned i = 0, e = NewMIImplDefs.size(); i != e; ++i) { - unsigned Reg = NewMIImplDefs[i]; + MCRegister Reg = NewMIImplDefs[i]; for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) if (LiveRange *LR = LIS->getCachedRegUnit(*Units)) LR->createDeadDef(NewMIIdx.getRegSlot(), LIS->getVNInfoAllocator()); @@ -1571,7 +1589,8 @@ MachineInstr *RegisterCoalescer::eliminateUndefCopy(MachineInstr *CopyMI) { // Note that we do not query CoalescerPair here but redo isMoveInstr as the // CoalescerPair may have a new register class with adjusted subreg indices // at this point. - unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx; + Register SrcReg, DstReg; + unsigned SrcSubIdx = 0, DstSubIdx = 0; if(!isMoveInstr(*TRI, CopyMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)) return nullptr; @@ -1696,7 +1715,7 @@ void RegisterCoalescer::addUndefFlag(const LiveInterval &Int, SlotIndex UseIdx, } } -void RegisterCoalescer::updateRegDefsUses(unsigned SrcReg, unsigned DstReg, +void RegisterCoalescer::updateRegDefsUses(Register SrcReg, Register DstReg, unsigned SubIdx) { bool DstIsPhys = Register::isPhysicalRegister(DstReg); LiveInterval *DstInt = DstIsPhys ? nullptr : &LIS->getInterval(DstReg); @@ -1752,7 +1771,7 @@ void RegisterCoalescer::updateRegDefsUses(unsigned SrcReg, unsigned DstReg, if (SubIdx != 0 && MO.isUse() && MRI->shouldTrackSubRegLiveness(DstReg)) { if (!DstInt->hasSubRanges()) { BumpPtrAllocator &Allocator = LIS->getVNInfoAllocator(); - LaneBitmask FullMask = MRI->getMaxLaneMaskForVReg(DstInt->reg); + LaneBitmask FullMask = MRI->getMaxLaneMaskForVReg(DstInt->reg()); LaneBitmask UsedLanes = TRI->getSubRegIndexLaneMask(SubIdx); LaneBitmask UnusedLanes = FullMask & ~UsedLanes; DstInt->createSubRangeFrom(Allocator, UsedLanes, *DstInt); @@ -1802,6 +1821,49 @@ bool RegisterCoalescer::canJoinPhys(const CoalescerPair &CP) { return false; } +bool RegisterCoalescer::copyValueUndefInPredecessors( + LiveRange &S, const MachineBasicBlock *MBB, LiveQueryResult SLRQ) { + for (const MachineBasicBlock *Pred : MBB->predecessors()) { + SlotIndex PredEnd = LIS->getMBBEndIdx(Pred); + if (VNInfo *V = S.getVNInfoAt(PredEnd.getPrevSlot())) { + // If this is a self loop, we may be reading the same value. + if (V->id != SLRQ.valueOutOrDead()->id) + return false; + } + } + + return true; +} + +void RegisterCoalescer::setUndefOnPrunedSubRegUses(LiveInterval &LI, + Register Reg, + LaneBitmask PrunedLanes) { + // If we had other instructions in the segment reading the undef sublane + // value, we need to mark them with undef. + for (MachineOperand &MO : MRI->use_nodbg_operands(Reg)) { + unsigned SubRegIdx = MO.getSubReg(); + if (SubRegIdx == 0 || MO.isUndef()) + continue; + + LaneBitmask SubRegMask = TRI->getSubRegIndexLaneMask(SubRegIdx); + SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent()); + for (LiveInterval::SubRange &S : LI.subranges()) { + if (!S.liveAt(Pos) && (PrunedLanes & SubRegMask).any()) { + MO.setIsUndef(); + break; + } + } + } + + LI.removeEmptySubRanges(); + + // A def of a subregister may be a use of other register lanes. Replacing + // such a def with a def of a different register will eliminate the use, + // and may cause the recorded live range to be larger than the actual + // liveness in the program IR. + LIS->shrinkToUses(&LI); +} + bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) { Again = false; LLVM_DEBUG(dbgs() << LIS->getInstructionIndex(*CopyMI) << '\t' << *CopyMI); @@ -1861,16 +1923,35 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) { VNInfo *ReadVNI = LRQ.valueIn(); assert(ReadVNI && "No value before copy and no <undef> flag."); assert(ReadVNI != DefVNI && "Cannot read and define the same value."); - LI.MergeValueNumberInto(DefVNI, ReadVNI); + + // Track incoming undef lanes we need to eliminate from the subrange. + LaneBitmask PrunedLanes; + MachineBasicBlock *MBB = CopyMI->getParent(); // Process subregister liveranges. for (LiveInterval::SubRange &S : LI.subranges()) { LiveQueryResult SLRQ = S.Query(CopyIdx); if (VNInfo *SDefVNI = SLRQ.valueDefined()) { - VNInfo *SReadVNI = SLRQ.valueIn(); - S.MergeValueNumberInto(SDefVNI, SReadVNI); + if (VNInfo *SReadVNI = SLRQ.valueIn()) + SDefVNI = S.MergeValueNumberInto(SDefVNI, SReadVNI); + + // If this copy introduced an undef subrange from an incoming value, + // we need to eliminate the undef live in values from the subrange. + if (copyValueUndefInPredecessors(S, MBB, SLRQ)) { + LLVM_DEBUG(dbgs() << "Incoming sublane value is undef at copy\n"); + PrunedLanes |= S.LaneMask; + S.removeValNo(SDefVNI); + } } } + + LI.MergeValueNumberInto(DefVNI, ReadVNI); + if (PrunedLanes.any()) { + LLVM_DEBUG(dbgs() << "Pruning undef incoming lanes: " + << PrunedLanes << '\n'); + setUndefOnPrunedSubRegUses(LI, CP.getSrcReg(), PrunedLanes); + } + LLVM_DEBUG(dbgs() << "\tMerged values: " << LI << '\n'); } deleteInstr(CopyMI); @@ -1885,7 +1966,7 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) { if (!canJoinPhys(CP)) { // Before giving up coalescing, if definition of source is defined by // trivial computation, try rematerializing it. - bool IsDefCopy; + bool IsDefCopy = false; if (reMaterializeTrivialDef(CP, CopyMI, IsDefCopy)) return true; if (IsDefCopy) @@ -1924,7 +2005,7 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) { // If definition of source is defined by trivial computation, try // rematerializing it. - bool IsDefCopy; + bool IsDefCopy = false; if (reMaterializeTrivialDef(CP, CopyMI, IsDefCopy)) return true; @@ -1938,7 +2019,7 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) { if (Changed) { deleteInstr(CopyMI); if (Shrink) { - unsigned DstReg = CP.isFlipped() ? CP.getSrcReg() : CP.getDstReg(); + Register DstReg = CP.isFlipped() ? CP.getSrcReg() : CP.getDstReg(); LiveInterval &DstLI = LIS->getInterval(DstReg); shrinkToUses(&DstLI); LLVM_DEBUG(dbgs() << "\t\tshrunk: " << DstLI << '\n'); @@ -1991,7 +2072,7 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) { continue; LLVM_DEBUG(dbgs() << "Shrink LaneUses (Lane " << PrintLaneMask(S.LaneMask) << ")\n"); - LIS->shrinkToUses(S, LI.reg); + LIS->shrinkToUses(S, LI.reg()); } LI.removeEmptySubRanges(); } @@ -2030,8 +2111,8 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) { } bool RegisterCoalescer::joinReservedPhysReg(CoalescerPair &CP) { - unsigned DstReg = CP.getDstReg(); - unsigned SrcReg = CP.getSrcReg(); + Register DstReg = CP.getDstReg(); + Register SrcReg = CP.getSrcReg(); assert(CP.isPhys() && "Must be a physreg copy"); assert(MRI->isReserved(DstReg) && "Not a reserved register"); LiveInterval &RHS = LIS->getInterval(SrcReg); @@ -2128,7 +2209,7 @@ bool RegisterCoalescer::joinReservedPhysReg(CoalescerPair &CP) { LLVM_DEBUG(dbgs() << "\t\tRemoving phys reg def of " << printReg(DstReg, TRI) << " at " << CopyRegIdx << "\n"); - LIS->removePhysRegDefAt(DstReg, CopyRegIdx); + LIS->removePhysRegDefAt(DstReg.asMCReg(), CopyRegIdx); // Create a new dead def at the new def location. for (MCRegUnitIterator UI(DstReg, TRI); UI.isValid(); ++UI) { LiveRange &LR = LIS->getRegUnit(*UI); @@ -2219,7 +2300,7 @@ class JoinVals { LiveRange &LR; /// (Main) register we work on. - const unsigned Reg; + const Register Reg; /// Reg (and therefore the values in this liverange) will end up as /// subregister SubIdx in the coalesced register. Either CP.DstIdx or @@ -2339,7 +2420,7 @@ class JoinVals { LaneBitmask computeWriteLanes(const MachineInstr *DefMI, bool &Redef) const; /// Find the ultimate value that VNI was copied from. - std::pair<const VNInfo*,unsigned> followCopyChain(const VNInfo *VNI) const; + std::pair<const VNInfo *, Register> followCopyChain(const VNInfo *VNI) const; bool valuesIdentical(VNInfo *Value0, VNInfo *Value1, const JoinVals &Other) const; @@ -2378,7 +2459,7 @@ class JoinVals { /// Return true if MI uses any of the given Lanes from Reg. /// This does not include partial redefinitions of Reg. - bool usesLanes(const MachineInstr &MI, unsigned, unsigned, LaneBitmask) const; + bool usesLanes(const MachineInstr &MI, Register, unsigned, LaneBitmask) const; /// Determine if ValNo is a copy of a value number in LR or Other.LR that will /// be pruned: @@ -2389,14 +2470,15 @@ class JoinVals { bool isPrunedValue(unsigned ValNo, JoinVals &Other); public: - JoinVals(LiveRange &LR, unsigned Reg, unsigned SubIdx, LaneBitmask LaneMask, - SmallVectorImpl<VNInfo*> &newVNInfo, const CoalescerPair &cp, + JoinVals(LiveRange &LR, Register Reg, unsigned SubIdx, LaneBitmask LaneMask, + SmallVectorImpl<VNInfo *> &newVNInfo, const CoalescerPair &cp, LiveIntervals *lis, const TargetRegisterInfo *TRI, bool SubRangeJoin, bool TrackSubRegLiveness) - : LR(LR), Reg(Reg), SubIdx(SubIdx), LaneMask(LaneMask), - SubRangeJoin(SubRangeJoin), TrackSubRegLiveness(TrackSubRegLiveness), - NewVNInfo(newVNInfo), CP(cp), LIS(lis), Indexes(LIS->getSlotIndexes()), - TRI(TRI), Assignments(LR.getNumValNums(), -1), Vals(LR.getNumValNums()) {} + : LR(LR), Reg(Reg), SubIdx(SubIdx), LaneMask(LaneMask), + SubRangeJoin(SubRangeJoin), TrackSubRegLiveness(TrackSubRegLiveness), + NewVNInfo(newVNInfo), CP(cp), LIS(lis), Indexes(LIS->getSlotIndexes()), + TRI(TRI), Assignments(LR.getNumValNums(), -1), + Vals(LR.getNumValNums()) {} /// Analyze defs in LR and compute a value mapping in NewVNInfo. /// Returns false if any conflicts were impossible to resolve. @@ -2462,9 +2544,9 @@ LaneBitmask JoinVals::computeWriteLanes(const MachineInstr *DefMI, bool &Redef) return L; } -std::pair<const VNInfo*, unsigned> JoinVals::followCopyChain( - const VNInfo *VNI) const { - unsigned TrackReg = Reg; +std::pair<const VNInfo *, Register> +JoinVals::followCopyChain(const VNInfo *VNI) const { + Register TrackReg = Reg; while (!VNI->isPHIDef()) { SlotIndex Def = VNI->def; @@ -2473,7 +2555,7 @@ std::pair<const VNInfo*, unsigned> JoinVals::followCopyChain( if (!MI->isFullCopy()) return std::make_pair(VNI, TrackReg); Register SrcReg = MI->getOperand(1).getReg(); - if (!Register::isVirtualRegister(SrcReg)) + if (!SrcReg.isVirtual()) return std::make_pair(VNI, TrackReg); const LiveInterval &LI = LIS->getInterval(SrcReg); @@ -2518,13 +2600,13 @@ std::pair<const VNInfo*, unsigned> JoinVals::followCopyChain( bool JoinVals::valuesIdentical(VNInfo *Value0, VNInfo *Value1, const JoinVals &Other) const { const VNInfo *Orig0; - unsigned Reg0; + Register Reg0; std::tie(Orig0, Reg0) = followCopyChain(Value0); if (Orig0 == Value1 && Reg0 == Other.Reg) return true; const VNInfo *Orig1; - unsigned Reg1; + Register Reg1; std::tie(Orig1, Reg1) = Other.followCopyChain(Value1); // If both values are undefined, and the source registers are the same // register, the values are identical. Filter out cases where only one @@ -2685,14 +2767,8 @@ JoinVals::analyzeValue(unsigned ValNo, JoinVals &Other) { return CR_Replace; // Check for simple erasable conflicts. - if (DefMI->isImplicitDef()) { - // We need the def for the subregister if there is nothing else live at the - // subrange at this point. - if (TrackSubRegLiveness - && (V.WriteLanes & (OtherV.ValidLanes | OtherV.WriteLanes)).none()) - return CR_Replace; + if (DefMI->isImplicitDef()) return CR_Erase; - } // Include the non-conflict where DefMI is a coalescable copy that kills // OtherVNI. We still want the copy erased and value numbers merged. @@ -2881,7 +2957,7 @@ taintExtent(unsigned ValNo, LaneBitmask TaintedLanes, JoinVals &Other, return true; } -bool JoinVals::usesLanes(const MachineInstr &MI, unsigned Reg, unsigned SubIdx, +bool JoinVals::usesLanes(const MachineInstr &MI, Register Reg, unsigned SubIdx, LaneBitmask Lanes) const { if (MI.isDebugInstr()) return false; @@ -3353,7 +3429,7 @@ void RegisterCoalescer::mergeSubRangeInto(LiveInterval &LI, bool RegisterCoalescer::isHighCostLiveInterval(LiveInterval &LI) { if (LI.valnos.size() < LargeIntervalSizeThreshold) return false; - auto &Counter = LargeLIVisitCounter[LI.reg]; + auto &Counter = LargeLIVisitCounter[LI.reg()]; if (Counter < LargeIntervalFreqThreshold) { Counter++; return false; @@ -3456,8 +3532,8 @@ bool RegisterCoalescer::joinVirtRegs(CoalescerPair &CP) { // Kill flags are going to be wrong if the live ranges were overlapping. // Eventually, we should simply clear all kill flags when computing live // ranges. They are reinserted after register allocation. - MRI->clearKillFlags(LHS.reg); - MRI->clearKillFlags(RHS.reg); + MRI->clearKillFlags(LHS.reg()); + MRI->clearKillFlags(RHS.reg()); if (!EndPoints.empty()) { // Recompute the parts of the live range we had to remove because of @@ -3525,20 +3601,20 @@ void RegisterCoalescer::checkMergingChangesDbgValues(CoalescerPair &CP, JoinVals &LHSVals, LiveRange &RHS, JoinVals &RHSVals) { - auto ScanForDstReg = [&](unsigned Reg) { + auto ScanForDstReg = [&](Register Reg) { checkMergingChangesDbgValuesImpl(Reg, RHS, LHS, LHSVals); }; - auto ScanForSrcReg = [&](unsigned Reg) { + auto ScanForSrcReg = [&](Register Reg) { checkMergingChangesDbgValuesImpl(Reg, LHS, RHS, RHSVals); }; // Scan for potentially unsound DBG_VALUEs: examine first the register number // Reg, and then any other vregs that may have been merged into it. - auto PerformScan = [this](unsigned Reg, std::function<void(unsigned)> Func) { + auto PerformScan = [this](Register Reg, std::function<void(Register)> Func) { Func(Reg); if (DbgMergedVRegNums.count(Reg)) - for (unsigned X : DbgMergedVRegNums[Reg]) + for (Register X : DbgMergedVRegNums[Reg]) Func(X); }; @@ -3547,7 +3623,7 @@ void RegisterCoalescer::checkMergingChangesDbgValues(CoalescerPair &CP, PerformScan(CP.getDstReg(), ScanForDstReg); } -void RegisterCoalescer::checkMergingChangesDbgValuesImpl(unsigned Reg, +void RegisterCoalescer::checkMergingChangesDbgValuesImpl(Register Reg, LiveRange &OtherLR, LiveRange &RegLR, JoinVals &RegVals) { @@ -3673,7 +3749,7 @@ static bool isLocalCopy(MachineInstr *Copy, const LiveIntervals *LIS) { } void RegisterCoalescer::lateLiveIntervalUpdate() { - for (unsigned reg : ToBeUpdated) { + for (Register reg : ToBeUpdated) { if (!LIS->hasInterval(reg)) continue; LiveInterval &LI = LIS->getInterval(reg); @@ -3707,7 +3783,7 @@ copyCoalesceWorkList(MutableArrayRef<MachineInstr*> CurrList) { /// Check if DstReg is a terminal node. /// I.e., it does not have any affinity other than \p Copy. -static bool isTerminalReg(unsigned DstReg, const MachineInstr &Copy, +static bool isTerminalReg(Register DstReg, const MachineInstr &Copy, const MachineRegisterInfo *MRI) { assert(Copy.isCopyLike()); // Check if the destination of this copy as any other affinity. @@ -3721,15 +3797,16 @@ bool RegisterCoalescer::applyTerminalRule(const MachineInstr &Copy) const { assert(Copy.isCopyLike()); if (!UseTerminalRule) return false; - unsigned DstReg, DstSubReg, SrcReg, SrcSubReg; + Register SrcReg, DstReg; + unsigned SrcSubReg = 0, DstSubReg = 0; if (!isMoveInstr(*TRI, &Copy, SrcReg, DstReg, SrcSubReg, DstSubReg)) return false; // Check if the destination of this copy has any other affinity. - if (Register::isPhysicalRegister(DstReg) || + if (DstReg.isPhysical() || // If SrcReg is a physical register, the copy won't be coalesced. // Ignoring it may have other side effect (like missing // rematerialization). So keep it. - Register::isPhysicalRegister(SrcReg) || !isTerminalReg(DstReg, Copy, MRI)) + SrcReg.isPhysical() || !isTerminalReg(DstReg, Copy, MRI)) return false; // DstReg is a terminal node. Check if it interferes with any other @@ -3745,7 +3822,8 @@ bool RegisterCoalescer::applyTerminalRule(const MachineInstr &Copy) const { // For now, just consider the copies that are in the same block. if (&MI == &Copy || !MI.isCopyLike() || MI.getParent() != OrigBB) continue; - unsigned OtherReg, OtherSubReg, OtherSrcReg, OtherSrcSubReg; + Register OtherSrcReg, OtherReg; + unsigned OtherSrcSubReg = 0, OtherSubReg = 0; if (!isMoveInstr(*TRI, &Copy, OtherSrcReg, OtherReg, OtherSrcSubReg, OtherSubReg)) return false; @@ -3930,7 +4008,7 @@ bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) { LLVM_DEBUG(dbgs() << "Trying to inflate " << InflateRegs.size() << " regs.\n"); for (unsigned i = 0, e = InflateRegs.size(); i != e; ++i) { - unsigned Reg = InflateRegs[i]; + Register Reg = InflateRegs[i]; if (MRI->reg_nodbg_empty(Reg)) continue; if (MRI->recomputeRegClass(Reg)) { |
