Skip to content

Compiler: producer-expr index + comment-interval cache for big-file compiles (#16077)#16412

Open
PurHur wants to merge 1 commit into
masterfrom
feat/producer-index
Open

Compiler: producer-expr index + comment-interval cache for big-file compiles (#16077)#16412
PurHur wants to merge 1 commit into
masterfrom
feat/producer-index

Conversation

@PurHur

@PurHur PurHur commented Jul 5, 2026

Copy link
Copy Markdown
Owner

Two lint/compile hotspots on 15–30k-line files, found by SIGALRM sampling of the lintScript pass after the frontend fixes:

  1. findCfgProducerExprForOperand re-walked every seen CFG block tree twice per lookup — measured 929 lookups on lib/Compiler.php, 88% returning null after a full scan. Now an incremental index over the seen set answers exact hits O(1) and a global "roots with any candidate" set proves the null case without scanning; only true root-matches (1 per file measured) fall back to the legacy scan. Blocks re-index when their child count changes; index misses self-heal through the fallback. Kill switch: PHP_COMPILER_PRODUCER_INDEX_LEGACY=1.
  2. PropertyHooks::isOffsetInComment rescanned the class body from byte 0 per $var probe — O(vars×body), 70% of samples on lib/VM.php. Now one scan per body builds sorted comment intervals (exact legacy boundary semantics documented in-code), binary-searched per probe. Kill switch: PHP_COMPILER_COMMENT_SCAN_LEGACY=1.

Measured (pinned container, end-to-end lint)

file before after
lib/VM.php 2m50s 40s
lib/Compiler.php 1m49s 1m11s

Verified

  • Lint output identical to legacy paths on lib/VM.php, lib/Compiler.php, lib/JIT.php, ext/standard/VmString.php
  • check-aot-build-smoke.sh rc=0 (build+run+VM-differential) — unlike the Speed up inventory lint: opt-in fast frontend patches + parallel cached bin/lint.php (#16077) #16394 vendor paths, these are safe for compiles: results are equivalence-checked, not just order-stable
  • make north-star5-verify-fast OK (spine link + gen-0 cold boot)
  • PropertyHook/ArrayLiteral unit tests green
  • bootstrap inventory regen included (method-count drift)

🤖 Generated with Claude Code

…ompiles (#16077).

Two lint/compile hotspots on 15-30k-line files, found by sampling the
lintScript pass after the frontend fixes landed:

- findCfgProducerExprForOperand re-walked every seen CFG block tree
  twice per lookup. Measured on lib/Compiler.php: 929 lookups, 88%
  returning null after a full scan. Now an incremental index over the
  seen set answers exact hits O(1), and a global "cfg var roots with
  any candidate" set proves the null case without scanning; only true
  root-match lookups (1 per file measured) fall back to the legacy
  scan. Blocks are re-indexed when their child count changes; misses
  self-heal through the fallback (its non-exact arm still matches
  exact producers first). PHP_COMPILER_PRODUCER_INDEX_LEGACY=1 restores
  the scan.

- SourcePreprocessor\PropertyHooks::isOffsetInComment rescanned the
  class body from byte 0 for every $var occurrence — O(vars x body),
  70% of lint samples on lib/VM.php. Now one pass per body builds
  sorted comment intervals (exact legacy boundary semantics), binary
  searched per probe. PHP_COMPILER_COMMENT_SCAN_LEGACY=1 restores the
  per-offset scan.

Measured in the pinned container (lint end-to-end, output identical to
legacy on lib/VM.php, lib/Compiler.php, lib/JIT.php,
ext/standard/VmString.php):
  lib/VM.php       2m50s -> 40s
  lib/Compiler.php 1m49s -> 1m11s

Includes bootstrap inventory/profile regen for the method-count drift.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@PurHur PurHur force-pushed the feat/producer-index branch from 64b5f9f to d0230d3 Compare July 5, 2026 15:45
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.

2 participants