Home | History | Annotate | Download | only in AMDGPU
      1 //===- GCNIterativeScheduler.h - GCN Scheduler ------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #ifndef LLVM_LIB_TARGET_AMDGPU_GCNITERATIVESCHEDULER_H
     11 #define LLVM_LIB_TARGET_AMDGPU_GCNITERATIVESCHEDULER_H
     12 
     13 #include "GCNRegPressure.h"
     14 #include "llvm/ADT/ArrayRef.h"
     15 #include "llvm/CodeGen/MachineBasicBlock.h"
     16 #include "llvm/CodeGen/MachineScheduler.h"
     17 #include "llvm/Support/Allocator.h"
     18 #include <limits>
     19 #include <memory>
     20 #include <vector>
     21 
     22 namespace llvm {
     23 
     24 class MachineInstr;
     25 class SUnit;
     26 class raw_ostream;
     27 
     28 class GCNIterativeScheduler : public ScheduleDAGMILive {
     29   using BaseClass = ScheduleDAGMILive;
     30 
     31 public:
     32   enum StrategyKind {
     33     SCHEDULE_MINREGONLY,
     34     SCHEDULE_MINREGFORCED,
     35     SCHEDULE_LEGACYMAXOCCUPANCY,
     36     SCHEDULE_ILP
     37   };
     38 
     39   GCNIterativeScheduler(MachineSchedContext *C,
     40                         StrategyKind S);
     41 
     42   void schedule() override;
     43 
     44   void enterRegion(MachineBasicBlock *BB,
     45                    MachineBasicBlock::iterator Begin,
     46                    MachineBasicBlock::iterator End,
     47                    unsigned RegionInstrs) override;
     48 
     49   void finalizeSchedule() override;
     50 
     51 protected:
     52   using ScheduleRef = ArrayRef<const SUnit *>;
     53 
     54   struct TentativeSchedule {
     55     std::vector<MachineInstr *> Schedule;
     56     GCNRegPressure MaxPressure;
     57   };
     58 
     59   struct Region {
     60     // Fields except for BestSchedule are supposed to reflect current IR state
     61     // `const` fields are to emphasize they shouldn't change for any schedule.
     62     MachineBasicBlock::iterator Begin;
     63     // End is either a boundary instruction or end of basic block
     64     const MachineBasicBlock::iterator End;
     65     const unsigned NumRegionInstrs;
     66     GCNRegPressure MaxPressure;
     67 
     68     // best schedule for the region so far (not scheduled yet)
     69     std::unique_ptr<TentativeSchedule> BestSchedule;
     70   };
     71 
     72   SpecificBumpPtrAllocator<Region> Alloc;
     73   std::vector<Region*> Regions;
     74 
     75   MachineSchedContext *Context;
     76   const StrategyKind Strategy;
     77   mutable GCNUpwardRPTracker UPTracker;
     78 
     79   class BuildDAG;
     80   class OverrideLegacyStrategy;
     81 
     82   template <typename Range>
     83   GCNRegPressure getSchedulePressure(const Region &R,
     84                                      Range &&Schedule) const;
     85 
     86   GCNRegPressure getRegionPressure(MachineBasicBlock::iterator Begin,
     87                                    MachineBasicBlock::iterator End) const;
     88 
     89   GCNRegPressure getRegionPressure(const Region &R) const {
     90     return getRegionPressure(R.Begin, R.End);
     91   }
     92 
     93   void setBestSchedule(Region &R,
     94                        ScheduleRef Schedule,
     95                        const GCNRegPressure &MaxRP = GCNRegPressure());
     96 
     97   void scheduleBest(Region &R);
     98 
     99   std::vector<MachineInstr*> detachSchedule(ScheduleRef Schedule) const;
    100 
    101   void sortRegionsByPressure(unsigned TargetOcc);
    102 
    103   template <typename Range>
    104   void scheduleRegion(Region &R, Range &&Schedule,
    105                       const GCNRegPressure &MaxRP = GCNRegPressure());
    106 
    107   unsigned tryMaximizeOccupancy(unsigned TargetOcc =
    108                                 std::numeric_limits<unsigned>::max());
    109 
    110   void scheduleLegacyMaxOccupancy(bool TryMaximizeOccupancy = true);
    111   void scheduleMinReg(bool force = false);
    112   void scheduleILP(bool TryMaximizeOccupancy = true);
    113 
    114   void printRegions(raw_ostream &OS) const;
    115   void printSchedResult(raw_ostream &OS,
    116                         const Region *R,
    117                         const GCNRegPressure &RP) const;
    118   void printSchedRP(raw_ostream &OS,
    119                     const GCNRegPressure &Before,
    120                     const GCNRegPressure &After) const;
    121 };
    122 
    123 } // end namespace llvm
    124 
    125 #endif // LLVM_LIB_TARGET_AMDGPU_GCNITERATIVESCHEDULER_H
    126