Sema: allocate inst_map with arena where appropriate

This commit is contained in:
Andrew Kelley 2021-03-19 15:31:50 -07:00
parent 81a935aef8
commit 0357cd8653
2 changed files with 70 additions and 73 deletions

View File

@ -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,

View File

@ -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 });
}