summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/AMDGPU/GCNIterativeScheduler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/AMDGPU/GCNIterativeScheduler.cpp')
-rw-r--r--llvm/lib/Target/AMDGPU/GCNIterativeScheduler.cpp51
1 files changed, 48 insertions, 3 deletions
diff --git a/llvm/lib/Target/AMDGPU/GCNIterativeScheduler.cpp b/llvm/lib/Target/AMDGPU/GCNIterativeScheduler.cpp
index 9e743850f9a..942063d5f93 100644
--- a/llvm/lib/Target/AMDGPU/GCNIterativeScheduler.cpp
+++ b/llvm/lib/Target/AMDGPU/GCNIterativeScheduler.cpp
@@ -39,7 +39,9 @@ namespace llvm {
std::vector<const SUnit *> makeMinRegSchedule(ArrayRef<const SUnit *> TopRoots,
const ScheduleDAG &DAG);
-} // end namespace llvm
+ std::vector<const SUnit*> makeGCNILPScheduler(ArrayRef<const SUnit*> BotRoots,
+ const ScheduleDAG &DAG);
+}
// shim accessors for different order containers
static inline MachineInstr *getMachineInstr(MachineInstr *MI) {
@@ -141,6 +143,7 @@ class GCNIterativeScheduler::BuildDAG {
GCNIterativeScheduler &Sch;
SmallVector<SUnit *, 8> TopRoots;
+ SmallVector<SUnit*, 8> BotRoots;
public:
BuildDAG(const Region &R, GCNIterativeScheduler &_Sch)
: Sch(_Sch) {
@@ -151,8 +154,6 @@ public:
Sch.buildSchedGraph(Sch.AA, nullptr, nullptr, nullptr,
/*TrackLaneMask*/true);
Sch.Topo.InitDAGTopologicalSorting();
-
- SmallVector<SUnit *, 8> BotRoots;
Sch.findRootsAndBiasEdges(TopRoots, BotRoots);
}
@@ -164,6 +165,9 @@ public:
ArrayRef<const SUnit *> getTopRoots() const {
return TopRoots;
}
+ ArrayRef<SUnit*> getBottomRoots() const {
+ return BotRoots;
+ }
};
class GCNIterativeScheduler::OverrideLegacyStrategy {
@@ -323,6 +327,7 @@ void GCNIterativeScheduler::finalizeSchedule() { // overriden
case SCHEDULE_MINREGONLY: scheduleMinReg(); break;
case SCHEDULE_MINREGFORCED: scheduleMinReg(true); break;
case SCHEDULE_LEGACYMAXOCCUPANCY: scheduleLegacyMaxOccupancy(); break;
+ case SCHEDULE_ILP: scheduleILP(false); break;
}
}
@@ -553,3 +558,43 @@ void GCNIterativeScheduler::scheduleMinReg(bool force) {
MaxPressure = RP;
}
}
+
+///////////////////////////////////////////////////////////////////////////////
+// ILP scheduler port
+
+void GCNIterativeScheduler::scheduleILP(
+ bool TryMaximizeOccupancy) {
+ const auto &ST = MF.getSubtarget<SISubtarget>();
+ auto TgtOcc = std::min(ST.getOccupancyWithLocalMemSize(MF),
+ ST.getWavesPerEU(*MF.getFunction()).second);
+
+ sortRegionsByPressure(TgtOcc);
+ auto Occ = Regions.front()->MaxPressure.getOccupancy(ST);
+
+ if (TryMaximizeOccupancy && Occ < TgtOcc)
+ Occ = tryMaximizeOccupancy(TgtOcc);
+
+ TgtOcc = std::min(Occ, TgtOcc);
+ DEBUG(dbgs() << "Scheduling using default scheduler, "
+ "target occupancy = " << TgtOcc << '\n');
+
+ for (auto R : Regions) {
+ BuildDAG DAG(*R, *this);
+ const auto ILPSchedule = makeGCNILPScheduler(DAG.getBottomRoots(), *this);
+
+ const auto RP = getSchedulePressure(*R, ILPSchedule);
+ DEBUG(printSchedRP(dbgs(), R->MaxPressure, RP));
+
+ if (RP.getOccupancy(ST) < TgtOcc) {
+ DEBUG(dbgs() << "Didn't fit into target occupancy O" << TgtOcc);
+ if (R->BestSchedule.get() &&
+ R->BestSchedule->MaxPressure.getOccupancy(ST) >= TgtOcc) {
+ DEBUG(dbgs() << ", scheduling minimal register\n");
+ scheduleBest(*R);
+ }
+ } else {
+ scheduleRegion(*R, ILPSchedule, RP);
+ DEBUG(printSchedResult(dbgs(), R, RP));
+ }
+ }
+}
OpenPOWER on IntegriCloud