authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-06-23 19:53:32-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-06-23 19:53:32-04:00
logd9c1d8fed3e121c4fe91d5aea301574ff763ef95
tree4c59beda76ccadca05efe4be4064bba7527d208f
parent6938245fcc1daa6a63bcfcb3ba1092d569efc875

self-hosted: improve handling of anonymous decls

* anonymous decls have automatically generated names and symbols, and participate in the same memory management as named decls. * the Ref instruction is deleted * the DeclRef instruction now takes a `[]const u8` and DeclRefStr takes an arbitrary string instruction operand. * introduce a `zir.Decl` type for ZIR Module decls which holds content_hash and name - fields that are not needed for `zir.Inst` which are created as part of semantic analysis. This improves the function signatures of Module.zig and lowers memory usage. * the Str instruction is now defined to create an anonymous Decl and reference it.

2 files changed, 242 insertions(+), 231 deletions(-)

src-self-hosted/Module.zig+117-78
......@@ -63,6 +63,8 @@ failed_exports: std.AutoHashMap(*Export, *ErrorMsg),
6363/// previous analysis.
6464generation: u32 = 0,
6565
66next_anon_name_index: usize = 0,
67
6668/// Candidates for deletion. After a semantic analysis update completes, this list
6769/// contains Decls that need to be deleted if they end up having no references to them.
6870deletion_set: std.ArrayListUnmanaged(*Decl) = .{},
......@@ -193,8 +195,8 @@ pub const Decl = struct {
193195 .zir_module => {
194196 const zir_module = @fieldParentPtr(Scope.ZIRModule, "base", self.scope);
195197 const module = zir_module.contents.module;
196 const decl_inst = module.decls[self.src_index];
197 return decl_inst.src;
198 const src_decl = module.decls[self.src_index];
199 return src_decl.inst.src;
198200 },
199201 .block => unreachable,
200202 .gen_zir => unreachable,
......@@ -999,9 +1001,9 @@ pub fn performAllTheWork(self: *Module) error{OutOfMemory}!void {
9991001 };
10001002 const decl_name = mem.spanZ(decl.name);
10011003 // We already detected deletions, so we know this will be found.
1002 const src_decl = zir_module.findDecl(decl_name).?;
1003 decl.src_index = src_decl.index;
1004 self.reAnalyzeDecl(decl, src_decl.decl) catch |err| switch (err) {
1004 const src_decl_and_index = zir_module.findDecl(decl_name).?;
1005 decl.src_index = src_decl_and_index.index;
1006 self.reAnalyzeDecl(decl, src_decl_and_index.decl.inst) catch |err| switch (err) {
10051007 error.OutOfMemory => return error.OutOfMemory,
10061008 error.AnalysisFail => continue,
10071009 };
......@@ -1280,10 +1282,7 @@ fn astGenIdent(self: *Module, scope: *Scope, ident: *ast.Node.Identifier) InnerE
12801282 }
12811283 }
12821284
1283 // Decl lookup
1284 const namespace = scope.namespace();
1285 const name_hash = namespace.fullyQualifiedNameHash(ident_name);
1286 if (self.decl_table.getValue(name_hash)) |decl| {
1285 if (self.lookupDeclName(scope, ident_name)) |decl| {
12871286 const src = tree.token_locs[ident.token].start;
12881287 return try self.addZIRInst(scope, src, zir.Inst.DeclValInModule, .{ .decl = decl }, .{});
12891288 }
......@@ -1307,24 +1306,26 @@ fn astGenStringLiteral(self: *Module, scope: *Scope, str_lit: *ast.Node.StringLi
13071306 };
13081307
13091308 const src = tree.token_locs[str_lit.token].start;
1310 const str_inst = try self.addZIRInst(scope, src, zir.Inst.Str, .{ .bytes = bytes }, .{});
1311 return self.addZIRInst(scope, src, zir.Inst.Ref, .{ .operand = str_inst }, .{});
1309 return self.addZIRInst(scope, src, zir.Inst.Str, .{ .bytes = bytes }, .{});
13121310}
13131311
13141312fn astGenIntegerLiteral(self: *Module, scope: *Scope, int_lit: *ast.Node.IntegerLiteral) InnerError!*zir.Inst {
13151313 const arena = scope.arena();
13161314 const tree = scope.tree();
1317 var bytes = tree.tokenSlice(int_lit.token);
1318 const base = if (mem.startsWith(u8, bytes, "0x"))
1315 const prefixed_bytes = tree.tokenSlice(int_lit.token);
1316 const base = if (mem.startsWith(u8, prefixed_bytes, "0x"))
13191317 16
1320 else if (mem.startsWith(u8, bytes, "0o"))
1318 else if (mem.startsWith(u8, prefixed_bytes, "0o"))
13211319 8
1322 else if (mem.startsWith(u8, bytes, "0b"))
1320 else if (mem.startsWith(u8, prefixed_bytes, "0b"))
13231321 2
13241322 else
13251323 @as(u8, 10);
13261324
1327 if (base != 10) bytes = bytes[2..];
1325 const bytes = if (base == 10)
1326 prefixed_bytes
1327 else
1328 prefixed_bytes[2..];
13281329
13291330 if (std.fmt.parseInt(u64, bytes, base)) |small_int| {
13301331 const int_payload = try arena.create(Value.Payload.Int_u64);
......@@ -1647,9 +1648,9 @@ fn analyzeRootZIRModule(self: *Module, root_scope: *Scope.ZIRModule) !void {
16471648 // appendAssumeCapacity.
16481649 try self.work_queue.ensureUnusedCapacity(src_module.decls.len);
16491650
1650 for (src_module.decls) |decl| {
1651 if (decl.cast(zir.Inst.Export)) |export_inst| {
1652 _ = try self.resolveDecl(&root_scope.base, &export_inst.base);
1651 for (src_module.decls) |src_decl| {
1652 if (src_decl.inst.cast(zir.Inst.Export)) |export_inst| {
1653 _ = try self.resolveDecl(&root_scope.base, src_decl);
16531654 }
16541655 }
16551656 },
......@@ -1662,7 +1663,7 @@ fn analyzeRootZIRModule(self: *Module, root_scope: *Scope.ZIRModule) !void {
16621663 => {
16631664 const src_module = try self.getSrcModule(root_scope);
16641665
1665 var exports_to_resolve = std.ArrayList(*zir.Inst).init(self.allocator);
1666 var exports_to_resolve = std.ArrayList(*zir.Decl).init(self.allocator);
16661667 defer exports_to_resolve.deinit();
16671668
16681669 // Keep track of the decls that we expect to see in this file so that
......@@ -1687,8 +1688,8 @@ fn analyzeRootZIRModule(self: *Module, root_scope: *Scope.ZIRModule) !void {
16871688 try self.markOutdatedDecl(decl);
16881689 decl.contents_hash = src_decl.contents_hash;
16891690 }
1690 } else if (src_decl.cast(zir.Inst.Export)) |export_inst| {
1691 try exports_to_resolve.append(&export_inst.base);
1691 } else if (src_decl.inst.cast(zir.Inst.Export)) |export_inst| {
1692 try exports_to_resolve.append(src_decl);
16921693 }
16931694 }
16941695 {
......@@ -1700,8 +1701,8 @@ fn analyzeRootZIRModule(self: *Module, root_scope: *Scope.ZIRModule) !void {
17001701 try self.deleteDecl(kv.key);
17011702 }
17021703 }
1703 for (exports_to_resolve.items) |export_inst| {
1704 _ = try self.resolveDecl(&root_scope.base, export_inst);
1704 for (exports_to_resolve.items) |export_decl| {
1705 _ = try self.resolveDecl(&root_scope.base, export_decl);
17051706 }
17061707 },
17071708 }
......@@ -1945,7 +1946,7 @@ fn createNewDecl(
19451946 return new_decl;
19461947}
19471948
1948fn analyzeNewDecl(self: *Module, new_decl: *Decl, old_inst: *zir.Inst) InnerError!void {
1949fn analyzeNewDecl(self: *Module, new_decl: *Decl, src_decl: *zir.Decl) InnerError!void {
19491950 var decl_scope: Scope.DeclAnalysis = .{
19501951 .decl = new_decl,
19511952 .arena = std.heap.ArenaAllocator.init(self.allocator),
......@@ -1954,7 +1955,7 @@ fn analyzeNewDecl(self: *Module, new_decl: *Decl, old_inst: *zir.Inst) InnerErro
19541955
19551956 new_decl.analysis = .in_progress;
19561957
1957 const typed_value = self.analyzeConstInst(&decl_scope.base, old_inst) catch |err| switch (err) {
1958 const typed_value = self.analyzeConstInst(&decl_scope.base, src_decl.inst) catch |err| switch (err) {
19581959 error.OutOfMemory => return error.OutOfMemory,
19591960 error.AnalysisFail => {
19601961 switch (new_decl.analysis) {
......@@ -1986,33 +1987,32 @@ fn analyzeNewDecl(self: *Module, new_decl: *Decl, old_inst: *zir.Inst) InnerErro
19861987 }
19871988}
19881989
1989fn resolveDecl(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*Decl {
1990 assert(old_inst.name.len == 0);
1990fn resolveDecl(self: *Module, scope: *Scope, src_decl: *zir.Decl) InnerError!*Decl {
19911991 // If the name is empty, then we make this an anonymous Decl.
19921992 const scope_decl = scope.decl().?;
1993 const new_decl = try self.allocateNewDecl(scope, scope_decl.src_index, old_inst.contents_hash);
1994 try self.analyzeNewDecl(new_decl, old_inst);
1993 const new_decl = try self.allocateNewDecl(scope, scope_decl.src_index, src_decl.contents_hash);
1994 try self.analyzeNewDecl(new_decl, src_decl);
19951995 return new_decl;
1996 //const name_hash = Decl.hashSimpleName(old_inst.name);
1996 //const name_hash = Decl.hashSimpleName(src_decl.name);
19971997 //if (self.decl_table.get(name_hash)) |kv| {
19981998 // const decl = kv.value;
1999 // decl.src = old_inst.src;
2000 // try self.reAnalyzeDecl(decl, old_inst);
1999 // decl.src = src_decl.src;
2000 // try self.reAnalyzeDecl(decl, src_decl);
20012001 // return decl;
2002 //} else if (old_inst.cast(zir.Inst.DeclVal)) |decl_val| {
2002 //} else if (src_decl.cast(zir.Inst.DeclVal)) |decl_val| {
20032003 // // This is just a named reference to another decl.
20042004 // return self.analyzeDeclVal(scope, decl_val);
20052005 //} else {
2006 // const new_decl = try self.createNewDecl(scope, old_inst.name, old_inst.src, name_hash, old_inst.contents_hash);
2007 // try self.analyzeNewDecl(new_decl, old_inst);
2006 // const new_decl = try self.createNewDecl(scope, src_decl.name, src_decl.src, name_hash, src_decl.contents_hash);
2007 // try self.analyzeNewDecl(new_decl, src_decl);
20082008
20092009 // return new_decl;
20102010 //}
20112011}
20122012
20132013/// Declares a dependency on the decl.
2014fn resolveCompleteDecl(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*Decl {
2015 const decl = try self.resolveDecl(scope, old_inst);
2014fn resolveCompleteDecl(self: *Module, scope: *Scope, src_decl: *zir.Decl) InnerError!*Decl {
2015 const decl = try self.resolveDecl(scope, src_decl);
20162016 switch (decl.analysis) {
20172017 .unreferenced => unreachable,
20182018 .in_progress => unreachable,
......@@ -2163,7 +2163,6 @@ fn newZIRInst(
21632163 inst.* = .{
21642164 .base = .{
21652165 .tag = T.base_tag,
2166 .name = "",
21672166 .src = src,
21682167 },
21692168 .positionals = positionals,
......@@ -2220,19 +2219,6 @@ fn constInst(self: *Module, scope: *Scope, src: usize, typed_value: TypedValue)
22202219 return &const_inst.base;
22212220}
22222221
2223fn constStr(self: *Module, scope: *Scope, src: usize, str: []const u8) !*Inst {
2224 const ty_payload = try scope.arena().create(Type.Payload.Array_u8_Sentinel0);
2225 ty_payload.* = .{ .len = str.len };
2226
2227 const bytes_payload = try scope.arena().create(Value.Payload.Bytes);
2228 bytes_payload.* = .{ .data = str };
2229
2230 return self.constInst(scope, src, .{
2231 .ty = Type.initPayload(&ty_payload.base),
2232 .val = Value.initPayload(&bytes_payload.base),
2233 });
2234}
2235
22362222fn constType(self: *Module, scope: *Scope, src: usize, ty: Type) !*Inst {
22372223 return self.constInst(scope, src, .{
22382224 .ty = Type.initTag(.type),
......@@ -2339,15 +2325,10 @@ fn analyzeInst(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*In
23392325 .compileerror => return self.analyzeInstCompileError(scope, old_inst.cast(zir.Inst.CompileError).?),
23402326 .@"const" => return self.analyzeInstConst(scope, old_inst.cast(zir.Inst.Const).?),
23412327 .declref => return self.analyzeInstDeclRef(scope, old_inst.cast(zir.Inst.DeclRef).?),
2328 .declref_str => return self.analyzeInstDeclRefStr(scope, old_inst.cast(zir.Inst.DeclRefStr).?),
23422329 .declval => return self.analyzeInstDeclVal(scope, old_inst.cast(zir.Inst.DeclVal).?),
23432330 .declval_in_module => return self.analyzeInstDeclValInModule(scope, old_inst.cast(zir.Inst.DeclValInModule).?),
2344 .str => {
2345 const bytes = old_inst.cast(zir.Inst.Str).?.positionals.bytes;
2346 // The bytes references memory inside the ZIR module, which can get deallocated
2347 // after semantic analysis is complete. We need the memory to be in the Decl's arena.
2348 const arena_bytes = try scope.arena().dupe(u8, bytes);
2349 return self.constStr(scope, old_inst.src, arena_bytes);
2350 },
2331 .str => return self.analyzeInstStr(scope, old_inst.cast(zir.Inst.Str).?),
23512332 .int => {
23522333 const big_int = old_inst.cast(zir.Inst.Int).?.positionals.int;
23532334 return self.constIntBig(scope, old_inst.src, Type.initTag(.comptime_int), big_int);
......@@ -2363,7 +2344,6 @@ fn analyzeInst(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*In
23632344 .@"fn" => return self.analyzeInstFn(scope, old_inst.cast(zir.Inst.Fn).?),
23642345 .@"export" => return self.analyzeInstExport(scope, old_inst.cast(zir.Inst.Export).?),
23652346 .primitive => return self.analyzeInstPrimitive(scope, old_inst.cast(zir.Inst.Primitive).?),
2366 .ref => return self.analyzeInstRef(scope, old_inst.cast(zir.Inst.Ref).?),
23672347 .fntype => return self.analyzeInstFnType(scope, old_inst.cast(zir.Inst.FnType).?),
23682348 .intcast => return self.analyzeInstIntCast(scope, old_inst.cast(zir.Inst.IntCast).?),
23692349 .bitcast => return self.analyzeInstBitCast(scope, old_inst.cast(zir.Inst.BitCast).?),
......@@ -2376,9 +2356,75 @@ fn analyzeInst(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*In
23762356 }
23772357}
23782358
2359fn analyzeInstStr(self: *Module, scope: *Scope, str_inst: *zir.Inst.Str) InnerError!*Inst {
2360 // The bytes references memory inside the ZIR module, which can get deallocated
2361 // after semantic analysis is complete. We need the memory to be in the new anonymous Decl's arena.
2362 var new_decl_arena = std.heap.ArenaAllocator.init(self.allocator);
2363 const arena_bytes = try new_decl_arena.allocator.dupe(u8, str_inst.positionals.bytes);
2364
2365 const ty_payload = try scope.arena().create(Type.Payload.Array_u8_Sentinel0);
2366 ty_payload.* = .{ .len = arena_bytes.len };
2367
2368 const bytes_payload = try scope.arena().create(Value.Payload.Bytes);
2369 bytes_payload.* = .{ .data = arena_bytes };
2370
2371 const new_decl = try self.createAnonymousDecl(scope, &new_decl_arena, .{
2372 .ty = Type.initPayload(&ty_payload.base),
2373 .val = Value.initPayload(&bytes_payload.base),
2374 });
2375 return self.analyzeDeclRef(scope, str_inst.base.src, new_decl);
2376}
2377
2378fn createAnonymousDecl(
2379 self: *Module,
2380 scope: *Scope,
2381 decl_arena: *std.heap.ArenaAllocator,
2382 typed_value: TypedValue,
2383) !*Decl {
2384 var name_buf: [32]u8 = undefined;
2385 const name_index = self.getNextAnonNameIndex();
2386 const name = std.fmt.bufPrint(&name_buf, "unnamed_{}", .{name_index}) catch unreachable;
2387 const name_hash = scope.namespace().fullyQualifiedNameHash(name);
2388 const scope_decl = scope.decl().?;
2389 const src_hash: std.zig.SrcHash = undefined;
2390 const new_decl = try self.createNewDecl(scope, name, scope_decl.src_index, name_hash, src_hash);
2391 const decl_arena_state = try decl_arena.allocator.create(std.heap.ArenaAllocator.State);
2392
2393 decl_arena_state.* = decl_arena.state;
2394 new_decl.typed_value = .{
2395 .most_recent = .{
2396 .typed_value = typed_value,
2397 .arena = decl_arena_state,
2398 },
2399 };
2400 new_decl.analysis = .complete;
2401 new_decl.generation = self.generation;
2402
2403 // TODO: This generates the Decl into the machine code file if it is of a type that is non-zero size.
2404 // We should be able to further improve the compiler to not omit Decls which are only referenced at
2405 // compile-time and not runtime.
2406 if (typed_value.ty.hasCodeGenBits()) {
2407 try self.bin_file.allocateDeclIndexes(new_decl);
2408 try self.work_queue.writeItem(.{ .codegen_decl = new_decl });
2409 }
2410
2411 return new_decl;
2412}
2413
2414fn getNextAnonNameIndex(self: *Module) usize {
2415 return @atomicRmw(usize, &self.next_anon_name_index, .Add, 1, .Monotonic);
2416}
2417
2418fn lookupDeclName(self: *Module, scope: *Scope, ident_name: []const u8) ?*Decl {
2419 const namespace = scope.namespace();
2420 const name_hash = namespace.fullyQualifiedNameHash(ident_name);
2421 return self.decl_table.getValue(name_hash);
2422}
2423
23792424fn analyzeInstExport(self: *Module, scope: *Scope, export_inst: *zir.Inst.Export) InnerError!*Inst {
23802425 const symbol_name = try self.resolveConstString(scope, export_inst.positionals.symbol_name);
2381 const exported_decl = try self.resolveCompleteDecl(scope, export_inst.positionals.value);
2426 const exported_decl = self.lookupDeclName(scope, export_inst.positionals.decl_name) orelse
2427 return self.fail(scope, export_inst.base.src, "decl '{}' not found", .{export_inst.positionals.decl_name});
23822428 try self.analyzeExport(scope, export_inst.base.src, symbol_name, exported_decl);
23832429 return self.constVoid(scope, export_inst.base.src);
23842430}
......@@ -2392,26 +2438,13 @@ fn analyzeInstBreakpoint(self: *Module, scope: *Scope, inst: *zir.Inst.Breakpoin
23922438 return self.addNewInstArgs(b, inst.base.src, Type.initTag(.void), Inst.Breakpoint, {});
23932439}
23942440
2395fn analyzeInstRef(self: *Module, scope: *Scope, inst: *zir.Inst.Ref) InnerError!*Inst {
2396 const decl = try self.resolveCompleteDecl(scope, inst.positionals.operand);
2397 return self.analyzeDeclRef(scope, inst.base.src, decl);
2441fn analyzeInstDeclRefStr(self: *Module, scope: *Scope, inst: *zir.Inst.DeclRefStr) InnerError!*Inst {
2442 const decl_name = try self.resolveConstString(scope, inst.positionals.name);
2443 return self.analyzeDeclRefByName(scope, inst.base.src, decl_name);
23982444}
23992445
24002446fn analyzeInstDeclRef(self: *Module, scope: *Scope, inst: *zir.Inst.DeclRef) InnerError!*Inst {
2401 const decl_name = try self.resolveConstString(scope, inst.positionals.name);
2402 // This will need to get more fleshed out when there are proper structs & namespaces.
2403 const namespace = scope.namespace();
2404 if (namespace.cast(Scope.File)) |scope_file| {
2405 return self.fail(scope, inst.base.src, "TODO implement declref for zig source", .{});
2406 } else if (namespace.cast(Scope.ZIRModule)) |zir_module| {
2407 const src_decl = zir_module.contents.module.findDecl(decl_name) orelse
2408 return self.fail(scope, inst.positionals.name.src, "use of undeclared identifier '{}'", .{decl_name});
2409
2410 const decl = try self.resolveCompleteDecl(scope, src_decl.decl);
2411 return self.analyzeDeclRef(scope, inst.base.src, decl);
2412 } else {
2413 unreachable;
2414 }
2447 return self.analyzeDeclRefByName(scope, inst.base.src, inst.positionals.name);
24152448}
24162449
24172450fn analyzeDeclVal(self: *Module, scope: *Scope, inst: *zir.Inst.DeclVal) InnerError!*Decl {
......@@ -2465,6 +2498,12 @@ fn analyzeDeclRef(self: *Module, scope: *Scope, src: usize, decl: *Decl) InnerEr
24652498 });
24662499}
24672500
2501fn analyzeDeclRefByName(self: *Module, scope: *Scope, src: usize, decl_name: []const u8) InnerError!*Inst {
2502 const decl = self.lookupDeclName(scope, decl_name) orelse
2503 return self.fail(scope, src, "decl '{}' not found", .{decl_name});
2504 return self.analyzeDeclRef(scope, src, decl);
2505}
2506
24682507fn analyzeInstCall(self: *Module, scope: *Scope, inst: *zir.Inst.Call) InnerError!*Inst {
24692508 const func = try self.resolveInst(scope, inst.positionals.func);
24702509 if (func.ty.zigTypeTag() != .Fn)
src-self-hosted/zir.zig+125-153
......@@ -12,19 +12,23 @@ const TypedValue = @import("TypedValue.zig");
1212const ir = @import("ir.zig");
1313const IrModule = @import("Module.zig");
1414
15/// This struct is relevent only for the ZIR Module text format. It is not used for
16/// semantic analysis of Zig source code.
17pub const Decl = struct {
18 name: []const u8,
19
20 /// Hash of slice into the source of the part after the = and before the next instruction.
21 contents_hash: std.zig.SrcHash,
22
23 inst: *Inst,
24};
25
1526/// These are instructions that correspond to the ZIR text format. See `ir.Inst` for
1627/// in-memory, analyzed instructions with types and values.
17/// TODO Separate into Decl and Inst. Decl will have extra fields, and will make the
18/// undefined default field value of contents_hash no longer needed.
1928pub const Inst = struct {
2029 tag: Tag,
2130 /// Byte offset into the source.
2231 src: usize,
23 name: []const u8,
24
25 /// Hash of slice into the source of the part after the = and before the next instruction.
26 contents_hash: std.zig.SrcHash = undefined,
27
2832 /// Pre-allocated field for mapping ZIR text instructions to post-analysis instructions.
2933 analyzed_inst: *ir.Inst = undefined,
3034
......@@ -37,11 +41,14 @@ pub const Inst = struct {
3741 @"const",
3842 /// Represents a pointer to a global decl by name.
3943 declref,
44 /// Represents a pointer to a global decl by string name.
45 declref_str,
4046 /// The syntax `@foo` is equivalent to `declval("foo")`.
4147 /// declval is equivalent to declref followed by deref.
4248 declval,
4349 /// Same as declval but the parameter is a `*Module.Decl` rather than a name.
4450 declval_in_module,
51 /// String Literal. Makes an anonymous Decl and then takes a pointer to it.
4552 str,
4653 int,
4754 ptrtoint,
......@@ -56,7 +63,6 @@ pub const Inst = struct {
5663 fntype,
5764 @"export",
5865 primitive,
59 ref,
6066 intcast,
6167 bitcast,
6268 elemptr,
......@@ -72,6 +78,7 @@ pub const Inst = struct {
7278 .breakpoint => Breakpoint,
7379 .call => Call,
7480 .declref => DeclRef,
81 .declref_str => DeclRefStr,
7582 .declval => DeclVal,
7683 .declval_in_module => DeclValInModule,
7784 .compileerror => CompileError,
......@@ -89,7 +96,6 @@ pub const Inst = struct {
8996 .@"fn" => Fn,
9097 .@"export" => Export,
9198 .primitive => Primitive,
92 .ref => Ref,
9399 .fntype => FnType,
94100 .intcast => IntCast,
95101 .bitcast => BitCast,
......@@ -134,6 +140,16 @@ pub const Inst = struct {
134140 pub const base_tag = Tag.declref;
135141 base: Inst,
136142
143 positionals: struct {
144 name: []const u8,
145 },
146 kw_args: struct {},
147 };
148
149 pub const DeclRefStr = struct {
150 pub const base_tag = Tag.declref_str;
151 base: Inst,
152
137153 positionals: struct {
138154 name: *Inst,
139155 },
......@@ -316,17 +332,7 @@ pub const Inst = struct {
316332
317333 positionals: struct {
318334 symbol_name: *Inst,
319 value: *Inst,
320 },
321 kw_args: struct {},
322 };
323
324 pub const Ref = struct {
325 pub const base_tag = Tag.ref;
326 base: Inst,
327
328 positionals: struct {
329 operand: *Inst,
335 decl_name: []const u8,
330336 },
331337 kw_args: struct {},
332338 };
......@@ -500,7 +506,7 @@ pub const ErrorMsg = struct {
500506};
501507
502508pub const Module = struct {
503 decls: []*Inst,
509 decls: []*Decl,
504510 arena: std.heap.ArenaAllocator,
505511 error_msg: ?ErrorMsg = null,
506512
......@@ -519,10 +525,10 @@ pub const Module = struct {
519525 self.writeToStream(std.heap.page_allocator, std.io.getStdErr().outStream()) catch {};
520526 }
521527
522 const InstPtrTable = std.AutoHashMap(*Inst, struct { inst: *Inst, index: ?usize });
528 const InstPtrTable = std.AutoHashMap(*Inst, struct { inst: *Inst, index: ?usize, name: []const u8 });
523529
524530 const DeclAndIndex = struct {
525 decl: *Inst,
531 decl: *Decl,
526532 index: usize,
527533 };
528534
......@@ -549,18 +555,18 @@ pub const Module = struct {
549555 try inst_table.ensureCapacity(self.decls.len);
550556
551557 for (self.decls) |decl, decl_i| {
552 try inst_table.putNoClobber(decl, .{ .inst = decl, .index = null });
558 try inst_table.putNoClobber(decl.inst, .{ .inst = decl.inst, .index = null, .name = decl.name });
553559
554 if (decl.cast(Inst.Fn)) |fn_inst| {
560 if (decl.inst.cast(Inst.Fn)) |fn_inst| {
555561 for (fn_inst.positionals.body.instructions) |inst, inst_i| {
556 try inst_table.putNoClobber(inst, .{ .inst = inst, .index = inst_i });
562 try inst_table.putNoClobber(inst, .{ .inst = inst, .index = inst_i, .name = undefined });
557563 }
558564 }
559565 }
560566
561567 for (self.decls) |decl, i| {
562568 try stream.print("@{} ", .{decl.name});
563 try self.writeInstToStream(stream, decl, &inst_table);
569 try self.writeInstToStream(stream, decl.inst, &inst_table);
564570 try stream.writeByte('\n');
565571 }
566572 }
......@@ -568,41 +574,41 @@ pub const Module = struct {
568574 fn writeInstToStream(
569575 self: Module,
570576 stream: var,
571 decl: *Inst,
577 inst: *Inst,
572578 inst_table: *const InstPtrTable,
573579 ) @TypeOf(stream).Error!void {
574580 // TODO I tried implementing this with an inline for loop and hit a compiler bug
575 switch (decl.tag) {
576 .breakpoint => return self.writeInstToStreamGeneric(stream, .breakpoint, decl, inst_table),
577 .call => return self.writeInstToStreamGeneric(stream, .call, decl, inst_table),
578 .declref => return self.writeInstToStreamGeneric(stream, .declref, decl, inst_table),
579 .declval => return self.writeInstToStreamGeneric(stream, .declval, decl, inst_table),
580 .declval_in_module => return self.writeInstToStreamGeneric(stream, .declval_in_module, decl, inst_table),
581 .compileerror => return self.writeInstToStreamGeneric(stream, .compileerror, decl, inst_table),
582 .@"const" => return self.writeInstToStreamGeneric(stream, .@"const", decl, inst_table),
583 .str => return self.writeInstToStreamGeneric(stream, .str, decl, inst_table),
584 .int => return self.writeInstToStreamGeneric(stream, .int, decl, inst_table),
585 .ptrtoint => return self.writeInstToStreamGeneric(stream, .ptrtoint, decl, inst_table),
586 .fieldptr => return self.writeInstToStreamGeneric(stream, .fieldptr, decl, inst_table),
587 .deref => return self.writeInstToStreamGeneric(stream, .deref, decl, inst_table),
588 .as => return self.writeInstToStreamGeneric(stream, .as, decl, inst_table),
589 .@"asm" => return self.writeInstToStreamGeneric(stream, .@"asm", decl, inst_table),
590 .@"unreachable" => return self.writeInstToStreamGeneric(stream, .@"unreachable", decl, inst_table),
591 .@"return" => return self.writeInstToStreamGeneric(stream, .@"return", decl, inst_table),
592 .returnvoid => return self.writeInstToStreamGeneric(stream, .returnvoid, decl, inst_table),
593 .@"fn" => return self.writeInstToStreamGeneric(stream, .@"fn", decl, inst_table),
594 .@"export" => return self.writeInstToStreamGeneric(stream, .@"export", decl, inst_table),
595 .ref => return self.writeInstToStreamGeneric(stream, .ref, decl, inst_table),
596 .primitive => return self.writeInstToStreamGeneric(stream, .primitive, decl, inst_table),
597 .fntype => return self.writeInstToStreamGeneric(stream, .fntype, decl, inst_table),
598 .intcast => return self.writeInstToStreamGeneric(stream, .intcast, decl, inst_table),
599 .bitcast => return self.writeInstToStreamGeneric(stream, .bitcast, decl, inst_table),
600 .elemptr => return self.writeInstToStreamGeneric(stream, .elemptr, decl, inst_table),
601 .add => return self.writeInstToStreamGeneric(stream, .add, decl, inst_table),
602 .cmp => return self.writeInstToStreamGeneric(stream, .cmp, decl, inst_table),
603 .condbr => return self.writeInstToStreamGeneric(stream, .condbr, decl, inst_table),
604 .isnull => return self.writeInstToStreamGeneric(stream, .isnull, decl, inst_table),
605 .isnonnull => return self.writeInstToStreamGeneric(stream, .isnonnull, decl, inst_table),
581 switch (inst.tag) {
582 .breakpoint => return self.writeInstToStreamGeneric(stream, .breakpoint, inst, inst_table),
583 .call => return self.writeInstToStreamGeneric(stream, .call, inst, inst_table),
584 .declref => return self.writeInstToStreamGeneric(stream, .declref, inst, inst_table),
585 .declref_str => return self.writeInstToStreamGeneric(stream, .declref_str, inst, inst_table),
586 .declval => return self.writeInstToStreamGeneric(stream, .declval, inst, inst_table),
587 .declval_in_module => return self.writeInstToStreamGeneric(stream, .declval_in_module, inst, inst_table),
588 .compileerror => return self.writeInstToStreamGeneric(stream, .compileerror, inst, inst_table),
589 .@"const" => return self.writeInstToStreamGeneric(stream, .@"const", inst, inst_table),
590 .str => return self.writeInstToStreamGeneric(stream, .str, inst, inst_table),
591 .int => return self.writeInstToStreamGeneric(stream, .int, inst, inst_table),
592 .ptrtoint => return self.writeInstToStreamGeneric(stream, .ptrtoint, inst, inst_table),
593 .fieldptr => return self.writeInstToStreamGeneric(stream, .fieldptr, inst, inst_table),
594 .deref => return self.writeInstToStreamGeneric(stream, .deref, inst, inst_table),
595 .as => return self.writeInstToStreamGeneric(stream, .as, inst, inst_table),
596 .@"asm" => return self.writeInstToStreamGeneric(stream, .@"asm", inst, inst_table),
597 .@"unreachable" => return self.writeInstToStreamGeneric(stream, .@"unreachable", inst, inst_table),
598 .@"return" => return self.writeInstToStreamGeneric(stream, .@"return", inst, inst_table),
599 .returnvoid => return self.writeInstToStreamGeneric(stream, .returnvoid, inst, inst_table),
600 .@"fn" => return self.writeInstToStreamGeneric(stream, .@"fn", inst, inst_table),
601 .@"export" => return self.writeInstToStreamGeneric(stream, .@"export", inst, inst_table),
602 .primitive => return self.writeInstToStreamGeneric(stream, .primitive, inst, inst_table),
603 .fntype => return self.writeInstToStreamGeneric(stream, .fntype, inst, inst_table),
604 .intcast => return self.writeInstToStreamGeneric(stream, .intcast, inst, inst_table),
605 .bitcast => return self.writeInstToStreamGeneric(stream, .bitcast, inst, inst_table),
606 .elemptr => return self.writeInstToStreamGeneric(stream, .elemptr, inst, inst_table),
607 .add => return self.writeInstToStreamGeneric(stream, .add, inst, inst_table),
608 .cmp => return self.writeInstToStreamGeneric(stream, .cmp, inst, inst_table),
609 .condbr => return self.writeInstToStreamGeneric(stream, .condbr, inst, inst_table),
610 .isnull => return self.writeInstToStreamGeneric(stream, .isnull, inst, inst_table),
611 .isnonnull => return self.writeInstToStreamGeneric(stream, .isnonnull, inst, inst_table),
606612 }
607613 }
608614
......@@ -685,7 +691,7 @@ pub const Module = struct {
685691 if (info.index) |i| {
686692 try stream.print("%{}", .{info.index});
687693 } else {
688 try stream.print("@{}", .{info.inst.name});
694 try stream.print("@{}", .{info.name});
689695 }
690696 } else if (inst.cast(Inst.DeclVal)) |decl_val| {
691697 try stream.print("@{}", .{decl_val.positionals.name});
......@@ -732,7 +738,7 @@ const Parser = struct {
732738 arena: std.heap.ArenaAllocator,
733739 i: usize,
734740 source: [:0]const u8,
735 decls: std.ArrayListUnmanaged(*Inst),
741 decls: std.ArrayListUnmanaged(*Decl),
736742 global_name_map: *std.StringHashMap(usize),
737743 error_msg: ?ErrorMsg = null,
738744 unnamed_index: usize,
......@@ -761,12 +767,12 @@ const Parser = struct {
761767 skipSpace(self);
762768 try requireEatBytes(self, "=");
763769 skipSpace(self);
764 const inst = try parseInstruction(self, &body_context, ident);
770 const decl = try parseInstruction(self, &body_context, ident);
765771 const ident_index = body_context.instructions.items.len;
766772 if (try body_context.name_map.put(ident, ident_index)) |_| {
767773 return self.fail("redefinition of identifier '{}'", .{ident});
768774 }
769 try body_context.instructions.append(inst);
775 try body_context.instructions.append(decl.inst);
770776 continue;
771777 },
772778 ' ', '\n' => continue,
......@@ -916,7 +922,7 @@ const Parser = struct {
916922 return error.ParseFailure;
917923 }
918924
919 fn parseInstruction(self: *Parser, body_ctx: ?*Body, name: []const u8) InnerError!*Inst {
925 fn parseInstruction(self: *Parser, body_ctx: ?*Body, name: []const u8) InnerError!*Decl {
920926 const contents_start = self.i;
921927 const fn_name = try skipToAndOver(self, '(');
922928 inline for (@typeInfo(Inst.Tag).Enum.fields) |field| {
......@@ -935,10 +941,9 @@ const Parser = struct {
935941 body_ctx: ?*Body,
936942 inst_name: []const u8,
937943 contents_start: usize,
938 ) InnerError!*Inst {
944 ) InnerError!*Decl {
939945 const inst_specific = try self.arena.allocator.create(InstType);
940946 inst_specific.base = .{
941 .name = inst_name,
942947 .src = self.i,
943948 .tag = InstType.base_tag,
944949 };
......@@ -988,10 +993,15 @@ const Parser = struct {
988993 }
989994 try requireEatBytes(self, ")");
990995
991 inst_specific.base.contents_hash = std.zig.hashSrc(self.source[contents_start..self.i]);
996 const decl = try self.arena.allocator.create(Decl);
997 decl.* = .{
998 .name = inst_name,
999 .contents_hash = std.zig.hashSrc(self.source[contents_start..self.i]),
1000 .inst = &inst_specific.base,
1001 };
9921002 //std.debug.warn("parsed {} = '{}'\n", .{ inst_specific.base.name, inst_specific.base.contents });
9931003
994 return &inst_specific.base;
1004 return decl;
9951005 }
9961006
9971007 fn parseParameterGeneric(self: *Parser, comptime T: type, body_ctx: ?*Body) !T {
......@@ -1075,7 +1085,6 @@ const Parser = struct {
10751085 const declval = try self.arena.allocator.create(Inst.DeclVal);
10761086 declval.* = .{
10771087 .base = .{
1078 .name = try self.generateName(),
10791088 .src = src,
10801089 .tag = Inst.DeclVal.base_tag,
10811090 },
......@@ -1088,7 +1097,7 @@ const Parser = struct {
10881097 if (local_ref) {
10891098 return body_ctx.?.instructions.items[kv.value];
10901099 } else {
1091 return self.decls.items[kv.value];
1100 return self.decls.items[kv.value].inst;
10921101 }
10931102 }
10941103
......@@ -1107,7 +1116,7 @@ pub fn emit(allocator: *Allocator, old_module: IrModule) !Module {
11071116 .old_module = &old_module,
11081117 .next_auto_name = 0,
11091118 .names = std.StringHashMap(void).init(allocator),
1110 .primitive_table = std.AutoHashMap(Inst.Primitive.Builtin, *Inst).init(allocator),
1119 .primitive_table = std.AutoHashMap(Inst.Primitive.Builtin, *Decl).init(allocator),
11111120 };
11121121 defer ctx.decls.deinit(allocator);
11131122 defer ctx.names.deinit();
......@@ -1126,10 +1135,10 @@ const EmitZIR = struct {
11261135 allocator: *Allocator,
11271136 arena: std.heap.ArenaAllocator,
11281137 old_module: *const IrModule,
1129 decls: std.ArrayListUnmanaged(*Inst),
1138 decls: std.ArrayListUnmanaged(*Decl),
11301139 names: std.StringHashMap(void),
11311140 next_auto_name: usize,
1132 primitive_table: std.AutoHashMap(Inst.Primitive.Builtin, *Inst),
1141 primitive_table: std.AutoHashMap(Inst.Primitive.Builtin, *Decl),
11331142
11341143 fn emit(self: *EmitZIR) !void {
11351144 // Put all the Decls in a list and sort them by name to avoid nondeterminism introduced
......@@ -1156,22 +1165,20 @@ const EmitZIR = struct {
11561165 for (src_decls.items) |ir_decl| {
11571166 if (self.old_module.export_owners.getValue(ir_decl)) |exports| {
11581167 for (exports) |module_export| {
1159 const declval = try self.emitDeclVal(ir_decl.src(), mem.spanZ(module_export.exported_decl.name));
11601168 const symbol_name = try self.emitStringLiteral(module_export.src, module_export.options.name);
11611169 const export_inst = try self.arena.allocator.create(Inst.Export);
11621170 export_inst.* = .{
11631171 .base = .{
1164 .name = try self.autoName(),
11651172 .src = module_export.src,
11661173 .tag = Inst.Export.base_tag,
11671174 },
11681175 .positionals = .{
1169 .symbol_name = symbol_name,
1170 .value = declval,
1176 .symbol_name = symbol_name.inst,
1177 .decl_name = mem.spanZ(module_export.exported_decl.name),
11711178 },
11721179 .kw_args = .{},
11731180 };
1174 try self.decls.append(self.allocator, &export_inst.base);
1181 _ = try self.emitUnnamedDecl(&export_inst.base);
11751182 }
11761183 } else {
11771184 const new_decl = try self.emitTypedValue(ir_decl.src(), ir_decl.typed_value.most_recent.typed_value);
......@@ -1188,7 +1195,7 @@ const EmitZIR = struct {
11881195 } else if (const_inst.val.cast(Value.Payload.DeclRef)) |declref| blk: {
11891196 break :blk try self.emitDeclRef(inst.src, declref.decl);
11901197 } else blk: {
1191 break :blk try self.emitTypedValue(inst.src, .{ .ty = inst.ty, .val = const_inst.val });
1198 break :blk (try self.emitTypedValue(inst.src, .{ .ty = inst.ty, .val = const_inst.val })).inst;
11921199 };
11931200 try inst_table.putNoClobber(inst, new_decl);
11941201 return new_decl;
......@@ -1201,7 +1208,6 @@ const EmitZIR = struct {
12011208 const declval = try self.arena.allocator.create(Inst.DeclVal);
12021209 declval.* = .{
12031210 .base = .{
1204 .name = try self.autoName(),
12051211 .src = src,
12061212 .tag = Inst.DeclVal.base_tag,
12071213 },
......@@ -1211,12 +1217,11 @@ const EmitZIR = struct {
12111217 return &declval.base;
12121218 }
12131219
1214 fn emitComptimeIntVal(self: *EmitZIR, src: usize, val: Value) !*Inst {
1220 fn emitComptimeIntVal(self: *EmitZIR, src: usize, val: Value) !*Decl {
12151221 const big_int_space = try self.arena.allocator.create(Value.BigIntSpace);
12161222 const int_inst = try self.arena.allocator.create(Inst.Int);
12171223 int_inst.* = .{
12181224 .base = .{
1219 .name = try self.autoName(),
12201225 .src = src,
12211226 .tag = Inst.Int.base_tag,
12221227 },
......@@ -1225,34 +1230,29 @@ const EmitZIR = struct {
12251230 },
12261231 .kw_args = .{},
12271232 };
1228 try self.decls.append(self.allocator, &int_inst.base);
1229 return &int_inst.base;
1233 return self.emitUnnamedDecl(&int_inst.base);
12301234 }
12311235
1232 fn emitDeclRef(self: *EmitZIR, src: usize, decl: *IrModule.Decl) !*Inst {
1233 const declval = try self.emitDeclVal(src, mem.spanZ(decl.name));
1234 const ref_inst = try self.arena.allocator.create(Inst.Ref);
1235 ref_inst.* = .{
1236 fn emitDeclRef(self: *EmitZIR, src: usize, module_decl: *IrModule.Decl) !*Inst {
1237 const declref_inst = try self.arena.allocator.create(Inst.DeclRef);
1238 declref_inst.* = .{
12361239 .base = .{
1237 .name = try self.autoName(),
12381240 .src = src,
1239 .tag = Inst.Ref.base_tag,
1241 .tag = Inst.DeclRef.base_tag,
12401242 },
12411243 .positionals = .{
1242 .operand = declval,
1244 .name = mem.spanZ(module_decl.name),
12431245 },
12441246 .kw_args = .{},
12451247 };
1246 try self.decls.append(self.allocator, &ref_inst.base);
1247
1248 return &ref_inst.base;
1248 return &declref_inst.base;
12491249 }
12501250
1251 fn emitTypedValue(self: *EmitZIR, src: usize, typed_value: TypedValue) Allocator.Error!*Inst {
1251 fn emitTypedValue(self: *EmitZIR, src: usize, typed_value: TypedValue) Allocator.Error!*Decl {
12521252 const allocator = &self.arena.allocator;
12531253 if (typed_value.val.cast(Value.Payload.DeclRef)) |decl_ref| {
12541254 const decl = decl_ref.decl;
1255 return self.emitDeclRef(src, decl);
1255 return try self.emitUnnamedDecl(try self.emitDeclRef(src, decl));
12561256 }
12571257 switch (typed_value.ty.zigTypeTag()) {
12581258 .Pointer => {
......@@ -1279,18 +1279,16 @@ const EmitZIR = struct {
12791279 const as_inst = try self.arena.allocator.create(Inst.As);
12801280 as_inst.* = .{
12811281 .base = .{
1282 .name = try self.autoName(),
12831282 .src = src,
12841283 .tag = Inst.As.base_tag,
12851284 },
12861285 .positionals = .{
1287 .dest_type = try self.emitType(src, typed_value.ty),
1288 .value = try self.emitComptimeIntVal(src, typed_value.val),
1286 .dest_type = (try self.emitType(src, typed_value.ty)).inst,
1287 .value = (try self.emitComptimeIntVal(src, typed_value.val)).inst,
12891288 },
12901289 .kw_args = .{},
12911290 };
1292
1293 return &as_inst.base;
1291 return self.emitUnnamedDecl(&as_inst.base);
12941292 },
12951293 .Type => {
12961294 const ty = typed_value.val.toType();
......@@ -1316,7 +1314,6 @@ const EmitZIR = struct {
13161314 const fail_inst = try self.arena.allocator.create(Inst.CompileError);
13171315 fail_inst.* = .{
13181316 .base = .{
1319 .name = try self.autoName(),
13201317 .src = src,
13211318 .tag = Inst.CompileError.base_tag,
13221319 },
......@@ -1331,7 +1328,6 @@ const EmitZIR = struct {
13311328 const fail_inst = try self.arena.allocator.create(Inst.CompileError);
13321329 fail_inst.* = .{
13331330 .base = .{
1334 .name = try self.autoName(),
13351331 .src = src,
13361332 .tag = Inst.CompileError.base_tag,
13371333 },
......@@ -1352,18 +1348,16 @@ const EmitZIR = struct {
13521348 const fn_inst = try self.arena.allocator.create(Inst.Fn);
13531349 fn_inst.* = .{
13541350 .base = .{
1355 .name = try self.autoName(),
13561351 .src = src,
13571352 .tag = Inst.Fn.base_tag,
13581353 },
13591354 .positionals = .{
1360 .fn_type = fn_type,
1355 .fn_type = fn_type.inst,
13611356 .body = .{ .instructions = arena_instrs },
13621357 },
13631358 .kw_args = .{},
13641359 };
1365 try self.decls.append(self.allocator, &fn_inst.base);
1366 return &fn_inst.base;
1360 return self.emitUnnamedDecl(&fn_inst.base);
13671361 },
13681362 .Array => {
13691363 // TODO more checks to make sure this can be emitted as a string literal
......@@ -1379,7 +1373,6 @@ const EmitZIR = struct {
13791373 const str_inst = try self.arena.allocator.create(Inst.Str);
13801374 str_inst.* = .{
13811375 .base = .{
1382 .name = try self.autoName(),
13831376 .src = src,
13841377 .tag = Inst.Str.base_tag,
13851378 },
......@@ -1388,8 +1381,7 @@ const EmitZIR = struct {
13881381 },
13891382 .kw_args = .{},
13901383 };
1391 try self.decls.append(self.allocator, &str_inst.base);
1392 return &str_inst.base;
1384 return self.emitUnnamedDecl(&str_inst.base);
13931385 },
13941386 .Void => return self.emitPrimitive(src, .void_value),
13951387 else => |t| std.debug.panic("TODO implement emitTypedValue for {}", .{@tagName(t)}),
......@@ -1400,7 +1392,6 @@ const EmitZIR = struct {
14001392 const new_inst = try self.arena.allocator.create(T);
14011393 new_inst.* = .{
14021394 .base = .{
1403 .name = try self.autoName(),
14041395 .src = src,
14051396 .tag = T.base_tag,
14061397 },
......@@ -1429,7 +1420,6 @@ const EmitZIR = struct {
14291420 }
14301421 new_inst.* = .{
14311422 .base = .{
1432 .name = try self.autoName(),
14331423 .src = inst.src,
14341424 .tag = Inst.Call.base_tag,
14351425 },
......@@ -1447,7 +1437,6 @@ const EmitZIR = struct {
14471437 const new_inst = try self.arena.allocator.create(Inst.Return);
14481438 new_inst.* = .{
14491439 .base = .{
1450 .name = try self.autoName(),
14511440 .src = inst.src,
14521441 .tag = Inst.Return.base_tag,
14531442 },
......@@ -1466,12 +1455,12 @@ const EmitZIR = struct {
14661455
14671456 const inputs = try self.arena.allocator.alloc(*Inst, old_inst.args.inputs.len);
14681457 for (inputs) |*elem, i| {
1469 elem.* = try self.emitStringLiteral(inst.src, old_inst.args.inputs[i]);
1458 elem.* = (try self.emitStringLiteral(inst.src, old_inst.args.inputs[i])).inst;
14701459 }
14711460
14721461 const clobbers = try self.arena.allocator.alloc(*Inst, old_inst.args.clobbers.len);
14731462 for (clobbers) |*elem, i| {
1474 elem.* = try self.emitStringLiteral(inst.src, old_inst.args.clobbers[i]);
1463 elem.* = (try self.emitStringLiteral(inst.src, old_inst.args.clobbers[i])).inst;
14751464 }
14761465
14771466 const args = try self.arena.allocator.alloc(*Inst, old_inst.args.args.len);
......@@ -1481,18 +1470,17 @@ const EmitZIR = struct {
14811470
14821471 new_inst.* = .{
14831472 .base = .{
1484 .name = try self.autoName(),
14851473 .src = inst.src,
14861474 .tag = Inst.Asm.base_tag,
14871475 },
14881476 .positionals = .{
1489 .asm_source = try self.emitStringLiteral(inst.src, old_inst.args.asm_source),
1490 .return_type = try self.emitType(inst.src, inst.ty),
1477 .asm_source = (try self.emitStringLiteral(inst.src, old_inst.args.asm_source)).inst,
1478 .return_type = (try self.emitType(inst.src, inst.ty)).inst,
14911479 },
14921480 .kw_args = .{
14931481 .@"volatile" = old_inst.args.is_volatile,
14941482 .output = if (old_inst.args.output) |o|
1495 try self.emitStringLiteral(inst.src, o)
1483 (try self.emitStringLiteral(inst.src, o)).inst
14961484 else
14971485 null,
14981486 .inputs = inputs,
......@@ -1507,7 +1495,6 @@ const EmitZIR = struct {
15071495 const new_inst = try self.arena.allocator.create(Inst.PtrToInt);
15081496 new_inst.* = .{
15091497 .base = .{
1510 .name = try self.autoName(),
15111498 .src = inst.src,
15121499 .tag = Inst.PtrToInt.base_tag,
15131500 },
......@@ -1523,12 +1510,11 @@ const EmitZIR = struct {
15231510 const new_inst = try self.arena.allocator.create(Inst.BitCast);
15241511 new_inst.* = .{
15251512 .base = .{
1526 .name = try self.autoName(),
15271513 .src = inst.src,
15281514 .tag = Inst.BitCast.base_tag,
15291515 },
15301516 .positionals = .{
1531 .dest_type = try self.emitType(inst.src, inst.ty),
1517 .dest_type = (try self.emitType(inst.src, inst.ty)).inst,
15321518 .operand = try self.resolveInst(inst_table, old_inst.args.operand),
15331519 },
15341520 .kw_args = .{},
......@@ -1540,7 +1526,6 @@ const EmitZIR = struct {
15401526 const new_inst = try self.arena.allocator.create(Inst.Cmp);
15411527 new_inst.* = .{
15421528 .base = .{
1543 .name = try self.autoName(),
15441529 .src = inst.src,
15451530 .tag = Inst.Cmp.base_tag,
15461531 },
......@@ -1568,7 +1553,6 @@ const EmitZIR = struct {
15681553 const new_inst = try self.arena.allocator.create(Inst.CondBr);
15691554 new_inst.* = .{
15701555 .base = .{
1571 .name = try self.autoName(),
15721556 .src = inst.src,
15731557 .tag = Inst.CondBr.base_tag,
15741558 },
......@@ -1586,7 +1570,6 @@ const EmitZIR = struct {
15861570 const new_inst = try self.arena.allocator.create(Inst.IsNull);
15871571 new_inst.* = .{
15881572 .base = .{
1589 .name = try self.autoName(),
15901573 .src = inst.src,
15911574 .tag = Inst.IsNull.base_tag,
15921575 },
......@@ -1602,7 +1585,6 @@ const EmitZIR = struct {
16021585 const new_inst = try self.arena.allocator.create(Inst.IsNonNull);
16031586 new_inst.* = .{
16041587 .base = .{
1605 .name = try self.autoName(),
16061588 .src = inst.src,
16071589 .tag = Inst.IsNonNull.base_tag,
16081590 },
......@@ -1619,7 +1601,7 @@ const EmitZIR = struct {
16191601 }
16201602 }
16211603
1622 fn emitType(self: *EmitZIR, src: usize, ty: Type) Allocator.Error!*Inst {
1604 fn emitType(self: *EmitZIR, src: usize, ty: Type) Allocator.Error!*Decl {
16231605 switch (ty.tag()) {
16241606 .isize => return self.emitPrimitive(src, .isize),
16251607 .usize => return self.emitPrimitive(src, .usize),
......@@ -1652,26 +1634,24 @@ const EmitZIR = struct {
16521634 ty.fnParamTypes(param_types);
16531635 const emitted_params = try self.arena.allocator.alloc(*Inst, param_types.len);
16541636 for (param_types) |param_type, i| {
1655 emitted_params[i] = try self.emitType(src, param_type);
1637 emitted_params[i] = (try self.emitType(src, param_type)).inst;
16561638 }
16571639
16581640 const fntype_inst = try self.arena.allocator.create(Inst.FnType);
16591641 fntype_inst.* = .{
16601642 .base = .{
1661 .name = try self.autoName(),
16621643 .src = src,
16631644 .tag = Inst.FnType.base_tag,
16641645 },
16651646 .positionals = .{
16661647 .param_types = emitted_params,
1667 .return_type = try self.emitType(src, ty.fnReturnType()),
1648 .return_type = (try self.emitType(src, ty.fnReturnType())).inst,
16681649 },
16691650 .kw_args = .{
16701651 .cc = ty.fnCallingConvention(),
16711652 },
16721653 };
1673 try self.decls.append(self.allocator, &fntype_inst.base);
1674 return &fntype_inst.base;
1654 return self.emitUnnamedDecl(&fntype_inst.base);
16751655 },
16761656 else => std.debug.panic("TODO implement emitType for {}", .{ty}),
16771657 },
......@@ -1690,13 +1670,12 @@ const EmitZIR = struct {
16901670 }
16911671 }
16921672
1693 fn emitPrimitive(self: *EmitZIR, src: usize, tag: Inst.Primitive.Builtin) !*Inst {
1673 fn emitPrimitive(self: *EmitZIR, src: usize, tag: Inst.Primitive.Builtin) !*Decl {
16941674 const gop = try self.primitive_table.getOrPut(tag);
16951675 if (!gop.found_existing) {
16961676 const primitive_inst = try self.arena.allocator.create(Inst.Primitive);
16971677 primitive_inst.* = .{
16981678 .base = .{
1699 .name = try self.autoName(),
17001679 .src = src,
17011680 .tag = Inst.Primitive.base_tag,
17021681 },
......@@ -1705,17 +1684,15 @@ const EmitZIR = struct {
17051684 },
17061685 .kw_args = .{},
17071686 };
1708 try self.decls.append(self.allocator, &primitive_inst.base);
1709 gop.kv.value = &primitive_inst.base;
1687 gop.kv.value = try self.emitUnnamedDecl(&primitive_inst.base);
17101688 }
17111689 return gop.kv.value;
17121690 }
17131691
1714 fn emitStringLiteral(self: *EmitZIR, src: usize, str: []const u8) !*Inst {
1692 fn emitStringLiteral(self: *EmitZIR, src: usize, str: []const u8) !*Decl {
17151693 const str_inst = try self.arena.allocator.create(Inst.Str);
17161694 str_inst.* = .{
17171695 .base = .{
1718 .name = try self.autoName(),
17191696 .src = src,
17201697 .tag = Inst.Str.base_tag,
17211698 },
......@@ -1724,22 +1701,17 @@ const EmitZIR = struct {
17241701 },
17251702 .kw_args = .{},
17261703 };
1727 try self.decls.append(self.allocator, &str_inst.base);
1704 return self.emitUnnamedDecl(&str_inst.base);
1705 }
17281706
1729 const ref_inst = try self.arena.allocator.create(Inst.Ref);
1730 ref_inst.* = .{
1731 .base = .{
1732 .name = try self.autoName(),
1733 .src = src,
1734 .tag = Inst.Ref.base_tag,
1735 },
1736 .positionals = .{
1737 .operand = &str_inst.base,
1738 },
1739 .kw_args = .{},
1707 fn emitUnnamedDecl(self: *EmitZIR, inst: *Inst) !*Decl {
1708 const decl = try self.arena.allocator.create(Decl);
1709 decl.* = .{
1710 .name = try self.autoName(),
1711 .contents_hash = undefined,
1712 .inst = inst,
17401713 };
1741 try self.decls.append(self.allocator, &ref_inst.base);
1742
1743 return &ref_inst.base;
1714 try self.decls.append(self.allocator, decl);
1715 return decl;
17441716 }
17451717};