https://github.com/kasuga-fj created https://github.com/llvm/llvm-project/pull/154940
This patch limits the number of store instructions in the target basic block of MachinePipeliner to improve compilation time.
Contexts:
- In the worst case, the time complexity of the dependency analysis is `O(N^2)`, where `N` is the number of store instructions in the basic block.
- Based on my experience, the pipeliner often fails to find a valid schedule when the number of store instructions is too large.
>From 17d1f3126355abeb16cad7dc218169df537dcee2 Mon Sep 17 00:00:00 2001
From: Ryotaro Kasuga <kasuga.ryotaro at fujitsu.com>
Date: Fri, 22 Aug 2025 12:51:51 +0000
Subject: [PATCH] [MachinePipeliner] Limit the number of stores in BB
---
llvm/lib/CodeGen/MachinePipeliner.cpp | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/llvm/lib/CodeGen/MachinePipeliner.cpp b/llvm/lib/CodeGen/MachinePipeliner.cpp
index 3a9651c5cee04..7579c20b2b580 100644
--- a/llvm/lib/CodeGen/MachinePipeliner.cpp
+++ b/llvm/lib/CodeGen/MachinePipeliner.cpp
@@ -110,6 +110,7 @@ STATISTIC(NumFailZeroMII, "Pipeliner abort due to zero MII");
STATISTIC(NumFailNoSchedule, "Pipeliner abort due to no schedule found");
STATISTIC(NumFailZeroStage, "Pipeliner abort due to zero stage");
STATISTIC(NumFailLargeMaxStage, "Pipeliner abort due to too many stages");
+STATISTIC(NumFailTooManyStores, "Pipeliner abort due to too many stores");
/// A command line option to turn software pipelining on or off.
static cl::opt<bool> EnableSWP("enable-pipeliner", cl::Hidden, cl::init(true),
@@ -193,6 +194,12 @@ static cl::opt<bool>
MVECodeGen("pipeliner-mve-cg", cl::Hidden, cl::init(false),
cl::desc("Use the MVE code generator for software pipelining"));
+/// A command line argument to limit the number of store instructions in the target basic block.
+static cl::opt<unsigned>
+SwpMaxNumStores("pipeliner-max-num-stores",
+ cl::desc("Maximum number of stores allwed in the target loop."),
+ cl::Hidden, cl::init(100));
+
namespace llvm {
// A command line option to enable the CopyToPhi DAG mutation.
@@ -544,6 +551,24 @@ bool MachinePipeliner::canPipelineLoop(MachineLoop &L) {
return false;
}
+ unsigned NumStores = 0;
+ for (MachineInstr &MI : *L.getHeader())
+ if (MI.mayStore())
+ ++NumStores;
+ if (NumStores > SwpMaxNumStores) {
+ NumFailPreheader++;
+ ORE->emit([&]() {
+ return MachineOptimizationRemarkAnalysis(DEBUG_TYPE, "canPipelineLoop",
+ L.getStartLoc(), L.getHeader())
+ << "Too many store instructions in the loop: "
+ << ore::NV("NumStores", NumStores) << " > "
+ << ore::NV("SwpMaxNumStores", SwpMaxNumStores) << ".";
+
+ });
+ ++NumFailTooManyStores;
+ return false;
+ }
+
// Remove any subregisters from inputs to phi nodes.
preprocessPhiNodes(*L.getHeader());
return true;