Skip to content

Materialize isbits boxed constants as device globals#874

Merged
maleadt merged 6 commits into
mainfrom
tb/materialize-boxed-constants
Jul 14, 2026
Merged

Materialize isbits boxed constants as device globals#874
maleadt merged 6 commits into
mainfrom
tb/materialize-boxed-constants

Conversation

@maleadt

@maleadt maleadt commented Jul 10, 2026

Copy link
Copy Markdown
Member

Since JuliaLang/julia#55045 (1.14.0-DEV.1348), small isbits unions built from
constants are kept fully boxed: codegen emits a julia.constgv slot holding a
pointer to the host box, which device code then dereferences for the payload
or type tag. relocate_gvs! used to bake that host address into the IR, so any
such kernel reads host memory → ERROR_ILLEGAL_ADDRESS.

Fixing this upstream was rejected (JuliaLang/julia#62191): inline storage is a
host-side de-optimization, and flag-guarding every eager-box site doesn't
scale. Instead, this implements @topolarity's suggestion on the GPUCompiler
side, where the GC-related objections don't apply.

relocate_gvs! now inspects the object behind each constgv slot. Non-ghost,
non-Bool isbits objects are materialized: a private constant replica of
the box (header word + payload bytes, heap-compatible layout and alignment) is
emitted into the module and the slot points at its payload. Everything else —
types, symbols, singletons, Bools, mutable objects — keeps the baked address;
those are only ever used as identity tokens.

Notes:

  • The replica's header holds the same value codegen compares against in
    typeof/isa (smalltag immediate or type pointer), and === on isbits
    falls back to bits comparison, so no identity-sensitive behavior changes.
  • Resolution runs before optimize!, so payload and tag loads constant-fold;
    the device code ends up identical to what inline union storage produced
    before #55045. No de-optimization, host codegen untouched.
  • Every eager-boxing site funnels through literal_pointer_val_slot, so
    future upstream boxing patterns are covered automatically.
  • Session-dependence marking is now precise: relocate_gvs! reports whether
    any host address survived (baked slot, or a materialized header carrying a
    non-smalltag type pointer). Kernels whose constants are all smalltag
    (Int/UInt/Char etc.) no longer get wiped from package images.

Applies to 1.13+ (older versions bake addresses in Julia itself); the union
regression only exists on 1.14.0-DEV.1348+.

@codecov

codecov Bot commented Jul 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.93939% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.57%. Comparing base (21b585d) to head (74386f6).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
src/jlgen.jl 93.44% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #874      +/-   ##
==========================================
+ Coverage   81.35%   81.57%   +0.22%     
==========================================
  Files          25       25              
  Lines        4789     4847      +58     
==========================================
+ Hits         3896     3954      +58     
  Misses        893      893              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@topolarity topolarity left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! This ended up even simpler than I hoped 👍

This seems like the better path to me. Something like JuliaLang/julia#62191 is possible, but it requires a more significant refactor to give any assurances that it's complete. This is complete by design, assuming it works, so that's quite nice.

Only concern is Bool, which might be worthy of more test coverage. Some notes inline.

Comment thread src/jlgen.jl
Comment thread src/jlgen.jl
maleadt and others added 6 commits July 14, 2026 11:09
Since JuliaLang/julia#55045 (1.14.0-DEV.1348), small isbits unions built from
constants stay fully boxed, so `julia.constgv` slots may now be dereferenced
on device. Instead of baking the host address, emit a constant replica of the
box (header word + payload bytes) and point the slot at its payload; LLVM
folds the loads. Ghosts, Bools and non-isbits objects keep their identity via
baked addresses. `relocate_gvs!` now reports whether the module remained
session-portable.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Materialized constgv slots (with smalltag headers) contain no session data,
so smalltag-only kernels can stay in package images.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@maleadt
maleadt force-pushed the tb/materialize-boxed-constants branch from 738528a to 74386f6 Compare July 14, 2026 09:24
@maleadt
maleadt merged commit 2eaea7f into main Jul 14, 2026
34 of 37 checks passed
@maleadt
maleadt deleted the tb/materialize-boxed-constants branch July 14, 2026 10:05
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.

3 participants