Phase 22.x WIP: LLVM backend improvements + MIR builder enhancements

LLVM backend improvements:
- Add native LLVM backend support (NYASH_LLVM_BACKEND=native)
- Add crate backend selector with priority (crate > llvmlite)
- Add native_llvm_builder.py for native IR generation
- Add NYASH_LLVM_NATIVE_TRACE=1 for IR dump

MIR builder enhancements:
- Refactor lower_if_compare_* boxes for better code generation
- Refactor lower_return_* boxes for optimized returns
- Refactor lower_loop_* boxes for loop handling
- Refactor lower_method_* boxes for method calls
- Update pattern_util_box for better pattern matching

Smoke tests:
- Add phase2100 S3 backend selector tests (17 new tests)
- Add phase2120 native backend tests (4 new tests)
- Add phase2034 MIR builder internal tests (2 new tests)
- Add phase2211 TLV shim parity test

Documentation:
- Update ENV_VARS.md with LLVM backend variables
- Update CURRENT_TASK.md with progress
- Update README.md and CHANGELOG.md

Config:
- Add NYASH_LLVM_BACKEND env support in src/config/env.rs
- Update ny_mir_builder.sh for backend selection
- Update dispatch.rs for backend routing

Tools:
- Add tools/native_llvm_builder.py
- Update smokes/v2/profiles/quick/core/phase2100/run_all.sh

Known: Many Hako builder internal files modified for optimization
This commit is contained in:
nyash-codex
2025-11-09 23:40:36 +09:00
parent fb6129183d
commit f6c5dc9e43
65 changed files with 1965 additions and 434 deletions

View File

@ -24,8 +24,8 @@ def lower_function(builder, func_data: Dict[str, Any]):
# Determine function signature
if name == "ny_main":
# Special case: ny_main returns i32
func_ty = ir.FunctionType(builder.i32, [])
# Special case: ny_main returns i64 to match runtime (nyrt) expectations
func_ty = ir.FunctionType(builder.i64, [])
else:
# Default: i64(i64, ...) signature; derive arity from '/N' suffix when params missing
m = re.search(r"/(\d+)$", name)

View File

@ -45,7 +45,23 @@ def lower_binop(
lhs_val = ir.Constant(ir.IntType(64), 0)
if rhs_val is None:
rhs_val = ir.Constant(ir.IntType(64), 0)
# Normalize operation aliases (textual -> symbolic)
op_raw = op or ''
op_l = op_raw.lower()
alias = {
'add': '+', 'plus': '+',
'sub': '-', 'minus': '-',
'mul': '*', 'times': '*',
'div': '/',
'mod': '%', 'rem': '%',
'band': '&', 'bitand': '&',
'bor': '|', 'bitor': '|',
'bxor': '^', 'xor': '^',
'shl': '<<',
'shr': '>>', 'ashr': '>>',
}
op = alias.get(op_l, op_raw)
# Relational/equality operators delegate to compare
if op in ('==','!=','<','>','<=','>='):
# Delegate to compare with resolver/preds context to maintain dominance via localization

View File

@ -97,9 +97,16 @@ def lower_return(
# 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.
# If still zero-like (typed zero) and we have predecessor snapshots, synthesize a minimal PHI at block head.
try:
zero_like = isinstance(ret_val, ir.Constant)
zero_like = False
if isinstance(ret_val, ir.Constant):
if isinstance(return_type, ir.IntType):
zero_like = (str(ret_val) == str(ir.Constant(return_type, 0)))
elif isinstance(return_type, ir.DoubleType):
zero_like = (str(ret_val) == str(ir.Constant(return_type, 0.0)))
elif isinstance(return_type, ir.PointerType):
zero_like = (str(ret_val) == str(ir.Constant(return_type, None)))
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

View File

@ -152,7 +152,8 @@ class NyashLLVMBuilder:
else:
arity = int(m.group(1)) if m else len(params_list)
if name == "ny_main":
fty = ir.FunctionType(self.i32, [])
# Align with runtime expectation: ny_main returns i64
fty = ir.FunctionType(self.i64, [])
else:
fty = ir.FunctionType(self.i64, [self.i64] * arity)
exists = False