mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 19:52:54 +01:00
LiveIntervalAnalysis: Cleanup; NFC
- Fix doxygen comments: Do not repeat name, remove duplicated doxygen comment (on declaration + implementation), etc. - Use more range based for llvm-svn: 292455
This commit is contained in:
parent
dff5eed453
commit
a2f54981f9
@ -7,13 +7,13 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements the LiveInterval analysis pass. Given some numbering of
|
||||
// each the machine instructions (in this implemention depth-first order) an
|
||||
// interval [i, j) is said to be a live interval for register v if there is no
|
||||
// instruction with number j' > j such that v is live at j' and there is no
|
||||
// instruction with number i' < i such that v is live at i'. In this
|
||||
// implementation intervals can have holes, i.e. an interval might look like
|
||||
// [1,20), [50,65), [1000,1001).
|
||||
/// \file This file implements the LiveInterval analysis pass. Given some
|
||||
/// numbering of each the machine instructions (in this implemention depth-first
|
||||
/// order) an interval [i, j) is said to be a live interval for register v if
|
||||
/// there is no instruction with number j' > j such that v is live at j' and
|
||||
/// there is no instruction with number i' < i such that v is live at i'. In
|
||||
/// this implementation intervals can have holes, i.e. an interval might look
|
||||
/// like [1,20), [50,65), [1000,1001).
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@ -60,20 +60,17 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
|
||||
LiveRangeCalc *LRCalc;
|
||||
|
||||
/// Special pool allocator for VNInfo's (LiveInterval val#).
|
||||
///
|
||||
VNInfo::Allocator VNInfoAllocator;
|
||||
|
||||
/// Live interval pointers for all the virtual registers.
|
||||
IndexedMap<LiveInterval*, VirtReg2IndexFunctor> VirtRegIntervals;
|
||||
|
||||
/// RegMaskSlots - Sorted list of instructions with register mask operands.
|
||||
/// Always use the 'r' slot, RegMasks are normal clobbers, not early
|
||||
/// clobbers.
|
||||
/// Sorted list of instructions with register mask operands. Always use the
|
||||
/// 'r' slot, RegMasks are normal clobbers, not early clobbers.
|
||||
SmallVector<SlotIndex, 8> RegMaskSlots;
|
||||
|
||||
/// RegMaskBits - This vector is parallel to RegMaskSlots, it holds a
|
||||
/// pointer to the corresponding register mask. This pointer can be
|
||||
/// recomputed as:
|
||||
/// This vector is parallel to RegMaskSlots, it holds a pointer to the
|
||||
/// corresponding register mask. This pointer can be recomputed as:
|
||||
///
|
||||
/// MI = Indexes->getInstructionFromIndex(RegMaskSlot[N]);
|
||||
/// unsigned OpNum = findRegMaskOperand(MI);
|
||||
@ -97,11 +94,11 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
|
||||
SmallVector<LiveRange*, 0> RegUnitRanges;
|
||||
|
||||
public:
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
static char ID;
|
||||
LiveIntervals();
|
||||
~LiveIntervals() override;
|
||||
|
||||
// Calculate the spill weight to assign to a single instruction.
|
||||
/// Calculate the spill weight to assign to a single instruction.
|
||||
static float getSpillWeight(bool isDef, bool isUse,
|
||||
const MachineBlockFrequencyInfo *MBFI,
|
||||
const MachineInstr &Instr);
|
||||
@ -121,7 +118,7 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
|
||||
return VirtRegIntervals.inBounds(Reg) && VirtRegIntervals[Reg];
|
||||
}
|
||||
|
||||
// Interval creation.
|
||||
/// Interval creation.
|
||||
LiveInterval &createEmptyInterval(unsigned Reg) {
|
||||
assert(!hasInterval(Reg) && "Interval already exists!");
|
||||
VirtRegIntervals.grow(Reg);
|
||||
@ -135,7 +132,7 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
|
||||
return LI;
|
||||
}
|
||||
|
||||
// Interval removal.
|
||||
/// Interval removal.
|
||||
void removeInterval(unsigned Reg) {
|
||||
delete VirtRegIntervals[Reg];
|
||||
VirtRegIntervals[Reg] = nullptr;
|
||||
@ -163,16 +160,16 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
|
||||
/// LiveInterval::removeEmptySubranges() afterwards.
|
||||
void shrinkToUses(LiveInterval::SubRange &SR, unsigned Reg);
|
||||
|
||||
/// Extend the live range @p LR to reach all points in @p Indices. The
|
||||
/// points in the @p Indices array must be jointly dominated by the union
|
||||
/// of the existing defs in @p LR and points in @p Undefs.
|
||||
/// Extend the live range \p LR to reach all points in \p Indices. The
|
||||
/// points in the \p Indices array must be jointly dominated by the union
|
||||
/// of the existing defs in \p LR and points in \p Undefs.
|
||||
///
|
||||
/// PHI-defs are added as needed to maintain SSA form.
|
||||
///
|
||||
/// If a SlotIndex in @p Indices is the end index of a basic block, @p LR
|
||||
/// If a SlotIndex in \p Indices is the end index of a basic block, \p LR
|
||||
/// will be extended to be live out of the basic block.
|
||||
/// If a SlotIndex in @p Indices is jointy dominated only by points in
|
||||
/// @p Undefs, the live range will not be extended to that point.
|
||||
/// If a SlotIndex in \p Indices is jointy dominated only by points in
|
||||
/// \p Undefs, the live range will not be extended to that point.
|
||||
///
|
||||
/// See also LiveRangeCalc::extend().
|
||||
void extendToIndices(LiveRange &LR, ArrayRef<SlotIndex> Indices,
|
||||
@ -182,7 +179,7 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
|
||||
extendToIndices(LR, Indices, /*Undefs=*/{});
|
||||
}
|
||||
|
||||
/// If @p LR has a live value at @p Kill, prune its live range by removing
|
||||
/// If \p LR has a live value at \p Kill, prune its live range by removing
|
||||
/// any liveness reachable from Kill. Add live range end points to
|
||||
/// EndPoints such that extendToIndices(LI, EndPoints) will reconstruct the
|
||||
/// value's live range.
|
||||
@ -200,8 +197,8 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
|
||||
return AA;
|
||||
}
|
||||
|
||||
/// isNotInMIMap - returns true if the specified machine instr has been
|
||||
/// removed or was never entered in the map.
|
||||
/// Returns true if the specified machine instr has been removed or was
|
||||
/// never entered in the map.
|
||||
bool isNotInMIMap(const MachineInstr &Instr) const {
|
||||
return !Indexes->hasIndex(Instr);
|
||||
}
|
||||
@ -270,35 +267,32 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override;
|
||||
void releaseMemory() override;
|
||||
|
||||
/// runOnMachineFunction - pass entry point
|
||||
/// Pass entry point; Calculates LiveIntervals.
|
||||
bool runOnMachineFunction(MachineFunction&) override;
|
||||
|
||||
/// print - Implement the dump method.
|
||||
/// Implement the dump method.
|
||||
void print(raw_ostream &O, const Module* = nullptr) const override;
|
||||
|
||||
/// intervalIsInOneMBB - If LI is confined to a single basic block, return
|
||||
/// a pointer to that block. If LI is live in to or out of any block,
|
||||
/// return NULL.
|
||||
/// If LI is confined to a single basic block, return a pointer to that
|
||||
/// block. If LI is live in to or out of any block, return NULL.
|
||||
MachineBasicBlock *intervalIsInOneMBB(const LiveInterval &LI) const;
|
||||
|
||||
/// Returns true if VNI is killed by any PHI-def values in LI.
|
||||
/// This may conservatively return true to avoid expensive computations.
|
||||
bool hasPHIKill(const LiveInterval &LI, const VNInfo *VNI) const;
|
||||
|
||||
/// addKillFlags - Add kill flags to any instruction that kills a virtual
|
||||
/// register.
|
||||
/// Add kill flags to any instruction that kills a virtual register.
|
||||
void addKillFlags(const VirtRegMap*);
|
||||
|
||||
/// handleMove - call this method to notify LiveIntervals that
|
||||
/// instruction 'mi' has been moved within a basic block. This will update
|
||||
/// the live intervals for all operands of mi. Moves between basic blocks
|
||||
/// are not supported.
|
||||
/// Call this method to notify LiveIntervals that instruction \p MI has been
|
||||
/// moved within a basic block. This will update the live intervals for all
|
||||
/// operands of \p MI. Moves between basic blocks are not supported.
|
||||
///
|
||||
/// \param UpdateFlags Update live intervals for nonallocatable physregs.
|
||||
void handleMove(MachineInstr &MI, bool UpdateFlags = false);
|
||||
|
||||
/// moveIntoBundle - Update intervals for operands of MI so that they
|
||||
/// begin/end on the SlotIndex for BundleStart.
|
||||
/// Update intervals for operands of \p MI so that they begin/end on the
|
||||
/// SlotIndex for \p BundleStart.
|
||||
///
|
||||
/// \param UpdateFlags Update live intervals for nonallocatable physregs.
|
||||
///
|
||||
@ -308,10 +302,9 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
|
||||
void handleMoveIntoBundle(MachineInstr &MI, MachineInstr &BundleStart,
|
||||
bool UpdateFlags = false);
|
||||
|
||||
/// repairIntervalsInRange - Update live intervals for instructions in a
|
||||
/// range of iterators. It is intended for use after target hooks that may
|
||||
/// insert or remove instructions, and is only efficient for a small number
|
||||
/// of instructions.
|
||||
/// Update live intervals for instructions in a range of iterators. It is
|
||||
/// intended for use after target hooks that may insert or remove
|
||||
/// instructions, and is only efficient for a small number of instructions.
|
||||
///
|
||||
/// OrigRegs is a vector of registers that were originally used by the
|
||||
/// instructions in the range between the two iterators.
|
||||
@ -334,34 +327,33 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
|
||||
// LiveIntervalAnalysis maintains a sorted list of instructions with
|
||||
// register mask operands.
|
||||
|
||||
/// getRegMaskSlots - Returns a sorted array of slot indices of all
|
||||
/// instructions with register mask operands.
|
||||
/// Returns a sorted array of slot indices of all instructions with
|
||||
/// register mask operands.
|
||||
ArrayRef<SlotIndex> getRegMaskSlots() const { return RegMaskSlots; }
|
||||
|
||||
/// getRegMaskSlotsInBlock - Returns a sorted array of slot indices of all
|
||||
/// instructions with register mask operands in the basic block numbered
|
||||
/// MBBNum.
|
||||
/// Returns a sorted array of slot indices of all instructions with register
|
||||
/// mask operands in the basic block numbered \p MBBNum.
|
||||
ArrayRef<SlotIndex> getRegMaskSlotsInBlock(unsigned MBBNum) const {
|
||||
std::pair<unsigned, unsigned> P = RegMaskBlocks[MBBNum];
|
||||
return getRegMaskSlots().slice(P.first, P.second);
|
||||
}
|
||||
|
||||
/// getRegMaskBits() - Returns an array of register mask pointers
|
||||
/// corresponding to getRegMaskSlots().
|
||||
/// Returns an array of register mask pointers corresponding to
|
||||
/// getRegMaskSlots().
|
||||
ArrayRef<const uint32_t*> getRegMaskBits() const { return RegMaskBits; }
|
||||
|
||||
/// getRegMaskBitsInBlock - Returns an array of mask pointers corresponding
|
||||
/// to getRegMaskSlotsInBlock(MBBNum).
|
||||
/// Returns an array of mask pointers corresponding to
|
||||
/// getRegMaskSlotsInBlock(MBBNum).
|
||||
ArrayRef<const uint32_t*> getRegMaskBitsInBlock(unsigned MBBNum) const {
|
||||
std::pair<unsigned, unsigned> P = RegMaskBlocks[MBBNum];
|
||||
return getRegMaskBits().slice(P.first, P.second);
|
||||
}
|
||||
|
||||
/// checkRegMaskInterference - Test if LI is live across any register mask
|
||||
/// instructions, and compute a bit mask of physical registers that are not
|
||||
/// clobbered by any of them.
|
||||
/// Test if \p LI is live across any register mask instructions, and
|
||||
/// compute a bit mask of physical registers that are not clobbered by any
|
||||
/// of them.
|
||||
///
|
||||
/// Returns false if LI doesn't cross any register mask instructions. In
|
||||
/// 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,
|
||||
BitVector &UsableRegs);
|
||||
@ -377,8 +369,8 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
|
||||
// track liveness per register unit to handle aliasing registers more
|
||||
// efficiently.
|
||||
|
||||
/// getRegUnit - Return the live range for Unit.
|
||||
/// It will be computed if it doesn't exist.
|
||||
/// Return the live range for register unit \p Unit. It will be computed if
|
||||
/// it doesn't exist.
|
||||
LiveRange &getRegUnit(unsigned Unit) {
|
||||
LiveRange *LR = RegUnitRanges[Unit];
|
||||
if (!LR) {
|
||||
@ -390,8 +382,8 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
|
||||
return *LR;
|
||||
}
|
||||
|
||||
/// getCachedRegUnit - Return the live range for Unit if it has already
|
||||
/// been computed, or NULL if it hasn't been computed yet.
|
||||
/// Return the live range for register unit \p Unit if it has already been
|
||||
/// computed, or nullptr if it hasn't been computed yet.
|
||||
LiveRange *getCachedRegUnit(unsigned Unit) {
|
||||
return RegUnitRanges[Unit];
|
||||
}
|
||||
@ -400,7 +392,7 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
|
||||
return RegUnitRanges[Unit];
|
||||
}
|
||||
|
||||
/// removeRegUnit - Remove computed live range for Unit. Subsequent uses
|
||||
/// Remove computed live range for register unit \p Unit. Subsequent uses
|
||||
/// should rely on on-demand recomputation.
|
||||
void removeRegUnit(unsigned Unit) {
|
||||
delete RegUnitRanges[Unit];
|
||||
@ -408,12 +400,12 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
|
||||
}
|
||||
|
||||
/// Remove value numbers and related live segments starting at position
|
||||
/// @p Pos that are part of any liverange of physical register @p Reg or one
|
||||
/// \p Pos that are part of any liverange of physical register \p Reg or one
|
||||
/// of its subregisters.
|
||||
void removePhysRegDefAt(unsigned Reg, SlotIndex Pos);
|
||||
|
||||
/// Remove value number and related live segments of @p LI and its subranges
|
||||
/// that start at position @p Pos.
|
||||
/// Remove value number and related live segments of \p LI and its subranges
|
||||
/// that start at position \p Pos.
|
||||
void removeVRegDefAt(LiveInterval &LI, SlotIndex Pos);
|
||||
|
||||
/// Split separate components in LiveInterval \p LI into separate intervals.
|
||||
@ -432,10 +424,10 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
|
||||
/// Compute RegMaskSlots and RegMaskBits.
|
||||
void computeRegMasks();
|
||||
|
||||
/// Walk the values in @p LI and check for dead values:
|
||||
/// Walk the values in \p LI and check for dead values:
|
||||
/// - Dead PHIDef values are marked as unused.
|
||||
/// - Dead operands are marked as such.
|
||||
/// - Completely dead machine instructions are added to the @p dead vector
|
||||
/// - Completely dead machine instructions are added to the \p dead vector
|
||||
/// if it is not nullptr.
|
||||
/// Returns true if any PHI value numbers have been removed which may
|
||||
/// have separated the interval into multiple connected components.
|
||||
@ -453,8 +445,8 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
|
||||
|
||||
|
||||
/// Helper function for repairIntervalsInRange(), walks backwards and
|
||||
/// creates/modifies live segments in @p LR to match the operands found.
|
||||
/// Only full operands or operands with subregisters matching @p LaneMask
|
||||
/// creates/modifies live segments in \p LR to match the operands found.
|
||||
/// Only full operands or operands with subregisters matching \p LaneMask
|
||||
/// are considered.
|
||||
void repairOldRegInRange(MachineBasicBlock::iterator Begin,
|
||||
MachineBasicBlock::iterator End,
|
||||
|
@ -7,10 +7,10 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements the LiveInterval analysis pass which is used
|
||||
// by the Linear Scan Register allocator. This pass linearizes the
|
||||
// basic blocks of the function in DFS order and computes live intervals for
|
||||
// each virtual and physical register.
|
||||
/// \file This file implements the LiveInterval analysis pass which is used
|
||||
/// by the Linear Scan Register allocator. This pass linearizes the
|
||||
/// basic blocks of the function in DFS order and computes live intervals for
|
||||
/// each virtual and physical register.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@ -96,16 +96,14 @@ void LiveIntervals::releaseMemory() {
|
||||
RegMaskBits.clear();
|
||||
RegMaskBlocks.clear();
|
||||
|
||||
for (unsigned i = 0, e = RegUnitRanges.size(); i != e; ++i)
|
||||
delete RegUnitRanges[i];
|
||||
for (LiveRange *LR : RegUnitRanges)
|
||||
delete LR;
|
||||
RegUnitRanges.clear();
|
||||
|
||||
// Release VNInfo memory regions, VNInfo objects don't need to be dtor'd.
|
||||
VNInfoAllocator.Reset();
|
||||
}
|
||||
|
||||
/// runOnMachineFunction - calculates LiveIntervals
|
||||
///
|
||||
bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
|
||||
MF = &fn;
|
||||
MRI = &MF->getRegInfo();
|
||||
@ -135,14 +133,13 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/// print - Implement the dump method.
|
||||
void LiveIntervals::print(raw_ostream &OS, const Module* ) const {
|
||||
OS << "********** INTERVALS **********\n";
|
||||
|
||||
// Dump the regunits.
|
||||
for (unsigned i = 0, e = RegUnitRanges.size(); i != e; ++i)
|
||||
if (LiveRange *LR = RegUnitRanges[i])
|
||||
OS << PrintRegUnit(i, TRI) << ' ' << *LR << '\n';
|
||||
for (unsigned Unit = 0, UnitE = RegUnitRanges.size(); Unit != UnitE; ++Unit)
|
||||
if (LiveRange *LR = RegUnitRanges[Unit])
|
||||
OS << PrintRegUnit(Unit, TRI) << ' ' << *LR << '\n';
|
||||
|
||||
// Dump the virtregs.
|
||||
for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) {
|
||||
@ -152,8 +149,8 @@ void LiveIntervals::print(raw_ostream &OS, const Module* ) const {
|
||||
}
|
||||
|
||||
OS << "RegMasks:";
|
||||
for (unsigned i = 0, e = RegMaskSlots.size(); i != e; ++i)
|
||||
OS << ' ' << RegMaskSlots[i];
|
||||
for (SlotIndex Idx : RegMaskSlots)
|
||||
OS << ' ' << Idx;
|
||||
OS << '\n';
|
||||
|
||||
printInstrs(OS);
|
||||
@ -177,8 +174,7 @@ LiveInterval* LiveIntervals::createInterval(unsigned reg) {
|
||||
}
|
||||
|
||||
|
||||
/// computeVirtRegInterval - Compute the live interval of a virtual register,
|
||||
/// based on defs and uses.
|
||||
/// Compute the live interval of a virtual register, based on defs and uses.
|
||||
void LiveIntervals::computeVirtRegInterval(LiveInterval &LI) {
|
||||
assert(LRCalc && "LRCalc not initialized.");
|
||||
assert(LI.empty() && "Should only compute empty intervals.");
|
||||
@ -200,7 +196,7 @@ void LiveIntervals::computeRegMasks() {
|
||||
RegMaskBlocks.resize(MF->getNumBlockIDs());
|
||||
|
||||
// Find all instructions with regmask operands.
|
||||
for (MachineBasicBlock &MBB : *MF) {
|
||||
for (const MachineBasicBlock &MBB : *MF) {
|
||||
std::pair<unsigned, unsigned> &RMB = RegMaskBlocks[MBB.getNumber()];
|
||||
RMB.first = RegMaskSlots.size();
|
||||
|
||||
@ -210,7 +206,7 @@ void LiveIntervals::computeRegMasks() {
|
||||
RegMaskBits.push_back(Mask);
|
||||
}
|
||||
|
||||
for (MachineInstr &MI : MBB) {
|
||||
for (const MachineInstr &MI : MBB) {
|
||||
for (const MachineOperand &MO : MI.operands()) {
|
||||
if (!MO.isRegMask())
|
||||
continue;
|
||||
@ -245,9 +241,9 @@ void LiveIntervals::computeRegMasks() {
|
||||
// interference.
|
||||
//
|
||||
|
||||
/// computeRegUnitInterval - Compute the live range of a register unit, based
|
||||
/// on the uses and defs of aliasing registers. The range should be empty,
|
||||
/// or contain only dead phi-defs from ABI blocks.
|
||||
/// Compute the live range of a register unit, based on the uses and defs of
|
||||
/// aliasing registers. The range should be empty, or contain only dead
|
||||
/// phi-defs from ABI blocks.
|
||||
void LiveIntervals::computeRegUnitRange(LiveRange &LR, unsigned Unit) {
|
||||
assert(LRCalc && "LRCalc not initialized.");
|
||||
LRCalc->reset(MF, getSlotIndexes(), DomTree, &getVNInfoAllocator());
|
||||
@ -257,20 +253,21 @@ void LiveIntervals::computeRegUnitRange(LiveRange &LR, unsigned Unit) {
|
||||
// may share super-registers. That's OK because createDeadDefs() is
|
||||
// idempotent. It is very rare for a register unit to have multiple roots, so
|
||||
// uniquing super-registers is probably not worthwhile.
|
||||
for (MCRegUnitRootIterator Roots(Unit, TRI); Roots.isValid(); ++Roots) {
|
||||
for (MCSuperRegIterator Supers(*Roots, TRI, /*IncludeSelf=*/true);
|
||||
Supers.isValid(); ++Supers) {
|
||||
if (!MRI->reg_empty(*Supers))
|
||||
LRCalc->createDeadDefs(LR, *Supers);
|
||||
for (MCRegUnitRootIterator Root(Unit, TRI); Root.isValid(); ++Root) {
|
||||
for (MCSuperRegIterator Super(*Root, TRI, /*IncludeSelf=*/true);
|
||||
Super.isValid(); ++Super) {
|
||||
unsigned Reg = *Super;
|
||||
if (!MRI->reg_empty(Reg))
|
||||
LRCalc->createDeadDefs(LR, Reg);
|
||||
}
|
||||
}
|
||||
|
||||
// Now extend LR to reach all uses.
|
||||
// Ignore uses of reserved registers. We only track defs of those.
|
||||
for (MCRegUnitRootIterator Roots(Unit, TRI); Roots.isValid(); ++Roots) {
|
||||
for (MCSuperRegIterator Supers(*Roots, TRI, /*IncludeSelf=*/true);
|
||||
Supers.isValid(); ++Supers) {
|
||||
unsigned Reg = *Supers;
|
||||
for (MCRegUnitRootIterator Root(Unit, TRI); Root.isValid(); ++Root) {
|
||||
for (MCSuperRegIterator Super(*Root, TRI, /*IncludeSelf=*/true);
|
||||
Super.isValid(); ++Super) {
|
||||
unsigned Reg = *Super;
|
||||
if (!MRI->isReserved(Reg) && !MRI->reg_empty(Reg))
|
||||
LRCalc->extendToUses(LR, Reg);
|
||||
}
|
||||
@ -281,11 +278,9 @@ void LiveIntervals::computeRegUnitRange(LiveRange &LR, unsigned Unit) {
|
||||
LR.flushSegmentSet();
|
||||
}
|
||||
|
||||
|
||||
/// computeLiveInRegUnits - Precompute the live ranges of any register units
|
||||
/// that are live-in to an ABI block somewhere. Register values can appear
|
||||
/// without a corresponding def when entering the entry block or a landing pad.
|
||||
///
|
||||
/// Precompute the live ranges of any register units that are live-in to an ABI
|
||||
/// block somewhere. Register values can appear without a corresponding def when
|
||||
/// entering the entry block or a landing pad.
|
||||
void LiveIntervals::computeLiveInRegUnits() {
|
||||
RegUnitRanges.resize(TRI->getNumRegUnits());
|
||||
DEBUG(dbgs() << "Computing live-in reg-units in ABI blocks.\n");
|
||||
@ -294,18 +289,15 @@ void LiveIntervals::computeLiveInRegUnits() {
|
||||
SmallVector<unsigned, 8> NewRanges;
|
||||
|
||||
// Check all basic blocks for live-ins.
|
||||
for (MachineFunction::const_iterator MFI = MF->begin(), MFE = MF->end();
|
||||
MFI != MFE; ++MFI) {
|
||||
const MachineBasicBlock *MBB = &*MFI;
|
||||
|
||||
for (const MachineBasicBlock &MBB : *MF) {
|
||||
// We only care about ABI blocks: Entry + landing pads.
|
||||
if ((MFI != MF->begin() && !MBB->isEHPad()) || MBB->livein_empty())
|
||||
if ((&MBB != &MF->front() && !MBB.isEHPad()) || MBB.livein_empty())
|
||||
continue;
|
||||
|
||||
// Create phi-defs at Begin for all live-in registers.
|
||||
SlotIndex Begin = Indexes->getMBBStartIdx(MBB);
|
||||
DEBUG(dbgs() << Begin << "\tBB#" << MBB->getNumber());
|
||||
for (const auto &LI : MBB->liveins()) {
|
||||
SlotIndex Begin = Indexes->getMBBStartIdx(&MBB);
|
||||
DEBUG(dbgs() << Begin << "\tBB#" << MBB.getNumber());
|
||||
for (const auto &LI : MBB.liveins()) {
|
||||
for (MCRegUnitIterator Units(LI.PhysReg, TRI); Units.isValid(); ++Units) {
|
||||
unsigned Unit = *Units;
|
||||
LiveRange *LR = RegUnitRanges[Unit];
|
||||
@ -324,16 +316,13 @@ void LiveIntervals::computeLiveInRegUnits() {
|
||||
DEBUG(dbgs() << "Created " << NewRanges.size() << " new intervals.\n");
|
||||
|
||||
// Compute the 'normal' part of the ranges.
|
||||
for (unsigned i = 0, e = NewRanges.size(); i != e; ++i) {
|
||||
unsigned Unit = NewRanges[i];
|
||||
for (unsigned Unit : NewRanges)
|
||||
computeRegUnitRange(*RegUnitRanges[Unit], Unit);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void createSegmentsForValues(LiveRange &LR,
|
||||
iterator_range<LiveInterval::vni_iterator> VNIs) {
|
||||
for (auto VNI : VNIs) {
|
||||
iterator_range<LiveInterval::vni_iterator> VNIs) {
|
||||
for (VNInfo *VNI : VNIs) {
|
||||
if (VNI->isUnused())
|
||||
continue;
|
||||
SlotIndex Def = VNI->def;
|
||||
@ -349,7 +338,7 @@ static void extendSegmentsToUses(LiveRange &LR, const SlotIndexes &Indexes,
|
||||
// Keep track of the PHIs that are in use.
|
||||
SmallPtrSet<VNInfo*, 8> UsedPHIs;
|
||||
// Blocks that have already been added to WorkList as live-out.
|
||||
SmallPtrSet<MachineBasicBlock*, 16> LiveOut;
|
||||
SmallPtrSet<const MachineBasicBlock*, 16> LiveOut;
|
||||
|
||||
// Extend intervals to reach all uses in WorkList.
|
||||
while (!WorkList.empty()) {
|
||||
@ -368,7 +357,7 @@ static void extendSegmentsToUses(LiveRange &LR, const SlotIndexes &Indexes,
|
||||
!UsedPHIs.insert(VNI).second)
|
||||
continue;
|
||||
// The PHI is live, make sure the predecessors are live-out.
|
||||
for (auto &Pred : MBB->predecessors()) {
|
||||
for (const MachineBasicBlock *Pred : MBB->predecessors()) {
|
||||
if (!LiveOut.insert(Pred).second)
|
||||
continue;
|
||||
SlotIndex Stop = Indexes.getMBBEndIdx(Pred);
|
||||
@ -384,7 +373,7 @@ static void extendSegmentsToUses(LiveRange &LR, const SlotIndexes &Indexes,
|
||||
LR.addSegment(LiveRange::Segment(BlockStart, Idx, VNI));
|
||||
|
||||
// Make sure VNI is live-out from the predecessors.
|
||||
for (auto &Pred : MBB->predecessors()) {
|
||||
for (const MachineBasicBlock *Pred : MBB->predecessors()) {
|
||||
if (!LiveOut.insert(Pred).second)
|
||||
continue;
|
||||
SlotIndex Stop = Indexes.getMBBEndIdx(Pred);
|
||||
@ -415,22 +404,20 @@ bool LiveIntervals::shrinkToUses(LiveInterval *li,
|
||||
ShrinkToUsesWorkList WorkList;
|
||||
|
||||
// Visit all instructions reading li->reg.
|
||||
for (MachineRegisterInfo::reg_instr_iterator
|
||||
I = MRI->reg_instr_begin(li->reg), E = MRI->reg_instr_end();
|
||||
I != E; ) {
|
||||
MachineInstr *UseMI = &*(I++);
|
||||
if (UseMI->isDebugValue() || !UseMI->readsVirtualRegister(li->reg))
|
||||
unsigned Reg = li->reg;
|
||||
for (MachineInstr &UseMI : MRI->reg_instructions(Reg)) {
|
||||
if (UseMI.isDebugValue() || !UseMI.readsVirtualRegister(Reg))
|
||||
continue;
|
||||
SlotIndex Idx = getInstructionIndex(*UseMI).getRegSlot();
|
||||
SlotIndex Idx = getInstructionIndex(UseMI).getRegSlot();
|
||||
LiveQueryResult LRQ = li->Query(Idx);
|
||||
VNInfo *VNI = LRQ.valueIn();
|
||||
if (!VNI) {
|
||||
// This shouldn't happen: readsVirtualRegister returns true, but there is
|
||||
// no live value. It is likely caused by a target getting <undef> flags
|
||||
// wrong.
|
||||
DEBUG(dbgs() << Idx << '\t' << *UseMI
|
||||
DEBUG(dbgs() << Idx << '\t' << UseMI
|
||||
<< "Warning: Instr claims to read non-existent value in "
|
||||
<< *li << '\n');
|
||||
<< *li << '\n');
|
||||
continue;
|
||||
}
|
||||
// Special case: An early-clobber tied operand reads and writes the
|
||||
@ -458,7 +445,7 @@ bool LiveIntervals::shrinkToUses(LiveInterval *li,
|
||||
bool LiveIntervals::computeDeadValues(LiveInterval &LI,
|
||||
SmallVectorImpl<MachineInstr*> *dead) {
|
||||
bool MayHaveSplitComponents = false;
|
||||
for (auto VNI : LI.valnos) {
|
||||
for (VNInfo *VNI : LI.valnos) {
|
||||
if (VNI->isUnused())
|
||||
continue;
|
||||
SlotIndex Def = VNI->def;
|
||||
@ -548,7 +535,7 @@ void LiveIntervals::shrinkToUses(LiveInterval::SubRange &SR, unsigned Reg) {
|
||||
SR.segments.swap(NewLR.segments);
|
||||
|
||||
// Remove dead PHI value numbers
|
||||
for (auto VNI : SR.valnos) {
|
||||
for (VNInfo *VNI : SR.valnos) {
|
||||
if (VNI->isUnused())
|
||||
continue;
|
||||
const LiveRange::Segment *Segment = SR.getSegmentContaining(VNI->def);
|
||||
@ -571,8 +558,8 @@ void LiveIntervals::extendToIndices(LiveRange &LR,
|
||||
ArrayRef<SlotIndex> Undefs) {
|
||||
assert(LRCalc && "LRCalc not initialized.");
|
||||
LRCalc->reset(MF, getSlotIndexes(), DomTree, &getVNInfoAllocator());
|
||||
for (unsigned i = 0, e = Indices.size(); i != e; ++i)
|
||||
LRCalc->extend(LR, Indices[i], /*PhysReg=*/0, Undefs);
|
||||
for (SlotIndex Idx : Indices)
|
||||
LRCalc->extend(LR, Idx, /*PhysReg=*/0, Undefs);
|
||||
}
|
||||
|
||||
void LiveIntervals::pruneValue(LiveRange &LR, SlotIndex Kill,
|
||||
@ -601,11 +588,9 @@ void LiveIntervals::pruneValue(LiveRange &LR, SlotIndex Kill,
|
||||
// from each successor.
|
||||
typedef df_iterator_default_set<MachineBasicBlock*,9> VisitedTy;
|
||||
VisitedTy Visited;
|
||||
for (MachineBasicBlock::succ_iterator
|
||||
SuccI = KillMBB->succ_begin(), SuccE = KillMBB->succ_end();
|
||||
SuccI != SuccE; ++SuccI) {
|
||||
for (MachineBasicBlock *Succ : KillMBB->successors()) {
|
||||
for (df_ext_iterator<MachineBasicBlock*, VisitedTy>
|
||||
I = df_ext_begin(*SuccI, Visited), E = df_ext_end(*SuccI, Visited);
|
||||
I = df_ext_begin(Succ, Visited), E = df_ext_end(Succ, Visited);
|
||||
I != E;) {
|
||||
MachineBasicBlock *MBB = *I;
|
||||
|
||||
@ -657,9 +642,9 @@ void LiveIntervals::addKillFlags(const VirtRegMap *VRM) {
|
||||
// Find the regunit intervals for the assigned register. They may overlap
|
||||
// the virtual register live range, cancelling any kills.
|
||||
RU.clear();
|
||||
for (MCRegUnitIterator Units(VRM->getPhys(Reg), TRI); Units.isValid();
|
||||
++Units) {
|
||||
const LiveRange &RURange = getRegUnit(*Units);
|
||||
for (MCRegUnitIterator Unit(VRM->getPhys(Reg), TRI); Unit.isValid();
|
||||
++Unit) {
|
||||
const LiveRange &RURange = getRegUnit(*Unit);
|
||||
if (RURange.empty())
|
||||
continue;
|
||||
RU.push_back(std::make_pair(&RURange, RURange.find(LI.begin()->end)));
|
||||
@ -802,9 +787,8 @@ LiveIntervals::hasPHIKill(const LiveInterval &LI, const VNInfo *VNI) const {
|
||||
// Conservatively return true instead of scanning huge predecessor lists.
|
||||
if (PHIMBB->pred_size() > 100)
|
||||
return true;
|
||||
for (MachineBasicBlock::const_pred_iterator
|
||||
PI = PHIMBB->pred_begin(), PE = PHIMBB->pred_end(); PI != PE; ++PI)
|
||||
if (VNI == LI.getVNInfoBefore(Indexes->getMBBEndIdx(*PI)))
|
||||
for (const MachineBasicBlock *Pred : PHIMBB->predecessors())
|
||||
if (VNI == LI.getVNInfoBefore(Indexes->getMBBEndIdx(Pred)))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -895,7 +879,7 @@ bool LiveIntervals::checkRegMaskInterference(LiveInterval &LI,
|
||||
// IntervalUpdate class.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// HMEditor is a toolkit used by handleMove to trim or extend live intervals.
|
||||
/// Toolkit used by handleMove to trim or extend live intervals.
|
||||
class LiveIntervals::HMEditor {
|
||||
private:
|
||||
LiveIntervals& LIS;
|
||||
@ -1514,8 +1498,7 @@ LiveIntervals::repairIntervalsInRange(MachineBasicBlock *MBB,
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned i = 0, e = OrigRegs.size(); i != e; ++i) {
|
||||
unsigned Reg = OrigRegs[i];
|
||||
for (unsigned Reg : OrigRegs) {
|
||||
if (!TargetRegisterInfo::isVirtualRegister(Reg))
|
||||
continue;
|
||||
|
||||
@ -1524,16 +1507,16 @@ LiveIntervals::repairIntervalsInRange(MachineBasicBlock *MBB,
|
||||
if (!LI.hasAtLeastOneValue())
|
||||
continue;
|
||||
|
||||
for (LiveInterval::SubRange &S : LI.subranges()) {
|
||||
for (LiveInterval::SubRange &S : LI.subranges())
|
||||
repairOldRegInRange(Begin, End, endIdx, S, Reg, S.LaneMask);
|
||||
}
|
||||
|
||||
repairOldRegInRange(Begin, End, endIdx, LI, Reg);
|
||||
}
|
||||
}
|
||||
|
||||
void LiveIntervals::removePhysRegDefAt(unsigned Reg, SlotIndex Pos) {
|
||||
for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) {
|
||||
if (LiveRange *LR = getCachedRegUnit(*Units))
|
||||
for (MCRegUnitIterator Unit(Reg, TRI); Unit.isValid(); ++Unit) {
|
||||
if (LiveRange *LR = getCachedRegUnit(*Unit))
|
||||
if (VNInfo *VNI = LR->getVNInfoAt(Pos))
|
||||
LR->removeValNo(VNI);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user