New Pass Manager: PreservedAnalyses and Analysis Cache Invalidation
0 reputation · 07 Nov 2023, 11:25 UTC
0 reputation · 07 Nov 2023, 11:25 UTC
The LLVM New Pass Manager (NPM) utilizes a caching mechanism for analysis results to optimize the pipeline. To maintain correctness, passes must explicitly specify which analyses remain valid after an IR transformation by returning a PreservedAnalyses object.
When a pass modifies the IR but fails to correctly invalidate a dependent analysis, the pipeline may reuse stale cached data. This behavior can lead to inconsistent optimization results or miscompiles that are difficult to trace, as they often depend on the specific sequence of passes executed in the pipeline.
Given the transition to the NPM in recent LLVM releases (v17+), there is uncertainty regarding the most reliable way to verify that a custom pass is not inadvertently preserving an analysis that should be invalidated.
-O2 or -O3 pipeline?31275 reputation · 07 Nov 2023, 12:03 UTC
To determine whether a specific analysis is being recomputed after a custom pass (instead of being served from the NPM cache), you can add observable side‑effects to the analysis’ run method and then inspect the pass‑manager diagnostics.
LLVM_DEBUG macro guarded by a DEBUG_TYPE string; when the binary is built with assertions and debug support, each invocation of the analysis’ run method prints a message.-debug-pass-manager (or -mllvm -debug-pass-manager when using clang) causes the New Pass Manager to emit a line for every analysis invalidation or preservation decision, including the analysis name.-debug-pass-manager with -debug-only=passmanager limits the output to pass‑manager events, making it easy to grep for the analysis of interest.run method; after a pipeline run the counter value tells you how many times the analysis was actually executed.-DLLVM_ENABLE_ASSERTIONS=ON) and debug support; otherwise the debug prints will be omitted.#include "llvm/Support/Debug.h"
#define DEBUG_TYPE "my-analysis"
AnalysisResult MyAnalysis::run(Module &M, ModuleAnalysisManager &AM) {
LLVM_DEBUG(dbgs() << "[MyAnalysis] running on " << M.getName() << "\n");
// … existing analysis logic …
return Result;
}
clang -O2 -mllvm -debug-pass-manager -mllvm -debug-only=passmanager input.c -o output
static unsigned MyAnalysisInvocations = 0;
LLVM_DEBUG(dbgs() << "[MyAnalysis] invocation #" << ++MyAnalysisInvocations << "\n");
After the run, print or expose MyAnalysisInvocations and compare it to the expected number of invalidations (e.g., one per modifying pass).If you are not using an assertions‑enabled LLVM build, let me know so I can suggest an alternative verification method (e.g., using a custom pass plugin that registers a callback).
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.