#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/LiveInterval.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/SlotIndexes.h"
#include "llvm/Support/Allocator.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include <cmath>
#include <iterator>
namespace llvm {
- class AliasAnalysis;
+extern cl::opt<bool> UseSegmentSetForPhysRegs;
+
class BitVector;
class BlockFrequency;
class LiveRangeCalc;
public:
static char ID; // Pass identification, replacement for typeid
LiveIntervals();
- virtual ~LiveIntervals();
+ ~LiveIntervals() override;
// Calculate the spill weight to assign to a single instruction.
static float getSpillWeight(bool isDef, bool isUse,
LiveInterval::Segment addSegmentToEndOfBlock(unsigned reg,
MachineInstr* startInst);
- /// shrinkToUses - After removing some uses of a register, shrink its live
- /// range to just the remaining uses. This method does not compute reaching
- /// defs for new uses, and it doesn't remove dead defs.
- /// Dead PHIDef values are marked as unused.
- /// New dead machine instructions are added to the dead vector.
- /// Return true if the interval may have been separated into multiple
- /// connected components.
+ /// After removing some uses of a register, shrink its live range to just
+ /// the remaining uses. This method does not compute reaching defs for new
+ /// uses, and it doesn't remove dead defs.
+ /// Dead PHIDef values are marked as unused. New dead machine instructions
+ /// are added to the dead vector. Returns true if the interval may have been
+ /// separated into multiple connected components.
bool shrinkToUses(LiveInterval *li,
SmallVectorImpl<MachineInstr*> *dead = nullptr);
+ /// Specialized version of
+ /// shrinkToUses(LiveInterval *li, SmallVectorImpl<MachineInstr*> *dead)
+ /// that works on a subregister live range and only looks at uses matching
+ /// the lane mask of the subregister range.
+ /// This may leave the subrange empty which needs to be cleaned up with
+ /// LiveInterval::removeEmptySubranges() afterwards.
+ void shrinkToUses(LiveInterval::SubRange &SR, unsigned Reg);
+
/// extendToIndices - Extend the live range of LI to reach all points in
/// Indices. The points in the Indices array must be jointly dominated by
/// existing defs in LI. PHI-defs are added as needed to maintain SSA form.
/// See also LiveRangeCalc::extend().
void extendToIndices(LiveRange &LR, ArrayRef<SlotIndex> Indices);
- /// pruneValue - If an LI value is live at Kill, prune its live range by
- /// removing any liveness reachable from Kill. Add live range end points to
+
+ /// 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.
///
/// Calling pruneValue() and extendToIndices() can be used to reconstruct
/// SSA form after adding defs to a virtual register.
- void pruneValue(LiveInterval *LI, SlotIndex Kill,
+ void pruneValue(LiveRange &LR, SlotIndex Kill,
SmallVectorImpl<SlotIndex> *EndPoints);
SlotIndexes *getSlotIndexes() const {
Indexes->replaceMachineInstrInMaps(MI, NewMI);
}
- bool findLiveInMBBs(SlotIndex Start, SlotIndex End,
- SmallVectorImpl<MachineBasicBlock*> &MBBs) const {
- return Indexes->findLiveInMBBs(Start, End, MBBs);
- }
-
VNInfo::Allocator& getVNInfoAllocator() { return VNInfoAllocator; }
void getAnalysisUsage(AnalysisUsage &AU) const override;
LiveRange *LR = RegUnitRanges[Unit];
if (!LR) {
// Compute missing ranges on demand.
- RegUnitRanges[Unit] = LR = new LiveRange();
+ // Use segment set to speed-up initial computation of the live range.
+ RegUnitRanges[Unit] = LR = new LiveRange(UseSegmentSetForPhysRegs);
computeRegUnitRange(*LR, Unit);
}
return *LR;
return RegUnitRanges[Unit];
}
+ /// 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
+ /// 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.
+ void removeVRegDefAt(LiveInterval &LI, SlotIndex Pos);
+
+ /// Split separate components in LiveInterval \p LI into separate intervals.
+ void splitSeparateComponents(LiveInterval &LI,
+ SmallVectorImpl<LiveInterval*> &SplitLIs);
+
private:
/// Compute live intervals for all virtual registers.
void computeVirtRegs();
/// Compute RegMaskSlots and RegMaskBits.
void computeRegMasks();
- /// \brief Walk the values in the @p LR live range and compute which ones
- /// are dead in live range @p Segments. Dead values are not deleted,
- /// however:
+ /// Walk the values in @p LI and check for dead values:
/// - Dead PHIDef values are marked as unused.
- /// - if @p dead != nullptr then dead operands are marked as such and
- /// completely dead machine instructions are added to the @p dead vector.
- /// - CanSeparate is set to true if the interval may have been separated
- /// into multiple connected components.
- void computeDeadValues(LiveRange &Segments, LiveRange &LR,
- bool *CanSeparate = nullptr, unsigned Reg = 0,
- SmallVectorImpl<MachineInstr*> *dead = nullptr);
+ /// - Dead operands are marked as such.
+ /// - 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.
+ bool computeDeadValues(LiveInterval &LI,
+ SmallVectorImpl<MachineInstr*> *dead);
static LiveInterval* createInterval(unsigned Reg);
void computeRegUnitRange(LiveRange&, unsigned Unit);
void computeVirtRegInterval(LiveInterval&);
- /// Specialized version of
- /// shrinkToUses(LiveInterval *li, SmallVectorImpl<MachineInstr*> *dead)
- /// that works on a subregister live range and only looks at uses matching
- /// the lane mask of the subregister range.
- bool shrinkToUses(LiveInterval::SubRange &SR, unsigned Reg);
/// Helper function for repairIntervalsInRange(), walks backwards and
/// creates/modifies live segments in @p LR to match the operands found.
void repairOldRegInRange(MachineBasicBlock::iterator Begin,
MachineBasicBlock::iterator End,
const SlotIndex endIdx, LiveRange &LR,
- unsigned Reg, unsigned LaneMask = ~0u);
+ unsigned Reg, LaneBitmask LaneMask = ~0u);
class HMEditor;
};