From b3ec548422f6ec63f40e17cdca72f86927aa4f4e Mon Sep 17 00:00:00 2001 From: Cliff Click Date: Mon, 26 Oct 2026 18:42:42 -0700 Subject: More incremental loading and compilation. --- skills/chapter25-codex-notes.md | 39 +++++++++++++++++++++++++++++++++++---- skills/incremental-builds.md | 21 +++++++++++---------- 2 files changed, 46 insertions(+), 14 deletions(-) (limited to 'skills') diff --git a/skills/chapter25-codex-notes.md b/skills/chapter25-codex-notes.md index be9768f8..f585f654 100644 --- a/skills/chapter25-codex-notes.md +++ b/skills/chapter25-codex-notes.md @@ -36,10 +36,16 @@ For shared viewer work, read [the graph viewer notes](graph-viewer-codex-notes.m Static `_spillScaled` also counts each inlined loop copy separately, without credit for eliminated calls; inspect the optimized call graph before calling a higher cross-chapter score an allocator regression. -- Prefer concrete ArrayList to List, common base classes to unnecessary - interfaces, and short names (`pred`, `proj`, `def`, `use`). Avoid redundant +- Use concrete JDK collection types in fields, parameters, and return types: + ArrayList, HashMap, HashSet, etc., rather than List, Map, or Set interfaces. + Prefer common base classes to unnecessary interfaces, and short names + (`pred`, `proj`, `def`, `use`). Avoid redundant Objects.requireNonNull. Prefer int[]/AryInt to List; avoid large boxed ID collections (use arrays/BitSet or NBHML as appropriate). Node ID 0 means null. +- When both branches assign the same field or variable, prefer one assignment + with a ternary expression over an if/else. +- Space declaration initializers as `Type name = expression;`. Preserve + deliberate column alignment when it makes related declarations easier to read. - Do not introduce Java streams. Use loops and explicit sorts; ask Cliff before making any exception. - Cliff often debugs the same failure in parallel. If asked to work in a side @@ -65,6 +71,31 @@ For shared viewer work, read [the graph viewer notes](graph-viewer-codex-notes.m ## Mutability and chapter boundaries +- Chapter 28b emits one object per source CompUnit. Imported functions have + Fun/Summary/Return graphs until an object is materialized. SummaryNodes are + never inlineable bodies. Only local calls request speculative IR; an unused + imported function must not recursively fetch its callees. Function identity + survives materialization through GlobalBits and rewired call/return edges. +- Initialization summaries retain direct call/touch edges and parent edges. + A potential cycle requires full IR refinement before diagnosis: a helper + outside the SCC can provide the constant that removes an internal edge. + Native linking uses the compiler's resolved CompUnit object paths when + available. Object-only tests without a CodeGen list all link inputs explicitly; + TestC does no dependency search. Eval2 trusts TypeCheck and a coherent set of + library objects; it does not revalidate cross-object compatibility. + SummaryNode.load uses CodeGen.getElf directly; + Eval2 needs no extra byte snapshot or protection from rewritten object files. + Tests must isolate output paths to avoid writer/reader races. + Eval2 materializes one object's checked IR on demand and schedules it + independently; never reoptimize graphs with active evaluation frames. Eval2 + executes CLInit directly using shared run-once flags. The child's clinit + body checks its parent before setting its own flag, so Eval2 and Lower need + only the requested class's flag-test/call at each active use. +- Summary escape information must include retention on nonreturning paths and + references passed by new callers. Result types alone do not capture this. + Import reanalysis releases prior SCCP memory keeps before starting another + solve; freshly deserialized nodes need parser-like construction semantics. + - Prefix updates must share ordinary name resolution: a method's bare field name denotes memory, while constructor fields may still be local SSA values. Do not update the declaration's scope slot before resolving that distinction. @@ -153,8 +184,8 @@ For shared viewer work, read [the graph viewer notes](graph-viewer-codex-notes.m - CLInit lowering (2026-10-17): TypeCheck queues surviving markers; optional Serialize saves opaque ideal IR, then Lower runs Iter before LoopTree. Serialization includes disconnected Returns and filters cross-object links - without mutating the live graph. Parent initialization precedes the child's - flag test/call; the true flag store remains inside the initializer. Runtime + without mutating the live graph. In Chapter 28b the child's initializer owns + both its parent-init check and its subsequent true flag store. Runtime flag reads follow ordinary Load idealization, including removing control. Handle x86 condition-flag lifetime constraints in the backend, not by pinning ideal Loads. Generated calls remain unlinked and diff --git a/skills/incremental-builds.md b/skills/incremental-builds.md index 050bd1ba..47c06fd9 100644 --- a/skills/incremental-builds.md +++ b/skills/incremental-builds.md @@ -19,7 +19,8 @@ For example: Use a fresh visited set for each candidate object. Cycles terminate safely, but a provisional success inside a cycle must not be cached for another root. -Dependencies owned by the same object are checked through its bundled sources. +Each source compilation unit now owns its own object; units compiled together +share a build timestamp so cycles do not invalidate themselves due to write order. An unchanged public signature is insufficient: Simple imports implementation details for optimization as well as declarations for type checking. @@ -30,7 +31,7 @@ objects. Validating those combinations requires saved input versions, not a guess from file times. A newer library object does invalidate a source-backed local dependent that can be rebuilt. -`IncrementalBuildTest` covers unchanged reuse, transitive source edits, bundled +`IncrementalBuildTest` covers unchanged reuse, transitive source edits, cycles, missing inputs, library dependencies, and clean/incremental native execution parity. It sets file times directly, without sleeps. @@ -39,16 +40,15 @@ execution parity. It sets file times directly, without sleeps. - Plan object targets and rebuilds across invocations. Handle cycles as groups and newly discovered dependencies. The compiler's per-object reuse check is not a complete scheduling or linking policy. -- Record actual input identities. An object can own several source units, so - track all of their sources and resolved library paths and versions. A search +- Record actual input identities: source units and resolved library paths and + versions. A search path change can select a different library even with an older timestamp. - Record compiler and serialization versions, target, ABI, and relevant options. Content hashes would also detect changes with preserved timestamps. Specify which changes require rebuilding source and which reject an incompatible source-free library. -- Make build targets match output ownership. The old ignored `testModule0` - expects separate A.o and A/B.o, while the current compiler can bundle several - units into one object. The target must identify the complete set it owns. +- Make build targets account for every output of a compilation request, which + can discover several source units and produce a separate object for each. - Provide an "ensure current" build operation. Explicit source compilation currently always recompiles. An unchanged build should do no compilation or linking; a changed object or link input should trigger relinking. @@ -66,10 +66,11 @@ requests straightforward. A clean build and an incremental build must produce the same observable program behavior. Cover unchanged builds, direct and transitive source edits, inlined constants -and bodies, cyclic dependencies, bundled sources, removed inputs, library-path +and bodies, cyclic dependencies, multiple outputs, removed inputs, library-path changes, compiler/target changes, and failed builds. Use controlled timestamps or hashes instead of sleeps. Replace the ignored historical experiment with tests matching the chosen object ownership model. -Selective library IR loading is separate future work. It can reduce compile -cost, but is not required to make conservative incremental rebuilding correct. +Library IR loading is independent of build and native link dependencies. +Summary-only imports still require coherent objects at link time, and inlining +does not erase the build dependency on the object supplying the copied body. -- cgit v1.2.3