llvm: add LoopForm PHI hygiene smoke (no empty PHI); docs: MIR hints (zero-cost); macros: scaffold If/Match normalize (identity)
This commit is contained in:
13
apps/macros/examples/if_match_normalize_macro.nyash
Normal file
13
apps/macros/examples/if_match_normalize_macro.nyash
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// if_match_normalize_macro.nyash
|
||||||
|
// Scaffold: identity expansion for now. Future: introduce join variable and
|
||||||
|
// canonical If/Match normalization (scrutinee once, guard fused) as documented
|
||||||
|
// in docs/guides/if-match-normalize.md.
|
||||||
|
|
||||||
|
static box MacroBoxSpec {
|
||||||
|
name() { return "IfMatchNormalizeScaffold" }
|
||||||
|
|
||||||
|
expand(json, ctx) {
|
||||||
|
return json
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
33
docs/reference/mir/hints.md
Normal file
33
docs/reference/mir/hints.md
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# MIR Hints — Zero‑Cost Structural Guidance
|
||||||
|
|
||||||
|
目的
|
||||||
|
- 構造を変えずに最適な IR を導くための“軽量ヒント”集合。Release では完全に剥離(ゼロコスト)。
|
||||||
|
|
||||||
|
原則
|
||||||
|
- ヒントは意味論を持たない(最適化・検証の補助のみ)。
|
||||||
|
- 生成器はヒントなしでも正しい MIR/IR を出す。ヒントは安定化・検証・最適化誘導のために用いる。
|
||||||
|
|
||||||
|
ヒント一覧(MVP 案)
|
||||||
|
- hint.scope_enter(id), hint.scope_leave(id)
|
||||||
|
- スコープ境界を指示(cleanup 合流の挿入点検討に使用)。
|
||||||
|
- hint.defer(call-list)
|
||||||
|
- defer 呼出し列の静的展開に用いる(例外未導入の間は分岐/return/loop-exit 経路へ複製)。
|
||||||
|
- hint.join_result(var)
|
||||||
|
- If/Match 式の合流結果(join 変数)を明示。空 PHI 抑止とブロック先頭 PHI を誘導。
|
||||||
|
- hint.loop_carrier(vars…)
|
||||||
|
- ループヘッダで同一グループ PHI へ揃える対象変数集合(LoopForm と整合)。
|
||||||
|
- hint.loop_header, hint.loop_latch
|
||||||
|
- 自然ループの境界指示(コードレイアウト/最適化の補助)。
|
||||||
|
- hint.no_empty_phi(検証)
|
||||||
|
- 空 PHI 禁止の検証を有効化(開発/CI向け)。
|
||||||
|
|
||||||
|
パイプラインでの扱い
|
||||||
|
1) Macro: If/Match 正規化・Scope 属性付与・LoopForm(while/for/foreach)整形後に、
|
||||||
|
2) Lowering: 上記ヒントを埋める(構造は不変)。
|
||||||
|
3) Verify: 空 PHI 不在・PHI は合流先頭・ループヘッダの PHI 整列などを確認。
|
||||||
|
4) Strip: Release ではヒントを完全剥離(IRには一切痕跡なし)。
|
||||||
|
|
||||||
|
注意
|
||||||
|
- 既存の機能(マクロ・正規化)で構造を整えた上で使う。ヒントのみでは誤構造は正せない。
|
||||||
|
- CI の軽量ゲートでは `hint.no_empty_phi` 相当のスモークで IR 健全性を監視する。
|
||||||
|
|
||||||
60
tools/test/smoke/llvm/ir_phi_hygiene_loopform.sh
Normal file
60
tools/test/smoke/llvm/ir_phi_hygiene_loopform.sh
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
root=$(cd "$(dirname "$0")"/../../../.. && pwd)
|
||||||
|
bin="$root/target/release/nyash"
|
||||||
|
|
||||||
|
if [ ! -x "$bin" ]; then
|
||||||
|
echo "nyash binary not found at $bin; build first (cargo build --release --features llvm)" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Enable loop normalization macro and macro engine
|
||||||
|
export NYASH_MACRO_ENABLE=1
|
||||||
|
export NYASH_MACRO_PATHS="apps/macros/examples/loop_normalize_macro.nyash"
|
||||||
|
|
||||||
|
# Use self-host pre-expand (auto) with PyVM only to normalize before MIR
|
||||||
|
export NYASH_USE_NY_COMPILER=1
|
||||||
|
export NYASH_VM_USE_PY=1
|
||||||
|
|
||||||
|
# Use LLVM harness and dump IR
|
||||||
|
export NYASH_LLVM_USE_HARNESS=1
|
||||||
|
|
||||||
|
fails=0
|
||||||
|
|
||||||
|
check_case() {
|
||||||
|
local src="$1"
|
||||||
|
local irfile="$root/tmp/$(basename "$src" .nyash)_llvm.ll"
|
||||||
|
mkdir -p "$root/tmp"
|
||||||
|
NYASH_LLVM_DUMP_IR="$irfile" "$bin" --macro-preexpand --backend llvm "$src" >/dev/null 2>&1 || {
|
||||||
|
echo "[FAIL] LLVM run failed for $src" >&2
|
||||||
|
fails=$((fails+1))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if [ ! -s "$irfile" ]; then
|
||||||
|
echo "[FAIL] IR not dumped for $src" >&2
|
||||||
|
fails=$((fails+1))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
# Hygiene checks:
|
||||||
|
# 1) No empty phi nodes (phi ... with no '[' incoming pairs)
|
||||||
|
local empty_cnt
|
||||||
|
empty_cnt=$(rg -n "\\bphi\\b" "$irfile" | rg -v "\\[" | wc -l | tr -d ' ')
|
||||||
|
if [ "${empty_cnt:-0}" != "0" ]; then
|
||||||
|
echo "[FAIL] Empty PHI detected in $irfile" >&2
|
||||||
|
rg -n "\\bphi\\b" "$irfile" | rg -v "\\[" || true
|
||||||
|
fails=$((fails+1))
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
echo "[OK] PHI hygiene (no empty PHI): $(basename "$irfile")"
|
||||||
|
}
|
||||||
|
|
||||||
|
check_case "apps/tests/macro_golden_loop_simple.nyash"
|
||||||
|
check_case "apps/tests/macro_golden_loop_two_vars.nyash"
|
||||||
|
|
||||||
|
if [ "$fails" -ne 0 ]; then
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
echo "[OK] LLVM PHI hygiene for LoopForm cases passed"
|
||||||
|
exit 0
|
||||||
|
|
||||||
Reference in New Issue
Block a user