125 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			125 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===- 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
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #ifndef LLVM_LIB_TARGET_AMDGPU_GCNITERATIVESCHEDULER_H
 | |
| #define LLVM_LIB_TARGET_AMDGPU_GCNITERATIVESCHEDULER_H
 | |
| 
 | |
| #include "GCNRegPressure.h"
 | |
| #include "llvm/ADT/ArrayRef.h"
 | |
| #include "llvm/CodeGen/MachineBasicBlock.h"
 | |
| #include "llvm/CodeGen/MachineScheduler.h"
 | |
| #include "llvm/Support/Allocator.h"
 | |
| #include <limits>
 | |
| #include <memory>
 | |
| #include <vector>
 | |
| 
 | |
| 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
 |