authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-03-19 15:31:50-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-03-19 15:31:50-07:00
log0357cd86537f708d915976398a38837feb1a5528
tree244f9334803dbbda47169bd94e1a2c5fec282a81
parent81a935aef81cac9e8c20ad6351290b8a56a7cf65

Sema: allocate inst_map with arena where appropriate


2 files changed, 70 insertions(+), 73 deletions(-)

src/Module.zig+11-21
...@@ -1826,7 +1826,7 @@ fn astgenAndSemaDecl(mod: *Module, decl: *Decl) !bool {...@@ -1826,7 +1826,7 @@ fn astgenAndSemaDecl(mod: *Module, decl: *Decl) !bool {
18261826
1827 const code = try gen_scope.finish();1827 const code = try gen_scope.finish();
1828 if (std.builtin.mode == .Debug and mod.comp.verbose_ir) {1828 if (std.builtin.mode == .Debug and mod.comp.verbose_ir) {
1829 zir.dumpZir(mod.gpa, "comptime_block", decl.name, code) catch {};1829 code.dump(mod.gpa, "comptime_block", decl.name) catch {};
1830 }1830 }
1831 break :blk code;1831 break :blk code;
1832 };1832 };
...@@ -1836,13 +1836,11 @@ fn astgenAndSemaDecl(mod: *Module, decl: *Decl) !bool {...@@ -1836,13 +1836,11 @@ fn astgenAndSemaDecl(mod: *Module, decl: *Decl) !bool {
1836 .gpa = mod.gpa,1836 .gpa = mod.gpa,
1837 .arena = &analysis_arena.allocator,1837 .arena = &analysis_arena.allocator,
1838 .code = code,1838 .code = code,
1839 .inst_map = try mod.gpa.alloc(*ir.Inst, code.instructions.len),1839 .inst_map = try analysis_arena.allocator.alloc(*ir.Inst, code.instructions.len),
1840 .owner_decl = decl,1840 .owner_decl = decl,
1841 .func = null,1841 .func = null,
1842 .param_inst_list = &.{},1842 .param_inst_list = &.{},
1843 };1843 };
1844 defer mod.gpa.free(sema.inst_map);
1845
1846 var block_scope: Scope.Block = .{1844 var block_scope: Scope.Block = .{
1847 .parent = null,1845 .parent = null,
1848 .sema = &sema,1846 .sema = &sema,
...@@ -2049,7 +2047,7 @@ fn astgenAndSemaFn(...@@ -2049,7 +2047,7 @@ fn astgenAndSemaFn(
20492047
2050 const fn_type_code = try fn_type_scope.finish();2048 const fn_type_code = try fn_type_scope.finish();
2051 if (std.builtin.mode == .Debug and mod.comp.verbose_ir) {2049 if (std.builtin.mode == .Debug and mod.comp.verbose_ir) {
2052 zir.dumpZir(mod.gpa, "fn_type", decl.name, fn_type_code) catch {};2050 fn_type_code.dump(mod.gpa, "fn_type", decl.name) catch {};
2053 }2051 }
20542052
2055 var fn_type_sema: Sema = .{2053 var fn_type_sema: Sema = .{
...@@ -2057,13 +2055,11 @@ fn astgenAndSemaFn(...@@ -2057,13 +2055,11 @@ fn astgenAndSemaFn(
2057 .gpa = mod.gpa,2055 .gpa = mod.gpa,
2058 .arena = &decl_arena.allocator,2056 .arena = &decl_arena.allocator,
2059 .code = fn_type_code,2057 .code = fn_type_code,
2060 .inst_map = try mod.gpa.alloc(*ir.Inst, fn_type_code.instructions.len),2058 .inst_map = try fn_type_scope_arena.allocator.alloc(*ir.Inst, fn_type_code.instructions.len),
2061 .owner_decl = decl,2059 .owner_decl = decl,
2062 .func = null,2060 .func = null,
2063 .param_inst_list = &.{},2061 .param_inst_list = &.{},
2064 };2062 };
2065 defer mod.gpa.free(fn_type_sema.inst_map);
2066
2067 var block_scope: Scope.Block = .{2063 var block_scope: Scope.Block = .{
2068 .parent = null,2064 .parent = null,
2069 .sema = &fn_type_sema,2065 .sema = &fn_type_sema,
...@@ -2174,7 +2170,7 @@ fn astgenAndSemaFn(...@@ -2174,7 +2170,7 @@ fn astgenAndSemaFn(
21742170
2175 const code = try gen_scope.finish();2171 const code = try gen_scope.finish();
2176 if (std.builtin.mode == .Debug and mod.comp.verbose_ir) {2172 if (std.builtin.mode == .Debug and mod.comp.verbose_ir) {
2177 zir.dumpZir(mod.gpa, "fn_body", decl.name, code) catch {};2173 code.dump(mod.gpa, "fn_body", decl.name) catch {};
2178 }2174 }
21792175
2180 break :blk code;2176 break :blk code;
...@@ -2351,7 +2347,7 @@ fn astgenAndSemaVarDecl(...@@ -2351,7 +2347,7 @@ fn astgenAndSemaVarDecl(
2351 );2347 );
2352 const code = try gen_scope.finish();2348 const code = try gen_scope.finish();
2353 if (std.builtin.mode == .Debug and mod.comp.verbose_ir) {2349 if (std.builtin.mode == .Debug and mod.comp.verbose_ir) {
2354 zir.dumpZir(mod.gpa, "var_init", decl.name, code) catch {};2350 code.dump(mod.gpa, "var_init", decl.name) catch {};
2355 }2351 }
23562352
2357 var sema: Sema = .{2353 var sema: Sema = .{
...@@ -2359,13 +2355,11 @@ fn astgenAndSemaVarDecl(...@@ -2359,13 +2355,11 @@ fn astgenAndSemaVarDecl(
2359 .gpa = mod.gpa,2355 .gpa = mod.gpa,
2360 .arena = &gen_scope_arena.allocator,2356 .arena = &gen_scope_arena.allocator,
2361 .code = code,2357 .code = code,
2362 .inst_map = try mod.gpa.alloc(*ir.Inst, code.instructions.len),2358 .inst_map = try gen_scope_arena.allocator.alloc(*ir.Inst, code.instructions.len),
2363 .owner_decl = decl,2359 .owner_decl = decl,
2364 .func = null,2360 .func = null,
2365 .param_inst_list = &.{},2361 .param_inst_list = &.{},
2366 };2362 };
2367 defer mod.gpa.free(sema.inst_map);
2368
2369 var block_scope: Scope.Block = .{2363 var block_scope: Scope.Block = .{
2370 .parent = null,2364 .parent = null,
2371 .sema = &sema,2365 .sema = &sema,
...@@ -2415,7 +2409,7 @@ fn astgenAndSemaVarDecl(...@@ -2415,7 +2409,7 @@ fn astgenAndSemaVarDecl(
2415 const var_type = try astgen.typeExpr(mod, &type_scope.base, var_decl.ast.type_node);2409 const var_type = try astgen.typeExpr(mod, &type_scope.base, var_decl.ast.type_node);
2416 const code = try type_scope.finish();2410 const code = try type_scope.finish();
2417 if (std.builtin.mode == .Debug and mod.comp.verbose_ir) {2411 if (std.builtin.mode == .Debug and mod.comp.verbose_ir) {
2418 zir.dumpZir(mod.gpa, "var_type", decl.name, code) catch {};2412 code.dump(mod.gpa, "var_type", decl.name) catch {};
2419 }2413 }
24202414
2421 var sema: Sema = .{2415 var sema: Sema = .{
...@@ -2423,13 +2417,11 @@ fn astgenAndSemaVarDecl(...@@ -2423,13 +2417,11 @@ fn astgenAndSemaVarDecl(
2423 .gpa = mod.gpa,2417 .gpa = mod.gpa,
2424 .arena = &type_scope_arena.allocator,2418 .arena = &type_scope_arena.allocator,
2425 .code = code,2419 .code = code,
2426 .inst_map = try mod.gpa.alloc(*ir.Inst, code.instructions.len),2420 .inst_map = try type_scope_arena.allocator.alloc(*ir.Inst, code.instructions.len),
2427 .owner_decl = decl,2421 .owner_decl = decl,
2428 .func = null,2422 .func = null,
2429 .param_inst_list = &.{},2423 .param_inst_list = &.{},
2430 };2424 };
2431 defer mod.gpa.free(sema.inst_map);
2432
2433 var block_scope: Scope.Block = .{2425 var block_scope: Scope.Block = .{
2434 .parent = null,2426 .parent = null,
2435 .sema = &sema,2427 .sema = &sema,
...@@ -2985,9 +2977,6 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn) !void {...@@ -2985,9 +2977,6 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn) !void {
2985 var arena = decl.typed_value.most_recent.arena.?.promote(mod.gpa);2977 var arena = decl.typed_value.most_recent.arena.?.promote(mod.gpa);
2986 defer decl.typed_value.most_recent.arena.?.* = arena.state;2978 defer decl.typed_value.most_recent.arena.?.* = arena.state;
29872979
2988 const inst_map = try mod.gpa.alloc(*ir.Inst, func.zir.instructions.len);
2989 defer mod.gpa.free(inst_map);
2990
2991 const fn_ty = decl.typed_value.most_recent.typed_value.ty;2980 const fn_ty = decl.typed_value.most_recent.typed_value.ty;
2992 const param_inst_list = try mod.gpa.alloc(*ir.Inst, fn_ty.fnParamLen());2981 const param_inst_list = try mod.gpa.alloc(*ir.Inst, fn_ty.fnParamLen());
2993 defer mod.gpa.free(param_inst_list);2982 defer mod.gpa.free(param_inst_list);
...@@ -3012,11 +3001,12 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn) !void {...@@ -3012,11 +3001,12 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn) !void {
3012 .gpa = mod.gpa,3001 .gpa = mod.gpa,
3013 .arena = &arena.allocator,3002 .arena = &arena.allocator,
3014 .code = func.zir,3003 .code = func.zir,
3015 .inst_map = inst_map,3004 .inst_map = try mod.gpa.alloc(*ir.Inst, func.zir.instructions.len),
3016 .owner_decl = decl,3005 .owner_decl = decl,
3017 .func = func,3006 .func = func,
3018 .param_inst_list = param_inst_list,3007 .param_inst_list = param_inst_list,
3019 };3008 };
3009 defer mod.gpa.free(sema.inst_map);
30203010
3021 var inner_block: Scope.Block = .{3011 var inner_block: Scope.Block = .{
3022 .parent = null,3012 .parent = null,
src/zir.zig+59-52
...@@ -1,4 +1,5 @@...@@ -1,4 +1,5 @@
1//! This file has to do with parsing and rendering the ZIR text format.1//! Zig Intermediate Representation. astgen.zig converts AST nodes to these
2//! untyped IR instructions. Next, Sema.zig processes these into TZIR.
23
3const std = @import("std");4const std = @import("std");
4const mem = std.mem;5const mem = std.mem;
...@@ -6,12 +7,13 @@ const Allocator = std.mem.Allocator;...@@ -6,12 +7,13 @@ const Allocator = std.mem.Allocator;
6const assert = std.debug.assert;7const assert = std.debug.assert;
7const BigIntConst = std.math.big.int.Const;8const BigIntConst = std.math.big.int.Const;
8const BigIntMutable = std.math.big.int.Mutable;9const BigIntMutable = std.math.big.int.Mutable;
10const ast = std.zig.ast;
11
9const Type = @import("type.zig").Type;12const Type = @import("type.zig").Type;
10const Value = @import("value.zig").Value;13const Value = @import("value.zig").Value;
11const TypedValue = @import("TypedValue.zig");14const TypedValue = @import("TypedValue.zig");
12const ir = @import("ir.zig");15const ir = @import("ir.zig");
13const Module = @import("Module.zig");16const Module = @import("Module.zig");
14const ast = std.zig.ast;
15const LazySrcLoc = Module.LazySrcLoc;17const LazySrcLoc = Module.LazySrcLoc;
1618
17/// The minimum amount of information needed to represent a list of ZIR instructions.19/// The minimum amount of information needed to represent a list of ZIR instructions.
...@@ -64,6 +66,61 @@ pub const Code = struct {...@@ -64,6 +66,61 @@ pub const Code = struct {
64 }66 }
65 return code.string_bytes[index..end :0];67 return code.string_bytes[index..end :0];
66 }68 }
69
70 /// For debugging purposes, like dumpFn but for unanalyzed zir blocks
71 pub fn dump(code: Code, gpa: *Allocator, kind: []const u8, decl_name: [*:0]const u8) !void {
72 var arena = std.heap.ArenaAllocator.init(gpa);
73 defer arena.deinit();
74
75 if (true) @panic("TODO fix this function for zir-memory-layout branch");
76
77 var writer: Writer = .{
78 .gpa = gpa,
79 .arena = &arena.allocator,
80 .code = code,
81 .inst_map = try arena.allocator.alloc(*ir.Inst, code.instructions.len),
82 .owner_decl = decl,
83 .func = null,
84 .param_inst_list = &.{},
85 };
86 var write = Writer{
87 .inst_table = InstPtrTable.init(gpa),
88 .block_table = std.AutoHashMap(*Inst.Block, []const u8).init(gpa),
89 .loop_table = std.AutoHashMap(*Inst.Loop, []const u8).init(gpa),
90 .arena = std.heap.ArenaAllocator.init(gpa),
91 .indent = 4,
92 .next_instr_index = 0,
93 };
94 defer write.arena.deinit();
95 defer write.inst_table.deinit();
96 defer write.block_table.deinit();
97 defer write.loop_table.deinit();
98
99 try write.inst_table.ensureCapacity(@intCast(u32, instructions.len));
100
101 const stderr = std.io.getStdErr().writer();
102 try stderr.print("{s} {s} {{ // unanalyzed\n", .{ kind, decl_name });
103
104 for (instructions) |inst| {
105 const my_i = write.next_instr_index;
106 write.next_instr_index += 1;
107
108 if (inst.cast(Inst.Block)) |block| {
109 const name = try std.fmt.allocPrint(&write.arena.allocator, "label_{d}", .{my_i});
110 try write.block_table.put(block, name);
111 } else if (inst.cast(Inst.Loop)) |loop| {
112 const name = try std.fmt.allocPrint(&write.arena.allocator, "loop_{d}", .{my_i});
113 try write.loop_table.put(loop, name);
114 }
115
116 try write.inst_table.putNoClobber(inst, .{ .inst = inst, .index = my_i, .name = "inst" });
117 try stderr.print(" %{d} ", .{my_i});
118 try write.writeInstToStream(stderr, inst);
119 try stderr.writeByte('\n');
120 }
121
122 try stderr.print("}} // {s} {s}\n\n", .{ kind, decl_name });
123 }
67};124};
68125
69/// These correspond to the first N tags of Value.126/// These correspond to the first N tags of Value.
...@@ -1209,53 +1266,3 @@ pub const Inst = struct {...@@ -1209,53 +1266,3 @@ pub const Inst = struct {
1209 field_name: Ref,1266 field_name: Ref,
1210 };1267 };
1211};1268};
1212
1213/// For debugging purposes, like dumpFn but for unanalyzed zir blocks
1214pub fn dumpZir(gpa: *Allocator, kind: []const u8, decl_name: [*:0]const u8, code: Code) !void {
1215 if (true) @panic("TODO fix this function for zir-memory-layout branch");
1216 var fib = std.heap.FixedBufferAllocator.init(&[_]u8{});
1217 var module = Module{
1218 .decls = &[_]*Module.Decl{},
1219 .arena = std.heap.ArenaAllocator.init(&fib.allocator),
1220 .metadata = std.AutoHashMap(*Inst, Module.MetaData).init(&fib.allocator),
1221 .body_metadata = std.AutoHashMap(*Body, Module.BodyMetaData).init(&fib.allocator),
1222 };
1223 var write = Writer{
1224 .module = &module,
1225 .inst_table = InstPtrTable.init(gpa),
1226 .block_table = std.AutoHashMap(*Inst.Block, []const u8).init(gpa),
1227 .loop_table = std.AutoHashMap(*Inst.Loop, []const u8).init(gpa),
1228 .arena = std.heap.ArenaAllocator.init(gpa),
1229 .indent = 4,
1230 .next_instr_index = 0,
1231 };
1232 defer write.arena.deinit();
1233 defer write.inst_table.deinit();
1234 defer write.block_table.deinit();
1235 defer write.loop_table.deinit();
1236
1237 try write.inst_table.ensureCapacity(@intCast(u32, instructions.len));
1238
1239 const stderr = std.io.getStdErr().writer();
1240 try stderr.print("{s} {s} {{ // unanalyzed\n", .{ kind, decl_name });
1241
1242 for (instructions) |inst| {
1243 const my_i = write.next_instr_index;
1244 write.next_instr_index += 1;
1245
1246 if (inst.cast(Inst.Block)) |block| {
1247 const name = try std.fmt.allocPrint(&write.arena.allocator, "label_{d}", .{my_i});
1248 try write.block_table.put(block, name);
1249 } else if (inst.cast(Inst.Loop)) |loop| {
1250 const name = try std.fmt.allocPrint(&write.arena.allocator, "loop_{d}", .{my_i});
1251 try write.loop_table.put(loop, name);
1252 }
1253
1254 try write.inst_table.putNoClobber(inst, .{ .inst = inst, .index = my_i, .name = "inst" });
1255 try stderr.print(" %{d} ", .{my_i});
1256 try write.writeInstToStream(stderr, inst);
1257 try stderr.writeByte('\n');
1258 }
1259
1260 try stderr.print("}} // {s} {s}\n\n", .{ kind, decl_name });
1261}