From 900db912a5691e366263520432038057a3ee98b4 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Thu, 12 Feb 2026 09:43:13 -0600 Subject: [PATCH] streamline mcode --- docs/spec/pipeline.md | 24 +- docs/spec/streamline.md | 202 +++++++++++++ dump_ast.cm | 12 + dump_mcode.cm | 119 +++++++- dump_stream.cm | 166 ++++++++++ dump_types.cm | 242 +++++++++++++++ fold.mach | Bin 157352 -> 155160 bytes internal/bootstrap.mach | Bin 18369 -> 17918 bytes internal/engine.cm | 4 + internal/engine.mach | Bin 44672 -> 44197 bytes mcode.cm | 46 +++ mcode.mach | Bin 150904 -> 156295 bytes parse.mach | Bin 202524 -> 197232 bytes qbe_emit.mach | Bin 80218 -> 79266 bytes source/mach.c | 27 +- source/quickjs-internal.h | 13 + source/quickjs.h | 2 +- streamline.cm | 621 +++++++++++++++++++++++++++++++++----- streamline.mach | Bin 32631 -> 97368 bytes test_backward.cm | 27 ++ test_intrinsics.cm | 63 ++++ tokenize.mach | Bin 76339 -> 74839 bytes 22 files changed, 1475 insertions(+), 93 deletions(-) create mode 100644 docs/spec/streamline.md create mode 100644 dump_ast.cm create mode 100644 dump_stream.cm create mode 100644 dump_types.cm create mode 100644 test_backward.cm create mode 100644 test_intrinsics.cm diff --git a/docs/spec/pipeline.md b/docs/spec/pipeline.md index fe1240ba..c8fda47d 100644 --- a/docs/spec/pipeline.md +++ b/docs/spec/pipeline.md @@ -47,16 +47,22 @@ Lowers the AST to a JSON-based intermediate representation with explicit operati - **Typed load/store**: Emits `load_index` (array by integer), `load_field` (record by string), or `load_dynamic` (unknown) based on type information from fold. - **Decomposed calls**: Function calls are split into `frame` (create call frame) + `setarg` (set arguments) + `invoke` (execute call). - **Intrinsic access**: Intrinsic functions are loaded via `access` with an intrinsic marker rather than global lookup. +- **Intrinsic inlining**: Type-check intrinsics (`is_array`, `is_text`, `is_number`, `is_integer`, `is_logical`, `is_null`, `is_function`, `is_object`, `is_stone`), `length`, and `push` are emitted as direct opcodes instead of frame/setarg/invoke call sequences. See [Mcode IR](mcode.md) for instruction format details. ### Streamline (`streamline.cm`) -Optimizes the Mcode IR. Operates per-function: +Optimizes the Mcode IR through a series of independent passes. Operates per-function: -- **Redundant instruction elimination**: Removes no-op patterns and redundant moves. -- **Dead code removal**: Eliminates instructions whose results are never used. -- **Type-based narrowing**: When type information is available, narrows `load_dynamic`/`store_dynamic` to typed variants. +1. **Backward type inference**: Infers parameter types from how they are used in typed operators. Immutable `def` parameters keep their inferred type across label join points. +2. **Type-check elimination**: When a slot's type is known, eliminates `is_` + conditional jump pairs. Narrows `load_dynamic`/`store_dynamic` to typed variants. +3. **Algebraic simplification**: Rewrites identity operations (add 0, multiply 1, divide 1) and folds same-slot comparisons. +4. **Boolean simplification**: Fuses `not` + conditional jump into a single jump with inverted condition. +5. **Move elimination**: Removes self-moves (`move a, a`). +6. **Dead jump elimination**: Removes jumps to the immediately following label. + +See [Streamline Optimizer](streamline.md) for detailed pass descriptions. ### QBE Emit (`qbe_emit.cm`) @@ -107,6 +113,14 @@ Generates QBE IL that can be compiled to native code. | `qbe.cm` | QBE IL operation templates | | `internal/bootstrap.cm` | Pipeline orchestrator | +## Debug Tools + +| File | Purpose | +|------|---------| +| `dump_mcode.cm` | Print raw Mcode IR before streamlining | +| `dump_stream.cm` | Print IR after streamlining with before/after stats | +| `dump_types.cm` | Print streamlined IR with type annotations | + ## Test Files | File | Tests | @@ -116,3 +130,5 @@ Generates QBE IL that can be compiled to native code. | `mcode_test.ce` | Typed load/store, decomposed calls | | `streamline_test.ce` | Optimization counts, IR before/after | | `qbe_test.ce` | End-to-end QBE IL generation | +| `test_intrinsics.cm` | Inlined intrinsic opcodes (is_array, length, push, etc.) | +| `test_backward.cm` | Backward type propagation for parameters | diff --git a/docs/spec/streamline.md b/docs/spec/streamline.md new file mode 100644 index 00000000..3d413695 --- /dev/null +++ b/docs/spec/streamline.md @@ -0,0 +1,202 @@ +--- +title: "Streamline Optimizer" +description: "Mcode IR optimization passes" +--- + +## Overview + +The streamline optimizer (`streamline.cm`) runs a series of independent passes over the Mcode IR to eliminate redundant operations. Each pass is a standalone function that can be enabled, disabled, or reordered. Passes communicate only through the instruction array they mutate in place, replacing eliminated instructions with nop strings (e.g., `_nop_tc_1`). + +The optimizer runs after `mcode.cm` generates the IR and before the result is lowered to the Mach VM or emitted as QBE IL. + +``` +Fold (AST) → Mcode (JSON IR) → Streamline → Mach VM / QBE +``` + +## Type Lattice + +The optimizer tracks a type for each slot in the register file: + +| Type | Meaning | +|------|---------| +| `unknown` | No type information | +| `int` | Integer | +| `float` | Floating-point | +| `num` | Number (subsumes int and float) | +| `text` | String | +| `bool` | Logical (true/false) | +| `null` | Null value | +| `array` | Array | +| `record` | Record (object) | +| `function` | Function | +| `blob` | Binary blob | + +Subsumption: `int` and `float` both satisfy a `num` check. + +## Passes + +### 1. infer_param_types (backward type inference) + +Scans all typed operators to determine what types their operands must be. For example, `add_int dest, a, b` implies both `a` and `b` are integers. + +When a parameter slot (1..nr_args) is consistently inferred as a single type, that type is recorded. Since parameters are immutable (`def`), the inferred type holds for the entire function and persists across label join points (loop headers, branch targets). + +Backward inference rules: + +| Operator class | Operand type inferred | +|---|---| +| `add_int`, `sub_int`, `mul_int`, `div_int`, `mod_int`, `eq_int`, comparisons, bitwise | T_INT | +| `add_float`, `sub_float`, `mul_float`, `div_float`, `mod_float`, float comparisons | T_FLOAT | +| `concat`, text comparisons | T_TEXT | +| `eq_bool`, `ne_bool`, `not`, `and`, `or` | T_BOOL | +| `store_index` (object operand) | T_ARRAY | +| `store_index` (index operand) | T_INT | +| `store_field` (object operand) | T_RECORD | +| `push` (array operand) | T_ARRAY | + +When a slot appears with conflicting type inferences (e.g., used in both `add_int` and `concat` across different type-dispatch branches), the result is `unknown`. INT + FLOAT conflicts produce `num`. + +**Nop prefix:** none (analysis only, does not modify instructions) + +### 2. eliminate_type_checks (type-check + jump elimination) + +Forward pass that tracks the known type of each slot. When a type check (`is_int`, `is_text`, `is_num`, etc.) is followed by a conditional jump, and the slot's type is already known, the check and jump can be eliminated or converted to an unconditional jump. + +Three cases: + +- **Known match** (e.g., `is_int` on a slot known to be `int`): both the check and the conditional jump are eliminated (nop'd). +- **Known mismatch** (e.g., `is_text` on a slot known to be `int`): the check is nop'd and the conditional jump is rewritten to an unconditional `jump`. +- **Unknown**: the check remains, but on fallthrough, the slot's type is narrowed to the checked type (enabling downstream eliminations). + +This pass also reduces `load_dynamic`/`store_dynamic` to `load_field`/`store_field` or `load_index`/`store_index` when the key slot's type is known. + +At label join points, all type information is reset except for parameter types seeded by the backward inference pass. + +**Nop prefix:** `_nop_tc_` + +### 3. simplify_algebra (algebraic identity + comparison folding) + +Tracks known constant values alongside types. Rewrites identity operations: + +| Pattern | Rewrite | +|---------|---------| +| `add_int dest, x, 0` | `move dest, x` | +| `add_int dest, 0, x` | `move dest, x` | +| `sub_int dest, x, 0` | `move dest, x` | +| `mul_int dest, x, 1` | `move dest, x` | +| `mul_int dest, 1, x` | `move dest, x` | +| `mul_int dest, x, 0` | `int dest, 0` | +| `div_int dest, x, 1` | `move dest, x` | +| `add_float dest, x, 0` | `move dest, x` | +| `mul_float dest, x, 1` | `move dest, x` | +| `div_float dest, x, 1` | `move dest, x` | + +Float multiplication by zero is intentionally not optimized because it is not safe with NaN and Inf values. + +Same-slot comparison folding: + +| Pattern | Rewrite | +|---------|---------| +| `eq_* dest, x, x` | `true dest` | +| `le_* dest, x, x` | `true dest` | +| `ge_* dest, x, x` | `true dest` | +| `is_identical dest, x, x` | `true dest` | +| `ne_* dest, x, x` | `false dest` | +| `lt_* dest, x, x` | `false dest` | +| `gt_* dest, x, x` | `false dest` | + +**Nop prefix:** none (rewrites in place, does not create nops) + +### 4. simplify_booleans (not + jump fusion) + +Peephole pass that eliminates unnecessary `not` instructions: + +| Pattern | Rewrite | +|---------|---------| +| `not d, x; jump_false d, L` | nop; `jump_true x, L` | +| `not d, x; jump_true d, L` | nop; `jump_false x, L` | +| `not d1, x; not d2, d1` | nop; `move d2, x` | + +This is particularly effective on `if (!cond)` patterns, which the compiler generates as `not; jump_false`. After this pass, they become a single `jump_true`. + +**Nop prefix:** `_nop_bl_` + +### 5. eliminate_moves (self-move elimination) + +Removes `move a, a` instructions where the source and destination are the same slot. These can arise from earlier passes rewriting binary operations into moves. + +**Nop prefix:** `_nop_mv_` + +### 6. eliminate_unreachable (dead code after return/disrupt) + +*Currently disabled.* Nops instructions after `return` or `disrupt` until the next real label. + +Disabled because disruption handler code is placed after the `return`/`disrupt` instruction without a label boundary. The VM dispatches to handlers via the `disruption_pc` offset, not through normal control flow. Re-enabling this pass requires the mcode compiler to emit labels at disruption handler entry points. + +**Nop prefix:** `_nop_ur_` + +### 7. eliminate_dead_jumps (jump-to-next-label elimination) + +Removes `jump L` instructions where `L` is the immediately following label (skipping over any intervening nop strings). These are common after other passes eliminate conditional branches, leaving behind jumps that fall through naturally. + +**Nop prefix:** `_nop_dj_` + +## Pass Composition + +All passes run in sequence in `optimize_function`: + +``` +infer_param_types → returns param_types map +eliminate_type_checks → uses param_types +simplify_algebra +simplify_booleans +eliminate_moves +(eliminate_unreachable) → disabled +eliminate_dead_jumps +``` + +Each pass is independent and can be commented out for testing or benchmarking. + +## Intrinsic Inlining + +Before streamlining, `mcode.cm` recognizes calls to built-in intrinsic functions and emits direct opcodes instead of the generic frame/setarg/invoke call sequence. This reduces a 6-instruction call pattern to a single instruction: + +| Call | Emitted opcode | +|------|---------------| +| `is_array(x)` | `is_array dest, src` | +| `is_function(x)` | `is_func dest, src` | +| `is_object(x)` | `is_record dest, src` | +| `is_stone(x)` | `is_stone dest, src` | +| `is_integer(x)` | `is_int dest, src` | +| `is_text(x)` | `is_text dest, src` | +| `is_number(x)` | `is_num dest, src` | +| `is_logical(x)` | `is_bool dest, src` | +| `is_null(x)` | `is_null dest, src` | +| `length(x)` | `length dest, src` | +| `push(arr, val)` | `push arr, val` | + +These inlined opcodes have corresponding Mach VM implementations in `mach.c`. + +## Debugging Tools + +Three dump tools inspect the IR at different stages: + +- **`dump_mcode.cm`** — prints the raw Mcode IR after `mcode.cm`, before streamlining +- **`dump_stream.cm`** — prints the IR after streamlining, with before/after instruction counts +- **`dump_types.cm`** — prints the streamlined IR with type annotations on each instruction + +Usage: +``` +./cell --core . dump_mcode.cm +./cell --core . dump_stream.cm +./cell --core . dump_types.cm +``` + +## Nop Convention + +Eliminated instructions are replaced with strings matching `_nop__`. The prefix identifies which pass created the nop. Nop strings are: + +- Skipped during interpretation (the VM ignores them) +- Skipped during QBE emission +- Not counted in instruction statistics +- Preserved in the instruction array to maintain positional stability for jump targets diff --git a/dump_ast.cm b/dump_ast.cm new file mode 100644 index 00000000..9b73666a --- /dev/null +++ b/dump_ast.cm @@ -0,0 +1,12 @@ +var fd = use("fd") +var json = use("json") +var tokenize = use("tokenize") +var parse = use("parse") +var fold = use("fold") + +var filename = args[0] +var src = text(fd.slurp(filename)) +var tok = tokenize(src, filename) +var ast = parse(tok.tokens, src, filename, tokenize) +var folded = fold(ast) +print(json.encode(folded)) diff --git a/dump_mcode.cm b/dump_mcode.cm index 291b6e46..52395280 100644 --- a/dump_mcode.cm +++ b/dump_mcode.cm @@ -1,20 +1,117 @@ +// dump_mcode.cm — pretty-print mcode IR (before streamlining) +// +// Usage: ./cell --core . dump_mcode.cm + var fd = use("fd") var json = use("json") var tokenize = use("tokenize") var parse = use("parse") var fold = use("fold") var mcode = use("mcode") -var streamline = use("streamline") -var name = args[0] -var src = text(fd.slurp(name)) -var tok = tokenize(src, name) -var ast = parse(tok.tokens, src, name, tokenize) +if (length(args) < 1) { + print("usage: cell --core . dump_mcode.cm ") + return +} + +var filename = args[0] +var src = text(fd.slurp(filename)) +var tok = tokenize(src, filename) +var ast = parse(tok.tokens, src, filename, tokenize) var folded = fold(ast) var compiled = mcode(folded) -var optimized = streamline(compiled) -var out = json.encode(optimized) -var f = fd.open("/tmp/mcode_dump.json", "w") -fd.write(f, out) -fd.close(f) -print("wrote /tmp/mcode_dump.json") + +var pad_right = function(s, w) { + var r = s + while (length(r) < w) { + r = r + " " + } + return r +} + +var fmt_val = function(v) { + if (is_null(v)) { + return "null" + } + if (is_number(v)) { + return text(v) + } + if (is_text(v)) { + return `"${v}"` + } + if (is_object(v)) { + return json.encode(v) + } + if (is_logical(v)) { + return v ? "true" : "false" + } + return text(v) +} + +var dump_function = function(func, name) { + var nr_args = func.nr_args != null ? func.nr_args : 0 + var nr_slots = func.nr_slots != null ? func.nr_slots : 0 + var nr_close = func.nr_close_slots != null ? func.nr_close_slots : 0 + var instrs = func.instructions + var i = 0 + var pc = 0 + var instr = null + var op = null + var n = 0 + var parts = null + var j = 0 + var operands = null + var pc_str = null + var op_str = null + print(`\n=== ${name} (args=${text(nr_args)}, slots=${text(nr_slots)}, closures=${text(nr_close)}) ===`) + if (instrs == null || length(instrs) == 0) { + print(" (empty)") + return null + } + while (i < length(instrs)) { + instr = instrs[i] + if (is_text(instr)) { + if (!starts_with(instr, "_nop_")) { + print(`${instr}:`) + } + } else if (is_array(instr)) { + op = instr[0] + n = length(instr) + parts = [] + j = 1 + while (j < n - 2) { + push(parts, fmt_val(instr[j])) + j = j + 1 + } + operands = text(parts, ", ") + pc_str = pad_right(text(pc), 5) + op_str = pad_right(op, 14) + print(` ${pc_str} ${op_str} ${operands}`) + pc = pc + 1 + } + i = i + 1 + } + return null +} + +var main_name = null +var fi = 0 +var func = null +var fname = null + +// Dump main +if (compiled.main != null) { + main_name = compiled.name != null ? compiled.name : "
" + dump_function(compiled.main, main_name) +} + +// Dump sub-functions +if (compiled.functions != null) { + fi = 0 + while (fi < length(compiled.functions)) { + func = compiled.functions[fi] + fname = func.name != null ? func.name : `` + dump_function(func, `[${text(fi)}] ${fname}`) + fi = fi + 1 + } +} diff --git a/dump_stream.cm b/dump_stream.cm new file mode 100644 index 00000000..e74a0443 --- /dev/null +++ b/dump_stream.cm @@ -0,0 +1,166 @@ +// dump_stream.cm — show mcode IR before and after streamlining +// +// Usage: ./cell --core . dump_stream.cm + +var fd = use("fd") +var json = use("json") +var tokenize = use("tokenize") +var parse = use("parse") +var fold = use("fold") +var mcode = use("mcode") +var streamline = use("streamline") + +if (length(args) < 1) { + print("usage: cell --core . dump_stream.cm ") + return +} + +var filename = args[0] +var src = text(fd.slurp(filename)) +var tok = tokenize(src, filename) +var ast = parse(tok.tokens, src, filename, tokenize) +var folded = fold(ast) +var compiled = mcode(folded) + +// Deep copy IR for before snapshot +var before = json.decode(json.encode(compiled)) + +var optimized = streamline(compiled) + +var pad_right = function(s, w) { + var r = s + while (length(r) < w) { + r = r + " " + } + return r +} + +var fmt_val = function(v) { + if (is_null(v)) { + return "null" + } + if (is_number(v)) { + return text(v) + } + if (is_text(v)) { + return `"${v}"` + } + if (is_object(v)) { + return json.encode(v) + } + if (is_logical(v)) { + return v ? "true" : "false" + } + return text(v) +} + +var count_stats = function(func) { + var instrs = func.instructions + var total = 0 + var nops = 0 + var calls = 0 + var i = 0 + var instr = null + if (instrs == null) { + return {total: 0, nops: 0, real: 0, calls: 0} + } + while (i < length(instrs)) { + instr = instrs[i] + if (is_text(instr)) { + if (starts_with(instr, "_nop_")) { + nops = nops + 1 + } + } else if (is_array(instr)) { + total = total + 1 + if (instr[0] == "invoke") { + calls = calls + 1 + } + } + i = i + 1 + } + return {total: total, nops: nops, real: total - nops, calls: calls} +} + +var dump_function = function(func, show_nops) { + var instrs = func.instructions + var i = 0 + var pc = 0 + var instr = null + var op = null + var n = 0 + var parts = null + var j = 0 + var operands = null + var pc_str = null + var op_str = null + if (instrs == null || length(instrs) == 0) { + return null + } + while (i < length(instrs)) { + instr = instrs[i] + if (is_text(instr)) { + if (starts_with(instr, "_nop_")) { + if (show_nops) { + print(` ${pad_right(text(pc), 5)} --- nop ---`) + pc = pc + 1 + } + } else { + print(`${instr}:`) + } + } else if (is_array(instr)) { + op = instr[0] + n = length(instr) + parts = [] + j = 1 + while (j < n - 2) { + push(parts, fmt_val(instr[j])) + j = j + 1 + } + operands = text(parts, ", ") + pc_str = pad_right(text(pc), 5) + op_str = pad_right(op, 14) + print(` ${pc_str} ${op_str} ${operands}`) + pc = pc + 1 + } + i = i + 1 + } + return null +} + +var dump_pair = function(before_func, after_func, name) { + var nr_args = after_func.nr_args != null ? after_func.nr_args : 0 + var nr_slots = after_func.nr_slots != null ? after_func.nr_slots : 0 + var b_stats = count_stats(before_func) + var a_stats = count_stats(after_func) + var eliminated = a_stats.nops + print(`\n=== ${name} (args=${text(nr_args)}, slots=${text(nr_slots)}) ===`) + print(` before: ${text(b_stats.total)} instructions, ${text(b_stats.calls)} invokes`) + print(` after: ${text(a_stats.real)} instructions (${text(eliminated)} eliminated), ${text(a_stats.calls)} invokes`) + print("\n -- streamlined --") + dump_function(after_func, false) + return null +} + +var main_name = null +var fi = 0 +var func = null +var bfunc = null +var fname = null + +// Dump main +if (optimized.main != null && before.main != null) { + main_name = optimized.name != null ? optimized.name : "
" + dump_pair(before.main, optimized.main, main_name) +} + +// Dump sub-functions +if (optimized.functions != null && before.functions != null) { + fi = 0 + while (fi < length(optimized.functions)) { + func = optimized.functions[fi] + bfunc = before.functions[fi] + fname = func.name != null ? func.name : `` + dump_pair(bfunc, func, `[${text(fi)}] ${fname}`) + fi = fi + 1 + } +} diff --git a/dump_types.cm b/dump_types.cm new file mode 100644 index 00000000..7b8d2ea5 --- /dev/null +++ b/dump_types.cm @@ -0,0 +1,242 @@ +// dump_types.cm — show streamlined IR with type annotations +// +// Usage: ./cell --core . dump_types.cm + +var fd = use("fd") +var json = use("json") +var tokenize = use("tokenize") +var parse = use("parse") +var fold = use("fold") +var mcode = use("mcode") +var streamline = use("streamline") + +if (length(args) < 1) { + print("usage: cell --core . dump_types.cm ") + return +} + +var filename = args[0] +var src = text(fd.slurp(filename)) +var tok = tokenize(src, filename) +var ast = parse(tok.tokens, src, filename, tokenize) +var folded = fold(ast) +var compiled = mcode(folded) +var optimized = streamline(compiled) + +// Type constants +def T_UNKNOWN = "unknown" +def T_INT = "int" +def T_FLOAT = "float" +def T_NUM = "num" +def T_TEXT = "text" +def T_BOOL = "bool" +def T_NULL = "null" +def T_ARRAY = "array" +def T_RECORD = "record" +def T_FUNCTION = "function" + +def int_result_ops = { + add_int: true, sub_int: true, mul_int: true, + div_int: true, mod_int: true, neg_int: true, + bitnot: true, bitand: true, bitor: true, + bitxor: true, shl: true, shr: true, ushr: true +} +def float_result_ops = { + add_float: true, sub_float: true, mul_float: true, + div_float: true, mod_float: true, neg_float: true +} +def bool_result_ops = { + eq_int: true, ne_int: true, lt_int: true, gt_int: true, + le_int: true, ge_int: true, + eq_float: true, ne_float: true, lt_float: true, gt_float: true, + le_float: true, ge_float: true, + eq_text: true, ne_text: true, lt_text: true, gt_text: true, + le_text: true, ge_text: true, + eq_bool: true, ne_bool: true, + not: true, and: true, or: true, + is_int: true, is_text: true, is_num: true, + is_bool: true, is_null: true, is_identical: true, + is_array: true, is_func: true, is_record: true, is_stone: true +} + +var access_value_type = function(val) { + if (is_number(val)) { + return is_integer(val) ? T_INT : T_FLOAT + } + if (is_text(val)) { + return T_TEXT + } + return T_UNKNOWN +} + +var track_types = function(slot_types, instr) { + var op = instr[0] + var src_type = null + if (op == "access") { + slot_types[text(instr[1])] = access_value_type(instr[2]) + } else if (op == "int") { + slot_types[text(instr[1])] = T_INT + } else if (op == "true" || op == "false") { + slot_types[text(instr[1])] = T_BOOL + } else if (op == "null") { + slot_types[text(instr[1])] = T_NULL + } else if (op == "move") { + src_type = slot_types[text(instr[2])] + slot_types[text(instr[1])] = src_type != null ? src_type : T_UNKNOWN + } else if (int_result_ops[op] == true) { + slot_types[text(instr[1])] = T_INT + } else if (float_result_ops[op] == true) { + slot_types[text(instr[1])] = T_FLOAT + } else if (op == "concat") { + slot_types[text(instr[1])] = T_TEXT + } else if (bool_result_ops[op] == true) { + slot_types[text(instr[1])] = T_BOOL + } else if (op == "typeof") { + slot_types[text(instr[1])] = T_TEXT + } else if (op == "array") { + slot_types[text(instr[1])] = T_ARRAY + } else if (op == "record") { + slot_types[text(instr[1])] = T_RECORD + } else if (op == "function") { + slot_types[text(instr[1])] = T_FUNCTION + } else if (op == "invoke") { + slot_types[text(instr[2])] = T_UNKNOWN + } else if (op == "load_field" || op == "load_index" || op == "load_dynamic") { + slot_types[text(instr[1])] = T_UNKNOWN + } else if (op == "pop" || op == "get") { + slot_types[text(instr[1])] = T_UNKNOWN + } else if (op == "length") { + slot_types[text(instr[1])] = T_INT + } + return null +} + +var pad_right = function(s, w) { + var r = s + while (length(r) < w) { + r = r + " " + } + return r +} + +var fmt_val = function(v) { + if (is_null(v)) { + return "null" + } + if (is_number(v)) { + return text(v) + } + if (is_text(v)) { + return `"${v}"` + } + if (is_object(v)) { + return json.encode(v) + } + if (is_logical(v)) { + return v ? "true" : "false" + } + return text(v) +} + +// Build type annotation string for an instruction +var type_annotation = function(slot_types, instr) { + var n = length(instr) + var parts = [] + var j = 1 + var v = null + var t = null + while (j < n - 2) { + v = instr[j] + if (is_number(v)) { + t = slot_types[text(v)] + if (t != null && t != T_UNKNOWN) { + push(parts, `s${text(v)}:${t}`) + } + } + j = j + 1 + } + if (length(parts) == 0) { + return "" + } + return text(parts, " ") +} + +var dump_function_typed = function(func, name) { + var nr_args = func.nr_args != null ? func.nr_args : 0 + var nr_slots = func.nr_slots != null ? func.nr_slots : 0 + var instrs = func.instructions + var slot_types = {} + var i = 0 + var pc = 0 + var instr = null + var op = null + var n = 0 + var annotation = null + var operand_parts = null + var j = 0 + var operands = null + var pc_str = null + var op_str = null + var line = null + print(`\n=== ${name} (args=${text(nr_args)}, slots=${text(nr_slots)}) ===`) + if (instrs == null || length(instrs) == 0) { + print(" (empty)") + return null + } + while (i < length(instrs)) { + instr = instrs[i] + if (is_text(instr)) { + if (starts_with(instr, "_nop_")) { + i = i + 1 + continue + } + slot_types = {} + print(`${instr}:`) + } else if (is_array(instr)) { + op = instr[0] + n = length(instr) + annotation = type_annotation(slot_types, instr) + operand_parts = [] + j = 1 + while (j < n - 2) { + push(operand_parts, fmt_val(instr[j])) + j = j + 1 + } + operands = text(operand_parts, ", ") + pc_str = pad_right(text(pc), 5) + op_str = pad_right(op, 14) + line = pad_right(` ${pc_str} ${op_str} ${operands}`, 50) + if (length(annotation) > 0) { + print(`${line} ; ${annotation}`) + } else { + print(line) + } + track_types(slot_types, instr) + pc = pc + 1 + } + i = i + 1 + } + return null +} + +var main_name = null +var fi = 0 +var func = null +var fname = null + +// Dump main +if (optimized.main != null) { + main_name = optimized.name != null ? optimized.name : "
" + dump_function_typed(optimized.main, main_name) +} + +// Dump sub-functions +if (optimized.functions != null) { + fi = 0 + while (fi < length(optimized.functions)) { + func = optimized.functions[fi] + fname = func.name != null ? func.name : `` + dump_function_typed(func, `[${text(fi)}] ${fname}`) + fi = fi + 1 + } +} diff --git a/fold.mach b/fold.mach index f637ed3b357c98fe2c2c66d993fe0a132519fde2..b6dd8fb13d0835fd8b3fab37fb5d80f972f2187a 100644 GIT binary patch delta 26040 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 delta 28750 zcmd6wcYIVwmhVs1?c2&(1d#=e`VvLXNf?_f31|u2k~$bfXh5Lb27|F_f^ER|;Lx@k zFqmwDvt?UO;~Zve*m-Yv=b86A)klD5*!TIoKiK#FxU}x~)V+1; z)TwYQvG3)q)9148UZk#19-UC$%}Yd@|A{YMx4t=U{#?`Cvf}!c$tO?tOlS{8%bKIh z%pdDF#8>_SAl65bZTF$_zKUA=^;OzO*+ zHQ8Q2RXP^g#ST>t@Q__PfGP*tWM>Ve%0XVTtwB^dID_o&gQ;>zCfSM1Ayhdui|m}C zw7wEA>{LnXhvB#PFsdA$O?KDeR5>Dt?7|ULIWm`QJ(6?}q^KuR<)}Qedyb;Y(fMTe z7)`neY)k>!MPo?!!rx;H$?i3lD#sO(-EAD{d_0$ns|>R7#boD?r-aVK&4d!Nb0<*c z#8R@$CQ{|3PGsjzqRPpg$?iOvTBmj+Jq;F^O4H&~r%tKAu@ z%AKL7$7ftctChY=!LG4ulvO?p7Mwjx={X2Do94K))iv?iGpT8whn#ty1U1c{NzQyt zbLM(xRzR6hT0kM;wahb!!otJC>zON}8<1Vj+%k$)E32iZ+S9rqPw9n-YymBF7pR)} zf?86G6gAZ$!a7Y81D-_{Ie4GBPk1O?zlfZAO*2_wLjeg`#rG0{?FmrD2j|ZZU5u>h zvY2!Mky?VkJxeHdEmGNlR5ms!-Gqo6smX0r*Tx%z)D%XfxSAqCaw14%$P+Y)6dp>5 zpq2%kN)d#G*E8=(WoQP)qDbX+QIB149mSRwc&ueajm=A!`I{A0Xd+KDQAKZ}rsYe? zS&oQTEF))yrr8KnfqV}M4+&4yu%HAHiy$n5I_AiZsPL$869E*B2#*MF;P6n?f&xx+ zCY7(UsWrAr>(#JGj8?lb)y0kJf_Q8tRUpgM8e~Ze^51Deo~-q(F?rGgbKwfFTSLw| zWC?T562moB@%@D?SxXg1&!1ndtS+ssok_chsFmD!>v|f5Fgi{&2$xML1-QIaa+%9E zFxk_yAPc3BwooYzOWxo)*IYn9w66G-{D$3}fJ@QOtz!Cxl}o?0GR^fXt26xy@&7km z$vW>NJu~QY>%Y8`MH!Qmy)ts!sxww+sAsrVRo#+5$UotgdUQ*{JiXgW_4$*!y=_t9 zj*P@qQq{1$RZX!PRZza5kXjcmP)k z39n_&WkYyacs=uuvJvP_vBj#OWyxa8mk6qi)`pEp57%oF2T1F~Y{2BlF=yBp~SccY5O zH(pOmH(gK8CS=8Cm<^Z7iW`v?H$j=3kQH038%?wM)Of$X&woD>@&FR@fFuOWB*ZWzBy}G- zDI|nBCq#Hycz}5xd?YG@s0gh4B_+Zm!h`$(Cj@eP-~Hs@*OzF2XKFm4_xle(nFpcF zgQ5(WQN}PRb8tU72cZmeRz`UEU{P8SU;&%;L7nV*UzY^G3jQpQ1zE~bAK<7DkbP($ z`41ubhq_SXVf~Q*Frq(#XO2kpU?zIQ5dG1I$T^DWnRE2Q!@>j1Id4AzBs?rU z5nuspB!Z|2tP`S;@QCmrhi8Q#w~w75=U55FPN_2A8F-jgpV| z+|@R`*L@ky#ng+g_?67B@F#~?{Le%&3iFk}{M4EJ)JLv-{K}QQ(_hrK-yh6W6HN1$ zne065n!HQCCFUz`{vK@m_hCIfiS87uRCf9B3~C)QT%pHK?g$#`j!>2H5yME0LicRU zFmlFdnm2mbD9-MXxrcv@9YxMqO$(WGT`N2+dGAl*Rh!&C z`qnl*W}K%}PYTlCUCF5vW+!VWWVY>|P*70N8E?8I9mxl0e^0%W+%TtKq8y#%*4!MW z@$2SNj+?7gJU54$a#2O+qP@t=Atw**MZT3|(jYt}yp}nqL3mhrJ#$HelYh)^$x)VV z=TI!iR<;+BPEIyI zX(zkRe;2Z!%s-xK$MSL%5c|LrH*QB;6d3R)RMgcS zC6*`!v)UeG<4)!H1Z>4C`BTu%qg*#n<;0OUO~}))=c`BZHO(*PE4azmG{2ay;1}|B z0wCYO$7Wl1&_BAaea{;mmmh=dj;|Jro9w52nWlh&#p zN$TiaH6vLa9h@knW9Zvo>FYQ?3-~&L`hc&K_?9qN+Yh6k6*iaB2M}K2tL;DCt8KN} zR6n_?t$#!p{N_yyiql}UIo2Z(kgeQYL2g5PED&}sMRpkn&srILDd(tmK#F}4+*bj&V~{m7GBRh zZ77GF7}|-ouvE)hE4Hr1^0mTPZmZ%CSJ$Pu>#B8ecYX4mvTO3+OB+jXLKVM>lIOSW zYTL2>ZX1p8@6jw?;j67-m!%NZpApp+zLKYQZ&x3&j~A5D*BhqlJ^z~6h+0&k_s@e% z8h^9fmuI3n%gRK>4zp!Zwwr}!Dk}rknJv{>M!K2G!5|$swZcPrXB5$F;2%cN)C8tn;g?75cy;4zig26r+1~X%YEL(cSE1QDbLsCx2%|-38&hNYr2^ zYQqq9*G}YgMbykWYT;qw0p=XF@F?>H9>DNJy3~juA`b-l0agZbyRExiiaiL9@NwAp~~Vtx>3a+(WLdVsj;`Wm%lfZ?E_`|h_YZtS;L@gc`tIxH6^N9 zz}ku+EP?=Y)>e2_xP|d9Q^bWwgaJAJ%XIk`0^bI z&R@O~u!`>`BHJ^PD!7iocOQ+(pvJM@G5)bI_c)k)oR}NTnA8nkt)_g z(WzO~IL$lNKMjgjLD8zTqKR36MpFZ!>GY}OOoyh-SySO*;Q{8XsPL$8Ynmu3JR&^E z;aO40ooTZub`=!88j4RSh&a^Q0YP102G5$ zHq|YZ0kHH4^lXHwC`%xZMG%sq=^7Sr%7u3fS=TY=lnakac#Kx3ON8)<@CFW#lv|KH zfh>%eSvkIIp?vUKeW8uU=-Fa72&u^$_Wn%uVK#02@eaeW6sJ6j|%tj z`%#NVgh#*=96j4K~x0R4l$GPi0~jkz)C@G zZ{0!8R+Q;mq10`+dVIU#lzVn7eLEa)58dwWQMbkS>@taq-C-5_z5)5(Zzz2iQTD+bZ(iivY=cmA(%Fl60S&RCmXd_fYJ9tJs% ze|+Bq6gvQqKM0RMbWrPuAUi}4xrfvN_Yge((1Yj?;N^!gB74Mp*nb4pItq_JD%JvH zYb8Pk!d%A=V>}DyVgZ{=cvyIVIp?A9sBr6uSW9?Bc#y-hwIH{TA0hwozC$hOiH|Z_+P4$}lCQSO~>tvc@AI$nThMM2; zzU_YpW_=fCeOJs1W)wFJX8qRNcTo5zR#q5kZh2V6#H* zyrW5f8{wdjdJnzV5AgBy0eY|R+wYmqtGP$#_1t^poI~f8Id@(qTovErT{qx)+kT%a z?*8j}{UJVXaV3A2DsC<$rLOqZHhJHVRiczK)s?@pR8PuMez|h+D_2|Mz`tkNuacry zliN>}w>@;?Gb`H*yQD{U+T7ERspP=31N2orAGlvV)b^*dKg?Cnwtdo`)ZRjvw4{6T z%h$HI{r1IG+KVw9DkW^WoBfmBU&~!y zUh1dTPNhnh!rMAgsoP1F#5`*4~x6=uqK%KKn*i%BnL&9sB!^OkG!@}#C zOXfPAldZ4Cv%iIJla=^jFL79##6(i?NIMI26(y?Tzef+uz#*=d(vmD+@}}2T8kKTb zr2$5z$^Q>j!j!eB6iW_%bA2|Zkt-fW+fy>|{}(ISoN+bDqi^4qOrY=&PJZ>)_8iVP ze-_%#k|EG@dx4#WWkV%dw%U@9fH-sbg8zRNITDHOrow zT>ag5qdm3lz+d0@sOhQYNjYVWMoZ(*d=S+ClaJ)UBg z>JziAsi}z>Dv9vc)b@e4N=S&i5%7W_1wqgDf5}i!YgL*$maQI96H|Nh)m@$PCh_oL zqt~+iURW;!!?_tc^_LvHrz*8ESG|RR6Z6!=Su^svX~UH|o2`y`uC{DSRp+QXhC8fC zMY)Zt(`ze@x4B-jU9Ym@UJHYh>T++7_xix%$9UXwjcs}CV%v;g+C>&#S3E8CW`TOJ za2nrM+z5}tY9R7VOtloMU1ji4PqC=&5w$T?1hs$qu!?)py|IcXrtT6Z+;0OqB^{0pEu4QdR)3wrldx7h;`$AAk#{OO420y?QFz0|I}1z0M$ z(5mPUQ(IN-Ks!5QoH?eh_|=|0S`{eFDz8UeSNdwjz+qd)#pC-BQ>G@ z{C(=EPD~<&-iVEbY_SaGEziXCJI@PXegN|VnV1*IF!KVLDD;`=-C&Nu$wKcY+e*(1 z2oDLbWzM}D;bGzR%sYBF+2~auu9nOU%a^kDsg?O?FnRSM*B)eLriScSJ29t?!k?9T zZolf4mt|cPXQ#zW)djIPi|dK3)IaZ6r|cYGhAKU4-cvX2~5IyRY`dUY>=6uG}7T_QihwUyzxx0u~QR% zolGo2$nr}1`5xa5*|1ACmLM=U=}+^p@FmPUy6zTwiWcHRygsigYt8U#o|AD?IS;9# z;*zx1UZb^_6-qsHkhS)vwSN7eI+fPc``@D}=AkX+RnTxv28L}dmD`&7=#Ux;bAEM5 z^}~w;oduc(Jg6?a7j&5{q;6V%C+WiVmyY$f*N|O{OAbRtyaQS)EeH>DJN8~>@ur@J0dLp@}%mOnsrj0Q{7X0PatS_gR;Au1RzLWD*rT8 z&b!19d!(u!R(GhLsjtxBba*Sj=xg4Z%b~VsI=oclvajj&wE(@1YI(gciKmYV(B5)J z{YbAZrYe2quj#rkP1l1{M<0bDo_th!+FyQD{n_f&m+Bz-n=AFylWKnZe>|y*6#_IM zz~5Y{qNmX)_Ier>RPbr_n;f+!S+%L+l3FQQy{B7h$17@bwnkG=yq%y+>a|x?_e43S zCtGu})2l9Wu<9ZQ)08<`)Rd3nmXGSF07a<))lptXmigEc9ui*5oQtFIu<&~39o13Z zpB4HH8NOmTc1f`|A9f}9uq#oCLbn9t2qoAFfQdxi37w$M9+^KxZ{ouIp-1KqnV~MY zFnBDsRNY_MqA~J|bSzDezbkNaOWf(i?4hwY0*g?09 zGBb8y?h#3kGIDxg?0`A?Ss@8m#rGW*PzL50&)^#c#*X#$DC&jb;od!EuCeFExyA&b z86D}v5Gj*6!fNK6GT|5J8o@bb!vB7*G5wy4bBzek3B#C@-M2US`}V^;BNXysXt;kr zUy;8*hHEPNky9bVHK}QS-KDG=G84ZMA<=#xIetxn)Ov^$7P>~9>k$!0L>%PDI6BDf zzWvGRdppG(k0&<3v2E`F(&%|L4)PB4qZZ-OOwS;^hljfcqcR^1ZyPd@oFN$QLKtHf z;UVEQ%u6s79u`4Z1a&N6y9kd8HxaO+!Xv^PI6M@^z87)^MF>-%IhX>~mrQ|bcbN9_ zG^lM2B|QR)kF-YkN3!A=ipI=lTJuq8wlVeDB-5d@5y)sRJS4n^IcKQwj_K1n=B&8z zsDwA~XT^m_gg0>bX{lgwM5{fS)7k$!uGm#@yBU~Uz51#d{;T12*IY%;HR5$( zMp46{=*$_I?w$!vS-@r!L3rj2!voA&b>UIr*45&e!Xv_i9G(*cxjpM@a%TA{Hrr$K z_MgVNv*-BdibLWnz&PZ*#BAONgl#}`%r>Ce2xK&zm*yeiHOyH-;bGx*%vnLptA%GSz^v^;m^!_8NV^NPSs-OwHI$yjwJtM> z3&%9O7#5jb46_3kCUJQVH_b23;evAlF6?4Rhfmb;1Dpa8{QV?u`b8HfaS@(V5I_nR z2gq3r$6Nx(ycQ-7F1gkpgkv@=A*TV3iF>1rxkr9CUQ13RvYR<8)3Br~0;1j#L4XCU zOv94Y>;JC0B=|iZiikMKV$R+m$BjKri{XQqnuQNGUGTq!%g&0~2xIgU9ui)|ob^kHpkpgW9Sc}L;Zb?O!x31D;#G99z0;E=;L0W|dX%!lzl^H9hn-<9c7%8>_tG3W0L10=W z30TGVh{TL$XJCKRAOF|+K{l2rtwxt|b?OiAs2-~dDW$LcwNLj-h2F*B#|`hQFRb?F z_b~*L>i(g6yk{?ZT>qC>>cbCJ6NagHXOA~k{gLW6Ff}OF@EYdq zQ^Lc->zK1k36Bal?`M}19ueNqJ%I<Cnjl|mA(itjPw zoc1-#p^Ag&&&LKSj~)#33>h@oKSWC05V6kCLF5dDbt(swQwi%JjIoaJknkGjY#rfY z;dRW}I>MvisZ+mG`HA#}Kd8rhV(=4w;#%Pd45l}Z%BAZcr9}--@?Pf>zRx5I^}-V;>*dmJwBrT=(bmQ`uib7 zcNP2BU{upR@Z$plSCfN2t^@ByAmahTL&9sAvjYeZ3$J6&4j?=#+`OO5w(yAX1`dz< zh4^dPsrWs$49NA^s-r`#F4Lh_f778>(xFcCiydlkR&a2dU+hnVvx34+e>#Dl`Na-( z`hklbYCOO$ItVSWDU)dZE0v{&p$rYL9OfU6Y#LEX&Iq*rxHr}^_b4tSvFl_cT7TxO zjPS7V0COmlh>9R80t*WkO?eR>5gz0Rpo|A{d+2boM-4?M9X-C$80j8^WuGWd|5t@N zU8b@57Yh@wM4`4vjU{^m_Sj5-k`tliByZ}ce^K`&>q#tUmvN7Ukd zHTl)%edZqTTTo5T0w~9v-zVX!`2IqRmR~~^uYPr2EyRlg1z4nr7cDASXkKLQ@glRR z5ierSFOqOoeBYs1!6K^I{ndFM_^hmlb7s_=YLFL+S1!hR4cUvSatY3Bu$K@PK&nJ6 zcx`5DBPMjvnUxLv!FXc>`9j!<6AopyMj^WnvM62WMpZZ-jnMj~c(GneJi@Fo{#LmR z2R~#jqsnF+{E*p9K1^iARxHnKU4>ET7@l24F?W?(5nr{Ee5)Z_vpTD_1+sOh@!S?# z=eDRd@s_nT6if2#y!E77@mtV}V+`(>85}r8dJUZ^Y_6ERdVCslcqZ z3keSiuVv2Fvhc9*`b`N4#B|Q4tH`$n5#F>VyXEGa3R<@6n=RCcjoY@$Cfco+Y@*#N zn`oJ#f{{(J)d*|6e|wr=+(Zk`-Y@*ZCfdX{@qQ8TF52`aT08*7Jdiuva>%z6irum^ zyXDqf3d(ooQ0wkpTJM2rcheqsx5{&O>s#ZyZ%cROZ-)=v3Cr9GAG)L9cH=|l9zOJq z+sXL`e26)GXkbVJRx!BXM0c1I27G&!TD>9q0`350pB5AfhBy3w|thSD{S zQXl?a?M(gf_ZVVd@TIy%HJ8v|@R@mqul8R5swQi-$GC6-@2)%W_dDz6^3J;Nd3jSE zuSUnXM=Ydr%OiQz8jW1qI)viUFg2kyaF)S+n!`AX0hRJn%ZyxvgolLJGG~t#9u{8D zyu+iHVvcRO%57P(9H(2XQrS3JMe*o@oUF2fPgO~usDen%fhv|9sKWQikqZZ^fOC$t zq{CIM#eGK(TR2dqV^`k#d}?gf>;0`5Kg6PQ$CdFzuyl=YAZq;hdUE3EQbJ$~f$*^K z0CO$`!lS}1G;O8~2#*L4a(F1@f!t}uo}KI2($`aL11x<5EWPQ5gwj}D>TaUV?k2S% zzG)*hZ9!_bz|=QwG>1pbxzXBaDi7fy;kC@!)WXBU>zQ|$`bO;8xf!P3db1TvY_)yc zVeK8;mEMUschF9EM{2-OJ@>+nyxs8H-IOZ-t4gGX{Z-|*ANi|l^sX(XuGW>m%B-GL zX8BVKEZr$}ouz+;t*E^b?-jmM_jvSn^%E{E1sIjNbpLp2`ybWl)LL7=r%t8DdG)Ep zh3&@qFkl|#W4p03+l>qHX@{$+2;0apo;0UGwi^o%39n_&nI=3eyq-W|X^^Gtu$WSFI&~sn8Aj~8l_`zEA-5ZKce`OjXSc2t>!B@QFJ=GD zXLS$$td5myj}Iq{wc;P$AJ6%yzw1-wabI7mzz`Xs$Ts@z3cnvINjOlzk)!~cq!@;z z45%=pN!83bDZ<0T1I#%o!lS}1zm!Jd5#d1&&xwQF#)y=EU|)1qagJHzV0(~%Ftiy0 zWrm0{U`83kpp5xCgJRH9Z46+_Ghd+t)U@DICz&GzSsSK|?;CK1O5KZ&4sd2tN&p#jLu7;(m#oS=V+=jv2HS@@+fp0Kpa|;g(4=`tQ3y%uN zMt0erBZ7zsg8TrRdp^uPAAV7*b9@Vt;zbLU#zcv`hyv~+RU2QlfGVa#(K>8stGDa? z^-y#%6vadaPn6CAGm07pMVHi(gAc`O=B(&q&i}s9F1##XNK$D~_}FHqC1UAb*NwM(Inl!Ir&M6ii7M`eM z0jF35Q4x4J0yt$vctm&uhewJn$ekFnX06Wmt%Kt0*C~x=-d#_v?s~O0zP=^h!~8x1 zyVw;Mw_Sf6*>gQCe!XN*+)lVgTLY0l8(i!UL;fJJ(N=g^cz`)8D?BRPii@(sBf^6m zp0fvXdt;pZ8~bA1q>vgn**Ew%L7B~*|C>b{K%>lNW>DtF8_f52HFGwd@UZXzb5=%p zRJet0{l;>_Bf^6mo|S>z-na=n@CvZ!YzrLbW;o2&n-x!xyIU#YZdF_2TW_M+HZ(Fj zVA`EKl)eSBopg)4Q*Ddy+)fp@;Z3*VT(aBjTm82oCA*;XE=dTONr+)c$nIOo*$t~Q z=Y$9kgC|%JU;(E@1W|dwx=m6dJR&^E;W;IcJGbql*dATX8`B!^*mJx84sp;s@N93a zQMhvtzS&U=$~XFKgfYscd4fVBs9^zXCl7Rd)Yma*<%CBiyoV!T2NfO>-oW9ZoCUda z2lg87)y1*9_A0s?&F(#S-R-{z*1GpDa_(ho!Q`_5jYbB-T*mE@^ctm)R!?U#@x9_`${P$rU+5J!o8$c+LLi4-tfs}tAwA%jwIr}9K!HiOd zL8${Nat=T#=B$+Pu?uJlRBPtZyCggP2Oam33S&zz#zBf8Z07-Ww>rt}k#Jx)bWxR0wx;*UQ{u_xi}Pb)jMevU3p zRD6J*=(E@#_niH#|2f#E9sb=ewgEG?F$}hO{#k5CgKe0zZG?w~2bi;Mghz#2&xvh> zM}!BTvlGvn976yb+tB78ciC%q)f7@k0vR2~TO1MEHsV84KUZ7-nGeFe3~YcS;NuPOZo4EZ{};l8e3 ziNF3TRp6*RdJ`wAy=A}Ye+$aK4Q1aJWx1X#e@iXbZ7 zdP}qw9uXeo@T@H4&RbCQU1aLFQH8ztZKdCbqVLiB?tALp_L>{cz`)8Dm*IOIwy(>j|dNPcvcj0=iCU2 zeXPs$C#b?c{rD6AryX~oV$Dyu8Qvwftf?_{D3NM!H&Hj-OpWb-xTASmG%KYbnK+sl4*#`P8~%xza093RciccZFIOU(rlWF?7~r@U7L& z=*ZzKVU^X)z7i515?;$3z7iH57GBR>a?)9afu%JnuVw8T3@oivS(odSDHra74w!R2 z+$Cz2qd?7F;M0i+ufH{{C;Zflh9MqH$;Su3M4iAMqkUKZvdkp(*Z0kmfZGok4 zhNZXOjDaOI?w9tbny|5-=QWyk++?OB=4`WWGNu+D5?;%kO)WeuyqX*`|nfw0VMQ(dceJ3-5b9@NwE};gWM0M$&Ighz#YI0CL^g-3)paCj(b zLGGMECHp9peC$yx_V{BNz9*5LSU;|xhGm|jr`@O2}jQr8p!E1E8Jlgsk#M zSLwnke_K}hGecE-VU<5P7n3e&esPsQI2RM)f4|B<9sc4WVF(Y!%pqZAXs!Ka=nZ$n zLip}BmhYkB?|}z;NW~9k3aw#KMpoHXGiPOlcdXV6FlS|icdXXq#dxO73h!907wpat zur>%_mvtwn44uqg7;x>QvQp1A~T%(A*ULp%da<_Ql~rg<%M&OG5^;q}ZrGH(c42CRW^ z89vPR#6}GFq}DmQYeHc)T+?_&gS9Xd$9cw@O2gcv(vXGcGnsRxA>pd{US4Z^#--bV z^O|TP4h5TJPxMcM^(Vvnlg0XA#`=cA`co#F8NKRBcGE;-ei4L45a0*c{KBKctw~~j z;Su3M4$szy+$?IJsxy66Dl7Tq&7BgTK{2yX-Ij&wQ0&4&bz2syGlOC?XUIBraCVDp z(){8&b#T^8_}{NnPlvy_PTii7URiK86uTM?&MYW42X*+|IqK4LzS3uW>1>?wm5DRH z)TL*9rO)@$US9yRx`5L4aFRNzck9%`c-zU9;V_R#Q4Et_XUkDrFyT`18!)5nQfA1WWl=e5 z3!Ie|e(|U+a8_2hIch7h3?H%AiMArRc+?giV84OfZoZEE&3%cM$j_!vogZN!UN2qOd=|Rs0geTqKxo}@E||H%0O;6V+}a|cZgUF z{;~%CvUZKS^lUFa*DJOTBb=?U?BAc}Nfl+V>hJ+@gZ7#hE|ZJto8=v_y!ERZPJB2b=r92 zrpR8MXi#UCZ7S=YT z=0lulU@>Aw{~80L7*V@f7sfDNiT`fq%B~~YW->5Ak^jRwB75gH^6$im+AUD()>{8I5rFeYPUnFJ8t*jbgrz+p3aqlCDV87LLAPOb-Ba2`13xNxL+6H zgs!a1pU{QTxPy=#I;bu^p^H!FiXDdE9);f?JF4_?)CkAuxO+?;jvqTh6=7(40w;H! zwB@iYINQTk+HJv%r5Le_6 z`Xu>Jqc%8$le^B^XZ&Z8ZI2-QBcjY%J8{NnV<7VF(K9&m9{GmAMj7E@;Q{8XjPR&% z3uBR{A{8DH9^~+>4CMCdv*escW%?LugC}5BbDTbZMW)ZwH^=E$6e0A}7@2IdpZ2#w z+h?HdGome+QPwah`|Q)^E1{Y>TTXabcz`)8D?BRPY7=FdC!RqiAc7!2z}g~!(}u6W z=a9$GBadHrUg;O1=nM3s`+|Bd{z5y&UecX?--PUyZz}yNWUtVx?kno0_$x1ydJUiVgZ@q!zsPKvNF7m(WTW^@Nr{=t4y}{asL=X~Q z%N(8@79JK}&m79)8y%yJXq3N=UeSBswqozUm#Hzn+j#DM4E#yWbq*=+jiI&=-zVoo zw4*XkH~ZZC2^k1X3pxe@Yw)l!sXWjz5Lm~YO)9)&Adm<8O#Tb+7zk|O@KBNm3Y~NK z3j7#Ke)6#u`}C7c-#@|!K8yUL(inSlKcjzgKU1H^Kl_LDXW)0xq5B?8^gVRwzH5EQ zbm+`IYV?2p4mtmfuR!KDEGFTq_+BhxTi;E81#V3}hyQRV0k``xGV`a%u%G=@>7OIU zpV80VpQ#_mfA*8~VCgR~So%x*7ye(u>wX2#_?37anDIKp;B~+L1v$S)5n;|=Cp;`X zz?@AaJjy(Q2drO;jYJTU2ZH4xA}oSB7O-|Ahzj>`1n{zm@QCmR4$m0~x$^}w@b?%i z{SsrPU;dta{|amV;a`>hBdqxc`lI^?^=14I|B~(y!7J6Dkca<<54V5QGic(Uy?-*9 zXaF+tFMlHEFUUmZoQdgxRK@olndtp9RX7+s{U7*@{~weJSL>armTH}u`dPK^gJINr zFpPSIulBh$8V8?srhOPjz0%iy>|x$-RmzozU%A@9u|WSYGtq_Gtt)>$Zxzw=_(n`$ hL+~qC`?;Y0MBBf|VD9fzPc&g2)oV@KbK##Q{~MNj&zArI diff --git a/internal/bootstrap.mach b/internal/bootstrap.mach index f025bb52d3b9485c1f9c985c139e2f8ff049809a..7bd676638686d2c148d402823f3e00ad5b9bda0e 100644 GIT binary patch delta 3992 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 XDW=6bGHc~9AGxRE9X3)|`HJ>0jdFU| diff --git a/internal/engine.cm b/internal/engine.cm index 011fdbbc..86f6f255 100644 --- a/internal/engine.cm +++ b/internal/engine.cm @@ -818,6 +818,10 @@ function enet_check() actor_mod.setname(_cell.args.program) var prog = _cell.args.program +if (ends_with(prog, '.cm')) { + os.print(`error: ${prog} is a module (.cm), not an actor (.ce). Run it with: cell --core ${prog}\n`) + os.exit(1) +} if (ends_with(prog, '.ce')) prog = text(prog, 0, -3) var package = use_core('package') diff --git a/internal/engine.mach b/internal/engine.mach index 8fc4257b094193616740ddb51794835d6620fc37..a4b2dbbb4300afe6a0de0de274f78babdde8640a 100644 GIT binary patch delta 6935 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 DhHb&G diff --git a/mcode.cm b/mcode.cm index 5f6df508..8439006d 100644 --- a/mcode.cm +++ b/mcode.cm @@ -1428,6 +1428,52 @@ var mcode = function(ast) { return d } + // Tier 1 intrinsic inlining: emit direct opcodes instead of frame/invoke + if (callee_kind == "name" && callee.intrinsic == true) { + fname = callee.name + nargs = args_list != null ? length(args_list) : 0 + // 1-arg type check intrinsics → direct opcode + if (nargs == 1) { + if (fname == "is_array" || fname == "is_function" || + fname == "is_object" || fname == "is_stone" || + fname == "is_integer" || fname == "is_text" || + fname == "is_number" || fname == "is_logical" || + fname == "is_null" || fname == "length") { + a0 = gen_expr(args_list[0], -1) + d = alloc_slot() + if (fname == "is_array") { + emit_2("is_array", d, a0) + } else if (fname == "is_function") { + emit_2("is_func", d, a0) + } else if (fname == "is_object") { + emit_2("is_record", d, a0) + } else if (fname == "is_stone") { + emit_2("is_stone", d, a0) + } else if (fname == "is_integer") { + emit_2("is_int", d, a0) + } else if (fname == "is_text") { + emit_2("is_text", d, a0) + } else if (fname == "is_number") { + emit_2("is_num", d, a0) + } else if (fname == "is_logical") { + emit_2("is_bool", d, a0) + } else if (fname == "is_null") { + emit_2("is_null", d, a0) + } else if (fname == "length") { + emit_2("length", d, a0) + } + return d + } + } + // 2-arg push: push(arr, val) → direct opcode + if (nargs == 2 && fname == "push") { + a0 = gen_expr(args_list[0], -1) + a1 = gen_expr(args_list[1], -1) + emit_2("push", a0, a1) + return a1 + } + } + // Collect arg slots arg_slots = [] _i = 0 diff --git a/mcode.mach b/mcode.mach index 3584d85c94ee3c218fe31910a058894be6723ebd..71ef2a6b106ab97991d70bc846eb03372c504511 100644 GIT binary patch literal 156295 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 OuW$!_00B^m_kRFco=@xm literal 150904 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≠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 P&{kOG0*N*XE&u-m|8Z$X diff --git a/qbe_emit.mach b/qbe_emit.mach index fb19e2c4fed4c1a1cb9b1e71cfcbc8de196392cc..6b6ee4db37c9788c69f094778842a6681f2a2831 100644 GIT binary patch delta 4556 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 delta 5369 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 diff --git a/source/mach.c b/source/mach.c index 7edc15ff..679ef71f 100644 --- a/source/mach.c +++ b/source/mach.c @@ -1658,6 +1658,24 @@ JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code, case MACH_IS_NULL: frame->slots[a] = JS_NewBool(ctx, JS_IsNull(frame->slots[b])); break; + case MACH_IS_ARRAY: + frame->slots[a] = JS_NewBool(ctx, JS_IsArray(frame->slots[b])); + break; + case MACH_IS_FUNC: + frame->slots[a] = JS_NewBool(ctx, JS_IsFunction(frame->slots[b])); + break; + case MACH_IS_RECORD: + frame->slots[a] = JS_NewBool(ctx, JS_IsRecord(frame->slots[b])); + break; + case MACH_IS_STONE: + frame->slots[a] = JS_NewBool(ctx, JS_IsStone(frame->slots[b])); + break; + case MACH_LENGTH: { + JSValue res = JS_CellLength(ctx, frame->slots[b]); + frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val); + frame->slots[a] = res; + break; + } case MACH_TYPEOF: { JSValue val = frame->slots[b]; const char *tname = "unknown"; @@ -2552,8 +2570,13 @@ static MachCode *mcode_lower_func(cJSON *fobj, const char *filename) { else if (strcmp(op, "is_num") == 0) { AB2(MACH_IS_NUM); } else if (strcmp(op, "is_text") == 0) { AB2(MACH_IS_TEXT); } else if (strcmp(op, "is_bool") == 0) { AB2(MACH_IS_BOOL); } - else if (strcmp(op, "is_null") == 0) { AB2(MACH_IS_NULL); } - else if (strcmp(op, "typeof") == 0) { AB2(MACH_TYPEOF); } + else if (strcmp(op, "is_null") == 0) { AB2(MACH_IS_NULL); } + else if (strcmp(op, "is_array") == 0) { AB2(MACH_IS_ARRAY); } + else if (strcmp(op, "is_func") == 0) { AB2(MACH_IS_FUNC); } + else if (strcmp(op, "is_record") == 0) { AB2(MACH_IS_RECORD); } + else if (strcmp(op, "is_stone") == 0) { AB2(MACH_IS_STONE); } + else if (strcmp(op, "length") == 0) { AB2(MACH_LENGTH); } + else if (strcmp(op, "typeof") == 0) { AB2(MACH_TYPEOF); } /* Logical */ else if (strcmp(op, "not") == 0) { AB2(MACH_NOT); } else if (strcmp(op, "and") == 0) { ABC3(MACH_AND); } diff --git a/source/quickjs-internal.h b/source/quickjs-internal.h index ed9d9828..f43a2273 100644 --- a/source/quickjs-internal.h +++ b/source/quickjs-internal.h @@ -596,6 +596,13 @@ typedef enum MachOpcode { /* Misc */ MACH_IN, /* R(A) = (R(B) in R(C)) — has property (ABC) */ + /* Extended type checks (AB) */ + MACH_IS_ARRAY, /* R(A) = is_array(R(B)) */ + MACH_IS_FUNC, /* R(A) = is_function(R(B)) */ + MACH_IS_RECORD, /* R(A) = is_object(R(B)) */ + MACH_IS_STONE, /* R(A) = is_stone(R(B)) */ + MACH_LENGTH, /* R(A) = length(R(B)) — array/text/blob length */ + MACH_OP_COUNT } MachOpcode; @@ -724,6 +731,12 @@ static const char *mach_opcode_names[MACH_OP_COUNT] = { [MACH_DISRUPT] = "disrupt", [MACH_SET_VAR] = "set_var", [MACH_IN] = "in", + /* Extended type checks */ + [MACH_IS_ARRAY] = "is_array", + [MACH_IS_FUNC] = "is_func", + [MACH_IS_RECORD] = "is_record", + [MACH_IS_STONE] = "is_stone", + [MACH_LENGTH] = "length", }; /* Compiled register-based code (off-heap, never GC'd). diff --git a/source/quickjs.h b/source/quickjs.h index 054ab737..e6c0f119 100644 --- a/source/quickjs.h +++ b/source/quickjs.h @@ -486,7 +486,7 @@ JS_BOOL JS_IsRecord(JSValue v); JS_BOOL JS_IsFunction(JSValue v); JS_BOOL JS_IsBlob(JSValue v); JS_BOOL JS_IsText(JSValue v); -static JS_BOOL JS_IsStone(JSValue v); +JS_BOOL JS_IsStone(JSValue v); // Fundamental int JS_GetLength (JSContext *ctx, JSValue obj, int64_t *pres); diff --git a/streamline.cm b/streamline.cm index 2606395f..4ccb876f 100644 --- a/streamline.cm +++ b/streamline.cm @@ -1,5 +1,5 @@ // streamline.cm — mcode IR optimizer -// Single forward pass: type inference + strength reduction +// Composed of independent passes, each a separate function. var streamline = function(ir) { // Type constants @@ -10,20 +10,19 @@ var streamline = function(ir) { var T_TEXT = "text" var T_BOOL = "bool" var T_NULL = "null" + var T_ARRAY = "array" + var T_RECORD = "record" + var T_FUNCTION = "function" + var T_BLOB = "blob" - // Integer arithmetic ops that produce integer results var int_result_ops = { add_int: true, sub_int: true, mul_int: true, div_int: true, mod_int: true } - - // Float arithmetic ops that produce float results var float_result_ops = { add_float: true, sub_float: true, mul_float: true, div_float: true, mod_float: true } - - // Comparison ops that produce bool results var bool_result_ops = { eq_int: true, ne_int: true, lt_int: true, gt_int: true, le_int: true, ge_int: true, @@ -35,19 +34,18 @@ var streamline = function(ir) { eq_tol: true, ne_tol: true, not: true, and: true, or: true, is_int: true, is_text: true, is_num: true, - is_bool: true, is_null: true, is_identical: true + is_bool: true, is_null: true, is_identical: true, + is_array: true, is_func: true, is_record: true, is_stone: true } - - // Type check opcodes and what type they verify var type_check_map = { - is_int: T_INT, - is_text: T_TEXT, - is_num: T_NUM, - is_bool: T_BOOL, - is_null: T_NULL + is_int: T_INT, is_text: T_TEXT, is_num: T_NUM, + is_bool: T_BOOL, is_null: T_NULL, + is_array: T_ARRAY, is_func: T_FUNCTION, + is_record: T_RECORD, is_stone: T_RECORD } - // Determine the type of an access literal value + // --- Shared helpers --- + var access_value_type = function(val) { if (is_number(val)) { if (is_integer(val)) { @@ -61,11 +59,9 @@ var streamline = function(ir) { return T_UNKNOWN } - // Update slot_types for an instruction (shared tracking logic) var track_types = function(slot_types, instr) { var op = instr[0] var src_type = null - if (op == "access") { slot_types[text(instr[1])] = access_value_type(instr[2]) } else if (op == "int") { @@ -76,11 +72,7 @@ var streamline = function(ir) { slot_types[text(instr[1])] = T_NULL } else if (op == "move") { src_type = slot_types[text(instr[2])] - if (src_type != null) { - slot_types[text(instr[1])] = src_type - } else { - slot_types[text(instr[1])] = T_UNKNOWN - } + slot_types[text(instr[1])] = src_type != null ? src_type : T_UNKNOWN } else if (int_result_ops[op] == true) { slot_types[text(instr[1])] = T_INT } else if (float_result_ops[op] == true) { @@ -93,8 +85,16 @@ var streamline = function(ir) { slot_types[text(instr[1])] = T_UNKNOWN } else if (op == "invoke") { slot_types[text(instr[2])] = T_UNKNOWN - } else if (op == "pop" || op == "get" || op == "function") { + } else if (op == "pop" || op == "get") { slot_types[text(instr[1])] = T_UNKNOWN + } else if (op == "array") { + slot_types[text(instr[1])] = T_ARRAY + } else if (op == "record") { + slot_types[text(instr[1])] = T_RECORD + } else if (op == "function") { + slot_types[text(instr[1])] = T_FUNCTION + } else if (op == "length") { + slot_types[text(instr[1])] = T_INT } else if (op == "typeof") { slot_types[text(instr[1])] = T_TEXT } else if (op == "neg_int") { @@ -108,7 +108,6 @@ var streamline = function(ir) { return null } - // Check if a slot has a known type (with T_NUM subsumption) var slot_is = function(slot_types, slot, typ) { var known = slot_types[text(slot)] if (known == null) { @@ -123,13 +122,137 @@ var streamline = function(ir) { return false } - // Optimize a single function's instructions - var optimize_function = function(func) { + var merge_backward = function(backward_types, slot, typ) { + var sk = null + var existing = null + if (!is_number(slot)) { + return null + } + sk = text(slot) + existing = backward_types[sk] + if (existing == null) { + backward_types[sk] = typ + } else if (existing != typ && existing != T_UNKNOWN) { + if ((existing == T_INT || existing == T_FLOAT) && typ == T_NUM) { + // Keep more specific + } else if (existing == T_NUM && (typ == T_INT || typ == T_FLOAT)) { + backward_types[sk] = typ + } else if ((existing == T_INT && typ == T_FLOAT) || (existing == T_FLOAT && typ == T_INT)) { + backward_types[sk] = T_NUM + } else { + backward_types[sk] = T_UNKNOWN + } + } + return null + } + + var seed_params = function(slot_types, param_types, nr_args) { + var j = 1 + while (j <= nr_args) { + if (param_types[text(j)] != null) { + slot_types[text(j)] = param_types[text(j)] + } + j = j + 1 + } + return null + } + + // ========================================================= + // Pass: infer_param_types — backward type inference + // Scans typed operators to infer immutable parameter types. + // ========================================================= + var infer_param_types = function(func) { var instructions = func.instructions + var nr_args = func.nr_args != null ? func.nr_args : 0 + var num_instr = 0 + var backward_types = null + var param_types = null + var i = 0 + var j = 0 + var instr = null + var op = null + var bt = null + + if (instructions == null || nr_args == 0) { + return {} + } + + num_instr = length(instructions) + backward_types = {} + i = 0 + while (i < num_instr) { + instr = instructions[i] + if (is_array(instr)) { + op = instr[0] + if (op == "add_int" || op == "sub_int" || op == "mul_int" || + op == "div_int" || op == "mod_int" || + op == "eq_int" || op == "ne_int" || op == "lt_int" || + op == "gt_int" || op == "le_int" || op == "ge_int" || + op == "bitand" || op == "bitor" || op == "bitxor" || + op == "shl" || op == "shr" || op == "ushr") { + merge_backward(backward_types, instr[2], T_INT) + merge_backward(backward_types, instr[3], T_INT) + } else if (op == "neg_int" || op == "bitnot") { + merge_backward(backward_types, instr[2], T_INT) + } else if (op == "add_float" || op == "sub_float" || op == "mul_float" || + op == "div_float" || op == "mod_float" || + op == "eq_float" || op == "ne_float" || op == "lt_float" || + op == "gt_float" || op == "le_float" || op == "ge_float") { + merge_backward(backward_types, instr[2], T_FLOAT) + merge_backward(backward_types, instr[3], T_FLOAT) + } else if (op == "neg_float") { + merge_backward(backward_types, instr[2], T_FLOAT) + } else if (op == "concat" || + op == "eq_text" || op == "ne_text" || op == "lt_text" || + op == "gt_text" || op == "le_text" || op == "ge_text") { + merge_backward(backward_types, instr[2], T_TEXT) + merge_backward(backward_types, instr[3], T_TEXT) + } else if (op == "eq_bool" || op == "ne_bool") { + merge_backward(backward_types, instr[2], T_BOOL) + merge_backward(backward_types, instr[3], T_BOOL) + } else if (op == "not") { + merge_backward(backward_types, instr[2], T_BOOL) + } else if (op == "and" || op == "or") { + merge_backward(backward_types, instr[2], T_BOOL) + merge_backward(backward_types, instr[3], T_BOOL) + } else if (op == "store_index") { + merge_backward(backward_types, instr[1], T_ARRAY) + merge_backward(backward_types, instr[2], T_INT) + } else if (op == "store_field") { + merge_backward(backward_types, instr[1], T_RECORD) + } else if (op == "push") { + merge_backward(backward_types, instr[1], T_ARRAY) + } + } + i = i + 1 + } + + param_types = {} + j = 1 + while (j <= nr_args) { + bt = backward_types[text(j)] + if (bt != null && bt != T_UNKNOWN) { + param_types[text(j)] = bt + } + j = j + 1 + } + return param_types + } + + // ========================================================= + // Pass: eliminate_type_checks — language-level type narrowing + // Eliminates is_/jump pairs when type is known. + // Reduces load_dynamic/store_dynamic to field/index forms. + // ========================================================= + var eliminate_type_checks = function(func, param_types) { + var instructions = func.instructions + var nr_args = func.nr_args != null ? func.nr_args : 0 + var has_params = false var num_instr = 0 var slot_types = null - var nop_counter = 0 + var nc = 0 var i = 0 + var j = 0 var instr = null var op = null var dest = 0 @@ -140,24 +263,34 @@ var streamline = function(ir) { var target_label = null var src_known = null var jlen = 0 - var j = 0 - var peek = null if (instructions == null || length(instructions) == 0) { return null } num_instr = length(instructions) - slot_types = {} + j = 1 + while (j <= nr_args) { + if (param_types[text(j)] != null) { + has_params = true + } + j = j + 1 + } + + slot_types = {} + if (has_params) { + seed_params(slot_types, param_types, nr_args) + } - // Peephole optimization pass: type tracking + strength reduction i = 0 while (i < num_instr) { instr = instructions[i] - // Labels are join points: clear all type info (conservative) if (is_text(instr)) { slot_types = {} + if (has_params) { + seed_params(slot_types, param_types, nr_args) + } i = i + 1 continue } @@ -169,7 +302,7 @@ var streamline = function(ir) { op = instr[0] - // --- Peephole: type-check + jump where we know the type --- + // Type-check + jump elimination if (type_check_map[op] != null && i + 1 < num_instr) { dest = instr[1] src = instr[2] @@ -179,102 +312,84 @@ var streamline = function(ir) { if (is_array(next)) { next_op = next[0] - // Pattern: is_ t, x -> jump_false t, label if (next_op == "jump_false" && next[1] == dest) { target_label = next[2] - if (slot_is(slot_types, src, checked_type)) { - // Known match: check always true, never jumps — eliminate both - nop_counter = nop_counter + 1 - instructions[i] = "_nop_" + text(nop_counter) - nop_counter = nop_counter + 1 - instructions[i + 1] = "_nop_" + text(nop_counter) + nc = nc + 1 + instructions[i] = "_nop_tc_" + text(nc) + nc = nc + 1 + instructions[i + 1] = "_nop_tc_" + text(nc) slot_types[text(dest)] = T_BOOL i = i + 2 continue } - src_known = slot_types[text(src)] if (src_known != null && src_known != T_UNKNOWN && src_known != checked_type) { - // Check for T_NUM subsumption: INT and FLOAT match T_NUM if (checked_type == T_NUM && (src_known == T_INT || src_known == T_FLOAT)) { - // Actually matches — eliminate both - nop_counter = nop_counter + 1 - instructions[i] = "_nop_" + text(nop_counter) - nop_counter = nop_counter + 1 - instructions[i + 1] = "_nop_" + text(nop_counter) + nc = nc + 1 + instructions[i] = "_nop_tc_" + text(nc) + nc = nc + 1 + instructions[i + 1] = "_nop_tc_" + text(nc) slot_types[text(dest)] = T_BOOL i = i + 2 continue } - // Known mismatch: always jumps — nop the check, rewrite jump - nop_counter = nop_counter + 1 - instructions[i] = "_nop_" + text(nop_counter) + nc = nc + 1 + instructions[i] = "_nop_tc_" + text(nc) jlen = length(next) instructions[i + 1] = ["jump", target_label, next[jlen - 2], next[jlen - 1]] slot_types[text(dest)] = T_UNKNOWN i = i + 2 continue } - - // Unknown: can't eliminate, but narrow type on fallthrough slot_types[text(dest)] = T_BOOL slot_types[text(src)] = checked_type i = i + 2 continue } - // Pattern: is_ t, x -> jump_true t, label if (next_op == "jump_true" && next[1] == dest) { target_label = next[2] - if (slot_is(slot_types, src, checked_type)) { - // Known match: always true, always jumps — nop check, rewrite to jump - nop_counter = nop_counter + 1 - instructions[i] = "_nop_" + text(nop_counter) + nc = nc + 1 + instructions[i] = "_nop_tc_" + text(nc) jlen = length(next) instructions[i + 1] = ["jump", target_label, next[jlen - 2], next[jlen - 1]] slot_types[text(dest)] = T_BOOL i = i + 2 continue } - src_known = slot_types[text(src)] if (src_known != null && src_known != T_UNKNOWN && src_known != checked_type) { if (checked_type == T_NUM && (src_known == T_INT || src_known == T_FLOAT)) { - // Actually matches T_NUM — always jumps - nop_counter = nop_counter + 1 - instructions[i] = "_nop_" + text(nop_counter) + nc = nc + 1 + instructions[i] = "_nop_tc_" + text(nc) jlen = length(next) instructions[i + 1] = ["jump", target_label, next[jlen - 2], next[jlen - 1]] slot_types[text(dest)] = T_BOOL i = i + 2 continue } - // Known mismatch: never jumps — eliminate both - nop_counter = nop_counter + 1 - instructions[i] = "_nop_" + text(nop_counter) - nop_counter = nop_counter + 1 - instructions[i + 1] = "_nop_" + text(nop_counter) + nc = nc + 1 + instructions[i] = "_nop_tc_" + text(nc) + nc = nc + 1 + instructions[i + 1] = "_nop_tc_" + text(nc) slot_types[text(dest)] = T_BOOL i = i + 2 continue } - - // Unknown: can't optimize slot_types[text(dest)] = T_BOOL i = i + 2 continue } } - // Standalone type check (no jump following): just track the result slot_types[text(dest)] = T_BOOL i = i + 1 continue } - // --- Strength reduction: load_dynamic / store_dynamic --- + // Dynamic access reduction if (op == "load_dynamic") { if (slot_is(slot_types, instr[3], T_TEXT)) { instr[0] = "load_field" @@ -295,26 +410,361 @@ var streamline = function(ir) { continue } - // --- Standard type tracking --- track_types(slot_types, instr) + i = i + 1 + } + + return null + } + + // ========================================================= + // Pass: simplify_algebra — algebraic identity & comparison + // Tracks known constant values. Rewrites identity ops to + // moves or constants. Folds same-slot comparisons. + // ========================================================= + var simplify_algebra = function(func) { + var instructions = func.instructions + var num_instr = 0 + var slot_values = null + var nc = 0 + var i = 0 + var instr = null + var op = null + var ilen = 0 + var v2 = null + var v3 = null + var sv = null + + if (instructions == null || length(instructions) == 0) { + return null + } + + num_instr = length(instructions) + slot_values = {} + + i = 0 + while (i < num_instr) { + instr = instructions[i] + + if (is_text(instr)) { + slot_values = {} + i = i + 1 + continue + } + if (!is_array(instr)) { + i = i + 1 + continue + } + + op = instr[0] + ilen = length(instr) + + // Track known constant values + if (op == "int") { + slot_values[text(instr[1])] = instr[2] + } else if (op == "access" && is_number(instr[2])) { + slot_values[text(instr[1])] = instr[2] + } else if (op == "true") { + slot_values[text(instr[1])] = true + } else if (op == "false") { + slot_values[text(instr[1])] = false + } else if (op == "move") { + sv = slot_values[text(instr[2])] + if (sv != null) { + slot_values[text(instr[1])] = sv + } else { + slot_values[text(instr[1])] = null + } + } + + // Integer: x+0, x-0 → move x + if (op == "add_int" || op == "sub_int") { + v3 = slot_values[text(instr[3])] + if (v3 == 0) { + instructions[i] = ["move", instr[1], instr[2], instr[ilen - 2], instr[ilen - 1]] + i = i + 1 + continue + } + if (op == "add_int") { + v2 = slot_values[text(instr[2])] + if (v2 == 0) { + instructions[i] = ["move", instr[1], instr[3], instr[ilen - 2], instr[ilen - 1]] + i = i + 1 + continue + } + } + } else if (op == "mul_int") { + v3 = slot_values[text(instr[3])] + v2 = slot_values[text(instr[2])] + if (v3 == 1) { + instructions[i] = ["move", instr[1], instr[2], instr[ilen - 2], instr[ilen - 1]] + i = i + 1 + continue + } + if (v2 == 1) { + instructions[i] = ["move", instr[1], instr[3], instr[ilen - 2], instr[ilen - 1]] + i = i + 1 + continue + } + if (v3 == 0 || v2 == 0) { + instructions[i] = ["int", instr[1], 0, instr[ilen - 2], instr[ilen - 1]] + slot_values[text(instr[1])] = 0 + i = i + 1 + continue + } + } else if (op == "div_int") { + v3 = slot_values[text(instr[3])] + if (v3 == 1) { + instructions[i] = ["move", instr[1], instr[2], instr[ilen - 2], instr[ilen - 1]] + i = i + 1 + continue + } + } + + // Float: x+0, x-0 → move x; x*1, x/1 → move x + // (skip mul_float * 0 — not safe with NaN/Inf) + if (op == "add_float" || op == "sub_float") { + v3 = slot_values[text(instr[3])] + if (v3 == 0) { + instructions[i] = ["move", instr[1], instr[2], instr[ilen - 2], instr[ilen - 1]] + i = i + 1 + continue + } + if (op == "add_float") { + v2 = slot_values[text(instr[2])] + if (v2 == 0) { + instructions[i] = ["move", instr[1], instr[3], instr[ilen - 2], instr[ilen - 1]] + i = i + 1 + continue + } + } + } else if (op == "mul_float") { + v3 = slot_values[text(instr[3])] + v2 = slot_values[text(instr[2])] + if (v3 == 1) { + instructions[i] = ["move", instr[1], instr[2], instr[ilen - 2], instr[ilen - 1]] + i = i + 1 + continue + } + if (v2 == 1) { + instructions[i] = ["move", instr[1], instr[3], instr[ilen - 2], instr[ilen - 1]] + i = i + 1 + continue + } + } else if (op == "div_float") { + v3 = slot_values[text(instr[3])] + if (v3 == 1) { + instructions[i] = ["move", instr[1], instr[2], instr[ilen - 2], instr[ilen - 1]] + i = i + 1 + continue + } + } + + // Same-slot comparisons + if (is_number(instr[2]) && instr[2] == instr[3]) { + if (op == "eq_int" || op == "eq_float" || op == "eq_text" || + op == "eq_bool" || op == "is_identical" || + op == "le_int" || op == "le_float" || op == "le_text" || + op == "ge_int" || op == "ge_float" || op == "ge_text") { + instructions[i] = ["true", instr[1], instr[ilen - 2], instr[ilen - 1]] + slot_values[text(instr[1])] = true + i = i + 1 + continue + } + if (op == "ne_int" || op == "ne_float" || op == "ne_text" || + op == "ne_bool" || + op == "lt_int" || op == "lt_float" || op == "lt_text" || + op == "gt_int" || op == "gt_float" || op == "gt_text") { + instructions[i] = ["false", instr[1], instr[ilen - 2], instr[ilen - 1]] + slot_values[text(instr[1])] = false + i = i + 1 + continue + } + } + + // Clear value tracking for dest-producing ops (not reads-only) + if (op == "invoke") { + slot_values[text(instr[2])] = null + } else if (op != "int" && op != "access" && op != "true" && + op != "false" && op != "move" && op != "null" && + op != "jump" && op != "jump_true" && op != "jump_false" && + op != "jump_not_null" && op != "return" && op != "disrupt" && + op != "store_field" && op != "store_index" && + op != "store_dynamic" && op != "push" && op != "setarg") { + if (is_number(instr[1])) { + slot_values[text(instr[1])] = null + } + } i = i + 1 } - // Second pass: remove dead jumps (jump to the immediately next label) + return null + } + + // ========================================================= + // Pass: simplify_booleans — not+jump fusion, double-not + // ========================================================= + var simplify_booleans = function(func) { + var instructions = func.instructions + var num_instr = 0 + var nc = 0 + var i = 0 + var instr = null + var next = null + var next_op = null + var nlen = 0 + + if (instructions == null || length(instructions) == 0) { + return null + } + + num_instr = length(instructions) + i = 0 + while (i < num_instr) { + instr = instructions[i] + if (!is_array(instr) || instr[0] != "not" || i + 1 >= num_instr) { + i = i + 1 + continue + } + + next = instructions[i + 1] + if (!is_array(next)) { + i = i + 1 + continue + } + + next_op = next[0] + nlen = length(next) + + // not d, x; jump_false d, label → jump_true x, label + if (next_op == "jump_false" && next[1] == instr[1]) { + nc = nc + 1 + instructions[i] = "_nop_bl_" + text(nc) + instructions[i + 1] = ["jump_true", instr[2], next[2], next[nlen - 2], next[nlen - 1]] + i = i + 2 + continue + } + + // not d, x; jump_true d, label → jump_false x, label + if (next_op == "jump_true" && next[1] == instr[1]) { + nc = nc + 1 + instructions[i] = "_nop_bl_" + text(nc) + instructions[i + 1] = ["jump_false", instr[2], next[2], next[nlen - 2], next[nlen - 1]] + i = i + 2 + continue + } + + // not d1, x; not d2, d1 → move d2, x + if (next_op == "not" && next[2] == instr[1]) { + nc = nc + 1 + instructions[i] = "_nop_bl_" + text(nc) + instructions[i + 1] = ["move", next[1], instr[2], next[nlen - 2], next[nlen - 1]] + i = i + 2 + continue + } + + i = i + 1 + } + + return null + } + + // ========================================================= + // Pass: eliminate_moves — move a, a → nop + // ========================================================= + var eliminate_moves = function(func) { + var instructions = func.instructions + var num_instr = 0 + var nc = 0 + var i = 0 + var instr = null + + if (instructions == null || length(instructions) == 0) { + return null + } + + num_instr = length(instructions) + i = 0 + while (i < num_instr) { + instr = instructions[i] + if (is_array(instr) && instr[0] == "move" && instr[1] == instr[2]) { + nc = nc + 1 + instructions[i] = "_nop_mv_" + text(nc) + } + i = i + 1 + } + + return null + } + + // ========================================================= + // Pass: eliminate_unreachable — nop code after return/disrupt + // ========================================================= + var eliminate_unreachable = function(func) { + var instructions = func.instructions + var num_instr = 0 + var nc = 0 + var after_return = false + var i = 0 + var instr = null + + if (instructions == null || length(instructions) == 0) { + return null + } + + num_instr = length(instructions) + i = 0 + while (i < num_instr) { + instr = instructions[i] + if (is_text(instr)) { + if (!starts_with(instr, "_nop_")) { + after_return = false + } + } else if (is_array(instr)) { + if (after_return) { + nc = nc + 1 + instructions[i] = "_nop_ur_" + text(nc) + } else if (instr[0] == "return" || instr[0] == "disrupt") { + after_return = true + } + } + i = i + 1 + } + + return null + } + + // ========================================================= + // Pass: eliminate_dead_jumps — jump to next label → nop + // ========================================================= + var eliminate_dead_jumps = function(func) { + var instructions = func.instructions + var num_instr = 0 + var nc = 0 + var i = 0 + var j = 0 + var instr = null + var target_label = null + var peek = null + + if (instructions == null || length(instructions) == 0) { + return null + } + + num_instr = length(instructions) i = 0 while (i < num_instr) { instr = instructions[i] if (is_array(instr) && instr[0] == "jump") { target_label = instr[1] - // Check if the very next non-nop item is that label j = i + 1 while (j < num_instr) { peek = instructions[j] if (is_text(peek)) { if (peek == target_label) { - nop_counter = nop_counter + 1 - instructions[i] = "_nop_" + text(nop_counter) + nc = nc + 1 + instructions[i] = "_nop_dj_" + text(nc) } break } @@ -330,6 +780,27 @@ var streamline = function(ir) { return null } + // ========================================================= + // Compose all passes + // ========================================================= + var optimize_function = function(func) { + var param_types = null + if (func.instructions == null || length(func.instructions) == 0) { + return null + } + param_types = infer_param_types(func) + eliminate_type_checks(func, param_types) + simplify_algebra(func) + simplify_booleans(func) + eliminate_moves(func) + // NOTE: eliminate_unreachable is disabled because disruption handler + // code is placed after return/disrupt without label boundaries. + // Re-enable once mcode.cm emits labels for handler entry points. + //eliminate_unreachable(func) + eliminate_dead_jumps(func) + return null + } + // Process main function if (ir.main != null) { optimize_function(ir.main) diff --git a/streamline.mach b/streamline.mach index 88a7e3ee1a1fb6144d178c43dde8f77551c37114..26875a75c887c0260bec4ebe6710c666448cdc9f 100644 GIT binary patch literal 97368 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%0DW+ z{*Acel4)fV!0}`l$Qp?gNfS;agUZQdXhxG!7}c=v3w(dFCd@HWOU77}yi&4b{1r8J zt@D8@#>v^+;|OW&xU}+v${!bA#ygeID}PdW8DCVspuEi=-9yR`DSt}Rqg(c0U}=7A zz*kPJh239Klgw49HhyQdRiUj48Ϝf~Pp+LRwu{P5Hd?CxsVn$`_PpD*`uW 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 literal 32631 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 g!3Z{Ogroc}c$63W*9ylt-&)`Ve 0) { + total = total + i + i = i - 1 + } + return total +} + +var concat_all = function(a, b, c) { + return a + b + c +} + +if (sum_ints(1, 2, 3) != 6) { print("FAIL sum_ints") } +if (count_down(5) != 15) { print("FAIL count_down") } +if (concat_all("a", "b", "c") != "abc") { print("FAIL concat_all") } + +print("backward type tests passed") diff --git a/test_intrinsics.cm b/test_intrinsics.cm new file mode 100644 index 00000000..a649aeae --- /dev/null +++ b/test_intrinsics.cm @@ -0,0 +1,63 @@ +// Test all inlined intrinsics +var arr = [1, 2, 3] +var rec = {a: 1} +var fn = function() { return 1 } +var txt = "hello" +var num = 42 +var boo = true + +// is_array +if (!is_array(arr)) { print("FAIL is_array(arr)") } +if (is_array(rec)) { print("FAIL is_array(rec)") } +if (is_array(42)) { print("FAIL is_array(42)") } + +// is_object +if (!is_object(rec)) { print("FAIL is_object(rec)") } +if (is_object(arr)) { print("FAIL is_object(arr)") } +if (is_object(42)) { print("FAIL is_object(42)") } + +// is_function +if (!is_function(fn)) { print("FAIL is_function(fn)") } +if (is_function(rec)) { print("FAIL is_function(rec)") } + +// is_stone +var frozen = stone([1, 2]) +if (!is_stone(frozen)) { print("FAIL is_stone(frozen)") } +if (is_stone(arr)) { print("FAIL is_stone(arr)") } +if (!is_stone(42)) { print("FAIL is_stone(42)") } +if (!is_stone("hi")) { print("FAIL is_stone(str)") } + +// length +if (length(arr) != 3) { print("FAIL length(arr)") } +if (length(txt) != 5) { print("FAIL length(txt)") } +if (length([]) != 0) { print("FAIL length([])") } + +// is_integer (already existed but now inlined) +if (!is_integer(42)) { print("FAIL is_integer(42)") } +if (is_integer(3.14)) { print("FAIL is_integer(3.14)") } + +// is_text +if (!is_text("hi")) { print("FAIL is_text(hi)") } +if (is_text(42)) { print("FAIL is_text(42)") } + +// is_number +if (!is_number(42)) { print("FAIL is_number(42)") } +if (!is_number(3.14)) { print("FAIL is_number(3.14)") } +if (is_number("hi")) { print("FAIL is_number(hi)") } + +// is_logical +if (!is_logical(true)) { print("FAIL is_logical(true)") } +if (is_logical(42)) { print("FAIL is_logical(42)") } + +// is_null +if (!is_null(null)) { print("FAIL is_null(null)") } +if (is_null(42)) { print("FAIL is_null(42)") } + +// push (inlined) +var a = [1] +push(a, 2) +push(a, 3) +if (length(a) != 3) { print("FAIL push length") } +if (a[2] != 3) { print("FAIL push value") } + +print("all intrinsic tests passed") diff --git a/tokenize.mach b/tokenize.mach index 6b7682f1eae06562fc36477ee41eab5d53181d89..cd3a5f3342d7a06f73257f0d151dadfa6408f32b 100644 GIT binary patch delta 3946 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 Ly>`auBS-xY6SUms