release: v21.0.0 – Full Self‑Hosting (S1/S2/S3 complete)

- DoD met: S1/S2 determinism (const/compare/threeblock-collect), PRIMARY hv1 inline no-fallback, S3 (llvmlite+kernel) reps green
- Harness: v1→llvmlite direct, EXE links to libnyash_kernel.a
- Python LLVM builder fixes: cmp normalization, ret PHI synthesis, mir_call flat shape
- Using/alias polish (prod): modules-first; missing aliases added; duplicate using cleaned
- Docs: phase-21.0 COMPLETE; CurrentTask closed; release notes added
This commit is contained in:
nyash-codex
2025-11-06 16:59:34 +09:00
parent c40fdd95bc
commit e326e787a4
21 changed files with 311 additions and 100 deletions

View File

@ -48,11 +48,9 @@ def lower_return(
# Fast path: if vmap has a concrete non-PHI value defined in this block, use it directly
if isinstance(value_id, int):
tmp0 = vmap.get(value_id)
try:
is_phi0 = hasattr(tmp0, 'add_incoming')
except Exception:
is_phi0 = False
if tmp0 is not None and not is_phi0:
# Accept PHI or non-PHI values equally for returns; by this point
# PHIs for the current block should have been materialized at the top.
if tmp0 is not None:
ret_val = tmp0
if ret_val is None:
if resolver is not None and preds is not None and block_end_values is not None and bb_map is not None:
@ -98,6 +96,39 @@ def lower_return(
else:
# Pointer type - null
ret_val = ir.Constant(return_type, None)
# If still zero-like and we have predecessor snapshots, synthesize a minimal PHI at block head.
try:
zero_like = isinstance(ret_val, ir.Constant)
if zero_like and preds is not None and block_end_values is not None and bb_map is not None and isinstance(value_id, int):
# Derive current block id from name like 'bb3'
cur_bid = None
try:
cur_bid = int(str(builder.block.name).replace('bb',''))
except Exception:
cur_bid = None
if cur_bid is not None:
incoming = []
for p in preds.get(cur_bid, []):
# Skip self-loop
if p == cur_bid: continue
v = None
try:
v = block_end_values.get(p, {}).get(value_id)
except Exception:
v = None
if v is None:
v = ir.Constant(return_type, 0)
bblk = bb_map.get(p)
if bblk is not None:
incoming.append((v, bblk))
if incoming:
phi = builder.phi(return_type, name=f"ret_phi_{value_id}")
for (v, bblk) in incoming:
phi.add_incoming(v, bblk)
ret_val = phi
except Exception:
pass
# Type adjustment if needed
if hasattr(ret_val, 'type') and ret_val.type != return_type: