Skip to content

[CodeGen] Add MachineRegisterClassInfo analysis pass #120690

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

wangpc-pp
Copy link
Contributor

Which is a wrapper of RegisterClassInfo.

This can cache the result of RegisterClassInfo and hence
we can reduce compile time.

@llvmbot
Copy link
Member

llvmbot commented Jan 10, 2025

@llvm/pr-subscribers-backend-loongarch
@llvm/pr-subscribers-backend-aarch64
@llvm/pr-subscribers-llvm-regalloc
@llvm/pr-subscribers-backend-arm

@llvm/pr-subscribers-backend-amdgpu

Author: Pengcheng Wang (wangpc-pp)

Changes

Which is a wrapper of RegisterClassInfo.

This can cache the result of RegisterClassInfo and hence
we can reduce compile time.


Patch is 43.10 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/120690.diff

27 Files Affected:

  • (modified) llvm/include/llvm/CodeGen/MachinePipeliner.h (+1-1)
  • (added) llvm/include/llvm/CodeGen/MachineRegisterClassInfo.h (+57)
  • (modified) llvm/include/llvm/CodeGen/MachineScheduler.h (-6)
  • (modified) llvm/include/llvm/InitializePasses.h (+1)
  • (modified) llvm/include/llvm/Passes/MachinePassRegistry.def (+2)
  • (modified) llvm/lib/CodeGen/BreakFalseDeps.cpp (+6-4)
  • (modified) llvm/lib/CodeGen/CMakeLists.txt (+1)
  • (modified) llvm/lib/CodeGen/MachineCombiner.cpp (+6-3)
  • (modified) llvm/lib/CodeGen/MachineLICM.cpp (+1)
  • (modified) llvm/lib/CodeGen/MachinePipeliner.cpp (+7-3)
  • (added) llvm/lib/CodeGen/MachineRegisterClassInfo.cpp (+50)
  • (modified) llvm/lib/CodeGen/MachineScheduler.cpp (+4-9)
  • (modified) llvm/lib/CodeGen/MachineSink.cpp (+7-4)
  • (modified) llvm/lib/CodeGen/PostRASchedulerList.cpp (+10-5)
  • (modified) llvm/lib/CodeGen/RegisterCoalescer.cpp (+7-4)
  • (modified) llvm/lib/CodeGen/ShrinkWrap.cpp (+6-3)
  • (modified) llvm/lib/Passes/PassBuilder.cpp (+1)
  • (modified) llvm/lib/Target/AArch64/AArch64A57FPLoadBalancing.cpp (+7-3)
  • (modified) llvm/lib/Target/AMDGPU/SIPreAllocateWWMRegs.cpp (+11-8)
  • (modified) llvm/test/CodeGen/AArch64/O3-pipeline.ll (+1)
  • (modified) llvm/test/CodeGen/AMDGPU/llc-pipeline.ll (+8)
  • (modified) llvm/test/CodeGen/AMDGPU/sgpr-regalloc-flags.ll (+1)
  • (modified) llvm/test/CodeGen/ARM/O3-pipeline.ll (+1)
  • (modified) llvm/test/CodeGen/LoongArch/opt-pipeline.ll (+1)
  • (modified) llvm/test/CodeGen/PowerPC/O3-pipeline.ll (+1)
  • (modified) llvm/test/CodeGen/RISCV/O3-pipeline.ll (+1)
  • (modified) llvm/test/CodeGen/X86/opt-pipeline.ll (+2)
