diff --git a/llvm/include/llvm/CodeGen/LiveIntervalUnion.h b/llvm/include/llvm/CodeGen/LiveIntervalUnion.h --- a/llvm/include/llvm/CodeGen/LiveIntervalUnion.h +++ b/llvm/include/llvm/CodeGen/LiveIntervalUnion.h @@ -43,7 +43,7 @@ // A set of live virtual register segments that supports fast insertion, // intersection, and removal. // Mapping SlotIndex intervals to virtual register numbers. - using LiveSegments = IntervalMap; + using LiveSegments = IntervalMap; public: // SegmentIter can advance to the next segment ordered by starting position @@ -88,10 +88,10 @@ bool changedSince(unsigned tag) const { return tag != Tag; } // Add a live virtual register to this union and merge its segments. - void unify(LiveInterval &VirtReg, const LiveRange &Range); + void unify(const LiveInterval &VirtReg, const LiveRange &Range); // Remove a live virtual register's segments from this union. - void extract(LiveInterval &VirtReg, const LiveRange &Range); + void extract(const LiveInterval &VirtReg, const LiveRange &Range); // Remove all inserted virtual registers. void clear() { Segments.clear(); ++Tag; } @@ -105,7 +105,7 @@ #endif // Get any virtual register that is assign to this physical unit - LiveInterval *getOneVReg() const; + const LiveInterval *getOneVReg() const; /// Query interferences between a single live virtual register and a live /// interval union. @@ -114,7 +114,7 @@ const LiveRange *LR = nullptr; LiveRange::const_iterator LRI; ///< current position in LR ConstSegmentIter LiveUnionI; ///< current position in LiveUnion - SmallVector InterferingVRegs; + SmallVector InterferingVRegs; bool CheckedFirstInterference = false; bool SeenAllInterferences = false; unsigned Tag = 0; @@ -125,7 +125,7 @@ unsigned collectInterferingVRegs(unsigned MaxInterferingRegs); // Was this virtual register visited during collectInterferingVRegs? - bool isSeenInterference(LiveInterval *VirtReg) const; + bool isSeenInterference(const LiveInterval *VirtReg) const; public: Query() = default; @@ -159,7 +159,7 @@ bool checkInterference() { return collectInterferingVRegs(1); } // Vector generated by collectInterferingVRegs. - const SmallVectorImpl &interferingVRegs( + const SmallVectorImpl &interferingVRegs( unsigned MaxInterferingRegs = std::numeric_limits::max()) { if (!SeenAllInterferences || MaxInterferingRegs < InterferingVRegs.size()) collectInterferingVRegs(MaxInterferingRegs); 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 @@ -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 LiveInterval &LI, BitVector &UsableRegs); // Register unit functions. diff --git a/llvm/include/llvm/CodeGen/LiveRangeEdit.h b/llvm/include/llvm/CodeGen/LiveRangeEdit.h --- a/llvm/include/llvm/CodeGen/LiveRangeEdit.h +++ b/llvm/include/llvm/CodeGen/LiveRangeEdit.h @@ -66,7 +66,7 @@ }; private: - LiveInterval *Parent; + const LiveInterval *const Parent; SmallVectorImpl &NewRegs; MachineRegisterInfo &MRI; LiveIntervals &LIS; @@ -129,7 +129,7 @@ /// be done. This could be the case if called before Regalloc. /// @param deadRemats The collection of all the instructions defining an /// original reg and are dead after remat. - LiveRangeEdit(LiveInterval *parent, SmallVectorImpl &newRegs, + LiveRangeEdit(const LiveInterval *parent, SmallVectorImpl &newRegs, MachineFunction &MF, LiveIntervals &lis, VirtRegMap *vrm, Delegate *delegate = nullptr, SmallPtrSet *deadRemats = nullptr) @@ -141,7 +141,7 @@ ~LiveRangeEdit() override { MRI.resetDelegate(this); } - LiveInterval &getParent() const { + const LiveInterval &getParent() const { assert(Parent && "No parent LiveInterval"); return *Parent; } @@ -193,11 +193,11 @@ /// Remat - Information needed to rematerialize at a specific location. struct Remat { - VNInfo *ParentVNI; // parent_'s value at the remat location. + const VNInfo *const ParentVNI; // parent_'s value at the remat location. MachineInstr *OrigMI = nullptr; // Instruction defining OrigVNI. It contains // the real expr for remat. - explicit Remat(VNInfo *ParentVNI) : ParentVNI(ParentVNI) {} + explicit Remat(const VNInfo *ParentVNI) : ParentVNI(ParentVNI) {} }; /// allUsesAvailableAt - Return true if all registers used by OrigMI at 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 @@ -104,7 +104,8 @@ /// If this function returns IK_Free, it is legal to assign(VirtReg, PhysReg). /// When there is more than one kind of interference, the InterferenceKind /// with the highest enum value is returned. - InterferenceKind checkInterference(LiveInterval &VirtReg, MCRegister PhysReg); + InterferenceKind checkInterference(const LiveInterval &VirtReg, + MCRegister PhysReg); /// Check for interference in the segment [Start, End) that may prevent /// assignment to PhysReg. If this function returns true, there is @@ -116,12 +117,12 @@ /// 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. - void assign(LiveInterval &VirtReg, MCRegister PhysReg); + void assign(const LiveInterval &VirtReg, MCRegister PhysReg); /// Unassign VirtReg from its PhysReg. /// Assuming that VirtReg was previously assigned to a PhysReg, this undoes /// the assignment and updates VirtRegMap accordingly. - void unassign(LiveInterval &VirtReg); + void unassign(const LiveInterval &VirtReg); /// Returns true if the given \p PhysReg has any live intervals assigned. bool isPhysRegUsed(MCRegister PhysReg) const; @@ -136,13 +137,14 @@ /// 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, + bool checkRegMaskInterference(const LiveInterval &VirtReg, MCRegister PhysReg = MCRegister::NoRegister); /// Check for regunit interference only. /// Return true if VirtReg overlaps a fixed assignment of one of PhysRegs's /// register units. - bool checkRegUnitInterference(LiveInterval &VirtReg, MCRegister PhysReg); + bool checkRegUnitInterference(const LiveInterval &VirtReg, + MCRegister PhysReg); /// Query a line of the assigned virtual register matrix directly. /// Use MCRegUnitIterator to enumerate all regunits in the desired PhysReg. diff --git a/llvm/lib/CodeGen/LiveIntervalUnion.cpp b/llvm/lib/CodeGen/LiveIntervalUnion.cpp --- a/llvm/lib/CodeGen/LiveIntervalUnion.cpp +++ b/llvm/lib/CodeGen/LiveIntervalUnion.cpp @@ -26,7 +26,8 @@ #define DEBUG_TYPE "regalloc" // Merge a LiveInterval's segments. Guarantee no overlaps. -void LiveIntervalUnion::unify(LiveInterval &VirtReg, const LiveRange &Range) { +void LiveIntervalUnion::unify(const LiveInterval &VirtReg, + const LiveRange &Range) { if (Range.empty()) return; ++Tag; @@ -53,7 +54,8 @@ } // Remove a live virtual register's segments from this union. -void LiveIntervalUnion::extract(LiveInterval &VirtReg, const LiveRange &Range) { +void LiveIntervalUnion::extract(const LiveInterval &VirtReg, + const LiveRange &Range) { if (Range.empty()) return; ++Tag; @@ -99,7 +101,7 @@ } #endif //!NDEBUG -LiveInterval *LiveIntervalUnion::getOneVReg() const { +const LiveInterval *LiveIntervalUnion::getOneVReg() const { if (empty()) return nullptr; for (LiveSegments::const_iterator SI = Segments.begin(); SI.valid(); ++SI) { @@ -111,7 +113,8 @@ // Scan the vector of interfering virtual registers in this union. Assume it's // quite small. -bool LiveIntervalUnion::Query::isSeenInterference(LiveInterval *VirtReg) const { +bool LiveIntervalUnion::Query::isSeenInterference( + const LiveInterval *VirtReg) const { return is_contained(InterferingVRegs, VirtReg); } @@ -147,14 +150,14 @@ } LiveRange::const_iterator LREnd = LR->end(); - LiveInterval *RecentReg = nullptr; + const LiveInterval *RecentReg = nullptr; while (LiveUnionI.valid()) { assert(LRI != LREnd && "Reached end of LR"); // Check for overlapping interference. while (LRI->start < LiveUnionI.stop() && LRI->end > LiveUnionI.start()) { // This is an overlap, record the interfering register. - LiveInterval *VReg = LiveUnionI.value(); + const LiveInterval *VReg = LiveUnionI.value(); if (VReg != RecentReg && !isSeenInterference(VReg)) { RecentReg = VReg; InterferingVRegs.push_back(VReg); 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 @@ -913,11 +913,11 @@ return false; } -bool LiveIntervals::checkRegMaskInterference(LiveInterval &LI, +bool LiveIntervals::checkRegMaskInterference(const LiveInterval &LI, BitVector &UsableRegs) { if (LI.empty()) return false; - LiveInterval::iterator LiveI = LI.begin(), LiveE = LI.end(); + LiveInterval::const_iterator LiveI = LI.begin(), LiveE = LI.end(); // Use a smaller arrays for local live ranges. ArrayRef Slots; 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 @@ -78,13 +78,13 @@ template static bool foreachUnit(const TargetRegisterInfo *TRI, - LiveInterval &VRegInterval, MCRegister PhysReg, + const LiveInterval &VRegInterval, MCRegister PhysReg, Callable Func) { if (VRegInterval.hasSubRanges()) { for (MCRegUnitMaskIterator Units(PhysReg, TRI); Units.isValid(); ++Units) { unsigned Unit = (*Units).first; LaneBitmask Mask = (*Units).second; - for (LiveInterval::SubRange &S : VRegInterval.subranges()) { + for (const LiveInterval::SubRange &S : VRegInterval.subranges()) { if ((S.LaneMask & Mask).any()) { if (Func(Unit, S)) return true; @@ -101,7 +101,7 @@ return false; } -void LiveRegMatrix::assign(LiveInterval &VirtReg, MCRegister PhysReg) { +void LiveRegMatrix::assign(const LiveInterval &VirtReg, MCRegister PhysReg) { LLVM_DEBUG(dbgs() << "assigning " << printReg(VirtReg.reg(), TRI) << " to " << printReg(PhysReg, TRI) << ':'); assert(!VRM->hasPhys(VirtReg.reg()) && "Duplicate VirtReg assignment"); @@ -118,7 +118,7 @@ LLVM_DEBUG(dbgs() << '\n'); } -void LiveRegMatrix::unassign(LiveInterval &VirtReg) { +void LiveRegMatrix::unassign(const LiveInterval &VirtReg) { Register PhysReg = VRM->getPhys(VirtReg.reg()); LLVM_DEBUG(dbgs() << "unassigning " << printReg(VirtReg.reg(), TRI) << " from " << printReg(PhysReg, TRI) << ':'); @@ -143,7 +143,7 @@ return false; } -bool LiveRegMatrix::checkRegMaskInterference(LiveInterval &VirtReg, +bool LiveRegMatrix::checkRegMaskInterference(const LiveInterval &VirtReg, MCRegister PhysReg) { // Check if the cached information is valid. // The same BitVector can be reused for all PhysRegs. @@ -161,7 +161,7 @@ return !RegMaskUsable.empty() && (!PhysReg || !RegMaskUsable.test(PhysReg)); } -bool LiveRegMatrix::checkRegUnitInterference(LiveInterval &VirtReg, +bool LiveRegMatrix::checkRegUnitInterference(const LiveInterval &VirtReg, MCRegister PhysReg) { if (VirtReg.empty()) return false; @@ -183,7 +183,8 @@ } LiveRegMatrix::InterferenceKind -LiveRegMatrix::checkInterference(LiveInterval &VirtReg, MCRegister PhysReg) { +LiveRegMatrix::checkInterference(const LiveInterval &VirtReg, + MCRegister PhysReg) { if (VirtReg.empty()) return IK_Free; @@ -237,7 +238,7 @@ } Register LiveRegMatrix::getOneVReg(unsigned PhysReg) const { - LiveInterval *VRegInterval = nullptr; + const LiveInterval *VRegInterval = nullptr; for (MCRegUnitIterator Unit(PhysReg, TRI); Unit.isValid(); ++Unit) { if ((VRegInterval = Matrix[*Unit].getOneVReg())) return VRegInterval->reg(); diff --git a/llvm/lib/CodeGen/MLRegallocEvictAdvisor.cpp b/llvm/lib/CodeGen/MLRegallocEvictAdvisor.cpp --- a/llvm/lib/CodeGen/MLRegallocEvictAdvisor.cpp +++ b/llvm/lib/CodeGen/MLRegallocEvictAdvisor.cpp @@ -259,14 +259,16 @@ /// if we're just capturing the log of the default advisor, it needs to call /// the latter instead, so we need to pass all the necessary parameters for /// it. In the development case, it will also log. - virtual int64_t tryFindEvictionCandidatePosition( - LiveInterval &VirtReg, const AllocationOrder &Order, unsigned OrderLimit, - uint8_t CostPerUseLimit, const SmallVirtRegSet &FixedRegisters) const; + virtual int64_t + tryFindEvictionCandidatePosition(const LiveInterval &VirtReg, + const AllocationOrder &Order, + unsigned OrderLimit, uint8_t CostPerUseLimit, + const SmallVirtRegSet &FixedRegisters) const; /// Load the features of the given VirtReg (allocated or not) at column Pos, /// but if that can't be evicted, return false instead. bool - loadInterferenceFeatures(LiveInterval &VirtReg, MCRegister PhysReg, + loadInterferenceFeatures(const LiveInterval &VirtReg, MCRegister PhysReg, bool IsHint, const SmallVirtRegSet &FixedRegisters, std::array &Largest, size_t Pos) const; @@ -275,18 +277,18 @@ static float getInitialQueueSize(const MachineFunction &MF); MCRegister tryFindEvictionCandidate( - LiveInterval &VirtReg, const AllocationOrder &Order, + const LiveInterval &VirtReg, const AllocationOrder &Order, uint8_t CostPerUseLimit, const SmallVirtRegSet &FixedRegisters) const override; - void extractFeatures(const SmallVectorImpl &Intervals, + void extractFeatures(const SmallVectorImpl &Intervals, std::array &Largest, size_t Pos, int64_t IsHint, int64_t LocalIntfsCount, float NrUrgent) const; // Point-in-time: we didn't learn this, so we always delegate to the default. bool canEvictHintInterference( - LiveInterval &VirtReg, MCRegister PhysReg, + const LiveInterval &VirtReg, MCRegister PhysReg, const SmallVirtRegSet &FixedRegisters) const override { return getDefaultAdvisor().canEvictHintInterference(VirtReg, PhysReg, FixedRegisters); @@ -390,8 +392,8 @@ private: int64_t tryFindEvictionCandidatePosition( - LiveInterval &VirtReg, const AllocationOrder &Order, unsigned OrderLimit, - uint8_t CostPerUseLimit, + const LiveInterval &VirtReg, const AllocationOrder &Order, + unsigned OrderLimit, uint8_t CostPerUseLimit, const SmallVirtRegSet &FixedRegisters) const override; Logger *const Log; @@ -516,7 +518,7 @@ } int64_t MLEvictAdvisor::tryFindEvictionCandidatePosition( - LiveInterval &, const AllocationOrder &, unsigned, uint8_t, + const LiveInterval &, const AllocationOrder &, unsigned, uint8_t, const SmallVirtRegSet &) const { int64_t Ret = Runner->evaluate(); assert(Ret >= 0); @@ -525,7 +527,7 @@ } bool MLEvictAdvisor::loadInterferenceFeatures( - LiveInterval &VirtReg, MCRegister PhysReg, bool IsHint, + const LiveInterval &VirtReg, MCRegister PhysReg, bool IsHint, const SmallVirtRegSet &FixedRegisters, FeaturesListNormalizer &Largest, size_t Pos) const { // It is only possible to evict virtual register interference. @@ -541,7 +543,7 @@ // The cascade tracking is the same as in the default advisor unsigned Cascade = RA.getExtraInfo().getCascadeOrCurrentNext(VirtReg.reg()); - SmallVector InterferingIntervals; + SmallVector InterferingIntervals; for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) { LiveIntervalUnion::Query &Q = Matrix->query(VirtReg, *Units); // Different from the default heuristic, we don't make any assumptions about @@ -552,7 +554,7 @@ if (IFIntervals.size() >= EvictInterferenceCutoff) return false; InterferingIntervals.append(IFIntervals.begin(), IFIntervals.end()); - for (LiveInterval *Intf : reverse(IFIntervals)) { + for (const LiveInterval *Intf : reverse(IFIntervals)) { assert(Register::isVirtualRegister(Intf->reg()) && "Only expecting virtual register interference from query"); // This is the same set of legality checks as in the default case: don't @@ -591,7 +593,7 @@ } MCRegister MLEvictAdvisor::tryFindEvictionCandidate( - LiveInterval &VirtReg, const AllocationOrder &Order, + const LiveInterval &VirtReg, const AllocationOrder &Order, uint8_t CostPerUseLimit, const SmallVirtRegSet &FixedRegisters) const { auto MaybeOrderLimit = getOrderLimit(VirtReg, Order, CostPerUseLimit); if (!MaybeOrderLimit) @@ -656,7 +658,7 @@ // decision making process. Regs[CandidateVirtRegPos].second = !MustFindEviction; if (!MustFindEviction) - extractFeatures(SmallVector(1, &VirtReg), Largest, + extractFeatures(SmallVector(1, &VirtReg), Largest, CandidateVirtRegPos, /*IsHint*/ 0, /*LocalIntfsCount*/ 0, /*NrUrgent*/ 0.0); assert(InitialQSize > 0.0 && "We couldn't have gotten here if we had " @@ -737,7 +739,7 @@ // Overall, this currently mimics what we do for weight calculation, but instead // of accummulating the various features, we keep them separate. void MLEvictAdvisor::extractFeatures( - const SmallVectorImpl &Intervals, + const SmallVectorImpl &Intervals, std::array &Largest, size_t Pos, int64_t IsHint, int64_t LocalIntfsCount, float NrUrgent) const { int64_t NrDefsAndUses = 0; @@ -835,8 +837,9 @@ } int64_t DevelopmentModeEvictAdvisor::tryFindEvictionCandidatePosition( - LiveInterval &VirtReg, const AllocationOrder &Order, unsigned OrderLimit, - uint8_t CostPerUseLimit, const SmallVirtRegSet &FixedRegisters) const { + const LiveInterval &VirtReg, const AllocationOrder &Order, + unsigned OrderLimit, uint8_t CostPerUseLimit, + const SmallVirtRegSet &FixedRegisters) const { int64_t Ret = 0; if (isa(getRunner())) { Ret = MLEvictAdvisor::tryFindEvictionCandidatePosition( diff --git a/llvm/lib/CodeGen/RegAllocBase.h b/llvm/lib/CodeGen/RegAllocBase.h --- a/llvm/lib/CodeGen/RegAllocBase.h +++ b/llvm/lib/CodeGen/RegAllocBase.h @@ -96,19 +96,19 @@ virtual Spiller &spiller() = 0; /// enqueue - Add VirtReg to the priority queue of unassigned registers. - virtual void enqueueImpl(LiveInterval *LI) = 0; + virtual void enqueueImpl(const LiveInterval *LI) = 0; /// enqueue - Add VirtReg to the priority queue of unassigned registers. - void enqueue(LiveInterval *LI); + void enqueue(const LiveInterval *LI); /// dequeue - Return the next unassigned register, or NULL. - virtual LiveInterval *dequeue() = 0; + virtual const LiveInterval *dequeue() = 0; // A RegAlloc pass should override this to provide the allocation heuristics. // Each call must guarantee forward progess by returning an available PhysReg // or new set of split live virtual registers. It is up to the splitter to // converge quickly toward fully spilled live ranges. - virtual MCRegister selectOrSplit(LiveInterval &VirtReg, + virtual MCRegister selectOrSplit(const LiveInterval &VirtReg, SmallVectorImpl &splitLVRs) = 0; // Use this group name for NamedRegionTimer. @@ -116,7 +116,7 @@ static const char TimerGroupDescription[]; /// Method called when the allocator is about to remove a LiveInterval. - virtual void aboutToRemoveInterval(LiveInterval &LI) {} + virtual void aboutToRemoveInterval(const LiveInterval &LI) {} public: /// VerifyEnabled - True when -verify-regalloc is given. diff --git a/llvm/lib/CodeGen/RegAllocBase.cpp b/llvm/lib/CodeGen/RegAllocBase.cpp --- a/llvm/lib/CodeGen/RegAllocBase.cpp +++ b/llvm/lib/CodeGen/RegAllocBase.cpp @@ -85,7 +85,7 @@ seedLiveRegs(); // Continue assigning vregs one at a time to available physical registers. - while (LiveInterval *VirtReg = dequeue()) { + while (const LiveInterval *VirtReg = dequeue()) { assert(!VRM->hasPhys(VirtReg->reg()) && "Register already assigned"); // Unused registers can appear when the spiller coalesces snippets. @@ -176,7 +176,7 @@ DeadRemats.clear(); } -void RegAllocBase::enqueue(LiveInterval *LI) { +void RegAllocBase::enqueue(const LiveInterval *LI) { const Register Reg = LI->reg(); assert(Reg.isVirtual() && "Can only enqueue virtual registers"); diff --git a/llvm/lib/CodeGen/RegAllocBasic.cpp b/llvm/lib/CodeGen/RegAllocBasic.cpp --- a/llvm/lib/CodeGen/RegAllocBasic.cpp +++ b/llvm/lib/CodeGen/RegAllocBasic.cpp @@ -45,7 +45,7 @@ namespace { struct CompSpillWeight { - bool operator()(LiveInterval *A, LiveInterval *B) const { + bool operator()(const LiveInterval *A, const LiveInterval *B) const { return A->weight() < B->weight(); } }; @@ -65,8 +65,9 @@ // state std::unique_ptr SpillerInstance; - std::priority_queue, - CompSpillWeight> Queue; + std::priority_queue, + CompSpillWeight> + Queue; // Scratch space. Allocated here to avoid repeated malloc calls in // selectOrSplit(). @@ -88,19 +89,17 @@ Spiller &spiller() override { return *SpillerInstance; } - void enqueueImpl(LiveInterval *LI) override { - Queue.push(LI); - } + void enqueueImpl(const LiveInterval *LI) override { Queue.push(LI); } - LiveInterval *dequeue() override { + const LiveInterval *dequeue() override { if (Queue.empty()) return nullptr; - LiveInterval *LI = Queue.top(); + const LiveInterval *LI = Queue.top(); Queue.pop(); return LI; } - MCRegister selectOrSplit(LiveInterval &VirtReg, + MCRegister selectOrSplit(const LiveInterval &VirtReg, SmallVectorImpl &SplitVRegs) override; /// Perform register allocation. @@ -119,7 +118,7 @@ // Helper for spilling all live virtual registers currently unified under preg // that interfere with the most recently queried lvr. Return true if spilling // was successful, and append any new spilled/split intervals to splitLVRs. - bool spillInterferences(LiveInterval &VirtReg, MCRegister PhysReg, + bool spillInterferences(const LiveInterval &VirtReg, MCRegister PhysReg, SmallVectorImpl &SplitVRegs); static char ID; @@ -208,16 +207,17 @@ // Spill or split all live virtual registers currently unified under PhysReg // that interfere with VirtReg. The newly spilled or split live intervals are // returned by appending them to SplitVRegs. -bool RABasic::spillInterferences(LiveInterval &VirtReg, MCRegister PhysReg, +bool RABasic::spillInterferences(const LiveInterval &VirtReg, + MCRegister PhysReg, SmallVectorImpl &SplitVRegs) { // Record each interference and determine if all are spillable before mutating // either the union or live intervals. - SmallVector Intfs; + SmallVector Intfs; // Collect interferences assigned to any alias of the physical register. for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) { LiveIntervalUnion::Query &Q = Matrix->query(VirtReg, *Units); - for (auto *Intf : reverse(Q.interferingVRegs())) { + for (const auto *Intf : reverse(Q.interferingVRegs())) { if (!Intf->isSpillable() || Intf->weight() > VirtReg.weight()) return false; Intfs.push_back(Intf); @@ -229,7 +229,7 @@ // Spill each interfering vreg allocated to PhysReg or an alias. for (unsigned i = 0, e = Intfs.size(); i != e; ++i) { - LiveInterval &Spill = *Intfs[i]; + const LiveInterval &Spill = *Intfs[i]; // Skip duplicates. if (!VRM->hasPhys(Spill.reg())) @@ -258,7 +258,7 @@ // |vregs| * |machineregs|. And since the number of interference tests is // minimal, there is no value in caching them outside the scope of // selectOrSplit(). -MCRegister RABasic::selectOrSplit(LiveInterval &VirtReg, +MCRegister RABasic::selectOrSplit(const LiveInterval &VirtReg, SmallVectorImpl &SplitVRegs) { // Populate a list of physical register spill candidates. SmallVector PhysRegSpillCands; diff --git a/llvm/lib/CodeGen/RegAllocEvictionAdvisor.h b/llvm/lib/CodeGen/RegAllocEvictionAdvisor.h --- a/llvm/lib/CodeGen/RegAllocEvictionAdvisor.h +++ b/llvm/lib/CodeGen/RegAllocEvictionAdvisor.h @@ -99,15 +99,14 @@ /// Find a physical register that can be freed by evicting the FixedRegisters, /// or return NoRegister. The eviction decision is assumed to be correct (i.e. /// no fixed live ranges are evicted) and profitable. - virtual MCRegister - tryFindEvictionCandidate(LiveInterval &VirtReg, const AllocationOrder &Order, - uint8_t CostPerUseLimit, - const SmallVirtRegSet &FixedRegisters) const = 0; + virtual MCRegister tryFindEvictionCandidate( + const LiveInterval &VirtReg, const AllocationOrder &Order, + uint8_t CostPerUseLimit, const SmallVirtRegSet &FixedRegisters) const = 0; /// Find out if we can evict the live ranges occupying the given PhysReg, /// which is a hint (preferred register) for VirtReg. virtual bool - canEvictHintInterference(LiveInterval &VirtReg, MCRegister PhysReg, + canEvictHintInterference(const LiveInterval &VirtReg, MCRegister PhysReg, const SmallVirtRegSet &FixedRegisters) const = 0; /// Returns true if the given \p PhysReg is a callee saved register and has @@ -117,7 +116,7 @@ protected: RegAllocEvictionAdvisor(MachineFunction &MF, const RAGreedy &RA); - Register canReassign(LiveInterval &VirtReg, Register PrevReg) const; + Register canReassign(const LiveInterval &VirtReg, Register PrevReg) const; // Get the upper limit of elements in the given Order we need to analize. // TODO: is this heuristic, we could consider learning it. @@ -204,15 +203,16 @@ : RegAllocEvictionAdvisor(MF, RA) {} private: - MCRegister tryFindEvictionCandidate(LiveInterval &, const AllocationOrder &, - uint8_t, + MCRegister tryFindEvictionCandidate(const LiveInterval &, + const AllocationOrder &, uint8_t, const SmallVirtRegSet &) const override; - bool canEvictHintInterference(LiveInterval &, MCRegister, + bool canEvictHintInterference(const LiveInterval &, MCRegister, const SmallVirtRegSet &) const override; - bool canEvictInterferenceBasedOnCost(LiveInterval &, MCRegister, bool, + bool canEvictInterferenceBasedOnCost(const LiveInterval &, MCRegister, bool, EvictionCost &, const SmallVirtRegSet &) const; - bool shouldEvict(LiveInterval &A, bool, LiveInterval &B, bool) const; + bool shouldEvict(const LiveInterval &A, bool, const LiveInterval &B, + bool) const; }; } // namespace llvm diff --git a/llvm/lib/CodeGen/RegAllocEvictionAdvisor.cpp b/llvm/lib/CodeGen/RegAllocEvictionAdvisor.cpp --- a/llvm/lib/CodeGen/RegAllocEvictionAdvisor.cpp +++ b/llvm/lib/CodeGen/RegAllocEvictionAdvisor.cpp @@ -144,8 +144,8 @@ /// register. /// @param B The live range to be evicted. /// @param BreaksHint True when B is already assigned to its preferred register. -bool DefaultEvictionAdvisor::shouldEvict(LiveInterval &A, bool IsHint, - LiveInterval &B, +bool DefaultEvictionAdvisor::shouldEvict(const LiveInterval &A, bool IsHint, + const LiveInterval &B, bool BreaksHint) const { bool CanSplit = RA.getExtraInfo().getStage(B) < RS_Spill; @@ -164,7 +164,7 @@ /// canEvictHintInterference - return true if the interference for VirtReg /// on the PhysReg, which is VirtReg's hint, can be evicted in favor of VirtReg. bool DefaultEvictionAdvisor::canEvictHintInterference( - LiveInterval &VirtReg, MCRegister PhysReg, + const LiveInterval &VirtReg, MCRegister PhysReg, const SmallVirtRegSet &FixedRegisters) const { EvictionCost MaxCost; MaxCost.setBrokenHints(1); @@ -182,7 +182,7 @@ /// when returning true. /// @returns True when interference can be evicted cheaper than MaxCost. bool DefaultEvictionAdvisor::canEvictInterferenceBasedOnCost( - LiveInterval &VirtReg, MCRegister PhysReg, bool IsHint, + const LiveInterval &VirtReg, MCRegister PhysReg, bool IsHint, EvictionCost &MaxCost, const SmallVirtRegSet &FixedRegisters) const { // It is only possible to evict virtual register interference. if (Matrix->checkInterference(VirtReg, PhysReg) > LiveRegMatrix::IK_VirtReg) @@ -208,7 +208,7 @@ return false; // Check if any interfering live range is heavier than MaxWeight. - for (LiveInterval *Intf : reverse(Interferences)) { + for (const LiveInterval *Intf : reverse(Interferences)) { assert(Register::isVirtualRegister(Intf->reg()) && "Only expecting virtual register interference from query"); @@ -269,7 +269,7 @@ } MCRegister DefaultEvictionAdvisor::tryFindEvictionCandidate( - LiveInterval &VirtReg, const AllocationOrder &Order, + const LiveInterval &VirtReg, const AllocationOrder &Order, uint8_t CostPerUseLimit, const SmallVirtRegSet &FixedRegisters) const { // Keep track of the cheapest interference seen so far. EvictionCost BestCost; diff --git a/llvm/lib/CodeGen/RegAllocGreedy.h b/llvm/lib/CodeGen/RegAllocGreedy.h --- a/llvm/lib/CodeGen/RegAllocGreedy.h +++ b/llvm/lib/CodeGen/RegAllocGreedy.h @@ -162,7 +162,7 @@ private: // Convenient shortcuts. using PQueue = std::priority_queue>; - using SmallLISet = SmallPtrSet; + using SmallLISet = SmallPtrSet; // context MachineFunction *MF; @@ -325,7 +325,7 @@ bool EnableAdvancedRASplitCost; /// Set of broken hints that may be reconciled later because of eviction. - SmallSetVector SetOfBrokenHints; + SmallSetVector SetOfBrokenHints; /// The register cost values. This list will be recreated for each Machine /// Function @@ -341,11 +341,11 @@ void getAnalysisUsage(AnalysisUsage &AU) const override; void releaseMemory() override; Spiller &spiller() override { return *SpillerInstance; } - void enqueueImpl(LiveInterval *LI) override; - LiveInterval *dequeue() override; - MCRegister selectOrSplit(LiveInterval &, + void enqueueImpl(const LiveInterval *LI) override; + const LiveInterval *dequeue() override; + MCRegister selectOrSplit(const LiveInterval &, SmallVectorImpl &) override; - void aboutToRemoveInterval(LiveInterval &) override; + void aboutToRemoveInterval(const LiveInterval &) override; /// Perform register allocation. bool runOnMachineFunction(MachineFunction &mf) override; @@ -363,14 +363,15 @@ static char ID; private: - MCRegister selectOrSplitImpl(LiveInterval &, SmallVectorImpl &, - SmallVirtRegSet &, unsigned = 0); + MCRegister selectOrSplitImpl(const LiveInterval &, + SmallVectorImpl &, SmallVirtRegSet &, + unsigned = 0); bool LRE_CanEraseVirtReg(Register) override; void LRE_WillShrinkVirtReg(Register) override; void LRE_DidCloneVirtReg(Register, Register) override; - void enqueue(PQueue &CurQueue, LiveInterval *LI); - LiveInterval *dequeue(PQueue &CurQueue); + void enqueue(PQueue &CurQueue, const LiveInterval *LI); + const LiveInterval *dequeue(PQueue &CurQueue); BlockFrequency calcSpillCost(); bool addSplitConstraints(InterferenceCache::Cursor, BlockFrequency &); @@ -395,49 +396,50 @@ const LiveInterval &VirtReg, SlotIndex Start, SlotIndex End, float *BestEvictWeight) const; - void evictInterference(LiveInterval &, MCRegister, + void evictInterference(const LiveInterval &, MCRegister, SmallVectorImpl &); - bool mayRecolorAllInterferences(MCRegister PhysReg, LiveInterval &VirtReg, + bool mayRecolorAllInterferences(MCRegister PhysReg, + const LiveInterval &VirtReg, SmallLISet &RecoloringCandidates, const SmallVirtRegSet &FixedRegisters); - MCRegister tryAssign(LiveInterval &, AllocationOrder &, + MCRegister tryAssign(const LiveInterval &, AllocationOrder &, SmallVectorImpl &, const SmallVirtRegSet &); - MCRegister tryEvict(LiveInterval &, AllocationOrder &, + MCRegister tryEvict(const LiveInterval &, AllocationOrder &, SmallVectorImpl &, uint8_t, const SmallVirtRegSet &); - MCRegister tryRegionSplit(LiveInterval &, AllocationOrder &, + MCRegister tryRegionSplit(const LiveInterval &, AllocationOrder &, SmallVectorImpl &); /// Calculate cost of region splitting. - unsigned calculateRegionSplitCost(LiveInterval &VirtReg, + unsigned calculateRegionSplitCost(const LiveInterval &VirtReg, AllocationOrder &Order, BlockFrequency &BestCost, unsigned &NumCands, bool IgnoreCSR, bool *CanCauseEvictionChain = nullptr); /// Perform region splitting. - unsigned doRegionSplit(LiveInterval &VirtReg, unsigned BestCand, + unsigned doRegionSplit(const LiveInterval &VirtReg, unsigned BestCand, bool HasCompact, SmallVectorImpl &NewVRegs); /// Check other options before using a callee-saved register for the first /// time. - MCRegister tryAssignCSRFirstTime(LiveInterval &VirtReg, + MCRegister tryAssignCSRFirstTime(const LiveInterval &VirtReg, AllocationOrder &Order, MCRegister PhysReg, uint8_t &CostPerUseLimit, SmallVectorImpl &NewVRegs); void initializeCSRCost(); - unsigned tryBlockSplit(LiveInterval &, AllocationOrder &, + unsigned tryBlockSplit(const LiveInterval &, AllocationOrder &, SmallVectorImpl &); - unsigned tryInstructionSplit(LiveInterval &, AllocationOrder &, + unsigned tryInstructionSplit(const LiveInterval &, AllocationOrder &, SmallVectorImpl &); - unsigned tryLocalSplit(LiveInterval &, AllocationOrder &, + unsigned tryLocalSplit(const LiveInterval &, AllocationOrder &, SmallVectorImpl &); - unsigned trySplit(LiveInterval &, AllocationOrder &, + unsigned trySplit(const LiveInterval &, AllocationOrder &, SmallVectorImpl &, const SmallVirtRegSet &); - unsigned tryLastChanceRecoloring(LiveInterval &, AllocationOrder &, + unsigned tryLastChanceRecoloring(const LiveInterval &, AllocationOrder &, SmallVectorImpl &, SmallVirtRegSet &, unsigned); bool tryRecoloringCandidates(PQueue &, SmallVectorImpl &, SmallVirtRegSet &, unsigned); - void tryHintRecoloring(LiveInterval &); + void tryHintRecoloring(const LiveInterval &); void tryHintsRecoloring(); /// Model the information carried by one end of a copy. 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 @@ -277,9 +277,9 @@ GlobalCand.clear(); } -void RAGreedy::enqueueImpl(LiveInterval *LI) { enqueue(Queue, LI); } +void RAGreedy::enqueueImpl(const LiveInterval *LI) { enqueue(Queue, LI); } -void RAGreedy::enqueue(PQueue &CurQueue, LiveInterval *LI) { +void RAGreedy::enqueue(PQueue &CurQueue, const LiveInterval *LI) { // Prioritize live ranges by size, assigning larger ranges first. // The queue holds (size, reg) pairs. const unsigned Size = LI->getSize(); @@ -345,9 +345,9 @@ CurQueue.push(std::make_pair(Prio, ~Reg)); } -LiveInterval *RAGreedy::dequeue() { return dequeue(Queue); } +const LiveInterval *RAGreedy::dequeue() { return dequeue(Queue); } -LiveInterval *RAGreedy::dequeue(PQueue &CurQueue) { +const LiveInterval *RAGreedy::dequeue(PQueue &CurQueue) { if (CurQueue.empty()) return nullptr; LiveInterval *LI = &LIS->getInterval(~CurQueue.top().second); @@ -360,10 +360,10 @@ //===----------------------------------------------------------------------===// /// tryAssign - Try to assign VirtReg to an available register. -MCRegister RAGreedy::tryAssign(LiveInterval &VirtReg, - AllocationOrder &Order, - SmallVectorImpl &NewVRegs, - const SmallVirtRegSet &FixedRegisters) { +MCRegister RAGreedy::tryAssign(const LiveInterval &VirtReg, + AllocationOrder &Order, + SmallVectorImpl &NewVRegs, + const SmallVirtRegSet &FixedRegisters) { MCRegister PhysReg; for (auto I = Order.begin(), E = Order.end(); I != E && !PhysReg; ++I) { assert(*I); @@ -413,7 +413,7 @@ // Interference eviction //===----------------------------------------------------------------------===// -Register RegAllocEvictionAdvisor::canReassign(LiveInterval &VirtReg, +Register RegAllocEvictionAdvisor::canReassign(const LiveInterval &VirtReg, Register PrevReg) const { auto Order = AllocationOrder::create(VirtReg.reg(), *VRM, RegClassInfo, Matrix); @@ -527,7 +527,8 @@ /// evictInterference - Evict any interferring registers that prevent VirtReg /// from being assigned to Physreg. This assumes that canEvictInterference /// returned true. -void RAGreedy::evictInterference(LiveInterval &VirtReg, MCRegister PhysReg, +void RAGreedy::evictInterference(const LiveInterval &VirtReg, + MCRegister PhysReg, SmallVectorImpl &NewVRegs) { // Make sure that VirtReg has a cascade number, and assign that cascade // number to every evicted register. These live ranges than then only be @@ -538,19 +539,19 @@ << " interference: Cascade " << Cascade << '\n'); // Collect all interfering virtregs first. - SmallVector Intfs; + SmallVector Intfs; for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) { LiveIntervalUnion::Query &Q = Matrix->query(VirtReg, *Units); // We usually have the interfering VRegs cached so collectInterferingVRegs() // should be fast, we may need to recalculate if when different physregs // overlap the same register unit so we had different SubRanges queried // against it. - ArrayRef IVR = Q.interferingVRegs(); + ArrayRef IVR = Q.interferingVRegs(); Intfs.append(IVR.begin(), IVR.end()); } // Evict them second. This will invalidate the queries. - for (LiveInterval *Intf : Intfs) { + for (const LiveInterval *Intf : Intfs) { // The same VirtReg may be present in multiple RegUnits. Skip duplicates. if (!VRM->hasPhys(Intf->reg())) continue; @@ -624,7 +625,8 @@ /// @param VirtReg Currently unassigned virtual register. /// @param Order Physregs to try. /// @return Physreg to assign VirtReg, or 0. -MCRegister RAGreedy::tryEvict(LiveInterval &VirtReg, AllocationOrder &Order, +MCRegister RAGreedy::tryEvict(const LiveInterval &VirtReg, + AllocationOrder &Order, SmallVectorImpl &NewVRegs, uint8_t CostPerUseLimit, const SmallVirtRegSet &FixedRegisters) { @@ -1253,7 +1255,7 @@ MF->verify(this, "After splitting live range around region"); } -MCRegister RAGreedy::tryRegionSplit(LiveInterval &VirtReg, +MCRegister RAGreedy::tryRegionSplit(const LiveInterval &VirtReg, AllocationOrder &Order, SmallVectorImpl &NewVRegs) { if (!TRI->shouldRegionSplitForVirtReg(*MF, VirtReg)) @@ -1297,7 +1299,7 @@ return doRegionSplit(VirtReg, BestCand, HasCompact, NewVRegs); } -unsigned RAGreedy::calculateRegionSplitCost(LiveInterval &VirtReg, +unsigned RAGreedy::calculateRegionSplitCost(const LiveInterval &VirtReg, AllocationOrder &Order, BlockFrequency &BestCost, unsigned &NumCands, bool IgnoreCSR, @@ -1397,7 +1399,7 @@ return BestCand; } -unsigned RAGreedy::doRegionSplit(LiveInterval &VirtReg, unsigned BestCand, +unsigned RAGreedy::doRegionSplit(const LiveInterval &VirtReg, unsigned BestCand, bool HasCompact, SmallVectorImpl &NewVRegs) { SmallVector UsedCands; @@ -1444,7 +1446,8 @@ /// tryBlockSplit - Split a global live range around every block with uses. This /// creates a lot of local live ranges, that will be split by tryLocalSplit if /// they don't allocate. -unsigned RAGreedy::tryBlockSplit(LiveInterval &VirtReg, AllocationOrder &Order, +unsigned RAGreedy::tryBlockSplit(const LiveInterval &VirtReg, + AllocationOrder &Order, SmallVectorImpl &NewVRegs) { assert(&SA->getParent() == &VirtReg && "Live range wasn't analyzed"); Register Reg = VirtReg.reg(); @@ -1507,9 +1510,9 @@ /// be moved to a larger register class. /// /// This is similar to spilling to a larger register class. -unsigned -RAGreedy::tryInstructionSplit(LiveInterval &VirtReg, AllocationOrder &Order, - SmallVectorImpl &NewVRegs) { +unsigned RAGreedy::tryInstructionSplit(const LiveInterval &VirtReg, + AllocationOrder &Order, + SmallVectorImpl &NewVRegs) { const TargetRegisterClass *CurRC = MRI->getRegClass(VirtReg.reg()); // There is no point to this if there are no larger sub-classes. if (!RegClassInfo.isProperSubClass(CurRC)) @@ -1649,7 +1652,8 @@ /// tryLocalSplit - Try to split VirtReg into smaller intervals inside its only /// basic block. /// -unsigned RAGreedy::tryLocalSplit(LiveInterval &VirtReg, AllocationOrder &Order, +unsigned RAGreedy::tryLocalSplit(const LiveInterval &VirtReg, + AllocationOrder &Order, SmallVectorImpl &NewVRegs) { // TODO: the function currently only handles a single UseBlock; it should be // possible to generalize. @@ -1879,7 +1883,7 @@ /// trySplit - Try to split VirtReg or one of its interferences, making it /// assignable. /// @return Physreg when VirtReg may be assigned and/or new NewVRegs. -unsigned RAGreedy::trySplit(LiveInterval &VirtReg, AllocationOrder &Order, +unsigned RAGreedy::trySplit(const LiveInterval &VirtReg, AllocationOrder &Order, SmallVectorImpl &NewVRegs, const SmallVirtRegSet &FixedRegisters) { // Ranges must be Split2 or less. @@ -1937,8 +1941,8 @@ /// \p FixedRegisters contains all the virtual registers that cannot be /// recolored. bool RAGreedy::mayRecolorAllInterferences( - MCRegister PhysReg, LiveInterval &VirtReg, SmallLISet &RecoloringCandidates, - const SmallVirtRegSet &FixedRegisters) { + MCRegister PhysReg, const LiveInterval &VirtReg, + SmallLISet &RecoloringCandidates, const SmallVirtRegSet &FixedRegisters) { const TargetRegisterClass *CurRC = MRI->getRegClass(VirtReg.reg()); for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) { @@ -1952,7 +1956,7 @@ CutOffInfo |= CO_Interf; return false; } - for (LiveInterval *Intf : reverse(Q.interferingVRegs())) { + for (const LiveInterval *Intf : reverse(Q.interferingVRegs())) { // If Intf is done and sit on the same register class as VirtReg, // it would not be recolorable as it is in the same state as VirtReg. // However, if VirtReg has tied defs and Intf doesn't, then @@ -2011,7 +2015,7 @@ /// \p Depth gives the current depth of the last chance recoloring. /// \return a physical register that can be used for VirtReg or ~0u if none /// exists. -unsigned RAGreedy::tryLastChanceRecoloring(LiveInterval &VirtReg, +unsigned RAGreedy::tryLastChanceRecoloring(const LiveInterval &VirtReg, AllocationOrder &Order, SmallVectorImpl &NewVRegs, SmallVirtRegSet &FixedRegisters, @@ -2073,7 +2077,7 @@ // with VirtReg on PhysReg (or one of its aliases). // Enqueue them for recoloring and perform the actual recoloring. PQueue RecoloringQueue; - for (LiveInterval *RC : RecoloringCandidates) { + for (const LiveInterval *RC : RecoloringCandidates) { Register ItVirtReg = RC->reg(); enqueue(RecoloringQueue, RC); assert(VRM->hasPhys(ItVirtReg) && @@ -2122,7 +2126,7 @@ NewVRegs.push_back(R); } - for (LiveInterval *RC : RecoloringCandidates) { + for (const LiveInterval *RC : RecoloringCandidates) { Register ItVirtReg = RC->reg(); if (VRM->hasPhys(ItVirtReg)) Matrix->unassign(*RC); @@ -2148,7 +2152,7 @@ SmallVirtRegSet &FixedRegisters, unsigned Depth) { while (!RecoloringQueue.empty()) { - LiveInterval *LI = dequeue(RecoloringQueue); + const LiveInterval *LI = dequeue(RecoloringQueue); LLVM_DEBUG(dbgs() << "Try to recolor: " << *LI << '\n'); MCRegister PhysReg = selectOrSplitImpl(*LI, NewVRegs, FixedRegisters, Depth + 1); @@ -2178,7 +2182,7 @@ // Main Entry Point //===----------------------------------------------------------------------===// -MCRegister RAGreedy::selectOrSplit(LiveInterval &VirtReg, +MCRegister RAGreedy::selectOrSplit(const LiveInterval &VirtReg, SmallVectorImpl &NewVRegs) { CutOffInfo = CO_None; LLVMContext &Ctx = MF->getFunction().getContext(); @@ -2208,10 +2212,9 @@ /// Spilling a live range in the cold path can have lower cost than using /// the CSR for the first time. Returns the physical register if we decide /// to use the CSR; otherwise return 0. -MCRegister -RAGreedy::tryAssignCSRFirstTime(LiveInterval &VirtReg, AllocationOrder &Order, - MCRegister PhysReg, uint8_t &CostPerUseLimit, - SmallVectorImpl &NewVRegs) { +MCRegister RAGreedy::tryAssignCSRFirstTime( + const LiveInterval &VirtReg, AllocationOrder &Order, MCRegister PhysReg, + uint8_t &CostPerUseLimit, SmallVectorImpl &NewVRegs) { if (ExtraInfo->getStage(VirtReg) == RS_Spill && VirtReg.isSpillable()) { // We choose spill over using the CSR for the first time if the spill cost // is lower than CSRCost. @@ -2243,7 +2246,7 @@ return PhysReg; } -void RAGreedy::aboutToRemoveInterval(LiveInterval &LI) { +void RAGreedy::aboutToRemoveInterval(const LiveInterval &LI) { // Do not keep invalid information around. SetOfBrokenHints.remove(&LI); } @@ -2317,7 +2320,7 @@ /// For a given live range, profitability is determined by the sum of the /// frequencies of the non-identity copies it would introduce with the old /// and new register. -void RAGreedy::tryHintRecoloring(LiveInterval &VirtReg) { +void RAGreedy::tryHintRecoloring(const LiveInterval &VirtReg) { // We have a broken hint, check if it is possible to fix it by // reusing PhysReg for the copy-related live-ranges. Indeed, we evicted // some register and PhysReg may be available for the other live-ranges. @@ -2431,7 +2434,7 @@ /// This is likely that we can assign the same register for b, c, and d, /// getting rid of 2 copies. void RAGreedy::tryHintsRecoloring() { - for (LiveInterval *LI : SetOfBrokenHints) { + for (const LiveInterval *LI : SetOfBrokenHints) { assert(Register::isVirtualRegister(LI->reg()) && "Recoloring is possible only for virtual registers"); // Some dead defs may be around (e.g., because of debug uses). @@ -2442,7 +2445,7 @@ } } -MCRegister RAGreedy::selectOrSplitImpl(LiveInterval &VirtReg, +MCRegister RAGreedy::selectOrSplitImpl(const LiveInterval &VirtReg, SmallVectorImpl &NewVRegs, SmallVirtRegSet &FixedRegisters, unsigned Depth) { diff --git a/llvm/lib/CodeGen/SplitKit.h b/llvm/lib/CodeGen/SplitKit.h --- a/llvm/lib/CodeGen/SplitKit.h +++ b/llvm/lib/CodeGen/SplitKit.h @@ -350,14 +350,20 @@ /// interval @p LI. The interval @p LI is assumed to contain such a subrange. /// This function is used to find corresponding subranges between the /// original interval and the new intervals. - LiveInterval::SubRange &getSubRangeForMaskExact(LaneBitmask LM, - LiveInterval &LI); + static const LiveInterval::SubRange & + getSubRangeForMaskExact(LaneBitmask LM, const LiveInterval &LI); + + /// Non-const variant of the above, used when building up the result(s) of a + /// split. + static LiveInterval::SubRange &getSubRangeForMaskExact(LaneBitmask LM, + LiveInterval &LI); /// Find a subrange corresponding to the lane mask @p LM, or a superset of it, /// in the live interval @p LI. The interval @p LI is assumed to contain such /// a subrange. This function is used to find corresponding subranges between /// the original interval and the new intervals. - LiveInterval::SubRange &getSubRangeForMask(LaneBitmask LM, LiveInterval &LI); + static const LiveInterval::SubRange & + getSubRangeForMask(LaneBitmask LM, const LiveInterval &LI); /// Add a segment to the interval LI for the value number VNI. If LI has /// subranges, corresponding segments will be added to them as well, but @@ -390,10 +396,8 @@ /// defFromParent - Define Reg from ParentVNI at UseIdx using either /// rematerialization or a COPY from parent. Return the new value. - VNInfo *defFromParent(unsigned RegIdx, - VNInfo *ParentVNI, - SlotIndex UseIdx, - MachineBasicBlock &MBB, + VNInfo *defFromParent(unsigned RegIdx, const VNInfo *ParentVNI, + SlotIndex UseIdx, MachineBasicBlock &MBB, MachineBasicBlock::iterator I); /// removeBackCopies - Remove the copy instructions that defines the values diff --git a/llvm/lib/CodeGen/SplitKit.cpp b/llvm/lib/CodeGen/SplitKit.cpp --- a/llvm/lib/CodeGen/SplitKit.cpp +++ b/llvm/lib/CodeGen/SplitKit.cpp @@ -389,17 +389,26 @@ } #endif -LiveInterval::SubRange &SplitEditor::getSubRangeForMaskExact(LaneBitmask LM, - LiveInterval &LI) { - for (LiveInterval::SubRange &S : LI.subranges()) +template auto &getSubrangeImpl(LaneBitmask LM, T &LI) { + for (auto &S : LI.subranges()) if (S.LaneMask == LM) return S; llvm_unreachable("SubRange for this mask not found"); } -LiveInterval::SubRange &SplitEditor::getSubRangeForMask(LaneBitmask LM, - LiveInterval &LI) { - for (LiveInterval::SubRange &S : LI.subranges()) +LiveInterval::SubRange &SplitEditor::getSubRangeForMaskExact(LaneBitmask LM, + LiveInterval &LI) { + return getSubrangeImpl(LM, LI); +} + +const LiveInterval::SubRange & +SplitEditor::getSubRangeForMaskExact(LaneBitmask LM, const LiveInterval &LI) { + return getSubrangeImpl(LM, LI); +} + +const LiveInterval::SubRange & +SplitEditor::getSubRangeForMask(LaneBitmask LM, const LiveInterval &LI) { + for (const LiveInterval::SubRange &S : LI.subranges()) if ((S.LaneMask & LM) == LM) return S; llvm_unreachable("SubRange for this mask not found"); @@ -566,10 +575,8 @@ return Def; } -VNInfo *SplitEditor::defFromParent(unsigned RegIdx, - VNInfo *ParentVNI, - SlotIndex UseIdx, - MachineBasicBlock &MBB, +VNInfo *SplitEditor::defFromParent(unsigned RegIdx, const VNInfo *ParentVNI, + SlotIndex UseIdx, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) { SlotIndex Def; LiveInterval *LI = &LIS.getInterval(Edit->get(RegIdx)); @@ -937,7 +944,7 @@ void SplitEditor::computeRedundantBackCopies( DenseSet &NotToHoistSet, SmallVectorImpl &BackCopies) { LiveInterval *LI = &LIS.getInterval(Edit->get(0)); - LiveInterval *Parent = &Edit->getParent(); + const LiveInterval *Parent = &Edit->getParent(); SmallVector, 8> EqualVNs(Parent->getNumValNums()); SmallPtrSet DominatedVNIs; @@ -952,7 +959,7 @@ // For VNI aggregation of each ParentVNI, collect dominated, i.e., // redundant VNIs to BackCopies. for (unsigned i = 0, e = Parent->getNumValNums(); i != e; ++i) { - VNInfo *ParentVNI = Parent->getValNumInfo(i); + const VNInfo *ParentVNI = Parent->getValNumInfo(i); if (!NotToHoistSet.count(ParentVNI->id)) continue; SmallPtrSetIterator It1 = EqualVNs[ParentVNI->id].begin(); @@ -990,7 +997,7 @@ void SplitEditor::hoistCopies() { // Get the complement interval, always RegIdx 0. LiveInterval *LI = &LIS.getInterval(Edit->get(0)); - LiveInterval *Parent = &Edit->getParent(); + const LiveInterval *Parent = &Edit->getParent(); // Track the nearest common dominator for all back-copies for each ParentVNI, // indexed by ParentVNI->id. @@ -1067,7 +1074,7 @@ if (!Dom.first || Dom.second.isValid()) continue; // This value needs a hoisted copy inserted at the end of Dom.first. - VNInfo *ParentVNI = Parent->getValNumInfo(i); + const VNInfo *ParentVNI = Parent->getValNumInfo(i); MachineBasicBlock *DefMBB = LIS.getMBBFromIndex(ParentVNI->def); // Get a less loopy dominator than Dom.first. Dom.first = findShallowDominator(Dom.first, DefMBB); @@ -1237,11 +1244,11 @@ SlotIndex LastUse = End.getPrevSlot(); // The predecessor may not have a live-out value. That is OK, like an // undef PHI operand. - LiveInterval &PLI = Edit->getParent(); + const LiveInterval &PLI = Edit->getParent(); // Need the cast because the inputs to ?: would otherwise be deemed // "incompatible": SubRange vs LiveInterval. - LiveRange &PSR = !LM.all() ? getSubRangeForMaskExact(LM, PLI) - : static_cast(PLI); + const LiveRange &PSR = !LM.all() ? getSubRangeForMaskExact(LM, PLI) + : static_cast(PLI); if (PSR.liveAt(LastUse)) LIC.extend(LR, End, /*PhysReg=*/0, Undefs); } @@ -1254,7 +1261,7 @@ // remove it. Otherwise, extend the live interval to reach the end indexes // of all predecessor blocks. - LiveInterval &ParentLI = Edit->getParent(); + const LiveInterval &ParentLI = Edit->getParent(); for (const VNInfo *V : ParentLI.valnos) { if (V->isUnused() || !V->isPHIDef()) continue; @@ -1270,7 +1277,7 @@ SmallVector Undefs; LiveIntervalCalc SubLIC; - for (LiveInterval::SubRange &PS : ParentLI.subranges()) { + for (const LiveInterval::SubRange &PS : ParentLI.subranges()) { for (const VNInfo *V : PS.valnos) { if (V->isUnused() || !V->isPHIDef()) continue;