Skip to content

codegen: Propagate ipo_purity_bits to LLVM function attributes - #61420

Closed
gbaraldi wants to merge 1 commit into
masterfrom
ib/fib
Closed

gbaraldi wants to merge 1 commit into
masterfrom
ib/fib

Conversation

@gbaraldi

Copy link
Copy Markdown
Member

Summary

Continues #61394. Translates Julia's inferred ipo_purity_bits into LLVM function attributes so that middle-end passes (GVN, LICM, DSE) can exploit them.

  • GVN/CSE: memory(argmem: read) on pure functions lets GVN eliminate duplicate calls (e.g. fib(37) called twice after inlining → CSE'd to one call, ~1.3x speedup on recursive fib)
  • LICM: Pure function calls with loop-invariant args are hoisted out of loops (e.g. exp(y) in for i in eachindex(x); x[i] = exp(y); end)
  • Speculation: speculatable on pure nothrow functions allows branch elimination via select
  • Dead call elimination: Unused pure calls are removed

Design

The key insight is that GC interactions don't need to be visible before GC lowering. Call-site declarations get optimistic memory attributes for pre-GC optimization, then LateLowerGCFrame widens them before safepoint analysis so post-GC passes see correct semantics.

Attributes added by add_fn_attrs_for_effects:

Attribute Condition Purpose
nounwind nothrow No LLVM unwind edges
uwtable(async) nothrow + definition Preserve .eh_frame for stack scanning
mustprogress terminates No infinite loops
willreturn nothrow + terminates Function returns to caller
memory(argmem: read) consistent + effect_free, no user ptr args Enables GVN/CSE/LICM
speculatable above + nothrow + terminates Enables speculative execution
readnone on gcstack notaskstate + above LICM past heap stores
"julia.safepoint" all call-site decls Marker for GC lowering

LateLowerGCFrame cleanup (before safepoint analysis):

  • Widens memory(readwrite) on both call instructions and declarations
  • Strips readnone from gcstack parameters

Test plan

  • make -C src analyze-{jitlayers,llvm-late-gc-lowering} for static analysis
  • Base.runtests(["core", "Compiler/codegen", "Compiler/inference", "Compiler/inline", "worlds", "boundscheck", "exceptions", "arrayops"]) — all pass
  • Test precompilation passes (previously broken by memory attr on call-site declarations)

This PR was developed with the assistance of generative AI.

Co-authored-by: Ian Butterworth ibutterworth@gmail.com

🤖 Generated with Claude Code

Translate Julia's inferred effects (consistent, effect_free, nothrow,
terminates, notaskstate) into LLVM function attributes so that
middle-end passes like GVN, LICM, and DSE can exploit them.

The key design insight is that GC interactions don't need to be visible
before GC lowering. Call-site declarations get optimistic memory
attributes (e.g. memory(argmem: read)) that enable pre-GC optimizations,
then LateLowerGCFrame widens them to memory(readwrite) before safepoint
analysis so post-GC passes see correct semantics.

Attributes added:
- nounwind: for nothrow functions (with uwtable(async) on definitions
  to preserve .eh_frame for stack scanning)
- mustprogress: for terminating functions
- willreturn: for nothrow+terminating functions
- memory(argmem: read): for consistent+effect_free functions with no
  user-facing pointer arguments (call-site declarations only)
- speculatable: for the above when also nothrow+terminating
- readnone on gcstack param: for notaskstate functions, so LICM can
  hoist pure calls past heap stores
- "julia.safepoint" marker: on all call-site declarations, used by
  LateLowerGCFrame to identify and widen optimistic attrs

LateLowerGCFrame strips all optimistic attributes (memory effects,
readnone on gcstack) from both call instructions and function
declarations before safepoint analysis runs.

Co-Authored-By: Ian Butterworth <ibutterworth@gmail.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@gbaraldi gbaraldi closed this Mar 27, 2026
@gbaraldi
gbaraldi deleted the ib/fib branch March 27, 2026 16:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant