diff --git a/src/Module.zig b/src/Module.zig index ca0ecaf0bb..53e1850c0d 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -1826,7 +1826,7 @@ fn astgenAndSemaDecl(mod: *Module, decl: *Decl) !bool { const code = try gen_scope.finish(); if (std.builtin.mode == .Debug and mod.comp.verbose_ir) { - zir.dumpZir(mod.gpa, "comptime_block", decl.name, code) catch {}; + code.dump(mod.gpa, "comptime_block", decl.name) catch {}; } break :blk code; }; @@ -1836,13 +1836,11 @@ fn astgenAndSemaDecl(mod: *Module, decl: *Decl) !bool { .gpa = mod.gpa, .arena = &analysis_arena.allocator, .code = code, - .inst_map = try mod.gpa.alloc(*ir.Inst, code.instructions.len), + .inst_map = try analysis_arena.allocator.alloc(*ir.Inst, code.instructions.len), .owner_decl = decl, .func = null, .param_inst_list = &.{}, }; - defer mod.gpa.free(sema.inst_map); - var block_scope: Scope.Block = .{ .parent = null, .sema = &sema, @@ -2049,7 +2047,7 @@ fn astgenAndSemaFn( const fn_type_code = try fn_type_scope.finish(); if (std.builtin.mode == .Debug and mod.comp.verbose_ir) { - zir.dumpZir(mod.gpa, "fn_type", decl.name, fn_type_code) catch {}; + fn_type_code.dump(mod.gpa, "fn_type", decl.name) catch {}; } var fn_type_sema: Sema = .{ @@ -2057,13 +2055,11 @@ fn astgenAndSemaFn( .gpa = mod.gpa, .arena = &decl_arena.allocator, .code = fn_type_code, - .inst_map = try mod.gpa.alloc(*ir.Inst, fn_type_code.instructions.len), + .inst_map = try fn_type_scope_arena.allocator.alloc(*ir.Inst, fn_type_code.instructions.len), .owner_decl = decl, .func = null, .param_inst_list = &.{}, }; - defer mod.gpa.free(fn_type_sema.inst_map); - var block_scope: Scope.Block = .{ .parent = null, .sema = &fn_type_sema, @@ -2174,7 +2170,7 @@ fn astgenAndSemaFn( const code = try gen_scope.finish(); if (std.builtin.mode == .Debug and mod.comp.verbose_ir) { - zir.dumpZir(mod.gpa, "fn_body", decl.name, code) catch {}; + code.dump(mod.gpa, "fn_body", decl.name) catch {}; } break :blk code; @@ -2351,7 +2347,7 @@ fn astgenAndSemaVarDecl( ); const code = try gen_scope.finish(); if (std.builtin.mode == .Debug and mod.comp.verbose_ir) { - zir.dumpZir(mod.gpa, "var_init", decl.name, code) catch {}; + code.dump(mod.gpa, "var_init", decl.name) catch {}; } var sema: Sema = .{ @@ -2359,13 +2355,11 @@ fn astgenAndSemaVarDecl( .gpa = mod.gpa, .arena = &gen_scope_arena.allocator, .code = code, - .inst_map = try mod.gpa.alloc(*ir.Inst, code.instructions.len), + .inst_map = try gen_scope_arena.allocator.alloc(*ir.Inst, code.instructions.len), .owner_decl = decl, .func = null, .param_inst_list = &.{}, }; - defer mod.gpa.free(sema.inst_map); - var block_scope: Scope.Block = .{ .parent = null, .sema = &sema, @@ -2415,7 +2409,7 @@ fn astgenAndSemaVarDecl( const var_type = try astgen.typeExpr(mod, &type_scope.base, var_decl.ast.type_node); const code = try type_scope.finish(); if (std.builtin.mode == .Debug and mod.comp.verbose_ir) { - zir.dumpZir(mod.gpa, "var_type", decl.name, code) catch {}; + code.dump(mod.gpa, "var_type", decl.name) catch {}; } var sema: Sema = .{ @@ -2423,13 +2417,11 @@ fn astgenAndSemaVarDecl( .gpa = mod.gpa, .arena = &type_scope_arena.allocator, .code = code, - .inst_map = try mod.gpa.alloc(*ir.Inst, code.instructions.len), + .inst_map = try type_scope_arena.allocator.alloc(*ir.Inst, code.instructions.len), .owner_decl = decl, .func = null, .param_inst_list = &.{}, }; - defer mod.gpa.free(sema.inst_map); - var block_scope: Scope.Block = .{ .parent = null, .sema = &sema, @@ -2985,9 +2977,6 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn) !void { var arena = decl.typed_value.most_recent.arena.?.promote(mod.gpa); defer decl.typed_value.most_recent.arena.?.* = arena.state; - const inst_map = try mod.gpa.alloc(*ir.Inst, func.zir.instructions.len); - defer mod.gpa.free(inst_map); - const fn_ty = decl.typed_value.most_recent.typed_value.ty; const param_inst_list = try mod.gpa.alloc(*ir.Inst, fn_ty.fnParamLen()); defer mod.gpa.free(param_inst_list); @@ -3012,11 +3001,12 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn) !void { .gpa = mod.gpa, .arena = &arena.allocator, .code = func.zir, - .inst_map = inst_map, + .inst_map = try mod.gpa.alloc(*ir.Inst, func.zir.instructions.len), .owner_decl = decl, .func = func, .param_inst_list = param_inst_list, }; + defer mod.gpa.free(sema.inst_map); var inner_block: Scope.Block = .{ .parent = null, diff --git a/src/zir.zig b/src/zir.zig index b2c4a38832..9e63ab0219 100644 --- a/src/zir.zig +++ b/src/zir.zig @@ -1,4 +1,5 @@ -//! This file has to do with parsing and rendering the ZIR text format. +//! Zig Intermediate Representation. astgen.zig converts AST nodes to these +//! untyped IR instructions. Next, Sema.zig processes these into TZIR. const std = @import("std"); const mem = std.mem; @@ -6,12 +7,13 @@ const Allocator = std.mem.Allocator; const assert = std.debug.assert; const BigIntConst = std.math.big.int.Const; const BigIntMutable = std.math.big.int.Mutable; +const ast = std.zig.ast; + const Type = @import("type.zig").Type; const Value = @import("value.zig").Value; const TypedValue = @import("TypedValue.zig"); const ir = @import("ir.zig"); const Module = @import("Module.zig"); -const ast = std.zig.ast; const LazySrcLoc = Module.LazySrcLoc; /// The minimum amount of information needed to represent a list of ZIR instructions. @@ -64,6 +66,61 @@ pub const Code = struct { } return code.string_bytes[index..end :0]; } + + /// For debugging purposes, like dumpFn but for unanalyzed zir blocks + pub fn dump(code: Code, gpa: *Allocator, kind: []const u8, decl_name: [*:0]const u8) !void { + var arena = std.heap.ArenaAllocator.init(gpa); + defer arena.deinit(); + + if (true) @panic("TODO fix this function for zir-memory-layout branch"); + + var writer: Writer = .{ + .gpa = gpa, + .arena = &arena.allocator, + .code = code, + .inst_map = try arena.allocator.alloc(*ir.Inst, code.instructions.len), + .owner_decl = decl, + .func = null, + .param_inst_list = &.{}, + }; + var write = Writer{ + .inst_table = InstPtrTable.init(gpa), + .block_table = std.AutoHashMap(*Inst.Block, []const u8).init(gpa), + .loop_table = std.AutoHashMap(*Inst.Loop, []const u8).init(gpa), + .arena = std.heap.ArenaAllocator.init(gpa), + .indent = 4, + .next_instr_index = 0, + }; + defer write.arena.deinit(); + defer write.inst_table.deinit(); + defer write.block_table.deinit(); + defer write.loop_table.deinit(); + + try write.inst_table.ensureCapacity(@intCast(u32, instructions.len)); + + const stderr = std.io.getStdErr().writer(); + try stderr.print("{s} {s} {{ // unanalyzed\n", .{ kind, decl_name }); + + for (instructions) |inst| { + const my_i = write.next_instr_index; + write.next_instr_index += 1; + + if (inst.cast(Inst.Block)) |block| { + const name = try std.fmt.allocPrint(&write.arena.allocator, "label_{d}", .{my_i}); + try write.block_table.put(block, name); + } else if (inst.cast(Inst.Loop)) |loop| { + const name = try std.fmt.allocPrint(&write.arena.allocator, "loop_{d}", .{my_i}); + try write.loop_table.put(loop, name); + } + + try write.inst_table.putNoClobber(inst, .{ .inst = inst, .index = my_i, .name = "inst" }); + try stderr.print(" %{d} ", .{my_i}); + try write.writeInstToStream(stderr, inst); + try stderr.writeByte('\n'); + } + + try stderr.print("}} // {s} {s}\n\n", .{ kind, decl_name }); + } }; /// These correspond to the first N tags of Value. @@ -1209,53 +1266,3 @@ pub const Inst = struct { field_name: Ref, }; }; - -/// For debugging purposes, like dumpFn but for unanalyzed zir blocks -pub fn dumpZir(gpa: *Allocator, kind: []const u8, decl_name: [*:0]const u8, code: Code) !void { - if (true) @panic("TODO fix this function for zir-memory-layout branch"); - var fib = std.heap.FixedBufferAllocator.init(&[_]u8{}); - var module = Module{ - .decls = &[_]*Module.Decl{}, - .arena = std.heap.ArenaAllocator.init(&fib.allocator), - .metadata = std.AutoHashMap(*Inst, Module.MetaData).init(&fib.allocator), - .body_metadata = std.AutoHashMap(*Body, Module.BodyMetaData).init(&fib.allocator), - }; - var write = Writer{ - .module = &module, - .inst_table = InstPtrTable.init(gpa), - .block_table = std.AutoHashMap(*Inst.Block, []const u8).init(gpa), - .loop_table = std.AutoHashMap(*Inst.Loop, []const u8).init(gpa), - .arena = std.heap.ArenaAllocator.init(gpa), - .indent = 4, - .next_instr_index = 0, - }; - defer write.arena.deinit(); - defer write.inst_table.deinit(); - defer write.block_table.deinit(); - defer write.loop_table.deinit(); - - try write.inst_table.ensureCapacity(@intCast(u32, instructions.len)); - - const stderr = std.io.getStdErr().writer(); - try stderr.print("{s} {s} {{ // unanalyzed\n", .{ kind, decl_name }); - - for (instructions) |inst| { - const my_i = write.next_instr_index; - write.next_instr_index += 1; - - if (inst.cast(Inst.Block)) |block| { - const name = try std.fmt.allocPrint(&write.arena.allocator, "label_{d}", .{my_i}); - try write.block_table.put(block, name); - } else if (inst.cast(Inst.Loop)) |loop| { - const name = try std.fmt.allocPrint(&write.arena.allocator, "loop_{d}", .{my_i}); - try write.loop_table.put(loop, name); - } - - try write.inst_table.putNoClobber(inst, .{ .inst = inst, .index = my_i, .name = "inst" }); - try stderr.print(" %{d} ", .{my_i}); - try write.writeInstToStream(stderr, inst); - try stderr.writeByte('\n'); - } - - try stderr.print("}} // {s} {s}\n\n", .{ kind, decl_name }); -}