LLVM  6.0.0svn
GCNIterativeScheduler.cpp
Go to the documentation of this file.
1 //===- GCNIterativeScheduler.cpp ------------------------------------------===//
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 #include "GCNIterativeScheduler.h"
11 #include "AMDGPUSubtarget.h"
12 #include "GCNRegPressure.h"
13 #include "GCNSchedStrategy.h"
14 #include "llvm/ADT/ArrayRef.h"
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/ADT/SmallVector.h"
22 #include "llvm/Support/Compiler.h"
23 #include "llvm/Support/Debug.h"
25 #include <algorithm>
26 #include <cassert>
27 #include <iterator>
28 #include <limits>
29 #include <memory>
30 #include <type_traits>
31 #include <vector>
32 
33 using namespace llvm;
34 
35 #define DEBUG_TYPE "machine-scheduler"
36 
37 namespace llvm {
38 
39 std::vector<const SUnit *> makeMinRegSchedule(ArrayRef<const SUnit *> TopRoots,
40  const ScheduleDAG &DAG);
41 
42 } // end namespace llvm
43 
44 // shim accessors for different order containers
46  return MI;
47 }
48 static inline MachineInstr *getMachineInstr(const SUnit *SU) {
49  return SU->getInstr();
50 }
51 static inline MachineInstr *getMachineInstr(const SUnit &SU) {
52  return SU.getInstr();
53 }
54 
55 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
57 static void printRegion(raw_ostream &OS,
60  const LiveIntervals *LIS,
61  unsigned MaxInstNum =
63  auto BB = Begin->getParent();
64  OS << BB->getParent()->getName() << ":BB#" << BB->getNumber()
65  << ' ' << BB->getName() << ":\n";
66  auto I = Begin;
67  MaxInstNum = std::max(MaxInstNum, 1u);
68  for (; I != End && MaxInstNum; ++I, --MaxInstNum) {
69  if (!I->isDebugValue() && LIS)
70  OS << LIS->getInstructionIndex(*I);
71  OS << '\t' << *I;
72  }
73  if (I != End) {
74  OS << "\t...\n";
75  I = std::prev(End);
76  if (!I->isDebugValue() && LIS)
77  OS << LIS->getInstructionIndex(*I);
78  OS << '\t' << *I;
79  }
80  if (End != BB->end()) { // print boundary inst if present
81  OS << "----\n";
82  if (LIS) OS << LIS->getInstructionIndex(*End) << '\t';
83  OS << *End;
84  }
85 }
86 
91  const LiveIntervals *LIS) {
92  const auto BB = Begin->getParent();
93  const auto &MRI = BB->getParent()->getRegInfo();
94 
95  const auto LiveIns = getLiveRegsBefore(*Begin, *LIS);
96  OS << "LIn RP: ";
97  getRegPressure(MRI, LiveIns).print(OS);
98 
99  const auto BottomMI = End == BB->end() ? std::prev(End) : End;
100  const auto LiveOuts = getLiveRegsAfter(*BottomMI, *LIS);
101  OS << "LOt RP: ";
102  getRegPressure(MRI, LiveOuts).print(OS);
103 }
104 
107  const auto &ST = MF.getSubtarget<SISubtarget>();
108  for (const auto R : Regions) {
109  OS << "Region to schedule ";
110  printRegion(OS, R->Begin, R->End, LIS, 1);
111  printLivenessInfo(OS, R->Begin, R->End, LIS);
112  OS << "Max RP: ";
113  R->MaxPressure.print(OS, &ST);
114  }
115 }
116 
119  const Region *R,
120  const GCNRegPressure &RP) const {
121  OS << "\nAfter scheduling ";
122  printRegion(OS, R->Begin, R->End, LIS);
123  printSchedRP(OS, R->MaxPressure, RP);
124  OS << '\n';
125 }
126 
129  const GCNRegPressure &Before,
130  const GCNRegPressure &After) const {
131  const auto &ST = MF.getSubtarget<SISubtarget>();
132  OS << "RP before: ";
133  Before.print(OS, &ST);
134  OS << "RP after: ";
135  After.print(OS, &ST);
136 }
137 #endif
138 
139 // DAG builder helper
142  SmallVector<SUnit *, 8> TopRoots;
143 
144 public:
146  : Sch(_Sch) {
147  auto BB = R.Begin->getParent();
148  Sch.BaseClass::startBlock(BB);
149  Sch.BaseClass::enterRegion(BB, R.Begin, R.End, R.NumRegionInstrs);
150 
151  Sch.buildSchedGraph(Sch.AA, nullptr, nullptr, nullptr,
152  /*TrackLaneMask*/true);
154 
155  SmallVector<SUnit *, 8> BotRoots;
156  Sch.findRootsAndBiasEdges(TopRoots, BotRoots);
157  }
158 
160  Sch.BaseClass::exitRegion();
161  Sch.BaseClass::finishBlock();
162  }
163 
165  return TopRoots;
166  }
167 };
168 
171  Region &Rgn;
172  std::unique_ptr<MachineSchedStrategy> SaveSchedImpl;
173  GCNRegPressure SaveMaxRP;
174 
175 public:
177  MachineSchedStrategy &OverrideStrategy,
178  GCNIterativeScheduler &_Sch)
179  : Sch(_Sch)
180  , Rgn(R)
181  , SaveSchedImpl(std::move(_Sch.SchedImpl))
182  , SaveMaxRP(R.MaxPressure) {
183  Sch.SchedImpl.reset(&OverrideStrategy);
184  auto BB = R.Begin->getParent();
185  Sch.BaseClass::startBlock(BB);
186  Sch.BaseClass::enterRegion(BB, R.Begin, R.End, R.NumRegionInstrs);
187  }
188 
190  Sch.BaseClass::exitRegion();
191  Sch.BaseClass::finishBlock();
192  Sch.SchedImpl.release();
193  Sch.SchedImpl = std::move(SaveSchedImpl);
194  }
195 
196  void schedule() {
197  assert(Sch.RegionBegin == Rgn.Begin && Sch.RegionEnd == Rgn.End);
198  DEBUG(dbgs() << "\nScheduling ";
199  printRegion(dbgs(), Rgn.Begin, Rgn.End, Sch.LIS, 2));
200  Sch.BaseClass::schedule();
201 
202  // Unfortunatelly placeDebugValues incorrectly modifies RegionEnd, restore
203  Sch.RegionEnd = Rgn.End;
204  //assert(Rgn.End == Sch.RegionEnd);
205  Rgn.Begin = Sch.RegionBegin;
206  Rgn.MaxPressure.clear();
207  }
208 
209  void restoreOrder() {
210  assert(Sch.RegionBegin == Rgn.Begin && Sch.RegionEnd == Rgn.End);
211  // DAG SUnits are stored using original region's order
212  // so just use SUnits as the restoring schedule
213  Sch.scheduleRegion(Rgn, Sch.SUnits, SaveMaxRP);
214  }
215 };
216 
217 namespace {
218 
219 // just a stub to make base class happy
220 class SchedStrategyStub : public MachineSchedStrategy {
221 public:
222  bool shouldTrackPressure() const override { return false; }
223  bool shouldTrackLaneMasks() const override { return false; }
224  void initialize(ScheduleDAGMI *DAG) override {}
225  SUnit *pickNode(bool &IsTopNode) override { return nullptr; }
226  void schedNode(SUnit *SU, bool IsTopNode) override {}
227  void releaseTopNode(SUnit *SU) override {}
228  void releaseBottomNode(SUnit *SU) override {}
229 };
230 
231 } // end anonymous namespace
232 
234  StrategyKind S)
235  : BaseClass(C, llvm::make_unique<SchedStrategyStub>())
236  , Context(C)
237  , Strategy(S)
238  , UPTracker(*LIS) {
239 }
240 
241 // returns max pressure for a region
245  const {
246  // For the purpose of pressure tracking bottom inst of the region should
247  // be also processed. End is either BB end, BB terminator inst or sched
248  // boundary inst.
249  auto const BBEnd = Begin->getParent()->end();
250  auto const BottomMI = End == BBEnd ? std::prev(End) : End;
251 
252  // scheduleRegions walks bottom to top, so its likely we just get next
253  // instruction to track
254  auto AfterBottomMI = std::next(BottomMI);
255  if (AfterBottomMI == BBEnd ||
256  &*AfterBottomMI != UPTracker.getLastTrackedMI()) {
257  UPTracker.reset(*BottomMI);
258  } else {
260  }
261 
262  for (auto I = BottomMI; I != Begin; --I)
263  UPTracker.recede(*I);
264 
265  UPTracker.recede(*Begin);
266 
268  (dbgs() << "Tracked region ",
269  printRegion(dbgs(), Begin, End, LIS), false));
270  return UPTracker.moveMaxPressure();
271 }
272 
273 // returns max pressure for a tentative schedule
274 template <typename Range> GCNRegPressure
276  Range &&Schedule) const {
277  auto const BBEnd = R.Begin->getParent()->end();
279  if (R.End != BBEnd) {
280  // R.End points to the boundary instruction but the
281  // schedule doesn't include it
282  RPTracker.reset(*R.End);
283  RPTracker.recede(*R.End);
284  } else {
285  // R.End doesn't point to the boundary instruction
286  RPTracker.reset(*std::prev(BBEnd));
287  }
288  for (auto I = Schedule.end(), B = Schedule.begin(); I != B;) {
289  RPTracker.recede(*getMachineInstr(*--I));
290  }
291  return RPTracker.moveMaxPressure();
292 }
293 
297  unsigned NumRegionInstrs) {
298  BaseClass::enterRegion(BB, Begin, End, NumRegionInstrs);
299  if (NumRegionInstrs > 2) {
300  Regions.push_back(
301  new (Alloc.Allocate())
302  Region { Begin, End, NumRegionInstrs,
303  getRegionPressure(Begin, End), nullptr });
304  }
305 }
306 
307 void GCNIterativeScheduler::schedule() { // overriden
308  // do nothing
309  DEBUG(
311  if (!Regions.empty() && Regions.back()->Begin == RegionBegin) {
312  dbgs() << "Max RP: ";
313  Regions.back()->MaxPressure.print(dbgs(), &MF.getSubtarget<SISubtarget>());
314  }
315  dbgs() << '\n';
316  );
317 }
318 
320  if (Regions.empty())
321  return;
322  switch (Strategy) {
323  case SCHEDULE_MINREGONLY: scheduleMinReg(); break;
324  case SCHEDULE_MINREGFORCED: scheduleMinReg(true); break;
326  }
327 }
328 
329 // Detach schedule from SUnits and interleave it with debug values.
330 // Returned schedule becomes independent of DAG state.
331 std::vector<MachineInstr*>
333  std::vector<MachineInstr*> Res;
334  Res.reserve(Schedule.size() * 2);
335 
336  if (FirstDbgValue)
337  Res.push_back(FirstDbgValue);
338 
339  const auto DbgB = DbgValues.begin(), DbgE = DbgValues.end();
340  for (auto SU : Schedule) {
341  Res.push_back(SU->getInstr());
342  const auto &D = std::find_if(DbgB, DbgE, [SU](decltype(*DbgB) &P) {
343  return P.second == SU->getInstr();
344  });
345  if (D != DbgE)
346  Res.push_back(D->first);
347  }
348  return Res;
349 }
350 
352  ScheduleRef Schedule,
353  const GCNRegPressure &MaxRP) {
354  R.BestSchedule.reset(
355  new TentativeSchedule{ detachSchedule(Schedule), MaxRP });
356 }
357 
359  assert(R.BestSchedule.get() && "No schedule specified");
360  scheduleRegion(R, R.BestSchedule->Schedule, R.BestSchedule->MaxPressure);
361  R.BestSchedule.reset();
362 }
363 
364 // minimal required region scheduler, works for ranges of SUnits*,
365 // SUnits or MachineIntrs*
366 template <typename Range>
368  const GCNRegPressure &MaxRP) {
369  assert(RegionBegin == R.Begin && RegionEnd == R.End);
370  assert(LIS != nullptr);
371 #ifndef NDEBUG
372  const auto SchedMaxRP = getSchedulePressure(R, Schedule);
373 #endif
374  auto BB = R.Begin->getParent();
375  auto Top = R.Begin;
376  for (const auto &I : Schedule) {
377  auto MI = getMachineInstr(I);
378  if (MI != &*Top) {
379  BB->remove(MI);
380  BB->insert(Top, MI);
381  if (!MI->isDebugValue())
382  LIS->handleMove(*MI, true);
383  }
384  if (!MI->isDebugValue()) {
385  // Reset read - undef flags and update them later.
386  for (auto &Op : MI->operands())
387  if (Op.isReg() && Op.isDef())
388  Op.setIsUndef(false);
389 
390  RegisterOperands RegOpers;
391  RegOpers.collect(*MI, *TRI, MRI, /*ShouldTrackLaneMasks*/true,
392  /*IgnoreDead*/false);
393  // Adjust liveness and add missing dead+read-undef flags.
394  auto SlotIdx = LIS->getInstructionIndex(*MI).getRegSlot();
395  RegOpers.adjustLaneLiveness(*LIS, MRI, SlotIdx, MI);
396  }
397  Top = std::next(MI->getIterator());
398  }
399  RegionBegin = getMachineInstr(Schedule.front());
400 
401  // Schedule consisting of MachineInstr* is considered 'detached'
402  // and already interleaved with debug values
403  if (!std::is_same<decltype(*Schedule.begin()), MachineInstr*>::value) {
405  // Unfortunatelly placeDebugValues incorrectly modifies RegionEnd, restore
406  //assert(R.End == RegionEnd);
407  RegionEnd = R.End;
408  }
409 
410  R.Begin = RegionBegin;
411  R.MaxPressure = MaxRP;
412 
413 #ifndef NDEBUG
414  const auto RegionMaxRP = getRegionPressure(R);
415  const auto &ST = MF.getSubtarget<SISubtarget>();
416 #endif
417  assert((SchedMaxRP == RegionMaxRP && (MaxRP.empty() || SchedMaxRP == MaxRP))
418  || (dbgs() << "Max RP mismatch!!!\n"
419  "RP for schedule (calculated): ",
420  SchedMaxRP.print(dbgs(), &ST),
421  dbgs() << "RP for schedule (reported): ",
422  MaxRP.print(dbgs(), &ST),
423  dbgs() << "RP after scheduling: ",
424  RegionMaxRP.print(dbgs(), &ST),
425  false));
426 }
427 
428 // Sort recorded regions by pressure - highest at the front
430  const auto &ST = MF.getSubtarget<SISubtarget>();
431  std::sort(Regions.begin(), Regions.end(),
432  [&ST, TargetOcc](const Region *R1, const Region *R2) {
433  return R2->MaxPressure.less(ST, R1->MaxPressure, TargetOcc);
434  });
435 }
436 
437 ///////////////////////////////////////////////////////////////////////////////
438 // Legacy MaxOccupancy Strategy
439 
440 // Tries to increase occupancy applying minreg scheduler for a sequence of
441 // most demanding regions. Obtained schedules are saved as BestSchedule for a
442 // region.
443 // TargetOcc is the best achievable occupancy for a kernel.
444 // Returns better occupancy on success or current occupancy on fail.
445 // BestSchedules aren't deleted on fail.
446 unsigned GCNIterativeScheduler::tryMaximizeOccupancy(unsigned TargetOcc) {
447  // TODO: assert Regions are sorted descending by pressure
448  const auto &ST = MF.getSubtarget<SISubtarget>();
449  const auto Occ = Regions.front()->MaxPressure.getOccupancy(ST);
450  DEBUG(dbgs() << "Trying to to improve occupancy, target = " << TargetOcc
451  << ", current = " << Occ << '\n');
452 
453  auto NewOcc = TargetOcc;
454  for (auto R : Regions) {
455  if (R->MaxPressure.getOccupancy(ST) >= NewOcc)
456  break;
457 
458  DEBUG(printRegion(dbgs(), R->Begin, R->End, LIS, 3);
459  printLivenessInfo(dbgs(), R->Begin, R->End, LIS));
460 
461  BuildDAG DAG(*R, *this);
462  const auto MinSchedule = makeMinRegSchedule(DAG.getTopRoots(), *this);
463  const auto MaxRP = getSchedulePressure(*R, MinSchedule);
464  DEBUG(dbgs() << "Occupancy improvement attempt:\n";
465  printSchedRP(dbgs(), R->MaxPressure, MaxRP));
466 
467  NewOcc = std::min(NewOcc, MaxRP.getOccupancy(ST));
468  if (NewOcc <= Occ)
469  break;
470 
471  setBestSchedule(*R, MinSchedule, MaxRP);
472  }
473  DEBUG(dbgs() << "New occupancy = " << NewOcc
474  << ", prev occupancy = " << Occ << '\n');
475  return std::max(NewOcc, Occ);
476 }
477 
479  bool TryMaximizeOccupancy) {
480  const auto &ST = MF.getSubtarget<SISubtarget>();
481  auto TgtOcc = ST.getOccupancyWithLocalMemSize(MF);
482 
483  sortRegionsByPressure(TgtOcc);
484  auto Occ = Regions.front()->MaxPressure.getOccupancy(ST);
485 
486  if (TryMaximizeOccupancy && Occ < TgtOcc)
487  Occ = tryMaximizeOccupancy(TgtOcc);
488 
489  // This is really weird but for some magic scheduling regions twice
490  // gives performance improvement
491  const int NumPasses = Occ < TgtOcc ? 2 : 1;
492 
493  TgtOcc = std::min(Occ, TgtOcc);
494  DEBUG(dbgs() << "Scheduling using default scheduler, "
495  "target occupancy = " << TgtOcc << '\n');
497 
498  for (int I = 0; I < NumPasses; ++I) {
499  // running first pass with TargetOccupancy = 0 mimics previous scheduling
500  // approach and is a performance magic
501  LStrgy.setTargetOccupancy(I == 0 ? 0 : TgtOcc);
502  for (auto R : Regions) {
503  OverrideLegacyStrategy Ovr(*R, LStrgy, *this);
504 
505  Ovr.schedule();
506  const auto RP = getRegionPressure(*R);
507  DEBUG(printSchedRP(dbgs(), R->MaxPressure, RP));
508 
509  if (RP.getOccupancy(ST) < TgtOcc) {
510  DEBUG(dbgs() << "Didn't fit into target occupancy O" << TgtOcc);
511  if (R->BestSchedule.get() &&
512  R->BestSchedule->MaxPressure.getOccupancy(ST) >= TgtOcc) {
513  DEBUG(dbgs() << ", scheduling minimal register\n");
514  scheduleBest(*R);
515  } else {
516  DEBUG(dbgs() << ", restoring\n");
517  Ovr.restoreOrder();
518  assert(R->MaxPressure.getOccupancy(ST) >= TgtOcc);
519  }
520  }
521  }
522  }
523 }
524 
525 ///////////////////////////////////////////////////////////////////////////////
526 // Minimal Register Strategy
527 
529  const auto &ST = MF.getSubtarget<SISubtarget>();
530  const auto TgtOcc = ST.getOccupancyWithLocalMemSize(MF);
531  sortRegionsByPressure(TgtOcc);
532 
533  auto MaxPressure = Regions.front()->MaxPressure;
534  for (auto R : Regions) {
535  if (!force && R->MaxPressure.less(ST, MaxPressure, TgtOcc))
536  break;
537 
538  BuildDAG DAG(*R, *this);
539  const auto MinSchedule = makeMinRegSchedule(DAG.getTopRoots(), *this);
540 
541  const auto RP = getSchedulePressure(*R, MinSchedule);
542  DEBUG(if (R->MaxPressure.less(ST, RP, TgtOcc)) {
543  dbgs() << "\nWarning: Pressure becomes worse after minreg!";
544  printSchedRP(dbgs(), R->MaxPressure, RP);
545  });
546 
547  if (!force && MaxPressure.less(ST, RP, TgtOcc))
548  break;
549 
550  scheduleRegion(*R, MinSchedule, RP);
551  DEBUG(printSchedResult(dbgs(), R, RP));
552 
553  MaxPressure = RP;
554  }
555 }
unsigned tryMaximizeOccupancy(unsigned TargetOcc=std::numeric_limits< unsigned >::max())
uint64_t CallInst * C
void enterRegion(MachineBasicBlock *BB, MachineBasicBlock::iterator Begin, MachineBasicBlock::iterator End, unsigned RegionInstrs) override
Implement the ScheduleDAGInstrs interface for handling the next scheduling region.
GCNRegPressure getRegionPressure(MachineBasicBlock::iterator Begin, MachineBasicBlock::iterator End) const
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
AMDGPU specific subclass of TargetSubtarget.
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds...
Definition: Compiler.h:449
This is a minimal scheduler strategy.
void sortRegionsByPressure(unsigned TargetOcc)
ScheduleDAGTopologicalSort Topo
Topo - A topological ordering for SUnits which permits fast IsReachable and similar queries...
decltype(MaxPressure) moveMaxPressure()
SpecificBumpPtrAllocator< Region > Alloc
std::vector< Region * > Regions
std::vector< MachineInstr * > detachSchedule(ScheduleRef Schedule) const
std::enable_if<!std::is_array< T >::value, std::unique_ptr< T > >::type make_unique(Args &&... args)
Constructs a new T() with the given args and returns a unique_ptr<T> which owns the object...
Definition: STLExtras.h:899
#define R2(n)
unsigned NumRegionInstrs
Instructions in this region (distance(RegionBegin, RegionEnd)).
ScheduleDAGMI is an implementation of ScheduleDAGInstrs that simply schedules machine instructions ac...
std::unique_ptr< MachineSchedStrategy > SchedImpl
ScheduleDAGMILive is an implementation of ScheduleDAGInstrs that schedules machine instructions while...
MachineFunction & MF
Machine function.
Definition: ScheduleDAG.h:570
void buildSchedGraph(AliasAnalysis *AA, RegPressureTracker *RPTracker=nullptr, PressureDiffs *PDiffs=nullptr, LiveIntervals *LIS=nullptr, bool TrackLaneMasks=false)
Builds SUnits for the current region.
void printRegions(raw_ostream &OS) const
Definition: BitVector.h:920
MachineBasicBlock::iterator RegionEnd
The end of the range to be scheduled.
void finalizeSchedule() override
Allow targets to perform final scheduling actions at the level of the whole MachineFunction.
DbgValueVector DbgValues
Remember instruction that precedes DBG_VALUE.
void InitDAGTopologicalSorting()
Creates the initial topological ordering from the DAG to be scheduled.
void scheduleLegacyMaxOccupancy(bool TryMaximizeOccupancy=true)
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def...
Definition: SlotIndexes.h:255
MachineBasicBlock::iterator RegionBegin
The beginning of the range to be scheduled.
static LLVM_DUMP_METHOD void printLivenessInfo(raw_ostream &OS, MachineBasicBlock::iterator Begin, MachineBasicBlock::iterator End, const LiveIntervals *LIS)
std::vector< const SUnit * > makeMinRegSchedule(ArrayRef< const SUnit *> TopRoots, const ScheduleDAG &DAG)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
GCNRPTracker::LiveRegSet getLiveRegsBefore(const MachineInstr &MI, const LiveIntervals &LIS)
void collect(const MachineInstr &MI, const TargetRegisterInfo &TRI, const MachineRegisterInfo &MRI, bool TrackLaneMasks, bool IgnoreDead)
Analyze the given instruction MI and fill in the Uses, Defs and DeadDefs list based on the MachineOpe...
static MachineInstr * getMachineInstr(MachineInstr *MI)
List of registers defined and used by a machine instruction.
void printSchedRP(raw_ostream &OS, const GCNRegPressure &Before, const GCNRegPressure &After) const
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
void reset(const MachineInstr &MI, const LiveRegSet *LiveRegs=nullptr)
void print(raw_ostream &OS, const SISubtarget *ST=nullptr) const
#define P(N)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
MachineInstr * getInstr() const
Returns the representative MachineInstr for this SUnit.
Definition: ScheduleDAG.h:378
void setBestSchedule(Region &R, ScheduleRef Schedule, const GCNRegPressure &MaxRP=GCNRegPressure())
unsigned const MachineRegisterInfo * MRI
const MachineInstr * getLastTrackedMI() const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:149
static const unsigned End
GCNRPTracker::LiveRegSet getLiveRegsAfter(const MachineInstr &MI, const LiveIntervals &LIS)
void adjustLaneLiveness(const LiveIntervals &LIS, const MachineRegisterInfo &MRI, SlotIndex Pos, MachineInstr *AddFlagsMI=nullptr)
Use liveness information to find out which uses/defs are partially undefined/dead and adjust the Regi...
GCNRegPressure getSchedulePressure(const Region &R, Range &&Schedule) const
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:864
OverrideLegacyStrategy(Region &R, MachineSchedStrategy &OverrideStrategy, GCNIterativeScheduler &_Sch)
void enterRegion(MachineBasicBlock *bb, MachineBasicBlock::iterator begin, MachineBasicBlock::iterator end, unsigned regioninstrs) override
Implement the ScheduleDAGInstrs interface for handling the next scheduling region.
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
void schedule() override
Implement ScheduleDAGInstrs interface for scheduling a sequence of reorderable instructions.
MachineInstr * remove(MachineInstr *I)
Remove the unbundled instruction from the instruction list without deleting it.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, ArrayRef< StringRef > StandardNames)
initialize - Initialize the set of available library functions based on the specified target triple...
const MachineBasicBlock::iterator End
static LLVM_DUMP_METHOD void printRegion(raw_ostream &OS, MachineBasicBlock::iterator Begin, MachineBasicBlock::iterator End, const LiveIntervals *LIS, unsigned MaxInstNum=std::numeric_limits< unsigned >::max())
ArrayRef< const SUnit * > getTopRoots() const
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
GCNRegPressure getRegPressure(const MachineRegisterInfo &MRI, Range &&LiveRegs)
Representation of each machine instruction.
Definition: MachineInstr.h:59
LiveIntervals * LIS
BuildDAG(const Region &R, GCNIterativeScheduler &_Sch)
const TargetRegisterInfo * TRI
Target processor register info.
Definition: ScheduleDAG.h:569
void findRootsAndBiasEdges(SmallVectorImpl< SUnit *> &TopRoots, SmallVectorImpl< SUnit *> &BotRoots)
void printSchedResult(raw_ostream &OS, const Region *R, const GCNRegPressure &RP) const
GCNIterativeScheduler(MachineSchedContext *C, StrategyKind S)
MachineSchedContext provides enough context from the MachineScheduler pass for the target to instanti...
MachineSchedStrategy - Interface to the scheduling algorithm used by ScheduleDAGMI.
#define I(x, y, z)
Definition: MD5.cpp:58
void placeDebugValues()
Reinsert debug_values recorded in ScheduleDAGInstrs::DbgValues.
void scheduleRegion(Region &R, Range &&Schedule, const GCNRegPressure &MaxRP=GCNRegPressure())
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void scheduleMinReg(bool force=false)
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:44
#define DEBUG(X)
Definition: Debug.h:118
MachineBasicBlock * BB
The block in which to insert instructions.
IRTranslator LLVM IR MI
void sort(Policy policy, RandomAccessIterator Start, RandomAccessIterator End, const Comparator &Comp=Comparator())
Definition: Parallel.h:199
MachineRegisterInfo & MRI
Virtual/real register map.
Definition: ScheduleDAG.h:571
std::vector< SUnit > SUnits
The scheduling units.
Definition: ScheduleDAG.h:572
auto find_if(R &&Range, UnaryPredicate P) -> decltype(std::begin(Range))
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:795
void recede(const MachineInstr &MI)
AliasAnalysis * AA
RegPressureTracker RPTracker
std::unique_ptr< TentativeSchedule > BestSchedule
void handleMove(MachineInstr &MI, bool UpdateFlags=false)
Call this method to notify LiveIntervals that instruction MI has been moved within a basic block...
Scheduling unit. This is a node in the scheduling DAG.
Definition: ScheduleDAG.h:247