Phase 21.7 normalization: optimization pre-work + bench harness expansion
- Add opt-in optimizations (defaults OFF) - Ret purity verifier: NYASH_VERIFY_RET_PURITY=1 - strlen FAST enhancement for const handles - FAST_INT gate for same-BB SSA optimization - length cache for string literals in llvmlite - Expand bench harness (tools/perf/microbench.sh) - Add branch/call/stringchain/arraymap/chip8/kilo cases - Auto-calculate ratio vs C reference - Document in benchmarks/README.md - Compiler health improvements - Unify PHI insertion to insert_phi_at_head() - Add NYASH_LLVM_SKIP_BUILD=1 for build reuse - Runtime & safety enhancements - Clarify Rust/Hako ownership boundaries - Strengthen receiver localization (LocalSSA/pin/after-PHIs) - Stop excessive PluginInvoke→BoxCall rewrites - Update CURRENT_TASK.md, docs, and canaries 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -1,31 +1,33 @@
|
||||
# Phase 21.5 — Optimization (ny-llvm crate line)
|
||||
# Phase 21.5 — Optimization (AotPrep‑First)
|
||||
|
||||
Scope
|
||||
- Optimize hot paths for the crate (ny-llvmc) line using Hakorune scripts only.
|
||||
- Preserve default behavior; all risky changes behind dev toggles.
|
||||
- Measure EXE runtime (build once, run many) to avoid toolchain overhead noise.
|
||||
目的
|
||||
- .hako 側(AotPrep)で前処理最適化(構造のみ)を行い、LLVM/AOT に渡すIRを軽量にする。
|
||||
- 既定は挙動不変(opt‑in)。Return 純化ガードで安全性を担保。
|
||||
|
||||
Targets (initial)
|
||||
- loop: integer accumulations (no I/O)
|
||||
- strlen: FAST=1 path (pointer → nyrt_string_length)
|
||||
- box: construct/destroy minimal boxes (String/Integer)
|
||||
チェックリスト
|
||||
- [x] パス分割(StrlenFold / LoopHoist / ConstDedup / CollectionsHot / BinopCSE)
|
||||
- [x] CollectionsHot(Array/Map)導入(既定OFF)
|
||||
- [x] Map key モード `NYASH_AOT_MAP_KEY_MODE={h|i64|hh|auto}`
|
||||
- [x] LoopHoist v1 / BinopCSE v1(最小)
|
||||
- [x] ベンチ `linidx`/`maplin` 追加
|
||||
- [ ] LoopHoist v2(+/* 右項 const の連鎖前出し/fix‑point)
|
||||
- [ ] BinopCSE v2(線形 `i*n` 共通化の強化)
|
||||
- [ ] CollectionsHot v2(array index の共通SSA利用)
|
||||
- [ ] Map auto 精緻化(_is_const_or_linear の再帰判定)
|
||||
- [ ] Idempotence(置換済みタグで再実行時も不変)
|
||||
- [ ] `arraymap`/`matmul` ≤ 125%(C基準)
|
||||
|
||||
Methodology
|
||||
- Build once via ny-llvmc; time execution only (`--exe` mode).
|
||||
- Runs: 3–5; report median and average (target ≥ 100ms per run).
|
||||
- Observe NYASH_VM_STATS=1 (inst/compare/branch) where relevant to correlate structure and runtime.
|
||||
|
||||
Commands (examples)
|
||||
- tools/perf/phase215/bench_loop.sh --runs 5
|
||||
- tools/perf/phase215/bench_strlen.sh --runs 5 --fast 1
|
||||
- tools/perf/phase215/run_all.sh --runs 5 --timeout 120
|
||||
|
||||
Dev Toggles (keep OFF by default)
|
||||
- NYASH_LLVM_FAST=1 (strlen FAST)
|
||||
- HAKO_MIR_BUILDER_JSONFRAG_NORMALIZE=1 (normalize)
|
||||
- HAKO_MIR_BUILDER_NORMALIZE_TAG=1 (tag, test-only)
|
||||
|
||||
Exit Criteria
|
||||
- Representative microbenches stable (≤ 5% variance) and ≥ 80% of C baselines.
|
||||
- No regression in EXE canaries (loop/print/strlen FAST) and VM parity canaries.
|
||||
トグル
|
||||
- `NYASH_MIR_LOOP_HOIST=1` … StrlenFold/LoopHoist/ConstDedup/BinopCSE を有効化
|
||||
- `NYASH_AOT_COLLECTIONS_HOT=1` … CollectionsHot(Array/Map)
|
||||
- `NYASH_AOT_MAP_KEY_MODE` … `h|i64|hh|auto`(推奨: `auto`)
|
||||
- `NYASH_VERIFY_RET_PURITY=1` … Return 純化ガード(開発時ON)
|
||||
|
||||
ベンチ(例)
|
||||
```bash
|
||||
export NYASH_SKIP_TOML_ENV=1 NYASH_DISABLE_PLUGINS=1 \
|
||||
NYASH_LLVM_SKIP_BUILD=1 NYASH_LLVM_FAST=1 NYASH_LLVM_FAST_INT=1 \
|
||||
NYASH_MIR_LOOP_HOIST=1 NYASH_AOT_COLLECTIONS_HOT=1 NYASH_VERIFY_RET_PURITY=1
|
||||
for c in arraymap matmul sieve linidx maplin; do \
|
||||
tools/perf/microbench.sh --case $c --exe --runs 3; echo; done
|
||||
```
|
||||
|
||||
@ -36,7 +36,13 @@ Canaries
|
||||
- tools/dev/stageb_loop_json_canary.sh — Program(JSON) shape for loop(i<n){i=i+1}
|
||||
- tools/dev/phase216_chain_canary.sh — end‑to‑end EXE rc=10 for minimal loop
|
||||
|
||||
Provider Path Notes (Dev)
|
||||
- Optional normalization for provider output is available via `HAKO_MIR_NORMALIZE_PROVIDER=1`.
|
||||
- This applies the same JsonFrag normalizer/purifier to MIR(JSON) emitted by the Rust Provider path.
|
||||
- Keep defaults unchanged; use only during bring‑up to eliminate ret‑after effects.
|
||||
- `HAKO_MIR_BUILDER_LOOP_FORCE_JSONFRAG=1` now short‑circuits both selfhost‑first and provider‑first wrappers to emit a minimal, pure control‑flow MIR suitable for EXE build sanity.
|
||||
- Default OFF; intended for small canaries and performance harness bring‑up.
|
||||
|
||||
Removal Plan for temporary parser fallback
|
||||
- Once VM/gpos interaction is fixed and parser emits correct loop JSON without guards,
|
||||
remove the conservative fallback in ParserControlBox.parse_loop.
|
||||
|
||||
|
||||
51
docs/development/roadmap/phases/phase-21.6/README.md
Normal file
51
docs/development/roadmap/phases/phase-21.6/README.md
Normal file
@ -0,0 +1,51 @@
|
||||
# Phase 21.6 — Dual‑Emit Parity & C‑line Readiness
|
||||
|
||||
Goal: Produce identical MIR(JSON) from both provider (Rust) and selfhost (Hako) builder paths, measure generation cost, and keep AOT (ny‑llvmc) fast/green. All work is semantics‑preserving; defaults remain unchanged.
|
||||
|
||||
## Checklists
|
||||
|
||||
- [ ] Dual‑emit parity on representative apps (MIR(JSON) normalized SHA1 equal)
|
||||
- [ ] Resolver‑first ON passes quick/integration
|
||||
- [ ] Selfhost‑first fallback ok (provider/legacy on failure)
|
||||
- [ ] AOT obj/exe via ny‑llvmc (crate backend) green
|
||||
- [ ] Docs updated (bench guides, env vars, quick recipes)
|
||||
|
||||
## Scripts
|
||||
|
||||
- Dual emit + compare + bench: `tools/perf/dual_emit_compare.sh <input.hako> [rounds]`
|
||||
- MIR emit bench: `tools/perf/bench_hakorune_emit_mir.sh <input.hako> [rounds]`
|
||||
- AOT bench: `tools/perf/bench_ny_mir_builder.sh <mir.json> [rounds]`
|
||||
- MIR diff: `tools/perf/compare_mir_json.sh <a.json> <b.json>`
|
||||
|
||||
## Env Knobs
|
||||
|
||||
- `HAKO_USING_RESOLVER_FIRST=1` (resolver‑first)
|
||||
- `HAKO_SELFHOST_BUILDER_FIRST=1` (selfhost→provider→legacy)
|
||||
- `HAKO_MIR_BUILDER_BOX=hako.mir.builder|min`
|
||||
- `NYASH_LLVM_BACKEND=crate`(ny‑llvmc)
|
||||
- `HAKO_LLVM_OPT_LEVEL=0|1`(AOT O0 既定)
|
||||
|
||||
## Benchmarks — Tracking
|
||||
|
||||
Record normalized parity and generation times here (edit in place).
|
||||
|
||||
Legend: SHA1 = normalized JSON digest; Parity=Yes when SHA1 equal; Times are medians unless noted.
|
||||
|
||||
| Benchmark (Hako) | Resolver | Parity | Provider p50 (ms) | Selfhost p50 (ms) | Notes |
|
||||
|------------------------------------------|----------|--------|-------------------|-------------------|-------|
|
||||
| apps/examples/json_query/main.hako | off/on | | | | |
|
||||
| apps/examples/json_pp/main.hako | off/on | | | | |
|
||||
| apps/examples/json_lint/main.hako | off/on | | | | |
|
||||
| apps/examples/json_query_min/main.hako | off/on | | | | |
|
||||
|
||||
How to fill:
|
||||
1) Run `tools/perf/dual_emit_compare.sh <file> 5`
|
||||
2) Copy p50s from the summary lines and mark Parity based on `compare_mir_json.sh` output.
|
||||
3) Note any diffs (callee kinds/order/phi/meta) in Notes.
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [ ] If parity holds on the above set, extend to apps/tests subset
|
||||
- [ ] If diffs remain, categorize and align either provider or selfhost output
|
||||
- [ ] Keep AOT line green under `HAKO_LLVM_OPT_LEVEL=0` and optional `=1` spot checks
|
||||
|
||||
@ -9,12 +9,15 @@ Targets (must be green)
|
||||
|
||||
Canaries
|
||||
- tools/dev/phase216_chain_canary_call.sh — remains PASS when OFF, PASS when ON
|
||||
- Add: tools/dev/phase217_methodize_canary.sh (dev) — asserts method callee usage in MIR or IR tags
|
||||
- tools/dev/phase217_methodize_canary.sh (dev) — compile-run rc=5(セマンティクス)
|
||||
- tools/dev/phase217_methodize_json_canary.sh (dev) — v1 root(schema_version)+ mir_call present(Methodが望ましい、Globalは経過容認)
|
||||
|
||||
Toggles
|
||||
- HAKO_MIR_BUILDER_METHODIZE=1 (new)
|
||||
- HAKO_STAGEB_FUNC_SCAN=1 / HAKO_MIR_BUILDER_FUNCS=1 / HAKO_MIR_BUILDER_CALL_RESOLVE=1 (existing)
|
||||
- 一軍(devプロファイルで既定ON): 上記3つ + NYASH_JSON_SCHEMA_V1=1 + NYASH_MIR_UNIFIED_CALL=1
|
||||
- 診断(既定OFF): HAKO_BRIDGE_METHODIZE=1(core_bridge側の補助。Hako既定化後に撤去)
|
||||
|
||||
Rollback
|
||||
- Disable HAKO_MIR_BUILDER_METHODIZE; remove methodization rewrite; keep Global path active.
|
||||
|
||||
- core_bridgeの methodize ブリッジは Hako側が既定化され次第、撤去(タグ: [bridge/methodize:*] を一時観測可能にして差分検知)
|
||||
|
||||
Reference in New Issue
Block a user