[llvm] [clang] [clang][DepScan] Make OptimizeArgs a bit mask enum and enable by default (PR #71588)
Michael Spencer via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 7 13:04:01 PST 2023
https://github.com/Bigcheese created https://github.com/llvm/llvm-project/pull/71588
Make it easier to control which optimizations are enabled by making
OptimizeArgs a bit masked enum. There's currently only one such
optimization, but more will be added in followup commits.
>From 7d8281c6a4880006b590fd68b0c348dd0baef4eb Mon Sep 17 00:00:00 2001
From: Michael Spencer <bigcheesegs at gmail.com>
Date: Tue, 7 Nov 2023 10:00:59 -1000
Subject: [PATCH 1/2] [clang][DepScan] Make OptimizeArgs a bit mask enum.
Make it easier to control which optimizations are enabled by making
OptimizeArgs a bit masked enum. There's currently only one such
optimization, but more will be added in followup commits.
---
.../DependencyScanningService.h | 22 ++++++++++++++----
.../DependencyScanningWorker.h | 2 +-
.../DependencyScanning/ModuleDepCollector.h | 8 ++++---
.../DependencyScanningService.cpp | 4 ++--
.../DependencyScanningWorker.cpp | 9 ++++----
.../DependencyScanning/ModuleDepCollector.cpp | 5 ++--
.../header-search-pruning-transitive.c | 4 ++--
.../ClangScanDeps/header-search-pruning.cpp | 6 ++---
.../modules-symlink-dir-from-module.c | 2 +-
.../test/ClangScanDeps/modules-symlink-dir.c | 2 +-
clang/tools/clang-scan-deps/ClangScanDeps.cpp | 23 +++++++++++++++++--
clang/tools/clang-scan-deps/Opts.td | 2 +-
llvm/include/llvm/ADT/BitmaskEnum.h | 8 ++++++-
13 files changed, 69 insertions(+), 28 deletions(-)
diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h
index 109cf049a65231e..60daeec6fe2a678 100644
--- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h
+++ b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h
@@ -10,6 +10,7 @@
#define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGSERVICE_H
#include "clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h"
+#include "llvm/ADT/BitmaskEnum.h"
namespace clang {
namespace tooling {
@@ -44,19 +45,30 @@ enum class ScanningOutputFormat {
P1689,
};
+enum class ScanningOptimizations {
+ None = 0,
+
+ /// Remove unused header search paths including header maps.
+ HeaderSearch = 1,
+
+ LLVM_MARK_AS_BITMASK_ENUM(HeaderSearch),
+ All = HeaderSearch
+};
+
/// The dependency scanning service contains shared configuration and state that
/// is used by the individual dependency scanning workers.
class DependencyScanningService {
public:
- DependencyScanningService(ScanningMode Mode, ScanningOutputFormat Format,
- bool OptimizeArgs = false,
- bool EagerLoadModules = false);
+ DependencyScanningService(
+ ScanningMode Mode, ScanningOutputFormat Format,
+ ScanningOptimizations OptimizeArgs = ScanningOptimizations::None,
+ bool EagerLoadModules = false);
ScanningMode getMode() const { return Mode; }
ScanningOutputFormat getFormat() const { return Format; }
- bool canOptimizeArgs() const { return OptimizeArgs; }
+ ScanningOptimizations getOptimizeArgs() const { return OptimizeArgs; }
bool shouldEagerLoadModules() const { return EagerLoadModules; }
@@ -68,7 +80,7 @@ class DependencyScanningService {
const ScanningMode Mode;
const ScanningOutputFormat Format;
/// Whether to optimize the modules' command-line arguments.
- const bool OptimizeArgs;
+ const ScanningOptimizations OptimizeArgs;
/// Whether to set up command-lines to load PCM files eagerly.
const bool EagerLoadModules;
/// The global file system cache.
diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h
index 778d579bfb50154..0f607862194b316 100644
--- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h
+++ b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h
@@ -116,7 +116,7 @@ class DependencyScanningWorker {
llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS;
ScanningOutputFormat Format;
/// Whether to optimize the modules' command-line arguments.
- bool OptimizeArgs;
+ ScanningOptimizations OptimizeArgs;
/// Whether to set up command-lines to load PCM files eagerly.
bool EagerLoadModules;
};
diff --git a/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h b/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h
index f5dbb26452da4e6..051363b075de997 100644
--- a/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h
+++ b/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h
@@ -16,6 +16,7 @@
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/PPCallbacks.h"
#include "clang/Serialization/ASTReader.h"
+#include "clang/Tooling/DependencyScanning/DependencyScanningService.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/StringSet.h"
@@ -211,8 +212,9 @@ class ModuleDepCollector final : public DependencyCollector {
ModuleDepCollector(std::unique_ptr<DependencyOutputOptions> Opts,
CompilerInstance &ScanInstance, DependencyConsumer &C,
DependencyActionController &Controller,
- CompilerInvocation OriginalCI, bool OptimizeArgs,
- bool EagerLoadModules, bool IsStdModuleP1689Format);
+ CompilerInvocation OriginalCI,
+ ScanningOptimizations OptimizeArgs, bool EagerLoadModules,
+ bool IsStdModuleP1689Format);
void attachToPreprocessor(Preprocessor &PP) override;
void attachToASTReader(ASTReader &R) override;
@@ -254,7 +256,7 @@ class ModuleDepCollector final : public DependencyCollector {
/// for each individual module.
CowCompilerInvocation CommonInvocation;
/// Whether to optimize the modules' command-line arguments.
- bool OptimizeArgs;
+ ScanningOptimizations OptimizeArgs;
/// Whether to set up command-lines to load PCM files eagerly.
bool EagerLoadModules;
/// If we're generating dependency output in P1689 format
diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp
index 6dccb3d131cd72b..7458ef484b16c40 100644
--- a/clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp
+++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp
@@ -14,8 +14,8 @@ using namespace tooling;
using namespace dependencies;
DependencyScanningService::DependencyScanningService(
- ScanningMode Mode, ScanningOutputFormat Format, bool OptimizeArgs,
- bool EagerLoadModules)
+ ScanningMode Mode, ScanningOutputFormat Format,
+ ScanningOptimizations OptimizeArgs, bool EagerLoadModules)
: Mode(Mode), Format(Format), OptimizeArgs(OptimizeArgs),
EagerLoadModules(EagerLoadModules) {
// Initialize targets for object file support.
diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
index dc7bb289cf8f905..d1d3cc50cb25b83 100644
--- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
+++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
@@ -137,8 +137,9 @@ class DependencyScanningAction : public tooling::ToolAction {
StringRef WorkingDirectory, DependencyConsumer &Consumer,
DependencyActionController &Controller,
llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS,
- ScanningOutputFormat Format, bool OptimizeArgs, bool EagerLoadModules,
- bool DisableFree, std::optional<StringRef> ModuleName = std::nullopt)
+ ScanningOutputFormat Format, ScanningOptimizations OptimizeArgs,
+ bool EagerLoadModules, bool DisableFree,
+ std::optional<StringRef> ModuleName = std::nullopt)
: WorkingDirectory(WorkingDirectory), Consumer(Consumer),
Controller(Controller), DepFS(std::move(DepFS)), Format(Format),
OptimizeArgs(OptimizeArgs), EagerLoadModules(EagerLoadModules),
@@ -297,7 +298,7 @@ class DependencyScanningAction : public tooling::ToolAction {
DependencyActionController &Controller;
llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS;
ScanningOutputFormat Format;
- bool OptimizeArgs;
+ ScanningOptimizations OptimizeArgs;
bool EagerLoadModules;
bool DisableFree;
std::optional<StringRef> ModuleName;
@@ -312,7 +313,7 @@ class DependencyScanningAction : public tooling::ToolAction {
DependencyScanningWorker::DependencyScanningWorker(
DependencyScanningService &Service,
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS)
- : Format(Service.getFormat()), OptimizeArgs(Service.canOptimizeArgs()),
+ : Format(Service.getFormat()), OptimizeArgs(Service.getOptimizeArgs()),
EagerLoadModules(Service.shouldEagerLoadModules()) {
PCHContainerOps = std::make_shared<PCHContainerOperations>();
// We need to read object files from PCH built outside the scanner.
diff --git a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
index 2abacc426f4c975..5d95bb305bc38d8 100644
--- a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
+++ b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
@@ -529,7 +529,7 @@ ModuleDepCollectorPP::handleTopLevelModule(const Module *M) {
CowCompilerInvocation CI =
MDC.getInvocationAdjustedForModuleBuildWithoutOutputs(
MD, [&](CowCompilerInvocation &BuildInvocation) {
- if (MDC.OptimizeArgs)
+ if (any(MDC.OptimizeArgs & ScanningOptimizations::HeaderSearch))
optimizeHeaderSearchOpts(BuildInvocation.getMutHeaderSearchOpts(),
*MDC.ScanInstance.getASTReader(), *MF);
});
@@ -628,7 +628,8 @@ ModuleDepCollector::ModuleDepCollector(
std::unique_ptr<DependencyOutputOptions> Opts,
CompilerInstance &ScanInstance, DependencyConsumer &C,
DependencyActionController &Controller, CompilerInvocation OriginalCI,
- bool OptimizeArgs, bool EagerLoadModules, bool IsStdModuleP1689Format)
+ ScanningOptimizations OptimizeArgs, bool EagerLoadModules,
+ bool IsStdModuleP1689Format)
: ScanInstance(ScanInstance), Consumer(C), Controller(Controller),
Opts(std::move(Opts)),
CommonInvocation(
diff --git a/clang/test/ClangScanDeps/header-search-pruning-transitive.c b/clang/test/ClangScanDeps/header-search-pruning-transitive.c
index b56e10cac1eeb5b..eb93b1369204344 100644
--- a/clang/test/ClangScanDeps/header-search-pruning-transitive.c
+++ b/clang/test/ClangScanDeps/header-search-pruning-transitive.c
@@ -54,8 +54,8 @@ module X { header "X.h" }
// RUN: sed -e "s|DIR|%/t|g" %t/cdb_with_a.json.template > %t/cdb_with_a.json
// RUN: sed -e "s|DIR|%/t|g" %t/cdb_without_a.json.template > %t/cdb_without_a.json
-// RUN: clang-scan-deps -compilation-database %t/cdb_with_a.json -format experimental-full -optimize-args > %t/results.json
-// RUN: clang-scan-deps -compilation-database %t/cdb_without_a.json -format experimental-full -optimize-args >> %t/results.json
+// RUN: clang-scan-deps -compilation-database %t/cdb_with_a.json -format experimental-full -optimize-args=header-search > %t/results.json
+// RUN: clang-scan-deps -compilation-database %t/cdb_without_a.json -format experimental-full -optimize-args=header-search >> %t/results.json
// RUN: cat %t/results.json | sed 's:\\\\\?:/:g' | FileCheck %s -DPREFIX=%/t
// CHECK: {
diff --git a/clang/test/ClangScanDeps/header-search-pruning.cpp b/clang/test/ClangScanDeps/header-search-pruning.cpp
index 0632cccbac643c8..daacd3d319fb0de 100644
--- a/clang/test/ClangScanDeps/header-search-pruning.cpp
+++ b/clang/test/ClangScanDeps/header-search-pruning.cpp
@@ -5,13 +5,13 @@
// RUN: sed -e "s|DIR|%/t|g" -e "s|DEFINES|-DINCLUDE_B|g" %S/Inputs/header-search-pruning/cdb.json > %t/cdb_b.json
// RUN: sed -e "s|DIR|%/t|g" -e "s|DEFINES|-DINCLUDE_A -DINCLUDE_B|g" %S/Inputs/header-search-pruning/cdb.json > %t/cdb_ab.json
//
-// RUN: clang-scan-deps -compilation-database %t/cdb_a.json -format experimental-full -optimize-args >> %t/result_a.json
+// RUN: clang-scan-deps -compilation-database %t/cdb_a.json -format experimental-full -optimize-args=header-search >> %t/result_a.json
// RUN: cat %t/result_a.json | sed 's:\\\\\?:/:g' | FileCheck --check-prefixes=CHECK_A %s
//
-// RUN: clang-scan-deps -compilation-database %t/cdb_b.json -format experimental-full -optimize-args >> %t/result_b.json
+// RUN: clang-scan-deps -compilation-database %t/cdb_b.json -format experimental-full -optimize-args=header-search >> %t/result_b.json
// RUN: cat %t/result_b.json | sed 's:\\\\\?:/:g' | FileCheck --check-prefixes=CHECK_B %s
//
-// RUN: clang-scan-deps -compilation-database %t/cdb_ab.json -format experimental-full -optimize-args >> %t/result_ab.json
+// RUN: clang-scan-deps -compilation-database %t/cdb_ab.json -format experimental-full -optimize-args=header-search >> %t/result_ab.json
// RUN: cat %t/result_ab.json | sed 's:\\\\\?:/:g' | FileCheck --check-prefixes=CHECK_AB %s
#include "mod.h"
diff --git a/clang/test/ClangScanDeps/modules-symlink-dir-from-module.c b/clang/test/ClangScanDeps/modules-symlink-dir-from-module.c
index d1f7479adc6f926..5f0ebc13eb2ee96 100644
--- a/clang/test/ClangScanDeps/modules-symlink-dir-from-module.c
+++ b/clang/test/ClangScanDeps/modules-symlink-dir-from-module.c
@@ -12,7 +12,7 @@
// RUN: clang-scan-deps -compilation-database %t/cdb.json -j 1 \
// RUN: -format experimental-full -mode=preprocess-dependency-directives \
-// RUN: -optimize-args -module-files-dir %t/build > %t/deps.json
+// RUN: -optimize-args=all -module-files-dir %t/build > %t/deps.json
// RUN: cat %t/deps.json | sed 's:\\\\\?:/:g' | FileCheck %s -DPREFIX=%/t
diff --git a/clang/test/ClangScanDeps/modules-symlink-dir.c b/clang/test/ClangScanDeps/modules-symlink-dir.c
index 810b88942d2aab8..35e830e8c6c5718 100644
--- a/clang/test/ClangScanDeps/modules-symlink-dir.c
+++ b/clang/test/ClangScanDeps/modules-symlink-dir.c
@@ -14,7 +14,7 @@
// RUN: clang-scan-deps -compilation-database %t/cdb.json -j 1 \
// RUN: -format experimental-full -mode=preprocess-dependency-directives \
-// RUN: -optimize-args -module-files-dir %t/build > %t/deps.json
+// RUN: -optimize-args=all -module-files-dir %t/build > %t/deps.json
// RUN: cat %t/deps.json | sed 's:\\\\\?:/:g' | FileCheck -DPREFIX=%/t %s
diff --git a/clang/tools/clang-scan-deps/ClangScanDeps.cpp b/clang/tools/clang-scan-deps/ClangScanDeps.cpp
index 0213bb9c9616d67..7b271a02e57d775 100644
--- a/clang/tools/clang-scan-deps/ClangScanDeps.cpp
+++ b/clang/tools/clang-scan-deps/ClangScanDeps.cpp
@@ -75,8 +75,8 @@ enum ResourceDirRecipeKind {
static ScanningMode ScanMode = ScanningMode::DependencyDirectivesScan;
static ScanningOutputFormat Format = ScanningOutputFormat::Make;
+static ScanningOptimizations OptimizeArgs;
static std::string ModuleFilesDir;
-static bool OptimizeArgs;
static bool EagerLoadModules;
static unsigned NumThreads = 0;
static std::string CompilationDB;
@@ -148,10 +148,29 @@ static void ParseArgs(int argc, char **argv) {
Format = *FormatType;
}
+ std::vector<std::string> OptimizationFlags =
+ Args.getAllArgValues(OPT_optimize_args_EQ);
+ OptimizeArgs = ScanningOptimizations::None;
+ for (const auto &Arg : OptimizationFlags) {
+ auto Optimization =
+ llvm::StringSwitch<std::optional<ScanningOptimizations>>(Arg)
+ .Case("none", ScanningOptimizations::None)
+ .Case("header-search", ScanningOptimizations::HeaderSearch)
+ .Case("all", ScanningOptimizations::All)
+ .Default(std::nullopt);
+ if (!Optimization) {
+ llvm::errs()
+ << ToolName
+ << ": for the --optimize-args option: Cannot find option named '"
+ << Arg << "'\n";
+ std::exit(1);
+ }
+ OptimizeArgs |= *Optimization;
+ }
+
if (const llvm::opt::Arg *A = Args.getLastArg(OPT_module_files_dir_EQ))
ModuleFilesDir = A->getValue();
- OptimizeArgs = Args.hasArg(OPT_optimize_args);
EagerLoadModules = Args.hasArg(OPT_eager_load_pcm);
if (const llvm::opt::Arg *A = Args.getLastArg(OPT_j)) {
diff --git a/clang/tools/clang-scan-deps/Opts.td b/clang/tools/clang-scan-deps/Opts.td
index 27917b4f4808a47..5cd5d1a9fb37bc1 100644
--- a/clang/tools/clang-scan-deps/Opts.td
+++ b/clang/tools/clang-scan-deps/Opts.td
@@ -18,7 +18,7 @@ defm format : Eq<"format", "The output format for the dependencies">;
defm module_files_dir : Eq<"module-files-dir",
"The build directory for modules. Defaults to the value of '-fmodules-cache-path=' from command lines for implicit modules">;
-def optimize_args : F<"optimize-args", "Whether to optimize command-line arguments of modules">;
+def optimize_args_EQ : CommaJoined<["-", "--"], "optimize-args=">, HelpText<"Which command-line arguments of modules to optimize">;
def eager_load_pcm : F<"eager-load-pcm", "Load PCM files eagerly (instead of lazily on import)">;
def j : Arg<"j", "Number of worker threads to use (default: use all concurrent threads)">;
diff --git a/llvm/include/llvm/ADT/BitmaskEnum.h b/llvm/include/llvm/ADT/BitmaskEnum.h
index 5fe724d80c3302e..c87e7cac65a5b1d 100644
--- a/llvm/include/llvm/ADT/BitmaskEnum.h
+++ b/llvm/include/llvm/ADT/BitmaskEnum.h
@@ -87,8 +87,9 @@
using ::llvm::BitmaskEnumDetail::operator^; \
using ::llvm::BitmaskEnumDetail::operator|=; \
using ::llvm::BitmaskEnumDetail::operator&=; \
+ using ::llvm::BitmaskEnumDetail::operator^=; \
/* Force a semicolon at the end of this macro. */ \
- using ::llvm::BitmaskEnumDetail::operator^=
+ using ::llvm::BitmaskEnumDetail::any
namespace llvm {
@@ -136,6 +137,11 @@ constexpr unsigned bitWidth(uint64_t Value) {
return Value ? 1 + bitWidth(Value >> 1) : 0;
}
+template <typename E, typename = std::enable_if_t<is_bitmask_enum<E>::value>>
+constexpr bool any(E Val) {
+ return Val != static_cast<E>(0);
+}
+
template <typename E, typename = std::enable_if_t<is_bitmask_enum<E>::value>>
constexpr E operator~(E Val) {
return static_cast<E>(~Underlying(Val) & Mask<E>());
>From cd22abf6c42bcaedfa9884eead368154ddbca8ed Mon Sep 17 00:00:00 2001
From: Michael Spencer <bigcheesegs at gmail.com>
Date: Tue, 7 Nov 2023 10:18:21 -1000
Subject: [PATCH 2/2] [clang][DepScan] Enable header search optimizations by
default
---
.../Tooling/DependencyScanning/DependencyScanningService.h | 5 +++--
clang/tools/clang-scan-deps/ClangScanDeps.cpp | 2 ++
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h
index 60daeec6fe2a678..a4a03b88b205175 100644
--- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h
+++ b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h
@@ -52,7 +52,8 @@ enum class ScanningOptimizations {
HeaderSearch = 1,
LLVM_MARK_AS_BITMASK_ENUM(HeaderSearch),
- All = HeaderSearch
+ All = HeaderSearch,
+ Default = All
};
/// The dependency scanning service contains shared configuration and state that
@@ -61,7 +62,7 @@ class DependencyScanningService {
public:
DependencyScanningService(
ScanningMode Mode, ScanningOutputFormat Format,
- ScanningOptimizations OptimizeArgs = ScanningOptimizations::None,
+ ScanningOptimizations OptimizeArgs = ScanningOptimizations::Default,
bool EagerLoadModules = false);
ScanningMode getMode() const { return Mode; }
diff --git a/clang/tools/clang-scan-deps/ClangScanDeps.cpp b/clang/tools/clang-scan-deps/ClangScanDeps.cpp
index 7b271a02e57d775..50631fdf0bc3b75 100644
--- a/clang/tools/clang-scan-deps/ClangScanDeps.cpp
+++ b/clang/tools/clang-scan-deps/ClangScanDeps.cpp
@@ -167,6 +167,8 @@ static void ParseArgs(int argc, char **argv) {
}
OptimizeArgs |= *Optimization;
}
+ if (OptimizationFlags.empty())
+ OptimizeArgs = ScanningOptimizations::Default;
if (const llvm::opt::Arg *A = Args.getLastArg(OPT_module_files_dir_EQ))
ModuleFilesDir = A->getValue();
More information about the llvm-commits
mailing list