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 1/3] 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 2/3] 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 3/3] 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); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits