compile: prune unused side-effect-free re-export subgraphs - #10245
proggeramlug wants to merge 5 commits into
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (4)
Included review availability: Your plan provides up to 8 included reviews per hour; 1 remains after this review. 📝 WalkthroughWalkthroughThe compiler now prunes unused re-exports when static dependency trees are proven side-effect-free through contracts or conservative purity analysis. It propagates demand, preserves unsafe cases, supports collect-only graph output, updates cache behavior, and adds regression coverage and documentation. ChangesRe-export pruning
Priority: ➖ Normal Estimated code review effort: 4 (Complex) | ~60 minutes Change: Feature Sequence Diagram(s)sequenceDiagram
participant CompilePipeline
participant ModuleCollector
participant ReexportPruner
participant NativeModules
CompilePipeline->>ModuleCollector: Collect modules
ModuleCollector->>ReexportPruner: Record imports and re-export edges
ReexportPruner->>ModuleCollector: Return newly activated paths
ModuleCollector->>NativeModules: Remove inactive re-export edges
CompilePipeline->>ReexportPruner: Write module graph in collect-only mode
Merge Risk: ⚪ Minimal · up to The pruning change is ready to merge based on the available evidence; no concrete behavior regression remains identified. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
OpenCode v1.18.30 collects unused siblings behind package barrels. This change removes 971 modules before HIR lowering/codegen: 7,897 → 6,926, including Remeda's generated mixed forwarding barrel (170 → 30 modules). Eager modules fall from 2,433 to 2,232. No version bump.
The issue's acceptance target remains unmet: the paired Bun build has 4,068 inputs, and OpenCode native CPU/
.textmeasurements remain blocked by an existing CommonJS getter-forwarding linker failure. This PR provides the pruning implementation and measured progress; it should not automatically close #10180.Behavior
sideEffects: falseand supported glob arrays. When metadata is absent, conservatively prove inert initialization from the AST, including first-party/workspace modules. Explicit effectful or unknown contracts veto inference. Calls, property/binding reads, destructuring, classes, unknown loads, and unsupported constructs retain their modules.import { x }; export { x }forwarding, including barrels containing bare imports and other re-exports. Preserve genuine bare imports. Require a pure, acyclic static tree before normalization; cyclic initialization entry points and effectful dependency order remain intact.PERRY_NO_REEXPORT_PRUNE=1disables pruning;PERRY_COLLECT_ONLY=1writesaudit.jsonandmodule-graph.jsonwithout codegen/linking. Both controls are documented.Dynamic-only code remains compiled and available; this change does not split it into separate native binaries or deduplicate installed package versions.
OpenCode measurement
Windows x64, OpenCode tag
v1.18.30, locked Bun 1.3.14 installation, builtpackages/app/dist, entrypackages/opencode/src/index.ts, Bun platform condition,OPENCODE_MODELS_DEV=undefined, and the generated web-UI asset module. Paired collection with pruning disabled/enabled:@ai-sdk/provider@ai-sdk/provider-utilsremedaeffectaiopenaiAfter normalizing the cache-local generated asset path, the enabled graph is a strict subset: 971 removed, zero added (12.3% fewer modules; 8.3% fewer eager modules). All 15 Prettier and 257 Babel modules are deferred in both graphs. TypeScript uses the native binding and has zero collected source modules. These are graph observations; running OpenCode
--versionremains unverified.The Bun metafile has 4,068 inputs, including 24 Remeda inputs. Its build externalizes the generated asset module and platform-specific
@opentui/core-*packages. The issue's reference is 4,063. Dynamic provider namespaces still retain their full export surfaces and installed dependency versions; Perry source files and Bun bundled distribution files also differ in granularity. The remaining gap is explicit, not an acceptance pass.Native fixture measurement
Using the exact locked Remeda 2.26.0 package,
import { sum } from 'remeda'; console.log(sum([1, 2, 3]));:.textbytes (llvm-size)66Both native executables match Node 26.5.1. This fixture reduces
.textby 39.2%; it is not an OpenCode size measurement.Validation and limits
test_gap_dynamic_import*parity tests pass on Node 26.5.1, with zero skips, compile failures, or crashes. The full gap suite was not rerun for this update; snapshots are unchanged.cargo check --locked -p perry --no-default-features --features dev-cli -j4, targeted rustfmt checks,git diff --check, file-size, test-registration, docs, and Node-version consistency checks pass. Targeted rustfmt is used becausecargo fmt --allexceeds Windows' command-length limit.PERRY_RS4GC=0for the existing WinEH/statepoint restriction (Windows: native-root stack walker so PERRY_RS4GC=1 works there (#7173) #7354). Compiler and full runtime/stdlib archives use the same explicit build stamp. The source-graph integration target is built through a temporary Cargo manifest pointing directly at the repository's actual test file, withCARGO_BIN_EXE_perryandPERRY_RUNTIME_DIRselecting that build.The existing Babel blocker is independently reproducible with the final compiler and full archives: a CommonJS package exposing
transformAsyncthroughObject.defineProperty(exports, ..., { get: function () { return _transform.transformAsync; } })fails to link its public function symbol with pruning both enabled and disabled. Node prints42. The prior PR revision's full OpenCode build failed at this same getter-forwarded symbol. Therefore this update does not report OpenCode native CPU, binary size, or CLI parity as verified.CI is not all green. Current failures report the existing raw
thread_local!in unchangedcrates/perry-runtime/src/regex/perex_owner.rs, unused functions in unchangedglobal_this_webassembly.rs, stale public benchmark inputs, and stale documentation gettext catalogs. Other checks may still be running; this PR does not claim a green full CI run.Refs #10180
Summary by CodeRabbit
New Features
Bug Fixes
Documentation