diff options
author | Cullen Rhodes <cullen.rhodes@arm.com> | 2025-05-09 10:06:35 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-05-09 10:06:35 +0100 |
commit | cdde6a650a0773e672c81b61aa53d9af2c92d2b2 (patch) | |
tree | 3b9a9d1130aa89e16032deaf2e826218411815aa | |
parent | 36bb17aa6544c1f62309a6162555262f282e1d13 (diff) | |
download | llvm-cdde6a650a0773e672c81b61aa53d9af2c92d2b2.zip llvm-cdde6a650a0773e672c81b61aa53d9af2c92d2b2.tar.gz llvm-cdde6a650a0773e672c81b61aa53d9af2c92d2b2.tar.bz2 |
[MISched] Add statistics for heuristics (#137981)
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.
-rw-r--r-- | llvm/lib/CodeGen/MachineScheduler.cpp | 241 |
1 files changed, 228 insertions, 13 deletions
diff --git a/llvm/lib/CodeGen/MachineScheduler.cpp b/llvm/lib/CodeGen/MachineScheduler.cpp index b8a7eb6..236c55c 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; |