Skip to content

Globals through their bindings, as native code - #22

Draft
vchuravy wants to merge 1 commit into
vc/jc-20-target-layoutsfrom
vc/jc-21-globals
Draft

vchuravy wants to merge 1 commit into
vc/jc-20-target-layoutsfrom
vc/jc-21-globals

Conversation

@vchuravy

Copy link
Copy Markdown
Contributor

Stacked on #21. GPUCompiler's suite with codegen=:juliacodegen found this gap.

A global that is not a constant (PARTITION_KIND_GLOBAL in the code's world) is now read and written through its binding's value field, as Julia's code generator does in emit_globalop:

  • Reads: an unordered atomic load (jtbaa_binding), with a null check that throws UndefVarError through ijl_undefined_var_error(sym, mod). The result has the binding's declared type.
  • Assignments of Any-typed globals: a release store plus the binding's write barrier (object form on 1.12, field form from 1.13 on).
  • Builtins: getglobal and setglobal! with constant module and name (and default order) take the same paths.

Other bindings (imported, unresolved) and assignments of typed globals, which convert the value, still go through the runtime.

GPUCompiler's validation recognizes these accesses and reports "use of a non-constant global" (with the binding's name), as it does for native code. Through getglobal calls it reported dynamic invocations instead.

Tests (test/exceptions.jl):

  • typed globals read and assigned;
  • a declared global without a value (UndefVarError);
  • FileCheck of the binding store, load and error path, with no dynamic call;
  • typed assignments still going through the runtime.

Tested locally with julia +1.12, +1.13 and +nightly: 5943, 5949 and 5948 tests pass.

🤖 Generated with Claude Code

A global that is not a constant (`PARTITION_KIND_GLOBAL` in the world of the
code) is read and written through its binding's `value` field, as Julia's
code generator does (`emit_globalop`):

- reads are an unordered load (`jtbaa_binding`) with a null check that
  throws `UndefVarError` through `ijl_undefined_var_error`;
- assignments of globals of type `Any` are a release store and the
  binding's write barrier.

This also covers `getglobal` and `setglobal!` (default order) with constant
arguments. Other bindings (imported, unresolved) and assignments of typed
globals, which convert the value, still go through the runtime.

GPUCompiler's validation recognizes these accesses ("use of a non-constant
global"); calls of `getglobal` it reports as dynamic invocations.

Assisted-by: Claude Code (Opus 5.5)
@vchuravy
vchuravy force-pushed the vc/jc-20-target-layouts branch from bd35ca5 to 81d56e6 Compare October 19, 2026 17:35
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