| //===- GCNIterativeScheduler.h - GCN Scheduler ------------------*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| /// |
| /// \file |
| /// This file defines the class GCNIterativeScheduler, which uses an iterative |
| /// approach to find a best schedule for GCN architecture. It basically makes |
| /// use of various lightweight schedules, scores them, chooses best one based on |
| /// their scores, and finally implements the chosen one. |
| /// |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLVM_LIB_TARGET_AMDGPU_GCNITERATIVESCHEDULER_H |
| #define LLVM_LIB_TARGET_AMDGPU_GCNITERATIVESCHEDULER_H |
| |
| #include "GCNRegPressure.h" |
| #include "llvm/CodeGen/MachineScheduler.h" |
| |
| namespace llvm { |
| |
| class MachineInstr; |
| class SUnit; |
| class raw_ostream; |
| |
| class GCNIterativeScheduler : public ScheduleDAGMILive { |
| using BaseClass = ScheduleDAGMILive; |
| |
| public: |
| enum StrategyKind { |
| SCHEDULE_MINREGONLY, |
| SCHEDULE_MINREGFORCED, |
| SCHEDULE_LEGACYMAXOCCUPANCY, |
| SCHEDULE_ILP |
| }; |
| |
| GCNIterativeScheduler(MachineSchedContext *C, |
| StrategyKind S); |
| |
| void schedule() override; |
| |
| void enterRegion(MachineBasicBlock *BB, |
| MachineBasicBlock::iterator Begin, |
| MachineBasicBlock::iterator End, |
| unsigned RegionInstrs) override; |
| |
| void finalizeSchedule() override; |
| |
| protected: |
| using ScheduleRef = ArrayRef<const SUnit *>; |
| |
| struct TentativeSchedule { |
| std::vector<MachineInstr *> Schedule; |
| GCNRegPressure MaxPressure; |
| }; |
| |
| struct Region { |
| // Fields except for BestSchedule are supposed to reflect current IR state |
| // `const` fields are to emphasize they shouldn't change for any schedule. |
| MachineBasicBlock::iterator Begin; |
| // End is either a boundary instruction or end of basic block |
| const MachineBasicBlock::iterator End; |
| const unsigned NumRegionInstrs; |
| GCNRegPressure MaxPressure; |
| |
| // best schedule for the region so far (not scheduled yet) |
| std::unique_ptr<TentativeSchedule> BestSchedule; |
| }; |
| |
| SpecificBumpPtrAllocator<Region> Alloc; |
| std::vector<Region*> Regions; |
| |
| MachineSchedContext *Context; |
| const StrategyKind Strategy; |
| mutable GCNUpwardRPTracker UPTracker; |
| |
| class BuildDAG; |
| class OverrideLegacyStrategy; |
| |
| template <typename Range> |
| GCNRegPressure getSchedulePressure(const Region &R, |
| Range &&Schedule) const; |
| |
| GCNRegPressure getRegionPressure(MachineBasicBlock::iterator Begin, |
| MachineBasicBlock::iterator End) const; |
| |
| GCNRegPressure getRegionPressure(const Region &R) const { |
| return getRegionPressure(R.Begin, R.End); |
| } |
| |
| void setBestSchedule(Region &R, |
| ScheduleRef Schedule, |
| const GCNRegPressure &MaxRP = GCNRegPressure()); |
| |
| void scheduleBest(Region &R); |
| |
| std::vector<MachineInstr*> detachSchedule(ScheduleRef Schedule) const; |
| |
| void sortRegionsByPressure(unsigned TargetOcc); |
| |
| template <typename Range> |
| void scheduleRegion(Region &R, Range &&Schedule, |
| const GCNRegPressure &MaxRP = GCNRegPressure()); |
| |
| unsigned tryMaximizeOccupancy(unsigned TargetOcc = |
| std::numeric_limits<unsigned>::max()); |
| |
| void scheduleLegacyMaxOccupancy(bool TryMaximizeOccupancy = true); |
| void scheduleMinReg(bool force = false); |
| void scheduleILP(bool TryMaximizeOccupancy = true); |
| |
| void printRegions(raw_ostream &OS) const; |
| void printSchedResult(raw_ostream &OS, |
| const Region *R, |
| const GCNRegPressure &RP) const; |
| void printSchedRP(raw_ostream &OS, |
| const GCNRegPressure &Before, |
| const GCNRegPressure &After) const; |
| }; |
| |
| } // end namespace llvm |
| |
| #endif // LLVM_LIB_TARGET_AMDGPU_GCNITERATIVESCHEDULER_H |