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 <cristianassaia...@outlook.com> Date: Fri, 20 Jun 2025 16:56:23 +0200 Subject: [PATCH 01/11] 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 <cristianassaia...@outlook.com> Date: Mon, 23 Jun 2025 11:08:02 +0200 Subject: [PATCH 02/11] 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 <cristianassaia...@outlook.com> Date: Mon, 23 Jun 2025 12:33:05 +0200 Subject: [PATCH 03/11] 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 <cristianassaia...@outlook.com> Date: Mon, 23 Jun 2025 19:23:15 +0200 Subject: [PATCH 04/11] 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 <cristianassaia...@outlook.com> Date: Fri, 27 Jun 2025 19:07:03 +0200 Subject: [PATCH 05/11] 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 <cristianassaia...@outlook.com> Date: Thu, 3 Jul 2025 01:41:22 +0200 Subject: [PATCH 06/11] 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 <cristianassaia...@outlook.com> Date: Thu, 3 Jul 2025 01:53:33 +0200 Subject: [PATCH 07/11] 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 <cristianassaia...@outlook.com> Date: Thu, 3 Jul 2025 10:28:05 +0200 Subject: [PATCH 08/11] 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 <assaia...@diag.uniroma1.it> Date: Thu, 10 Jul 2025 01:35:42 +0200 Subject: [PATCH 09/11] Update llvm/lib/IR/OptBisect.cpp Co-authored-by: Nikita Popov <git...@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 <cristianassaia...@outlook.com> Date: Thu, 10 Jul 2025 09:36:32 +0200 Subject: [PATCH 10/11] 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() >From 4810d329119d61719247c8d52fc9a773daa72a7d Mon Sep 17 00:00:00 2001 From: Cristian Assaiante <cristianassaia...@outlook.com> Date: Thu, 10 Jul 2025 09:45:31 +0200 Subject: [PATCH 11/11] 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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits