forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			133 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			133 lines
		
	
	
		
			4.2 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
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
///
 | 
						|
/// \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/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
 |