namespace llvm {
+ class AliasAnalysis;
class LiveVariables;
class MachineLoopInfo;
class TargetRegisterInfo;
const TargetMachine* tm_;
const TargetRegisterInfo* tri_;
const TargetInstrInfo* tii_;
+ AliasAnalysis *aa_;
LiveVariables* lv_;
/// Special pool allocator for VNInfo's (LiveInterval val#).
/// and MBB id.
std::vector<IdxMBBPair> Idx2MBBMap;
+ /// FunctionSize - The number of instructions present in the function
+ uint64_t FunctionSize;
+
typedef std::map<MachineInstr*, unsigned> Mi2IndexMap;
Mi2IndexMap mi2iMap_;
const_iterator end() const { return r2iMap_.end(); }
iterator begin() { return r2iMap_.begin(); }
iterator end() { return r2iMap_.end(); }
- unsigned getNumIntervals() const { return r2iMap_.size(); }
+ unsigned getNumIntervals() const { return (unsigned)r2iMap_.size(); }
LiveInterval &getInterval(unsigned reg) {
Reg2IntervalMap::iterator I = r2iMap_.find(reg);
return MBB2IdxMap[MBBNo].second;
}
+ /// getScaledIntervalSize - get the size of an interval in "units,"
+ /// where every function is composed of one thousand units. This
+ /// measure scales properly with empty index slots in the function.
+ double getScaledIntervalSize(LiveInterval& I) {
+ return (1000.0 / InstrSlots::NUM * I.getSize()) / i2miMap_.size();
+ }
+
+ /// getApproximateInstructionCount - computes an estimate of the number
+ /// of instructions in a given LiveInterval.
+ unsigned getApproximateInstructionCount(LiveInterval& I) {
+ double IntervalPercentage = getScaledIntervalSize(I) / 1000.0;
+ return IntervalPercentage * FunctionSize;
+ }
+
/// getMBBFromIndex - given an index in any instruction of an
/// MBB return a pointer the MBB
MachineBasicBlock* getMBBFromIndex(unsigned index) const {
/// findLiveInMBBs - Given a live range, if the value of the range
/// is live in any MBB returns true as well as the list of basic blocks
- /// where the value is live in.
+ /// in which the value is live.
bool findLiveInMBBs(const LiveRange &LR,
SmallVectorImpl<MachineBasicBlock*> &MBBs) const;
I = r2iMap_.insert(I, std::make_pair(reg, createInterval(reg)));
return I->second;
}
+
+ /// 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);
// Interval removal
}
/// addIntervalsForSpills - Create new intervals for spilled defs / uses of
- /// the given interval.
+ /// the given interval. FIXME: It also returns the weight of the spill slot
+ /// (if any is created) by reference. This is temporary.
std::vector<LiveInterval*>
addIntervalsForSpills(const LiveInterval& i,
- const MachineLoopInfo *loopInfo, VirtRegMap& vrm);
+ const MachineLoopInfo *loopInfo, VirtRegMap& vrm,
+ float &SSWeight);
/// spillPhysRegAroundRegDefsUses - Spill the specified physical register
/// around all defs and uses of the specified interval.
unsigned getNumConflictsWithPhysReg(const LiveInterval &li,
unsigned PhysReg) const;
+ /// computeNumbering - Compute the index numbering.
+ void computeNumbering();
+
private:
/// computeIntervals - Compute live intervals.
void computeIntervals();
/// handleVirtualRegisterDef)
void handleRegisterDef(MachineBasicBlock *MBB,
MachineBasicBlock::iterator MI, unsigned MIIdx,
- unsigned reg);
+ MachineOperand& MO, unsigned MOIdx);
/// handleVirtualRegisterDef - update intervals for a virtual
/// register def
void handleVirtualRegisterDef(MachineBasicBlock *MBB,
MachineBasicBlock::iterator MI,
- unsigned MIIdx,
- LiveInterval& interval);
+ unsigned MIIdx, MachineOperand& MO,
+ unsigned MOIdx, LiveInterval& interval);
/// handlePhysicalRegisterDef - update intervals for a physical register
/// def.
void handlePhysicalRegisterDef(MachineBasicBlock* mbb,
MachineBasicBlock::iterator mi,
- unsigned MIIdx,
+ unsigned MIIdx, MachineOperand& MO,
LiveInterval &interval,
MachineInstr *CopyMI);
BitVector &RestoreMBBs,
std::map<unsigned,std::vector<SRInfo> >&RestoreIdxes);
+ /// handleSpilledImpDefs - Remove IMPLICIT_DEF instructions which are being
+ /// spilled and create empty intervals for their uses.
+ void handleSpilledImpDefs(const LiveInterval &li, VirtRegMap &vrm,
+ const TargetRegisterClass* rc,
+ std::vector<LiveInterval*> &NewLIs);
+
/// rewriteImplicitOps - Rewrite implicit use operands of MI (i.e. uses of
/// interval on to-be re-materialized operands of MI) with new register.
void rewriteImplicitOps(const LiveInterval &li,
SmallVector<int, 4> &ReMatIds, const MachineLoopInfo *loopInfo,
unsigned &NewVReg, unsigned ImpUse, bool &HasDef, bool &HasUse,
std::map<unsigned,unsigned> &MBBVRegsMap,
- std::vector<LiveInterval*> &NewLIs);
+ std::vector<LiveInterval*> &NewLIs, float &SSWeight);
void rewriteInstructionsForSpills(const LiveInterval &li, bool TrySplit,
LiveInterval::Ranges::const_iterator &I,
MachineInstr *OrigDefMI, MachineInstr *DefMI, unsigned Slot, int LdSlot,
BitVector &RestoreMBBs,
std::map<unsigned,std::vector<SRInfo> > &RestoreIdxes,
std::map<unsigned,unsigned> &MBBVRegsMap,
- std::vector<LiveInterval*> &NewLIs);
+ std::vector<LiveInterval*> &NewLIs, float &SSWeight);
static LiveInterval createInterval(unsigned Reg);