|  | //===-- GCNSchedStrategy.h - GCN Scheduler Strategy -*- C++ -*-------------===// | 
|  | // | 
|  | //                     The LLVM Compiler Infrastructure | 
|  | // | 
|  | // This file is distributed under the University of Illinois Open Source | 
|  | // License. See LICENSE.TXT for details. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  | // | 
|  | /// \file | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #ifndef LLVM_LIB_TARGET_AMDGPU_GCNSCHEDSTRATEGY_H | 
|  | #define LLVM_LIB_TARGET_AMDGPU_GCNSCHEDSTRATEGY_H | 
|  |  | 
|  | #include "GCNRegPressure.h" | 
|  | #include "llvm/CodeGen/MachineScheduler.h" | 
|  |  | 
|  | namespace llvm { | 
|  |  | 
|  | class SIMachineFunctionInfo; | 
|  | class SIRegisterInfo; | 
|  | class SISubtarget; | 
|  |  | 
|  | /// This is a minimal scheduler strategy.  The main difference between this | 
|  | /// and the GenericScheduler is that GCNSchedStrategy uses different | 
|  | /// heuristics to determine excess/critical pressure sets.  Its goal is to | 
|  | /// maximize kernel occupancy (i.e. maximum number of waves per simd). | 
|  | class GCNMaxOccupancySchedStrategy : public GenericScheduler { | 
|  | friend class GCNScheduleDAGMILive; | 
|  |  | 
|  | SUnit *pickNodeBidirectional(bool &IsTopNode); | 
|  |  | 
|  | void pickNodeFromQueue(SchedBoundary &Zone, const CandPolicy &ZonePolicy, | 
|  | const RegPressureTracker &RPTracker, | 
|  | SchedCandidate &Cand); | 
|  |  | 
|  | void initCandidate(SchedCandidate &Cand, SUnit *SU, | 
|  | bool AtTop, const RegPressureTracker &RPTracker, | 
|  | const SIRegisterInfo *SRI, | 
|  | unsigned SGPRPressure, unsigned VGPRPressure); | 
|  |  | 
|  | unsigned SGPRExcessLimit; | 
|  | unsigned VGPRExcessLimit; | 
|  | unsigned SGPRCriticalLimit; | 
|  | unsigned VGPRCriticalLimit; | 
|  |  | 
|  | unsigned TargetOccupancy; | 
|  |  | 
|  | MachineFunction *MF; | 
|  |  | 
|  | public: | 
|  | GCNMaxOccupancySchedStrategy(const MachineSchedContext *C); | 
|  |  | 
|  | SUnit *pickNode(bool &IsTopNode) override; | 
|  |  | 
|  | void initialize(ScheduleDAGMI *DAG) override; | 
|  |  | 
|  | void setTargetOccupancy(unsigned Occ) { TargetOccupancy = Occ; } | 
|  | }; | 
|  |  | 
|  | class GCNScheduleDAGMILive : public ScheduleDAGMILive { | 
|  |  | 
|  | const SISubtarget &ST; | 
|  |  | 
|  | SIMachineFunctionInfo &MFI; | 
|  |  | 
|  | // Occupancy target at the beginning of function scheduling cycle. | 
|  | unsigned StartingOccupancy; | 
|  |  | 
|  | // Minimal real occupancy recorder for the function. | 
|  | unsigned MinOccupancy; | 
|  |  | 
|  | // Scheduling stage number. | 
|  | unsigned Stage; | 
|  |  | 
|  | // Current region index. | 
|  | size_t RegionIdx; | 
|  |  | 
|  | // Vecor of regions recorder for later rescheduling | 
|  | SmallVector<std::pair<MachineBasicBlock::iterator, | 
|  | MachineBasicBlock::iterator>, 32> Regions; | 
|  |  | 
|  | // Region live-in cache. | 
|  | SmallVector<GCNRPTracker::LiveRegSet, 32> LiveIns; | 
|  |  | 
|  | // Region pressure cache. | 
|  | SmallVector<GCNRegPressure, 32> Pressure; | 
|  |  | 
|  | // Temporary basic block live-in cache. | 
|  | DenseMap<const MachineBasicBlock*, GCNRPTracker::LiveRegSet> MBBLiveIns; | 
|  |  | 
|  | // Return current region pressure. | 
|  | GCNRegPressure getRealRegPressure() const; | 
|  |  | 
|  | // Compute and cache live-ins and pressure for all regions in block. | 
|  | void computeBlockPressure(const MachineBasicBlock *MBB); | 
|  |  | 
|  |  | 
|  | public: | 
|  | GCNScheduleDAGMILive(MachineSchedContext *C, | 
|  | std::unique_ptr<MachineSchedStrategy> S); | 
|  |  | 
|  | void schedule() override; | 
|  |  | 
|  | void finalizeSchedule() override; | 
|  | }; | 
|  |  | 
|  | } // End namespace llvm | 
|  |  | 
|  | #endif // GCNSCHEDSTRATEGY_H |