Skip to content

Self-host M3: defer emit-bridge IR until after spine pre-lower in compileM3EmitTuMainNative #2512

Description

@PurHur

Problem

compileM3EmitTuMainNative in lib/JIT.php builds the emit bridge LLVM IR before bundled Runtime::parse / Runtime::compile are guaranteed to be real-lowered. When LLVM binds the stub (null-returning) version first, the resulting native binary produces parse returned null at runtime and the probe falls back to emit_path=zend partial.

This is the root cause identified in #2506 and the current blocker for #2442 (emit-TU execute without startup crash).

Repro

./script/docker-exec.sh -- bash -lc '
  source script/php-env.sh
  BOOTSTRAP_M3_LINK_COMPILE_DRIVER=1 \
  BOOTSTRAP_M3_COMPILE_DRIVER_REAL_LOWERING=1 \
  BOOTSTRAP_M3_RUNTIME_COMPILE=1 \
  ./script/bootstrap-selfhost-helloworld-probe.sh
'
# Expected: emit_path=native
# Actual:   emit_path=zend partial  (parse returned null)

Root cause

In lib/JIT.php, compileM3EmitTuMainNative() emits the bridge call to Runtime::parse before runQueue() / spine pre-lower has committed real lowering for the bundled Runtime methods. LLVM 9 resolves the call to the stub entry from an earlier compile pass.

Fix

Defer the emit-bridge IR construction until after runQueue() completes the spine pre-lower, or restructure compileM3EmitTuMainNative to emit the bridge as a post-queue step (similar to how compileRuntimeLoadJitM3Native gates its helpers).

Relevant code paths:

File Symbol Notes
lib/JIT.php compileM3EmitTuMainNative() Bridge IR built too early
lib/JIT.php runQueue() / spine pre-lower Must complete before bridge references Runtime symbols
test/bootstrap-aot/runtime_m3_emit_native_entry.php smallest emit TU Use for bisect
test/bootstrap-aot/compile_smoke_m3_emit_native_entry.php mid emit TU Second bisect step
test/bootstrap-aot/helloworld_m3_emit_native_entry.php full emit TU Final gate

Done when

  • ./script/bootstrap-selfhost-helloworld-probe.sh (with BOOTSTRAP_M3_LINK_COMPILE_DRIVER=1 BOOTSTRAP_M3_COMPILE_DRIVER_REAL_LOWERING=1) reports emit_path=native (not zend partial)
  • build/selfhost-helloworld-emit exits 0 with helloworld_compile_smoke: compile OK
  • docs/bootstrap-m5-fast-path.md Step 2 updated to remove "bridge ordering" note

Gate sequence

# Smallest TU first:
BOOTSTRAP_M3_RUNTIME_COMPILE=1 make bootstrap-selfhost-runtime-compile-smoke
# Then full helloworld:
BOOTSTRAP_M3_LINK_COMPILE_DRIVER=1 BOOTSTRAP_M3_COMPILE_DRIVER_REAL_LOWERING=1 \
  BOOTSTRAP_M3_RUNTIME_COMPILE=1 \
  ./script/bootstrap-selfhost-helloworld-probe.sh

Dependencies

Epic #1492 · ROADMAP #78 Phase 0

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions