class MachineLoopInfo;
class MachineDominatorTree;
class LiveIntervals;
+ class RegPressureTracker;
/// LoopDependencies - This class analyzes loop-oriented register
/// dependencies, which are used to guide scheduling decisions.
/// scheduled as soon as possible after the variable's last use.
///
class LoopDependencies {
- const MachineLoopInfo &MLI;
const MachineDominatorTree &MDT;
public:
LoopDeps;
LoopDeps Deps;
- LoopDependencies(const MachineLoopInfo &mli,
- const MachineDominatorTree &mdt) :
- MLI(mli), MDT(mdt) {}
+ LoopDependencies(const MachineDominatorTree &mdt) : MDT(mdt) {}
/// VisitLoop - Clear out any previous state and analyze the given loop.
///
VReg2SUnit(unsigned reg, SUnit *su): VirtReg(reg), SU(su) {}
- unsigned getSparseSetKey() const {
+ unsigned getSparseSetIndex() const {
return TargetRegisterInfo::virtReg2Index(VirtReg);
}
};
/// compares ValueT's, only unsigned keys. This allows the set to be cleared
/// between scheduling regions in constant time as long as ValueT does not
/// require a destructor.
- typedef SparseSet<VReg2SUnit> VReg2SUnitMap;
+ typedef SparseSet<VReg2SUnit, VirtReg2IndexFunctor> VReg2SUnitMap;
/// ScheduleDAGInstrs - A ScheduleDAG subclass for scheduling lists of
/// MachineInstrs.
/// the def-side latency only.
bool UnitLatencies;
+ /// The standard DAG builder does not normally include terminators as DAG
+ /// nodes because it does not create the necessary dependencies to prevent
+ /// reordering. A specialized scheduler can overide
+ /// TargetInstrInfo::isSchedulingBoundary then enable this flag to indicate
+ /// it has taken responsibility for scheduling the terminator correctly.
+ bool CanHandleTerminators;
+
/// State specific to the current scheduling region.
/// ------------------------------------------------
MachineBasicBlock *BB;
/// The beginning of the range to be scheduled.
- MachineBasicBlock::iterator Begin;
+ MachineBasicBlock::iterator RegionBegin;
/// The end of the range to be scheduled.
- MachineBasicBlock::iterator End;
+ MachineBasicBlock::iterator RegionEnd;
- /// The index in BB of End.
+ /// The index in BB of RegionEnd.
unsigned EndIndex;
/// After calling BuildSchedGraph, each machine instruction in the current
///
LoopDependencies LoopRegs;
- /// DbgValues - Remember instruction that preceeds DBG_VALUE.
+ /// DbgValues - Remember instruction that precedes DBG_VALUE.
/// These are generated by buildSchedGraph but persist so they can be
/// referenced when emitting the final schedule.
typedef std::vector<std::pair<MachineInstr *, MachineInstr *> >
virtual ~ScheduleDAGInstrs() {}
/// begin - Return an iterator to the top of the current scheduling region.
- MachineBasicBlock::iterator begin() const { return Begin; }
+ MachineBasicBlock::iterator begin() const { return RegionBegin; }
/// end - Return an iterator to the bottom of the current scheduling region.
- MachineBasicBlock::iterator end() const { return End; }
+ MachineBasicBlock::iterator end() const { return RegionEnd; }
- /// NewSUnit - Creates a new SUnit and return a ptr to it.
+ /// newSUnit - Creates a new SUnit and return a ptr to it.
SUnit *newSUnit(MachineInstr *MI);
+ /// getSUnit - Return an existing SUnit for this MI, or NULL.
+ SUnit *getSUnit(MachineInstr *MI) const;
+
/// startBlock - Prepare to perform scheduling in the given block.
- ///
virtual void startBlock(MachineBasicBlock *BB);
/// finishBlock - Clean up after scheduling in the given block.
- ///
virtual void finishBlock();
/// Initialize the scheduler state for the next scheduling region.
/// buildSchedGraph - Build SUnits from the MachineBasicBlock that we are
/// input.
- void buildSchedGraph(AliasAnalysis *AA);
+ void buildSchedGraph(AliasAnalysis *AA, RegPressureTracker *RPTracker = 0);
/// addSchedBarrierDeps - Add dependencies from instructions in the current
/// list of instructions being scheduled to scheduling barrier. We want to
///
virtual void computeLatency(SUnit *SU);
- /// computeOperandLatency - Override dependence edge latency using
+ /// computeOperandLatency - Return dependence edge latency using
/// operand use/def information
///
- virtual void computeOperandLatency(SUnit *Def, SUnit *Use,
- SDep& dep) const;
+ /// FindMin may be set to get the minimum vs. expected latency. Minimum
+ /// latency is used for scheduling groups, while expected latency is for
+ /// instruction cost and critical path.
+ virtual unsigned computeOperandLatency(SUnit *Def, SUnit *Use,
+ const SDep& dep,
+ bool FindMin = false) const;
/// schedule - Order nodes according to selected style, filling
/// in the Sequence member.
/// overriding enterRegion() or exitRegion().
virtual void schedule() = 0;
+ /// finalizeSchedule - Allow targets to perform final scheduling actions at
+ /// the level of the whole MachineFunction. By default does nothing.
+ virtual void finalizeSchedule() {}
+
virtual void dumpNode(const SUnit *SU) const;
/// Return a label for a DAG node that points to an instruction.
virtual std::string getDAGName() const;
protected:
- SUnit *getSUnit(MachineInstr *MI) const {
- DenseMap<MachineInstr*, SUnit*>::const_iterator I = MISUnitMap.find(MI);
- if (I == MISUnitMap.end())
- return 0;
- return I->second;
- }
-
void initSUnits();
void addPhysRegDataDeps(SUnit *SU, const MachineOperand &MO);
void addPhysRegDeps(SUnit *SU, unsigned OperIdx);
void addVRegDefDeps(SUnit *SU, unsigned OperIdx);
void addVRegUseDeps(SUnit *SU, unsigned OperIdx);
-
- VReg2SUnitMap::iterator findVRegDef(unsigned VirtReg) {
- return VRegDefs.find(TargetRegisterInfo::virtReg2Index(VirtReg));
- }
};
- /// NewSUnit - Creates a new SUnit and return a ptr to it.
- ///
+ /// newSUnit - Creates a new SUnit and return a ptr to it.
inline SUnit *ScheduleDAGInstrs::newSUnit(MachineInstr *MI) {
#ifndef NDEBUG
const SUnit *Addr = SUnits.empty() ? 0 : &SUnits[0];
SUnits.back().OrigNode = &SUnits.back();
return &SUnits.back();
}
+
+ /// getSUnit - Return an existing SUnit for this MI, or NULL.
+ inline SUnit *ScheduleDAGInstrs::getSUnit(MachineInstr *MI) const {
+ DenseMap<MachineInstr*, SUnit*>::const_iterator I = MISUnitMap.find(MI);
+ if (I == MISUnitMap.end())
+ return 0;
+ return I->second;
+ }
} // namespace llvm
#endif