Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

247 lines
9.2 KiB

  1. //==- ScheduleDAGInstrs.h - MachineInstr Scheduling --------------*- C++ -*-==//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file implements the ScheduleDAGInstrs class, which implements
  11. // scheduling for a MachineInstr-based dependency graph.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #ifndef LLVM_CODEGEN_SCHEDULEDAGINSTRS_H
  15. #define LLVM_CODEGEN_SCHEDULEDAGINSTRS_H
  16. #include "llvm/ADT/SparseSet.h"
  17. #include "llvm/ADT/SparseMultiSet.h"
  18. #include "llvm/CodeGen/ScheduleDAG.h"
  19. #include "llvm/CodeGen/TargetSchedule.h"
  20. #include "llvm/Support/Compiler.h"
  21. #include "llvm/Target/TargetRegisterInfo.h"
  22. namespace llvm {
  23. class MachineFrameInfo;
  24. class MachineLoopInfo;
  25. class MachineDominatorTree;
  26. class LiveIntervals;
  27. class RegPressureTracker;
  28. /// An individual mapping from virtual register number to SUnit.
  29. struct VReg2SUnit {
  30. unsigned VirtReg;
  31. SUnit *SU;
  32. VReg2SUnit(unsigned reg, SUnit *su): VirtReg(reg), SU(su) {}
  33. unsigned getSparseSetIndex() const {
  34. return TargetRegisterInfo::virtReg2Index(VirtReg);
  35. }
  36. };
  37. /// Record a physical register access.
  38. /// For non data-dependent uses, OpIdx == -1.
  39. struct PhysRegSUOper {
  40. SUnit *SU;
  41. int OpIdx;
  42. unsigned Reg;
  43. PhysRegSUOper(SUnit *su, int op, unsigned R): SU(su), OpIdx(op), Reg(R) {}
  44. unsigned getSparseSetIndex() const { return Reg; }
  45. };
  46. /// Use a SparseMultiSet to track physical registers. Storage is only
  47. /// allocated once for the pass. It can be cleared in constant time and reused
  48. /// without any frees.
  49. typedef SparseMultiSet<PhysRegSUOper, llvm::identity<unsigned>, uint16_t> Reg2SUnitsMap;
  50. /// Use SparseSet as a SparseMap by relying on the fact that it never
  51. /// compares ValueT's, only unsigned keys. This allows the set to be cleared
  52. /// between scheduling regions in constant time as long as ValueT does not
  53. /// require a destructor.
  54. typedef SparseSet<VReg2SUnit, VirtReg2IndexFunctor> VReg2SUnitMap;
  55. /// ScheduleDAGInstrs - A ScheduleDAG subclass for scheduling lists of
  56. /// MachineInstrs.
  57. class ScheduleDAGInstrs : public ScheduleDAG {
  58. protected:
  59. const MachineLoopInfo &MLI;
  60. const MachineDominatorTree &MDT;
  61. const MachineFrameInfo *MFI;
  62. /// Live Intervals provides reaching defs in preRA scheduling.
  63. LiveIntervals *LIS;
  64. /// TargetSchedModel provides an interface to the machine model.
  65. TargetSchedModel SchedModel;
  66. /// isPostRA flag indicates vregs cannot be present.
  67. bool IsPostRA;
  68. /// UnitLatencies (misnamed) flag avoids computing def-use latencies, using
  69. /// the def-side latency only.
  70. bool UnitLatencies;
  71. /// The standard DAG builder does not normally include terminators as DAG
  72. /// nodes because it does not create the necessary dependencies to prevent
  73. /// reordering. A specialized scheduler can overide
  74. /// TargetInstrInfo::isSchedulingBoundary then enable this flag to indicate
  75. /// it has taken responsibility for scheduling the terminator correctly.
  76. bool CanHandleTerminators;
  77. /// State specific to the current scheduling region.
  78. /// ------------------------------------------------
  79. /// The block in which to insert instructions
  80. MachineBasicBlock *BB;
  81. /// The beginning of the range to be scheduled.
  82. MachineBasicBlock::iterator RegionBegin;
  83. /// The end of the range to be scheduled.
  84. MachineBasicBlock::iterator RegionEnd;
  85. /// The index in BB of RegionEnd.
  86. unsigned EndIndex;
  87. /// After calling BuildSchedGraph, each machine instruction in the current
  88. /// scheduling region is mapped to an SUnit.
  89. DenseMap<MachineInstr*, SUnit*> MISUnitMap;
  90. /// State internal to DAG building.
  91. /// -------------------------------
  92. /// Defs, Uses - Remember where defs and uses of each register are as we
  93. /// iterate upward through the instructions. This is allocated here instead
  94. /// of inside BuildSchedGraph to avoid the need for it to be initialized and
  95. /// destructed for each block.
  96. Reg2SUnitsMap Defs;
  97. Reg2SUnitsMap Uses;
  98. /// Track the last instructon in this region defining each virtual register.
  99. VReg2SUnitMap VRegDefs;
  100. /// PendingLoads - Remember where unknown loads are after the most recent
  101. /// unknown store, as we iterate. As with Defs and Uses, this is here
  102. /// to minimize construction/destruction.
  103. std::vector<SUnit *> PendingLoads;
  104. /// DbgValues - Remember instruction that precedes DBG_VALUE.
  105. /// These are generated by buildSchedGraph but persist so they can be
  106. /// referenced when emitting the final schedule.
  107. typedef std::vector<std::pair<MachineInstr *, MachineInstr *> >
  108. DbgValueVector;
  109. DbgValueVector DbgValues;
  110. MachineInstr *FirstDbgValue;
  111. public:
  112. explicit ScheduleDAGInstrs(MachineFunction &mf,
  113. const MachineLoopInfo &mli,
  114. const MachineDominatorTree &mdt,
  115. bool IsPostRAFlag,
  116. LiveIntervals *LIS = 0);
  117. virtual ~ScheduleDAGInstrs() {}
  118. /// \brief Get the machine model for instruction scheduling.
  119. const TargetSchedModel *getSchedModel() const { return &SchedModel; }
  120. /// \brief Resolve and cache a resolved scheduling class for an SUnit.
  121. const MCSchedClassDesc *getSchedClass(SUnit *SU) const {
  122. if (!SU->SchedClass)
  123. SU->SchedClass = SchedModel.resolveSchedClass(SU->getInstr());
  124. return SU->SchedClass;
  125. }
  126. /// begin - Return an iterator to the top of the current scheduling region.
  127. MachineBasicBlock::iterator begin() const { return RegionBegin; }
  128. /// end - Return an iterator to the bottom of the current scheduling region.
  129. MachineBasicBlock::iterator end() const { return RegionEnd; }
  130. /// newSUnit - Creates a new SUnit and return a ptr to it.
  131. SUnit *newSUnit(MachineInstr *MI);
  132. /// getSUnit - Return an existing SUnit for this MI, or NULL.
  133. SUnit *getSUnit(MachineInstr *MI) const;
  134. /// startBlock - Prepare to perform scheduling in the given block.
  135. virtual void startBlock(MachineBasicBlock *BB);
  136. /// finishBlock - Clean up after scheduling in the given block.
  137. virtual void finishBlock();
  138. /// Initialize the scheduler state for the next scheduling region.
  139. virtual void enterRegion(MachineBasicBlock *bb,
  140. MachineBasicBlock::iterator begin,
  141. MachineBasicBlock::iterator end,
  142. unsigned endcount);
  143. /// Notify that the scheduler has finished scheduling the current region.
  144. virtual void exitRegion();
  145. /// buildSchedGraph - Build SUnits from the MachineBasicBlock that we are
  146. /// input.
  147. void buildSchedGraph(AliasAnalysis *AA, RegPressureTracker *RPTracker = 0);
  148. /// addSchedBarrierDeps - Add dependencies from instructions in the current
  149. /// list of instructions being scheduled to scheduling barrier. We want to
  150. /// make sure instructions which define registers that are either used by
  151. /// the terminator or are live-out are properly scheduled. This is
  152. /// especially important when the definition latency of the return value(s)
  153. /// are too high to be hidden by the branch or when the liveout registers
  154. /// used by instructions in the fallthrough block.
  155. void addSchedBarrierDeps();
  156. /// schedule - Order nodes according to selected style, filling
  157. /// in the Sequence member.
  158. ///
  159. /// Typically, a scheduling algorithm will implement schedule() without
  160. /// overriding enterRegion() or exitRegion().
  161. virtual void schedule() = 0;
  162. /// finalizeSchedule - Allow targets to perform final scheduling actions at
  163. /// the level of the whole MachineFunction. By default does nothing.
  164. virtual void finalizeSchedule() {}
  165. virtual void dumpNode(const SUnit *SU) const;
  166. /// Return a label for a DAG node that points to an instruction.
  167. virtual std::string getGraphNodeLabel(const SUnit *SU) const;
  168. /// Return a label for the region of code covered by the DAG.
  169. virtual std::string getDAGName() const;
  170. protected:
  171. void initSUnits();
  172. void addPhysRegDataDeps(SUnit *SU, unsigned OperIdx);
  173. void addPhysRegDeps(SUnit *SU, unsigned OperIdx);
  174. void addVRegDefDeps(SUnit *SU, unsigned OperIdx);
  175. void addVRegUseDeps(SUnit *SU, unsigned OperIdx);
  176. };
  177. /// newSUnit - Creates a new SUnit and return a ptr to it.
  178. inline SUnit *ScheduleDAGInstrs::newSUnit(MachineInstr *MI) {
  179. #ifndef NDEBUG
  180. const SUnit *Addr = SUnits.empty() ? 0 : &SUnits[0];
  181. #endif
  182. SUnits.push_back(SUnit(MI, (unsigned)SUnits.size()));
  183. assert((Addr == 0 || Addr == &SUnits[0]) &&
  184. "SUnits std::vector reallocated on the fly!");
  185. SUnits.back().OrigNode = &SUnits.back();
  186. return &SUnits.back();
  187. }
  188. /// getSUnit - Return an existing SUnit for this MI, or NULL.
  189. inline SUnit *ScheduleDAGInstrs::getSUnit(MachineInstr *MI) const {
  190. DenseMap<MachineInstr*, SUnit*>::const_iterator I = MISUnitMap.find(MI);
  191. if (I == MISUnitMap.end())
  192. return 0;
  193. return I->second;
  194. }
  195. } // namespace llvm
  196. #endif