[llvm] [NFC][MISched][AMDGPU] Expose tracePick to be used in AMDGPU backend (PR #184664)

via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 4 11:07:23 PST 2026


https://github.com/lijinpei-amd created https://github.com/llvm/llvm-project/pull/184664

- Fix wrong IsTopNode for `PostGenericScheduler::pickNode`.
- Add tracePick to pre-ra pickOnlyChoice.
- Applies eaff28c9 to GCNSchedStrategy
- Fix in-accurate GCNSchedStrategy::tryCandidate reason.

>From be1142ec9f7dee602c081664a28c41301f0953c1 Mon Sep 17 00:00:00 2001
From: Li Jinpei <jinpli at amd.com>
Date: Wed, 4 Mar 2026 15:07:39 +0800
Subject: [PATCH] [NFC][MISched][AMDGPU] Expose tracePick to be used in AMDGPU
 backend

- Fix wrong IsTopNode for `PostGenericScheduler::pickNode`.
- Add tracePick to pre-ra pickOnlyChoice.
- Applies eaff28c9 to GCNSchedStrategy
- Fix in-accurate GCNSchedStrategy::tryCandidate reason.
---
 llvm/include/llvm/CodeGen/MachineScheduler.h  |  6 ++
 llvm/lib/CodeGen/MachineScheduler.cpp         | 19 ++---
 .../lib/Target/AMDGPU/AMDGPUTargetMachine.cpp |  4 +-
 llvm/lib/Target/AMDGPU/GCNSchedStrategy.cpp   | 82 +++++++++++--------
 llvm/lib/Target/AMDGPU/GCNSchedStrategy.h     |  8 +-
 5 files changed, 70 insertions(+), 49 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/MachineScheduler.h b/llvm/include/llvm/CodeGen/MachineScheduler.h
index 33036030679e5..65d20f5192765 100644
--- a/llvm/include/llvm/CodeGen/MachineScheduler.h
+++ b/llvm/include/llvm/CodeGen/MachineScheduler.h
@@ -1204,6 +1204,12 @@ class GenericSchedulerBase : public MachineSchedStrategy {
                                     const TargetSchedModel *SchedModel);
   };
 
+  static void tracePick(CandReason Reason, bool IsTop, bool IsPostRA = false);
+
+  static void tracePick(const SchedCandidate &Cand, bool IsPostRA = false) {
+    tracePick(Cand.Reason, Cand.AtTop, IsPostRA);
+  }
+
 protected:
   const MachineSchedContext *Context;
   const TargetSchedModel *SchedModel = nullptr;
diff --git a/llvm/lib/CodeGen/MachineScheduler.cpp b/llvm/lib/CodeGen/MachineScheduler.cpp
index 6697c0a110dc3..4fff90a81fc38 100644
--- a/llvm/lib/CodeGen/MachineScheduler.cpp
+++ b/llvm/lib/CodeGen/MachineScheduler.cpp
@@ -3505,8 +3505,8 @@ bool llvm::tryLatency(GenericSchedulerBase::SchedCandidate &TryCand,
   return false;
 }
 
