[llvm] [MISched] Add statistics for heuristics (PR #137981)
Cullen Rhodes via llvm-commits
llvm-commits at lists.llvm.org
Fri May 9 00:56:52 PDT 2025
https://github.com/c-rhodes updated https://github.com/llvm/llvm-project/pull/137981
>From 04411f4c518759692e8be75b4f037a2b0d33bab9 Mon Sep 17 00:00:00 2001
From: Cullen Rhodes <cullen.rhodes at arm.com>
Date: Fri, 31 Jan 2025 14:21:49 +0000
Subject: [PATCH] [MISched] Add statistics for heuristics
When diagnosing scheduling issues it can be useful to know which
heuristics are driving the scheduler. This adds pre-RA and post-RA
statistics for all heuristics.
---
llvm/lib/CodeGen/MachineScheduler.cpp | 241 ++++++++++++++++++++++++--
1 file changed, 228 insertions(+), 13 deletions(-)
diff --git a/llvm/lib/CodeGen/MachineScheduler.cpp b/llvm/lib/CodeGen/MachineScheduler.cpp
index b8a7eb6b4068b..236c55cb04142 100644
--- a/llvm/lib/CodeGen/MachineScheduler.cpp
+++ b/llvm/lib/CodeGen/MachineScheduler.cpp
@@ -84,6 +84,97 @@ STATISTIC(NumInstrsScheduledPostRA,
"Number of instructions scheduled by post-RA scheduler");
STATISTIC(NumClustered, "Number of load/store pairs clustered");
+STATISTIC(NumTopPreRA,
+ "Number of scheduling units chosen from top queue pre-RA");
+STATISTIC(NumBotPreRA,
+ "Number of scheduling units chosen from bottom queue pre-RA");
+STATISTIC(NumNoCandPreRA,
+ "Number of scheduling units chosen for NoCand heuristic pre-RA");
+STATISTIC(NumOnly1PreRA,
+ "Number of scheduling units chosen for Only1 heuristic pre-RA");
+STATISTIC(NumPhysRegPreRA,
+ "Number of scheduling units chosen for PhysReg heuristic pre-RA");
+STATISTIC(NumRegExcessPreRA,
+ "Number of scheduling units chosen for RegExcess heuristic pre-RA");
+STATISTIC(NumRegCriticalPreRA,
+ "Number of scheduling units chosen for RegCritical heuristic pre-RA");
+STATISTIC(NumStallPreRA,
+ "Number of scheduling units chosen for Stall heuristic pre-RA");
+STATISTIC(NumClusterPreRA,
+ "Number of scheduling units chosen for Cluster heuristic pre-RA");
+STATISTIC(NumWeakPreRA,
+ "Number of scheduling units chosen for Weak heuristic pre-RA");
+STATISTIC(NumRegMaxPreRA,
+ "Number of scheduling units chosen for RegMax heuristic pre-RA");
+STATISTIC(
+ NumResourceReducePreRA,
+ "Number of scheduling units chosen for ResourceReduce heuristic pre-RA");
+STATISTIC(
+ NumResourceDemandPreRA,
+ "Number of scheduling units chosen for ResourceDemand heuristic pre-RA");
+STATISTIC(
+ NumTopDepthReducePreRA,
+ "Number of scheduling units chosen for TopDepthReduce heuristic pre-RA");
+STATISTIC(
+ NumTopPathReducePreRA,
+ "Number of scheduling units chosen for TopPathReduce heuristic pre-RA");
+STATISTIC(
+ NumBotHeightReducePreRA,
+ "Number of scheduling units chosen for BotHeightReduce heuristic pre-RA");
+STATISTIC(
+ NumBotPathReducePreRA,
+ "Number of scheduling units chosen for BotPathReduce heuristic pre-RA");
+STATISTIC(NumNodeOrderPreRA,
+ "Number of scheduling units chosen for NodeOrder heuristic pre-RA");
+STATISTIC(NumFirstValidPreRA,
+ "Number of scheduling units chosen for FirstValid heuristic pre-RA");
+
+STATISTIC(NumTopPostRA,
+ "Number of scheduling units chosen from top queue post-RA");
+STATISTIC(NumBotPostRA,
+ "Number of scheduling units chosen from bottom queue post-RA");
+STATISTIC(NumNoCandPostRA,
+ "Number of scheduling units chosen for NoCand heuristic post-RA");
+STATISTIC(NumOnly1PostRA,
+ "Number of scheduling units chosen for Only1 heuristic post-RA");
+STATISTIC(NumPhysRegPostRA,
+ "Number of scheduling units chosen for PhysReg heuristic post-RA");
+STATISTIC(NumRegExcessPostRA,
+ "Number of scheduling units chosen for RegExcess heuristic post-RA");
+STATISTIC(
+ NumRegCriticalPostRA,
+ "Number of scheduling units chosen for RegCritical heuristic post-RA");
+STATISTIC(NumStallPostRA,
+ "Number of scheduling units chosen for Stall heuristic post-RA");
+STATISTIC(NumClusterPostRA,
+ "Number of scheduling units chosen for Cluster heuristic post-RA");
+STATISTIC(NumWeakPostRA,
+ "Number of scheduling units chosen for Weak heuristic post-RA");
+STATISTIC(NumRegMaxPostRA,
+ "Number of scheduling units chosen for RegMax heuristic post-RA");
+STATISTIC(
+ NumResourceReducePostRA,
+ "Number of scheduling units chosen for ResourceReduce heuristic post-RA");
+STATISTIC(
+ NumResourceDemandPostRA,
+ "Number of scheduling units chosen for ResourceDemand heuristic post-RA");
+STATISTIC(
+ NumTopDepthReducePostRA,
+ "Number of scheduling units chosen for TopDepthReduce heuristic post-RA");
+STATISTIC(
+ NumTopPathReducePostRA,
+ "Number of scheduling units chosen for TopPathReduce heuristic post-RA");
+STATISTIC(
+ NumBotHeightReducePostRA,
+ "Number of scheduling units chosen for BotHeightReduce heuristic post-RA");
+STATISTIC(
+ NumBotPathReducePostRA,
+ "Number of scheduling units chosen for BotPathReduce heuristic post-RA");
+STATISTIC(NumNodeOrderPostRA,
+ "Number of scheduling units chosen for NodeOrder heuristic post-RA");
+STATISTIC(NumFirstValidPostRA,
+ "Number of scheduling units chosen for FirstValid heuristic post-RA");
+
namespace llvm {
cl::opt<MISched::Direction> PreRADirection(
@@ -3430,13 +3521,137 @@ bool tryLatency(GenericSchedulerBase::SchedCandidate &TryCand,
}
} // end namespace llvm
-static void tracePick(GenericSchedulerBase::CandReason Reason, bool IsTop) {
+static void tracePick(GenericSchedulerBase::CandReason Reason, bool IsTop,
+ bool IsPostRA = false) {
LLVM_DEBUG(dbgs() << "Pick " << (IsTop ? "Top " : "Bot ")
- << GenericSchedulerBase::getReasonStr(Reason) << '\n');
+ << GenericSchedulerBase::getReasonStr(Reason) << " ["
+ << (IsPostRA ? "post-RA" : "pre-RA") << "]\n");
+
+ if (IsPostRA) {
+ if (IsTop)
+ NumTopPostRA++;
+ else
+ NumBotPostRA++;
+
+ switch (Reason) {
+ case GenericScheduler::NoCand:
+ NumNoCandPostRA++;
+ return;
+ case GenericScheduler::Only1:
+ NumOnly1PostRA++;
+ return;
+ case GenericScheduler::PhysReg:
+ NumPhysRegPostRA++;
+ return;
+ case GenericScheduler::RegExcess:
+ NumRegExcessPostRA++;
+ return;
+ case GenericScheduler::RegCritical:
+ NumRegCriticalPostRA++;
+ return;
+ case GenericScheduler::Stall:
+ NumStallPostRA++;
+ return;
+ case GenericScheduler::Cluster:
+ NumClusterPostRA++;
+ return;
+ case GenericScheduler::Weak:
+ NumWeakPostRA++;
+ return;
+ case GenericScheduler::RegMax:
+ NumRegMaxPostRA++;
+ return;
+ case GenericScheduler::ResourceReduce:
+ NumResourceReducePostRA++;
+ return;
+ case GenericScheduler::ResourceDemand:
+ NumResourceDemandPostRA++;
+ return;
+ case GenericScheduler::TopDepthReduce:
+ NumTopDepthReducePostRA++;
+ return;
+ case GenericScheduler::TopPathReduce:
+ NumTopPathReducePostRA++;
+ return;
+ case GenericScheduler::BotHeightReduce:
+ NumBotHeightReducePostRA++;
+ return;
+ case GenericScheduler::BotPathReduce:
+ NumBotPathReducePostRA++;
+ return;
+ case GenericScheduler::NodeOrder:
+ NumNodeOrderPostRA++;
+ return;
+ case GenericScheduler::FirstValid:
+ NumFirstValidPostRA++;
+ return;
+ };
+ } else {
+ if (IsTop)
+ NumTopPreRA++;
+ else
+ NumBotPreRA++;
+
+ switch (Reason) {
+ case GenericScheduler::NoCand:
+ NumNoCandPreRA++;
+ return;
+ case GenericScheduler::Only1:
+ NumOnly1PreRA++;
+ return;
+ case GenericScheduler::PhysReg:
+ NumPhysRegPreRA++;
+ return;
+ case GenericScheduler::RegExcess:
+ NumRegExcessPreRA++;
+ return;
+ case GenericScheduler::RegCritical:
+ NumRegCriticalPreRA++;
+ return;
+ case GenericScheduler::Stall:
+ NumStallPreRA++;
+ return;
+ case GenericScheduler::Cluster:
+ NumClusterPreRA++;
+ return;
+ case GenericScheduler::Weak:
+ NumWeakPreRA++;
+ return;
+ case GenericScheduler::RegMax:
+ NumRegMaxPreRA++;
+ return;
+ case GenericScheduler::ResourceReduce:
+ NumResourceReducePreRA++;
+ return;
+ case GenericScheduler::ResourceDemand:
+ NumResourceDemandPreRA++;
+ return;
+ case GenericScheduler::TopDepthReduce:
+ NumTopDepthReducePreRA++;
+ return;
+ case GenericScheduler::TopPathReduce:
+ NumTopPathReducePreRA++;
+ return;
+ case GenericScheduler::BotHeightReduce:
+ NumBotHeightReducePreRA++;
+ return;
+ case GenericScheduler::BotPathReduce:
+ NumBotPathReducePreRA++;
+ return;
+ case GenericScheduler::NodeOrder:
+ NumNodeOrderPreRA++;
+ return;
+ case GenericScheduler::FirstValid:
+ NumFirstValidPreRA++;
+ return;
+ };
+ }
+ llvm_unreachable("Unknown reason!");
}
-static void tracePick(const GenericSchedulerBase::SchedCandidate &Cand) {
- tracePick(Cand.Reason, Cand.AtTop);
+static void tracePick(const GenericSchedulerBase::SchedCandidate &Cand,
+ bool IsPostRA = false) {
+ tracePick(Cand.Reason, Cand.AtTop, IsPostRA);
}
void GenericScheduler::initialize(ScheduleDAGMI *dag) {
@@ -3862,12 +4077,12 @@ SUnit *GenericScheduler::pickNodeBidirectional(bool &IsTopNode) {
// efficient, but also provides the best heuristics for CriticalPSets.
if (SUnit *SU = Bot.pickOnlyChoice()) {
IsTopNode = false;
- tracePick(Only1, false);
+ tracePick(Only1, /*IsTopNode=*/false);
return SU;
}
if (SUnit *SU = Top.pickOnlyChoice()) {
IsTopNode = true;
- tracePick(Only1, true);
+ tracePick(Only1, /*IsTopNode=*/true);
return SU;
}
// Set the bottom-up policy based on the state of the current bottom zone and
@@ -4224,12 +4439,12 @@ SUnit *PostGenericScheduler::pickNodeBidirectional(bool &IsTopNode) {
// efficient, but also provides the best heuristics for CriticalPSets.
if (SUnit *SU = Bot.pickOnlyChoice()) {
IsTopNode = false;
- tracePick(Only1, false);
+ tracePick(Only1, /*IsTopNode=*/false, /*IsPostRA=*/true);
return SU;
}
if (SUnit *SU = Top.pickOnlyChoice()) {
IsTopNode = true;
- tracePick(Only1, true);
+ tracePick(Only1, /*IsTopNode=*/true, /*IsPostRA=*/true);
return SU;
}
// Set the bottom-up policy based on the state of the current bottom zone and
@@ -4292,7 +4507,7 @@ SUnit *PostGenericScheduler::pickNodeBidirectional(bool &IsTopNode) {
}
IsTopNode = Cand.AtTop;
- tracePick(Cand);
+ tracePick(Cand, /*IsPostRA=*/true);
return Cand.SU;
}
@@ -4308,7 +4523,7 @@ SUnit *PostGenericScheduler::pickNode(bool &IsTopNode) {
if (RegionPolicy.OnlyBottomUp) {
SU = Bot.pickOnlyChoice();
if (SU) {
- tracePick(Only1, true);
+ tracePick(Only1, /*IsTopNode=*/true, /*IsPostRA=*/true);
} else {
CandPolicy NoPolicy;
BotCand.reset(NoPolicy);
@@ -4317,14 +4532,14 @@ SUnit *PostGenericScheduler::pickNode(bool &IsTopNode) {
setPolicy(BotCand.Policy, /*IsPostRA=*/true, Bot, nullptr);
pickNodeFromQueue(Bot, BotCand);
assert(BotCand.Reason != NoCand && "failed to find a candidate");
- tracePick(BotCand);
+ tracePick(BotCand, /*IsPostRA=*/true);
SU = BotCand.SU;
}
IsTopNode = false;
} else if (RegionPolicy.OnlyTopDown) {
SU = Top.pickOnlyChoice();
if (SU) {
- tracePick(Only1, true);
+ tracePick(Only1, /*IsTopNode=*/true, /*IsPostRA=*/true);
} else {
CandPolicy NoPolicy;
TopCand.reset(NoPolicy);
@@ -4333,7 +4548,7 @@ SUnit *PostGenericScheduler::pickNode(bool &IsTopNode) {
setPolicy(TopCand.Policy, /*IsPostRA=*/true, Top, nullptr);
pickNodeFromQueue(Top, TopCand);
assert(TopCand.Reason != NoCand && "failed to find a candidate");
- tracePick(TopCand);
+ tracePick(TopCand, /*IsPostRA=*/true);
SU = TopCand.SU;
}
IsTopNode = true;
More information about the llvm-commits
mailing list