Purity Analysis
Function-level purity and side-effect analysis for LLVM bitcode.
Headers: include/Analysis/Purity/
Implementation: lib/Analysis/Purity/
Build target: CanaryPurityAnalysis
Overview
The Purity Analysis subsystem determines whether functions have side effects (mutate memory, perform I/O, etc.) and classifies them into purity levels: const, pure, impure, or unknown. This information is used by optimization passes, checkers, and alias analyses to reason about call-site effects.
Purity classification follows the standard convention:
Const: The function reads no reachable memory and has no observable side effects. Its return value depends only on its arguments.
Pure: The function may read reachable memory but does not write to it and has no observable side effects.
Impure: The function writes to reachable memory or has observable side effects.
Unknown: No classification could be determined.
Components
FunctionPurityAnalysis
File: FunctionPurityAnalysis.h
The top-level analysis driver. Runs intraprocedural purity inference across a module, using optional MemorySSA-backed summaries for more precise results.
#include "Analysis/Purity/FunctionPurityAnalysis.h"
lotus::analysis::purity::FunctionPurityAnalysis purity(M);
purity.run();
if (purity.isConst(F)) { /* ... */ }
if (purity.isPure(F)) { /* ... */ }
if (purity.isKnown(F)) { /* ... */ }
PurityKind k = purity.getPurity(F);
FunctionEffectSummary fx = purity.getEffects(F);
Configuration (FunctionPurityAnalysisOptions):
MemorySSAMode: controls whether MemorySSA-based summaries are used (DisabledorUseIfAvailable)declarationSummaryProviders: external providers for declared (no-body) function summariesexternalSummaryProviders: external providers for summary files
PurityKind
enum class PurityKind {
Const = 0, // No memory reads/writes, no side effects
Pure = 1, // May read memory, no writes or side effects
Impure = 2, // May write memory or have side effects
Unknown = 3 // Classification not determined
};
FunctionEffectSummary
A structured summary of a function’s observable effects:
readsReachableMemory— The function may read globally reachable memory.writesReachableMemory— The function may write to globally reachable memory.hasObservableSideEffects— The function may perform I/O, volatile accesses, etc.hasUnknownEffects— The analysis could not fully determine the effects.source— Where the summary came from (SummarySource).confidence— Confidence level of the summary (SummaryConfidence).
Purity Inference Passes
PurityAttrInferencePass — Infers purity from LLVM function attributes (
readnone,readonly, etc.).PurityUnknownImpactPass — Identifies functions whose unknown effects may impact downstream analyses.
MemorySSAPuritySummary — Builds purity summaries from MemorySSA analysis for more precise per-call-site reasoning.
External Summary Store
File: ExternalPuritySummaryStore.h
Loads and caches external purity summaries for third-party or unavailable functions, enabling interprocedural purity analysis across library boundaries.
Usage
#include "Analysis/Purity/FunctionPurityAnalysis.h"
llvm::Module &M = ...;
lotus::analysis::purity::FunctionPurityAnalysis purity(M);
purity.run();
for (auto &F : M) {
if (purity.isConst(&F))
outs() << F.getName() << " is const\n";
else if (purity.isPure(&F))
outs() << F.getName() << " is pure\n";
else if (purity.isAtMostPure(&F))
outs() << F.getName() << " is at most pure\n";
}
See Also
Transforms — Optimisation passes that consume purity info
ShadowMem SSA — Sea-DSA Shadow Memory Queries — ShadowMem SSA used for summary generation