[nfc][regalloc] const LiveIntervals within the allocator
Once built, LiveIntervals are immutable. This patch captures that. Differential Revision: https://reviews.llvm.org/D118918
This commit is contained in:
parent
9fa3243ffc
commit
592f52de33
|
@ -43,7 +43,7 @@ class LiveIntervalUnion {
|
|||
// A set of live virtual register segments that supports fast insertion,
|
||||
// intersection, and removal.
|
||||
// Mapping SlotIndex intervals to virtual register numbers.
|
||||
using LiveSegments = IntervalMap<SlotIndex, LiveInterval*>;
|
||||
using LiveSegments = IntervalMap<SlotIndex, const LiveInterval *>;
|
||||
|
||||
public:
|
||||
// SegmentIter can advance to the next segment ordered by starting position
|
||||
|
@ -88,10 +88,10 @@ public:
|
|||
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 @@ public:
|
|||
#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 @@ public:
|
|||
const LiveRange *LR = nullptr;
|
||||
LiveRange::const_iterator LRI; ///< current position in LR
|
||||
ConstSegmentIter LiveUnionI; ///< current position in LiveUnion
|
||||
SmallVector<LiveInterval *, 4> InterferingVRegs;
|
||||
SmallVector<const LiveInterval *, 4> InterferingVRegs;
|
||||
bool CheckedFirstInterference = false;
|
||||
bool SeenAllInterferences = false;
|
||||
unsigned Tag = 0;
|
||||
|
@ -125,7 +125,7 @@ public:
|
|||
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 @@ public:
|
|||
bool checkInterference() { return collectInterferingVRegs(1); }
|
||||
|
||||
// Vector generated by collectInterferingVRegs.
|
||||
const SmallVectorImpl<LiveInterval *> &interferingVRegs(
|
||||
const SmallVectorImpl<const LiveInterval *> &interferingVRegs(
|
||||
unsigned MaxInterferingRegs = std::numeric_limits<unsigned>::max()) {
|
||||
if (!SeenAllInterferences || MaxInterferingRegs < InterferingVRegs.size())
|
||||
collectInterferingVRegs(MaxInterferingRegs);
|
||||
|
|
|
@ -374,7 +374,7 @@ class VirtRegMap;
|
|||
///
|
||||
/// 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.
|
||||
|
|
|
@ -66,7 +66,7 @@ public:
|
|||
};
|
||||
|
||||
private:
|
||||
LiveInterval *Parent;
|
||||
const LiveInterval *const Parent;
|
||||
SmallVectorImpl<Register> &NewRegs;
|
||||
MachineRegisterInfo &MRI;
|
||||
LiveIntervals &LIS;
|
||||
|
@ -129,7 +129,7 @@ public:
|
|||
/// 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<Register> &newRegs,
|
||||
LiveRangeEdit(const LiveInterval *parent, SmallVectorImpl<Register> &newRegs,
|
||||
MachineFunction &MF, LiveIntervals &lis, VirtRegMap *vrm,
|
||||
Delegate *delegate = nullptr,
|
||||
SmallPtrSet<MachineInstr *, 32> *deadRemats = nullptr)
|
||||
|
@ -141,7 +141,7 @@ public:
|
|||
|
||||
~LiveRangeEdit() override { MRI.resetDelegate(this); }
|
||||
|
||||
LiveInterval &getParent() const {
|
||||
const LiveInterval &getParent() const {
|
||||
assert(Parent && "No parent LiveInterval");
|
||||
return *Parent;
|
||||
}
|
||||
|
@ -193,11 +193,11 @@ public:
|
|||
|
||||
/// 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
|
||||
|
|
|
@ -104,7 +104,8 @@ public:
|
|||
/// 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 @@ public:
|
|||
/// 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 @@ public:
|
|||
/// 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.
|
||||
|
|
|
@ -26,7 +26,8 @@ using namespace llvm;
|
|||
#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 @@ void LiveIntervalUnion::unify(LiveInterval &VirtReg, const LiveRange &Range) {
|
|||
}
|
||||
|
||||
// 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 @@ void LiveIntervalUnion::verify(LiveVirtRegBitSet& VisitedVRegs) {
|
|||
}
|
||||
#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 @@ LiveInterval *LiveIntervalUnion::getOneVReg() const {
|
|||
|
||||
// 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 @@ LiveIntervalUnion::Query::collectInterferingVRegs(unsigned MaxInterferingRegs) {
|
|||
}
|
||||
|
||||
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);
|
||||
|
|
|
@ -913,11 +913,11 @@ static bool hasLiveThroughUse(const MachineInstr *MI, Register Reg) {
|
|||
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<SlotIndex> Slots;
|
||||
|
|
|
@ -78,13 +78,13 @@ void LiveRegMatrix::releaseMemory() {
|
|||
|
||||
template <typename Callable>
|
||||
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 @@ static bool foreachUnit(const TargetRegisterInfo *TRI,
|
|||
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 @@ void LiveRegMatrix::assign(LiveInterval &VirtReg, MCRegister PhysReg) {
|
|||
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 @@ bool LiveRegMatrix::isPhysRegUsed(MCRegister PhysReg) const {
|
|||
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 @@ bool LiveRegMatrix::checkRegMaskInterference(LiveInterval &VirtReg,
|
|||
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 @@ LiveIntervalUnion::Query &LiveRegMatrix::query(const LiveRange &LR,
|
|||
}
|
||||
|
||||
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 @@ bool LiveRegMatrix::checkInterference(SlotIndex Start, SlotIndex End,
|
|||
}
|
||||
|
||||
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();
|
||||
|
|
|
@ -259,14 +259,16 @@ protected:
|
|||
/// 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<float, FeatureIDs::FeatureCount> &Largest,
|
||||
size_t Pos) const;
|
||||
|
@ -275,18 +277,18 @@ private:
|
|||
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<LiveInterval *> &Intervals,
|
||||
void extractFeatures(const SmallVectorImpl<const LiveInterval *> &Intervals,
|
||||
std::array<float, FeatureIDs::FeatureCount> &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 @@ public:
|
|||
|
||||
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 @@ MLEvictAdvisor::MLEvictAdvisor(const MachineFunction &MF, const RAGreedy &RA,
|
|||
}
|
||||
|
||||
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<int64_t>();
|
||||
assert(Ret >= 0);
|
||||
|
@ -525,7 +527,7 @@ int64_t MLEvictAdvisor::tryFindEvictionCandidatePosition(
|
|||
}
|
||||
|
||||
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 @@ bool MLEvictAdvisor::loadInterferenceFeatures(
|
|||
// The cascade tracking is the same as in the default advisor
|
||||
unsigned Cascade = RA.getExtraInfo().getCascadeOrCurrentNext(VirtReg.reg());
|
||||
|
||||
SmallVector<LiveInterval *, MaxInterferences> InterferingIntervals;
|
||||
SmallVector<const LiveInterval *, MaxInterferences> 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 @@ bool MLEvictAdvisor::loadInterferenceFeatures(
|
|||
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 @@ bool MLEvictAdvisor::loadInterferenceFeatures(
|
|||
}
|
||||
|
||||
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 @@ MCRegister MLEvictAdvisor::tryFindEvictionCandidate(
|
|||
// decision making process.
|
||||
Regs[CandidateVirtRegPos].second = !MustFindEviction;
|
||||
if (!MustFindEviction)
|
||||
extractFeatures(SmallVector<LiveInterval *, 1>(1, &VirtReg), Largest,
|
||||
extractFeatures(SmallVector<const LiveInterval *, 1>(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 @@ MLEvictAdvisor::getLIFeatureComponents(const LiveInterval &LI) const {
|
|||
// 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<LiveInterval *> &Intervals,
|
||||
const SmallVectorImpl<const LiveInterval *> &Intervals,
|
||||
std::array<float, FeatureIDs::FeatureCount> &Largest, size_t Pos,
|
||||
int64_t IsHint, int64_t LocalIntfsCount, float NrUrgent) const {
|
||||
int64_t NrDefsAndUses = 0;
|
||||
|
@ -835,8 +837,9 @@ RegAllocEvictionAdvisorAnalysis *llvm::createDevelopmentModeAdvisor() {
|
|||
}
|
||||
|
||||
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<ModelUnderTrainingRunner>(getRunner())) {
|
||||
Ret = MLEvictAdvisor::tryFindEvictionCandidatePosition(
|
||||
|
|
|
@ -85,7 +85,7 @@ void RegAllocBase::allocatePhysRegs() {
|
|||
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 @@ void RegAllocBase::postOptimization() {
|
|||
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");
|
||||
|
|
|
@ -96,19 +96,19 @@ protected:
|
|||
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<Register> &splitLVRs) = 0;
|
||||
|
||||
// Use this group name for NamedRegionTimer.
|
||||
|
@ -116,7 +116,7 @@ protected:
|
|||
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.
|
||||
|
|
|
@ -45,7 +45,7 @@ static RegisterRegAlloc basicRegAlloc("basic", "basic register allocator",
|
|||
|
||||
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 @@ class RABasic : public MachineFunctionPass,
|
|||
|
||||
// state
|
||||
std::unique_ptr<Spiller> SpillerInstance;
|
||||
std::priority_queue<LiveInterval*, std::vector<LiveInterval*>,
|
||||
CompSpillWeight> Queue;
|
||||
std::priority_queue<const LiveInterval *, std::vector<const LiveInterval *>,
|
||||
CompSpillWeight>
|
||||
Queue;
|
||||
|
||||
// Scratch space. Allocated here to avoid repeated malloc calls in
|
||||
// selectOrSplit().
|
||||
|
@ -88,19 +89,17 @@ public:
|
|||
|
||||
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<Register> &SplitVRegs) override;
|
||||
|
||||
/// Perform register allocation.
|
||||
|
@ -119,7 +118,7 @@ public:
|
|||
// 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<Register> &SplitVRegs);
|
||||
|
||||
static char ID;
|
||||
|
@ -208,16 +207,17 @@ void RABasic::releaseMemory() {
|
|||
// 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<Register> &SplitVRegs) {
|
||||
// Record each interference and determine if all are spillable before mutating
|
||||
// either the union or live intervals.
|
||||
SmallVector<LiveInterval*, 8> Intfs;
|
||||
SmallVector<const LiveInterval *, 8> 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 @@ bool RABasic::spillInterferences(LiveInterval &VirtReg, MCRegister PhysReg,
|
|||
|
||||
// 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 @@ bool RABasic::spillInterferences(LiveInterval &VirtReg, MCRegister PhysReg,
|
|||
// |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<Register> &SplitVRegs) {
|
||||
// Populate a list of physical register spill candidates.
|
||||
SmallVector<MCRegister, 8> PhysRegSpillCands;
|
||||
|
|
|
@ -144,8 +144,8 @@ RegAllocEvictionAdvisor::RegAllocEvictionAdvisor(const MachineFunction &MF,
|
|||
/// 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 @@ bool DefaultEvictionAdvisor::shouldEvict(LiveInterval &A, bool IsHint,
|
|||
/// 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 @@ bool DefaultEvictionAdvisor::canEvictHintInterference(
|
|||
/// 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 @@ bool DefaultEvictionAdvisor::canEvictInterferenceBasedOnCost(
|
|||
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 @@ bool DefaultEvictionAdvisor::canEvictInterferenceBasedOnCost(
|
|||
}
|
||||
|
||||
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;
|
||||
|
|
|
@ -99,15 +99,14 @@ public:
|
|||
/// 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 @@ public:
|
|||
protected:
|
||||
RegAllocEvictionAdvisor(const 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 @@ public:
|
|||
: 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
|
||||
|
||||
|
|
|
@ -277,9 +277,9 @@ void RAGreedy::releaseMemory() {
|
|||
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 @@ void RAGreedy::enqueue(PQueue &CurQueue, LiveInterval *LI) {
|
|||
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 @@ LiveInterval *RAGreedy::dequeue(PQueue &CurQueue) {
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// tryAssign - Try to assign VirtReg to an available register.
|
||||
MCRegister RAGreedy::tryAssign(LiveInterval &VirtReg,
|
||||
AllocationOrder &Order,
|
||||
SmallVectorImpl<Register> &NewVRegs,
|
||||
const SmallVirtRegSet &FixedRegisters) {
|
||||
MCRegister RAGreedy::tryAssign(const LiveInterval &VirtReg,
|
||||
AllocationOrder &Order,
|
||||
SmallVectorImpl<Register> &NewVRegs,
|
||||
const SmallVirtRegSet &FixedRegisters) {
|
||||
MCRegister PhysReg;
|
||||
for (auto I = Order.begin(), E = Order.end(); I != E && !PhysReg; ++I) {
|
||||
assert(*I);
|
||||
|
@ -413,7 +413,7 @@ MCRegister RAGreedy::tryAssign(LiveInterval &VirtReg,
|
|||
// 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 @@ MCRegister RAGreedy::getCheapestEvicteeWeight(const AllocationOrder &Order,
|
|||
/// 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<Register> &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 @@ void RAGreedy::evictInterference(LiveInterval &VirtReg, MCRegister PhysReg,
|
|||
<< " interference: Cascade " << Cascade << '\n');
|
||||
|
||||
// Collect all interfering virtregs first.
|
||||
SmallVector<LiveInterval*, 8> Intfs;
|
||||
SmallVector<const LiveInterval *, 8> 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<LiveInterval*> IVR = Q.interferingVRegs();
|
||||
ArrayRef<const LiveInterval *> 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 @@ bool RegAllocEvictionAdvisor::canAllocatePhysReg(unsigned CostPerUseLimit,
|
|||
/// @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<Register> &NewVRegs,
|
||||
uint8_t CostPerUseLimit,
|
||||
const SmallVirtRegSet &FixedRegisters) {
|
||||
|
@ -1253,7 +1255,7 @@ void RAGreedy::splitAroundRegion(LiveRangeEdit &LREdit,
|
|||
MF->verify(this, "After splitting live range around region");
|
||||
}
|
||||
|
||||
MCRegister RAGreedy::tryRegionSplit(LiveInterval &VirtReg,
|
||||
MCRegister RAGreedy::tryRegionSplit(const LiveInterval &VirtReg,
|
||||
AllocationOrder &Order,
|
||||
SmallVectorImpl<Register> &NewVRegs) {
|
||||
if (!TRI->shouldRegionSplitForVirtReg(*MF, VirtReg))
|
||||
|
@ -1297,7 +1299,7 @@ MCRegister RAGreedy::tryRegionSplit(LiveInterval &VirtReg,
|
|||
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 @@ unsigned RAGreedy::calculateRegionSplitCost(LiveInterval &VirtReg,
|
|||
return BestCand;
|
||||
}
|
||||
|
||||
unsigned RAGreedy::doRegionSplit(LiveInterval &VirtReg, unsigned BestCand,
|
||||
unsigned RAGreedy::doRegionSplit(const LiveInterval &VirtReg, unsigned BestCand,
|
||||
bool HasCompact,
|
||||
SmallVectorImpl<Register> &NewVRegs) {
|
||||
SmallVector<unsigned, 8> UsedCands;
|
||||
|
@ -1444,7 +1446,8 @@ unsigned RAGreedy::doRegionSplit(LiveInterval &VirtReg, unsigned BestCand,
|
|||
/// 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<Register> &NewVRegs) {
|
||||
assert(&SA->getParent() == &VirtReg && "Live range wasn't analyzed");
|
||||
Register Reg = VirtReg.reg();
|
||||
|
@ -1507,9 +1510,9 @@ static unsigned getNumAllocatableRegsForConstraints(
|
|||
/// 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<Register> &NewVRegs) {
|
||||
unsigned RAGreedy::tryInstructionSplit(const LiveInterval &VirtReg,
|
||||
AllocationOrder &Order,
|
||||
SmallVectorImpl<Register> &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 @@ void RAGreedy::calcGapWeights(MCRegister PhysReg,
|
|||
/// 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<Register> &NewVRegs) {
|
||||
// TODO: the function currently only handles a single UseBlock; it should be
|
||||
// possible to generalize.
|
||||
|
@ -1879,7 +1883,7 @@ unsigned RAGreedy::tryLocalSplit(LiveInterval &VirtReg, AllocationOrder &Order,
|
|||
/// 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<Register> &NewVRegs,
|
||||
const SmallVirtRegSet &FixedRegisters) {
|
||||
// Ranges must be Split2 or less.
|
||||
|
@ -1937,8 +1941,8 @@ static bool hasTiedDef(MachineRegisterInfo *MRI, unsigned reg) {
|
|||
/// \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 @@ bool RAGreedy::mayRecolorAllInterferences(
|
|||
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 @@ bool RAGreedy::mayRecolorAllInterferences(
|
|||
/// \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<Register> &NewVRegs,
|
||||
SmallVirtRegSet &FixedRegisters,
|
||||
|
@ -2073,7 +2077,7 @@ unsigned RAGreedy::tryLastChanceRecoloring(LiveInterval &VirtReg,
|
|||
// 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 @@ unsigned RAGreedy::tryLastChanceRecoloring(LiveInterval &VirtReg,
|
|||
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 @@ bool RAGreedy::tryRecoloringCandidates(PQueue &RecoloringQueue,
|
|||
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 @@ bool RAGreedy::tryRecoloringCandidates(PQueue &RecoloringQueue,
|
|||
// Main Entry Point
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
MCRegister RAGreedy::selectOrSplit(LiveInterval &VirtReg,
|
||||
MCRegister RAGreedy::selectOrSplit(const LiveInterval &VirtReg,
|
||||
SmallVectorImpl<Register> &NewVRegs) {
|
||||
CutOffInfo = CO_None;
|
||||
LLVMContext &Ctx = MF->getFunction().getContext();
|
||||
|
@ -2208,10 +2212,9 @@ MCRegister RAGreedy::selectOrSplit(LiveInterval &VirtReg,
|
|||
/// 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<Register> &NewVRegs) {
|
||||
MCRegister RAGreedy::tryAssignCSRFirstTime(
|
||||
const LiveInterval &VirtReg, AllocationOrder &Order, MCRegister PhysReg,
|
||||
uint8_t &CostPerUseLimit, SmallVectorImpl<Register> &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 @@ RAGreedy::tryAssignCSRFirstTime(LiveInterval &VirtReg, AllocationOrder &Order,
|
|||
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 @@ BlockFrequency RAGreedy::getBrokenHintFreq(const HintsInfo &List,
|
|||
/// 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 @@ void RAGreedy::tryHintRecoloring(LiveInterval &VirtReg) {
|
|||
/// 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 @@ void RAGreedy::tryHintsRecoloring() {
|
|||
}
|
||||
}
|
||||
|
||||
MCRegister RAGreedy::selectOrSplitImpl(LiveInterval &VirtReg,
|
||||
MCRegister RAGreedy::selectOrSplitImpl(const LiveInterval &VirtReg,
|
||||
SmallVectorImpl<Register> &NewVRegs,
|
||||
SmallVirtRegSet &FixedRegisters,
|
||||
unsigned Depth) {
|
||||
|
|
|
@ -162,7 +162,7 @@ public:
|
|||
private:
|
||||
// Convenient shortcuts.
|
||||
using PQueue = std::priority_queue<std::pair<unsigned, unsigned>>;
|
||||
using SmallLISet = SmallPtrSet<LiveInterval *, 4>;
|
||||
using SmallLISet = SmallPtrSet<const LiveInterval *, 4>;
|
||||
|
||||
// context
|
||||
MachineFunction *MF;
|
||||
|
@ -325,7 +325,7 @@ private:
|
|||
bool EnableAdvancedRASplitCost;
|
||||
|
||||
/// Set of broken hints that may be reconciled later because of eviction.
|
||||
SmallSetVector<LiveInterval *, 8> SetOfBrokenHints;
|
||||
SmallSetVector<const LiveInterval *, 8> SetOfBrokenHints;
|
||||
|
||||
/// The register cost values. This list will be recreated for each Machine
|
||||
/// Function
|
||||
|
@ -341,11 +341,11 @@ public:
|
|||
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<Register> &) override;
|
||||
void aboutToRemoveInterval(LiveInterval &) override;
|
||||
void aboutToRemoveInterval(const LiveInterval &) override;
|
||||
|
||||
/// Perform register allocation.
|
||||
bool runOnMachineFunction(MachineFunction &mf) override;
|
||||
|
@ -363,14 +363,15 @@ public:
|
|||
static char ID;
|
||||
|
||||
private:
|
||||
MCRegister selectOrSplitImpl(LiveInterval &, SmallVectorImpl<Register> &,
|
||||
SmallVirtRegSet &, unsigned = 0);
|
||||
MCRegister selectOrSplitImpl(const LiveInterval &,
|
||||
SmallVectorImpl<Register> &, 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 @@ private:
|
|||
const LiveInterval &VirtReg,
|
||||
SlotIndex Start, SlotIndex End,
|
||||
float *BestEvictWeight) const;
|
||||
void evictInterference(LiveInterval &, MCRegister,
|
||||
void evictInterference(const LiveInterval &, MCRegister,
|
||||
SmallVectorImpl<Register> &);
|
||||
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<Register> &, const SmallVirtRegSet &);
|
||||
MCRegister tryEvict(LiveInterval &, AllocationOrder &,
|
||||
MCRegister tryEvict(const LiveInterval &, AllocationOrder &,
|
||||
SmallVectorImpl<Register> &, uint8_t,
|
||||
const SmallVirtRegSet &);
|
||||
MCRegister tryRegionSplit(LiveInterval &, AllocationOrder &,
|
||||
MCRegister tryRegionSplit(const LiveInterval &, AllocationOrder &,
|
||||
SmallVectorImpl<Register> &);
|
||||
/// 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<Register> &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<Register> &NewVRegs);
|
||||
void initializeCSRCost();
|
||||
unsigned tryBlockSplit(LiveInterval &, AllocationOrder &,
|
||||
unsigned tryBlockSplit(const LiveInterval &, AllocationOrder &,
|
||||
SmallVectorImpl<Register> &);
|
||||
unsigned tryInstructionSplit(LiveInterval &, AllocationOrder &,
|
||||
unsigned tryInstructionSplit(const LiveInterval &, AllocationOrder &,
|
||||
SmallVectorImpl<Register> &);
|
||||
unsigned tryLocalSplit(LiveInterval &, AllocationOrder &,
|
||||
unsigned tryLocalSplit(const LiveInterval &, AllocationOrder &,
|
||||
SmallVectorImpl<Register> &);
|
||||
unsigned trySplit(LiveInterval &, AllocationOrder &,
|
||||
unsigned trySplit(const LiveInterval &, AllocationOrder &,
|
||||
SmallVectorImpl<Register> &, const SmallVirtRegSet &);
|
||||
unsigned tryLastChanceRecoloring(LiveInterval &, AllocationOrder &,
|
||||
unsigned tryLastChanceRecoloring(const LiveInterval &, AllocationOrder &,
|
||||
SmallVectorImpl<Register> &,
|
||||
SmallVirtRegSet &, unsigned);
|
||||
bool tryRecoloringCandidates(PQueue &, SmallVectorImpl<Register> &,
|
||||
SmallVirtRegSet &, unsigned);
|
||||
void tryHintRecoloring(LiveInterval &);
|
||||
void tryHintRecoloring(const LiveInterval &);
|
||||
void tryHintsRecoloring();
|
||||
|
||||
/// Model the information carried by one end of a copy.
|
||||
|
|
|
@ -389,17 +389,34 @@ LLVM_DUMP_METHOD void SplitEditor::dump() const {
|
|||
}
|
||||
#endif
|
||||
|
||||
LiveInterval::SubRange &SplitEditor::getSubRangeForMaskExact(LaneBitmask LM,
|
||||
LiveInterval &LI) {
|
||||
for (LiveInterval::SubRange &S : LI.subranges())
|
||||
/// Find a subrange corresponding to the exact lane mask @p LM 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.
|
||||
template <typename T> 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 &getSubRangeForMaskExact(LaneBitmask LM,
|
||||
LiveInterval &LI) {
|
||||
return getSubrangeImpl(LM, LI);
|
||||
}
|
||||
|
||||
const LiveInterval::SubRange &getSubRangeForMaskExact(LaneBitmask LM,
|
||||
const LiveInterval &LI) {
|
||||
return getSubrangeImpl(LM, 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.
|
||||
const LiveInterval::SubRange &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 +583,8 @@ SlotIndex SplitEditor::buildCopy(Register FromReg, Register ToReg,
|
|||
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 +952,7 @@ SplitEditor::findShallowDominator(MachineBasicBlock *MBB,
|
|||
void SplitEditor::computeRedundantBackCopies(
|
||||
DenseSet<unsigned> &NotToHoistSet, SmallVectorImpl<VNInfo *> &BackCopies) {
|
||||
LiveInterval *LI = &LIS.getInterval(Edit->get(0));
|
||||
LiveInterval *Parent = &Edit->getParent();
|
||||
const LiveInterval *Parent = &Edit->getParent();
|
||||
SmallVector<SmallPtrSet<VNInfo *, 8>, 8> EqualVNs(Parent->getNumValNums());
|
||||
SmallPtrSet<VNInfo *, 8> DominatedVNIs;
|
||||
|
||||
|
@ -952,7 +967,7 @@ void SplitEditor::computeRedundantBackCopies(
|
|||
// 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<VNInfo *> It1 = EqualVNs[ParentVNI->id].begin();
|
||||
|
@ -990,7 +1005,7 @@ void SplitEditor::computeRedundantBackCopies(
|
|||
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 +1082,7 @@ void SplitEditor::hoistCopies() {
|
|||
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 +1252,11 @@ void SplitEditor::extendPHIRange(MachineBasicBlock &B, LiveIntervalCalc &LIC,
|
|||
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<LiveRange &>(PLI);
|
||||
const LiveRange &PSR = !LM.all() ? getSubRangeForMaskExact(LM, PLI)
|
||||
: static_cast<const LiveRange &>(PLI);
|
||||
if (PSR.liveAt(LastUse))
|
||||
LIC.extend(LR, End, /*PhysReg=*/0, Undefs);
|
||||
}
|
||||
|
@ -1254,7 +1269,7 @@ void SplitEditor::extendPHIKillRanges() {
|
|||
// 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 +1285,7 @@ void SplitEditor::extendPHIKillRanges() {
|
|||
SmallVector<SlotIndex, 4> 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;
|
||||
|
|
|
@ -346,19 +346,6 @@ private:
|
|||
return LICalc[SpillMode != SM_Partition && RegIdx != 0];
|
||||
}
|
||||
|
||||
/// Find a subrange corresponding to the exact lane mask @p LM 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 &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);
|
||||
|
||||
/// 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
|
||||
/// with newly created value numbers. If Original is true, dead def will
|
||||
|
@ -390,10 +377,8 @@ private:
|
|||
|
||||
/// 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
|
||||
|
|
Loading…
Reference in New Issue