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 (Disabled or UseIfAvailable)

  • declarationSummaryProviders: external providers for declared (no-body) function summaries

  • externalSummaryProviders: 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