1de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar//===-- SIMachineScheduler.h - SI Scheduler Interface -*- C++ -*-------===//
2de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar//
3de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar//                     The LLVM Compiler Infrastructure
4de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar//
5de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// This file is distributed under the University of Illinois Open Source
6de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// License. See LICENSE.TXT for details.
7de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar//
8de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar//===----------------------------------------------------------------------===//
9de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar//
10de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar/// \file
11de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar/// \brief SI Machine Scheduler interface
12de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar//
13de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar//===----------------------------------------------------------------------===//
14de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
15de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#ifndef LLVM_LIB_TARGET_AMDGPU_SIMACHINESCHEDULER_H
16de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#define LLVM_LIB_TARGET_AMDGPU_SIMACHINESCHEDULER_H
17de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
18de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "SIInstrInfo.h"
19de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/CodeGen/MachineScheduler.h"
20de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/CodeGen/RegisterPressure.h"
21de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
22de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarusing namespace llvm;
23de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
24de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarnamespace llvm {
25de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
26de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarenum SIScheduleCandReason {
27de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  NoCand,
28de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  RegUsage,
29de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  Latency,
30de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  Successor,
31de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  Depth,
32de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  NodeOrder
33de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar};
34de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
35de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstruct SISchedulerCandidate {
36de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // The reason for this candidate.
37de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SIScheduleCandReason Reason;
38de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
39de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Set of reasons that apply to multiple candidates.
40de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  uint32_t RepeatReasonSet;
41de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
42de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SISchedulerCandidate()
43de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    :  Reason(NoCand), RepeatReasonSet(0) {}
44de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
45de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  bool isRepeat(SIScheduleCandReason R) { return RepeatReasonSet & (1 << R); }
46de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void setRepeat(SIScheduleCandReason R) { RepeatReasonSet |= (1 << R); }
47de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar};
48de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
49de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarclass SIScheduleDAGMI;
50de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarclass SIScheduleBlockCreator;
51de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
52de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarclass SIScheduleBlock {
53de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SIScheduleDAGMI *DAG;
54de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SIScheduleBlockCreator *BC;
55de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
56de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<SUnit*> SUnits;
57de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::map<unsigned, unsigned> NodeNum2Index;
58de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<SUnit*> TopReadySUs;
59de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<SUnit*> ScheduledSUnits;
60de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
61de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  /// The top of the unscheduled zone.
62de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  IntervalPressure TopPressure;
63de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  RegPressureTracker TopRPTracker;
64de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
65de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Pressure: number of said class of registers needed to
66de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // store the live virtual and real registers.
67de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // We do care only of SGPR32 and VGPR32 and do track only virtual registers.
68de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Pressure of additional registers required inside the block.
69de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<unsigned> InternalAdditionnalPressure;
70de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Pressure of input and output registers
71de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<unsigned> LiveInPressure;
72de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<unsigned> LiveOutPressure;
73de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Registers required by the block, and outputs.
74de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // We do track only virtual registers.
75de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Note that some registers are not 32 bits,
76de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // and thus the pressure is not equal
77de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // to the number of live registers.
78de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::set<unsigned> LiveInRegs;
79de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::set<unsigned> LiveOutRegs;
80de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
81de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  bool Scheduled;
82de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  bool HighLatencyBlock;
83de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
84de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<unsigned> HasLowLatencyNonWaitedParent;
85de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
86de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Unique ID, the index of the Block in the SIScheduleDAGMI Blocks table.
87de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned ID;
88de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
89de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<SIScheduleBlock*> Preds;  // All blocks predecessors.
90de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<SIScheduleBlock*> Succs;  // All blocks successors.
91de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned NumHighLatencySuccessors;
92de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
93de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarpublic:
94de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SIScheduleBlock(SIScheduleDAGMI *DAG, SIScheduleBlockCreator *BC,
95de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                  unsigned ID):
96de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    DAG(DAG), BC(BC), SUnits(), TopReadySUs(), ScheduledSUnits(),
97de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TopRPTracker(TopPressure), Scheduled(false),
98de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    HighLatencyBlock(false), ID(ID),
99de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    Preds(), Succs(), NumHighLatencySuccessors(0) {};
100de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
101de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ~SIScheduleBlock() {};
102de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
103de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned getID() const { return ID; }
104de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
105de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  /// Functions for Block construction.
106de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void addUnit(SUnit *SU);
107de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
108de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // When all SUs have been added.
109de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void finalizeUnits();
110de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
111de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Add block pred, which has instruction predecessor of SU.
112de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void addPred(SIScheduleBlock *Pred);
113de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void addSucc(SIScheduleBlock *Succ);
114de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
115de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  const std::vector<SIScheduleBlock*>& getPreds() const { return Preds; }
116de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  const std::vector<SIScheduleBlock*>& getSuccs() const { return Succs; }
117de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
118de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned Height;  // Maximum topdown path length to block without outputs
119de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned Depth;   // Maximum bottomup path length to block without inputs
120de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
121de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned getNumHighLatencySuccessors() const {
122de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return NumHighLatencySuccessors;
123de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
124de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
125de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  bool isHighLatencyBlock() { return HighLatencyBlock; }
126de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
127de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // This is approximative.
128de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Ideally should take into accounts some instructions (rcp, etc)
129de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // are 4 times slower.
130de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  int getCost() { return SUnits.size(); }
131de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
132de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // The block Predecessors and Successors must be all registered
133de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // before fastSchedule().
134de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Fast schedule with no particular requirement.
135de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void fastSchedule();
136de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
137de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<SUnit*> getScheduledUnits() { return ScheduledSUnits; }
138de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
139de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Complete schedule that will try to minimize reg pressure and
140de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // low latencies, and will fill liveins and liveouts.
141de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Needs all MIs to be grouped between BeginBlock and EndBlock.
142de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // The MIs can be moved after the scheduling,
143de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // it is just used to allow correct track of live registers.
144de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void schedule(MachineBasicBlock::iterator BeginBlock,
145de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                MachineBasicBlock::iterator EndBlock);
146de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
147de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  bool isScheduled() { return Scheduled; }
148de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
149de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
150de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Needs the block to be scheduled inside
151de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // TODO: find a way to compute it.
152de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<unsigned> &getInternalAdditionnalRegUsage() {
153de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return InternalAdditionnalPressure;
154de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
155de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
156de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::set<unsigned> &getInRegs() { return LiveInRegs; }
157de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::set<unsigned> &getOutRegs() { return LiveOutRegs; }
158de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
159de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void printDebug(bool Full);
160de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
161de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarprivate:
162de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  struct SISchedCandidate : SISchedulerCandidate {
163de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    // The best SUnit candidate.
164de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    SUnit *SU;
165de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
166de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    unsigned SGPRUsage;
167de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    unsigned VGPRUsage;
168de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    bool IsLowLatency;
169de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    unsigned LowLatencyOffset;
170de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    bool HasLowLatencyNonWaitedParent;
171de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
172de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    SISchedCandidate()
173de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      : SU(nullptr) {}
174de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
175de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    bool isValid() const { return SU; }
176de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
177de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    // Copy the status of another candidate without changing policy.
178de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    void setBest(SISchedCandidate &Best) {
179de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      assert(Best.Reason != NoCand && "uninitialized Sched candidate");
180de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      SU = Best.SU;
181de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      Reason = Best.Reason;
182de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      SGPRUsage = Best.SGPRUsage;
183de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      VGPRUsage = Best.VGPRUsage;
184de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      IsLowLatency = Best.IsLowLatency;
185de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      LowLatencyOffset = Best.LowLatencyOffset;
186de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      HasLowLatencyNonWaitedParent = Best.HasLowLatencyNonWaitedParent;
187de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
188de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  };
189de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
190de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void undoSchedule();
191de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
192de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void undoReleaseSucc(SUnit *SU, SDep *SuccEdge);
193de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void releaseSucc(SUnit *SU, SDep *SuccEdge);
194de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // InOrOutBlock: restrict to links pointing inside the block (true),
195de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // or restrict to links pointing outside the block (false).
196de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void releaseSuccessors(SUnit *SU, bool InOrOutBlock);
197de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
198de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void nodeScheduled(SUnit *SU);
199de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void tryCandidateTopDown(SISchedCandidate &Cand, SISchedCandidate &TryCand);
200de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void tryCandidateBottomUp(SISchedCandidate &Cand, SISchedCandidate &TryCand);
201de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SUnit* pickNode();
202de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void traceCandidate(const SISchedCandidate &Cand);
203de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void initRegPressure(MachineBasicBlock::iterator BeginBlock,
204de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                       MachineBasicBlock::iterator EndBlock);
205de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar};
206de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
207de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstruct SIScheduleBlocks {
208de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<SIScheduleBlock*> Blocks;
209de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<int> TopDownIndex2Block;
210de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<int> TopDownBlock2Index;
211de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar};
212de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
213de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarenum SISchedulerBlockCreatorVariant {
214de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    LatenciesAlone,
215de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    LatenciesGrouped,
216de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    LatenciesAlonePlusConsecutive
217de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar};
218de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
219de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarclass SIScheduleBlockCreator {
220de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SIScheduleDAGMI *DAG;
221de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // unique_ptr handles freeing memory for us.
222de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<std::unique_ptr<SIScheduleBlock>> BlockPtrs;
223de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::map<SISchedulerBlockCreatorVariant,
224de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar           SIScheduleBlocks> Blocks;
225de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<SIScheduleBlock*> CurrentBlocks;
226de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<int> Node2CurrentBlock;
227de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
228de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Topological sort
229de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Maps topological index to the node number.
230de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<int> TopDownIndex2Block;
231de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<int> TopDownBlock2Index;
232de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<int> BottomUpIndex2Block;
233de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
234de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // 0 -> Color not given.
235de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // 1 to SUnits.size() -> Reserved group (you should only add elements to them).
236de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Above -> Other groups.
237de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  int NextReservedID;
238de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  int NextNonReservedID;
239de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<int> CurrentColoring;
240de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<int> CurrentTopDownReservedDependencyColoring;
241de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<int> CurrentBottomUpReservedDependencyColoring;
242de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
243de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarpublic:
244de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SIScheduleBlockCreator(SIScheduleDAGMI *DAG);
245de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ~SIScheduleBlockCreator();
246de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
247de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SIScheduleBlocks
248de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  getBlocks(SISchedulerBlockCreatorVariant BlockVariant);
249de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
250de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  bool isSUInBlock(SUnit *SU, unsigned ID);
251de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
252de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarprivate:
253de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Give a Reserved color to every high latency.
254de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void colorHighLatenciesAlone();
255de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
256de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Create groups of high latencies with a Reserved color.
257de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void colorHighLatenciesGroups();
258de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
259de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Compute coloring for topdown and bottom traversals with
260de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // different colors depending on dependencies on Reserved colors.
261de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void colorComputeReservedDependencies();
262de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
263de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Give color to all non-colored SUs according to Reserved groups dependencies.
264de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void colorAccordingToReservedDependencies();
265de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
266de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Divides Blocks having no bottom up or top down dependencies on Reserved groups.
267de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // The new colors are computed according to the dependencies on the other blocks
268de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // formed with colorAccordingToReservedDependencies.
269de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void colorEndsAccordingToDependencies();
270de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
271de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Cut groups into groups with SUs in consecutive order (except for Reserved groups).
272de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void colorForceConsecutiveOrderInGroup();
273de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
274de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Merge Constant loads that have all their users into another group to the group.
275de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // (TODO: else if all their users depend on the same group, put them there)
276de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void colorMergeConstantLoadsNextGroup();
277de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
278de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Merge SUs that have all their users into another group to the group
279de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void colorMergeIfPossibleNextGroup();
280de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
281de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Merge SUs that have all their users into another group to the group,
282de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // but only for Reserved groups.
283de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void colorMergeIfPossibleNextGroupOnlyForReserved();
284de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
285de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Merge SUs that have all their users into another group to the group,
286de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // but only if the group is no more than a few SUs.
287de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void colorMergeIfPossibleSmallGroupsToNextGroup();
288de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
289de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Divides Blocks with important size.
290de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Idea of implementation: attribute new colors depending on topdown and
291de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // bottom up links to other blocks.
292de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void cutHugeBlocks();
293de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
294de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Put in one group all instructions with no users in this scheduling region
295de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // (we'd want these groups be at the end).
296de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void regroupNoUserInstructions();
297de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
298de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void createBlocksForVariant(SISchedulerBlockCreatorVariant BlockVariant);
299de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
300de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void topologicalSort();
301de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
302de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void scheduleInsideBlocks();
303de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
304de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void fillStats();
305de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar};
306de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
307de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarenum SISchedulerBlockSchedulerVariant {
308de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  BlockLatencyRegUsage,
309de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  BlockRegUsageLatency,
310de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  BlockRegUsage
311de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar};
312de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
313de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarclass SIScheduleBlockScheduler {
314de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SIScheduleDAGMI *DAG;
315de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SISchedulerBlockSchedulerVariant Variant;
316de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<SIScheduleBlock*> Blocks;
317de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
318de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<std::map<unsigned, unsigned>> LiveOutRegsNumUsages;
319de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::set<unsigned> LiveRegs;
320de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Num of schedulable unscheduled blocks reading the register.
321de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::map<unsigned, unsigned> LiveRegsConsumers;
322de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
323de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<unsigned> LastPosHighLatencyParentScheduled;
324de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  int LastPosWaitedHighLatency;
325de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
326de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<SIScheduleBlock*> BlocksScheduled;
327de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned NumBlockScheduled;
328de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<SIScheduleBlock*> ReadyBlocks;
329de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
330de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned VregCurrentUsage;
331de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned SregCurrentUsage;
332de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
333de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Currently is only approximation.
334de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned maxVregUsage;
335de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned maxSregUsage;
336de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
337de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<unsigned> BlockNumPredsLeft;
338de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<unsigned> BlockNumSuccsLeft;
339de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
340de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarpublic:
341de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SIScheduleBlockScheduler(SIScheduleDAGMI *DAG,
342de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                           SISchedulerBlockSchedulerVariant Variant,
343de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                           SIScheduleBlocks BlocksStruct);
344de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ~SIScheduleBlockScheduler() {};
345de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
346de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<SIScheduleBlock*> getBlocks() { return BlocksScheduled; };
347de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
348de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned getVGPRUsage() { return maxVregUsage; };
349de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned getSGPRUsage() { return maxSregUsage; };
350de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
351de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarprivate:
352de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  struct SIBlockSchedCandidate : SISchedulerCandidate {
353de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    // The best Block candidate.
354de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    SIScheduleBlock *Block;
355de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
356de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    bool IsHighLatency;
357de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    int VGPRUsageDiff;
358de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    unsigned NumSuccessors;
359de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    unsigned NumHighLatencySuccessors;
360de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    unsigned LastPosHighLatParentScheduled;
361de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    unsigned Height;
362de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
363de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    SIBlockSchedCandidate()
364de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      : Block(nullptr) {}
365de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
366de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    bool isValid() const { return Block; }
367de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
368de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    // Copy the status of another candidate without changing policy.
369de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    void setBest(SIBlockSchedCandidate &Best) {
370de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      assert(Best.Reason != NoCand && "uninitialized Sched candidate");
371de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      Block = Best.Block;
372de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      Reason = Best.Reason;
373de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      IsHighLatency = Best.IsHighLatency;
374de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      VGPRUsageDiff = Best.VGPRUsageDiff;
375de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      NumSuccessors = Best.NumSuccessors;
376de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      NumHighLatencySuccessors = Best.NumHighLatencySuccessors;
377de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      LastPosHighLatParentScheduled = Best.LastPosHighLatParentScheduled;
378de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      Height = Best.Height;
379de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
380de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  };
381de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
382de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  bool tryCandidateLatency(SIBlockSchedCandidate &Cand,
383de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                           SIBlockSchedCandidate &TryCand);
384de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  bool tryCandidateRegUsage(SIBlockSchedCandidate &Cand,
385de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                            SIBlockSchedCandidate &TryCand);
386de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SIScheduleBlock *pickBlock();
387de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
388de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void addLiveRegs(std::set<unsigned> &Regs);
389de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void decreaseLiveRegs(SIScheduleBlock *Block, std::set<unsigned> &Regs);
390de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void releaseBlockSuccs(SIScheduleBlock *Parent);
391de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void blockScheduled(SIScheduleBlock *Block);
392de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
393de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Check register pressure change
394de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // by scheduling a block with these LiveIn and LiveOut.
395de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<int> checkRegUsageImpact(std::set<unsigned> &InRegs,
396de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                       std::set<unsigned> &OutRegs);
397de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
398de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void schedule();
399de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar};
400de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
401de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstruct SIScheduleBlockResult {
402de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<unsigned> SUs;
403de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned MaxSGPRUsage;
404de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned MaxVGPRUsage;
405de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar};
406de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
407de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarclass SIScheduler {
408de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SIScheduleDAGMI *DAG;
409de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SIScheduleBlockCreator BlockCreator;
410de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
411de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarpublic:
412de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SIScheduler(SIScheduleDAGMI *DAG) : DAG(DAG), BlockCreator(DAG) {};
413de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
414de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ~SIScheduler() {};
415de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
416de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  struct SIScheduleBlockResult
417de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  scheduleVariant(SISchedulerBlockCreatorVariant BlockVariant,
418de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                  SISchedulerBlockSchedulerVariant ScheduleVariant);
419de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar};
420de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
421de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarclass SIScheduleDAGMI final : public ScheduleDAGMILive {
422de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  const SIInstrInfo *SITII;
423de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  const SIRegisterInfo *SITRI;
424de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
425de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<SUnit> SUnitsLinksBackup;
426de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
427de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // For moveLowLatencies. After all Scheduling variants are tested.
428de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<unsigned> ScheduledSUnits;
429de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<unsigned> ScheduledSUnitsInv;
430de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
431de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned VGPRSetID;
432de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned SGPRSetID;
433de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
434de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarpublic:
435de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SIScheduleDAGMI(MachineSchedContext *C);
436de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
437de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ~SIScheduleDAGMI() override;
438de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
439de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Entry point for the schedule.
440de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void schedule() override;
441de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
442de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // To init Block's RPTracker.
443de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void initRPTracker(RegPressureTracker &RPTracker) {
444de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    RPTracker.init(&MF, RegClassInfo, LIS, BB, RegionBegin, false, false);
445de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
446de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
447de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MachineBasicBlock *getBB() { return BB; }
448de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MachineBasicBlock::iterator getCurrentTop() { return CurrentTop; };
449de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MachineBasicBlock::iterator getCurrentBottom() { return CurrentBottom; };
450de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  LiveIntervals *getLIS() { return LIS; }
451de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MachineRegisterInfo *getMRI() { return &MRI; }
452de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  const TargetRegisterInfo *getTRI() { return TRI; }
453de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SUnit& getEntrySU() { return EntrySU; };
454de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SUnit& getExitSU() { return ExitSU; };
455de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
456de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void restoreSULinksLeft();
457de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
458de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  template<typename _Iterator> void fillVgprSgprCost(_Iterator First,
459de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                                     _Iterator End,
460de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                                     unsigned &VgprUsage,
461de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                                     unsigned &SgprUsage);
462de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::set<unsigned> getInRegs() {
463de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    std::set<unsigned> InRegs;
464de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    for (const auto &RegMaskPair : RPTracker.getPressure().LiveInRegs) {
465de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      InRegs.insert(RegMaskPair.RegUnit);
466de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
467de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return InRegs;
468de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  };
469de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
470de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned getVGPRSetID() const { return VGPRSetID; }
471de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned getSGPRSetID() const { return SGPRSetID; }
472de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
473de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarprivate:
474de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void topologicalSort();
475de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // After scheduling is done, improve low latency placements.
476de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void moveLowLatencies();
477de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
478de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarpublic:
479de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Some stats for scheduling inside blocks.
480de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<unsigned> IsLowLatencySU;
481de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<unsigned> LowLatencyOffset;
482de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<unsigned> IsHighLatencySU;
483de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Topological sort
484de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Maps topological index to the node number.
485de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<int> TopDownIndex2SU;
486de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::vector<int> BottomUpIndex2SU;
487de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar};
488de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
489de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} // namespace llvm
490de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
491de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#endif /* SIMACHINESCHEDULER_H_ */
492