-static void tracePick(GenericSchedulerBase::CandReason Reason, bool IsTop,
-                      bool IsPostRA = false) {
+void GenericSchedulerBase::tracePick(CandReason Reason, bool IsTop,
+                                     bool IsPostRA) {
   LLVM_DEBUG(dbgs() << "Pick " << (IsTop ? "Top " : "Bot ")
                     << GenericSchedulerBase::getReasonStr(Reason) << " ["
                     << (IsPostRA ? "post-RA" : "pre-RA") << "]\n");
@@ -3633,11 +3633,6 @@ static void tracePick(GenericSchedulerBase::CandReason Reason, bool IsTop,
   llvm_unreachable("Unknown reason!");
 }
 
-static void tracePick(const GenericSchedulerBase::SchedCandidate &Cand,
-                      bool IsPostRA = false) {
-  tracePick(Cand.Reason, Cand.AtTop, IsPostRA);
-}
-
 void GenericScheduler::initialize(ScheduleDAGMI *dag) {
   assert(dag->hasVRegLiveness() &&
          "(PreRA)GenericScheduler needs vreg liveness");
@@ -4146,7 +4141,9 @@ SUnit *GenericScheduler::pickNode(bool &IsTopNode) {
   SUnit *SU;
   if (RegionPolicy.OnlyTopDown) {
     SU = Top.pickOnlyChoice();
-    if (!SU) {
+    if (SU) {
+      tracePick(Only1, /*IsTopNode=*/true, /*IsPostRA=*/false);
+    } else {
       CandPolicy NoPolicy;
       TopCand.reset(NoPolicy);
       pickNodeFromQueue(Top, NoPolicy, DAG->getTopRPTracker(), TopCand);
@@ -4157,7 +4154,9 @@ SUnit *GenericScheduler::pickNode(bool &IsTopNode) {
     IsTopNode = true;
   } else if (RegionPolicy.OnlyBottomUp) {
     SU = Bot.pickOnlyChoice();
-    if (!SU) {
+    if (SU) {
+      tracePick(Only1, /*IsTopNode=*/false, /*IsPostRA=*/false);
+    } else {
       CandPolicy NoPolicy;
       BotCand.reset(NoPolicy);
       pickNodeFromQueue(Bot, NoPolicy, DAG->getBotRPTracker(), BotCand);
@@ -4513,7 +4512,7 @@ SUnit *PostGenericScheduler::pickNode(bool &IsTopNode) {
   if (RegionPolicy.OnlyBottomUp) {
     SU = Bot.pickOnlyChoice();
     if (SU) {
-      tracePick(Only1, /*IsTopNode=*/true, /*IsPostRA=*/true);
+      tracePick(Only1, /*IsTopNode=*/false, /*IsPostRA=*/true);
     } else {
       CandPolicy NoPolicy;
       BotCand.reset(NoPolicy);
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
index 5b3effbcc7179..51a5bdfc38876 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
@@ -1268,8 +1268,8 @@ GCNTargetMachine::createMachineScheduler(MachineSchedContext *C) const {
 ScheduleDAGInstrs *
 GCNTargetMachine::createPostMachineScheduler(MachineSchedContext *C) const {
   ScheduleDAGMI *DAG =
-      new GCNPostScheduleDAGMILive(C, std::make_unique<PostGenericScheduler>(C),
-                                   /*RemoveKillFlags=*/true);
+      new GCNPostScheduleDAGMI(C, std::make_unique<PostGenericScheduler>(C),
+                               /*RemoveKillFlags=*/true);
   const GCNSubtarget &ST = C->MF->getSubtarget<GCNSubtarget>();
   DAG->addMutation(createLoadClusterDAGMutation(DAG->TII, DAG->TRI));
   if (ST.shouldClusterStores())
diff --git a/llvm/lib/Target/AMDGPU/GCNSchedStrategy.cpp b/llvm/lib/Target/AMDGPU/GCNSchedStrategy.cpp
index 77c322eb3178e..29e96ebb6db03 100644
--- a/llvm/lib/Target/AMDGPU/GCNSchedStrategy.cpp
+++ b/llvm/lib/Target/AMDGPU/GCNSchedStrategy.cpp
@@ -466,10 +466,12 @@ SUnit *GCNSchedStrategy::pickNodeBidirectional(bool &IsTopNode,
   // efficient, but also provides the best heuristics for CriticalPSets.
   if (SUnit *SU = pickOnlyChoice(Bot, SchedModel)) {
     IsTopNode = false;
+    tracePick(Only1, /*IsTopNode=*/false);
     return SU;
   }
   if (SUnit *SU = pickOnlyChoice(Top, SchedModel)) {
     IsTopNode = true;
+    tracePick(Only1, /*IsTopNode=*/true);
     return SU;
   }
   // Set the bottom-up policy based on the state of the current bottom zone
@@ -552,6 +554,7 @@ SUnit *GCNSchedStrategy::pickNodeBidirectional(bool &IsTopNode,
   LLVM_DEBUG(dbgs() << "Picking: "; traceCandidate(Cand););
 
   IsTopNode = Cand.AtTop;
+  tracePick(Cand);
   return Cand.SU;
 }
 
@@ -565,36 +568,41 @@ SUnit *GCNSchedStrategy::pickNode(bool &IsTopNode) {
   }
   bool PickedPending;
   SUnit *SU;
-  do {
-    PickedPending = false;
-    if (RegionPolicy.OnlyTopDown) {
-      SU = pickOnlyChoice(Top, SchedModel);
-      if (!SU) {
-        CandPolicy NoPolicy;
-        TopCand.reset(NoPolicy);
-        pickNodeFromQueue(Top, NoPolicy, DAG->getTopRPTracker(), TopCand,
-                          PickedPending,
-                          /*IsBottomUp=*/false);
-        assert(TopCand.Reason != NoCand && "failed to find a candidate");
-        SU = TopCand.SU;
-      }
-      IsTopNode = true;
-    } else if (RegionPolicy.OnlyBottomUp) {
-      SU = pickOnlyChoice(Bot, SchedModel);
-      if (!SU) {
-        CandPolicy NoPolicy;
-        BotCand.reset(NoPolicy);
-        pickNodeFromQueue(Bot, NoPolicy, DAG->getBotRPTracker(), BotCand,
-                          PickedPending,
-                          /*IsBottomUp=*/true);
-        assert(BotCand.Reason != NoCand && "failed to find a candidate");
-        SU = BotCand.SU;
-      }
-      IsTopNode = false;
+  PickedPending = false;
+  if (RegionPolicy.OnlyTopDown) {
+    SU = pickOnlyChoice(Top, SchedModel);
+    if (SU) {
+      tracePick(Only1, /*IsTopNode=*/true, /*IsPostRA=*/false);
     } else {
-      SU = pickNodeBidirectional(IsTopNode, PickedPending);
+      CandPolicy NoPolicy;
+      TopCand.reset(NoPolicy);
+      pickNodeFromQueue(Top, NoPolicy, DAG->getTopRPTracker(), TopCand,
+                        PickedPending,
+                        /*IsBottomUp=*/false);
+      assert(TopCand.Reason != NoCand && "failed to find a candidate");
+      tracePick(TopCand);
+      SU = TopCand.SU;
     }
-  } while (SU->isScheduled);
+    IsTopNode = true;
+  } else if (RegionPolicy.OnlyBottomUp) {
+    SU = pickOnlyChoice(Bot, SchedModel);
+    if (SU) {
+      tracePick(Only1, /*IsTopNode=*/false, /*IsPostRA=*/false);
+    } else {
+      CandPolicy NoPolicy;
+      BotCand.reset(NoPolicy);
+      pickNodeFromQueue(Bot, NoPolicy, DAG->getBotRPTracker(), BotCand,
+                        PickedPending,
+                        /*IsBottomUp=*/true);
+      assert(BotCand.Reason != NoCand && "failed to find a candidate");
+      tracePick(TopCand);
+      SU = BotCand.SU;
+    }
+    IsTopNode = false;
+  } else {
+    SU = pickNodeBidirectional(IsTopNode, PickedPending);
+  }
+  assert(!SU->isScheduled && "SUnit scheduled twice.");
 
   if (PickedPending) {
     unsigned ReadyCycle = IsTopNode ? SU->TopReadyCycle : SU->BotReadyCycle;
@@ -720,7 +728,7 @@ bool GCNMaxILPSchedStrategy::tryCandidate(SchedCandidate &Cand,
                                           SchedBoundary *Zone) const {
   // Initialize the candidate if needed.
   if (!Cand.isValid()) {
-    TryCand.Reason = NodeOrder;
+    TryCand.Reason = FirstValid;
     return true;
   }
 
@@ -796,8 +804,12 @@ bool GCNMaxILPSchedStrategy::tryCandidate(SchedCandidate &Cand,
         (!Zone->isTop() && TryCand.SU->NodeNum > Cand.SU->NodeNum)) {
       TryCand.Reason = NodeOrder;
       return true;
+    } else {
+      Cand.Reason = NodeOrder;
+      return false;
     }
   }
+  Cand.Reason = FirstValid;
   return false;
 }
 
@@ -822,7 +834,7 @@ bool GCNMaxMemoryClauseSchedStrategy::tryCandidate(SchedCandidate &Cand,
                                                    SchedBoundary *Zone) const {
   // Initialize the candidate if needed.
   if (!Cand.isValid()) {
-    TryCand.Reason = NodeOrder;
+    TryCand.Reason = FirstValid;
     return true;
   }
 
@@ -929,9 +941,13 @@ bool GCNMaxMemoryClauseSchedStrategy::tryCandidate(SchedCandidate &Cand,
       assert(TryCand.SU->NodeNum != Cand.SU->NodeNum);
       TryCand.Reason = NodeOrder;
       return true;
+    } else {
+      Cand.Reason = NodeOrder;
+      return false;
     }
   }
 
+  Cand.Reason = FirstValid;
   return false;
 }
 
@@ -3203,12 +3219,12 @@ static bool hasIGLPInstrs(ScheduleDAGInstrs *DAG) {
   });
 }
 
-GCNPostScheduleDAGMILive::GCNPostScheduleDAGMILive(
+GCNPostScheduleDAGMI::GCNPostScheduleDAGMI(
     MachineSchedContext *C, std::unique_ptr<MachineSchedStrategy> S,
     bool RemoveKillFlags)
     : ScheduleDAGMI(C, std::move(S), RemoveKillFlags) {}
 
-void GCNPostScheduleDAGMILive::schedule() {
+void GCNPostScheduleDAGMI::schedule() {
   HasIGLPInstrs = hasIGLPInstrs(this);
   if (HasIGLPInstrs) {
     SavedMutations.clear();
@@ -3219,7 +3235,7 @@ void GCNPostScheduleDAGMILive::schedule() {
   ScheduleDAGMI::schedule();
 }
 
-void GCNPostScheduleDAGMILive::finalizeSchedule() {
+void GCNPostScheduleDAGMI::finalizeSchedule() {
   if (HasIGLPInstrs)
     SavedMutations.swap(Mutations);
 
diff --git a/llvm/lib/Target/AMDGPU/GCNSchedStrategy.h b/llvm/lib/Target/AMDGPU/GCNSchedStrategy.h
index 99fd55db33285..572828db70721 100644
--- a/llvm/lib/Target/AMDGPU/GCNSchedStrategy.h
+++ b/llvm/lib/Target/AMDGPU/GCNSchedStrategy.h
@@ -783,7 +783,7 @@ class MemoryClauseInitialScheduleStage : public GCNSchedStage {
       : GCNSchedStage(StageID, DAG) {}
 };
 
-class GCNPostScheduleDAGMILive final : public ScheduleDAGMI {
+class GCNPostScheduleDAGMI final : public ScheduleDAGMI {
 private:
   std::vector<std::unique_ptr<ScheduleDAGMutation>> SavedMutations;
 
@@ -794,9 +794,9 @@ class GCNPostScheduleDAGMILive final : public ScheduleDAGMI {
 
   void finalizeSchedule() override;
 
-  GCNPostScheduleDAGMILive(MachineSchedContext *C,
-                           std::unique_ptr<MachineSchedStrategy> S,
-                           bool RemoveKillFlags);
+  GCNPostScheduleDAGMI(MachineSchedContext *C,
+                       std::unique_ptr<MachineSchedStrategy> S,
+                       bool RemoveKillFlags);
 };
 
 } // End namespace llvm



More information about the llvm-commits mailing list