[clang] [llvm] [OptBisect][IR] Adding a new OptPassGate for disabling passes via name (PR #145059)
Cristian Assaiante via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 10 10:02:01 PDT 2025
https://github.com/cristianassaiante updated https://github.com/llvm/llvm-project/pull/145059
>From ab6063493744ef5a1ee92fd249bf8d86b7299fad Mon Sep 17 00:00:00 2001
From: Cristian Assaiante <cristianassaiante at outlook.com>
Date: Fri, 20 Jun 2025 16:56:23 +0200
Subject: [PATCH 01/13] Adding -opt-disable and a test for it
---
clang/test/CodeGen/opt-disable.c | 13 +++++++
llvm/include/llvm/IR/OptBisect.h | 39 ++++++++++++++++++++
llvm/lib/IR/OptBisect.cpp | 63 ++++++++++++++++++++++++++++++--
3 files changed, 111 insertions(+), 4 deletions(-)
create mode 100644 clang/test/CodeGen/opt-disable.c
diff --git a/clang/test/CodeGen/opt-disable.c b/clang/test/CodeGen/opt-disable.c
new file mode 100644
index 0000000000000..ee90fc5620d65
--- /dev/null
+++ b/clang/test/CodeGen/opt-disable.c
@@ -0,0 +1,13 @@
+// REQUIRES: x86-registered-target
+
+// Make sure opt-bisect works through both pass managers
+//
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -O1 %s -mllvm -opt-disable="inlinerpass,SROAPass,machine code sinking" -mllvm -opt-disable-verbose -emit-obj -o /dev/null 2>&1 | FileCheck %s
+
+// CHECK-NOT: DISABLE: running pass InlinerPass
+// CHECK-NOT: DISABLE: running pass SROAPass
+// CHECK-NOT: DISABLE: running pass Machine code sinking
+// Make sure that legacy pass manager is running
+// CHECK: Instruction Selection
+
+int func(int a) { return a; }
diff --git a/llvm/include/llvm/IR/OptBisect.h b/llvm/include/llvm/IR/OptBisect.h
index be6aef3298b23..51c3a8040da9b 100644
--- a/llvm/include/llvm/IR/OptBisect.h
+++ b/llvm/include/llvm/IR/OptBisect.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include <limits>
+#include <set>
namespace llvm {
@@ -82,6 +83,44 @@ class LLVM_ABI OptBisect : public OptPassGate {
int LastBisectNum = 0;
};
+/// This class implements a mechanism to disable passes and individual
+/// optimizations at compile time based on a command line option
+/// (-opt-disable) in order to study how single transformations, or
+/// combinations thereof, affect the IR.
+class LLVM_ABI OptDisable : public OptPassGate {
+public:
+ /// Default constructor. Initializes the state to empty set. The disabling
+ /// will be enabled by the cl::opt call-back when the command line option
+ /// is processed.
+ /// Clients should not instantiate this class directly. All access should go
+ /// through LLVMContext.
+ OptDisable() = default;
+
+ virtual ~OptDisable() = default;
+
+ /// Checks the pass name to determine if the specified pass should run.
+ ///
+ /// The method prints the name of the pass, and whether or not the pass
+ /// will be executed. It returns true if the pass should run, i.e. if
+ /// its name is was not provided via command line.
+ ///
+ /// Most passes should not call this routine directly. Instead, it is called
+ /// through helper routines provided by the base classes of the pass. For
+ /// instance, function passes should call FunctionPass::skipFunction().
+ bool shouldRunPass(const StringRef PassName,
+ StringRef IRDescription) override;
+
+ /// Parses the command line argument to extract the names of the passes
+ /// to be disabled. Multiple pass names can be provided with comma separation.
+ void setDisabled(StringRef Passes);
+
+ /// isEnabled() should return true before calling shouldRunPass().
+ bool isEnabled() const override { return !DisabledPasses.empty(); }
+
+private:
+ std::set<std::string> DisabledPasses = {};
+};
+
/// Singleton instance of the OptBisect class, so multiple pass managers don't
/// need to coordinate their uses of OptBisect.
LLVM_ABI OptPassGate &getGlobalPassGate();
diff --git a/llvm/lib/IR/OptBisect.cpp b/llvm/lib/IR/OptBisect.cpp
index 559b199445366..aa1dbdfdbebd4 100644
--- a/llvm/lib/IR/OptBisect.cpp
+++ b/llvm/lib/IR/OptBisect.cpp
@@ -17,6 +17,7 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
+#include <sstream>
using namespace llvm;
@@ -37,8 +38,8 @@ static cl::opt<bool> OptBisectVerbose(
cl::desc("Show verbose output when opt-bisect-limit is set"), cl::Hidden,
cl::init(true), cl::Optional);
-static void printPassMessage(const StringRef &Name, int PassNum,
- StringRef TargetDesc, bool Running) {
+static void printBisectPassMessage(const StringRef &Name, int PassNum,
+ StringRef TargetDesc, bool Running) {
StringRef Status = Running ? "" : "NOT ";
errs() << "BISECT: " << Status << "running pass "
<< "(" << PassNum << ") " << Name << " on " << TargetDesc << "\n";
@@ -51,10 +52,64 @@ bool OptBisect::shouldRunPass(const StringRef PassName,
int CurBisectNum = ++LastBisectNum;
bool ShouldRun = (BisectLimit == -1 || CurBisectNum <= BisectLimit);
if (OptBisectVerbose)
- printPassMessage(PassName, CurBisectNum, IRDescription, ShouldRun);
+ printBisectPassMessage(PassName, CurBisectNum, IRDescription, ShouldRun);
return ShouldRun;
}
const int OptBisect::Disabled;
-OptPassGate &llvm::getGlobalPassGate() { return getOptBisector(); }
+static OptDisable &getOptDisabler() {
+ static OptDisable OptDisabler;
+ return OptDisabler;
+}
+
+static cl::opt<std::string> OptDisablePass(
+ "opt-disable", cl::Hidden, cl::init(""), cl::Optional,
+ cl::cb<void, std::string>([](std::string Passes) {
+ getOptDisabler().setDisabled(Passes);
+ }),
+ cl::desc("Optimization pass(es) to disable (comma separated)"));
+
+static cl::opt<bool>
+ OptDisableVerbose("opt-disable-verbose",
+ cl::desc("Show verbose output when opt-disable is set"),
+ cl::Hidden, cl::init(false), cl::Optional);
+
+static void printDisablePassMessage(const StringRef &Name, StringRef TargetDesc,
+ bool Running) {
+ StringRef Status = Running ? "" : "NOT ";
+ errs() << "DISABLE: " << Status << "running pass " << Name << " on "
+ << TargetDesc << "\n";
+}
+
+void OptDisable::setDisabled(StringRef Passes) {
+ std::stringstream StrStream(Passes.str());
+ std::string Token;
+
+ while (std::getline(StrStream, Token, ',')) {
+ if (!Token.empty()) {
+ std::transform(Token.begin(), Token.end(), Token.begin(), ::tolower);
+ DisabledPasses.insert(Token);
+ }
+ }
+}
+
+bool OptDisable::shouldRunPass(const StringRef PassName,
+ StringRef IRDescription) {
+ assert(isEnabled());
+
+ std::string LowerName = PassName.str();
+ std::transform(LowerName.begin(), LowerName.end(), LowerName.begin(),
+ ::tolower);
+
+ bool ShouldRun = DisabledPasses.find(LowerName) == DisabledPasses.end();
+ if (OptDisableVerbose)
+ printDisablePassMessage(PassName, IRDescription, ShouldRun);
+ return ShouldRun;
+}
+
+OptPassGate &llvm::getGlobalPassGate() {
+ if (getOptDisabler().isEnabled())
+ return getOptDisabler();
+ return getOptBisector();
+}
>From 5e79702e3bcee337ced764967d95cb3c684b7fa8 Mon Sep 17 00:00:00 2001
From: Cristian Assaiante <cristianassaiante at outlook.com>
Date: Mon, 23 Jun 2025 11:08:02 +0200
Subject: [PATCH 02/13] Partial solve of review comments
---
llvm/include/llvm/IR/OptBisect.h | 4 ++--
llvm/lib/IR/OptBisect.cpp | 21 +++++++--------------
2 files changed, 9 insertions(+), 16 deletions(-)
diff --git a/llvm/include/llvm/IR/OptBisect.h b/llvm/include/llvm/IR/OptBisect.h
index 51c3a8040da9b..20d332d78a8e5 100644
--- a/llvm/include/llvm/IR/OptBisect.h
+++ b/llvm/include/llvm/IR/OptBisect.h
@@ -15,9 +15,9 @@
#define LLVM_IR_OPTBISECT_H
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSet.h"
#include "llvm/Support/Compiler.h"
#include <limits>
-#include <set>
namespace llvm {
@@ -118,7 +118,7 @@ class LLVM_ABI OptDisable : public OptPassGate {
bool isEnabled() const override { return !DisabledPasses.empty(); }
private:
- std::set<std::string> DisabledPasses = {};
+ StringSet<> DisabledPasses = {};
};
/// Singleton instance of the OptBisect class, so multiple pass managers don't
diff --git a/llvm/lib/IR/OptBisect.cpp b/llvm/lib/IR/OptBisect.cpp
index aa1dbdfdbebd4..5adad939deab6 100644
--- a/llvm/lib/IR/OptBisect.cpp
+++ b/llvm/lib/IR/OptBisect.cpp
@@ -17,7 +17,6 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
-#include <sstream>
using namespace llvm;
@@ -83,14 +82,12 @@ static void printDisablePassMessage(const StringRef &Name, StringRef TargetDesc,
}
void OptDisable::setDisabled(StringRef Passes) {
- std::stringstream StrStream(Passes.str());
- std::string Token;
-
- while (std::getline(StrStream, Token, ',')) {
- if (!Token.empty()) {
- std::transform(Token.begin(), Token.end(), Token.begin(), ::tolower);
- DisabledPasses.insert(Token);
- }
+ llvm::SmallVector<llvm::StringRef, 8> Tokens;
+
+ Passes.split(Tokens, ',', -1, false);
+
+ for (auto Token : Tokens) {
+ DisabledPasses.insert(Token.lower());
}
}
@@ -98,11 +95,7 @@ bool OptDisable::shouldRunPass(const StringRef PassName,
StringRef IRDescription) {
assert(isEnabled());
- std::string LowerName = PassName.str();
- std::transform(LowerName.begin(), LowerName.end(), LowerName.begin(),
- ::tolower);
-
- bool ShouldRun = DisabledPasses.find(LowerName) == DisabledPasses.end();
+ bool ShouldRun = !DisabledPasses.contains(PassName.lower());
if (OptDisableVerbose)
printDisablePassMessage(PassName, IRDescription, ShouldRun);
return ShouldRun;
>From 88625075b9854ad7fabe0007b0bc0b44f8d91f58 Mon Sep 17 00:00:00 2001
From: Cristian Assaiante <cristianassaiante at outlook.com>
Date: Mon, 23 Jun 2025 12:33:05 +0200
Subject: [PATCH 03/13] Fix vector usage
---
llvm/lib/IR/OptBisect.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/IR/OptBisect.cpp b/llvm/lib/IR/OptBisect.cpp
index 5adad939deab6..a2591e07f0a00 100644
--- a/llvm/lib/IR/OptBisect.cpp
+++ b/llvm/lib/IR/OptBisect.cpp
@@ -65,6 +65,7 @@ static OptDisable &getOptDisabler() {
static cl::opt<std::string> OptDisablePass(
"opt-disable", cl::Hidden, cl::init(""), cl::Optional,
cl::cb<void, std::string>([](std::string Passes) {
+ getOptDisabler().initMap();
getOptDisabler().setDisabled(Passes);
}),
cl::desc("Optimization pass(es) to disable (comma separated)"));
@@ -82,7 +83,7 @@ static void printDisablePassMessage(const StringRef &Name, StringRef TargetDesc,
}
void OptDisable::setDisabled(StringRef Passes) {
- llvm::SmallVector<llvm::StringRef, 8> Tokens;
+ llvm::SmallVector<llvm::StringRef, 4> Tokens;
Passes.split(Tokens, ',', -1, false);
>From 9f95327b2b772d24b73f32164e8dad2e889d8847 Mon Sep 17 00:00:00 2001
From: Cristian Assaiante <cristianassaiante at outlook.com>
Date: Mon, 23 Jun 2025 19:23:15 +0200
Subject: [PATCH 04/13] Remove leftovers
---
llvm/lib/IR/OptBisect.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/llvm/lib/IR/OptBisect.cpp b/llvm/lib/IR/OptBisect.cpp
index a2591e07f0a00..db068633454b5 100644
--- a/llvm/lib/IR/OptBisect.cpp
+++ b/llvm/lib/IR/OptBisect.cpp
@@ -65,7 +65,6 @@ static OptDisable &getOptDisabler() {
static cl::opt<std::string> OptDisablePass(
"opt-disable", cl::Hidden, cl::init(""), cl::Optional,
cl::cb<void, std::string>([](std::string Passes) {
- getOptDisabler().initMap();
getOptDisabler().setDisabled(Passes);
}),
cl::desc("Optimization pass(es) to disable (comma separated)"));
>From 56405f21193edb70d4c55b14bc8fa54e7fb96b3e Mon Sep 17 00:00:00 2001
From: Cristian Assaiante <cristianassaiante at outlook.com>
Date: Fri, 27 Jun 2025 19:07:03 +0200
Subject: [PATCH 05/13] Converted to cl::list, renamed verbose flag, cleanup
---
llvm/include/llvm/IR/OptBisect.h | 15 ++++++++-------
llvm/lib/IR/OptBisect.cpp | 28 +++++++++++-----------------
2 files changed, 19 insertions(+), 24 deletions(-)
diff --git a/llvm/include/llvm/IR/OptBisect.h b/llvm/include/llvm/IR/OptBisect.h
index 20d332d78a8e5..83d3579225b1a 100644
--- a/llvm/include/llvm/IR/OptBisect.h
+++ b/llvm/include/llvm/IR/OptBisect.h
@@ -90,7 +90,7 @@ class LLVM_ABI OptBisect : public OptPassGate {
class LLVM_ABI OptDisable : public OptPassGate {
public:
/// Default constructor. Initializes the state to empty set. The disabling
- /// will be enabled by the cl::opt call-back when the command line option
+ /// will be enabled by the cl::list call-back when the command line option
/// is processed.
/// Clients should not instantiate this class directly. All access should go
/// through LLVMContext.
@@ -100,9 +100,10 @@ class LLVM_ABI OptDisable : public OptPassGate {
/// Checks the pass name to determine if the specified pass should run.
///
- /// The method prints the name of the pass, and whether or not the pass
- /// will be executed. It returns true if the pass should run, i.e. if
- /// its name is was not provided via command line.
+ /// It returns true if the pass should run, i.e. if its name is was
+ /// not provided via command line.
+ /// If -opt-disable-enable-verbosity is given, the method prints the
+ /// name of the pass, and whether or not the pass will be executed.
///
/// Most passes should not call this routine directly. Instead, it is called
/// through helper routines provided by the base classes of the pass. For
@@ -112,7 +113,7 @@ class LLVM_ABI OptDisable : public OptPassGate {
/// Parses the command line argument to extract the names of the passes
/// to be disabled. Multiple pass names can be provided with comma separation.
- void setDisabled(StringRef Passes);
+ void setDisabled(StringRef Pass);
/// isEnabled() should return true before calling shouldRunPass().
bool isEnabled() const override { return !DisabledPasses.empty(); }
@@ -121,8 +122,8 @@ class LLVM_ABI OptDisable : public OptPassGate {
StringSet<> DisabledPasses = {};
};
-/// Singleton instance of the OptBisect class, so multiple pass managers don't
-/// need to coordinate their uses of OptBisect.
+/// Singleton instance of the OptPassGate class, so multiple pass managers don't
+/// need to coordinate their uses of OptBisect and OptDisable.
LLVM_ABI OptPassGate &getGlobalPassGate();
} // end namespace llvm
diff --git a/llvm/lib/IR/OptBisect.cpp b/llvm/lib/IR/OptBisect.cpp
index db068633454b5..dc5637a31c08b 100644
--- a/llvm/lib/IR/OptBisect.cpp
+++ b/llvm/lib/IR/OptBisect.cpp
@@ -37,8 +37,8 @@ static cl::opt<bool> OptBisectVerbose(
cl::desc("Show verbose output when opt-bisect-limit is set"), cl::Hidden,
cl::init(true), cl::Optional);
-static void printBisectPassMessage(const StringRef &Name, int PassNum,
- StringRef TargetDesc, bool Running) {
+static void printPassMessage(const StringRef &Name, int PassNum,
+ StringRef TargetDesc, bool Running) {
StringRef Status = Running ? "" : "NOT ";
errs() << "BISECT: " << Status << "running pass "
<< "(" << PassNum << ") " << Name << " on " << TargetDesc << "\n";
@@ -51,7 +51,7 @@ bool OptBisect::shouldRunPass(const StringRef PassName,
int CurBisectNum = ++LastBisectNum;
bool ShouldRun = (BisectLimit == -1 || CurBisectNum <= BisectLimit);
if (OptBisectVerbose)
- printBisectPassMessage(PassName, CurBisectNum, IRDescription, ShouldRun);
+ printPassMessage(PassName, CurBisectNum, IRDescription, ShouldRun);
return ShouldRun;
}
@@ -62,15 +62,15 @@ static OptDisable &getOptDisabler() {
return OptDisabler;
}
-static cl::opt<std::string> OptDisablePass(
- "opt-disable", cl::Hidden, cl::init(""), cl::Optional,
- cl::cb<void, std::string>([](std::string Passes) {
- getOptDisabler().setDisabled(Passes);
+static cl::list<std::string> OptDisablePasses(
+ "opt-disable", cl::Hidden, cl::CommaSeparated, cl::Optional,
+ cl::cb<void, std::string>([](std::string Pass) {
+ getOptDisabler().setDisabled(Pass);
}),
- cl::desc("Optimization pass(es) to disable (comma separated)"));
+ cl::desc("Optimization pass(es) to disable (comma-separated list)"));
static cl::opt<bool>
- OptDisableVerbose("opt-disable-verbose",
+ OptDisableVerbose("opt-disable-enable-verbosity",
cl::desc("Show verbose output when opt-disable is set"),
cl::Hidden, cl::init(false), cl::Optional);
@@ -81,14 +81,8 @@ static void printDisablePassMessage(const StringRef &Name, StringRef TargetDesc,
<< TargetDesc << "\n";
}
-void OptDisable::setDisabled(StringRef Passes) {
- llvm::SmallVector<llvm::StringRef, 4> Tokens;
-
- Passes.split(Tokens, ',', -1, false);
-
- for (auto Token : Tokens) {
- DisabledPasses.insert(Token.lower());
- }
+void OptDisable::setDisabled(StringRef Pass) {
+ DisabledPasses.insert(Pass.lower());
}
bool OptDisable::shouldRunPass(const StringRef PassName,
>From 731bcdf9b93eea1345a269257fe3ef6ee9cc37a0 Mon Sep 17 00:00:00 2001
From: Cristian Assaiante <cristianassaiante at outlook.com>
Date: Thu, 3 Jul 2025 01:41:22 +0200
Subject: [PATCH 06/13] Fixes, new test using opt in llvm/test
---
clang/test/CodeGen/opt-disable.c | 13 -----
llvm/include/llvm/IR/OptBisect.h | 15 ++----
llvm/lib/IR/OptBisect.cpp | 2 +-
llvm/test/Other/opt-disable.ll | 89 ++++++++++++++++++++++++++++++++
4 files changed, 93 insertions(+), 26 deletions(-)
delete mode 100644 clang/test/CodeGen/opt-disable.c
create mode 100644 llvm/test/Other/opt-disable.ll
diff --git a/clang/test/CodeGen/opt-disable.c b/clang/test/CodeGen/opt-disable.c
deleted file mode 100644
index ee90fc5620d65..0000000000000
--- a/clang/test/CodeGen/opt-disable.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// REQUIRES: x86-registered-target
-
-// Make sure opt-bisect works through both pass managers
-//
-// RUN: %clang_cc1 -triple x86_64-linux-gnu -O1 %s -mllvm -opt-disable="inlinerpass,SROAPass,machine code sinking" -mllvm -opt-disable-verbose -emit-obj -o /dev/null 2>&1 | FileCheck %s
-
-// CHECK-NOT: DISABLE: running pass InlinerPass
-// CHECK-NOT: DISABLE: running pass SROAPass
-// CHECK-NOT: DISABLE: running pass Machine code sinking
-// Make sure that legacy pass manager is running
-// CHECK: Instruction Selection
-
-int func(int a) { return a; }
diff --git a/llvm/include/llvm/IR/OptBisect.h b/llvm/include/llvm/IR/OptBisect.h
index a0a6d2532748f..d5b2ece1f84bb 100644
--- a/llvm/include/llvm/IR/OptBisect.h
+++ b/llvm/include/llvm/IR/OptBisect.h
@@ -89,27 +89,18 @@ class LLVM_ABI OptBisect : public OptPassGate {
/// combinations thereof, affect the IR.
class LLVM_ABI OptDisable : public OptPassGate {
public:
- /// Default constructor. Initializes the state to empty set. The disabling
- /// will be enabled by the cl::list call-back when the command line option
- /// is processed.
- /// Clients should not instantiate this class directly. All access should go
- /// through LLVMContext.
- OptDisable() = default;
-
- virtual ~OptDisable() = default;
-
/// Checks the pass name to determine if the specified pass should run.
///
- /// It returns true if the pass should run, i.e. if its name is was
+ /// It returns true if the pass should run, i.e. if its name is was
/// not provided via command line.
- /// If -opt-disable-enable-verbosity is given, the method prints the
+ /// If -opt-disable-enable-verbosity is given, the method prints the
/// name of the pass, and whether or not the pass will be executed.
///
/// Most passes should not call this routine directly. Instead, it is called
/// through helper routines provided by the base classes of the pass. For
/// instance, function passes should call FunctionPass::skipFunction().
bool shouldRunPass(const StringRef PassName,
- StringRef IRDescription) override;
+ StringRef IRDescription) const override;
/// Parses the command line argument to extract the names of the passes
/// to be disabled. Multiple pass names can be provided with comma separation.
diff --git a/llvm/lib/IR/OptBisect.cpp b/llvm/lib/IR/OptBisect.cpp
index f83241f9903e7..471a9cfdc1491 100644
--- a/llvm/lib/IR/OptBisect.cpp
+++ b/llvm/lib/IR/OptBisect.cpp
@@ -86,7 +86,7 @@ void OptDisable::setDisabled(StringRef Pass) {
}
bool OptDisable::shouldRunPass(const StringRef PassName,
- StringRef IRDescription) {
+ StringRef IRDescription) const {
assert(isEnabled());
bool ShouldRun = !DisabledPasses.contains(PassName.lower());
diff --git a/llvm/test/Other/opt-disable.ll b/llvm/test/Other/opt-disable.ll
new file mode 100644
index 0000000000000..0b1a0b08a5a8b
--- /dev/null
+++ b/llvm/test/Other/opt-disable.ll
@@ -0,0 +1,89 @@
+; RUN: opt -disable-output -disable-verify \
+; RUN: -opt-disable-enable-verbosity \
+; RUN: -passes=inferattrs -opt-disable=inferfunctionattrspass %s 2>&1 \
+; RUN: | FileCheck %s --check-prefix=CHECK-MODULE-PASS
+; CHECK-MODULE-PASS: DISABLE: NOT running pass InferFunctionAttrsPass on [module]
+
+; RUN: opt -disable-output -disable-verify \
+; RUN: -opt-disable-enable-verbosity \
+; RUN: -passes=sroa -opt-disable=sroapass %s 2>&1 \
+; RUN: | FileCheck %s --check-prefix=CHECK-FUNCTION-PASS
+; CHECK-FUNCTION-PASS: DISABLE: NOT running pass SROAPass on f1
+; CHECK-FUNCTION-PASS: DISABLE: NOT running pass SROAPass on f2
+; CHECK-FUNCTION-PASS: DISABLE: NOT running pass SROAPass on f3
+; CHECK-FUNCTION-PASS: DISABLE: NOT running pass SROAPass on f4
+
+; RUN: opt -disable-output -disable-verify \
+; RUN: -opt-disable=inferfunctionattrspass,PostOrderFunctionAttrsPass \
+; RUN: -opt-disable-enable-verbosity \
+; RUN: -passes='inferattrs,cgscc(function-attrs,function(early-cse))' %s 2>&1 \
+; RUN: | FileCheck %s --check-prefix=CHECK-MULTI-PASS
+; CHECK-MULTI-PASS: DISABLE: NOT running pass InferFunctionAttrsPass on [module]
+; CHECK-MULTI-PASS: DISABLE: NOT running pass PostOrderFunctionAttrsPass on (f1)
+; CHECK-MULTI-PASS: DISABLE: running pass EarlyCSEPass on f1
+; CHECK-MULTI-PASS: DISABLE: NOT running pass PostOrderFunctionAttrsPass on (f2)
+; CHECK-MULTI-PASS: DISABLE: running pass EarlyCSEPass on f2
+; CHECK-MULTI-PASS: DISABLE: NOT running pass PostOrderFunctionAttrsPass on (f3)
+; CHECK-MULTI-PASS: DISABLE: running pass EarlyCSEPass on f3
+; CHECK-MULTI-PASS: DISABLE: NOT running pass PostOrderFunctionAttrsPass on (f4)
+; CHECK-MULTI-PASS: DISABLE: running pass EarlyCSEPass on f4
+
+declare i32 @g()
+
+define void @f1(i1 %arg) {
+entry:
+ br label %loop.0
+loop.0:
+ br i1 %arg, label %loop.0.0, label %loop.1
+loop.0.0:
+ br i1 %arg, label %loop.0.0, label %loop.0.1
+loop.0.1:
+ br i1 %arg, label %loop.0.1, label %loop.0
+loop.1:
+ br i1 %arg, label %loop.1, label %loop.1.bb1
+loop.1.bb1:
+ br i1 %arg, label %loop.1, label %loop.1.bb2
+loop.1.bb2:
+ br i1 %arg, label %end, label %loop.1.0
+loop.1.0:
+ br i1 %arg, label %loop.1.0, label %loop.1
+end:
+ ret void
+}
+
+define i32 @f2() {
+entry:
+ ret i32 0
+}
+
+define i32 @f3() {
+entry:
+ %temp = call i32 @g()
+ %icmp = icmp ugt i32 %temp, 2
+ br i1 %icmp, label %bb.true, label %bb.false
+bb.true:
+ %temp2 = call i32 @f2()
+ ret i32 %temp2
+bb.false:
+ ret i32 0
+}
+
+; This function is here to verify that opt-bisect can skip all passes for
+; functions that contain lifetime intrinsics.
+define void @f4(i1 %arg) {
+entry:
+ %i = alloca i32, align 4
+ call void @llvm.lifetime.start(i64 4, ptr %i)
+ br label %for.cond
+
+for.cond:
+ br i1 %arg, label %for.body, label %for.end
+
+for.body:
+ br label %for.cond
+
+for.end:
+ ret void
+}
+
+declare void @llvm.lifetime.start(i64, ptr nocapture)
\ No newline at end of file
>From 12bb09c24b4ac487a48b59f8a3ee5ba3e7a61d50 Mon Sep 17 00:00:00 2001
From: Cristian Assaiante <cristianassaiante at outlook.com>
Date: Thu, 3 Jul 2025 01:53:33 +0200
Subject: [PATCH 07/13] Added test description
---
llvm/test/Other/opt-disable.ll | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/llvm/test/Other/opt-disable.ll b/llvm/test/Other/opt-disable.ll
index 0b1a0b08a5a8b..63d59c5792d3f 100644
--- a/llvm/test/Other/opt-disable.ll
+++ b/llvm/test/Other/opt-disable.ll
@@ -1,3 +1,7 @@
+; This test uses the same IR functions of the opt-bisect test
+; but it checks the correctness of the -opt-disable flag.
+; -opt-disable-enable-verbosity is required to have output.
+
; RUN: opt -disable-output -disable-verify \
; RUN: -opt-disable-enable-verbosity \
; RUN: -passes=inferattrs -opt-disable=inferfunctionattrspass %s 2>&1 \
@@ -68,8 +72,6 @@ bb.false:
ret i32 0
}
-; This function is here to verify that opt-bisect can skip all passes for
-; functions that contain lifetime intrinsics.
define void @f4(i1 %arg) {
entry:
%i = alloca i32, align 4
@@ -86,4 +88,4 @@ for.end:
ret void
}
-declare void @llvm.lifetime.start(i64, ptr nocapture)
\ No newline at end of file
+declare void @llvm.lifetime.start(i64, ptr nocapture)
>From 6cc429b97977b06208548b8cc839f46312b75178 Mon Sep 17 00:00:00 2001
From: Cristian Assaiante <cristianassaiante at outlook.com>
Date: Thu, 3 Jul 2025 10:28:05 +0200
Subject: [PATCH 08/13] Removing leftovers, solving nits
---
llvm/include/llvm/IR/OptBisect.h | 2 +-
llvm/lib/IR/OptBisect.cpp | 40 +++++++++++++++-----------------
2 files changed, 20 insertions(+), 22 deletions(-)
diff --git a/llvm/include/llvm/IR/OptBisect.h b/llvm/include/llvm/IR/OptBisect.h
index d5b2ece1f84bb..d813ae933d65e 100644
--- a/llvm/include/llvm/IR/OptBisect.h
+++ b/llvm/include/llvm/IR/OptBisect.h
@@ -99,7 +99,7 @@ class LLVM_ABI OptDisable : public OptPassGate {
/// Most passes should not call this routine directly. Instead, it is called
/// through helper routines provided by the base classes of the pass. For
/// instance, function passes should call FunctionPass::skipFunction().
- bool shouldRunPass(const StringRef PassName,
+ bool shouldRunPass(StringRef PassName,
StringRef IRDescription) const override;
/// Parses the command line argument to extract the names of the passes
diff --git a/llvm/lib/IR/OptBisect.cpp b/llvm/lib/IR/OptBisect.cpp
index 471a9cfdc1491..9f2a844f13762 100644
--- a/llvm/lib/IR/OptBisect.cpp
+++ b/llvm/lib/IR/OptBisect.cpp
@@ -25,6 +25,11 @@ static OptBisect &getOptBisector() {
return OptBisector;
}
+static OptDisable &getOptDisabler() {
+ static OptDisable OptDisabler;
+ return OptDisabler;
+}
+
static cl::opt<int> OptBisectLimit("opt-bisect-limit", cl::Hidden,
cl::init(OptBisect::Disabled), cl::Optional,
cl::cb<void, int>([](int Limit) {
@@ -37,6 +42,18 @@ static cl::opt<bool> OptBisectVerbose(
cl::desc("Show verbose output when opt-bisect-limit is set"), cl::Hidden,
cl::init(true), cl::Optional);
+static cl::list<std::string> OptDisablePasses(
+ "opt-disable", cl::Hidden, cl::CommaSeparated, cl::Optional,
+ cl::cb<void, std::string>([](std::string Pass) {
+ getOptDisabler().setDisabled(Pass);
+ }),
+ cl::desc("Optimization pass(es) to disable (comma-separated list)"));
+
+static cl::opt<bool>
+ OptDisableVerbose("opt-disable-enable-verbosity",
+ cl::desc("Show verbose output when opt-disable is set"),
+ cl::Hidden, cl::init(false), cl::Optional);
+
static void printPassMessage(StringRef Name, int PassNum, StringRef TargetDesc,
bool Running) {
StringRef Status = Running ? "" : "NOT ";
@@ -55,29 +72,10 @@ bool OptBisect::shouldRunPass(StringRef PassName,
return ShouldRun;
}
-const int OptBisect::Disabled;
-
-static OptDisable &getOptDisabler() {
- static OptDisable OptDisabler;
- return OptDisabler;
-}
-
-static cl::list<std::string> OptDisablePasses(
- "opt-disable", cl::Hidden, cl::CommaSeparated, cl::Optional,
- cl::cb<void, std::string>([](std::string Pass) {
- getOptDisabler().setDisabled(Pass);
- }),
- cl::desc("Optimization pass(es) to disable (comma-separated list)"));
-
-static cl::opt<bool>
- OptDisableVerbose("opt-disable-enable-verbosity",
- cl::desc("Show verbose output when opt-disable is set"),
- cl::Hidden, cl::init(false), cl::Optional);
-
static void printDisablePassMessage(const StringRef &Name, StringRef TargetDesc,
bool Running) {
StringRef Status = Running ? "" : "NOT ";
- errs() << "DISABLE: " << Status << "running pass " << Name << " on "
+ dbgs() << "DISABLE: " << Status << "running pass " << Name << " on "
<< TargetDesc << "\n";
}
@@ -85,7 +83,7 @@ void OptDisable::setDisabled(StringRef Pass) {
DisabledPasses.insert(Pass.lower());
}
-bool OptDisable::shouldRunPass(const StringRef PassName,
+bool OptDisable::shouldRunPass(StringRef PassName,
StringRef IRDescription) const {
assert(isEnabled());
>From 825b711b36281e1583fa9dfb8ce86fc514d96fa6 Mon Sep 17 00:00:00 2001
From: Cristian Assaiante <assaiante at diag.uniroma1.it>
Date: Thu, 10 Jul 2025 01:35:42 +0200
Subject: [PATCH 09/13] Update llvm/lib/IR/OptBisect.cpp
Co-authored-by: Nikita Popov <github at npopov.com>
---
llvm/lib/IR/OptBisect.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/IR/OptBisect.cpp b/llvm/lib/IR/OptBisect.cpp
index 9f2a844f13762..c3f642accb21b 100644
--- a/llvm/lib/IR/OptBisect.cpp
+++ b/llvm/lib/IR/OptBisect.cpp
@@ -44,7 +44,7 @@ static cl::opt<bool> OptBisectVerbose(
static cl::list<std::string> OptDisablePasses(
"opt-disable", cl::Hidden, cl::CommaSeparated, cl::Optional,
- cl::cb<void, std::string>([](std::string Pass) {
+ cl::cb<void, std::string>([](const std::string &Pass) {
getOptDisabler().setDisabled(Pass);
}),
cl::desc("Optimization pass(es) to disable (comma-separated list)"));
>From 284a13f57565ecef96851c3cb229ef1924e52657 Mon Sep 17 00:00:00 2001
From: Cristian Assaiante <cristianassaiante at outlook.com>
Date: Thu, 10 Jul 2025 09:36:32 +0200
Subject: [PATCH 10/13] Short names with both NPM and Legacy, updated test,
solved nits
---
llvm/include/llvm/Pass.h | 4 +++
llvm/lib/IR/OptBisect.cpp | 4 +--
llvm/lib/IR/Pass.cpp | 24 ++++++++++++--
llvm/lib/Passes/StandardInstrumentations.cpp | 10 ++++--
llvm/test/Other/opt-disable.ll | 34 ++++++++++----------
5 files changed, 52 insertions(+), 24 deletions(-)
diff --git a/llvm/include/llvm/Pass.h b/llvm/include/llvm/Pass.h
index 2ecd47dd10bde..65772f6e64b60 100644
--- a/llvm/include/llvm/Pass.h
+++ b/llvm/include/llvm/Pass.h
@@ -114,6 +114,10 @@ class LLVM_ABI Pass {
/// Registration templates, but can be overloaded directly.
virtual StringRef getPassName() const;
+ /// getPassArgument - Return a nice clean name for a pass
+ /// corresponding to that used to enable the pass in opt
+ virtual StringRef getPassArgument() const;
+
/// getPassID - Return the PassID number that corresponds to this pass.
AnalysisID getPassID() const {
return PassID;
diff --git a/llvm/lib/IR/OptBisect.cpp b/llvm/lib/IR/OptBisect.cpp
index c3f642accb21b..2a60e83688576 100644
--- a/llvm/lib/IR/OptBisect.cpp
+++ b/llvm/lib/IR/OptBisect.cpp
@@ -75,7 +75,7 @@ bool OptBisect::shouldRunPass(StringRef PassName,
static void printDisablePassMessage(const StringRef &Name, StringRef TargetDesc,
bool Running) {
StringRef Status = Running ? "" : "NOT ";
- dbgs() << "DISABLE: " << Status << "running pass " << Name << " on "
+ dbgs() << "OptDisable: " << Status << "running pass " << Name << " on "
<< TargetDesc << "\n";
}
@@ -87,7 +87,7 @@ bool OptDisable::shouldRunPass(StringRef PassName,
StringRef IRDescription) const {
assert(isEnabled());
- bool ShouldRun = !DisabledPasses.contains(PassName.lower());
+ const bool ShouldRun = !DisabledPasses.contains(PassName.lower());
if (OptDisableVerbose)
printDisablePassMessage(PassName, IRDescription, ShouldRun);
return ShouldRun;
diff --git a/llvm/lib/IR/Pass.cpp b/llvm/lib/IR/Pass.cpp
index 2c5ef7193b463..9f66019afa4e9 100644
--- a/llvm/lib/IR/Pass.cpp
+++ b/llvm/lib/IR/Pass.cpp
@@ -62,8 +62,13 @@ static std::string getDescription(const Module &M) {
bool ModulePass::skipModule(const Module &M) const {
const OptPassGate &Gate = M.getContext().getOptPassGate();
+
+ StringRef PassName = this->getPassArgument();
+ if (PassName.empty())
+ PassName = this->getPassName();
+
return Gate.isEnabled() &&
- !Gate.shouldRunPass(this->getPassName(), getDescription(M));
+ !Gate.shouldRunPass(PassName, getDescription(M));
}
bool Pass::mustPreserveAnalysisID(char &AID) const {
@@ -86,6 +91,16 @@ StringRef Pass::getPassName() const {
return "Unnamed pass: implement Pass::getPassName()";
}
+/// getPassArgument - Return a nice clean name for a pass
+/// corresponding to that used to enable the pass in opt
+StringRef Pass::getPassArgument() const {
+ AnalysisID AID = getPassID();
+ const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(AID);
+ if (PI)
+ return PI->getPassArgument();
+ return "";
+}
+
void Pass::preparePassManager(PMStack &) {
// By default, don't do anything.
}
@@ -173,8 +188,13 @@ static std::string getDescription(const Function &F) {
bool FunctionPass::skipFunction(const Function &F) const {
OptPassGate &Gate = F.getContext().getOptPassGate();
+
+ StringRef PassName = this->getPassArgument();
+ if (PassName.empty())
+ PassName = this->getPassName();
+
if (Gate.isEnabled() &&
- !Gate.shouldRunPass(this->getPassName(), getDescription(F)))
+ !Gate.shouldRunPass(PassName, getDescription(F)))
return true;
if (F.hasOptNone()) {
diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp
index 0623e66772047..f165e85baf611 100644
--- a/llvm/lib/Passes/StandardInstrumentations.cpp
+++ b/llvm/lib/Passes/StandardInstrumentations.cpp
@@ -1078,9 +1078,13 @@ void OptPassGateInstrumentation::registerCallbacks(
if (!PassGate.isEnabled())
return;
- PIC.registerShouldRunOptionalPassCallback([this](StringRef PassName, Any IR) {
- return this->shouldRun(PassName, IR);
- });
+ PIC.registerShouldRunOptionalPassCallback(
+ [this, &PIC](StringRef ClassName, Any IR) {
+ StringRef PassName = PIC.getPassNameForClassName(ClassName);
+ if (PassName.empty())
+ return this->shouldRun(ClassName, IR);
+ return this->shouldRun(PassName, IR);
+ });
}
raw_ostream &PrintPassInstrumentation::print() {
diff --git a/llvm/test/Other/opt-disable.ll b/llvm/test/Other/opt-disable.ll
index 63d59c5792d3f..4506042215cbf 100644
--- a/llvm/test/Other/opt-disable.ll
+++ b/llvm/test/Other/opt-disable.ll
@@ -4,33 +4,33 @@
; RUN: opt -disable-output -disable-verify \
; RUN: -opt-disable-enable-verbosity \
-; RUN: -passes=inferattrs -opt-disable=inferfunctionattrspass %s 2>&1 \
+; RUN: -passes=inferattrs -opt-disable=inferattrs %s 2>&1 \
; RUN: | FileCheck %s --check-prefix=CHECK-MODULE-PASS
-; CHECK-MODULE-PASS: DISABLE: NOT running pass InferFunctionAttrsPass on [module]
+; CHECK-MODULE-PASS: OptDisable: NOT running pass inferattrs on [module]
; RUN: opt -disable-output -disable-verify \
; RUN: -opt-disable-enable-verbosity \
-; RUN: -passes=sroa -opt-disable=sroapass %s 2>&1 \
+; RUN: -passes=sroa -opt-disable=sroa %s 2>&1 \
; RUN: | FileCheck %s --check-prefix=CHECK-FUNCTION-PASS
-; CHECK-FUNCTION-PASS: DISABLE: NOT running pass SROAPass on f1
-; CHECK-FUNCTION-PASS: DISABLE: NOT running pass SROAPass on f2
-; CHECK-FUNCTION-PASS: DISABLE: NOT running pass SROAPass on f3
-; CHECK-FUNCTION-PASS: DISABLE: NOT running pass SROAPass on f4
+; CHECK-FUNCTION-PASS: OptDisable: NOT running pass sroa on f1
+; CHECK-FUNCTION-PASS: OptDisable: NOT running pass sroa on f2
+; CHECK-FUNCTION-PASS: OptDisable: NOT running pass sroa on f3
+; CHECK-FUNCTION-PASS: OptDisable: NOT running pass sroa on f4
; RUN: opt -disable-output -disable-verify \
-; RUN: -opt-disable=inferfunctionattrspass,PostOrderFunctionAttrsPass \
+; RUN: -opt-disable=inferattrs,function-attrs \
; RUN: -opt-disable-enable-verbosity \
; RUN: -passes='inferattrs,cgscc(function-attrs,function(early-cse))' %s 2>&1 \
; RUN: | FileCheck %s --check-prefix=CHECK-MULTI-PASS
-; CHECK-MULTI-PASS: DISABLE: NOT running pass InferFunctionAttrsPass on [module]
-; CHECK-MULTI-PASS: DISABLE: NOT running pass PostOrderFunctionAttrsPass on (f1)
-; CHECK-MULTI-PASS: DISABLE: running pass EarlyCSEPass on f1
-; CHECK-MULTI-PASS: DISABLE: NOT running pass PostOrderFunctionAttrsPass on (f2)
-; CHECK-MULTI-PASS: DISABLE: running pass EarlyCSEPass on f2
-; CHECK-MULTI-PASS: DISABLE: NOT running pass PostOrderFunctionAttrsPass on (f3)
-; CHECK-MULTI-PASS: DISABLE: running pass EarlyCSEPass on f3
-; CHECK-MULTI-PASS: DISABLE: NOT running pass PostOrderFunctionAttrsPass on (f4)
-; CHECK-MULTI-PASS: DISABLE: running pass EarlyCSEPass on f4
+; CHECK-MULTI-PASS: OptDisable: NOT running pass inferattrs on [module]
+; CHECK-MULTI-PASS: OptDisable: NOT running pass function-attrs on (f1)
+; CHECK-MULTI-PASS: OptDisable: running pass early-cse on f1
+; CHECK-MULTI-PASS: OptDisable: NOT running pass function-attrs on (f2)
+; CHECK-MULTI-PASS: OptDisable: running pass early-cse on f2
+; CHECK-MULTI-PASS: OptDisable: NOT running pass function-attrs on (f3)
+; CHECK-MULTI-PASS: OptDisable: running pass early-cse on f3
+; CHECK-MULTI-PASS: OptDisable: NOT running pass function-attrs on (f4)
+; CHECK-MULTI-PASS: OptDisable: running pass early-cse on f4
declare i32 @g()
>From 39b85f156f6b2a0246092a2219ecf4c7724a7345 Mon Sep 17 00:00:00 2001
From: Cristian Assaiante <cristianassaiante at outlook.com>
Date: Thu, 10 Jul 2025 09:45:31 +0200
Subject: [PATCH 11/13] Update failing opt-bisect test
---
.../test/Other/opt-bisect-new-pass-manager.ll | 76 +++++++++----------
1 file changed, 38 insertions(+), 38 deletions(-)
diff --git a/llvm/test/Other/opt-bisect-new-pass-manager.ll b/llvm/test/Other/opt-bisect-new-pass-manager.ll
index 01dad705ec362..8f8078d4d8409 100644
--- a/llvm/test/Other/opt-bisect-new-pass-manager.ll
+++ b/llvm/test/Other/opt-bisect-new-pass-manager.ll
@@ -11,84 +11,84 @@
; RUN: opt -disable-output -disable-verify \
; RUN: -passes=inferattrs -opt-bisect-limit=-1 %s 2>&1 \
; RUN: | FileCheck %s --check-prefix=CHECK-MODULE-PASS
-; CHECK-MODULE-PASS: BISECT: running pass (1) InferFunctionAttrsPass on [module]
+; CHECK-MODULE-PASS: BISECT: running pass (1) inferattrs on [module]
; RUN: opt -disable-output -disable-verify \
; RUN: -passes=inferattrs -opt-bisect-limit=0 %s 2>&1 \
; RUN: | FileCheck %s --check-prefix=CHECK-LIMIT-MODULE-PASS
-; CHECK-LIMIT-MODULE-PASS: BISECT: NOT running pass (1) InferFunctionAttrsPass on [module]
+; CHECK-LIMIT-MODULE-PASS: BISECT: NOT running pass (1) inferattrs on [module]
; RUN: opt -disable-output -debug-pass-manager \
; RUN: -passes=inferattrs -opt-bisect-limit=-1 %s 2>&1 \
; RUN: | FileCheck %s --check-prefix=CHECK-REQUIRED-PASS
-; CHECK-REQUIRED-PASS: BISECT: running pass (1) InferFunctionAttrsPass on [module]
+; CHECK-REQUIRED-PASS: BISECT: running pass (1) inferattrs on [module]
; CHECK-REQUIRED-PASS-NOT: BISECT: {{.*}}VerifierPass
; CHECK-REQUIRED-PASS: Running pass: VerifierPass
; RUN: opt -disable-output -debug-pass-manager \
; RUN: -passes=inferattrs -opt-bisect-limit=0 %s 2>&1 \
; RUN: | FileCheck %s --check-prefix=CHECK-LIMIT-REQUIRED-PASS
-; CHECK-LIMIT-REQUIRED-PASS: BISECT: NOT running pass (1) InferFunctionAttrsPass on [module]
+; CHECK-LIMIT-REQUIRED-PASS: BISECT: NOT running pass (1) inferattrs on [module]
; CHECK-LIMIT-REQUIRED-PASS-NOT: BISECT: {{.*}}VerifierPass
; CHECK-LIMIT-REQUIRED-PASS: Running pass: VerifierPass
; RUN: opt -disable-output -disable-verify \
; RUN: -passes=early-cse -opt-bisect-limit=-1 %s 2>&1 \
; RUN: | FileCheck %s --check-prefix=CHECK-FUNCTION-PASS
-; CHECK-FUNCTION-PASS: BISECT: running pass (1) EarlyCSEPass on f1
-; CHECK-FUNCTION-PASS: BISECT: running pass (2) EarlyCSEPass on f2
-; CHECK-FUNCTION-PASS: BISECT: running pass (3) EarlyCSEPass on f3
-; CHECK-FUNCTION-PASS: BISECT: running pass (4) EarlyCSEPass on f4
+; CHECK-FUNCTION-PASS: BISECT: running pass (1) early-cse on f1
+; CHECK-FUNCTION-PASS: BISECT: running pass (2) early-cse on f2
+; CHECK-FUNCTION-PASS: BISECT: running pass (3) early-cse on f3
+; CHECK-FUNCTION-PASS: BISECT: running pass (4) early-cse on f4
; RUN: opt -disable-output -disable-verify \
; RUN: -passes=early-cse -opt-bisect-limit=2 %s 2>&1 \
; RUN: | FileCheck %s --check-prefix=CHECK-LIMIT-FUNCTION-PASS
-; CHECK-LIMIT-FUNCTION-PASS: BISECT: running pass (1) EarlyCSEPass on f1
-; CHECK-LIMIT-FUNCTION-PASS: BISECT: running pass (2) EarlyCSEPass on f2
-; CHECK-LIMIT-FUNCTION-PASS: BISECT: NOT running pass (3) EarlyCSEPass on f3
-; CHECK-LIMIT-FUNCTION-PASS: BISECT: NOT running pass (4) EarlyCSEPass on f4
+; CHECK-LIMIT-FUNCTION-PASS: BISECT: running pass (1) early-cse on f1
+; CHECK-LIMIT-FUNCTION-PASS: BISECT: running pass (2) early-cse on f2
+; CHECK-LIMIT-FUNCTION-PASS: BISECT: NOT running pass (3) early-cse on f3
+; CHECK-LIMIT-FUNCTION-PASS: BISECT: NOT running pass (4) early-cse on f4
; RUN: opt -disable-output -disable-verify \
; RUN: -passes=function-attrs -opt-bisect-limit=-1 %s 2>&1 \
; RUN: | FileCheck %s --check-prefix=CHECK-CGSCC-PASS
-; CHECK-CGSCC-PASS: BISECT: running pass (1) PostOrderFunctionAttrsPass on (f1)
-; CHECK-CGSCC-PASS: BISECT: running pass (2) PostOrderFunctionAttrsPass on (f2)
-; CHECK-CGSCC-PASS: BISECT: running pass (3) PostOrderFunctionAttrsPass on (f3)
-; CHECK-CGSCC-PASS: BISECT: running pass (4) PostOrderFunctionAttrsPass on (f4)
+; CHECK-CGSCC-PASS: BISECT: running pass (1) function-attrs on (f1)
+; CHECK-CGSCC-PASS: BISECT: running pass (2) function-attrs on (f2)
+; CHECK-CGSCC-PASS: BISECT: running pass (3) function-attrs on (f3)
+; CHECK-CGSCC-PASS: BISECT: running pass (4) function-attrs on (f4)
; RUN: opt -disable-output -disable-verify \
; RUN: -passes=function-attrs -opt-bisect-limit=3 %s 2>&1 \
; RUN: | FileCheck %s --check-prefix=CHECK-LIMIT-CGSCC-PASS
-; CHECK-LIMIT-CGSCC-PASS: BISECT: running pass (1) PostOrderFunctionAttrsPass on (f1)
-; CHECK-LIMIT-CGSCC-PASS: BISECT: running pass (2) PostOrderFunctionAttrsPass on (f2)
-; CHECK-LIMIT-CGSCC-PASS: BISECT: running pass (3) PostOrderFunctionAttrsPass on (f3)
-; CHECK-LIMIT-CGSCC-PASS: BISECT: NOT running pass (4) PostOrderFunctionAttrsPass on (f4)
+; CHECK-LIMIT-CGSCC-PASS: BISECT: running pass (1) function-attrs on (f1)
+; CHECK-LIMIT-CGSCC-PASS: BISECT: running pass (2) function-attrs on (f2)
+; CHECK-LIMIT-CGSCC-PASS: BISECT: running pass (3) function-attrs on (f3)
+; CHECK-LIMIT-CGSCC-PASS: BISECT: NOT running pass (4) function-attrs on (f4)
; RUN: opt -disable-output -disable-verify -opt-bisect-limit=-1 \
; RUN: -passes='inferattrs,cgscc(function-attrs,function(early-cse))' %s 2>&1 \
; RUN: | FileCheck %s --check-prefix=CHECK-MULTI-PASS
-; CHECK-MULTI-PASS: BISECT: running pass (1) InferFunctionAttrsPass on [module]
-; CHECK-MULTI-PASS: BISECT: running pass (2) PostOrderFunctionAttrsPass on (f1)
-; CHECK-MULTI-PASS: BISECT: running pass (3) EarlyCSEPass on f1
-; CHECK-MULTI-PASS: BISECT: running pass (4) PostOrderFunctionAttrsPass on (f2)
-; CHECK-MULTI-PASS: BISECT: running pass (5) EarlyCSEPass on f2
-; CHECK-MULTI-PASS: BISECT: running pass (6) PostOrderFunctionAttrsPass on (f3)
-; CHECK-MULTI-PASS: BISECT: running pass (7) EarlyCSEPass on f3
-; CHECK-MULTI-PASS: BISECT: running pass (8) PostOrderFunctionAttrsPass on (f4)
-; CHECK-MULTI-PASS: BISECT: running pass (9) EarlyCSEPass on f4
+; CHECK-MULTI-PASS: BISECT: running pass (1) inferattrs on [module]
+; CHECK-MULTI-PASS: BISECT: running pass (2) function-attrs on (f1)
+; CHECK-MULTI-PASS: BISECT: running pass (3) early-cse on f1
+; CHECK-MULTI-PASS: BISECT: running pass (4) function-attrs on (f2)
+; CHECK-MULTI-PASS: BISECT: running pass (5) early-cse on f2
+; CHECK-MULTI-PASS: BISECT: running pass (6) function-attrs on (f3)
+; CHECK-MULTI-PASS: BISECT: running pass (7) early-cse on f3
+; CHECK-MULTI-PASS: BISECT: running pass (8) function-attrs on (f4)
+; CHECK-MULTI-PASS: BISECT: running pass (9) early-cse on f4
; RUN: opt -disable-output -disable-verify -opt-bisect-limit=7 \
; RUN: -passes='inferattrs,cgscc(function-attrs,function(early-cse))' %s 2>&1 \
; RUN: | FileCheck %s --check-prefix=CHECK-LIMIT-MULTI-PASS
-; CHECK-LIMIT-MULTI-PASS: BISECT: running pass (1) InferFunctionAttrsPass on [module]
-; CHECK-LIMIT-MULTI-PASS: BISECT: running pass (2) PostOrderFunctionAttrsPass on (f1)
-; CHECK-LIMIT-MULTI-PASS: BISECT: running pass (3) EarlyCSEPass on f1
-; CHECK-LIMIT-MULTI-PASS: BISECT: running pass (4) PostOrderFunctionAttrsPass on (f2)
-; CHECK-LIMIT-MULTI-PASS: BISECT: running pass (5) EarlyCSEPass on f2
-; CHECK-LIMIT-MULTI-PASS: BISECT: running pass (6) PostOrderFunctionAttrsPass on (f3)
-; CHECK-LIMIT-MULTI-PASS: BISECT: running pass (7) EarlyCSEPass on f3
-; CHECK-LIMIT-MULTI-PASS: BISECT: NOT running pass (8) PostOrderFunctionAttrsPass on (f4)
-; CHECK-LIMIT-MULTI-PASS: BISECT: NOT running pass (9) EarlyCSEPass on f4
+; CHECK-LIMIT-MULTI-PASS: BISECT: running pass (1) inferattrs on [module]
+; CHECK-LIMIT-MULTI-PASS: BISECT: running pass (2) function-attrs on (f1)
+; CHECK-LIMIT-MULTI-PASS: BISECT: running pass (3) early-cse on f1
+; CHECK-LIMIT-MULTI-PASS: BISECT: running pass (4) function-attrs on (f2)
+; CHECK-LIMIT-MULTI-PASS: BISECT: running pass (5) early-cse on f2
+; CHECK-LIMIT-MULTI-PASS: BISECT: running pass (6) function-attrs on (f3)
+; CHECK-LIMIT-MULTI-PASS: BISECT: running pass (7) early-cse on f3
+; CHECK-LIMIT-MULTI-PASS: BISECT: NOT running pass (8) function-attrs on (f4)
+; CHECK-LIMIT-MULTI-PASS: BISECT: NOT running pass (9) early-cse on f4
; Make sure we don't skip writing the output to stdout.
; RUN: opt %s -opt-bisect-limit=0 -passes=early-cse | opt -S | FileCheck %s -check-prefix=CHECK-OUTPUT
>From 3b766f22567489999076156aff81115d71f9ce46 Mon Sep 17 00:00:00 2001
From: Cristian Assaiante <assaiante at diag.uniroma1.it>
Date: Thu, 10 Jul 2025 18:53:58 +0200
Subject: [PATCH 12/13] Apply suggestions from code review
Co-authored-by: Nikita Popov <github at npopov.com>
---
llvm/include/llvm/Pass.h | 2 +-
llvm/lib/IR/OptBisect.cpp | 2 +-
llvm/lib/IR/Pass.cpp | 4 ++--
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/llvm/include/llvm/Pass.h b/llvm/include/llvm/Pass.h
index 65772f6e64b60..f7345f0da5c56 100644
--- a/llvm/include/llvm/Pass.h
+++ b/llvm/include/llvm/Pass.h
@@ -114,7 +114,7 @@ class LLVM_ABI Pass {
/// Registration templates, but can be overloaded directly.
virtual StringRef getPassName() const;
- /// getPassArgument - Return a nice clean name for a pass
+ /// Return a nice clean name for a pass
/// corresponding to that used to enable the pass in opt
virtual StringRef getPassArgument() const;
diff --git a/llvm/lib/IR/OptBisect.cpp b/llvm/lib/IR/OptBisect.cpp
index 2a60e83688576..7717ffcef85d2 100644
--- a/llvm/lib/IR/OptBisect.cpp
+++ b/llvm/lib/IR/OptBisect.cpp
@@ -87,7 +87,7 @@ bool OptDisable::shouldRunPass(StringRef PassName,
StringRef IRDescription) const {
assert(isEnabled());
- const bool ShouldRun = !DisabledPasses.contains(PassName.lower());
+ const bool ShouldRun = !DisabledPasses.contains(PassName);
if (OptDisableVerbose)
printDisablePassMessage(PassName, IRDescription, ShouldRun);
return ShouldRun;
diff --git a/llvm/lib/IR/Pass.cpp b/llvm/lib/IR/Pass.cpp
index 9f66019afa4e9..1edbe11823b78 100644
--- a/llvm/lib/IR/Pass.cpp
+++ b/llvm/lib/IR/Pass.cpp
@@ -63,7 +63,7 @@ static std::string getDescription(const Module &M) {
bool ModulePass::skipModule(const Module &M) const {
const OptPassGate &Gate = M.getContext().getOptPassGate();
- StringRef PassName = this->getPassArgument();
+ StringRef PassName = getPassArgument();
if (PassName.empty())
PassName = this->getPassName();
@@ -95,7 +95,7 @@ StringRef Pass::getPassName() const {
/// corresponding to that used to enable the pass in opt
StringRef Pass::getPassArgument() const {
AnalysisID AID = getPassID();
- const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(AID);
+ const PassInfo *PI = Pass::lookupPassInfo(AID);
if (PI)
return PI->getPassArgument();
return "";
>From 2cb80eaa4fe8ee2380ab2fac353100f4e9d02f57 Mon Sep 17 00:00:00 2001
From: Cristian Assaiante <cristianassaiante at outlook.com>
Date: Thu, 10 Jul 2025 19:01:17 +0200
Subject: [PATCH 13/13] Removing virtual, cleaning format
---
llvm/include/llvm/Pass.h | 2 +-
llvm/lib/IR/Pass.cpp | 3 +--
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/llvm/include/llvm/Pass.h b/llvm/include/llvm/Pass.h
index f7345f0da5c56..e2375c55d4f67 100644
--- a/llvm/include/llvm/Pass.h
+++ b/llvm/include/llvm/Pass.h
@@ -116,7 +116,7 @@ class LLVM_ABI Pass {
/// Return a nice clean name for a pass
/// corresponding to that used to enable the pass in opt
- virtual StringRef getPassArgument() const;
+ StringRef getPassArgument() const;
/// getPassID - Return the PassID number that corresponds to this pass.
AnalysisID getPassID() const {
diff --git a/llvm/lib/IR/Pass.cpp b/llvm/lib/IR/Pass.cpp
index 1edbe11823b78..d6e4b5b398712 100644
--- a/llvm/lib/IR/Pass.cpp
+++ b/llvm/lib/IR/Pass.cpp
@@ -67,8 +67,7 @@ bool ModulePass::skipModule(const Module &M) const {
if (PassName.empty())
PassName = this->getPassName();
- return Gate.isEnabled() &&
- !Gate.shouldRunPass(PassName, getDescription(M));
+ return Gate.isEnabled() && !Gate.shouldRunPass(PassName, getDescription(M));
}
bool Pass::mustPreserveAnalysisID(char &AID) const {
More information about the llvm-commits
mailing list