//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CODEGEN_LIVEINTERVAL_ANALYSIS_H
-#define LLVM_CODEGEN_LIVEINTERVAL_ANALYSIS_H
+#ifndef LLVM_CODEGEN_LIVEINTERVALANALYSIS_H
+#define LLVM_CODEGEN_LIVEINTERVALANALYSIS_H
#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/SmallVector.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 {
+extern cl::opt<bool> UseSegmentSetForPhysRegs;
+
class AliasAnalysis;
class BitVector;
class BlockFrequency;
class TargetInstrInfo;
class TargetRegisterClass;
class VirtRegMap;
+ class MachineBlockFrequencyInfo;
class LiveIntervals : public MachineFunctionPass {
MachineFunction* MF;
MachineRegisterInfo* MRI;
- const TargetMachine* TM;
const TargetRegisterInfo* TRI;
const TargetInstrInfo* TII;
AliasAnalysis *AA;
/// block.
SmallVector<std::pair<unsigned, unsigned>, 8> RegMaskBlocks;
- /// RegUnitIntervals - Keep a live interval for each register unit as a way
- /// of tracking fixed physreg interference.
- SmallVector<LiveInterval*, 0> RegUnitIntervals;
+ /// Keeps a live range set for each register unit to track fixed physreg
+ /// interference.
+ SmallVector<LiveRange*, 0> RegUnitRanges;
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, BlockFrequency freq);
+ static float getSpillWeight(bool isDef, bool isUse,
+ const MachineBlockFrequencyInfo *MBFI,
+ const MachineInstr *Instr);
LiveInterval &getInterval(unsigned Reg) {
if (hasInterval(Reg))
LiveInterval &createAndComputeVirtRegInterval(unsigned Reg) {
LiveInterval &LI = createEmptyInterval(Reg);
- computeVirtRegInterval(&LI);
+ computeVirtRegInterval(LI);
return LI;
}
// Interval removal.
void removeInterval(unsigned Reg) {
delete VirtRegIntervals[Reg];
- VirtRegIntervals[Reg] = 0;
+ VirtRegIntervals[Reg] = nullptr;
}
/// Given a register and an instruction, adds a live segment from that
/// Return true if the interval may have been separated into multiple
/// connected components.
bool shrinkToUses(LiveInterval *li,
- SmallVectorImpl<MachineInstr*> *dead = 0);
+ 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.
+ 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
/// extended to be live out of the basic block.
///
/// See also LiveRangeCalc::extend().
- void extendToIndices(LiveInterval *LI, ArrayRef<SlotIndex> Indices);
+ 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 {
VNInfo::Allocator& getVNInfoAllocator() { return VNInfoAllocator; }
- virtual void getAnalysisUsage(AnalysisUsage &AU) const;
- virtual void releaseMemory();
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+ void releaseMemory() override;
/// runOnMachineFunction - pass entry point
- virtual bool runOnMachineFunction(MachineFunction&);
+ bool runOnMachineFunction(MachineFunction&) override;
/// print - Implement the dump method.
- virtual void print(raw_ostream &O, const Module* = 0) const;
+ 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,
/// getRegUnit - Return the live range for Unit.
/// It will be computed if it doesn't exist.
- LiveInterval &getRegUnit(unsigned Unit) {
- LiveInterval *LI = RegUnitIntervals[Unit];
- if (!LI) {
+ LiveRange &getRegUnit(unsigned Unit) {
+ LiveRange *LR = RegUnitRanges[Unit];
+ if (!LR) {
// Compute missing ranges on demand.
- RegUnitIntervals[Unit] = LI = new LiveInterval(Unit, HUGE_VALF);
- computeRegUnitInterval(LI);
+ // Use segment set to speed-up initial computation of the live range.
+ RegUnitRanges[Unit] = LR = new LiveRange(UseSegmentSetForPhysRegs);
+ computeRegUnitRange(*LR, Unit);
}
- return *LI;
+ return *LR;
}
/// getCachedRegUnit - Return the live range for Unit if it has already
/// been computed, or NULL if it hasn't been computed yet.
- LiveInterval *getCachedRegUnit(unsigned Unit) {
- return RegUnitIntervals[Unit];
+ LiveRange *getCachedRegUnit(unsigned Unit) {
+ return RegUnitRanges[Unit];
}
- const LiveInterval *getCachedRegUnit(unsigned Unit) const {
- return RegUnitIntervals[Unit];
+ const LiveRange *getCachedRegUnit(unsigned Unit) const {
+ 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);
+
private:
/// Compute live intervals for all virtual registers.
void computeVirtRegs();
/// Compute RegMaskSlots and RegMaskBits.
void computeRegMasks();
+ /// 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
+ /// 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 printInstrs(raw_ostream &O) const;
void dumpInstrs() const;
void computeLiveInRegUnits();
- void computeRegUnitInterval(LiveInterval*);
- void computeVirtRegInterval(LiveInterval*);
+ void computeRegUnitRange(LiveRange&, unsigned Unit);
+ void computeVirtRegInterval(LiveInterval&);
+
+
+ /// 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
+ /// are considered.
+ void repairOldRegInRange(MachineBasicBlock::iterator Begin,
+ MachineBasicBlock::iterator End,
+ const SlotIndex endIdx, LiveRange &LR,
+ unsigned Reg, unsigned LaneMask = ~0u);
class HMEditor;
};