[llvm] Issue #32 solution (PR #144834)

Ishan Gupta via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 18 21:26:41 PDT 2025


https://github.com/ishangtxl created https://github.com/llvm/llvm-project/pull/144834

This commit introduces a new debugging flag, -debug-pass-list, to provide a simple, user-friendly way to view the sequence of passes being run by the New Pass Manager for a given optimization level.

This feature is implemented for the New Pass Manager by:

- Adding a new boolean cl::opt named DebugPassList.
- Hooking into StandardInstrumentations::registerCallbacks to register a BeforeNonSkippedPassCallback.
- When -debug-pass-list is active, the callback gets the name of each pass and prints it.
- Filtering logic has been included to exclude "Adaptor" and "Wrapper" passes to keep the list focused on the core transformations.


# First, create a test file
# echo 'int main() { return 0; }' > test.c

# Run with the new flag at different optimization levels
./bin/clang --sysroot $(xcrun --show-sdk-path) -O2 -mllvm -debug-pass-list test.c -S -o /dev/null
./bin/clang --sysroot $(xcrun --show-sdk-path) -O3 -mllvm -debug-pass-list test.c -S -o /dev/null

>From e1f7b3a12322f9880f0f3d859bd9d8911dfdc52f Mon Sep 17 00:00:00 2001
From: Ishan Gupta <ishangupta024 at gmail.com>
Date: Mon, 26 May 2025 16:22:04 +0530
Subject: [PATCH 1/3] Implement -debug-pass-list for New Pass Manager

---
 llvm/lib/Passes/StandardInstrumentations.cpp | 57 ++++++++++++++++++--
 1 file changed, 52 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp
index dc1dd5d9c7f4c..8350598b87718 100644
--- a/llvm/lib/Passes/StandardInstrumentations.cpp
+++ b/llvm/lib/Passes/StandardInstrumentations.cpp
@@ -61,6 +61,13 @@ static cl::opt<bool> VerifyAnalysisInvalidation("verify-analysis-invalidation",
 #endif
 );
 
+static cl::opt<bool> DebugPassList(
+    "debug-pass-list", // This will be the command-line flag, e.g., -debug-pass-list
+    cl::Hidden,        // Keep it hidden like other developer debug flags
+    cl::desc("Print all pass names in a simple list (New PM)"));
+
+
+
 // An option that supports the -print-changed option.  See
 // the description for -print-changed for an explanation of the use
 // of this option.  Note that this option has no effect without -print-changed.
