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),...@@ -63,6 +63,8 @@ failed_exports: std.AutoHashMap(*Export, *ErrorMsg),
63/// previous analysis.63/// previous analysis.
64generation: u32 = 0,64generation: u32 = 0,
6565
66next_anon_name_index: usize = 0,
67
66/// Candidates for deletion. After a semantic analysis update completes, this list68/// Candidates for deletion. After a semantic analysis update completes, this list
67/// contains Decls that need to be deleted if they end up having no references to them.69/// contains Decls that need to be deleted if they end up having no references to them.
68deletion_set: std.ArrayListUnmanaged(*Decl) = .{},70deletion_set: std.ArrayListUnmanaged(*Decl) = .{},
...@@ -193,8 +195,8 @@ pub const Decl = struct {...@@ -193,8 +195,8 @@ pub const Decl = struct {
193 .zir_module => {195 .zir_module => {
194 const zir_module = @fieldParentPtr(Scope.ZIRModule, "base", self.scope);196 const zir_module = @fieldParentPtr(Scope.ZIRModule, "base", self.scope);
195 const module = zir_module.contents.module;197 const module = zir_module.contents.module;
196 const decl_inst = module.decls[self.src_index];198 const src_decl = module.decls[self.src_index];
197 return decl_inst.src;199 return src_decl.inst.src;
198 },200 },
199 .block => unreachable,201 .block => unreachable,
200 .gen_zir => unreachable,202 .gen_zir => unreachable,
...@@ -999,9 +1001,9 @@ pub fn performAllTheWork(self: *Module) error{OutOfMemory}!void {...@@ -999,9 +1001,9 @@ pub fn performAllTheWork(self: *Module) error{OutOfMemory}!void {
999 };1001 };
1000 const decl_name = mem.spanZ(decl.name);1002 const decl_name = mem.spanZ(decl.name);
1001 // We already detected deletions, so we know this will be found.1003 // We already detected deletions, so we know this will be found.
1002 const src_decl = zir_module.findDecl(decl_name).?;1004 const src_decl_and_index = zir_module.findDecl(decl_name).?;
1003 decl.src_index = src_decl.index;1005 decl.src_index = src_decl_and_index.index;
1004 self.reAnalyzeDecl(decl, src_decl.decl) catch |err| switch (err) {1006 self.reAnalyzeDecl(decl, src_decl_and_index.decl.inst) catch |err| switch (err) {
1005 error.OutOfMemory => return error.OutOfMemory,1007 error.OutOfMemory => return error.OutOfMemory,
1006 error.AnalysisFail => continue,1008 error.AnalysisFail => continue,
1007 };1009 };
...@@ -1280,10 +1282,7 @@ fn astGenIdent(self: *Module, scope: *Scope, ident: *ast.Node.Identifier) InnerE...@@ -1280,10 +1282,7 @@ fn astGenIdent(self: *Module, scope: *Scope, ident: *ast.Node.Identifier) InnerE
1280 }1282 }
1281 }1283 }
12821284
1283 // Decl lookup1285 if (self.lookupDeclName(scope, ident_name)) |decl| {
1284 const namespace = scope.namespace();
1285 const name_hash = namespace.fullyQualifiedNameHash(ident_name);
1286 if (self.decl_table.getValue(name_hash)) |decl| {
1287 const src = tree.token_locs[ident.token].start;1286 const src = tree.token_locs[ident.token].start;
1288 return try self.addZIRInst(scope, src, zir.Inst.DeclValInModule, .{ .decl = decl }, .{});1287 return try self.addZIRInst(scope, src, zir.Inst.DeclValInModule, .{ .decl = decl }, .{});
1289 }1288 }
...@@ -1307,24 +1306,26 @@ fn astGenStringLiteral(self: *Module, scope: *Scope, str_lit: *ast.Node.StringLi...@@ -1307,24 +1306,26 @@ fn astGenStringLiteral(self: *Module, scope: *Scope, str_lit: *ast.Node.StringLi
1307 };1306 };
13081307
1309 const src = tree.token_locs[str_lit.token].start;1308 const src = tree.token_locs[str_lit.token].start;
1310 const str_inst = try self.addZIRInst(scope, src, zir.Inst.Str, .{ .bytes = bytes }, .{});1309 return self.addZIRInst(scope, src, zir.Inst.Str, .{ .bytes = bytes }, .{});
1311 return self.addZIRInst(scope, src, zir.Inst.Ref, .{ .operand = str_inst }, .{});
1312}1310}
13131311
1314fn astGenIntegerLiteral(self: *Module, scope: *Scope, int_lit: *ast.Node.IntegerLiteral) InnerError!*zir.Inst {1312fn astGenIntegerLiteral(self: *Module, scope: *Scope, int_lit: *ast.Node.IntegerLiteral) InnerError!*zir.Inst {
1315 const arena = scope.arena();1313 const arena = scope.arena();
1316 const tree = scope.tree();1314 const tree = scope.tree();
1317 var bytes = tree.tokenSlice(int_lit.token);1315 const prefixed_bytes = tree.tokenSlice(int_lit.token);
1318 const base = if (mem.startsWith(u8, bytes, "0x"))1316 const base = if (mem.startsWith(u8, prefixed_bytes, "0x"))
1319 161317 16
1320 else if (mem.startsWith(u8, bytes, "0o"))1318 else if (mem.startsWith(u8, prefixed_bytes, "0o"))
1321 81319 8
1322 else if (mem.startsWith(u8, bytes, "0b"))1320 else if (mem.startsWith(u8, prefixed_bytes, "0b"))
1323 21321 2
1324 else1322 else
1325 @as(u8, 10);1323 @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
1329 if (std.fmt.parseInt(u64, bytes, base)) |small_int| {1330 if (std.fmt.parseInt(u64, bytes, base)) |small_int| {
1330 const int_payload = try arena.create(Value.Payload.Int_u64);1331 const int_payload = try arena.create(Value.Payload.Int_u64);
...@@ -1647,9 +1648,9 @@ fn analyzeRootZIRModule(self: *Module, root_scope: *Scope.ZIRModule) !void {...@@ -1647,9 +1648,9 @@ fn analyzeRootZIRModule(self: *Module, root_scope: *Scope.ZIRModule) !void {
1647 // appendAssumeCapacity.1648 // appendAssumeCapacity.
1648 try self.work_queue.ensureUnusedCapacity(src_module.decls.len);1649 try self.work_queue.ensureUnusedCapacity(src_module.decls.len);
16491650
1650 for (src_module.decls) |decl| {1651 for (src_module.decls) |src_decl| {
1651 if (decl.cast(zir.Inst.Export)) |export_inst| {1652 if (src_decl.inst.cast(zir.Inst.Export)) |export_inst| {
1652 _ = try self.resolveDecl(&root_scope.base, &export_inst.base);1653 _ = try self.resolveDecl(&root_scope.base, src_decl);
1653 }1654 }
1654 }1655 }
1655 },1656 },
...@@ -1662,7 +1663,7 @@ fn analyzeRootZIRModule(self: *Module, root_scope: *Scope.ZIRModule) !void {...@@ -1662,7 +1663,7 @@ fn analyzeRootZIRModule(self: *Module, root_scope: *Scope.ZIRModule) !void {
1662 => {1663 => {
1663 const src_module = try self.getSrcModule(root_scope);1664 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);
1666 defer exports_to_resolve.deinit();1667 defer exports_to_resolve.deinit();
16671668
1668 // Keep track of the decls that we expect to see in this file so that1669 // 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 {...@@ -1687,8 +1688,8 @@ fn analyzeRootZIRModule(self: *Module, root_scope: *Scope.ZIRModule) !void {
1687 try self.markOutdatedDecl(decl);1688 try self.markOutdatedDecl(decl);
1688 decl.contents_hash = src_decl.contents_hash;1689 decl.contents_hash = src_decl.contents_hash;
1689 }1690 }
1690 } else if (src_decl.cast(zir.Inst.Export)) |export_inst| {1691 } else if (src_decl.inst.cast(zir.Inst.Export)) |export_inst| {
1691 try exports_to_resolve.append(&export_inst.base);1692 try exports_to_resolve.append(src_decl);
1692 }1693 }
1693 }1694 }
1694 {1695 {
...@@ -1700,8 +1701,8 @@ fn analyzeRootZIRModule(self: *Module, root_scope: *Scope.ZIRModule) !void {...@@ -1700,8 +1701,8 @@ fn analyzeRootZIRModule(self: *Module, root_scope: *Scope.ZIRModule) !void {
1700 try self.deleteDecl(kv.key);1701 try self.deleteDecl(kv.key);
1701 }1702 }
1702 }1703 }
1703 for (exports_to_resolve.items) |export_inst| {1704 for (exports_to_resolve.items) |export_decl| {
1704 _ = try self.resolveDecl(&root_scope.base, export_inst);1705 _ = try self.resolveDecl(&root_scope.base, export_decl);
1705 }1706 }
1706 },1707 },
1707 }1708 }
...@@ -1945,7 +1946,7 @@ fn createNewDecl(...@@ -1945,7 +1946,7 @@ fn createNewDecl(
1945 return new_decl;1946 return new_decl;
1946}1947}
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 {
1949 var decl_scope: Scope.DeclAnalysis = .{1950 var decl_scope: Scope.DeclAnalysis = .{
1950 .decl = new_decl,1951 .decl = new_decl,
1951 .arena = std.heap.ArenaAllocator.init(self.allocator),1952 .arena = std.heap.ArenaAllocator.init(self.allocator),
...@@ -1954,7 +1955,7 @@ fn analyzeNewDecl(self: *Module, new_decl: *Decl, old_inst: *zir.Inst) InnerErro...@@ -1954,7 +1955,7 @@ fn analyzeNewDecl(self: *Module, new_decl: *Decl, old_inst: *zir.Inst) InnerErro
19541955
1955 new_decl.analysis = .in_progress;1956 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) {
1958 error.OutOfMemory => return error.OutOfMemory,1959 error.OutOfMemory => return error.OutOfMemory,
1959 error.AnalysisFail => {1960 error.AnalysisFail => {
1960 switch (new_decl.analysis) {1961 switch (new_decl.analysis) {
...@@ -1986,33 +1987,32 @@ fn analyzeNewDecl(self: *Module, new_decl: *Decl, old_inst: *zir.Inst) InnerErro...@@ -1986,33 +1987,32 @@ fn analyzeNewDecl(self: *Module, new_decl: *Decl, old_inst: *zir.Inst) InnerErro
1986 }1987 }
1987}1988}
19881989
1989fn resolveDecl(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*Decl {1990fn resolveDecl(self: *Module, scope: *Scope, src_decl: *zir.Decl) InnerError!*Decl {
1990 assert(old_inst.name.len == 0);
1991 // If the name is empty, then we make this an anonymous Decl.1991 // If the name is empty, then we make this an anonymous Decl.
1992 const scope_decl = scope.decl().?;1992 const scope_decl = scope.decl().?;
1993 const new_decl = try self.allocateNewDecl(scope, scope_decl.src_index, old_inst.contents_hash);1993 const new_decl = try self.allocateNewDecl(scope, scope_decl.src_index, src_decl.contents_hash);
1994 try self.analyzeNewDecl(new_decl, old_inst);1994 try self.analyzeNewDecl(new_decl, src_decl);
1995 return new_decl;1995 return new_decl;
1996 //const name_hash = Decl.hashSimpleName(old_inst.name);1996 //const name_hash = Decl.hashSimpleName(src_decl.name);
1997 //if (self.decl_table.get(name_hash)) |kv| {1997 //if (self.decl_table.get(name_hash)) |kv| {
1998 // const decl = kv.value;1998 // const decl = kv.value;
1999 // decl.src = old_inst.src;1999 // decl.src = src_decl.src;
2000 // try self.reAnalyzeDecl(decl, old_inst);2000 // try self.reAnalyzeDecl(decl, src_decl);
2001 // return decl;2001 // return decl;
2002 //} else if (old_inst.cast(zir.Inst.DeclVal)) |decl_val| {2002 //} else if (src_decl.cast(zir.Inst.DeclVal)) |decl_val| {
2003 // // This is just a named reference to another decl.2003 // // This is just a named reference to another decl.
2004 // return self.analyzeDeclVal(scope, decl_val);2004 // return self.analyzeDeclVal(scope, decl_val);
2005 //} else {2005 //} else {
2006 // const new_decl = try self.createNewDecl(scope, old_inst.name, old_inst.src, name_hash, old_inst.contents_hash);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, old_inst);2007 // try self.analyzeNewDecl(new_decl, src_decl);
20082008
2009 // return new_decl;2009 // return new_decl;
2010 //}2010 //}
2011}2011}
20122012
2013/// Declares a dependency on the decl.2013/// Declares a dependency on the decl.
2014fn resolveCompleteDecl(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*Decl {2014fn resolveCompleteDecl(self: *Module, scope: *Scope, src_decl: *zir.Decl) InnerError!*Decl {
2015 const decl = try self.resolveDecl(scope, old_inst);2015 const decl = try self.resolveDecl(scope, src_decl);
2016 switch (decl.analysis) {2016 switch (decl.analysis) {
2017 .unreferenced => unreachable,2017 .unreferenced => unreachable,
2018 .in_progress => unreachable,2018 .in_progress => unreachable,
...@@ -2163,7 +2163,6 @@ fn newZIRInst(...@@ -2163,7 +2163,6 @@ fn newZIRInst(
2163 inst.* = .{2163 inst.* = .{
2164 .base = .{2164 .base = .{
2165 .tag = T.base_tag,2165 .tag = T.base_tag,
2166 .name = "",
2167 .src = src,2166 .src = src,
2168 },2167 },
2169 .positionals = positionals,2168 .positionals = positionals,
...@@ -2220,19 +2219,6 @@ fn constInst(self: *Module, scope: *Scope, src: usize, typed_value: TypedValue)...@@ -2220,19 +2219,6 @@ fn constInst(self: *Module, scope: *Scope, src: usize, typed_value: TypedValue)
2220 return &const_inst.base;2219 return &const_inst.base;
2221}2220}
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
2236fn constType(self: *Module, scope: *Scope, src: usize, ty: Type) !*Inst {2222fn constType(self: *Module, scope: *Scope, src: usize, ty: Type) !*Inst {
2237 return self.constInst(scope, src, .{2223 return self.constInst(scope, src, .{
2238 .ty = Type.initTag(.type),2224 .ty = Type.initTag(.type),
...@@ -2339,15 +2325,10 @@ fn analyzeInst(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*In...@@ -2339,15 +2325,10 @@ fn analyzeInst(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*In
2339 .compileerror => return self.analyzeInstCompileError(scope, old_inst.cast(zir.Inst.CompileError).?),2325 .compileerror => return self.analyzeInstCompileError(scope, old_inst.cast(zir.Inst.CompileError).?),
2340 .@"const" => return self.analyzeInstConst(scope, old_inst.cast(zir.Inst.Const).?),2326 .@"const" => return self.analyzeInstConst(scope, old_inst.cast(zir.Inst.Const).?),
2341 .declref => return self.analyzeInstDeclRef(scope, old_inst.cast(zir.Inst.DeclRef).?),2327 .declref => return self.analyzeInstDeclRef(scope, old_inst.cast(zir.Inst.DeclRef).?),
2328 .declref_str => return self.analyzeInstDeclRefStr(scope, old_inst.cast(zir.Inst.DeclRefStr).?),
2342 .declval => return self.analyzeInstDeclVal(scope, old_inst.cast(zir.Inst.DeclVal).?),2329 .declval => return self.analyzeInstDeclVal(scope, old_inst.cast(zir.Inst.DeclVal).?),
2343 .declval_in_module => return self.analyzeInstDeclValInModule(scope, old_inst.cast(zir.Inst.DeclValInModule).?),2330 .declval_in_module => return self.analyzeInstDeclValInModule(scope, old_inst.cast(zir.Inst.DeclValInModule).?),
2344 .str => {2331 .str => return self.analyzeInstStr(scope, old_inst.cast(zir.Inst.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 },
2351 .int => {2332 .int => {
2352 const big_int = old_inst.cast(zir.Inst.Int).?.positionals.int;2333 const big_int = old_inst.cast(zir.Inst.Int).?.positionals.int;
2353 return self.constIntBig(scope, old_inst.src, Type.initTag(.comptime_int), big_int);2334 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...@@ -2363,7 +2344,6 @@ fn analyzeInst(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*In
2363 .@"fn" => return self.analyzeInstFn(scope, old_inst.cast(zir.Inst.Fn).?),2344 .@"fn" => return self.analyzeInstFn(scope, old_inst.cast(zir.Inst.Fn).?),
2364 .@"export" => return self.analyzeInstExport(scope, old_inst.cast(zir.Inst.Export).?),2345 .@"export" => return self.analyzeInstExport(scope, old_inst.cast(zir.Inst.Export).?),
2365 .primitive => return self.analyzeInstPrimitive(scope, old_inst.cast(zir.Inst.Primitive).?),2346 .primitive => return self.analyzeInstPrimitive(scope, old_inst.cast(zir.Inst.Primitive).?),
2366 .ref => return self.analyzeInstRef(scope, old_inst.cast(zir.Inst.Ref).?),
2367 .fntype => return self.analyzeInstFnType(scope, old_inst.cast(zir.Inst.FnType).?),2347 .fntype => return self.analyzeInstFnType(scope, old_inst.cast(zir.Inst.FnType).?),
2368 .intcast => return self.analyzeInstIntCast(scope, old_inst.cast(zir.Inst.IntCast).?),2348 .intcast => return self.analyzeInstIntCast(scope, old_inst.cast(zir.Inst.IntCast).?),
2369 .bitcast => return self.analyzeInstBitCast(scope, old_inst.cast(zir.Inst.BitCast).?),2349 .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...@@ -2376,9 +2356,75 @@ fn analyzeInst(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*In
2376 }2356 }
2377}2357}
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
2379fn analyzeInstExport(self: *Module, scope: *Scope, export_inst: *zir.Inst.Export) InnerError!*Inst {2424fn analyzeInstExport(self: *Module, scope: *Scope, export_inst: *zir.Inst.Export) InnerError!*Inst {
2380 const symbol_name = try self.resolveConstString(scope, export_inst.positionals.symbol_name);2425 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});
2382 try self.analyzeExport(scope, export_inst.base.src, symbol_name, exported_decl);2428 try self.analyzeExport(scope, export_inst.base.src, symbol_name, exported_decl);
2383 return self.constVoid(scope, export_inst.base.src);2429 return self.constVoid(scope, export_inst.base.src);
2384}2430}
...@@ -2392,26 +2438,13 @@ fn analyzeInstBreakpoint(self: *Module, scope: *Scope, inst: *zir.Inst.Breakpoin...@@ -2392,26 +2438,13 @@ fn analyzeInstBreakpoint(self: *Module, scope: *Scope, inst: *zir.Inst.Breakpoin
2392 return self.addNewInstArgs(b, inst.base.src, Type.initTag(.void), Inst.Breakpoint, {});2438 return self.addNewInstArgs(b, inst.base.src, Type.initTag(.void), Inst.Breakpoint, {});
2393}2439}
23942440
2395fn analyzeInstRef(self: *Module, scope: *Scope, inst: *zir.Inst.Ref) InnerError!*Inst {2441fn analyzeInstDeclRefStr(self: *Module, scope: *Scope, inst: *zir.Inst.DeclRefStr) InnerError!*Inst {
2396 const decl = try self.resolveCompleteDecl(scope, inst.positionals.operand);2442 const decl_name = try self.resolveConstString(scope, inst.positionals.name);
2397 return self.analyzeDeclRef(scope, inst.base.src, decl);2443 return self.analyzeDeclRefByName(scope, inst.base.src, decl_name);
2398}2444}
23992445
2400fn analyzeInstDeclRef(self: *Module, scope: *Scope, inst: *zir.Inst.DeclRef) InnerError!*Inst {2446fn analyzeInstDeclRef(self: *Module, scope: *Scope, inst: *zir.Inst.DeclRef) InnerError!*Inst {
2401 const decl_name = try self.resolveConstString(scope, inst.positionals.name);2447 return self.analyzeDeclRefByName(scope, inst.base.src, 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 }
2415}2448}
24162449
2417fn analyzeDeclVal(self: *Module, scope: *Scope, inst: *zir.Inst.DeclVal) InnerError!*Decl {2450fn 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...@@ -2465,6 +2498,12 @@ fn analyzeDeclRef(self: *Module, scope: *Scope, src: usize, decl: *Decl) InnerEr
2465 });2498 });
2466}2499}
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
2468fn analyzeInstCall(self: *Module, scope: *Scope, inst: *zir.Inst.Call) InnerError!*Inst {2507fn analyzeInstCall(self: *Module, scope: *Scope, inst: *zir.Inst.Call) InnerError!*Inst {
2469 const func = try self.resolveInst(scope, inst.positionals.func);2508 const func = try self.resolveInst(scope, inst.positionals.func);
2470 if (func.ty.zigTypeTag() != .Fn)2509 if (func.ty.zigTypeTag() != .Fn)
src-self-hosted/zir.zig+125-153
...@@ -12,19 +12,23 @@ const TypedValue = @import("TypedValue.zig");...@@ -12,19 +12,23 @@ const TypedValue = @import("TypedValue.zig");
12const ir = @import("ir.zig");12const ir = @import("ir.zig");
13const IrModule = @import("Module.zig");13const 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
15/// These are instructions that correspond to the ZIR text format. See `ir.Inst` for26/// These are instructions that correspond to the ZIR text format. See `ir.Inst` for
16/// in-memory, analyzed instructions with types and values.27/// 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.
19pub const Inst = struct {28pub const Inst = struct {
20 tag: Tag,29 tag: Tag,
21 /// Byte offset into the source.30 /// Byte offset into the source.
22 src: usize,31 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
28 /// Pre-allocated field for mapping ZIR text instructions to post-analysis instructions.32 /// Pre-allocated field for mapping ZIR text instructions to post-analysis instructions.
29 analyzed_inst: *ir.Inst = undefined,33 analyzed_inst: *ir.Inst = undefined,
3034
...@@ -37,11 +41,14 @@ pub const Inst = struct {...@@ -37,11 +41,14 @@ pub const Inst = struct {
37 @"const",41 @"const",
38 /// Represents a pointer to a global decl by name.42 /// Represents a pointer to a global decl by name.
39 declref,43 declref,
44 /// Represents a pointer to a global decl by string name.
45 declref_str,
40 /// The syntax `@foo` is equivalent to `declval("foo")`.46 /// The syntax `@foo` is equivalent to `declval("foo")`.
41 /// declval is equivalent to declref followed by deref.47 /// declval is equivalent to declref followed by deref.
42 declval,48 declval,
43 /// Same as declval but the parameter is a `*Module.Decl` rather than a name.49 /// Same as declval but the parameter is a `*Module.Decl` rather than a name.
44 declval_in_module,50 declval_in_module,
51 /// String Literal. Makes an anonymous Decl and then takes a pointer to it.
45 str,52 str,
46 int,53 int,
47 ptrtoint,54 ptrtoint,
...@@ -56,7 +63,6 @@ pub const Inst = struct {...@@ -56,7 +63,6 @@ pub const Inst = struct {
56 fntype,63 fntype,
57 @"export",64 @"export",
58 primitive,65 primitive,
59 ref,
60 intcast,66 intcast,
61 bitcast,67 bitcast,
62 elemptr,68 elemptr,
...@@ -72,6 +78,7 @@ pub const Inst = struct {...@@ -72,6 +78,7 @@ pub const Inst = struct {
72 .breakpoint => Breakpoint,78 .breakpoint => Breakpoint,
73 .call => Call,79 .call => Call,
74 .declref => DeclRef,80 .declref => DeclRef,
81 .declref_str => DeclRefStr,
75 .declval => DeclVal,82 .declval => DeclVal,
76 .declval_in_module => DeclValInModule,83 .declval_in_module => DeclValInModule,
77 .compileerror => CompileError,84 .compileerror => CompileError,
...@@ -89,7 +96,6 @@ pub const Inst = struct {...@@ -89,7 +96,6 @@ pub const Inst = struct {
89 .@"fn" => Fn,96 .@"fn" => Fn,
90 .@"export" => Export,97 .@"export" => Export,
91 .primitive => Primitive,98 .primitive => Primitive,
92 .ref => Ref,
93 .fntype => FnType,99 .fntype => FnType,
94 .intcast => IntCast,100 .intcast => IntCast,
95 .bitcast => BitCast,101 .bitcast => BitCast,
...@@ -134,6 +140,16 @@ pub const Inst = struct {...@@ -134,6 +140,16 @@ pub const Inst = struct {
134 pub const base_tag = Tag.declref;140 pub const base_tag = Tag.declref;
135 base: Inst,141 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
137 positionals: struct {153 positionals: struct {
138 name: *Inst,154 name: *Inst,
139 },155 },
...@@ -316,17 +332,7 @@ pub const Inst = struct {...@@ -316,17 +332,7 @@ pub const Inst = struct {
316332
317 positionals: struct {333 positionals: struct {
318 symbol_name: *Inst,334 symbol_name: *Inst,
319 value: *Inst,335 decl_name: []const u8,
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,
330 },336 },
331 kw_args: struct {},337 kw_args: struct {},
332 };338 };
...@@ -500,7 +506,7 @@ pub const ErrorMsg = struct {...@@ -500,7 +506,7 @@ pub const ErrorMsg = struct {
500};506};
501507
502pub const Module = struct {508pub const Module = struct {
503 decls: []*Inst,509 decls: []*Decl,
504 arena: std.heap.ArenaAllocator,510 arena: std.heap.ArenaAllocator,
505 error_msg: ?ErrorMsg = null,511 error_msg: ?ErrorMsg = null,
506512
...@@ -519,10 +525,10 @@ pub const Module = struct {...@@ -519,10 +525,10 @@ pub const Module = struct {
519 self.writeToStream(std.heap.page_allocator, std.io.getStdErr().outStream()) catch {};525 self.writeToStream(std.heap.page_allocator, std.io.getStdErr().outStream()) catch {};
520 }526 }
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
524 const DeclAndIndex = struct {530 const DeclAndIndex = struct {
525 decl: *Inst,531 decl: *Decl,
526 index: usize,532 index: usize,
527 };533 };
528534
...@@ -549,18 +555,18 @@ pub const Module = struct {...@@ -549,18 +555,18 @@ pub const Module = struct {
549 try inst_table.ensureCapacity(self.decls.len);555 try inst_table.ensureCapacity(self.decls.len);
550556
551 for (self.decls) |decl, decl_i| {557 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| {
555 for (fn_inst.positionals.body.instructions) |inst, inst_i| {561 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 });
557 }563 }
558 }564 }
559 }565 }
560566
561 for (self.decls) |decl, i| {567 for (self.decls) |decl, i| {
562 try stream.print("@{} ", .{decl.name});568 try stream.print("@{} ", .{decl.name});
563 try self.writeInstToStream(stream, decl, &inst_table);569 try self.writeInstToStream(stream, decl.inst, &inst_table);
564 try stream.writeByte('\n');570 try stream.writeByte('\n');
565 }571 }
566 }572 }
...@@ -568,41 +574,41 @@ pub const Module = struct {...@@ -568,41 +574,41 @@ pub const Module = struct {
568 fn writeInstToStream(574 fn writeInstToStream(
569 self: Module,575 self: Module,
570 stream: var,576 stream: var,
571 decl: *Inst,577 inst: *Inst,
572 inst_table: *const InstPtrTable,578 inst_table: *const InstPtrTable,
573 ) @TypeOf(stream).Error!void {579 ) @TypeOf(stream).Error!void {
574 // TODO I tried implementing this with an inline for loop and hit a compiler bug580 // TODO I tried implementing this with an inline for loop and hit a compiler bug
575 switch (decl.tag) {581 switch (inst.tag) {
576 .breakpoint => return self.writeInstToStreamGeneric(stream, .breakpoint, decl, inst_table),582 .breakpoint => return self.writeInstToStreamGeneric(stream, .breakpoint, inst, inst_table),
577 .call => return self.writeInstToStreamGeneric(stream, .call, decl, inst_table),583 .call => return self.writeInstToStreamGeneric(stream, .call, inst, inst_table),
578 .declref => return self.writeInstToStreamGeneric(stream, .declref, decl, inst_table),584 .declref => return self.writeInstToStreamGeneric(stream, .declref, inst, inst_table),
579 .declval => return self.writeInstToStreamGeneric(stream, .declval, decl, inst_table),585 .declref_str => return self.writeInstToStreamGeneric(stream, .declref_str, inst, inst_table),
580 .declval_in_module => return self.writeInstToStreamGeneric(stream, .declval_in_module, decl, inst_table),586 .declval => return self.writeInstToStreamGeneric(stream, .declval, inst, inst_table),
581 .compileerror => return self.writeInstToStreamGeneric(stream, .compileerror, decl, inst_table),587 .declval_in_module => return self.writeInstToStreamGeneric(stream, .declval_in_module, inst, inst_table),
582 .@"const" => return self.writeInstToStreamGeneric(stream, .@"const", decl, inst_table),588 .compileerror => return self.writeInstToStreamGeneric(stream, .compileerror, inst, inst_table),
583 .str => return self.writeInstToStreamGeneric(stream, .str, decl, inst_table),589 .@"const" => return self.writeInstToStreamGeneric(stream, .@"const", inst, inst_table),
584 .int => return self.writeInstToStreamGeneric(stream, .int, decl, inst_table),590 .str => return self.writeInstToStreamGeneric(stream, .str, inst, inst_table),
585 .ptrtoint => return self.writeInstToStreamGeneric(stream, .ptrtoint, decl, inst_table),591 .int => return self.writeInstToStreamGeneric(stream, .int, inst, inst_table),
586 .fieldptr => return self.writeInstToStreamGeneric(stream, .fieldptr, decl, inst_table),592 .ptrtoint => return self.writeInstToStreamGeneric(stream, .ptrtoint, inst, inst_table),
587 .deref => return self.writeInstToStreamGeneric(stream, .deref, decl, inst_table),593 .fieldptr => return self.writeInstToStreamGeneric(stream, .fieldptr, inst, inst_table),
588 .as => return self.writeInstToStreamGeneric(stream, .as, decl, inst_table),594 .deref => return self.writeInstToStreamGeneric(stream, .deref, inst, inst_table),
589 .@"asm" => return self.writeInstToStreamGeneric(stream, .@"asm", decl, inst_table),595 .as => return self.writeInstToStreamGeneric(stream, .as, inst, inst_table),
590 .@"unreachable" => return self.writeInstToStreamGeneric(stream, .@"unreachable", decl, inst_table),596 .@"asm" => return self.writeInstToStreamGeneric(stream, .@"asm", inst, inst_table),
591 .@"return" => return self.writeInstToStreamGeneric(stream, .@"return", decl, inst_table),597 .@"unreachable" => return self.writeInstToStreamGeneric(stream, .@"unreachable", inst, inst_table),
592 .returnvoid => return self.writeInstToStreamGeneric(stream, .returnvoid, decl, inst_table),598 .@"return" => return self.writeInstToStreamGeneric(stream, .@"return", inst, inst_table),
593 .@"fn" => return self.writeInstToStreamGeneric(stream, .@"fn", decl, inst_table),599 .returnvoid => return self.writeInstToStreamGeneric(stream, .returnvoid, inst, inst_table),
594 .@"export" => return self.writeInstToStreamGeneric(stream, .@"export", decl, inst_table),600 .@"fn" => return self.writeInstToStreamGeneric(stream, .@"fn", inst, inst_table),
595 .ref => return self.writeInstToStreamGeneric(stream, .ref, decl, inst_table),601 .@"export" => return self.writeInstToStreamGeneric(stream, .@"export", inst, inst_table),
596 .primitive => return self.writeInstToStreamGeneric(stream, .primitive, decl, inst_table),602 .primitive => return self.writeInstToStreamGeneric(stream, .primitive, inst, inst_table),
597 .fntype => return self.writeInstToStreamGeneric(stream, .fntype, decl, inst_table),603 .fntype => return self.writeInstToStreamGeneric(stream, .fntype, inst, inst_table),
598 .intcast => return self.writeInstToStreamGeneric(stream, .intcast, decl, inst_table),604 .intcast => return self.writeInstToStreamGeneric(stream, .intcast, inst, inst_table),
599 .bitcast => return self.writeInstToStreamGeneric(stream, .bitcast, decl, inst_table),605 .bitcast => return self.writeInstToStreamGeneric(stream, .bitcast, inst, inst_table),
600 .elemptr => return self.writeInstToStreamGeneric(stream, .elemptr, decl, inst_table),606 .elemptr => return self.writeInstToStreamGeneric(stream, .elemptr, inst, inst_table),
601 .add => return self.writeInstToStreamGeneric(stream, .add, decl, inst_table),607 .add => return self.writeInstToStreamGeneric(stream, .add, inst, inst_table),
602 .cmp => return self.writeInstToStreamGeneric(stream, .cmp, decl, inst_table),608 .cmp => return self.writeInstToStreamGeneric(stream, .cmp, inst, inst_table),
603 .condbr => return self.writeInstToStreamGeneric(stream, .condbr, decl, inst_table),609 .condbr => return self.writeInstToStreamGeneric(stream, .condbr, inst, inst_table),
604 .isnull => return self.writeInstToStreamGeneric(stream, .isnull, decl, inst_table),610 .isnull => return self.writeInstToStreamGeneric(stream, .isnull, inst, inst_table),
605 .isnonnull => return self.writeInstToStreamGeneric(stream, .isnonnull, decl, inst_table),611 .isnonnull => return self.writeInstToStreamGeneric(stream, .isnonnull, inst, inst_table),
606 }612 }
607 }613 }
608614
...@@ -685,7 +691,7 @@ pub const Module = struct {...@@ -685,7 +691,7 @@ pub const Module = struct {
685 if (info.index) |i| {691 if (info.index) |i| {
686 try stream.print("%{}", .{info.index});692 try stream.print("%{}", .{info.index});
687 } else {693 } else {
688 try stream.print("@{}", .{info.inst.name});694 try stream.print("@{}", .{info.name});
689 }695 }
690 } else if (inst.cast(Inst.DeclVal)) |decl_val| {696 } else if (inst.cast(Inst.DeclVal)) |decl_val| {
691 try stream.print("@{}", .{decl_val.positionals.name});697 try stream.print("@{}", .{decl_val.positionals.name});
...@@ -732,7 +738,7 @@ const Parser = struct {...@@ -732,7 +738,7 @@ const Parser = struct {
732 arena: std.heap.ArenaAllocator,738 arena: std.heap.ArenaAllocator,
733 i: usize,739 i: usize,
734 source: [:0]const u8,740 source: [:0]const u8,
735 decls: std.ArrayListUnmanaged(*Inst),741 decls: std.ArrayListUnmanaged(*Decl),
736 global_name_map: *std.StringHashMap(usize),742 global_name_map: *std.StringHashMap(usize),
737 error_msg: ?ErrorMsg = null,743 error_msg: ?ErrorMsg = null,
738 unnamed_index: usize,744 unnamed_index: usize,
...@@ -761,12 +767,12 @@ const Parser = struct {...@@ -761,12 +767,12 @@ const Parser = struct {
761 skipSpace(self);767 skipSpace(self);
762 try requireEatBytes(self, "=");768 try requireEatBytes(self, "=");
763 skipSpace(self);769 skipSpace(self);
764 const inst = try parseInstruction(self, &body_context, ident);770 const decl = try parseInstruction(self, &body_context, ident);
765 const ident_index = body_context.instructions.items.len;771 const ident_index = body_context.instructions.items.len;
766 if (try body_context.name_map.put(ident, ident_index)) |_| {772 if (try body_context.name_map.put(ident, ident_index)) |_| {
767 return self.fail("redefinition of identifier '{}'", .{ident});773 return self.fail("redefinition of identifier '{}'", .{ident});
768 }774 }
769 try body_context.instructions.append(inst);775 try body_context.instructions.append(decl.inst);
770 continue;776 continue;
771 },777 },
772 ' ', '\n' => continue,778 ' ', '\n' => continue,
...@@ -916,7 +922,7 @@ const Parser = struct {...@@ -916,7 +922,7 @@ const Parser = struct {
916 return error.ParseFailure;922 return error.ParseFailure;
917 }923 }
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 {
920 const contents_start = self.i;926 const contents_start = self.i;
921 const fn_name = try skipToAndOver(self, '(');927 const fn_name = try skipToAndOver(self, '(');
922 inline for (@typeInfo(Inst.Tag).Enum.fields) |field| {928 inline for (@typeInfo(Inst.Tag).Enum.fields) |field| {
...@@ -935,10 +941,9 @@ const Parser = struct {...@@ -935,10 +941,9 @@ const Parser = struct {
935 body_ctx: ?*Body,941 body_ctx: ?*Body,
936 inst_name: []const u8,942 inst_name: []const u8,
937 contents_start: usize,943 contents_start: usize,
938 ) InnerError!*Inst {944 ) InnerError!*Decl {
939 const inst_specific = try self.arena.allocator.create(InstType);945 const inst_specific = try self.arena.allocator.create(InstType);
940 inst_specific.base = .{946 inst_specific.base = .{
941 .name = inst_name,
942 .src = self.i,947 .src = self.i,
943 .tag = InstType.base_tag,948 .tag = InstType.base_tag,
944 };949 };
...@@ -988,10 +993,15 @@ const Parser = struct {...@@ -988,10 +993,15 @@ const Parser = struct {
988 }993 }
989 try requireEatBytes(self, ")");994 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 };
992 //std.debug.warn("parsed {} = '{}'\n", .{ inst_specific.base.name, inst_specific.base.contents });1002 //std.debug.warn("parsed {} = '{}'\n", .{ inst_specific.base.name, inst_specific.base.contents });
9931003
994 return &inst_specific.base;1004 return decl;
995 }1005 }
9961006
997 fn parseParameterGeneric(self: *Parser, comptime T: type, body_ctx: ?*Body) !T {1007 fn parseParameterGeneric(self: *Parser, comptime T: type, body_ctx: ?*Body) !T {
...@@ -1075,7 +1085,6 @@ const Parser = struct {...@@ -1075,7 +1085,6 @@ const Parser = struct {
1075 const declval = try self.arena.allocator.create(Inst.DeclVal);1085 const declval = try self.arena.allocator.create(Inst.DeclVal);
1076 declval.* = .{1086 declval.* = .{
1077 .base = .{1087 .base = .{
1078 .name = try self.generateName(),
1079 .src = src,1088 .src = src,
1080 .tag = Inst.DeclVal.base_tag,1089 .tag = Inst.DeclVal.base_tag,
1081 },1090 },
...@@ -1088,7 +1097,7 @@ const Parser = struct {...@@ -1088,7 +1097,7 @@ const Parser = struct {
1088 if (local_ref) {1097 if (local_ref) {
1089 return body_ctx.?.instructions.items[kv.value];1098 return body_ctx.?.instructions.items[kv.value];
1090 } else {1099 } else {
1091 return self.decls.items[kv.value];1100 return self.decls.items[kv.value].inst;
1092 }1101 }
1093 }1102 }
10941103
...@@ -1107,7 +1116,7 @@ pub fn emit(allocator: *Allocator, old_module: IrModule) !Module {...@@ -1107,7 +1116,7 @@ pub fn emit(allocator: *Allocator, old_module: IrModule) !Module {
1107 .old_module = &old_module,1116 .old_module = &old_module,
1108 .next_auto_name = 0,1117 .next_auto_name = 0,
1109 .names = std.StringHashMap(void).init(allocator),1118 .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),
1111 };1120 };
1112 defer ctx.decls.deinit(allocator);1121 defer ctx.decls.deinit(allocator);
1113 defer ctx.names.deinit();1122 defer ctx.names.deinit();
...@@ -1126,10 +1135,10 @@ const EmitZIR = struct {...@@ -1126,10 +1135,10 @@ const EmitZIR = struct {
1126 allocator: *Allocator,1135 allocator: *Allocator,
1127 arena: std.heap.ArenaAllocator,1136 arena: std.heap.ArenaAllocator,
1128 old_module: *const IrModule,1137 old_module: *const IrModule,
1129 decls: std.ArrayListUnmanaged(*Inst),1138 decls: std.ArrayListUnmanaged(*Decl),
1130 names: std.StringHashMap(void),1139 names: std.StringHashMap(void),
1131 next_auto_name: usize,1140 next_auto_name: usize,
1132 primitive_table: std.AutoHashMap(Inst.Primitive.Builtin, *Inst),1141 primitive_table: std.AutoHashMap(Inst.Primitive.Builtin, *Decl),
11331142
1134 fn emit(self: *EmitZIR) !void {1143 fn emit(self: *EmitZIR) !void {
1135 // Put all the Decls in a list and sort them by name to avoid nondeterminism introduced1144 // Put all the Decls in a list and sort them by name to avoid nondeterminism introduced
...@@ -1156,22 +1165,20 @@ const EmitZIR = struct {...@@ -1156,22 +1165,20 @@ const EmitZIR = struct {
1156 for (src_decls.items) |ir_decl| {1165 for (src_decls.items) |ir_decl| {
1157 if (self.old_module.export_owners.getValue(ir_decl)) |exports| {1166 if (self.old_module.export_owners.getValue(ir_decl)) |exports| {
1158 for (exports) |module_export| {1167 for (exports) |module_export| {
1159 const declval = try self.emitDeclVal(ir_decl.src(), mem.spanZ(module_export.exported_decl.name));
1160 const symbol_name = try self.emitStringLiteral(module_export.src, module_export.options.name);1168 const symbol_name = try self.emitStringLiteral(module_export.src, module_export.options.name);
1161 const export_inst = try self.arena.allocator.create(Inst.Export);1169 const export_inst = try self.arena.allocator.create(Inst.Export);
1162 export_inst.* = .{1170 export_inst.* = .{
1163 .base = .{1171 .base = .{
1164 .name = try self.autoName(),
1165 .src = module_export.src,1172 .src = module_export.src,
1166 .tag = Inst.Export.base_tag,1173 .tag = Inst.Export.base_tag,
1167 },1174 },
1168 .positionals = .{1175 .positionals = .{
1169 .symbol_name = symbol_name,1176 .symbol_name = symbol_name.inst,
1170 .value = declval,1177 .decl_name = mem.spanZ(module_export.exported_decl.name),
1171 },1178 },
1172 .kw_args = .{},1179 .kw_args = .{},
1173 };1180 };
1174 try self.decls.append(self.allocator, &export_inst.base);1181 _ = try self.emitUnnamedDecl(&export_inst.base);
1175 }1182 }
1176 } else {1183 } else {
1177 const new_decl = try self.emitTypedValue(ir_decl.src(), ir_decl.typed_value.most_recent.typed_value);1184 const new_decl = try self.emitTypedValue(ir_decl.src(), ir_decl.typed_value.most_recent.typed_value);
...@@ -1188,7 +1195,7 @@ const EmitZIR = struct {...@@ -1188,7 +1195,7 @@ const EmitZIR = struct {
1188 } else if (const_inst.val.cast(Value.Payload.DeclRef)) |declref| blk: {1195 } else if (const_inst.val.cast(Value.Payload.DeclRef)) |declref| blk: {
1189 break :blk try self.emitDeclRef(inst.src, declref.decl);1196 break :blk try self.emitDeclRef(inst.src, declref.decl);
1190 } else blk: {1197 } 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;
1192 };1199 };
1193 try inst_table.putNoClobber(inst, new_decl);1200 try inst_table.putNoClobber(inst, new_decl);
1194 return new_decl;1201 return new_decl;
...@@ -1201,7 +1208,6 @@ const EmitZIR = struct {...@@ -1201,7 +1208,6 @@ const EmitZIR = struct {
1201 const declval = try self.arena.allocator.create(Inst.DeclVal);1208 const declval = try self.arena.allocator.create(Inst.DeclVal);
1202 declval.* = .{1209 declval.* = .{
1203 .base = .{1210 .base = .{
1204 .name = try self.autoName(),
1205 .src = src,1211 .src = src,
1206 .tag = Inst.DeclVal.base_tag,1212 .tag = Inst.DeclVal.base_tag,
1207 },1213 },
...@@ -1211,12 +1217,11 @@ const EmitZIR = struct {...@@ -1211,12 +1217,11 @@ const EmitZIR = struct {
1211 return &declval.base;1217 return &declval.base;
1212 }1218 }
12131219
1214 fn emitComptimeIntVal(self: *EmitZIR, src: usize, val: Value) !*Inst {1220 fn emitComptimeIntVal(self: *EmitZIR, src: usize, val: Value) !*Decl {
1215 const big_int_space = try self.arena.allocator.create(Value.BigIntSpace);1221 const big_int_space = try self.arena.allocator.create(Value.BigIntSpace);
1216 const int_inst = try self.arena.allocator.create(Inst.Int);1222 const int_inst = try self.arena.allocator.create(Inst.Int);
1217 int_inst.* = .{1223 int_inst.* = .{
1218 .base = .{1224 .base = .{
1219 .name = try self.autoName(),
1220 .src = src,1225 .src = src,
1221 .tag = Inst.Int.base_tag,1226 .tag = Inst.Int.base_tag,
1222 },1227 },
...@@ -1225,34 +1230,29 @@ const EmitZIR = struct {...@@ -1225,34 +1230,29 @@ const EmitZIR = struct {
1225 },1230 },
1226 .kw_args = .{},1231 .kw_args = .{},
1227 };1232 };
1228 try self.decls.append(self.allocator, &int_inst.base);1233 return self.emitUnnamedDecl(&int_inst.base);
1229 return &int_inst.base;
1230 }1234 }
12311235
1232 fn emitDeclRef(self: *EmitZIR, src: usize, decl: *IrModule.Decl) !*Inst {1236 fn emitDeclRef(self: *EmitZIR, src: usize, module_decl: *IrModule.Decl) !*Inst {
1233 const declval = try self.emitDeclVal(src, mem.spanZ(decl.name));1237 const declref_inst = try self.arena.allocator.create(Inst.DeclRef);
1234 const ref_inst = try self.arena.allocator.create(Inst.Ref);1238 declref_inst.* = .{
1235 ref_inst.* = .{
1236 .base = .{1239 .base = .{
1237 .name = try self.autoName(),
1238 .src = src,1240 .src = src,
1239 .tag = Inst.Ref.base_tag,1241 .tag = Inst.DeclRef.base_tag,
1240 },1242 },
1241 .positionals = .{1243 .positionals = .{
1242 .operand = declval,1244 .name = mem.spanZ(module_decl.name),
1243 },1245 },
1244 .kw_args = .{},1246 .kw_args = .{},
1245 };1247 };
1246 try self.decls.append(self.allocator, &ref_inst.base);1248 return &declref_inst.base;
1247
1248 return &ref_inst.base;
1249 }1249 }
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 {
1252 const allocator = &self.arena.allocator;1252 const allocator = &self.arena.allocator;
1253 if (typed_value.val.cast(Value.Payload.DeclRef)) |decl_ref| {1253 if (typed_value.val.cast(Value.Payload.DeclRef)) |decl_ref| {
1254 const decl = decl_ref.decl;1254 const decl = decl_ref.decl;
1255 return self.emitDeclRef(src, decl);1255 return try self.emitUnnamedDecl(try self.emitDeclRef(src, decl));
1256 }1256 }
1257 switch (typed_value.ty.zigTypeTag()) {1257 switch (typed_value.ty.zigTypeTag()) {
1258 .Pointer => {1258 .Pointer => {
...@@ -1279,18 +1279,16 @@ const EmitZIR = struct {...@@ -1279,18 +1279,16 @@ const EmitZIR = struct {
1279 const as_inst = try self.arena.allocator.create(Inst.As);1279 const as_inst = try self.arena.allocator.create(Inst.As);
1280 as_inst.* = .{1280 as_inst.* = .{
1281 .base = .{1281 .base = .{
1282 .name = try self.autoName(),
1283 .src = src,1282 .src = src,
1284 .tag = Inst.As.base_tag,1283 .tag = Inst.As.base_tag,
1285 },1284 },
1286 .positionals = .{1285 .positionals = .{
1287 .dest_type = try self.emitType(src, typed_value.ty),1286 .dest_type = (try self.emitType(src, typed_value.ty)).inst,
1288 .value = try self.emitComptimeIntVal(src, typed_value.val),1287 .value = (try self.emitComptimeIntVal(src, typed_value.val)).inst,
1289 },1288 },
1290 .kw_args = .{},1289 .kw_args = .{},
1291 };1290 };
12921291 return self.emitUnnamedDecl(&as_inst.base);
1293 return &as_inst.base;
1294 },1292 },
1295 .Type => {1293 .Type => {
1296 const ty = typed_value.val.toType();1294 const ty = typed_value.val.toType();
...@@ -1316,7 +1314,6 @@ const EmitZIR = struct {...@@ -1316,7 +1314,6 @@ const EmitZIR = struct {
1316 const fail_inst = try self.arena.allocator.create(Inst.CompileError);1314 const fail_inst = try self.arena.allocator.create(Inst.CompileError);
1317 fail_inst.* = .{1315 fail_inst.* = .{
1318 .base = .{1316 .base = .{
1319 .name = try self.autoName(),
1320 .src = src,1317 .src = src,
1321 .tag = Inst.CompileError.base_tag,1318 .tag = Inst.CompileError.base_tag,
1322 },1319 },
...@@ -1331,7 +1328,6 @@ const EmitZIR = struct {...@@ -1331,7 +1328,6 @@ const EmitZIR = struct {
1331 const fail_inst = try self.arena.allocator.create(Inst.CompileError);1328 const fail_inst = try self.arena.allocator.create(Inst.CompileError);
1332 fail_inst.* = .{1329 fail_inst.* = .{
1333 .base = .{1330 .base = .{
1334 .name = try self.autoName(),
1335 .src = src,1331 .src = src,
1336 .tag = Inst.CompileError.base_tag,1332 .tag = Inst.CompileError.base_tag,
1337 },1333 },
...@@ -1352,18 +1348,16 @@ const EmitZIR = struct {...@@ -1352,18 +1348,16 @@ const EmitZIR = struct {
1352 const fn_inst = try self.arena.allocator.create(Inst.Fn);1348 const fn_inst = try self.arena.allocator.create(Inst.Fn);
1353 fn_inst.* = .{1349 fn_inst.* = .{
1354 .base = .{1350 .base = .{
1355 .name = try self.autoName(),
1356 .src = src,1351 .src = src,
1357 .tag = Inst.Fn.base_tag,1352 .tag = Inst.Fn.base_tag,
1358 },1353 },
1359 .positionals = .{1354 .positionals = .{
1360 .fn_type = fn_type,1355 .fn_type = fn_type.inst,
1361 .body = .{ .instructions = arena_instrs },1356 .body = .{ .instructions = arena_instrs },
1362 },1357 },
1363 .kw_args = .{},1358 .kw_args = .{},
1364 };1359 };
1365 try self.decls.append(self.allocator, &fn_inst.base);1360 return self.emitUnnamedDecl(&fn_inst.base);
1366 return &fn_inst.base;
1367 },1361 },
1368 .Array => {1362 .Array => {
1369 // TODO more checks to make sure this can be emitted as a string literal1363 // TODO more checks to make sure this can be emitted as a string literal
...@@ -1379,7 +1373,6 @@ const EmitZIR = struct {...@@ -1379,7 +1373,6 @@ const EmitZIR = struct {
1379 const str_inst = try self.arena.allocator.create(Inst.Str);1373 const str_inst = try self.arena.allocator.create(Inst.Str);
1380 str_inst.* = .{1374 str_inst.* = .{
1381 .base = .{1375 .base = .{
1382 .name = try self.autoName(),
1383 .src = src,1376 .src = src,
1384 .tag = Inst.Str.base_tag,1377 .tag = Inst.Str.base_tag,
1385 },1378 },
...@@ -1388,8 +1381,7 @@ const EmitZIR = struct {...@@ -1388,8 +1381,7 @@ const EmitZIR = struct {
1388 },1381 },
1389 .kw_args = .{},1382 .kw_args = .{},
1390 };1383 };
1391 try self.decls.append(self.allocator, &str_inst.base);1384 return self.emitUnnamedDecl(&str_inst.base);
1392 return &str_inst.base;
1393 },1385 },
1394 .Void => return self.emitPrimitive(src, .void_value),1386 .Void => return self.emitPrimitive(src, .void_value),
1395 else => |t| std.debug.panic("TODO implement emitTypedValue for {}", .{@tagName(t)}),1387 else => |t| std.debug.panic("TODO implement emitTypedValue for {}", .{@tagName(t)}),
...@@ -1400,7 +1392,6 @@ const EmitZIR = struct {...@@ -1400,7 +1392,6 @@ const EmitZIR = struct {
1400 const new_inst = try self.arena.allocator.create(T);1392 const new_inst = try self.arena.allocator.create(T);
1401 new_inst.* = .{1393 new_inst.* = .{
1402 .base = .{1394 .base = .{
1403 .name = try self.autoName(),
1404 .src = src,1395 .src = src,
1405 .tag = T.base_tag,1396 .tag = T.base_tag,
1406 },1397 },
...@@ -1429,7 +1420,6 @@ const EmitZIR = struct {...@@ -1429,7 +1420,6 @@ const EmitZIR = struct {
1429 }1420 }
1430 new_inst.* = .{1421 new_inst.* = .{
1431 .base = .{1422 .base = .{
1432 .name = try self.autoName(),
1433 .src = inst.src,1423 .src = inst.src,
1434 .tag = Inst.Call.base_tag,1424 .tag = Inst.Call.base_tag,
1435 },1425 },
...@@ -1447,7 +1437,6 @@ const EmitZIR = struct {...@@ -1447,7 +1437,6 @@ const EmitZIR = struct {
1447 const new_inst = try self.arena.allocator.create(Inst.Return);1437 const new_inst = try self.arena.allocator.create(Inst.Return);
1448 new_inst.* = .{1438 new_inst.* = .{
1449 .base = .{1439 .base = .{
1450 .name = try self.autoName(),
1451 .src = inst.src,1440 .src = inst.src,
1452 .tag = Inst.Return.base_tag,1441 .tag = Inst.Return.base_tag,
1453 },1442 },
...@@ -1466,12 +1455,12 @@ const EmitZIR = struct {...@@ -1466,12 +1455,12 @@ const EmitZIR = struct {
14661455
1467 const inputs = try self.arena.allocator.alloc(*Inst, old_inst.args.inputs.len);1456 const inputs = try self.arena.allocator.alloc(*Inst, old_inst.args.inputs.len);
1468 for (inputs) |*elem, i| {1457 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;
1470 }1459 }
14711460
1472 const clobbers = try self.arena.allocator.alloc(*Inst, old_inst.args.clobbers.len);1461 const clobbers = try self.arena.allocator.alloc(*Inst, old_inst.args.clobbers.len);
1473 for (clobbers) |*elem, i| {1462 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;
1475 }1464 }
14761465
1477 const args = try self.arena.allocator.alloc(*Inst, old_inst.args.args.len);1466 const args = try self.arena.allocator.alloc(*Inst, old_inst.args.args.len);
...@@ -1481,18 +1470,17 @@ const EmitZIR = struct {...@@ -1481,18 +1470,17 @@ const EmitZIR = struct {
14811470
1482 new_inst.* = .{1471 new_inst.* = .{
1483 .base = .{1472 .base = .{
1484 .name = try self.autoName(),
1485 .src = inst.src,1473 .src = inst.src,
1486 .tag = Inst.Asm.base_tag,1474 .tag = Inst.Asm.base_tag,
1487 },1475 },
1488 .positionals = .{1476 .positionals = .{
1489 .asm_source = try self.emitStringLiteral(inst.src, old_inst.args.asm_source),1477 .asm_source = (try self.emitStringLiteral(inst.src, old_inst.args.asm_source)).inst,
1490 .return_type = try self.emitType(inst.src, inst.ty),1478 .return_type = (try self.emitType(inst.src, inst.ty)).inst,
1491 },1479 },
1492 .kw_args = .{1480 .kw_args = .{
1493 .@"volatile" = old_inst.args.is_volatile,1481 .@"volatile" = old_inst.args.is_volatile,
1494 .output = if (old_inst.args.output) |o|1482 .output = if (old_inst.args.output) |o|
1495 try self.emitStringLiteral(inst.src, o)1483 (try self.emitStringLiteral(inst.src, o)).inst
1496 else1484 else
1497 null,1485 null,
1498 .inputs = inputs,1486 .inputs = inputs,
...@@ -1507,7 +1495,6 @@ const EmitZIR = struct {...@@ -1507,7 +1495,6 @@ const EmitZIR = struct {
1507 const new_inst = try self.arena.allocator.create(Inst.PtrToInt);1495 const new_inst = try self.arena.allocator.create(Inst.PtrToInt);
1508 new_inst.* = .{1496 new_inst.* = .{
1509 .base = .{1497 .base = .{
1510 .name = try self.autoName(),
1511 .src = inst.src,1498 .src = inst.src,
1512 .tag = Inst.PtrToInt.base_tag,1499 .tag = Inst.PtrToInt.base_tag,
1513 },1500 },
...@@ -1523,12 +1510,11 @@ const EmitZIR = struct {...@@ -1523,12 +1510,11 @@ const EmitZIR = struct {
1523 const new_inst = try self.arena.allocator.create(Inst.BitCast);1510 const new_inst = try self.arena.allocator.create(Inst.BitCast);
1524 new_inst.* = .{1511 new_inst.* = .{
1525 .base = .{1512 .base = .{
1526 .name = try self.autoName(),
1527 .src = inst.src,1513 .src = inst.src,
1528 .tag = Inst.BitCast.base_tag,1514 .tag = Inst.BitCast.base_tag,
1529 },1515 },
1530 .positionals = .{1516 .positionals = .{
1531 .dest_type = try self.emitType(inst.src, inst.ty),1517 .dest_type = (try self.emitType(inst.src, inst.ty)).inst,
1532 .operand = try self.resolveInst(inst_table, old_inst.args.operand),1518 .operand = try self.resolveInst(inst_table, old_inst.args.operand),
1533 },1519 },
1534 .kw_args = .{},1520 .kw_args = .{},
...@@ -1540,7 +1526,6 @@ const EmitZIR = struct {...@@ -1540,7 +1526,6 @@ const EmitZIR = struct {
1540 const new_inst = try self.arena.allocator.create(Inst.Cmp);1526 const new_inst = try self.arena.allocator.create(Inst.Cmp);
1541 new_inst.* = .{1527 new_inst.* = .{
1542 .base = .{1528 .base = .{
1543 .name = try self.autoName(),
1544 .src = inst.src,1529 .src = inst.src,
1545 .tag = Inst.Cmp.base_tag,1530 .tag = Inst.Cmp.base_tag,
1546 },1531 },
...@@ -1568,7 +1553,6 @@ const EmitZIR = struct {...@@ -1568,7 +1553,6 @@ const EmitZIR = struct {
1568 const new_inst = try self.arena.allocator.create(Inst.CondBr);1553 const new_inst = try self.arena.allocator.create(Inst.CondBr);
1569 new_inst.* = .{1554 new_inst.* = .{
1570 .base = .{1555 .base = .{
1571 .name = try self.autoName(),
1572 .src = inst.src,1556 .src = inst.src,
1573 .tag = Inst.CondBr.base_tag,1557 .tag = Inst.CondBr.base_tag,
1574 },1558 },
...@@ -1586,7 +1570,6 @@ const EmitZIR = struct {...@@ -1586,7 +1570,6 @@ const EmitZIR = struct {
1586 const new_inst = try self.arena.allocator.create(Inst.IsNull);1570 const new_inst = try self.arena.allocator.create(Inst.IsNull);
1587 new_inst.* = .{1571 new_inst.* = .{
1588 .base = .{1572 .base = .{
1589 .name = try self.autoName(),
1590 .src = inst.src,1573 .src = inst.src,
1591 .tag = Inst.IsNull.base_tag,1574 .tag = Inst.IsNull.base_tag,
1592 },1575 },
...@@ -1602,7 +1585,6 @@ const EmitZIR = struct {...@@ -1602,7 +1585,6 @@ const EmitZIR = struct {
1602 const new_inst = try self.arena.allocator.create(Inst.IsNonNull);1585 const new_inst = try self.arena.allocator.create(Inst.IsNonNull);
1603 new_inst.* = .{1586 new_inst.* = .{
1604 .base = .{1587 .base = .{
1605 .name = try self.autoName(),
1606 .src = inst.src,1588 .src = inst.src,
1607 .tag = Inst.IsNonNull.base_tag,1589 .tag = Inst.IsNonNull.base_tag,
1608 },1590 },
...@@ -1619,7 +1601,7 @@ const EmitZIR = struct {...@@ -1619,7 +1601,7 @@ const EmitZIR = struct {
1619 }1601 }
1620 }1602 }
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 {
1623 switch (ty.tag()) {1605 switch (ty.tag()) {
1624 .isize => return self.emitPrimitive(src, .isize),1606 .isize => return self.emitPrimitive(src, .isize),
1625 .usize => return self.emitPrimitive(src, .usize),1607 .usize => return self.emitPrimitive(src, .usize),
...@@ -1652,26 +1634,24 @@ const EmitZIR = struct {...@@ -1652,26 +1634,24 @@ const EmitZIR = struct {
1652 ty.fnParamTypes(param_types);1634 ty.fnParamTypes(param_types);
1653 const emitted_params = try self.arena.allocator.alloc(*Inst, param_types.len);1635 const emitted_params = try self.arena.allocator.alloc(*Inst, param_types.len);
1654 for (param_types) |param_type, i| {1636 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;
1656 }1638 }
16571639
1658 const fntype_inst = try self.arena.allocator.create(Inst.FnType);1640 const fntype_inst = try self.arena.allocator.create(Inst.FnType);
1659 fntype_inst.* = .{1641 fntype_inst.* = .{
1660 .base = .{1642 .base = .{
1661 .name = try self.autoName(),
1662 .src = src,1643 .src = src,
1663 .tag = Inst.FnType.base_tag,1644 .tag = Inst.FnType.base_tag,
1664 },1645 },
1665 .positionals = .{1646 .positionals = .{
1666 .param_types = emitted_params,1647 .param_types = emitted_params,
1667 .return_type = try self.emitType(src, ty.fnReturnType()),1648 .return_type = (try self.emitType(src, ty.fnReturnType())).inst,
1668 },1649 },
1669 .kw_args = .{1650 .kw_args = .{
1670 .cc = ty.fnCallingConvention(),1651 .cc = ty.fnCallingConvention(),
1671 },1652 },
1672 };1653 };
1673 try self.decls.append(self.allocator, &fntype_inst.base);1654 return self.emitUnnamedDecl(&fntype_inst.base);
1674 return &fntype_inst.base;
1675 },1655 },
1676 else => std.debug.panic("TODO implement emitType for {}", .{ty}),1656 else => std.debug.panic("TODO implement emitType for {}", .{ty}),
1677 },1657 },
...@@ -1690,13 +1670,12 @@ const EmitZIR = struct {...@@ -1690,13 +1670,12 @@ const EmitZIR = struct {
1690 }1670 }
1691 }1671 }
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 {
1694 const gop = try self.primitive_table.getOrPut(tag);1674 const gop = try self.primitive_table.getOrPut(tag);
1695 if (!gop.found_existing) {1675 if (!gop.found_existing) {
1696 const primitive_inst = try self.arena.allocator.create(Inst.Primitive);1676 const primitive_inst = try self.arena.allocator.create(Inst.Primitive);
1697 primitive_inst.* = .{1677 primitive_inst.* = .{
1698 .base = .{1678 .base = .{
1699 .name = try self.autoName(),
1700 .src = src,1679 .src = src,
1701 .tag = Inst.Primitive.base_tag,1680 .tag = Inst.Primitive.base_tag,
1702 },1681 },
...@@ -1705,17 +1684,15 @@ const EmitZIR = struct {...@@ -1705,17 +1684,15 @@ const EmitZIR = struct {
1705 },1684 },
1706 .kw_args = .{},1685 .kw_args = .{},
1707 };1686 };
1708 try self.decls.append(self.allocator, &primitive_inst.base);1687 gop.kv.value = try self.emitUnnamedDecl(&primitive_inst.base);
1709 gop.kv.value = &primitive_inst.base;
1710 }1688 }
1711 return gop.kv.value;1689 return gop.kv.value;
1712 }1690 }
17131691
1714 fn emitStringLiteral(self: *EmitZIR, src: usize, str: []const u8) !*Inst {1692 fn emitStringLiteral(self: *EmitZIR, src: usize, str: []const u8) !*Decl {
1715 const str_inst = try self.arena.allocator.create(Inst.Str);1693 const str_inst = try self.arena.allocator.create(Inst.Str);
1716 str_inst.* = .{1694 str_inst.* = .{
1717 .base = .{1695 .base = .{
1718 .name = try self.autoName(),
1719 .src = src,1696 .src = src,
1720 .tag = Inst.Str.base_tag,1697 .tag = Inst.Str.base_tag,
1721 },1698 },
...@@ -1724,22 +1701,17 @@ const EmitZIR = struct {...@@ -1724,22 +1701,17 @@ const EmitZIR = struct {
1724 },1701 },
1725 .kw_args = .{},1702 .kw_args = .{},
1726 };1703 };
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);1707 fn emitUnnamedDecl(self: *EmitZIR, inst: *Inst) !*Decl {
1730 ref_inst.* = .{1708 const decl = try self.arena.allocator.create(Decl);
1731 .base = .{1709 decl.* = .{
1732 .name = try self.autoName(),1710 .name = try self.autoName(),
1733 .src = src,1711 .contents_hash = undefined,
1734 .tag = Inst.Ref.base_tag,1712 .inst = inst,
1735 },
1736 .positionals = .{
1737 .operand = &str_inst.base,
1738 },
1739 .kw_args = .{},
1740 };1713 };
1741 try self.decls.append(self.allocator, &ref_inst.base);1714 try self.decls.append(self.allocator, decl);
17421715 return decl;
1743 return &ref_inst.base;
1744 }1716 }
1745};1717};