#ifndef LLVM_CODEGEN_LIVEINTERVAL_ANALYSIS_H
#define LLVM_CODEGEN_LIVEINTERVAL_ANALYSIS_H
-#include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/ADT/IndexedMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/LiveInterval.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/LiveInterval.h"
#include "llvm/CodeGen/SlotIndexes.h"
-#include "llvm/ADT/BitVector.h"
-#include "llvm/ADT/IndexedMap.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Allocator.h"
+#include "llvm/Target/TargetRegisterInfo.h"
#include <cmath>
#include <iterator>
namespace llvm {
class AliasAnalysis;
+ class BitVector;
+ class BlockFrequency;
class LiveRangeCalc;
class LiveVariables;
class MachineDominatorTree;
class TargetInstrInfo;
class TargetRegisterClass;
class VirtRegMap;
+ class MachineBlockFrequencyInfo;
class LiveIntervals : public MachineFunctionPass {
MachineFunction* MF;
const TargetRegisterInfo* TRI;
const TargetInstrInfo* TII;
AliasAnalysis *AA;
- LiveVariables* LV;
SlotIndexes* Indexes;
MachineDominatorTree *DomTree;
LiveRangeCalc *LRCalc;
/// 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
virtual ~LiveIntervals();
// Calculate the spill weight to assign to a single instruction.
- static float getSpillWeight(bool isDef, bool isUse, unsigned loopDepth);
+ static float getSpillWeight(bool isDef, bool isUse,
+ const MachineBlockFrequencyInfo *MBFI,
+ const MachineInstr *Instr);
LiveInterval &getInterval(unsigned Reg) {
- LiveInterval *LI = VirtRegIntervals[Reg];
- assert(LI && "Interval does not exist for virtual register");
- return *LI;
+ if (hasInterval(Reg))
+ return *VirtRegIntervals[Reg];
+ else
+ return createAndComputeVirtRegInterval(Reg);
}
const LiveInterval &getInterval(unsigned Reg) const {
}
// Interval creation.
- LiveInterval &getOrCreateInterval(unsigned Reg) {
- if (!hasInterval(Reg)) {
- VirtRegIntervals.grow(Reg);
- VirtRegIntervals[Reg] = createInterval(Reg);
- }
- return getInterval(Reg);
+ LiveInterval &createEmptyInterval(unsigned Reg) {
+ assert(!hasInterval(Reg) && "Interval already exists!");
+ VirtRegIntervals.grow(Reg);
+ VirtRegIntervals[Reg] = createInterval(Reg);
+ return *VirtRegIntervals[Reg];
+ }
+
+ LiveInterval &createAndComputeVirtRegInterval(unsigned Reg) {
+ LiveInterval &LI = createEmptyInterval(Reg);
+ computeVirtRegInterval(LI);
+ return LI;
}
// Interval removal.
VirtRegIntervals[Reg] = 0;
}
- /// addLiveRangeToEndOfBlock - Given a register and an instruction,
- /// adds a live range from that instruction to the end of its MBB.
- LiveRange addLiveRangeToEndOfBlock(unsigned reg,
- MachineInstr* startInst);
+ /// Given a register and an instruction, adds a live segment from that
+ /// instruction to the end of its MBB.
+ 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
/// 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
return Indexes->getMBBEndIdx(mbb);
}
- bool isLiveInToMBB(const LiveInterval &li,
+ bool isLiveInToMBB(const LiveRange &LR,
const MachineBasicBlock *mbb) const {
- return li.liveAt(getMBBStartIdx(mbb));
+ return LR.liveAt(getMBBStartIdx(mbb));
}
- bool isLiveOutOfMBB(const LiveInterval &li,
+ bool isLiveOutOfMBB(const LiveRange &LR,
const MachineBasicBlock *mbb) const {
- return li.liveAt(getMBBEndIdx(mbb).getPrevSlot());
+ return LR.liveAt(getMBBEndIdx(mbb).getPrevSlot());
}
MachineBasicBlock* getMBBFromIndex(SlotIndex index) const {
return Indexes->getMBBFromIndex(index);
}
+ void insertMBBInMaps(MachineBasicBlock *MBB) {
+ Indexes->insertMBBInMaps(MBB);
+ assert(unsigned(MBB->getNumber()) == RegMaskBlocks.size() &&
+ "Blocks must be added in order.");
+ RegMaskBlocks.push_back(std::make_pair(RegMaskSlots.size(), 0));
+ }
+
SlotIndex InsertMachineInstrInMaps(MachineInstr *MI) {
return Indexes->insertMachineInstrInMaps(MI);
}
+ void InsertMachineInstrRangeInMaps(MachineBasicBlock::iterator B,
+ MachineBasicBlock::iterator E) {
+ for (MachineBasicBlock::iterator I = B; I != E; ++I)
+ Indexes->insertMachineInstrInMaps(I);
+ }
+
void RemoveMachineInstrFromMaps(MachineInstr *MI) {
Indexes->removeMachineInstrFromMaps(MI);
}
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.
+ ///
+ /// OrigRegs is a vector of registers that were originally used by the
+ /// instructions in the range between the two iterators.
+ ///
+ /// Currently, the only only changes that are supported are simple removal
+ /// and addition of uses.
+ void repairIntervalsInRange(MachineBasicBlock *MBB,
+ MachineBasicBlock::iterator Begin,
+ MachineBasicBlock::iterator End,
+ ArrayRef<unsigned> OrigRegs);
+
// Register mask functions.
//
// Machine instructions may use a register mask operand to indicate that a
/// 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);
+ RegUnitRanges[Unit] = LR = new LiveRange();
+ 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];
}
- private:
- /// computeIntervals - Compute live intervals.
- void computeIntervals();
+ const LiveRange *getCachedRegUnit(unsigned Unit) const {
+ return RegUnitRanges[Unit];
+ }
+ private:
/// Compute live intervals for all virtual registers.
void computeVirtRegs();
/// Compute RegMaskSlots and RegMaskBits.
void computeRegMasks();
- /// handleRegisterDef - update intervals for a register def
- /// (calls handleVirtualRegisterDef)
- void handleRegisterDef(MachineBasicBlock *MBB,
- MachineBasicBlock::iterator MI,
- SlotIndex MIIdx,
- MachineOperand& MO, unsigned MOIdx);
-
- /// isPartialRedef - Return true if the specified def at the specific index
- /// is partially re-defining the specified live interval. A common case of
- /// this is a definition of the sub-register.
- bool isPartialRedef(SlotIndex MIIdx, MachineOperand &MO,
- LiveInterval &interval);
-
- /// handleVirtualRegisterDef - update intervals for a virtual
- /// register def
- void handleVirtualRegisterDef(MachineBasicBlock *MBB,
- MachineBasicBlock::iterator MI,
- SlotIndex MIIdx, MachineOperand& MO,
- unsigned MOIdx,
- LiveInterval& interval);
-
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&);
class HMEditor;
};