• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
15 #ifndef LLVM_CODEGEN_SCHEDULEDAGINSTRS_H
16 #define LLVM_CODEGEN_SCHEDULEDAGINSTRS_H
17 
18 #include "llvm/ADT/MapVector.h"
19 #include "llvm/ADT/SparseMultiSet.h"
20 #include "llvm/ADT/SparseSet.h"
21 #include "llvm/CodeGen/ScheduleDAG.h"
22 #include "llvm/CodeGen/TargetSchedule.h"
23 #include "llvm/Support/Compiler.h"
24 #include "llvm/Target/TargetRegisterInfo.h"
25 #include <list>
26 
27 namespace llvm {
28   class MachineFrameInfo;
29   class MachineLoopInfo;
30   class MachineDominatorTree;
31   class RegPressureTracker;
32   class PressureDiffs;
33 
34   /// An individual mapping from virtual register number to SUnit.
35   struct VReg2SUnit {
36     unsigned VirtReg;
37     LaneBitmask LaneMask;
38     SUnit *SU;
39 
VReg2SUnitVReg2SUnit40     VReg2SUnit(unsigned VReg, LaneBitmask LaneMask, SUnit *SU)
41       : VirtReg(VReg), LaneMask(LaneMask), SU(SU) {}
42 
getSparseSetIndexVReg2SUnit43     unsigned getSparseSetIndex() const {
44       return TargetRegisterInfo::virtReg2Index(VirtReg);
45     }
46   };
47 
48   /// Mapping from virtual register to SUnit including an operand index.
49   struct VReg2SUnitOperIdx : public VReg2SUnit {
50     unsigned OperandIndex;
51 
VReg2SUnitOperIdxVReg2SUnitOperIdx52     VReg2SUnitOperIdx(unsigned VReg, LaneBitmask LaneMask,
53                       unsigned OperandIndex, SUnit *SU)
54       : VReg2SUnit(VReg, LaneMask, SU), OperandIndex(OperandIndex) {}
55   };
56 
57   /// Record a physical register access.
58   /// For non-data-dependent uses, OpIdx == -1.
59   struct PhysRegSUOper {
60     SUnit *SU;
61     int OpIdx;
62     unsigned Reg;
63 
PhysRegSUOperPhysRegSUOper64     PhysRegSUOper(SUnit *su, int op, unsigned R): SU(su), OpIdx(op), Reg(R) {}
65 
getSparseSetIndexPhysRegSUOper66     unsigned getSparseSetIndex() const { return Reg; }
67   };
68 
69   /// Use a SparseMultiSet to track physical registers. Storage is only
70   /// allocated once for the pass. It can be cleared in constant time and reused
71   /// without any frees.
72   typedef SparseMultiSet<PhysRegSUOper, llvm::identity<unsigned>, uint16_t>
73   Reg2SUnitsMap;
74 
75   /// Use SparseSet as a SparseMap by relying on the fact that it never
76   /// compares ValueT's, only unsigned keys. This allows the set to be cleared
77   /// between scheduling regions in constant time as long as ValueT does not
78   /// require a destructor.
79   typedef SparseSet<VReg2SUnit, VirtReg2IndexFunctor> VReg2SUnitMap;
80 
81   /// Track local uses of virtual registers. These uses are gathered by the DAG
82   /// builder and may be consulted by the scheduler to avoid iterating an entire
83   /// vreg use list.
84   typedef SparseMultiSet<VReg2SUnit, VirtReg2IndexFunctor> VReg2SUnitMultiMap;
85 
86   typedef SparseMultiSet<VReg2SUnitOperIdx, VirtReg2IndexFunctor>
87     VReg2SUnitOperIdxMultiMap;
88 
89   typedef PointerUnion<const Value *, const PseudoSourceValue *> ValueType;
90   struct UnderlyingObject : PointerIntPair<ValueType, 1, bool> {
UnderlyingObjectUnderlyingObject91     UnderlyingObject(ValueType V, bool MayAlias)
92         : PointerIntPair<ValueType, 1, bool>(V, MayAlias) {}
getValueUnderlyingObject93     ValueType getValue() const { return getPointer(); }
mayAliasUnderlyingObject94     bool mayAlias() const { return getInt(); }
95   };
96   typedef SmallVector<UnderlyingObject, 4> UnderlyingObjectsVector;
97 
98   /// ScheduleDAGInstrs - A ScheduleDAG subclass for scheduling lists of
99   /// MachineInstrs.
100   class ScheduleDAGInstrs : public ScheduleDAG {
101   protected:
102     const MachineLoopInfo *MLI;
103     const MachineFrameInfo *MFI;
104 
105     /// TargetSchedModel provides an interface to the machine model.
106     TargetSchedModel SchedModel;
107 
108     /// True if the DAG builder should remove kill flags (in preparation for
109     /// rescheduling).
110     bool RemoveKillFlags;
111 
112     /// The standard DAG builder does not normally include terminators as DAG
113     /// nodes because it does not create the necessary dependencies to prevent
114     /// reordering. A specialized scheduler can override
115     /// TargetInstrInfo::isSchedulingBoundary then enable this flag to indicate
116     /// it has taken responsibility for scheduling the terminator correctly.
117     bool CanHandleTerminators;
118 
119     /// Whether lane masks should get tracked.
120     bool TrackLaneMasks;
121 
122     /// State specific to the current scheduling region.
123     /// ------------------------------------------------
124 
125     /// The block in which to insert instructions
126     MachineBasicBlock *BB;
127 
128     /// The beginning of the range to be scheduled.
129     MachineBasicBlock::iterator RegionBegin;
130 
131     /// The end of the range to be scheduled.
132     MachineBasicBlock::iterator RegionEnd;
133 
134     /// Instructions in this region (distance(RegionBegin, RegionEnd)).
135     unsigned NumRegionInstrs;
136 
137     /// After calling BuildSchedGraph, each machine instruction in the current
138     /// scheduling region is mapped to an SUnit.
139     DenseMap<MachineInstr*, SUnit*> MISUnitMap;
140 
141     /// After calling BuildSchedGraph, each vreg used in the scheduling region
142     /// is mapped to a set of SUnits. These include all local vreg uses, not
143     /// just the uses for a singly defined vreg.
144     VReg2SUnitMultiMap VRegUses;
145 
146     /// State internal to DAG building.
147     /// -------------------------------
148 
149     /// Defs, Uses - Remember where defs and uses of each register are as we
150     /// iterate upward through the instructions. This is allocated here instead
151     /// of inside BuildSchedGraph to avoid the need for it to be initialized and
152     /// destructed for each block.
153     Reg2SUnitsMap Defs;
154     Reg2SUnitsMap Uses;
155 
156     /// Tracks the last instruction(s) in this region defining each virtual
157     /// register. There may be multiple current definitions for a register with
158     /// disjunct lanemasks.
159     VReg2SUnitMultiMap CurrentVRegDefs;
160     /// Tracks the last instructions in this region using each virtual register.
161     VReg2SUnitOperIdxMultiMap CurrentVRegUses;
162 
163     AliasAnalysis *AAForDep;
164 
165     /// Remember a generic side-effecting instruction as we proceed.
166     /// No other SU ever gets scheduled around it (except in the special
167     /// case of a huge region that gets reduced).
168     SUnit *BarrierChain;
169 
170   public:
171 
172     /// A list of SUnits, used in Value2SUsMap, during DAG construction.
173     /// Note: to gain speed it might be worth investigating an optimized
174     /// implementation of this data structure, such as a singly linked list
175     /// with a memory pool (SmallVector was tried but slow and SparseSet is not
176     /// applicable).
177     typedef std::list<SUnit *> SUList;
178   protected:
179     /// A map from ValueType to SUList, used during DAG construction,
180     /// as a means of remembering which SUs depend on which memory
181     /// locations.
182     class Value2SUsMap;
183 
184     /// Remove in FIFO order some SUs from huge maps.
185     void reduceHugeMemNodeMaps(Value2SUsMap &stores,
186                                Value2SUsMap &loads, unsigned N);
187 
188     /// Add a chain edge between SUa and SUb, but only if both AliasAnalysis
189     /// and Target fail to deny the dependency.
190     void addChainDependency(SUnit *SUa, SUnit *SUb,
191                             unsigned Latency = 0);
192 
193     /// Add dependencies as needed from all SUs in list to SU.
addChainDependencies(SUnit * SU,SUList & sus,unsigned Latency)194     void addChainDependencies(SUnit *SU, SUList &sus, unsigned Latency) {
195       for (auto *su : sus)
196         addChainDependency(SU, su, Latency);
197     }
198 
199     /// Add dependencies as needed from all SUs in map, to SU.
200     void addChainDependencies(SUnit *SU, Value2SUsMap &Val2SUsMap);
201 
202     /// Add dependencies as needed to SU, from all SUs mapped to V.
203     void addChainDependencies(SUnit *SU, Value2SUsMap &Val2SUsMap,
204                               ValueType V);
205 
206     /// Add barrier chain edges from all SUs in map, and then clear
207     /// the map. This is equivalent to insertBarrierChain(), but
208     /// optimized for the common case where the new BarrierChain (a
209     /// global memory object) has a higher NodeNum than all SUs in
210     /// map. It is assumed BarrierChain has been set before calling
211     /// this.
212     void addBarrierChain(Value2SUsMap &map);
213 
214     /// Insert a barrier chain in a huge region, far below current
215     /// SU. Add barrier chain edges from all SUs in map with higher
216     /// NodeNums than this new BarrierChain, and remove them from
217     /// map. It is assumed BarrierChain has been set before calling
218     /// this.
219     void insertBarrierChain(Value2SUsMap &map);
220 
221     /// For an unanalyzable memory access, this Value is used in maps.
222     UndefValue *UnknownValue;
223 
224     /// DbgValues - Remember instruction that precedes DBG_VALUE.
225     /// These are generated by buildSchedGraph but persist so they can be
226     /// referenced when emitting the final schedule.
227     typedef std::vector<std::pair<MachineInstr *, MachineInstr *> >
228       DbgValueVector;
229     DbgValueVector DbgValues;
230     MachineInstr *FirstDbgValue;
231 
232     /// Set of live physical registers for updating kill flags.
233     BitVector LiveRegs;
234 
235   public:
236     explicit ScheduleDAGInstrs(MachineFunction &mf,
237                                const MachineLoopInfo *mli,
238                                bool RemoveKillFlags = false);
239 
~ScheduleDAGInstrs()240     ~ScheduleDAGInstrs() override {}
241 
242     /// \brief Get the machine model for instruction scheduling.
getSchedModel()243     const TargetSchedModel *getSchedModel() const { return &SchedModel; }
244 
245     /// \brief Resolve and cache a resolved scheduling class for an SUnit.
getSchedClass(SUnit * SU)246     const MCSchedClassDesc *getSchedClass(SUnit *SU) const {
247       if (!SU->SchedClass && SchedModel.hasInstrSchedModel())
248         SU->SchedClass = SchedModel.resolveSchedClass(SU->getInstr());
249       return SU->SchedClass;
250     }
251 
252     /// begin - Return an iterator to the top of the current scheduling region.
begin()253     MachineBasicBlock::iterator begin() const { return RegionBegin; }
254 
255     /// end - Return an iterator to the bottom of the current scheduling region.
end()256     MachineBasicBlock::iterator end() const { return RegionEnd; }
257 
258     /// newSUnit - Creates a new SUnit and return a ptr to it.
259     SUnit *newSUnit(MachineInstr *MI);
260 
261     /// getSUnit - Return an existing SUnit for this MI, or NULL.
262     SUnit *getSUnit(MachineInstr *MI) const;
263 
264     /// startBlock - Prepare to perform scheduling in the given block.
265     virtual void startBlock(MachineBasicBlock *BB);
266 
267     /// finishBlock - Clean up after scheduling in the given block.
268     virtual void finishBlock();
269 
270     /// Initialize the scheduler state for the next scheduling region.
271     virtual void enterRegion(MachineBasicBlock *bb,
272                              MachineBasicBlock::iterator begin,
273                              MachineBasicBlock::iterator end,
274                              unsigned regioninstrs);
275 
276     /// Notify that the scheduler has finished scheduling the current region.
277     virtual void exitRegion();
278 
279     /// buildSchedGraph - Build SUnits from the MachineBasicBlock that we are
280     /// input.
281     void buildSchedGraph(AliasAnalysis *AA,
282                          RegPressureTracker *RPTracker = nullptr,
283                          PressureDiffs *PDiffs = nullptr,
284                          LiveIntervals *LIS = nullptr,
285                          bool TrackLaneMasks = false);
286 
287     /// addSchedBarrierDeps - Add dependencies from instructions in the current
288     /// list of instructions being scheduled to scheduling barrier. We want to
289     /// make sure instructions which define registers that are either used by
290     /// the terminator or are live-out are properly scheduled. This is
291     /// especially important when the definition latency of the return value(s)
292     /// are too high to be hidden by the branch or when the liveout registers
293     /// used by instructions in the fallthrough block.
294     void addSchedBarrierDeps();
295 
296     /// schedule - Order nodes according to selected style, filling
297     /// in the Sequence member.
298     ///
299     /// Typically, a scheduling algorithm will implement schedule() without
300     /// overriding enterRegion() or exitRegion().
301     virtual void schedule() = 0;
302 
303     /// finalizeSchedule - Allow targets to perform final scheduling actions at
304     /// the level of the whole MachineFunction. By default does nothing.
finalizeSchedule()305     virtual void finalizeSchedule() {}
306 
307     void dumpNode(const SUnit *SU) const override;
308 
309     /// Return a label for a DAG node that points to an instruction.
310     std::string getGraphNodeLabel(const SUnit *SU) const override;
311 
312     /// Return a label for the region of code covered by the DAG.
313     std::string getDAGName() const override;
314 
315     /// \brief Fix register kill flags that scheduling has made invalid.
316     void fixupKills(MachineBasicBlock *MBB);
317   protected:
318     void initSUnits();
319     void addPhysRegDataDeps(SUnit *SU, unsigned OperIdx);
320     void addPhysRegDeps(SUnit *SU, unsigned OperIdx);
321     void addVRegDefDeps(SUnit *SU, unsigned OperIdx);
322     void addVRegUseDeps(SUnit *SU, unsigned OperIdx);
323 
324     /// \brief PostRA helper for rewriting kill flags.
325     void startBlockForKills(MachineBasicBlock *BB);
326 
327     /// \brief Toggle a register operand kill flag.
328     ///
329     /// Other adjustments may be made to the instruction if necessary. Return
330     /// true if the operand has been deleted, false if not.
331     bool toggleKillFlag(MachineInstr *MI, MachineOperand &MO);
332 
333     /// Returns a mask for which lanes get read/written by the given (register)
334     /// machine operand.
335     LaneBitmask getLaneMaskForMO(const MachineOperand &MO) const;
336 
337     void collectVRegUses(SUnit *SU);
338   };
339 
340   /// newSUnit - Creates a new SUnit and return a ptr to it.
newSUnit(MachineInstr * MI)341   inline SUnit *ScheduleDAGInstrs::newSUnit(MachineInstr *MI) {
342 #ifndef NDEBUG
343     const SUnit *Addr = SUnits.empty() ? nullptr : &SUnits[0];
344 #endif
345     SUnits.emplace_back(MI, (unsigned)SUnits.size());
346     assert((Addr == nullptr || Addr == &SUnits[0]) &&
347            "SUnits std::vector reallocated on the fly!");
348     SUnits.back().OrigNode = &SUnits.back();
349     return &SUnits.back();
350   }
351 
352   /// getSUnit - Return an existing SUnit for this MI, or NULL.
getSUnit(MachineInstr * MI)353   inline SUnit *ScheduleDAGInstrs::getSUnit(MachineInstr *MI) const {
354     DenseMap<MachineInstr*, SUnit*>::const_iterator I = MISUnitMap.find(MI);
355     if (I == MISUnitMap.end())
356       return nullptr;
357     return I->second;
358   }
359 } // namespace llvm
360 
361 #endif
362