diff --git a/llvm/include/llvm/CodeGen/MachinePipeliner.h b/llvm/include/llvm/CodeGen/MachinePipeliner.h
index 8e47d0cead7571..5ae44b50b99f3d 100644
--- a/llvm/include/llvm/CodeGen/MachinePipeliner.h
+++ b/llvm/include/llvm/CodeGen/MachinePipeliner.h
@@ -74,7 +74,7 @@ class MachinePipeliner : public MachineFunctionPass {
   const MachineDominatorTree *MDT = nullptr;
   const InstrItineraryData *InstrItins = nullptr;
   const TargetInstrInfo *TII = nullptr;
-  RegisterClassInfo RegClassInfo;
+  RegisterClassInfo *RegClassInfo = nullptr;
   bool disabledByPragma = false;
   unsigned II_setByPragma = 0;
 
diff --git a/llvm/include/llvm/CodeGen/MachineRegisterClassInfo.h b/llvm/include/llvm/CodeGen/MachineRegisterClassInfo.h
new file mode 100644
index 00000000000000..dd8e34cab0bddf
--- /dev/null
+++ b/llvm/include/llvm/CodeGen/MachineRegisterClassInfo.h
@@ -0,0 +1,57 @@
+//=- MachineRegisterClassInfo.h - Machine Register Class Info -----*- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This analysis calculates register class info via RegisterClassInfo.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEREGISTERCLASSINFO_H
+#define LLVM_CODEGEN_MACHINEREGISTERCLASSINFO_H
+
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachinePassManager.h"
+#include "llvm/CodeGen/RegisterClassInfo.h"
+#include "llvm/Pass.h"
+
+namespace llvm {
+
+class MachineRegisterClassInfoAnalysis
+    : public AnalysisInfoMixin<MachineRegisterClassInfoAnalysis> {
+  friend AnalysisInfoMixin<MachineRegisterClassInfoAnalysis>;
+
+  static AnalysisKey Key;
+
+public:
+  using Result = RegisterClassInfo;
+
+  Result run(MachineFunction &, MachineFunctionAnalysisManager &);
+};
+
+class MachineRegisterClassInfoWrapperPass : public MachineFunctionPass {
+  virtual void anchor();
+
+  RegisterClassInfo RCI;
+
+public:
+  static char ID;
+
+  MachineRegisterClassInfoWrapperPass();
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override {
+    AU.setPreservesAll();
+    MachineFunctionPass::getAnalysisUsage(AU);
+  }
+
+  bool runOnMachineFunction(MachineFunction &MF) override;
+
+  RegisterClassInfo &getRCI() { return RCI; }
+  const RegisterClassInfo &getRCI() const { return RCI; }
+};
+} // namespace llvm
+
+#endif
diff --git a/llvm/include/llvm/CodeGen/MachineScheduler.h b/llvm/include/llvm/CodeGen/MachineScheduler.h
index 3dd62b2ba333c3..44698e04e1e8bf 100644
--- a/llvm/include/llvm/CodeGen/MachineScheduler.h
+++ b/llvm/include/llvm/CodeGen/MachineScheduler.h
@@ -140,13 +140,7 @@ struct MachineSchedContext {
   const TargetPassConfig *PassConfig = nullptr;
   AAResults *AA = nullptr;
   LiveIntervals *LIS = nullptr;
-
   RegisterClassInfo *RegClassInfo;
-
-  MachineSchedContext();
-  MachineSchedContext &operator=(const MachineSchedContext &other) = delete;
-  MachineSchedContext(const MachineSchedContext &other) = delete;
-  virtual ~MachineSchedContext();
 };
 
 /// MachineSchedRegistry provides a selection of available machine instruction
diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h
index 1cb9013bc48cc5..e4f6aced3ae454 100644
--- a/llvm/include/llvm/InitializePasses.h
+++ b/llvm/include/llvm/InitializePasses.h
@@ -208,6 +208,7 @@ void initializeMachineOutlinerPass(PassRegistry &);
 void initializeMachinePipelinerPass(PassRegistry &);
 void initializeMachinePostDominatorTreeWrapperPassPass(PassRegistry &);
 void initializeMachineRegionInfoPassPass(PassRegistry &);
+void initializeMachineRegisterClassInfoWrapperPassPass(PassRegistry &);
 void initializeMachineSanitizerBinaryMetadataPass(PassRegistry &);
 void initializeMachineSchedulerPass(PassRegistry &);
 void initializeMachineSinkingPass(PassRegistry &);
diff --git a/llvm/include/llvm/Passes/MachinePassRegistry.def b/llvm/include/llvm/Passes/MachinePassRegistry.def
index 29763995e8b516..8471960356b090 100644
--- a/llvm/include/llvm/Passes/MachinePassRegistry.def
+++ b/llvm/include/llvm/Passes/MachinePassRegistry.def
@@ -112,6 +112,8 @@ MACHINE_FUNCTION_ANALYSIS("machine-opt-remark-emitter",
                           MachineOptimizationRemarkEmitterAnalysis())
 MACHINE_FUNCTION_ANALYSIS("machine-post-dom-tree",
                           MachinePostDominatorTreeAnalysis())
+MACHINE_FUNCTION_ANALYSIS("machine-reg-class-info",
+                          MachineRegisterClassInfoAnalysis())
 MACHINE_FUNCTION_ANALYSIS("machine-trace-metrics", MachineTraceMetricsAnalysis())
 MACHINE_FUNCTION_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis(PIC))
 MACHINE_FUNCTION_ANALYSIS("slot-indexes", SlotIndexesAnalysis())