@@ -2520,6 +2527,50 @@ void StandardInstrumentations::registerCallbacks(
   OptPassGate.registerCallbacks(PIC);
   PrintChangedIR.registerCallbacks(PIC);
   PseudoProbeVerification.registerCallbacks(PIC);
+
+  // Your new logic for DebugPassList
+  if (DebugPassList) { // Ensure DebugPassList is accessible here
+    PIC.registerBeforeNonSkippedPassCallback( // Changed from registerBeforeNonContainerPassCallback
+        [](llvm::StringRef PassID, llvm::Any IR) {
+          // Heuristic filter to identify transformation passes.
+          // This attempts to exclude common analysis, utility, verifier, and manager passes.
+          // You may need to adjust this list based on your specific needs and LLVM version.
+          bool isLikelyTransformation = true;
+
+          // Filter out Pass Managers first, as registerBeforeNonSkippedPassCallback might call for them
+          if (PassID.contains("Manager") ||
+              PassID.ends_with("ManagerPass") || // Changed from endswith
+              PassID == "PassManager") { // Changed from equals
+            isLikelyTransformation = false;
+          } else if ( // Else if, to avoid re-evaluating if already identified as a manager
+              PassID.contains("Analysis") ||
+              PassID.contains("Info") || // Catches LoopInfo, TargetLibraryInfo, etc.
+              PassID.contains("Printer") ||
+              PassID.contains("Verifier") ||
+              PassID.contains("Checker") ||
+              PassID.contains("DomTree") || // DominatorTreeWrapperPass
+              PassID.contains("ScalarEvolution") ||
+              PassID.contains("AssumptionCache") || // AssumptionCacheTracker
+              PassID.contains("ProfileSummary") ||
+              PassID.contains("MemorySSA") ||
+              PassID.contains("MemorySanitizer") ||
+              PassID.contains("AddressSanitizer") ||
+              PassID.contains("ThreadSanitizer") ||
+              PassID.contains("HWAddressSanitizer") ||
+              PassID.contains("AA") || // Alias Analysis related passes
+              PassID == "ForceFunctionAttrsPass" || // Changed from equals
+              PassID == "InferFunctionAttrsPass"    // Changed from equals
+              // Add other specific non-transformation pass names or patterns here
+              ) {
+            isLikelyTransformation = false;
+          }
+
+          if (isLikelyTransformation) {
+            llvm::errs() << PassID << "\n";
+          }
+        });
+  }
+
   if (VerifyEach)
     Verify.registerCallbacks(PIC, MAM);
   PrintChangedDiff.registerCallbacks(PIC);
@@ -2531,11 +2582,7 @@ void StandardInstrumentations::registerCallbacks(
     PreservedCFGChecker.registerCallbacks(PIC, *MAM);
 
   // TimeProfiling records the pass running time cost.
-  // Its 'BeforePassCallback' can be appended at the tail of all the
-  // BeforeCallbacks by calling `registerCallbacks` in the end.
-  // Its 'AfterPassCallback' is put at the front of all the
-  // AfterCallbacks by its `registerCallbacks`. This is necessary
-  // to ensure that other callbacks are not included in the timings.
+  // ... (rest of the comment and code)
   TimeProfilingPasses.registerCallbacks(PIC);
 }
 

>From 053c37fee8fd0255d59e992a713b02902e8e6cd6 Mon Sep 17 00:00:00 2001
From: Ishan Gupta <ishangupta024 at gmail.com>
Date: Mon, 26 May 2025 16:41:52 +0530
Subject: [PATCH 2/3] Add README for -debug-pass-list feature

---
 README.md | 137 +++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 105 insertions(+), 32 deletions(-)

diff --git a/README.md b/README.md
index a9b29ecbc1a3a..0218aee0d3e1e 100644
--- a/README.md
+++ b/README.md
@@ -1,44 +1,117 @@
-# The LLVM Compiler Infrastructure
+# LLVM Project
 
-[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/llvm/llvm-project/badge)](https://securityscorecards.dev/viewer/?uri=github.com/llvm/llvm-project)
-[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/8273/badge)](https://www.bestpractices.dev/projects/8273)
-[![libc++](https://github.com/llvm/llvm-project/actions/workflows/libcxx-build-and-test.yaml/badge.svg?branch=main&event=schedule)](https://github.com/llvm/llvm-project/actions/workflows/libcxx-build-and-test.yaml?query=event%3Aschedule)
+## Introduction
 
-Welcome to the LLVM project!
+The LLVM Project is a collection of modular and reusable compiler and toolchain technologies. Despite its name, LLVM has little to do with traditional virtual machines. The name "LLVM" itself is not an acronym; it is the full name of the project.
 
-This repository contains the source code for LLVM, a toolkit for the
-construction of highly optimized compilers, optimizers, and run-time
-environments.
+LLVM is an umbrella project that includes:
+- LLVM Core libraries (optimizer, code generators, etc.)
+- Clang: A C/C++/Objective-C compiler frontend
+- LLDB: A debugger
+- lld: A linker
+- And many other subprojects
 
-The LLVM project has multiple components. The core of the project is
-itself called "LLVM". This contains all of the tools, libraries, and header
-files needed to process intermediate representations and convert them into
-object files. Tools include an assembler, disassembler, bitcode analyzer, and
-bitcode optimizer.
+## Prerequisites
 
-C-like languages use the [Clang](https://clang.llvm.org/) frontend. This
-component compiles C, C++, Objective-C, and Objective-C++ code into LLVM bitcode
--- and from there into object files, using LLVM.
+To build LLVM, you'll need:
 
-Other components include:
-the [libc++ C++ standard library](https://libcxx.llvm.org),
-the [LLD linker](https://lld.llvm.org), and more.
+- A C++17 compatible compiler (GCC ≥ 7.1.0, Clang ≥ 5.0.0, Apple Clang ≥ 10.0.0, MSVC ≥ 19.14)
+- CMake ≥ 3.13.4
+- Python ≥ 3.6
+- Git (for version control)
+- Ninja build system (recommended) or GNU Make
 
-## Getting the Source Code and Building LLVM
+On macOS, you can install the required tools with:
+```bash
+brew install cmake ninja python
+```
 
-Consult the
-[Getting Started with LLVM](https://llvm.org/docs/GettingStarted.html#getting-the-source-code-and-building-llvm)
-page for information on building and running LLVM.
+## Building LLVM
 
-For information on how to contribute to the LLVM project, please take a look at
-the [Contributing to LLVM](https://llvm.org/docs/Contributing.html) guide.
+### Basic Build Instructions
 
-## Getting in touch
+1. Clone the repository (if you haven't already):
+   ```bash
+   git clone https://github.com/llvm/llvm-project.git
+   cd llvm-project
+   ```
 
-Join the [LLVM Discourse forums](https://discourse.llvm.org/), [Discord
-chat](https://discord.gg/xS7Z362),
-[LLVM Office Hours](https://llvm.org/docs/GettingInvolved.html#office-hours) or
-[Regular sync-ups](https://llvm.org/docs/GettingInvolved.html#online-sync-ups).
+2. Create a build directory:
+   ```bash
+   mkdir build
+   cd build
+   ```
 
-The LLVM project has adopted a [code of conduct](https://llvm.org/docs/CodeOfConduct.html) for
-participants to all modes of communication within the project.
+3. Configure with CMake:
+   ```bash
+   cmake -G Ninja ../llvm \
+     -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;lld" \
+     -DCMAKE_BUILD_TYPE=Release \
+     -DLLVM_ENABLE_ASSERTIONS=ON
+   ```
+   
+   Note: Adjust the `-DLLVM_ENABLE_PROJECTS` parameter to include only the subprojects you need.
+
+4. Build:
+   ```bash
+   ninja
+   ```
+
+5. (Optional) Install:
+   ```bash
+   ninja install
+   ```
+
+### Using the New Pass Manager
+
+LLVM has transitioned to a new pass manager. When using tools like `opt`, use the new syntax:
+
+```bash
+# New pass manager syntax
+./bin/opt -passes=instcombine,reassociate -debug-pass-manager -disable-output test.ll
+
+# Old syntax (deprecated)
+# ./bin/opt -instcombine -reassociate -debug-pass=List -disable-output test.ll
+```
+
+## Documentation
+
+For more detailed information, refer to the official LLVM documentation:
+
+- [LLVM Documentation](https://llvm.org/docs/)
+- [Getting Started with LLVM](https://llvm.org/docs/GettingStarted.html)
+- [Building LLVM with CMake](https://llvm.org/docs/CMake.html)
+- [LLVM Programmer's Manual](https://llvm.org/docs/ProgrammersManual.html)
+- [New Pass Manager](https://llvm.org/docs/NewPassManager.html)
+
+## License
+
+LLVM is available under the [Apache License v2.0 with LLVM Exceptions](https://llvm.org/LICENSE.txt).
+
+-----------------------------------------------------------------------------------------------------------
+
+# LLVM with -debug-pass-list Feature (New Pass Manager)
+
+This is a fork of the [official LLVM Project](https://github.com/llvm/llvm-project) focused on implementing an experimental `-debug-pass-list` command-line option for the New Pass Manager (NPM).
+
+## Feature: -debug-pass-list
+
+This feature provides a simple, flat list of pass names invoked by the New Pass Manager for a given optimization level. It's intended to be a more beginner-friendly way to see the sequence of operations compared to more verbose options.
+
+### How to Use
+(Assuming you have built this version of Clang/LLVM)
+
+With `clang`:
+```bash
+./bin/clang -O2 -mllvm -debug-pass-list your_file.c -o /dev/null
+# Or to avoid linker issues during testing:
+# ./bin/clang -O2 -mllvm -debug-pass-list -S your_file.c -o /dev/null
+
+
+
+with opt:
+# First generate LLVM IR:
+# ./bin/clang -O2 -S -emit-llvm your_file.c -o your_file.ll
+
+# Then run opt:
+./bin/opt -passes='default<O2>' -debug-pass-list -disable-output your_file.ll

>From ca9ef5d5b9599c65d5df66a86c35f7e24d99fa7c Mon Sep 17 00:00:00 2001
From: Ishan Gupta <ishangupta024 at gmail.com>
Date: Mon, 26 May 2025 16:43:28 +0530
Subject: [PATCH 3/3] added README

---
 llvm/lib/Passes/StandardInstrumentations.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp
index 8350598b87718..5ff9c9b10c456 100644
--- a/llvm/lib/Passes/StandardInstrumentations.cpp
+++ b/llvm/lib/Passes/StandardInstrumentations.cpp
@@ -2528,7 +2528,7 @@ void StandardInstrumentations::registerCallbacks(
   PrintChangedIR.registerCallbacks(PIC);
   PseudoProbeVerification.registerCallbacks(PIC);
 
-  // Your new logic for DebugPassList
+  // new logic for DebugPassList
   if (DebugPassList) { // Ensure DebugPassList is accessible here
     PIC.registerBeforeNonSkippedPassCallback( // Changed from registerBeforeNonContainerPassCallback
         [](llvm::StringRef PassID, llvm::Any IR) {



More information about the llvm-commits mailing list