1f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===- MachineScheduler.h - MachineInstr Scheduling Pass --------*- C++ -*-===//
2f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
3f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//                     The LLVM Compiler Infrastructure
4f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
5f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// This file is distributed under the University of Illinois Open Source
6f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// License. See LICENSE.TXT for details.
7f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
8f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===//
9f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
10f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// This file provides an interface for customizing the standard MachineScheduler
11f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// pass. Note that the entire pass may be replaced as follows:
12f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
13f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// <Target>TargetMachine::createPassConfig(PassManagerBase &PM) {
14f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//   PM.substitutePass(&MachineSchedulerID, &CustomSchedulerPassID);
15f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//   ...}
16f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
17f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// The MachineScheduler pass is only responsible for choosing the regions to be
18f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// scheduled. Targets can override the DAG builder and scheduler without
19f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// replacing the pass as follows:
20f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
21f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// ScheduleDAGInstrs *<Target>PassConfig::
22f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// createMachineScheduler(MachineSchedContext *C) {
23f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//   return new CustomMachineScheduler(C);
24f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// }
25f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
26f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// The default scheduler, ScheduleDAGMILive, builds the DAG and drives list
27f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// scheduling while updating the instruction stream, register pressure, and live
28f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// intervals. Most targets don't need to override the DAG builder and list
29f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// scheduler, but subtargets that require custom scheduling heuristics may
30f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// plugin an alternate MachineSchedStrategy. The strategy is responsible for
31f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// selecting the highest priority node from the list:
32f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
33f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// ScheduleDAGInstrs *<Target>PassConfig::
34f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// createMachineScheduler(MachineSchedContext *C) {
35f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//   return new ScheduleDAGMILive(C, CustomStrategy(C));
36f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// }
37f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
38f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// The DAG builder can also be customized in a sense by adding DAG mutations
39f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// that will run after DAG building and before list scheduling. DAG mutations
40f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// can adjust dependencies based on target-specific knowledge or add weak edges
41f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// to aid heuristics:
42f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
43f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// ScheduleDAGInstrs *<Target>PassConfig::
44f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// createMachineScheduler(MachineSchedContext *C) {
45f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//   ScheduleDAGMI *DAG = createGenericSchedLive(C);
46f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//   DAG->addMutation(new CustomDAGMutation(...));
47f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//   return DAG;
48f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// }
49f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
50f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// A target that supports alternative schedulers can use the
51f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// MachineSchedRegistry to allow command line selection. This can be done by
52f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// implementing the following boilerplate:
53f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
54f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// static ScheduleDAGInstrs *createCustomMachineSched(MachineSchedContext *C) {
55f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//  return new CustomMachineScheduler(C);
56f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// }
57f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// static MachineSchedRegistry
58f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// SchedCustomRegistry("custom", "Run my target's custom scheduler",
59f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//                     createCustomMachineSched);
60f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
61f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
62f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// Finally, subtargets that don't need to implement custom heuristics but would
63f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// like to configure the GenericScheduler's policy for a given scheduler region,
64f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// including scheduling direction and register pressure tracking policy, can do
65f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// this:
66f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
67f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// void <SubTarget>Subtarget::
68f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// overrideSchedPolicy(MachineSchedPolicy &Policy,
69f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//                     unsigned NumRegionInstrs) const {
70f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//   Policy.<Flag> = true;
71f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// }
72f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
73f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===//
74f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
75f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#ifndef LLVM_CODEGEN_MACHINESCHEDULER_H
76f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#define LLVM_CODEGEN_MACHINESCHEDULER_H
77f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
78f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/ADT/ArrayRef.h"
79f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/ADT/BitVector.h"
80f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/ADT/STLExtras.h"
81f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/ADT/SmallVector.h"
82f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/ADT/StringRef.h"
83f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/ADT/Twine.h"
84f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/Analysis/AliasAnalysis.h"
85f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/CodeGen/MachineBasicBlock.h"
86f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/CodeGen/MachinePassRegistry.h"
87f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/CodeGen/RegisterPressure.h"
88f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/CodeGen/ScheduleDAG.h"
89f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/CodeGen/ScheduleDAGInstrs.h"
90f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/CodeGen/ScheduleDAGMutation.h"
91f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/CodeGen/TargetSchedule.h"
92f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/Support/CommandLine.h"
93f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/Support/ErrorHandling.h"
94f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include <algorithm>
95f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include <cassert>
96f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include <memory>
97f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include <string>
98f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include <vector>
99f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
100f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotnamespace llvm {
101f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
102f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotextern cl::opt<bool> ForceTopDown;
103f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotextern cl::opt<bool> ForceBottomUp;
104f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
105f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass LiveIntervals;
106f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass MachineDominatorTree;
107f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass MachineFunction;
108f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass MachineInstr;
109f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass MachineLoopInfo;
110f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass RegisterClassInfo;
111f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass SchedDFSResult;
112f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass ScheduleHazardRecognizer;
113f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass TargetInstrInfo;
114f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass TargetPassConfig;
115f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass TargetRegisterInfo;
116f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
117f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// MachineSchedContext provides enough context from the MachineScheduler pass
118f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// for the target to instantiate a scheduler.
119f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct MachineSchedContext {
120f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  MachineFunction *MF = nullptr;
121f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  const MachineLoopInfo *MLI = nullptr;
122f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  const MachineDominatorTree *MDT = nullptr;
123f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  const TargetPassConfig *PassConfig = nullptr;
124f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  AliasAnalysis *AA = nullptr;
125f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  LiveIntervals *LIS = nullptr;
126f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
127f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  RegisterClassInfo *RegClassInfo;
128f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
129f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  MachineSchedContext();
130f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  virtual ~MachineSchedContext();
131f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
132f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
133f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// MachineSchedRegistry provides a selection of available machine instruction
134f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// schedulers.
135f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass MachineSchedRegistry : public MachinePassRegistryNode {
136f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic:
137f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  using ScheduleDAGCtor = ScheduleDAGInstrs *(*)(MachineSchedContext *);
138f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
139f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // RegisterPassParser requires a (misnamed) FunctionPassCtor type.
140f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  using FunctionPassCtor = ScheduleDAGCtor;
141f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
142f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  static MachinePassRegistry Registry;
143f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
144f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  MachineSchedRegistry(const char *N, const char *D, ScheduleDAGCtor C)
145f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    : MachinePassRegistryNode(N, D, (MachinePassCtor)C) {
146f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    Registry.Add(this);
147f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
148f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
149f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ~MachineSchedRegistry() { Registry.Remove(this); }
150f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
151f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // Accessors.
152f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  //
153f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  MachineSchedRegistry *getNext() const {
154f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return (MachineSchedRegistry *)MachinePassRegistryNode::getNext();
155f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
156f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
157f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  static MachineSchedRegistry *getList() {
158f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return (MachineSchedRegistry *)Registry.getList();
159f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
160f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
161f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  static void setListener(MachinePassRegistryListener *L) {
162f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    Registry.setListener(L);
163f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
164f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
165f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
166f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass ScheduleDAGMI;
167f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
168f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Define a generic scheduling policy for targets that don't provide their own
169f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// MachineSchedStrategy. This can be overriden for each scheduling region
170f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// before building the DAG.
171f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct MachineSchedPolicy {
172f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // Allow the scheduler to disable register pressure tracking.
173f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool ShouldTrackPressure = false;
174f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Track LaneMasks to allow reordering of independent subregister writes
175f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// of the same vreg. \sa MachineSchedStrategy::shouldTrackLaneMasks()
176f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool ShouldTrackLaneMasks = false;
177f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
178f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // Allow the scheduler to force top-down or bottom-up scheduling. If neither
179f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // is true, the scheduler runs in both directions and converges.
180f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool OnlyTopDown = false;
181f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool OnlyBottomUp = false;
182f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
183f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // Disable heuristic that tries to fetch nodes from long dependency chains
184f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // first.
185f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool DisableLatencyHeuristic = false;
186f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
187f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  MachineSchedPolicy() = default;
188f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
189f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
190f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// MachineSchedStrategy - Interface to the scheduling algorithm used by
191f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// ScheduleDAGMI.
192f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///
193f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Initialization sequence:
194f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///   initPolicy -> shouldTrackPressure -> initialize(DAG) -> registerRoots
195f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass MachineSchedStrategy {
196f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  virtual void anchor();
197f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
198f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic:
199f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  virtual ~MachineSchedStrategy() = default;
200f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
201f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Optionally override the per-region scheduling policy.
202f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  virtual void initPolicy(MachineBasicBlock::iterator Begin,
203f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                          MachineBasicBlock::iterator End,
204f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                          unsigned NumRegionInstrs) {}
205f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
206f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  virtual void dumpPolicy() const {}
207f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
208f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Check if pressure tracking is needed before building the DAG and
209f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// initializing this strategy. Called after initPolicy.
210f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  virtual bool shouldTrackPressure() const { return true; }
211f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
212f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Returns true if lanemasks should be tracked. LaneMask tracking is
213f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// necessary to reorder independent subregister defs for the same vreg.
214f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// This has to be enabled in combination with shouldTrackPressure().
215f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  virtual bool shouldTrackLaneMasks() const { return false; }
216f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
217f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // If this method returns true, handling of the scheduling regions
218f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // themselves (in case of a scheduling boundary in MBB) will be done
219f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // beginning with the topmost region of MBB.
220f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  virtual bool doMBBSchedRegionsTopDown() const { return false; }
221f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
222f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Initialize the strategy after building the DAG for a new region.
223f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  virtual void initialize(ScheduleDAGMI *DAG) = 0;
224f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
225f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Tell the strategy that MBB is about to be processed.
226f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  virtual void enterMBB(MachineBasicBlock *MBB) {};
227f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
228f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Tell the strategy that current MBB is done.
229f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  virtual void leaveMBB() {};
230f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
231f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Notify this strategy that all roots have been released (including those
232f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// that depend on EntrySU or ExitSU).
233f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  virtual void registerRoots() {}
234f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
235f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Pick the next node to schedule, or return NULL. Set IsTopNode to true to
236f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// schedule the node at the top of the unscheduled region. Otherwise it will
237f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// be scheduled at the bottom.
238f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  virtual SUnit *pickNode(bool &IsTopNode) = 0;
239f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
240f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// \brief Scheduler callback to notify that a new subtree is scheduled.
241f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  virtual void scheduleTree(unsigned SubtreeID) {}
242f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
243f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Notify MachineSchedStrategy that ScheduleDAGMI has scheduled an
244f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// instruction and updated scheduled/remaining flags in the DAG nodes.
245f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  virtual void schedNode(SUnit *SU, bool IsTopNode) = 0;
246f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
247f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// When all predecessor dependencies have been resolved, free this node for
248f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// top-down scheduling.
249f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  virtual void releaseTopNode(SUnit *SU) = 0;
250f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
251f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// When all successor dependencies have been resolved, free this node for
252f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// bottom-up scheduling.
253f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  virtual void releaseBottomNode(SUnit *SU) = 0;
254f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
255f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
256f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// ScheduleDAGMI is an implementation of ScheduleDAGInstrs that simply
257f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// schedules machine instructions according to the given MachineSchedStrategy
258f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// without much extra book-keeping. This is the common functionality between
259f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// PreRA and PostRA MachineScheduler.
260f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass ScheduleDAGMI : public ScheduleDAGInstrs {
261f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotprotected:
262f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  AliasAnalysis *AA;
263f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  LiveIntervals *LIS;
264f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  std::unique_ptr<MachineSchedStrategy> SchedImpl;
265f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
266f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Topo - A topological ordering for SUnits which permits fast IsReachable
267f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// and similar queries.
268f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ScheduleDAGTopologicalSort Topo;
269f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
270f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Ordered list of DAG postprocessing steps.
271f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  std::vector<std::unique_ptr<ScheduleDAGMutation>> Mutations;
272f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
273f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// The top of the unscheduled zone.
274f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  MachineBasicBlock::iterator CurrentTop;
275f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
276f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// The bottom of the unscheduled zone.
277f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  MachineBasicBlock::iterator CurrentBottom;
278f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
279f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Record the next node in a scheduled cluster.
280f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  const SUnit *NextClusterPred = nullptr;
281f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  const SUnit *NextClusterSucc = nullptr;
282f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
283f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#ifndef NDEBUG
284f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// The number of instructions scheduled so far. Used to cut off the
285f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// scheduler at the point determined by misched-cutoff.
286f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned NumInstrsScheduled = 0;
287f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#endif
288f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
289f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic:
290f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ScheduleDAGMI(MachineSchedContext *C, std::unique_ptr<MachineSchedStrategy> S,
291f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                bool RemoveKillFlags)
292f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      : ScheduleDAGInstrs(*C->MF, C->MLI, RemoveKillFlags), AA(C->AA),
293f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        LIS(C->LIS), SchedImpl(std::move(S)), Topo(SUnits, &ExitSU) {}
294f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
295f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // Provide a vtable anchor
296f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ~ScheduleDAGMI() override;
297f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
298f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// If this method returns true, handling of the scheduling regions
299f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// themselves (in case of a scheduling boundary in MBB) will be done
300f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// beginning with the topmost region of MBB.
301f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool doMBBSchedRegionsTopDown() const override {
302f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return SchedImpl->doMBBSchedRegionsTopDown();
303f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
304f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
305f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // Returns LiveIntervals instance for use in DAG mutators and such.
306f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  LiveIntervals *getLIS() const { return LIS; }
307f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
308f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Return true if this DAG supports VReg liveness and RegPressure.
309f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  virtual bool hasVRegLiveness() const { return false; }
310f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
311f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Add a postprocessing step to the DAG builder.
312f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Mutations are applied in the order that they are added after normal DAG
313f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// building and before MachineSchedStrategy initialization.
314f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ///
315f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// ScheduleDAGMI takes ownership of the Mutation object.
316f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void addMutation(std::unique_ptr<ScheduleDAGMutation> Mutation) {
317f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (Mutation)
318f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      Mutations.push_back(std::move(Mutation));
319f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
320f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
321f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// \brief True if an edge can be added from PredSU to SuccSU without creating
322f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// a cycle.
323f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool canAddEdge(SUnit *SuccSU, SUnit *PredSU);
324f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
325f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// \brief Add a DAG edge to the given SU with the given predecessor
326f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// dependence data.
327f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ///
328f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// \returns true if the edge may be added without creating a cycle OR if an
329f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// equivalent edge already existed (false indicates failure).
330f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool addEdge(SUnit *SuccSU, const SDep &PredDep);
331f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
332f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  MachineBasicBlock::iterator top() const { return CurrentTop; }
333f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  MachineBasicBlock::iterator bottom() const { return CurrentBottom; }
334f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
335f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Implement the ScheduleDAGInstrs interface for handling the next scheduling
336f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// region. This covers all instructions in a block, while schedule() may only
337f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// cover a subset.
338f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void enterRegion(MachineBasicBlock *bb,
339f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                   MachineBasicBlock::iterator begin,
340f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                   MachineBasicBlock::iterator end,
341f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                   unsigned regioninstrs) override;
342f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
343f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Implement ScheduleDAGInstrs interface for scheduling a sequence of
344f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// reorderable instructions.
345f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void schedule() override;
346f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
347f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void startBlock(MachineBasicBlock *bb) override;
348f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void finishBlock() override;
349f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
350f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Change the position of an instruction within the basic block and update
351f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// live ranges and region boundary iterators.
352f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void moveInstruction(MachineInstr *MI, MachineBasicBlock::iterator InsertPos);
353f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
354f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  const SUnit *getNextClusterPred() const { return NextClusterPred; }
355f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
356f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  const SUnit *getNextClusterSucc() const { return NextClusterSucc; }
357f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
358f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void viewGraph(const Twine &Name, const Twine &Title) override;
359f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void viewGraph() override;
360f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
361f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotprotected:
362f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // Top-Level entry points for the schedule() driver...
363f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
364f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Apply each ScheduleDAGMutation step in order. This allows different
365f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// instances of ScheduleDAGMI to perform custom DAG postprocessing.
366f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void postprocessDAG();
367f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
368f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Release ExitSU predecessors and setup scheduler queues.
369f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void initQueues(ArrayRef<SUnit*> TopRoots, ArrayRef<SUnit*> BotRoots);
370f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
371f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Update scheduler DAG and queues after scheduling an instruction.
372f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void updateQueues(SUnit *SU, bool IsTopNode);
373f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
374f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Reinsert debug_values recorded in ScheduleDAGInstrs::DbgValues.
375f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void placeDebugValues();
376f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
377f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// \brief dump the scheduled Sequence.
378f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void dumpSchedule() const;
379f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
380f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // Lesser helpers...
381f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool checkSchedLimit();
382f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
383f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void findRootsAndBiasEdges(SmallVectorImpl<SUnit*> &TopRoots,
384f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                             SmallVectorImpl<SUnit*> &BotRoots);
385f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
386f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void releaseSucc(SUnit *SU, SDep *SuccEdge);
387f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void releaseSuccessors(SUnit *SU);
388f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void releasePred(SUnit *SU, SDep *PredEdge);
389f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void releasePredecessors(SUnit *SU);
390f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
391f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
392f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// ScheduleDAGMILive is an implementation of ScheduleDAGInstrs that schedules
393f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// machine instructions while updating LiveIntervals and tracking regpressure.
394f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass ScheduleDAGMILive : public ScheduleDAGMI {
395f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotprotected:
396f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  RegisterClassInfo *RegClassInfo;
397f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
398f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Information about DAG subtrees. If DFSResult is NULL, then SchedulerTrees
399f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// will be empty.
400f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  SchedDFSResult *DFSResult = nullptr;
401f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  BitVector ScheduledTrees;
402f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
403f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  MachineBasicBlock::iterator LiveRegionEnd;
404f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
405f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Maps vregs to the SUnits of their uses in the current scheduling region.
406f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  VReg2SUnitMultiMap VRegUses;
407f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
408f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // Map each SU to its summary of pressure changes. This array is updated for
409f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // liveness during bottom-up scheduling. Top-down scheduling may proceed but
410f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // has no affect on the pressure diffs.
411f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  PressureDiffs SUPressureDiffs;
412f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
413f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Register pressure in this region computed by initRegPressure.
414f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool ShouldTrackPressure = false;
415f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool ShouldTrackLaneMasks = false;
416f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  IntervalPressure RegPressure;
417f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  RegPressureTracker RPTracker;
418f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
419f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// List of pressure sets that exceed the target's pressure limit before
420f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// scheduling, listed in increasing set ID order. Each pressure set is paired
421f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// with its max pressure in the currently scheduled regions.
422f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  std::vector<PressureChange> RegionCriticalPSets;
423f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
424f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// The top of the unscheduled zone.
425f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  IntervalPressure TopPressure;
426f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  RegPressureTracker TopRPTracker;
427f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
428f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// The bottom of the unscheduled zone.
429f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  IntervalPressure BotPressure;
430f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  RegPressureTracker BotRPTracker;
431f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
432f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// True if disconnected subregister components are already renamed.
433f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// The renaming is only done on demand if lane masks are tracked.
434f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool DisconnectedComponentsRenamed = false;
435f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
436f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic:
437f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ScheduleDAGMILive(MachineSchedContext *C,
438f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                    std::unique_ptr<MachineSchedStrategy> S)
439f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      : ScheduleDAGMI(C, std::move(S), /*RemoveKillFlags=*/false),
440f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        RegClassInfo(C->RegClassInfo), RPTracker(RegPressure),
441f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        TopRPTracker(TopPressure), BotRPTracker(BotPressure) {}
442f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
443f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ~ScheduleDAGMILive() override;
444f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
445f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Return true if this DAG supports VReg liveness and RegPressure.
446f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool hasVRegLiveness() const override { return true; }
447f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
448f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// \brief Return true if register pressure tracking is enabled.
449f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool isTrackingPressure() const { return ShouldTrackPressure; }
450f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
451f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Get current register pressure for the top scheduled instructions.
452f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  const IntervalPressure &getTopPressure() const { return TopPressure; }
453f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  const RegPressureTracker &getTopRPTracker() const { return TopRPTracker; }
454f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
455f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Get current register pressure for the bottom scheduled instructions.
456f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  const IntervalPressure &getBotPressure() const { return BotPressure; }
457f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  const RegPressureTracker &getBotRPTracker() const { return BotRPTracker; }
458f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
459f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Get register pressure for the entire scheduling region before scheduling.
460f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  const IntervalPressure &getRegPressure() const { return RegPressure; }
461f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
462f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  const std::vector<PressureChange> &getRegionCriticalPSets() const {
463f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return RegionCriticalPSets;
464f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
465f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
466f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  PressureDiff &getPressureDiff(const SUnit *SU) {
467f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return SUPressureDiffs[SU->NodeNum];
468f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
469f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
470f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Compute a DFSResult after DAG building is complete, and before any
471f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// queue comparisons.
472f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void computeDFSResult();
473f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
474f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Return a non-null DFS result if the scheduling strategy initialized it.
475f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  const SchedDFSResult *getDFSResult() const { return DFSResult; }
476f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
477f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  BitVector &getScheduledTrees() { return ScheduledTrees; }
478f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
479f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Implement the ScheduleDAGInstrs interface for handling the next scheduling
480f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// region. This covers all instructions in a block, while schedule() may only
481f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// cover a subset.
482f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void enterRegion(MachineBasicBlock *bb,
483f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                   MachineBasicBlock::iterator begin,
484f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                   MachineBasicBlock::iterator end,
485f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                   unsigned regioninstrs) override;
486f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
487f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Implement ScheduleDAGInstrs interface for scheduling a sequence of
488f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// reorderable instructions.
489f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void schedule() override;
490f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
491f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Compute the cyclic critical path through the DAG.
492f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned computeCyclicCriticalPath();
493f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
494f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotprotected:
495f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // Top-Level entry points for the schedule() driver...
496f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
497f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Call ScheduleDAGInstrs::buildSchedGraph with register pressure tracking
498f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// enabled. This sets up three trackers. RPTracker will cover the entire DAG
499f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// region, TopTracker and BottomTracker will be initialized to the top and
500f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// bottom of the DAG region without covereing any unscheduled instruction.
501f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void buildDAGWithRegPressure();
502f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
503f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Release ExitSU predecessors and setup scheduler queues. Re-position
504f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// the Top RP tracker in case the region beginning has changed.
505f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void initQueues(ArrayRef<SUnit*> TopRoots, ArrayRef<SUnit*> BotRoots);
506f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
507f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Move an instruction and update register pressure.
508f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void scheduleMI(SUnit *SU, bool IsTopNode);
509f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
510f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // Lesser helpers...
511f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
512f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void initRegPressure();
513f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
514f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void updatePressureDiffs(ArrayRef<RegisterMaskPair> LiveUses);
515f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
516f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void updateScheduledPressure(const SUnit *SU,
517f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                               const std::vector<unsigned> &NewMaxPressure);
518f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
519f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void collectVRegUses(SUnit &SU);
520f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
521f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
522f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===//
523f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///
524f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Helpers for implementing custom MachineSchedStrategy classes. These take
525f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// care of the book-keeping associated with list scheduling heuristics.
526f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///
527f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===//
528f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
529f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// ReadyQueue encapsulates vector of "ready" SUnits with basic convenience
530f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// methods for pushing and removing nodes. ReadyQueue's are uniquely identified
531f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// by an ID. SUnit::NodeQueueId is a mask of the ReadyQueues the SUnit is in.
532f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///
533f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// This is a convenience class that may be used by implementations of
534f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// MachineSchedStrategy.
535f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass ReadyQueue {
536f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned ID;
537f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  std::string Name;
538f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  std::vector<SUnit*> Queue;
539f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
540f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic:
541f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ReadyQueue(unsigned id, const Twine &name): ID(id), Name(name.str()) {}
542f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
543f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned getID() const { return ID; }
544f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
545f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  StringRef getName() const { return Name; }
546f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
547f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // SU is in this queue if it's NodeQueueID is a superset of this ID.
548f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool isInQueue(SUnit *SU) const { return (SU->NodeQueueId & ID); }
549f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
550f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool empty() const { return Queue.empty(); }
551f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
552f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void clear() { Queue.clear(); }
553f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
554f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned size() const { return Queue.size(); }
555f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
556f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  using iterator = std::vector<SUnit*>::iterator;
557f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
558f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  iterator begin() { return Queue.begin(); }
559f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
560f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  iterator end() { return Queue.end(); }
561f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
562f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ArrayRef<SUnit*> elements() { return Queue; }
563f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
564f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  iterator find(SUnit *SU) { return llvm::find(Queue, SU); }
565f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
566f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void push(SUnit *SU) {
567f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    Queue.push_back(SU);
568f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    SU->NodeQueueId |= ID;
569f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
570f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
571f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  iterator remove(iterator I) {
572f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    (*I)->NodeQueueId &= ~ID;
573f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    *I = Queue.back();
574f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    unsigned idx = I - Queue.begin();
575f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    Queue.pop_back();
576f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return Queue.begin() + idx;
577f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
578f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
579f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void dump() const;
580f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
581f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
582f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Summarize the unscheduled region.
583f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct SchedRemainder {
584f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // Critical path through the DAG in expected latency.
585f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned CriticalPath;
586f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned CyclicCritPath;
587f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
588f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // Scaled count of micro-ops left to schedule.
589f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned RemIssueCount;
590f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
591f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool IsAcyclicLatencyLimited;
592f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
593f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // Unscheduled resources
594f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  SmallVector<unsigned, 16> RemainingCounts;
595f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
596f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  SchedRemainder() { reset(); }
597f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
598f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void reset() {
599f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    CriticalPath = 0;
600f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    CyclicCritPath = 0;
601f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    RemIssueCount = 0;
602f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    IsAcyclicLatencyLimited = false;
603f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    RemainingCounts.clear();
604f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
605f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
606f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void init(ScheduleDAGMI *DAG, const TargetSchedModel *SchedModel);
607f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
608f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
609f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Each Scheduling boundary is associated with ready queues. It tracks the
610f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// current cycle in the direction of movement, and maintains the state
611f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// of "hazards" and other interlocks at the current cycle.
612f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass SchedBoundary {
613f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic:
614f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// SUnit::NodeQueueId: 0 (none), 1 (top), 2 (bot), 3 (both)
615f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  enum {
616f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    TopQID = 1,
617f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    BotQID = 2,
618f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    LogMaxQID = 2
619f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  };
620f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
621f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ScheduleDAGMI *DAG = nullptr;
622f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  const TargetSchedModel *SchedModel = nullptr;
623f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  SchedRemainder *Rem = nullptr;
624f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
625f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ReadyQueue Available;
626f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ReadyQueue Pending;
627f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
628f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ScheduleHazardRecognizer *HazardRec = nullptr;
629f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
630f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotprivate:
631f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// True if the pending Q should be checked/updated before scheduling another
632f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// instruction.
633f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool CheckPending;
634f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
635f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Number of cycles it takes to issue the instructions scheduled in this
636f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// zone. It is defined as: scheduled-micro-ops / issue-width + stalls.
637f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// See getStalls().
638f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned CurrCycle;
639f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
640f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Micro-ops issued in the current cycle
641f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned CurrMOps;
642f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
643f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// MinReadyCycle - Cycle of the soonest available instruction.
644f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned MinReadyCycle;
645f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
646f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // The expected latency of the critical path in this scheduled zone.
647f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned ExpectedLatency;
648f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
649f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // The latency of dependence chains leading into this zone.
650f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // For each node scheduled bottom-up: DLat = max DLat, N.Depth.
651f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // For each cycle scheduled: DLat -= 1.
652f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned DependentLatency;
653f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
654f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Count the scheduled (issued) micro-ops that can be retired by
655f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// time=CurrCycle assuming the first scheduled instr is retired at time=0.
656f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned RetiredMOps;
657f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
658f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // Count scheduled resources that have been executed. Resources are
659f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // considered executed if they become ready in the time that it takes to
660f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // saturate any resource including the one in question. Counts are scaled
661f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // for direct comparison with other resources. Counts can be compared with
662f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // MOps * getMicroOpFactor and Latency * getLatencyFactor.
663f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  SmallVector<unsigned, 16> ExecutedResCounts;
664f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
665f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Cache the max count for a single resource.
666f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned MaxExecutedResCount;
667f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
668f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // Cache the critical resources ID in this scheduled zone.
669f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned ZoneCritResIdx;
670f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
671f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // Is the scheduled region resource limited vs. latency limited.
672f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool IsResourceLimited;
673f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
674f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // Record the highest cycle at which each resource has been reserved by a
675f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // scheduled instruction.
676f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  SmallVector<unsigned, 16> ReservedCycles;
677f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
678f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#ifndef NDEBUG
679f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // Remember the greatest possible stall as an upper bound on the number of
680f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // times we should retry the pending queue because of a hazard.
681f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned MaxObservedStall;
682f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#endif
683f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
684f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic:
685f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Pending queues extend the ready queues with the same ID and the
686f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// PendingFlag set.
687f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  SchedBoundary(unsigned ID, const Twine &Name):
688f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    Available(ID, Name+".A"), Pending(ID << LogMaxQID, Name+".P") {
689f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    reset();
690f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
691f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
692f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ~SchedBoundary();
693f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
694f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void reset();
695f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
696f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void init(ScheduleDAGMI *dag, const TargetSchedModel *smodel,
697f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot            SchedRemainder *rem);
698f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
699f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool isTop() const {
700f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return Available.getID() == TopQID;
701f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
702f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
703f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Number of cycles to issue the instructions scheduled in this zone.
704f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned getCurrCycle() const { return CurrCycle; }
705f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
706f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Micro-ops issued in the current cycle
707f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned getCurrMOps() const { return CurrMOps; }
708f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
709f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // The latency of dependence chains leading into this zone.
710f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned getDependentLatency() const { return DependentLatency; }
711f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
712f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Get the number of latency cycles "covered" by the scheduled
713f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// instructions. This is the larger of the critical path within the zone
714f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// and the number of cycles required to issue the instructions.
715f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned getScheduledLatency() const {
716f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return std::max(ExpectedLatency, CurrCycle);
717f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
718f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
719f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned getUnscheduledLatency(SUnit *SU) const {
720f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return isTop() ? SU->getHeight() : SU->getDepth();
721f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
722f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
723f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned getResourceCount(unsigned ResIdx) const {
724f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return ExecutedResCounts[ResIdx];
725f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
726f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
727f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Get the scaled count of scheduled micro-ops and resources, including
728f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// executed resources.
729f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned getCriticalCount() const {
730f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (!ZoneCritResIdx)
731f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return RetiredMOps * SchedModel->getMicroOpFactor();
732f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return getResourceCount(ZoneCritResIdx);
733f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
734f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
735f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Get a scaled count for the minimum execution time of the scheduled
736f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// micro-ops that are ready to execute by getExecutedCount. Notice the
737f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// feedback loop.
738f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned getExecutedCount() const {
739f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return std::max(CurrCycle * SchedModel->getLatencyFactor(),
740f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                    MaxExecutedResCount);
741f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
742f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
743f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned getZoneCritResIdx() const { return ZoneCritResIdx; }
744f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
745f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // Is the scheduled region resource limited vs. latency limited.
746f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool isResourceLimited() const { return IsResourceLimited; }
747f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
748f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Get the difference between the given SUnit's ready time and the current
749f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// cycle.
750f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned getLatencyStallCycles(SUnit *SU);
751f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
752f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned getNextResourceCycle(unsigned PIdx, unsigned Cycles);
753f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
754f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool checkHazard(SUnit *SU);
755f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
756f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned findMaxLatency(ArrayRef<SUnit*> ReadySUs);
757f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
758f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned getOtherResourceCount(unsigned &OtherCritIdx);
759f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
760f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void releaseNode(SUnit *SU, unsigned ReadyCycle);
761f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
762f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void bumpCycle(unsigned NextCycle);
763f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
764f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void incExecutedResources(unsigned PIdx, unsigned Count);
765f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
766f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned countResource(unsigned PIdx, unsigned Cycles, unsigned ReadyCycle);
767f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
768f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void bumpNode(SUnit *SU);
769f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
770f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void releasePending();
771f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
772f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void removeReady(SUnit *SU);
773f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
774f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Call this before applying any other heuristics to the Available queue.
775f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Updates the Available/Pending Q's if necessary and returns the single
776f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// available instruction, or NULL if there are multiple candidates.
777f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  SUnit *pickOnlyChoice();
778f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
779f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void dumpScheduledState() const;
780f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
781f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
782f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Base class for GenericScheduler. This class maintains information about
783f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// scheduling candidates based on TargetSchedModel making it easy to implement
784f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// heuristics for either preRA or postRA scheduling.
785f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass GenericSchedulerBase : public MachineSchedStrategy {
786f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic:
787f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Represent the type of SchedCandidate found within a single queue.
788f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// pickNodeBidirectional depends on these listed by decreasing priority.
789f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  enum CandReason : uint8_t {
790f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    NoCand, Only1, PhysRegCopy, RegExcess, RegCritical, Stall, Cluster, Weak,
791f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    RegMax, ResourceReduce, ResourceDemand, BotHeightReduce, BotPathReduce,
792f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    TopDepthReduce, TopPathReduce, NextDefUse, NodeOrder};
793f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
794f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#ifndef NDEBUG
795f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  static const char *getReasonStr(GenericSchedulerBase::CandReason Reason);
796f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#endif
797f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
798f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Policy for scheduling the next instruction in the candidate's zone.
799f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  struct CandPolicy {
800f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    bool ReduceLatency = false;
801f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    unsigned ReduceResIdx = 0;
802f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    unsigned DemandResIdx = 0;
803f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
804f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    CandPolicy() = default;
805f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
806f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    bool operator==(const CandPolicy &RHS) const {
807f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return ReduceLatency == RHS.ReduceLatency &&
808f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot             ReduceResIdx == RHS.ReduceResIdx &&
809f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot             DemandResIdx == RHS.DemandResIdx;
810f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    }
811f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    bool operator!=(const CandPolicy &RHS) const {
812f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return !(*this == RHS);
813f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    }
814f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  };
815f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
816f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Status of an instruction's critical resource consumption.
817f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  struct SchedResourceDelta {
818f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    // Count critical resources in the scheduled region required by SU.
819f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    unsigned CritResources = 0;
820f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
821f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    // Count critical resources from another region consumed by SU.
822f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    unsigned DemandedResources = 0;
823f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
824f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    SchedResourceDelta() = default;
825f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
826f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    bool operator==(const SchedResourceDelta &RHS) const {
827f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return CritResources == RHS.CritResources
828f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        && DemandedResources == RHS.DemandedResources;
829f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    }
830f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    bool operator!=(const SchedResourceDelta &RHS) const {
831f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return !operator==(RHS);
832f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    }
833f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  };
834f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
835f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Store the state used by GenericScheduler heuristics, required for the
836f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// lifetime of one invocation of pickNode().
837f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  struct SchedCandidate {
838f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    CandPolicy Policy;
839f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
840f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    // The best SUnit candidate.
841f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    SUnit *SU;
842f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
843f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    // The reason for this candidate.
844f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    CandReason Reason;
845f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
846f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    // Whether this candidate should be scheduled at top/bottom.
847f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    bool AtTop;
848f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
849f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    // Register pressure values for the best candidate.
850f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    RegPressureDelta RPDelta;
851f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
852f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    // Critical resource consumption of the best candidate.
853f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    SchedResourceDelta ResDelta;
854f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
855f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    SchedCandidate() { reset(CandPolicy()); }
856f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    SchedCandidate(const CandPolicy &Policy) { reset(Policy); }
857f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
858f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    void reset(const CandPolicy &NewPolicy) {
859f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      Policy = NewPolicy;
860f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      SU = nullptr;
861f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      Reason = NoCand;
862f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      AtTop = false;
863f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      RPDelta = RegPressureDelta();
864f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      ResDelta = SchedResourceDelta();
865f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    }
866f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
867f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    bool isValid() const { return SU; }
868f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
869f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    // Copy the status of another candidate without changing policy.
870f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    void setBest(SchedCandidate &Best) {
871f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      assert(Best.Reason != NoCand && "uninitialized Sched candidate");
872f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      SU = Best.SU;
873f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      Reason = Best.Reason;
874f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      AtTop = Best.AtTop;
875f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      RPDelta = Best.RPDelta;
876f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      ResDelta = Best.ResDelta;
877f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    }
878f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
879f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    void initResourceDelta(const ScheduleDAGMI *DAG,
880f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                           const TargetSchedModel *SchedModel);
881f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  };
882f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
883f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotprotected:
884f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  const MachineSchedContext *Context;
885f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  const TargetSchedModel *SchedModel = nullptr;
886f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  const TargetRegisterInfo *TRI = nullptr;
887f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
888f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  SchedRemainder Rem;
889f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
890f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  GenericSchedulerBase(const MachineSchedContext *C) : Context(C) {}
891f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
892f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void setPolicy(CandPolicy &Policy, bool IsPostRA, SchedBoundary &CurrZone,
893f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                 SchedBoundary *OtherZone);
894f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
895f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#ifndef NDEBUG
896f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void traceCandidate(const SchedCandidate &Cand);
897f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#endif
898f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
899f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
900f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// GenericScheduler shrinks the unscheduled zone using heuristics to balance
901f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// the schedule.
902f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass GenericScheduler : public GenericSchedulerBase {
903f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic:
904f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  GenericScheduler(const MachineSchedContext *C):
905f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    GenericSchedulerBase(C), Top(SchedBoundary::TopQID, "TopQ"),
906f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    Bot(SchedBoundary::BotQID, "BotQ") {}
907f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
908f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void initPolicy(MachineBasicBlock::iterator Begin,
909f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                  MachineBasicBlock::iterator End,
910f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                  unsigned NumRegionInstrs) override;
911f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
912f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void dumpPolicy() const override;
913f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
914f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool shouldTrackPressure() const override {
915f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return RegionPolicy.ShouldTrackPressure;
916f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
917f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
918f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool shouldTrackLaneMasks() const override {
919f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return RegionPolicy.ShouldTrackLaneMasks;
920f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
921f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
922f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void initialize(ScheduleDAGMI *dag) override;
923f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
924f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  SUnit *pickNode(bool &IsTopNode) override;
925f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
926f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void schedNode(SUnit *SU, bool IsTopNode) override;
927f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
928f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void releaseTopNode(SUnit *SU) override {
929f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (SU->isScheduled)
930f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return;
931f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
932f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    Top.releaseNode(SU, SU->TopReadyCycle);
933f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    TopCand.SU = nullptr;
934f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
935f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
936f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void releaseBottomNode(SUnit *SU) override {
937f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (SU->isScheduled)
938f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return;
939f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
940f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    Bot.releaseNode(SU, SU->BotReadyCycle);
941f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    BotCand.SU = nullptr;
942f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
943f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
944f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void registerRoots() override;
945f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
946f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotprotected:
947f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ScheduleDAGMILive *DAG = nullptr;
948f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
949f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  MachineSchedPolicy RegionPolicy;
950f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
951f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // State of the top and bottom scheduled instruction boundaries.
952f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  SchedBoundary Top;
953f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  SchedBoundary Bot;
954f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
955f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Candidate last picked from Top boundary.
956f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  SchedCandidate TopCand;
957f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Candidate last picked from Bot boundary.
958f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  SchedCandidate BotCand;
959f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
960f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void checkAcyclicLatency();
961f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
962f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void initCandidate(SchedCandidate &Cand, SUnit *SU, bool AtTop,
963f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                     const RegPressureTracker &RPTracker,
964f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                     RegPressureTracker &TempTracker);
965f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
966f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void tryCandidate(SchedCandidate &Cand,
967f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                    SchedCandidate &TryCand,
968f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                    SchedBoundary *Zone);
969f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
970f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  SUnit *pickNodeBidirectional(bool &IsTopNode);
971f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
972f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void pickNodeFromQueue(SchedBoundary &Zone,
973f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                         const CandPolicy &ZonePolicy,
974f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                         const RegPressureTracker &RPTracker,
975f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                         SchedCandidate &Candidate);
976f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
977f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void reschedulePhysRegCopies(SUnit *SU, bool isTop);
978f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
979f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
980f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// PostGenericScheduler - Interface to the scheduling algorithm used by
981f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// ScheduleDAGMI.
982f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///
983f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Callbacks from ScheduleDAGMI:
984f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///   initPolicy -> initialize(DAG) -> registerRoots -> pickNode ...
985f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass PostGenericScheduler : public GenericSchedulerBase {
986f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ScheduleDAGMI *DAG;
987f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  SchedBoundary Top;
988f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  SmallVector<SUnit*, 8> BotRoots;
989f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
990f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic:
991f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  PostGenericScheduler(const MachineSchedContext *C):
992f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    GenericSchedulerBase(C), Top(SchedBoundary::TopQID, "TopQ") {}
993f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
994f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ~PostGenericScheduler() override = default;
995f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
996f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void initPolicy(MachineBasicBlock::iterator Begin,
997f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                  MachineBasicBlock::iterator End,
998f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                  unsigned NumRegionInstrs) override {
999f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    /* no configurable policy */
1000f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
1001f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1002f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// PostRA scheduling does not track pressure.
1003f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool shouldTrackPressure() const override { return false; }
1004f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1005f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void initialize(ScheduleDAGMI *Dag) override;
1006f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1007f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void registerRoots() override;
1008f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1009f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  SUnit *pickNode(bool &IsTopNode) override;
1010f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1011f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void scheduleTree(unsigned SubtreeID) override {
1012f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    llvm_unreachable("PostRA scheduler does not support subtree analysis.");
1013f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
1014f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1015f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void schedNode(SUnit *SU, bool IsTopNode) override;
1016f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1017f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void releaseTopNode(SUnit *SU) override {
1018f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (SU->isScheduled)
1019f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return;
1020f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    Top.releaseNode(SU, SU->TopReadyCycle);
1021f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
1022f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1023f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // Only called for roots.
1024f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void releaseBottomNode(SUnit *SU) override {
1025f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    BotRoots.push_back(SU);
1026f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
1027f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1028f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotprotected:
1029f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void tryCandidate(SchedCandidate &Cand, SchedCandidate &TryCand);
1030f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1031f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void pickNodeFromQueue(SchedCandidate &Cand);
1032f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
1033f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1034f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Create the standard converging machine scheduler. This will be used as the
1035f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// default scheduler if the target does not set a default.
1036f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Adds default DAG mutations.
1037f3014761c955345d6e05491608e73228d014afbandroid-build-team RobotScheduleDAGMILive *createGenericSchedLive(MachineSchedContext *C);
1038f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1039f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Create a generic scheduler with no vreg liveness or DAG mutation passes.
1040f3014761c955345d6e05491608e73228d014afbandroid-build-team RobotScheduleDAGMI *createGenericSchedPostRA(MachineSchedContext *C);
1041f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1042f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstd::unique_ptr<ScheduleDAGMutation>
1043f3014761c955345d6e05491608e73228d014afbandroid-build-team RobotcreateLoadClusterDAGMutation(const TargetInstrInfo *TII,
1044f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                             const TargetRegisterInfo *TRI);
1045f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1046f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstd::unique_ptr<ScheduleDAGMutation>
1047f3014761c955345d6e05491608e73228d014afbandroid-build-team RobotcreateStoreClusterDAGMutation(const TargetInstrInfo *TII,
1048f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                              const TargetRegisterInfo *TRI);
1049f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1050f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstd::unique_ptr<ScheduleDAGMutation>
1051f3014761c955345d6e05491608e73228d014afbandroid-build-team RobotcreateCopyConstrainDAGMutation(const TargetInstrInfo *TII,
1052f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                               const TargetRegisterInfo *TRI);
1053f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1054f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot} // end namespace llvm
1055f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1056f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#endif // LLVM_CODEGEN_MACHINESCHEDULER_H
1057