1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
//===- 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
|