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