[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 00:36:50 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/10] 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/10] 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/10] 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/10] 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/10] 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/10] 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/10] 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/10] 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/10] 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 c2562c7c0cc6d5425df1fd740354651c6849957c 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/10] Short names with both NPM and Legacy, updated test,
solved nits
---
llvm/include/llvm/Pass.h | 24 +--
llvm/lib/IR/OptBisect.cpp | 4 +-
llvm/lib/IR/Pass.cpp | 46 +++--
llvm/lib/Passes/StandardInstrumentations.cpp | 182 ++++++++++---------
llvm/test/Other/opt-disable.ll | 34 ++--
5 files changed, 152 insertions(+), 138 deletions(-)
diff --git a/llvm/include/llvm/Pass.h b/llvm/include/llvm/Pass.h
index 2ecd47dd10bde..fc5d7410809a7 100644
--- a/llvm/include/llvm/Pass.h
+++ b/llvm/include/llvm/Pass.h
@@ -97,7 +97,7 @@ const char *to_string(ThinOrFullLTOPhase Phase);
/// constrained passes described below.
///
class LLVM_ABI Pass {
- AnalysisResolver *Resolver = nullptr; // Used to resolve analysis
+ AnalysisResolver *Resolver = nullptr; // Used to resolve analysis
const void *PassID;
PassKind Kind;
@@ -114,14 +114,16 @@ 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;
- }
+ AnalysisID getPassID() const { return PassID; }
/// doInitialization - Virtual method overridden by subclasses to do
/// any necessary initialization before any pass is run.
- virtual bool doInitialization(Module &) { return false; }
+ virtual bool doInitialization(Module &) { return false; }
/// doFinalization - Virtual method overriden by subclasses to do any
/// necessary clean up after all passes have run.
@@ -144,8 +146,7 @@ class LLVM_ABI Pass {
/// Each pass is responsible for assigning a pass manager to itself.
/// PMS is the stack of available pass manager.
- virtual void assignPassManager(PMStack &,
- PassManagerType) {}
+ virtual void assignPassManager(PMStack &, PassManagerType) {}
/// Check if available pass managers are suitable for this pass or not.
virtual void preparePassManager(PMStack &);
@@ -204,8 +205,9 @@ class LLVM_ABI Pass {
/// the case when the analysis is not available. This method is often used by
/// transformation APIs to update analysis results for a pass automatically as
/// the transform is performed.
- template<typename AnalysisType> AnalysisType *
- getAnalysisIfAvailable() const; // Defined in PassAnalysisSupport.h
+ template <typename AnalysisType>
+ AnalysisType *
+ getAnalysisIfAvailable() const; // Defined in PassAnalysisSupport.h
/// mustPreserveAnalysisID - This method serves the same function as
/// getAnalysisIfAvailable, but works if you just have an AnalysisID. This
@@ -217,7 +219,7 @@ class LLVM_ABI Pass {
/// getAnalysis<AnalysisType>() - This function is used by subclasses to get
/// to the analysis information that they claim to use by overriding the
/// getAnalysisUsage function.
- template<typename AnalysisType>
+ template <typename AnalysisType>
AnalysisType &getAnalysis() const; // Defined in PassAnalysisSupport.h
template <typename AnalysisType>
@@ -225,7 +227,7 @@ class LLVM_ABI Pass {
getAnalysis(Function &F,
bool *Changed = nullptr); // Defined in PassAnalysisSupport.h
- template<typename AnalysisType>
+ template <typename AnalysisType>
AnalysisType &getAnalysisID(AnalysisID PI) const;
template <typename AnalysisType>
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..9419c8d0af9c5 100644
--- a/llvm/lib/IR/Pass.cpp
+++ b/llvm/lib/IR/Pass.cpp
@@ -40,9 +40,7 @@ using namespace llvm;
//
// Force out-of-line virtual method.
-Pass::~Pass() {
- delete Resolver;
-}
+Pass::~Pass() { delete Resolver; }
// Force out-of-line virtual method.
ModulePass::~ModulePass() = default;
@@ -62,8 +60,12 @@ static std::string getDescription(const Module &M) {
bool ModulePass::skipModule(const Module &M) const {
const OptPassGate &Gate = M.getContext().getOptPassGate();
- return Gate.isEnabled() &&
- !Gate.shouldRunPass(this->getPassName(), getDescription(M));
+
+ StringRef PassName = this->getPassArgument();
+ if (PassName.empty())
+ PassName = this->getPassName();
+
+ return Gate.isEnabled() && !Gate.shouldRunPass(PassName, getDescription(M));
}
bool Pass::mustPreserveAnalysisID(char &AID) const {
@@ -72,20 +74,30 @@ bool Pass::mustPreserveAnalysisID(char &AID) const {
// dumpPassStructure - Implement the -debug-pass=Structure option
void Pass::dumpPassStructure(unsigned Offset) {
- dbgs().indent(Offset*2) << getPassName() << "\n";
+ dbgs().indent(Offset * 2) << getPassName() << "\n";
}
/// getPassName - Return a nice clean name for a pass. This usually
/// implemented in terms of the name that is registered by one of the
/// Registration templates, but can be overloaded directly.
StringRef Pass::getPassName() const {
- AnalysisID AID = getPassID();
+ AnalysisID AID = getPassID();
const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(AID);
if (PI)
return PI->getPassName();
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.
}
@@ -107,13 +119,9 @@ void Pass::verifyAnalysis() const {
// By default, don't do anything.
}
-ImmutablePass *Pass::getAsImmutablePass() {
- return nullptr;
-}
+ImmutablePass *Pass::getAsImmutablePass() { return nullptr; }
-PMDataManager *Pass::getAsPMDataManager() {
- return nullptr;
-}
+PMDataManager *Pass::getAsPMDataManager() { return nullptr; }
void Pass::setResolver(AnalysisResolver *AR) {
assert(!Resolver && "Resolver is already set");
@@ -129,9 +137,7 @@ void Pass::print(raw_ostream &OS, const Module *) const {
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
// dump - call print(cerr);
-LLVM_DUMP_METHOD void Pass::dump() const {
- print(dbgs(), nullptr);
-}
+LLVM_DUMP_METHOD void Pass::dump() const { print(dbgs(), nullptr); }
#endif
#ifdef EXPENSIVE_CHECKS
@@ -173,8 +179,12 @@ static std::string getDescription(const Function &F) {
bool FunctionPass::skipFunction(const Function &F) const {
OptPassGate &Gate = F.getContext().getOptPassGate();
- if (Gate.isEnabled() &&
- !Gate.shouldRunPass(this->getPassName(), getDescription(F)))
+
+ StringRef PassName = this->getPassArgument();
+ if (PassName.empty())
+ PassName = this->getPassName();
+
+ if (Gate.isEnabled() && !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..e2de2e734881a 100644
--- a/llvm/lib/Passes/StandardInstrumentations.cpp
+++ b/llvm/lib/Passes/StandardInstrumentations.cpp
@@ -105,18 +105,19 @@ static cl::opt<std::string> PrintOnCrashPath(
cl::desc("Print the last form of the IR before crash to a file"),
cl::Hidden);
-static cl::opt<bool> PrintOnCrash(
- "print-on-crash",
- cl::desc("Print the last form of the IR before crash (use -print-on-crash-path to dump to a file)"),
- cl::Hidden);
+static cl::opt<bool>
+ PrintOnCrash("print-on-crash",
+ cl::desc("Print the last form of the IR before crash (use "
+ "-print-on-crash-path to dump to a file)"),
+ cl::Hidden);
static cl::opt<std::string> OptBisectPrintIRPath(
"opt-bisect-print-ir-path",
cl::desc("Print IR to path when opt-bisect-limit is reached"), cl::Hidden);
-static cl::opt<bool> PrintPassNumbers(
- "print-pass-numbers", cl::init(false), cl::Hidden,
- cl::desc("Print pass names and their ordinals"));
+static cl::opt<bool>
+ PrintPassNumbers("print-pass-numbers", cl::init(false), cl::Hidden,
+ cl::desc("Print pass names and their ordinals"));
static cl::opt<unsigned> PrintBeforePassNumber(
"print-before-pass-number", cl::init(0), cl::Hidden,
@@ -863,8 +864,8 @@ void PrintIRInstrumentation::printBeforePass(StringRef PassID, Any IR) {
++CurrentPassNumber;
if (shouldPrintPassNumbers())
- dbgs() << " Running pass " << CurrentPassNumber << " " << PassID
- << " on " << getIRName(IR) << "\n";
+ dbgs() << " Running pass " << CurrentPassNumber << " " << PassID << " on "
+ << getIRName(IR) << "\n";
if (shouldPrintAfterCurrentPassNumber())
pushPassRunDescriptor(PassID, IR, CurrentPassNumber);
@@ -1078,9 +1079,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() {
@@ -1109,29 +1114,29 @@ void PrintPassInstrumentation::registerCallbacks(
print() << "Skipping pass: " << PassID << " on " << getIRName(IR) << "\n";
});
- PIC.registerBeforeNonSkippedPassCallback([this, SpecialPasses](
- StringRef PassID, Any IR) {
- if (isSpecialPass(PassID, SpecialPasses))
- return;
+ PIC.registerBeforeNonSkippedPassCallback(
+ [this, SpecialPasses](StringRef PassID, Any IR) {
+ if (isSpecialPass(PassID, SpecialPasses))
+ return;
- auto &OS = print();
- OS << "Running pass: " << PassID << " on " << getIRName(IR);
- if (const auto *F = unwrapIR<Function>(IR)) {
- unsigned Count = F->getInstructionCount();
- OS << " (" << Count << " instruction";
- if (Count != 1)
- OS << 's';
- OS << ')';
- } else if (const auto *C = unwrapIR<LazyCallGraph::SCC>(IR)) {
- int Count = C->size();
- OS << " (" << Count << " node";
- if (Count != 1)
- OS << 's';
- OS << ')';
- }
- OS << "\n";
- Indent += 2;
- });
+ auto &OS = print();
+ OS << "Running pass: " << PassID << " on " << getIRName(IR);
+ if (const auto *F = unwrapIR<Function>(IR)) {
+ unsigned Count = F->getInstructionCount();
+ OS << " (" << Count << " instruction";
+ if (Count != 1)
+ OS << 's';
+ OS << ')';
+ } else if (const auto *C = unwrapIR<LazyCallGraph::SCC>(IR)) {
+ int Count = C->size();
+ OS << " (" << Count << " node";
+ if (Count != 1)
+ OS << 's';
+ OS << ')';
+ }
+ OS << "\n";
+ Indent += 2;
+ });
PIC.registerAfterPassCallback(
[this, SpecialPasses](StringRef PassID, Any IR,
const PreservedAnalyses &) {
@@ -1450,75 +1455,72 @@ void PreservedCFGCheckerInstrumentation::registerCallbacks(
void VerifyInstrumentation::registerCallbacks(PassInstrumentationCallbacks &PIC,
ModuleAnalysisManager *MAM) {
- PIC.registerAfterPassCallback(
- [this, MAM](StringRef P, Any IR, const PreservedAnalyses &PassPA) {
- if (isIgnored(P) || P == "VerifierPass")
- return;
- const auto *F = unwrapIR<Function>(IR);
- if (!F) {
- if (const auto *L = unwrapIR<Loop>(IR))
- F = L->getHeader()->getParent();
- }
+ PIC.registerAfterPassCallback([this, MAM](StringRef P, Any IR,
+ const PreservedAnalyses &PassPA) {
+ if (isIgnored(P) || P == "VerifierPass")
+ return;
+ const auto *F = unwrapIR<Function>(IR);
+ if (!F) {
+ if (const auto *L = unwrapIR<Loop>(IR))
+ F = L->getHeader()->getParent();
+ }
+
+ if (F) {
+ if (DebugLogging)
+ dbgs() << "Verifying function " << F->getName() << "\n";
+
+ if (verifyFunction(*F, &errs()))
+ report_fatal_error(formatv("Broken function found after pass "
+ "\"{0}\", compilation aborted!",
+ P));
+ } else {
+ const auto *M = unwrapIR<Module>(IR);
+ if (!M) {
+ if (const auto *C = unwrapIR<LazyCallGraph::SCC>(IR))
+ M = C->begin()->getFunction().getParent();
+ }
+
+ if (M) {
+ if (DebugLogging)
+ dbgs() << "Verifying module " << M->getName() << "\n";
- if (F) {
- if (DebugLogging)
- dbgs() << "Verifying function " << F->getName() << "\n";
+ if (verifyModule(*M, &errs()))
+ report_fatal_error(formatv("Broken module found after pass "
+ "\"{0}\", compilation aborted!",
+ P));
+ }
- if (verifyFunction(*F, &errs()))
- report_fatal_error(formatv("Broken function found after pass "
- "\"{0}\", compilation aborted!",
- P));
+ if (auto *MF = unwrapIR<MachineFunction>(IR)) {
+ if (DebugLogging)
+ dbgs() << "Verifying machine function " << MF->getName() << '\n';
+ std::string Banner = formatv("Broken machine function found after pass "
+ "\"{0}\", compilation aborted!",
+ P);
+ if (MAM) {
+ Module &M = const_cast<Module &>(*MF->getFunction().getParent());
+ auto &MFAM =
+ MAM->getResult<MachineFunctionAnalysisManagerModuleProxy>(M)
+ .getManager();
+ MachineVerifierPass Verifier(Banner);
+ Verifier.run(const_cast<MachineFunction &>(*MF), MFAM);
} else {
- const auto *M = unwrapIR<Module>(IR);
- if (!M) {
- if (const auto *C = unwrapIR<LazyCallGraph::SCC>(IR))
- M = C->begin()->getFunction().getParent();
- }
-
- if (M) {
- if (DebugLogging)
- dbgs() << "Verifying module " << M->getName() << "\n";
-
- if (verifyModule(*M, &errs()))
- report_fatal_error(formatv("Broken module found after pass "
- "\"{0}\", compilation aborted!",
- P));
- }
-
- if (auto *MF = unwrapIR<MachineFunction>(IR)) {
- if (DebugLogging)
- dbgs() << "Verifying machine function " << MF->getName() << '\n';
- std::string Banner =
- formatv("Broken machine function found after pass "
- "\"{0}\", compilation aborted!",
- P);
- if (MAM) {
- Module &M = const_cast<Module &>(*MF->getFunction().getParent());
- auto &MFAM =
- MAM->getResult<MachineFunctionAnalysisManagerModuleProxy>(M)
- .getManager();
- MachineVerifierPass Verifier(Banner);
- Verifier.run(const_cast<MachineFunction &>(*MF), MFAM);
- } else {
- verifyMachineFunction(Banner, *MF);
- }
- }
+ verifyMachineFunction(Banner, *MF);
}
- });
+ }
+ }
+ });
}
InLineChangePrinter::~InLineChangePrinter() = default;
-void InLineChangePrinter::generateIRRepresentation(Any IR,
- StringRef PassID,
+void InLineChangePrinter::generateIRRepresentation(Any IR, StringRef PassID,
IRDataT<EmptyData> &D) {
IRComparer<EmptyData>::analyzeIR(IR, D);
}
void InLineChangePrinter::handleAfter(StringRef PassID, std::string &Name,
const IRDataT<EmptyData> &Before,
- const IRDataT<EmptyData> &After,
- Any IR) {
+ const IRDataT<EmptyData> &After, Any IR) {
SmallString<20> Banner =
formatv("*** IR Dump After {0} on {1} ***\n", PassID, Name);
Out << Banner;
@@ -2420,7 +2422,7 @@ DotCfgChangeReporter::~DotCfgChangeReporter() {
void DotCfgChangeReporter::registerCallbacks(
PassInstrumentationCallbacks &PIC) {
if (PrintChanged == ChangePrinter::DotCfgVerbose ||
- PrintChanged == ChangePrinter::DotCfgQuiet) {
+ PrintChanged == ChangePrinter::DotCfgQuiet) {
SmallString<128> OutputDir;
sys::fs::expand_tilde(DotCfgDir, OutputDir);
sys::fs::make_absolute(OutputDir);
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()
More information about the llvm-commits
mailing list