Commit 0357cd8653

Andrew Kelley <andrew@ziglang.org>
2021-03-19 23:31:50
Sema: allocate inst_map with arena where appropriate
1 parent 81a935a
Changed files (2)
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,
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 });
-}