130 lines · c
1//===- GCNIterativeScheduler.h - GCN Scheduler ------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// This file defines the class GCNIterativeScheduler, which uses an iterative11/// approach to find a best schedule for GCN architecture. It basically makes12/// use of various lightweight schedules, scores them, chooses best one based on13/// their scores, and finally implements the chosen one.14///15//===----------------------------------------------------------------------===//16 17#ifndef LLVM_LIB_TARGET_AMDGPU_GCNITERATIVESCHEDULER_H18#define LLVM_LIB_TARGET_AMDGPU_GCNITERATIVESCHEDULER_H19 20#include "GCNRegPressure.h"21#include "llvm/CodeGen/MachineScheduler.h"22 23namespace llvm {24 25class MachineInstr;26class SUnit;27class raw_ostream;28 29class GCNIterativeScheduler : public ScheduleDAGMILive {30 using BaseClass = ScheduleDAGMILive;31 32public:33 enum StrategyKind {34 SCHEDULE_MINREGONLY,35 SCHEDULE_MINREGFORCED,36 SCHEDULE_LEGACYMAXOCCUPANCY,37 SCHEDULE_ILP38 };39 40 GCNIterativeScheduler(MachineSchedContext *C,41 StrategyKind S);42 43 void schedule() override;44 45 void enterRegion(MachineBasicBlock *BB,46 MachineBasicBlock::iterator Begin,47 MachineBasicBlock::iterator End,48 unsigned RegionInstrs) override;49 50 void finalizeSchedule() override;51 52protected:53 using ScheduleRef = ArrayRef<const SUnit *>;54 55 struct TentativeSchedule {56 std::vector<MachineInstr *> Schedule;57 GCNRegPressure MaxPressure;58 };59 60 struct Region {61 // Fields except for BestSchedule are supposed to reflect current IR state62 // `const` fields are to emphasize they shouldn't change for any schedule.63 MachineBasicBlock::iterator Begin;64 // End is either a boundary instruction or end of basic block65 const MachineBasicBlock::iterator End;66 const unsigned NumRegionInstrs;67 GCNRegPressure MaxPressure;68 69 // best schedule for the region so far (not scheduled yet)70 std::unique_ptr<TentativeSchedule> BestSchedule;71 };72 73 SpecificBumpPtrAllocator<Region> Alloc;74 std::vector<Region*> Regions;75 76 MachineSchedContext *Context;77 const StrategyKind Strategy;78 mutable GCNUpwardRPTracker UPTracker;79 80 std::vector<std::unique_ptr<ScheduleDAGMutation>> SavedMutations;81 82 class BuildDAG;83 class OverrideLegacyStrategy;84 85 template <typename Range>86 GCNRegPressure getSchedulePressure(const Region &R,87 Range &&Schedule) const;88 89 GCNRegPressure getRegionPressure(MachineBasicBlock::iterator Begin,90 MachineBasicBlock::iterator End) const;91 92 GCNRegPressure getRegionPressure(const Region &R) const {93 return getRegionPressure(R.Begin, R.End);94 }95 96 void swapIGLPMutations(const Region &R, bool IsReentry);97 void setBestSchedule(Region &R,98 ScheduleRef Schedule,99 const GCNRegPressure &MaxRP = GCNRegPressure());100 101 void scheduleBest(Region &R);102 103 std::vector<MachineInstr*> detachSchedule(ScheduleRef Schedule) const;104 105 void sortRegionsByPressure(unsigned TargetOcc);106 107 template <typename Range>108 void scheduleRegion(Region &R, Range &&Schedule,109 const GCNRegPressure &MaxRP = GCNRegPressure());110 111 unsigned tryMaximizeOccupancy(unsigned TargetOcc =112 std::numeric_limits<unsigned>::max());113 114 void scheduleLegacyMaxOccupancy(bool TryMaximizeOccupancy = true);115 void scheduleMinReg(bool force = false);116 void scheduleILP(bool TryMaximizeOccupancy = true);117 118 void printRegions(raw_ostream &OS) const;119 void printSchedResult(raw_ostream &OS,120 const Region *R,121 const GCNRegPressure &RP) const;122 void printSchedRP(raw_ostream &OS,123 const GCNRegPressure &Before,124 const GCNRegPressure &After) const;125};126 127} // end namespace llvm128 129#endif // LLVM_LIB_TARGET_AMDGPU_GCNITERATIVESCHEDULER_H130