diff --git a/llvm/include/llvm/CodeGen/LiveIntervals.h b/llvm/include/llvm/CodeGen/LiveIntervals.h --- a/llvm/include/llvm/CodeGen/LiveIntervals.h +++ b/llvm/include/llvm/CodeGen/LiveIntervals.h @@ -292,9 +292,9 @@ /// Implement the dump method. void print(raw_ostream &O, const Module* = nullptr) const override; - /// If LI is confined to a single basic block, return a pointer to that - /// block. If LI is live in to or out of any block, return NULL. - MachineBasicBlock *intervalIsInOneMBB(const LiveInterval &LI) const; + /// If LR is confined to a single basic block, return a pointer to that + /// block. If LR is live in to or out of any block, return NULL. + MachineBasicBlock *intervalIsInOneMBB(const LiveRange &LR) const; /// Returns true if VNI is killed by any PHI-def values in LI. /// This may conservatively return true to avoid expensive computations. @@ -374,7 +374,7 @@ /// /// Returns false if \p LI doesn't cross any register mask instructions. In /// that case, the bit vector is not filled in. - bool checkRegMaskInterference(LiveInterval &LI, + bool checkRegMaskInterference(const LiveRange &LR, Register VirtReg, BitVector &UsableRegs); // Register unit functions. diff --git a/llvm/include/llvm/CodeGen/LiveRegMatrix.h b/llvm/include/llvm/CodeGen/LiveRegMatrix.h --- a/llvm/include/llvm/CodeGen/LiveRegMatrix.h +++ b/llvm/include/llvm/CodeGen/LiveRegMatrix.h @@ -113,6 +113,8 @@ /// the segment [Start, End). bool checkInterference(SlotIndex Start, SlotIndex End, MCRegister PhysReg); + bool checkInterferenceWithRange(const LiveRange& Range, MCRegister PhysReg); + /// Assign VirtReg to PhysReg. /// This will mark VirtReg's live range as occupied in the LiveRegMatrix and /// update VirtRegMap. The live range is expected to be available in PhysReg. @@ -134,9 +136,10 @@ // /// Check for regmask interference only. - /// Return true if VirtReg crosses a regmask operand that clobbers PhysReg. - /// If PhysReg is null, check if VirtReg crosses any regmask operands. - bool checkRegMaskInterference(LiveInterval &VirtReg, + /// Return true if live range LR crosses a regmask operand that clobbers + /// PhysReg. If PhysReg is NoRegister, check if LR crosses any regmask + /// operands. + bool checkRegMaskInterference(const LiveRange& LR, Register VirtReg, MCRegister PhysReg = MCRegister::NoRegister); /// Check for regunit interference only. diff --git a/llvm/lib/CodeGen/LiveIntervals.cpp b/llvm/lib/CodeGen/LiveIntervals.cpp --- a/llvm/lib/CodeGen/LiveIntervals.cpp +++ b/llvm/lib/CodeGen/LiveIntervals.cpp @@ -830,7 +830,7 @@ } MachineBasicBlock* -LiveIntervals::intervalIsInOneMBB(const LiveInterval &LI) const { +LiveIntervals::intervalIsInOneMBB(const LiveRange &LR) const { // A local live range must be fully contained inside the block, meaning it is // defined and killed at instructions, not at block boundaries. It is not // live in or out of any block. @@ -838,11 +838,11 @@ // It is technically possible to have a PHI-defined live range identical to a // single block, but we are going to return false in that case. - SlotIndex Start = LI.beginIndex(); + SlotIndex Start = LR.beginIndex(); if (Start.isBlock()) return nullptr; - SlotIndex Stop = LI.endIndex(); + SlotIndex Stop = LR.endIndex(); if (Stop.isBlock()) return nullptr; @@ -898,16 +898,16 @@ // Register mask functions //===----------------------------------------------------------------------===// -bool LiveIntervals::checkRegMaskInterference(LiveInterval &LI, +bool LiveIntervals::checkRegMaskInterference(const LiveRange &LR, Register VirtReg, BitVector &UsableRegs) { - if (LI.empty()) + if (LR.empty()) return false; - LiveInterval::iterator LiveI = LI.begin(), LiveE = LI.end(); + LiveRange::const_iterator LiveI = LR.begin(), LiveE = LR.end(); // Use a smaller arrays for local live ranges. ArrayRef Slots; ArrayRef Bits; - if (MachineBasicBlock *MBB = intervalIsInOneMBB(LI)) { + if (MachineBasicBlock *MBB = intervalIsInOneMBB(LR)) { Slots = getRegMaskSlotsInBlock(MBB->getNumber()); Bits = getRegMaskBitsInBlock(MBB->getNumber()); } else { @@ -915,12 +915,12 @@ Bits = getRegMaskBits(); } - // We are going to enumerate all the register mask slots contained in LI. + // We are going to enumerate all the register mask slots contained in LR. // Start with a binary search of RegMaskSlots to find a starting point. ArrayRef::iterator SlotI = llvm::lower_bound(Slots, LiveI->start); ArrayRef::iterator SlotE = Slots.end(); - // No slots in range, LI begins after the last call. + // No slots in range, LR begins after the last call. if (SlotI == SlotE) return false; @@ -929,7 +929,7 @@ assert(*SlotI >= LiveI->start); // Loop over all slots overlapping this segment. while (*SlotI < LiveI->end) { - // *SlotI overlaps LI. Collect mask bits. + // *SlotI overlaps LR. Collect mask bits. if (!Found) { // This is the first overlap. Initialize UsableRegs to all ones. UsableRegs.clear(); @@ -941,8 +941,8 @@ if (++SlotI == SlotE) return Found; } - // *SlotI is beyond the current LI segment. - LiveI = LI.advanceTo(LiveI, *SlotI); + // *SlotI is beyond the current LR segment. + LiveI = LR.advanceTo(LiveI, *SlotI); if (LiveI == LiveE) return Found; // Advance SlotI until it overlaps. diff --git a/llvm/lib/CodeGen/LiveRegMatrix.cpp b/llvm/lib/CodeGen/LiveRegMatrix.cpp --- a/llvm/lib/CodeGen/LiveRegMatrix.cpp +++ b/llvm/lib/CodeGen/LiveRegMatrix.cpp @@ -143,16 +143,18 @@ return false; } -bool LiveRegMatrix::checkRegMaskInterference(LiveInterval &VirtReg, +bool LiveRegMatrix::checkRegMaskInterference(const LiveRange &LR, + Register VirtReg, MCRegister PhysReg) { // Check if the cached information is valid. // The same BitVector can be reused for all PhysRegs. // We could cache multiple VirtRegs if it becomes necessary. - if (RegMaskVirtReg != VirtReg.reg() || RegMaskTag != UserTag) { - RegMaskVirtReg = VirtReg.reg(); + if (VirtReg == MCRegister::NoRegister || RegMaskVirtReg != VirtReg || + RegMaskTag != UserTag) { + RegMaskVirtReg = VirtReg; RegMaskTag = UserTag; RegMaskUsable.clear(); - LIS->checkRegMaskInterference(VirtReg, RegMaskUsable); + LIS->checkRegMaskInterference(LR, VirtReg, RegMaskUsable); } // The BitVector is indexed by PhysReg, not register unit. @@ -188,7 +190,7 @@ return IK_Free; // Regmask interference is the fastest check. - if (checkRegMaskInterference(VirtReg, PhysReg)) + if (checkRegMaskInterference(VirtReg, VirtReg.reg(), PhysReg)) return IK_RegMask; // Check for fixed interference. @@ -222,6 +224,26 @@ return false; } +bool LiveRegMatrix::checkInterferenceWithRange(const LiveRange& LR, MCRegister PhysReg) { + if (LR.empty()) + return false; + + // Regmask interference is the fastest check. + if (checkRegMaskInterference(LR, MCRegister::NoRegister, PhysReg)) + return true; + + for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) { + // Check for fixed interference. + const LiveRange &UnitRange = LIS->getRegUnit(*Units); + if (LR.overlaps(UnitRange)) + return true; + // Check for interference with current assignments. + if (query(LR, *Units).checkInterference()) + return true; + } + return false; +} + Register LiveRegMatrix::getOneVReg(unsigned PhysReg) const { LiveInterval *VRegInterval = nullptr; for (MCRegUnitIterator Unit(PhysReg, TRI); Unit.isValid(); ++Unit) { diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp b/llvm/lib/CodeGen/RegAllocGreedy.cpp --- a/llvm/lib/CodeGen/RegAllocGreedy.cpp +++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp @@ -2247,7 +2247,7 @@ // If VirtReg is live across any register mask operands, compute a list of // gaps with register masks. SmallVector RegMaskGaps; - if (Matrix->checkRegMaskInterference(VirtReg)) { + if (Matrix->checkRegMaskInterference(VirtReg, VirtReg.reg())) { // Get regmask slots for the whole block. ArrayRef RMS = LIS->getRegMaskSlotsInBlock(BI.MBB->getNumber()); LLVM_DEBUG(dbgs() << RMS.size() << " regmasks in block:"); @@ -2312,7 +2312,7 @@ calcGapWeights(PhysReg, GapWeight); // Remove any gaps with regmask clobbers. - if (Matrix->checkRegMaskInterference(VirtReg, PhysReg)) + if (Matrix->checkRegMaskInterference(VirtReg, VirtReg.reg(), PhysReg)) for (unsigned I = 0, E = RegMaskGaps.size(); I != E; ++I) GapWeight[RegMaskGaps[I]] = huge_valf; diff --git a/llvm/lib/CodeGen/RegAllocPBQP.cpp b/llvm/lib/CodeGen/RegAllocPBQP.cpp --- a/llvm/lib/CodeGen/RegAllocPBQP.cpp +++ b/llvm/lib/CodeGen/RegAllocPBQP.cpp @@ -618,7 +618,7 @@ // Record any overlaps with regmask operands. BitVector RegMaskOverlaps; - LIS.checkRegMaskInterference(VRegLI, RegMaskOverlaps); + LIS.checkRegMaskInterference(VRegLI, VRegLI.reg(), RegMaskOverlaps); // Compute an initial allowed set for the current vreg. std::vector VRegAllowed; diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp --- a/llvm/lib/CodeGen/RegisterCoalescer.cpp +++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp @@ -2143,7 +2143,7 @@ // We must also check for overlaps with regmask clobbers. BitVector RegMaskUsable; - if (LIS->checkRegMaskInterference(RHS, RegMaskUsable) && + if (LIS->checkRegMaskInterference(RHS, RHS.reg(), RegMaskUsable) && !RegMaskUsable.test(DstReg)) { LLVM_DEBUG(dbgs() << "\t\tRegMask interference\n"); return false;