// ir_report.ce — optimizer flight recorder CLI // // Usage: ./cell --core . ir_report.ce [options] // // Options: // --summary Per-pass JSON summaries (default) // --events Include rewrite events // --types Include type deltas // --ir-before=PASS Print canonical IR before PASS // --ir-after=PASS Print canonical IR after PASS // --ir-all Print canonical IR before/after every pass // --full Everything (summary + events + types + ir-all) 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 ir_stats = use("ir_stats") // --- Parse arguments --- var filename = null var opt_events = false var opt_types = false var opt_ir_before = null var opt_ir_after = null var opt_ir_all = false var i = 0 var arg = null var p = null var e = null var td = null while (i < length(args)) { arg = args[i] if (arg == "--events") { opt_events = true } else if (arg == "--types") { opt_types = true } else if (arg == "--ir-all") { opt_ir_all = true } else if (arg == "--full") { opt_events = true opt_types = true opt_ir_all = true } else if (arg == "--summary") { // default, no-op } else if (starts_with(arg, "--ir-before=")) { opt_ir_before = text(arg, 12) } else if (starts_with(arg, "--ir-after=")) { opt_ir_after = text(arg, 11) } else if (!starts_with(arg, "--")) { filename = arg } else { print(`unknown option: ${arg}\n`) print("usage: cell --core . ir_report.ce [options] \n") $stop() } i = i + 1 } if (filename == null) { print("usage: cell --core . ir_report.ce [options] \n") print(" --summary per-pass JSON summaries (default)\n") print(" --events include rewrite events\n") print(" --types include type deltas\n") print(" --ir-before=PASS print canonical IR before PASS\n") print(" --ir-after=PASS print canonical IR after PASS\n") print(" --ir-all print canonical IR before/after every pass\n") print(" --full everything\n") $stop() } // --- Compile --- 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) // --- Determine which passes need IR snapshots --- var need_snapshots = opt_ir_all || opt_ir_before != null || opt_ir_after != null // Deep copy for before snapshot if we need IR printing var before_ir = null if (need_snapshots) { before_ir = json.decode(json.encode(compiled)) } // --- Set up log --- var log = { passes: [], events: null, type_deltas: null } if (opt_events) { log.events = [] } if (opt_types) { log.type_deltas = [] } // --- Run optimizer --- var optimized = streamline(compiled, log) // --- Output --- var emit = function(obj) { print(json.encode(obj)) print("\n") } // Pass summaries (always) i = 0 while (i < length(log.passes)) { p = log.passes[i] p.type = "pass" emit(p) i = i + 1 } // Rewrite events if (opt_events && log.events != null) { i = 0 while (i < length(log.events)) { e = log.events[i] e.type = "event" emit(e) i = i + 1 } } // Type deltas if (opt_types && log.type_deltas != null) { i = 0 while (i < length(log.type_deltas)) { td = log.type_deltas[i] td.type = "types" emit(td) i = i + 1 } } // --- Canonical IR printing --- var print_ir = function(ir_obj, when_label, pass_name) { var fname = null var fi = 0 var func = null if (ir_obj.main != null) { fname = ir_obj.name != null ? ir_obj.name : "
" emit({ type: "ir", when: when_label, pass: pass_name, fn: fname, text: ir_stats.canonical_ir(ir_obj.main, fname, {show_nops: true}) }) } if (ir_obj.functions != null) { fi = 0 while (fi < length(ir_obj.functions)) { func = ir_obj.functions[fi] fname = func.name != null ? func.name : `` emit({ type: "ir", when: when_label, pass: pass_name, fn: fname, text: ir_stats.canonical_ir(func, fname, {show_nops: true}) }) fi = fi + 1 } } return null } if (need_snapshots) { if (opt_ir_all) { print_ir(before_ir, "before", "all") print_ir(optimized, "after", "all") } else { if (opt_ir_before != null) { print_ir(before_ir, "before", opt_ir_before) } if (opt_ir_after != null) { print_ir(optimized, "after", opt_ir_after) } } } $stop()