[llvm-branch-commits] [llvm] [CodeGen][NewPM] Port SpillPlacement analysis to NPM (PR #116618)

Akshat Oke via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Nov 22 03:15:24 PST 2024


https://github.com/optimisan updated https://github.com/llvm/llvm-project/pull/116618

>From d56857683955832290505f6cfed6fd27a07d7a94 Mon Sep 17 00:00:00 2001
From: Akshat Oke <Akshat.Oke at amd.com>
Date: Mon, 18 Nov 2024 12:42:00 +0000
Subject: [PATCH 1/4] [CodeGen][NewPM] Port SpillPlacement analysis to NPM

---
 llvm/include/llvm/InitializePasses.h |  2 +-
 llvm/lib/CodeGen/RegAllocGreedy.cpp  |  6 +-
 llvm/lib/CodeGen/SpillPlacement.cpp  | 91 ++++++++++++++++++----------
 llvm/lib/CodeGen/SpillPlacement.h    | 52 +++++++++++++---
 4 files changed, 104 insertions(+), 47 deletions(-)

diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h
index e883aae2758688..88bca2c75c9498 100644
--- a/llvm/include/llvm/InitializePasses.h
+++ b/llvm/include/llvm/InitializePasses.h
@@ -289,7 +289,7 @@ void initializeSinkingLegacyPassPass(PassRegistry &);
 void initializeSjLjEHPreparePass(PassRegistry &);
 void initializeSlotIndexesWrapperPassPass(PassRegistry &);
 void initializeSpeculativeExecutionLegacyPassPass(PassRegistry &);
-void initializeSpillPlacementPass(PassRegistry &);
+void initializeSpillPlacementWrapperLegacyPass(PassRegistry &);
 void initializeStackColoringLegacyPass(PassRegistry &);
 void initializeStackFrameLayoutAnalysisPassPass(PassRegistry &);
 void initializeStackMapLivenessPass(PassRegistry &);
diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp b/llvm/lib/CodeGen/RegAllocGreedy.cpp
index 3542bfe18af46f..3fdf2d6e07a75f 100644
--- a/llvm/lib/CodeGen/RegAllocGreedy.cpp
+++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp
@@ -162,7 +162,7 @@ INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(VirtRegMapWrapperLegacy)
 INITIALIZE_PASS_DEPENDENCY(LiveRegMatrixWrapperLegacy)
 INITIALIZE_PASS_DEPENDENCY(EdgeBundlesWrapperLegacy)
-INITIALIZE_PASS_DEPENDENCY(SpillPlacement)
+INITIALIZE_PASS_DEPENDENCY(SpillPlacementWrapperLegacy)
 INITIALIZE_PASS_DEPENDENCY(MachineOptimizationRemarkEmitterPass)
 INITIALIZE_PASS_DEPENDENCY(RegAllocEvictionAdvisorAnalysis)
 INITIALIZE_PASS_DEPENDENCY(RegAllocPriorityAdvisorAnalysis)
@@ -217,7 +217,7 @@ void RAGreedy::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.addRequired<LiveRegMatrixWrapperLegacy>();
   AU.addPreserved<LiveRegMatrixWrapperLegacy>();
   AU.addRequired<EdgeBundlesWrapperLegacy>();
-  AU.addRequired<SpillPlacement>();
+  AU.addRequired<SpillPlacementWrapperLegacy>();
   AU.addRequired<MachineOptimizationRemarkEmitterPass>();
   AU.addRequired<RegAllocEvictionAdvisorAnalysis>();
   AU.addRequired<RegAllocPriorityAdvisorAnalysis>();
@@ -2731,7 +2731,7 @@ bool RAGreedy::runOnMachineFunction(MachineFunction &mf) {
   ORE = &getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE();
   Loops = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
   Bundles = &getAnalysis<EdgeBundlesWrapperLegacy>().getEdgeBundles();
-  SpillPlacer = &getAnalysis<SpillPlacement>();
+  SpillPlacer = &getAnalysis<SpillPlacementWrapperLegacy>().getResult();
   DebugVars = &getAnalysis<LiveDebugVariables>();
 
   initializeCSRCost();
diff --git a/llvm/lib/CodeGen/SpillPlacement.cpp b/llvm/lib/CodeGen/SpillPlacement.cpp
index 318e2b19322bb4..c9baabf6161d3a 100644
--- a/llvm/lib/CodeGen/SpillPlacement.cpp
+++ b/llvm/lib/CodeGen/SpillPlacement.cpp
@@ -44,17 +44,17 @@ using namespace llvm;
 
 #define DEBUG_TYPE "spill-code-placement"
 
-char SpillPlacement::ID = 0;
+char SpillPlacementWrapperLegacy::ID = 0;
 
-char &llvm::SpillPlacementID = SpillPlacement::ID;
+char &llvm::SpillPlacementID = SpillPlacementWrapperLegacy::ID;
 
-INITIALIZE_PASS_BEGIN(SpillPlacement, DEBUG_TYPE,
+INITIALIZE_PASS_BEGIN(SpillPlacementWrapperLegacy, DEBUG_TYPE,
                       "Spill Code Placement Analysis", true, true)
 INITIALIZE_PASS_DEPENDENCY(EdgeBundlesWrapperLegacy)
-INITIALIZE_PASS_END(SpillPlacement, DEBUG_TYPE,
+INITIALIZE_PASS_END(SpillPlacementWrapperLegacy, DEBUG_TYPE,
                     "Spill Code Placement Analysis", true, true)
 
-void SpillPlacement::getAnalysisUsage(AnalysisUsage &AU) const {
+void SpillPlacementWrapperLegacy::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.setPreservesAll();
   AU.addRequired<MachineBlockFrequencyInfoWrapperPass>();
   AU.addRequiredTransitive<EdgeBundlesWrapperLegacy>();
@@ -189,32 +189,57 @@ struct SpillPlacement::Node {
   }
 };
 
-bool SpillPlacement::runOnMachineFunction(MachineFunction &mf) {
+bool SpillPlacementWrapperLegacy::runOnMachineFunction(MachineFunction &MF) {
+  auto *Bundles = &getAnalysis<EdgeBundlesWrapperLegacy>().getEdgeBundles();
+  auto *MBFI = &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
+
+  Impl.reset(new SpillPlacement(Bundles, MBFI));
+  Impl->run(MF);
+  return false;
+}
+
+AnalysisKey SpillPlacementAnalysis::Key;
+
+SpillPlacement
+SpillPlacementAnalysis::run(MachineFunction &MF,
+                            MachineFunctionAnalysisManager &MFAM) {
+  auto *Bundles = &MFAM.getResult<EdgeBundlesAnalysis>(MF);
+  auto *MBFI = &MFAM.getResult<MachineBlockFrequencyAnalysis>(MF);
+  SpillPlacement Impl(Bundles, MBFI);
+  Impl.run(MF);
+  return Impl;
+}
+
+bool SpillPlacementAnalysis::Result::invalidate(
+    MachineFunction &MF, const PreservedAnalyses &PA,
+    MachineFunctionAnalysisManager::Invalidator &Inv) {
+  auto PAC = PA.getChecker<SpillPlacementAnalysis>();
+  return !(PAC.preserved() ||
+           PAC.preservedSet<AllAnalysesOn<MachineFunction>>()) ||
+         Inv.invalidate<EdgeBundlesAnalysis>(MF, PA) ||
+         Inv.invalidate<MachineBlockFrequencyAnalysis>(MF, PA);
+}
+
+void SpillPlacement::arrayDeleter(Node *N) {
+  if (N)
+    delete[] N;
+}
+
+void SpillPlacement::run(MachineFunction &mf) {
   MF = &mf;
-  bundles = &getAnalysis<EdgeBundlesWrapperLegacy>().getEdgeBundles();
 
   assert(!nodes && "Leaking node array");
-  nodes = new Node[bundles->getNumBundles()];
+  nodes.reset(new Node[bundles->getNumBundles()]);
   TodoList.clear();
   TodoList.setUniverse(bundles->getNumBundles());
 
   // Compute total ingoing and outgoing block frequencies for all bundles.
   BlockFrequencies.resize(mf.getNumBlockIDs());
-  MBFI = &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
   setThreshold(MBFI->getEntryFreq());
   for (auto &I : mf) {
     unsigned Num = I.getNumber();
     BlockFrequencies[Num] = MBFI->getBlockFreq(&I);
   }
-
-  // We never change the function.
-  return false;
-}
-
-void SpillPlacement::releaseMemory() {
-  delete[] nodes;
-  nodes = nullptr;
-  TodoList.clear();
 }
 
 /// activate - mark node n as active if it wasn't already.
@@ -223,7 +248,7 @@ void SpillPlacement::activate(unsigned n) {
   if (ActiveNodes->test(n))
     return;
   ActiveNodes->set(n);
-  nodes[n].clear(Threshold);
+  nodes.get()[n].clear(Threshold);
 
   // Very large bundles usually come from big switches, indirect branches,
   // landing pads, or loops with many 'continue' statements. It is difficult to
@@ -235,10 +260,10 @@ void SpillPlacement::activate(unsigned n) {
   // limiting the number of blocks visited and the number of links in the
   // Hopfield network.
   if (bundles->getBlocks(n).size() > 100) {
-    nodes[n].BiasP = BlockFrequency(0);
+    nodes.get()[n].BiasP = BlockFrequency(0);
     BlockFrequency BiasN = MBFI->getEntryFreq();
     BiasN >>= 4;
-    nodes[n].BiasN = BiasN;
+    nodes.get()[n].BiasN = BiasN;
   }
 }
 
@@ -265,14 +290,14 @@ void SpillPlacement::addConstraints(ArrayRef<BlockConstraint> LiveBlocks) {
     if (LB.Entry != DontCare) {
       unsigned ib = bundles->getBundle(LB.Number, false);
       activate(ib);
-      nodes[ib].addBias(Freq, LB.Entry);
+      nodes.get()[ib].addBias(Freq, LB.Entry);
     }
 
     // Live-out from block?
     if (LB.Exit != DontCare) {
       unsigned ob = bundles->getBundle(LB.Number, true);
       activate(ob);
-      nodes[ob].addBias(Freq, LB.Exit);
+      nodes.get()[ob].addBias(Freq, LB.Exit);
     }
   }
 }
@@ -287,8 +312,8 @@ void SpillPlacement::addPrefSpill(ArrayRef<unsigned> Blocks, bool Strong) {
     unsigned ob = bundles->getBundle(B, true);
     activate(ib);
     activate(ob);
-    nodes[ib].addBias(Freq, PrefSpill);
-    nodes[ob].addBias(Freq, PrefSpill);
+    nodes.get()[ib].addBias(Freq, PrefSpill);
+    nodes.get()[ob].addBias(Freq, PrefSpill);
   }
 }
 
@@ -303,8 +328,8 @@ void SpillPlacement::addLinks(ArrayRef<unsigned> Links) {
     activate(ib);
     activate(ob);
     BlockFrequency Freq = BlockFrequencies[Number];
-    nodes[ib].addLink(ob, Freq);
-    nodes[ob].addLink(ib, Freq);
+    nodes.get()[ib].addLink(ob, Freq);
+    nodes.get()[ob].addLink(ib, Freq);
   }
 }
 
@@ -314,18 +339,18 @@ bool SpillPlacement::scanActiveBundles() {
     update(n);
     // A node that must spill, or a node without any links is not going to
     // change its value ever again, so exclude it from iterations.
-    if (nodes[n].mustSpill())
+    if (nodes.get()[n].mustSpill())
       continue;
-    if (nodes[n].preferReg())
+    if (nodes.get()[n].preferReg())
       RecentPositive.push_back(n);
   }
   return !RecentPositive.empty();
 }
 
 bool SpillPlacement::update(unsigned n) {
-  if (!nodes[n].update(nodes, Threshold))
+  if (!nodes.get()[n].update(nodes.get(), Threshold))
     return false;
-  nodes[n].getDissentingNeighbors(TodoList, nodes);
+  nodes.get()[n].getDissentingNeighbors(TodoList, nodes.get());
   return true;
 }
 
@@ -345,7 +370,7 @@ void SpillPlacement::iterate() {
     unsigned n = TodoList.pop_back_val();
     if (!update(n))
       continue;
-    if (nodes[n].preferReg())
+    if (nodes.get()[n].preferReg())
       RecentPositive.push_back(n);
   }
 }
@@ -366,7 +391,7 @@ SpillPlacement::finish() {
   // Write preferences back to ActiveNodes.
   bool Perfect = true;
   for (unsigned n : ActiveNodes->set_bits())
-    if (!nodes[n].preferReg()) {
+    if (!nodes.get()[n].preferReg()) {
       ActiveNodes->reset(n);
       Perfect = false;
     }
diff --git a/llvm/lib/CodeGen/SpillPlacement.h b/llvm/lib/CodeGen/SpillPlacement.h
index 5fd9b085259d1d..e5c03a3db9f987 100644
--- a/llvm/lib/CodeGen/SpillPlacement.h
+++ b/llvm/lib/CodeGen/SpillPlacement.h
@@ -29,6 +29,7 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/SparseSet.h"
+#include "llvm/CodeGen/MachineFunctionAnalysis.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/Support/BlockFrequency.h"
 
@@ -38,13 +39,21 @@ class BitVector;
 class EdgeBundles;
 class MachineBlockFrequencyInfo;
 class MachineFunction;
+class SpillPlacementWrapperLegacy;
+class SpillPlacementAnalysis;
+
+class SpillPlacement {
+  friend class SpillPlacementWrapperLegacy;
+  friend class SpillPlacementAnalysis;
 
-class SpillPlacement : public MachineFunctionPass {
   struct Node;
+
   const MachineFunction *MF = nullptr;
   const EdgeBundles *bundles = nullptr;
   const MachineBlockFrequencyInfo *MBFI = nullptr;
-  Node *nodes = nullptr;
+
+  static void arrayDeleter(Node *N);
+  std::unique_ptr<Node, decltype(&arrayDeleter)> nodes;
 
   // Nodes that are active in the current computation. Owned by the prepare()
   // caller.
@@ -68,11 +77,6 @@ class SpillPlacement : public MachineFunctionPass {
   SparseSet<unsigned> TodoList;
 
 public:
-  static char ID; // Pass identification, replacement for typeid.
-
-  SpillPlacement() : MachineFunctionPass(ID) {}
-  ~SpillPlacement() override { releaseMemory(); }
-
   /// BorderConstraint - A basic block has separate constraints for entry and
   /// exit.
   enum BorderConstraint {
@@ -154,17 +158,45 @@ class SpillPlacement : public MachineFunctionPass {
     return BlockFrequencies[Number];
   }
 
+  bool invalidate(MachineFunction &MF, const PreservedAnalyses &PA,
+                  MachineFunctionAnalysisManager::Invalidator &Inv);
+
 private:
-  bool runOnMachineFunction(MachineFunction &mf) override;
-  void getAnalysisUsage(AnalysisUsage &AU) const override;
-  void releaseMemory() override;
+  SpillPlacement(EdgeBundles *Bundles, MachineBlockFrequencyInfo *MBFI)
+      : bundles(Bundles), MBFI(MBFI), nodes(nullptr, &arrayDeleter) {}
 
+  void run(MachineFunction &MF);
   void activate(unsigned n);
   void setThreshold(BlockFrequency Entry);
 
   bool update(unsigned n);
 };
 
+class SpillPlacementWrapperLegacy : public MachineFunctionPass {
+public:
+  static char ID;
+  SpillPlacementWrapperLegacy() : MachineFunctionPass(ID) {}
+
+  SpillPlacement &getResult() { return *Impl; }
+  const SpillPlacement &getResult() const { return *Impl; }
+
+private:
+  std::unique_ptr<SpillPlacement> Impl;
+  bool runOnMachineFunction(MachineFunction &MF) override;
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+  void releaseMemory() override { Impl.reset(); }
+};
+
+class SpillPlacementAnalysis
+    : public AnalysisInfoMixin<SpillPlacementAnalysis> {
+  friend AnalysisInfoMixin<SpillPlacementAnalysis>;
+  static AnalysisKey Key;
+
+public:
+  using Result = SpillPlacement;
+  SpillPlacement run(MachineFunction &, MachineFunctionAnalysisManager &);
+};
+
 } // end namespace llvm
 
 #endif // LLVM_LIB_CODEGEN_SPILLPLACEMENT_H

>From d7bda934a8de41d21fc9e2e282b9da0d2e3f7baf Mon Sep 17 00:00:00 2001
From: Akshat Oke <Akshat.Oke at amd.com>
Date: Tue, 19 Nov 2024 05:32:16 +0000
Subject: [PATCH 2/4] apply suggestions

---
 .../llvm}/CodeGen/SpillPlacement.h            | 21 ++++----
 .../llvm/Passes/MachinePassRegistry.def       |  1 +
 llvm/lib/CodeGen/RegAllocGreedy.cpp           |  2 +-
 llvm/lib/CodeGen/RegAllocGreedy.h             |  2 +-
 llvm/lib/CodeGen/SpillPlacement.cpp           | 48 ++++++++++---------
 llvm/lib/Passes/PassBuilder.cpp               |  1 +
 6 files changed, 42 insertions(+), 33 deletions(-)
 rename llvm/{lib => include/llvm}/CodeGen/SpillPlacement.h (94%)

diff --git a/llvm/lib/CodeGen/SpillPlacement.h b/llvm/include/llvm/CodeGen/SpillPlacement.h
similarity index 94%
rename from llvm/lib/CodeGen/SpillPlacement.h
rename to llvm/include/llvm/CodeGen/SpillPlacement.h
index e5c03a3db9f987..10028e2fcdaa4f 100644
--- a/llvm/lib/CodeGen/SpillPlacement.h
+++ b/llvm/include/llvm/CodeGen/SpillPlacement.h
@@ -53,7 +53,7 @@ class SpillPlacement {
   const MachineBlockFrequencyInfo *MBFI = nullptr;
 
   static void arrayDeleter(Node *N);
-  std::unique_ptr<Node, decltype(&arrayDeleter)> nodes;
+  std::unique_ptr<Node[], decltype(&arrayDeleter)> nodes;
 
   // Nodes that are active in the current computation. Owned by the prepare()
   // caller.
@@ -162,10 +162,15 @@ class SpillPlacement {
                   MachineFunctionAnalysisManager::Invalidator &Inv);
 
 private:
-  SpillPlacement(EdgeBundles *Bundles, MachineBlockFrequencyInfo *MBFI)
-      : bundles(Bundles), MBFI(MBFI), nodes(nullptr, &arrayDeleter) {}
+  SpillPlacement() : nodes(nullptr, &arrayDeleter) {};
 
-  void run(MachineFunction &MF);
+  void releaseMemory() {
+    nodes.reset();
+    TodoList.clear();
+  }
+
+  void run(MachineFunction &MF, EdgeBundles *Bundles,
+           MachineBlockFrequencyInfo *MBFI);
   void activate(unsigned n);
   void setThreshold(BlockFrequency Entry);
 
@@ -177,14 +182,14 @@ class SpillPlacementWrapperLegacy : public MachineFunctionPass {
   static char ID;
   SpillPlacementWrapperLegacy() : MachineFunctionPass(ID) {}
 
-  SpillPlacement &getResult() { return *Impl; }
-  const SpillPlacement &getResult() const { return *Impl; }
+  SpillPlacement &getResult() { return Impl; }
+  const SpillPlacement &getResult() const { return Impl; }
 
 private:
-  std::unique_ptr<SpillPlacement> Impl;
+  SpillPlacement Impl;
   bool runOnMachineFunction(MachineFunction &MF) override;
   void getAnalysisUsage(AnalysisUsage &AU) const override;
-  void releaseMemory() override { Impl.reset(); }
+  void releaseMemory() override { Impl.releaseMemory(); }
 };
 
 class SpillPlacementAnalysis
diff --git a/llvm/include/llvm/Passes/MachinePassRegistry.def b/llvm/include/llvm/Passes/MachinePassRegistry.def
index cb1c295d824787..95d9fe20b80eb2 100644
--- a/llvm/include/llvm/Passes/MachinePassRegistry.def
+++ b/llvm/include/llvm/Passes/MachinePassRegistry.def
@@ -112,6 +112,7 @@ MACHINE_FUNCTION_ANALYSIS("machine-post-dom-tree",
                           MachinePostDominatorTreeAnalysis())
 MACHINE_FUNCTION_ANALYSIS("machine-trace-metrics", MachineTraceMetricsAnalysis())
 MACHINE_FUNCTION_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis(PIC))
+MACHINE_FUNCTION_ANALYSIS("spill-code-placement", SpillPlacementAnalysis())
 MACHINE_FUNCTION_ANALYSIS("slot-indexes", SlotIndexesAnalysis())
 MACHINE_FUNCTION_ANALYSIS("virtregmap", VirtRegMapAnalysis())
 // MACHINE_FUNCTION_ANALYSIS("live-stacks", LiveStacksPass())
diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp b/llvm/lib/CodeGen/RegAllocGreedy.cpp
index 3fdf2d6e07a75f..d0d2c585f0b54c 100644
--- a/llvm/lib/CodeGen/RegAllocGreedy.cpp
+++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp
@@ -17,7 +17,6 @@
 #include "RegAllocBase.h"
 #include "RegAllocEvictionAdvisor.h"
 #include "RegAllocPriorityAdvisor.h"
-#include "SpillPlacement.h"
 #include "SplitKit.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/BitVector.h"
@@ -50,6 +49,7 @@
 #include "llvm/CodeGen/RegAllocRegistry.h"
 #include "llvm/CodeGen/RegisterClassInfo.h"
 #include "llvm/CodeGen/SlotIndexes.h"
+#include "llvm/CodeGen/SpillPlacement.h"
 #include "llvm/CodeGen/Spiller.h"
 #include "llvm/CodeGen/TargetInstrInfo.h"
 #include "llvm/CodeGen/TargetRegisterInfo.h"
diff --git a/llvm/lib/CodeGen/RegAllocGreedy.h b/llvm/lib/CodeGen/RegAllocGreedy.h
index 2e7608a53e9cec..9578b8d3bef876 100644
--- a/llvm/lib/CodeGen/RegAllocGreedy.h
+++ b/llvm/lib/CodeGen/RegAllocGreedy.h
@@ -16,7 +16,6 @@
 #include "RegAllocBase.h"
 #include "RegAllocEvictionAdvisor.h"
 #include "RegAllocPriorityAdvisor.h"
-#include "SpillPlacement.h"
 #include "SplitKit.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/BitVector.h"
@@ -30,6 +29,7 @@
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/RegisterClassInfo.h"
+#include "llvm/CodeGen/SpillPlacement.h"
 #include "llvm/CodeGen/Spiller.h"
 #include "llvm/CodeGen/TargetRegisterInfo.h"
 #include <algorithm>
diff --git a/llvm/lib/CodeGen/SpillPlacement.cpp b/llvm/lib/CodeGen/SpillPlacement.cpp
index c9baabf6161d3a..424c7e2f7108fb 100644
--- a/llvm/lib/CodeGen/SpillPlacement.cpp
+++ b/llvm/lib/CodeGen/SpillPlacement.cpp
@@ -26,7 +26,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "SpillPlacement.h"
+#include "llvm/CodeGen/SpillPlacement.h"
 #include "llvm/ADT/BitVector.h"
 #include "llvm/CodeGen/EdgeBundles.h"
 #include "llvm/CodeGen/MachineBasicBlock.h"
@@ -193,8 +193,7 @@ bool SpillPlacementWrapperLegacy::runOnMachineFunction(MachineFunction &MF) {
   auto *Bundles = &getAnalysis<EdgeBundlesWrapperLegacy>().getEdgeBundles();
   auto *MBFI = &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
 
-  Impl.reset(new SpillPlacement(Bundles, MBFI));
-  Impl->run(MF);
+  Impl.run(MF, Bundles, MBFI);
   return false;
 }
 
@@ -205,8 +204,8 @@ SpillPlacementAnalysis::run(MachineFunction &MF,
                             MachineFunctionAnalysisManager &MFAM) {
   auto *Bundles = &MFAM.getResult<EdgeBundlesAnalysis>(MF);
   auto *MBFI = &MFAM.getResult<MachineBlockFrequencyAnalysis>(MF);
-  SpillPlacement Impl(Bundles, MBFI);
-  Impl.run(MF);
+  SpillPlacement Impl;
+  Impl.run(MF, Bundles, MBFI);
   return Impl;
 }
 
@@ -214,8 +213,8 @@ bool SpillPlacementAnalysis::Result::invalidate(
     MachineFunction &MF, const PreservedAnalyses &PA,
     MachineFunctionAnalysisManager::Invalidator &Inv) {
   auto PAC = PA.getChecker<SpillPlacementAnalysis>();
-  return !(PAC.preserved() ||
-           PAC.preservedSet<AllAnalysesOn<MachineFunction>>()) ||
+  return (!PAC.preserved() &&
+          !PAC.preservedSet<AllAnalysesOn<MachineFunction>>()) ||
          Inv.invalidate<EdgeBundlesAnalysis>(MF, PA) ||
          Inv.invalidate<MachineBlockFrequencyAnalysis>(MF, PA);
 }
@@ -225,8 +224,11 @@ void SpillPlacement::arrayDeleter(Node *N) {
     delete[] N;
 }
 
-void SpillPlacement::run(MachineFunction &mf) {
+void SpillPlacement::run(MachineFunction &mf, EdgeBundles *Bundles,
+                         MachineBlockFrequencyInfo *MBFI) {
   MF = &mf;
+  this->bundles = Bundles;
+  this->MBFI = MBFI;
 
   assert(!nodes && "Leaking node array");
   nodes.reset(new Node[bundles->getNumBundles()]);
@@ -248,7 +250,7 @@ void SpillPlacement::activate(unsigned n) {
   if (ActiveNodes->test(n))
     return;
   ActiveNodes->set(n);
-  nodes.get()[n].clear(Threshold);
+  nodes[n].clear(Threshold);
 
   // Very large bundles usually come from big switches, indirect branches,
   // landing pads, or loops with many 'continue' statements. It is difficult to
@@ -260,10 +262,10 @@ void SpillPlacement::activate(unsigned n) {
   // limiting the number of blocks visited and the number of links in the
   // Hopfield network.
   if (bundles->getBlocks(n).size() > 100) {
-    nodes.get()[n].BiasP = BlockFrequency(0);
+    nodes[n].BiasP = BlockFrequency(0);
     BlockFrequency BiasN = MBFI->getEntryFreq();
     BiasN >>= 4;
-    nodes.get()[n].BiasN = BiasN;
+    nodes[n].BiasN = BiasN;
   }
 }
 
@@ -290,14 +292,14 @@ void SpillPlacement::addConstraints(ArrayRef<BlockConstraint> LiveBlocks) {
     if (LB.Entry != DontCare) {
       unsigned ib = bundles->getBundle(LB.Number, false);
       activate(ib);
-      nodes.get()[ib].addBias(Freq, LB.Entry);
+      nodes[ib].addBias(Freq, LB.Entry);
     }
 
     // Live-out from block?
     if (LB.Exit != DontCare) {
       unsigned ob = bundles->getBundle(LB.Number, true);
       activate(ob);
-      nodes.get()[ob].addBias(Freq, LB.Exit);
+      nodes[ob].addBias(Freq, LB.Exit);
     }
   }
 }
@@ -312,8 +314,8 @@ void SpillPlacement::addPrefSpill(ArrayRef<unsigned> Blocks, bool Strong) {
     unsigned ob = bundles->getBundle(B, true);
     activate(ib);
     activate(ob);
-    nodes.get()[ib].addBias(Freq, PrefSpill);
-    nodes.get()[ob].addBias(Freq, PrefSpill);
+    nodes[ib].addBias(Freq, PrefSpill);
+    nodes[ob].addBias(Freq, PrefSpill);
   }
 }
 
@@ -328,8 +330,8 @@ void SpillPlacement::addLinks(ArrayRef<unsigned> Links) {
     activate(ib);
     activate(ob);
     BlockFrequency Freq = BlockFrequencies[Number];
-    nodes.get()[ib].addLink(ob, Freq);
-    nodes.get()[ob].addLink(ib, Freq);
+    nodes[ib].addLink(ob, Freq);
+    nodes[ob].addLink(ib, Freq);
   }
 }
 
@@ -339,18 +341,18 @@ bool SpillPlacement::scanActiveBundles() {
     update(n);
     // A node that must spill, or a node without any links is not going to
     // change its value ever again, so exclude it from iterations.
-    if (nodes.get()[n].mustSpill())
+    if (nodes[n].mustSpill())
       continue;
-    if (nodes.get()[n].preferReg())
+    if (nodes[n].preferReg())
       RecentPositive.push_back(n);
   }
   return !RecentPositive.empty();
 }
 
 bool SpillPlacement::update(unsigned n) {
-  if (!nodes.get()[n].update(nodes.get(), Threshold))
+  if (!nodes[n].update(nodes.get(), Threshold))
     return false;
-  nodes.get()[n].getDissentingNeighbors(TodoList, nodes.get());
+  nodes[n].getDissentingNeighbors(TodoList, nodes.get());
   return true;
 }
 
@@ -370,7 +372,7 @@ void SpillPlacement::iterate() {
     unsigned n = TodoList.pop_back_val();
     if (!update(n))
       continue;
-    if (nodes.get()[n].preferReg())
+    if (nodes[n].preferReg())
       RecentPositive.push_back(n);
   }
 }
@@ -391,7 +393,7 @@ SpillPlacement::finish() {
   // Write preferences back to ActiveNodes.
   bool Perfect = true;
   for (unsigned n : ActiveNodes->set_bits())
-    if (!nodes.get()[n].preferReg()) {
+    if (!nodes[n].preferReg()) {
       ActiveNodes->reset(n);
       Perfect = false;
     }
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index cf7ceed63607a6..ba52a37df9c25d 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -130,6 +130,7 @@
 #include "llvm/CodeGen/ShadowStackGCLowering.h"
 #include "llvm/CodeGen/SjLjEHPrepare.h"
 #include "llvm/CodeGen/SlotIndexes.h"
+#include "llvm/CodeGen/SpillPlacement.h"
 #include "llvm/CodeGen/StackColoring.h"
 #include "llvm/CodeGen/StackProtector.h"
 #include "llvm/CodeGen/TailDuplication.h"

>From 80af14ffe4f475187fee8660b1ce2ca7d01cdabb Mon Sep 17 00:00:00 2001
From: Akshat Oke <Akshat.Oke at amd.com>
Date: Tue, 19 Nov 2024 06:37:01 +0000
Subject: [PATCH 3/4] remove custom deleter and use out of line definitions

---
 llvm/include/llvm/CodeGen/SpillPlacement.h | 15 ++++++++-------
 llvm/lib/CodeGen/SpillPlacement.cpp        | 10 +++++++---
 2 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/SpillPlacement.h b/llvm/include/llvm/CodeGen/SpillPlacement.h
index 10028e2fcdaa4f..671ba2f717118f 100644
--- a/llvm/include/llvm/CodeGen/SpillPlacement.h
+++ b/llvm/include/llvm/CodeGen/SpillPlacement.h
@@ -52,8 +52,7 @@ class SpillPlacement {
   const EdgeBundles *bundles = nullptr;
   const MachineBlockFrequencyInfo *MBFI = nullptr;
 
-  static void arrayDeleter(Node *N);
-  std::unique_ptr<Node[], decltype(&arrayDeleter)> nodes;
+  std::unique_ptr<Node[]> nodes;
 
   // Nodes that are active in the current computation. Owned by the prepare()
   // caller.
@@ -161,13 +160,15 @@ class SpillPlacement {
   bool invalidate(MachineFunction &MF, const PreservedAnalyses &PA,
                   MachineFunctionAnalysisManager::Invalidator &Inv);
 
+  // Move the default definitions to the implementation
+  // so the full definition of Node is available.
+  SpillPlacement(SpillPlacement &&);
+  ~SpillPlacement();
+
 private:
-  SpillPlacement() : nodes(nullptr, &arrayDeleter) {};
+  SpillPlacement();
 
-  void releaseMemory() {
-    nodes.reset();
-    TodoList.clear();
-  }
+  void releaseMemory();
 
   void run(MachineFunction &MF, EdgeBundles *Bundles,
            MachineBlockFrequencyInfo *MBFI);
diff --git a/llvm/lib/CodeGen/SpillPlacement.cpp b/llvm/lib/CodeGen/SpillPlacement.cpp
index 424c7e2f7108fb..982aa01fc0e282 100644
--- a/llvm/lib/CodeGen/SpillPlacement.cpp
+++ b/llvm/lib/CodeGen/SpillPlacement.cpp
@@ -219,9 +219,13 @@ bool SpillPlacementAnalysis::Result::invalidate(
          Inv.invalidate<MachineBlockFrequencyAnalysis>(MF, PA);
 }
 
-void SpillPlacement::arrayDeleter(Node *N) {
-  if (N)
-    delete[] N;
+SpillPlacement::SpillPlacement() = default;
+SpillPlacement::~SpillPlacement() = default;
+SpillPlacement::SpillPlacement(SpillPlacement &&) = default;
+
+void SpillPlacement::releaseMemory() {
+  nodes.reset();
+  TodoList.clear();
 }
 
 void SpillPlacement::run(MachineFunction &mf, EdgeBundles *Bundles,

>From 05972fdc6f4a8173d41e5b45d4269e797c0d817c Mon Sep 17 00:00:00 2001
From: Akshat Oke <Akshat.Oke at amd.com>
Date: Fri, 22 Nov 2024 11:14:16 +0000
Subject: [PATCH 4/4] AS comments

---
 llvm/include/llvm/CodeGen/SpillPlacement.h       | 3 +--
 llvm/include/llvm/Passes/MachinePassRegistry.def | 2 +-
 llvm/lib/CodeGen/SpillPlacement.cpp              | 7 ++++---
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/SpillPlacement.h b/llvm/include/llvm/CodeGen/SpillPlacement.h
index 671ba2f717118f..85ff9a8fe0854b 100644
--- a/llvm/include/llvm/CodeGen/SpillPlacement.h
+++ b/llvm/include/llvm/CodeGen/SpillPlacement.h
@@ -160,8 +160,7 @@ class SpillPlacement {
   bool invalidate(MachineFunction &MF, const PreservedAnalyses &PA,
                   MachineFunctionAnalysisManager::Invalidator &Inv);
 
-  // Move the default definitions to the implementation
-  // so the full definition of Node is available.
+  // Out of line definitions so unique_ptr<Node[]> doesn't need to be complete.
   SpillPlacement(SpillPlacement &&);
   ~SpillPlacement();
 
diff --git a/llvm/include/llvm/Passes/MachinePassRegistry.def b/llvm/include/llvm/Passes/MachinePassRegistry.def
index 95d9fe20b80eb2..437ec39beb040e 100644
--- a/llvm/include/llvm/Passes/MachinePassRegistry.def
+++ b/llvm/include/llvm/Passes/MachinePassRegistry.def
@@ -112,8 +112,8 @@ MACHINE_FUNCTION_ANALYSIS("machine-post-dom-tree",
                           MachinePostDominatorTreeAnalysis())
 MACHINE_FUNCTION_ANALYSIS("machine-trace-metrics", MachineTraceMetricsAnalysis())
 MACHINE_FUNCTION_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis(PIC))
-MACHINE_FUNCTION_ANALYSIS("spill-code-placement", SpillPlacementAnalysis())
 MACHINE_FUNCTION_ANALYSIS("slot-indexes", SlotIndexesAnalysis())
+MACHINE_FUNCTION_ANALYSIS("spill-code-placement", SpillPlacementAnalysis())
 MACHINE_FUNCTION_ANALYSIS("virtregmap", VirtRegMapAnalysis())
 // MACHINE_FUNCTION_ANALYSIS("live-stacks", LiveStacksPass())
 // MACHINE_FUNCTION_ANALYSIS("lazy-machine-bfi",
diff --git a/llvm/lib/CodeGen/SpillPlacement.cpp b/llvm/lib/CodeGen/SpillPlacement.cpp
index 982aa01fc0e282..55a96a22a00ecf 100644
--- a/llvm/lib/CodeGen/SpillPlacement.cpp
+++ b/llvm/lib/CodeGen/SpillPlacement.cpp
@@ -213,9 +213,10 @@ bool SpillPlacementAnalysis::Result::invalidate(
     MachineFunction &MF, const PreservedAnalyses &PA,
     MachineFunctionAnalysisManager::Invalidator &Inv) {
   auto PAC = PA.getChecker<SpillPlacementAnalysis>();
-  return (!PAC.preserved() &&
-          !PAC.preservedSet<AllAnalysesOn<MachineFunction>>()) ||
-         Inv.invalidate<EdgeBundlesAnalysis>(MF, PA) ||
+  if (!PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<MachineFunction>>())
+    return true;
+  // Check dependencies.
+  return Inv.invalidate<EdgeBundlesAnalysis>(MF, PA) ||
          Inv.invalidate<MachineBlockFrequencyAnalysis>(MF, PA);
 }
 



More information about the llvm-branch-commits mailing list