127 lines
4.0 KiB
C
127 lines
4.0 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/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
|