diff options
Diffstat (limited to 'contrib/llvm/lib/Target/AMDGPU/GCNSchedStrategy.h')
-rw-r--r-- | contrib/llvm/lib/Target/AMDGPU/GCNSchedStrategy.h | 70 |
1 files changed, 64 insertions, 6 deletions
diff --git a/contrib/llvm/lib/Target/AMDGPU/GCNSchedStrategy.h b/contrib/llvm/lib/Target/AMDGPU/GCNSchedStrategy.h index 4cfc0ce..060d2ca 100644 --- a/contrib/llvm/lib/Target/AMDGPU/GCNSchedStrategy.h +++ b/contrib/llvm/lib/Target/AMDGPU/GCNSchedStrategy.h @@ -14,17 +14,21 @@ #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); @@ -35,18 +39,72 @@ class GCNMaxOccupancySchedStrategy : public GenericScheduler { void initCandidate(SchedCandidate &Cand, SUnit *SU, bool AtTop, const RegPressureTracker &RPTracker, const SIRegisterInfo *SRI, - int SGPRPressure, int VGPRPressure, - int SGPRExcessLimit, int VGPRExcessLimit, - int SGPRCriticalLimit, int VGPRCriticalLimit); + unsigned SGPRPressure, unsigned VGPRPressure); - void tryCandidate(SchedCandidate &Cand, SchedCandidate &TryCand, - SchedBoundary *Zone, 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; + + const 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 |