diff --git a/llvm/lib/CodeGen/BreakFalseDeps.cpp b/llvm/lib/CodeGen/BreakFalseDeps.cpp
index 618e41894b29bc..fece3bf14a75d8 100644
--- a/llvm/lib/CodeGen/BreakFalseDeps.cpp
+++ b/llvm/lib/CodeGen/BreakFalseDeps.cpp
@@ -20,6 +20,7 @@
 #include "llvm/ADT/DepthFirstIterator.h"
 #include "llvm/CodeGen/LivePhysRegs.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineRegisterClassInfo.h"
 #include "llvm/CodeGen/ReachingDefAnalysis.h"
 #include "llvm/CodeGen/RegisterClassInfo.h"
 #include "llvm/CodeGen/TargetInstrInfo.h"
@@ -38,7 +39,7 @@ class BreakFalseDeps : public MachineFunctionPass {
   MachineFunction *MF = nullptr;
   const TargetInstrInfo *TII = nullptr;
   const TargetRegisterInfo *TRI = nullptr;
-  RegisterClassInfo RegClassInfo;
+  RegisterClassInfo *RegClassInfo = nullptr;
 
   /// List of undefined register reads in this block in forward order.
   std::vector<std::pair<MachineInstr *, unsigned>> UndefReads;
@@ -58,6 +59,7 @@ class BreakFalseDeps : public MachineFunctionPass {
   void getAnalysisUsage(AnalysisUsage &AU) const override {
     AU.setPreservesAll();
     AU.addRequired<ReachingDefAnalysis>();
+    AU.addRequired<MachineRegisterClassInfoWrapperPass>();
     MachineFunctionPass::getAnalysisUsage(AU);
   }
 
@@ -103,6 +105,7 @@ class BreakFalseDeps : public MachineFunctionPass {
 char BreakFalseDeps::ID = 0;
 INITIALIZE_PASS_BEGIN(BreakFalseDeps, DEBUG_TYPE, "BreakFalseDeps", false, false)
 INITIALIZE_PASS_DEPENDENCY(ReachingDefAnalysis)
+INITIALIZE_PASS_DEPENDENCY(MachineRegisterClassInfoWrapperPass)
 INITIALIZE_PASS_END(BreakFalseDeps, DEBUG_TYPE, "BreakFalseDeps", false, false)
 
 FunctionPass *llvm::createBreakFalseDeps() { return new BreakFalseDeps(); }
@@ -153,7 +156,7 @@ bool BreakFalseDeps::pickBestRegisterForUndef(MachineInstr *MI, unsigned OpIdx,
   // max clearance or clearance higher than Pref.
   unsigned MaxClearance = 0;
   unsigned MaxClearanceReg = OriginalReg;
-  ArrayRef<MCPhysReg> Order = RegClassInfo.getOrder(OpRC);
+  ArrayRef<MCPhysReg> Order = RegClassInfo->getOrder(OpRC);
   for (MCPhysReg Reg : Order) {
     unsigned Clearance = RDA->getClearance(MI, Reg);
     if (Clearance <= MaxClearance)
@@ -285,8 +288,7 @@ bool BreakFalseDeps::runOnMachineFunction(MachineFunction &mf) {
   TII = MF->getSubtarget().getInstrInfo();
   TRI = MF->getSubtarget().getRegisterInfo();
   RDA = &getAnalysis<ReachingDefAnalysis>();
-
-  RegClassInfo.runOnMachineFunction(mf);
+  RegClassInfo = &getAnalysis<MachineRegisterClassInfoWrapperPass>().getRCI();
 
   LLVM_DEBUG(dbgs() << "********** BREAK FALSE DEPENDENCIES **********\n");
 
diff --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt
index 145fd2fac8b564..b5c0194d7ecd37 100644
--- a/llvm/lib/CodeGen/CMakeLists.txt
+++ b/llvm/lib/CodeGen/CMakeLists.txt
@@ -141,6 +141,7 @@ add_llvm_component_library(LLVMCodeGen
   MachinePipeliner.cpp
   MachinePostDominators.cpp
   MachineRegionInfo.cpp
+  MachineRegisterClassInfo.cpp
   MachineRegisterInfo.cpp
   MachineScheduler.cpp
   MachineSink.cpp
diff --git a/llvm/lib/CodeGen/MachineCombiner.cpp b/llvm/lib/CodeGen/MachineCombiner.cpp
index b8d59214a6ec32..0f3778a3cfb803 100644
--- a/llvm/lib/CodeGen/MachineCombiner.cpp
+++ b/llvm/lib/CodeGen/MachineCombiner.cpp
@@ -19,6 +19,7 @@
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineLoopInfo.h"
+#include "llvm/CodeGen/MachineRegisterClassInfo.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/MachineSizeOpts.h"
 #include "llvm/CodeGen/MachineTraceMetrics.h"
@@ -73,7 +74,7 @@ class MachineCombiner : public MachineFunctionPass {
   MachineTraceMetrics::Ensemble *TraceEnsemble = nullptr;
   MachineBlockFrequencyInfo *MBFI = nullptr;
   ProfileSummaryInfo *PSI = nullptr;
-  RegisterClassInfo RegClassInfo;
+  RegisterClassInfo *RegClassInfo = nullptr;
 
   TargetSchedModel TSchedModel;
 
@@ -131,6 +132,7 @@ INITIALIZE_PASS_BEGIN(MachineCombiner, DEBUG_TYPE,
                       "Machine InstCombiner", false, false)
 INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(MachineTraceMetricsWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(MachineRegisterClassInfoWrapperPass)
 INITIALIZE_PASS_END(MachineCombiner, DEBUG_TYPE, "Machine InstCombiner",
                     false, false)
 
@@ -143,6 +145,7 @@ void MachineCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.addPreserved<MachineTraceMetricsWrapperPass>();
   AU.addRequired<LazyMachineBlockFrequencyInfoPass>();
   AU.addRequired<ProfileSummaryInfoWrapperPass>();
+  AU.addRequired<MachineRegisterClassInfoWrapperPass>();
   MachineFunctionPass::getAnalysisUsage(AU);
 }
 
@@ -571,7 +574,7 @@ bool MachineCombiner::combineInstructions(MachineBasicBlock *MBB) {
   bool OptForSize = llvm::shouldOptimizeForSize(MBB, PSI, MBFI);
 
   bool DoRegPressureReduce =
-      TII->shouldReduceRegisterPressure(MBB, &RegClassInfo);
+      TII->shouldReduceRegisterPressure(MBB, RegClassInfo);
 
   while (BlockIter != MBB->end()) {
     auto &MI = *BlockIter++;
@@ -730,7 +733,7 @@ bool MachineCombiner::runOnMachineFunction(MachineFunction &MF) {
          &getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI() :
          nullptr;
   TraceEnsemble = nullptr;
-  RegClassInfo.runOnMachineFunction(MF);
+  RegClassInfo = &getAnalysis<MachineRegisterClassInfoWrapperPass>().getRCI();
 
   LLVM_DEBUG(dbgs() << getPassName() << ": " << MF.getName() << '\n');
   if (!TII->useMachineCombiner()) {
diff --git a/llvm/lib/CodeGen/MachineLICM.cpp b/llvm/lib/CodeGen/MachineLICM.cpp
index d1d5509dc482a2..976bd893561726 100644
--- a/llvm/lib/CodeGen/MachineLICM.cpp
+++ b/llvm/lib/CodeGen/MachineLICM.cpp
@@ -33,6 +33,7 @@
 #include "llvm/CodeGen/MachineLoopInfo.h"
 #include "llvm/CodeGen/MachineMemOperand.h"
 #include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/CodeGen/MachineRegisterClassInfo.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/PseudoSourceValue.h"
 #include "llvm/CodeGen/TargetInstrInfo.h"
diff --git a/llvm/lib/CodeGen/MachinePipeliner.cpp b/llvm/lib/CodeGen/MachinePipeliner.cpp
index acd42aa497c6fe..2c42f4de6556d2 100644
--- a/llvm/lib/CodeGen/MachinePipeliner.cpp
+++ b/llvm/lib/CodeGen/MachinePipeliner.cpp
@@ -58,6 +58,7 @@
 #include "llvm/CodeGen/MachineLoopInfo.h"
 #include "llvm/CodeGen/MachineMemOperand.h"
 #include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/CodeGen/MachineRegisterClassInfo.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/ModuloSchedule.h"
 #include "llvm/CodeGen/Register.h"
@@ -234,6 +235,7 @@ INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(MachineRegisterClassInfoWrapperPass)
 INITIALIZE_PASS_END(MachinePipeliner, DEBUG_TYPE,
                     "Modulo Software Pipelining", false, false)
 
@@ -263,8 +265,8 @@ bool MachinePipeliner::runOnMachineFunction(MachineFunction &mf) {
   MLI = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
   MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
   ORE = &getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE();
+  RegClassInfo = &getAnalysis<MachineRegisterClassInfoWrapperPass>().getRCI();
   TII = MF->getSubtarget().getInstrInfo();
-  RegClassInfo.runOnMachineFunction(*MF);
 
   for (const auto &L : *MLI)
     scheduleLoop(*L);
@@ -471,7 +473,7 @@ bool MachinePipeliner::swingModuloScheduler(MachineLoop &L) {
   assert(L.getBlocks().size() == 1 && "SMS works on single blocks only.");
 
   SwingSchedulerDAG SMS(
-      *this, L, getAnalysis<LiveIntervalsWrapperPass>().getLIS(), RegClassInfo,
+      *this, L, getAnalysis<LiveIntervalsWrapperPass>().getLIS(), *RegClassInfo,
       II_setByPragma, LI.LoopPipelinerInfo.get());
 
   MachineBasicBlock *MBB = L.getHeader();
@@ -503,6 +505,7 @@ void MachinePipeliner::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.addRequired<LiveIntervalsWrapperPass>();
   AU.addRequired<MachineOptimizationRemarkEmitterPass>();
   AU.addRequired<TargetPassConfig>();
+  AU.addRequired<MachineRegisterClassInfoWrapperPass>();
   MachineFunctionPass::getAnalysisUsage(AU);
 }
 
@@ -514,7 +517,8 @@ bool MachinePipeliner::runWindowScheduler(MachineLoop &L) {
   Context.PassConfig = &getAnalysis<TargetPassConfig>();
   Context.AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
   Context.LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
-  Context.RegClassInfo->runOnMachineFunction(*MF);
+  Context.RegClassInfo =
+      &getAnalysis<MachineRegisterClassInfoWrapperPass>().getRCI();
   WindowScheduler WS(&Context, L);
   return WS.run();
 }
diff --git a/llvm/lib/CodeGen/MachineRegisterClassInfo.cpp b/llvm/lib/CodeGen/MachineRegisterClassInfo.cpp
new file mode 100644
index 00000000000000..9d8138ec391a58
--- /dev/null
+++ b/llvm/lib/CodeGen/MachineRegisterClassInfo.cpp
@@ -0,0 +1,50 @@
+//===- MachineRegisterClassInfo.cpp - Machine Register Class Info ---------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This analysis calculates register class info via RegisterClassInfo.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/MachineRegisterClassInfo.h"
+#include "llvm/CodeGen/RegisterClassInfo.h"
+#include "llvm/InitializePasses.h"
+
+using namespace llvm;
+
+INITIALIZE_PASS_BEGIN(MachineRegisterClassInfoWrapperPass,
+                      "machine-reg-class-info",
+                      "Machine Register Class Info Analysis", false, true)
+INITIALIZE_PASS_END(MachineRegisterClassInfoWrapperPass,
+                    "machine-reg-class-info",
+                    "Machine Register Class Info Analysis", false, true)
+
+MachineRegisterClassInfoAnalysis::Result
+MachineRegisterClassInfoAnalysis::run(MachineFunction &MF,
+                                      MachineFunctionAnalysisManager &) {
+  RegisterClassInfo RCI;
+  RCI.runOnMachineFunction(MF);
+  return RCI;
+}
+
+char MachineRegisterClassInfoWrapperPass::ID = 0;
+
+MachineRegisterClassInfoWrapperPass::MachineRegisterClassInfoWrapperPass()
+    : MachineFunctionPass(ID), RCI() {
+  PassRegistry &Registry = *PassRegistry::getPassRegistry();
+  initializeMachineRegisterClassInfoWrapperPassPass(Registry);
+}
+
+bool MachineRegisterClassInfoWrapperPass::runOnMachineFunction(
+    MachineFunction &MF) {
+  RCI.runOnMachineFunction(MF);
+  return false;
+}
+
+void MachineRegisterClassInfoWrapperPass::anchor() {}
+
+AnalysisKey MachineRegisterClassInfoAnalysis::Key;
diff --git a/llvm/lib/CodeGen/MachineScheduler.cpp b/llvm/lib/CodeGen/MachineScheduler.cpp
index 91aaeea156c4a1..4b283f31ec3e5a 100644
--- a/llvm/lib/CodeGen/MachineScheduler.cpp
+++ b/llvm/lib/CodeGen/MachineScheduler.cpp
@@ -31,6 +31,7 @@
 #include "llvm/CodeGen/MachineLoopInfo.h"
 #include "llvm/CodeGen/MachineOperand.h"
 #include "llvm/CodeGen/MachinePassRegistry.h"
+#include "llvm/CodeGen/MachineRegisterClassInfo.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/RegisterClassInfo.h"
 #include "llvm/CodeGen/RegisterPressure.h"
@@ -205,14 +206,6 @@ void ScheduleDAGMutation::anchor() {}
 // Machine Instruction Scheduling Pass and Registry
 //===----------------------------------------------------------------------===//
 
-MachineSchedContext::MachineSchedContext() {
-  RegClassInfo = new RegisterClassInfo();
-}
-
-MachineSchedContext::~MachineSchedContext() {
-  delete RegClassInfo;
-}
-
 namespace {
 
 /// Base class for a machine scheduler class that can run at any point.
@@ -287,6 +280,7 @@ void MachineScheduler::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.addPreserved<SlotIndexesWrapperPass>();
   AU.addRequired<LiveIntervalsWrapperPass>();
   AU.addPreserved<LiveIntervalsWrapperPass>();
+  AU.addRequired<MachineRegisterClassInfoWrapperPass>();
   MachineFunctionPass::getAnalysisUsage(AU);
 }
 
@@ -299,6 +293,7 @@ INITIALIZE_PASS_BEGIN(PostMachineScheduler, "postmisched",
 INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(MachineRegisterClassInfoWrapperPass)
 INITIALIZE_PASS_END(PostMachineScheduler, "postmisched",
                     "PostRA Machine Instruction Scheduler", false, false)
 
@@ -455,7 +450,7 @@ bool MachineScheduler::runOnMachineFunction(MachineFunction &mf) {
     LLVM_DEBUG(LIS->dump());
     MF->verify(this, "Before machine scheduling.", &errs());
   }
-  RegClassInfo->runOnMachineFunction(*MF);
+  RegClassInfo = &getAnalysis<MachineRegisterClassInfoWrapperPass>().getRCI();
 
   // Instantiate the selected scheduler for this target, function, and
   // optimization level.
diff --git a/llvm/lib/CodeGen/MachineSink.cpp b/llvm/lib/CodeGen/MachineSink.cpp
index 3c816f97650901..8470d92505a114 100644
--- a/llvm/lib/CodeGen/MachineSink.cpp
+++ b/llvm/lib/CodeGen/MachineSink.cpp
@@ -38,6 +38,7 @@
 #include "llvm/CodeGen/MachineLoopInfo.h"
 #include "llvm/CodeGen/MachineOperand.h"
 #include "llvm/CodeGen/MachinePostDominators.h"
+#include "llvm/CodeGen/MachineRegisterClassInfo.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/MachineSizeOpts.h"
 #include "llvm/CodeGen/RegisterClassInfo.h"
@@ -127,7 +128,7 @@ class MachineSinking : public MachineFunctionPass {
   MachineBlockFrequencyInfo *MBFI = nullptr;
   const MachineBranchProbabilityInfo *MBPI = nullptr;
   AliasAnalysis *AA = nullptr;
-  RegisterClassInfo RegClassInfo;
+  RegisterClassInfo *RegClassInfo = nullptr;
 
   // Remember which edges have been considered for breaking.
   SmallSet<std::pair<MachineBasicBlock *, MachineBasicBlock *>, 8>
@@ -200,6 +201,7 @@ class MachineSinking : public MachineFunctionPass {
     AU.addRequired<MachineBranchProbabilityInfoWrapperPass>();
     AU.addPreserved<MachineCycleInfoWrapperPass>();
     AU.addPreserved<MachineLoopInfoWrapperPass>();
+    AU.addRequired<MachineRegisterClassInfoWrapperPass>();
     AU.addRequired<ProfileSummaryInfoWrapperPass>();
     if (UseBlockFreqInfo)
       AU.addRequired<MachineBlockFrequencyInfoWrapperPass>();
@@ -290,6 +292,7 @@ INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfoWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(MachineCycleInfoWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(MachineRegisterClassInfoWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
 INITIALIZE_PASS_END(MachineSinking, DEBUG_TYPE, "Machine code sinking", false,
                     false)
@@ -731,7 +734,7 @@ bool MachineSinking::runOnMachineFunction(MachineFunction &MF) {
              : nullptr;
   MBPI = &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
   AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
-  RegClassInfo.runOnMachineFunction(MF);
+  RegClassInfo = &getAnalysis<MachineRegisterClassInfoWrapperPass>().getRCI();
   TargetPassConfig *PassConfig = &getAnalysis<TargetPassConfig>();
   EnableSinkAndFold = PassConfig->getEnableSinkAn...
[truncated]

@wangpc-pp
Copy link
Contributor Author

@nikic Can you please evaluate the compile-time impact of this PR? Thanks in advance!

@rovka
Copy link
Collaborator

rovka commented Jan 10, 2025

RegisterClassInfo already has a pass-like interface (runOnMachineFunction) - could we just change it into a proper pass instead of adding MachineRegisterClassInfo as a wrapper?

@nikic
Copy link
Contributor

nikic commented Jan 10, 2025

@nikic Can you please evaluate the compile-time impact of this PR? Thanks in advance!

Sure: https://llvm-compile-time-tracker.com/compare.php?from=c39500f88c93f668c68bdafe56bd8d16e8abbec1&to=71cb02cd0071e85e4da9c13bf762b51b3f805e0b&stat=instructions:u It looks like a minor regression for now. Probably adding the preservation will improve things.

@wangpc-pp
Copy link
Contributor Author

RegisterClassInfo already has a pass-like interface (runOnMachineFunction) - could we just change it into a proper pass instead of adding MachineRegisterClassInfo as a wrapper?

Thanks for your advice! I thought about the same thing, but it is not possible since RegisterClassInfo is also an utility class. Please see previous discussion: #118787 (comment).

@wangpc-pp
Copy link
Contributor Author

@nikic Can you please evaluate the compile-time impact of this PR? Thanks in advance!

Sure: https://llvm-compile-time-tracker.com/compare.php?from=c39500f88c93f668c68bdafe56bd8d16e8abbec1&to=71cb02cd0071e85e4da9c13bf762b51b3f805e0b&stat=instructions:u It looks like a minor regression for now. Probably adding the preservation will improve things.

I added the preserved set, how about now?

; GCN-O1-NEXT: Register Coalescer
; GCN-O1-NEXT: Rename Disconnected Subregister Components
; GCN-O1-NEXT: Rewrite Partial Register Uses
; GCN-O1-NEXT: Machine Register Class Info Analysis
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary recalculation here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appears in the pipeline doesn't mean it will be run? The analysis result can be cached.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Every line here indicates an uncached re-computation of the the analysis. So for example on X86 it is computed 7 times, because it's not preserved by the passes running in between.

Copy link
Contributor Author

@wangpc-pp wangpc-pp Jan 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So why would it be uncached? I noticed that every time it prints something like:

 -*- 'Machine InstCombiner' is the last user of following pass instances. Free these instances
[2025-01-13 16:24:22.476751826] 0x555561c532c0      Freeing Pass 'Machine Register Class Info Analysis' on Function 'test'...

Why would it be unused as there are several uses in the late pipeline? Is this a bug?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And also other passes like Machine Block Frequency Analysis will be re-computed several times even if they are untouched.
I am not familiar with pass manager but it seems to be not intuitive.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You probably need to addPreserved to every pass in the regalloc pipeline, even if the pass does not use it. e.g. I think you need to add it to RenameIndependentSubregs

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to do this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How else would the pass manager know it doesn't invalidate the pass? Does not use the analysis does not imply it cannot be invalidated

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That will be a lot of work? I haven't make regalloc use this pass yet so there is no worry about this currently.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't make regalloc use this pass yet so there is no worry about this currently.

I don't follow. It's a bunch of addPreserved or another preserves-CFG like field, it's merely annoying. You will need something to avoid the recomputatio

Which is a wrapper of `RegisterClassInfo`.

This can cache the result of `RegisterClassInfo` and hence
we can reduce compile time.
@wangpc-pp wangpc-pp force-pushed the main-regclassinfo-pass branch from e50a41a to 86c55df Compare March 17, 2025 08:52
@wangpc-pp
Copy link
Contributor Author

Ping!

@@ -1005,6 +1016,7 @@
; GCN-O2-NEXT: SI lower SGPR spill instructions
; GCN-O2-NEXT: Virtual Register Map
; GCN-O2-NEXT: Live Register Matrix
; GCN-O2-NEXT: Machine Register Class Info Analysis
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still a lot of avoidable recomputations happening, need to addPreserved in more places

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you teach me how to eliminate these recomputations? Or can I land first and can you make a follow-up? I have no idea how to fix this. :-(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants