authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-06-03 21:53:13-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-06-08 15:16:40-04:00
logcf654b52d68f20a403965e70371a9ad193370d8c
treeead20daa8c4bcf8d4f269707fa24448df0cd1e1a
parentd4d954abd20d57ff62940993f5b95700ebfbbda7

stage2: -femit-zir respects decl names and supports cycles


5 files changed, 330 insertions(+), 153 deletions(-)

src-self-hosted/Module.zig+23-1
......@@ -1097,6 +1097,9 @@ fn resolveDecl(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*De
10971097 const decl = kv.value;
10981098 try self.reAnalyzeDecl(decl, old_inst);
10991099 return decl;
1100 } else if (old_inst.cast(zir.Inst.DeclVal)) |decl_val| {
1101 // This is just a named reference to another decl.
1102 return self.analyzeDeclVal(scope, decl_val);
11001103 } else {
11011104 const new_decl = blk: {
11021105 try self.decl_table.ensureCapacity(self.decl_table.size + 1);
......@@ -1443,6 +1446,7 @@ fn analyzeInst(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*In
14431446 .breakpoint => return self.analyzeInstBreakpoint(scope, old_inst.cast(zir.Inst.Breakpoint).?),
14441447 .call => return self.analyzeInstCall(scope, old_inst.cast(zir.Inst.Call).?),
14451448 .declref => return self.analyzeInstDeclRef(scope, old_inst.cast(zir.Inst.DeclRef).?),
1449 .declval => return self.analyzeInstDeclVal(scope, old_inst.cast(zir.Inst.DeclVal).?),
14461450 .str => {
14471451 const bytes = old_inst.cast(zir.Inst.Str).?.positionals.bytes;
14481452 // The bytes references memory inside the ZIR module, which can get deallocated
......@@ -1501,6 +1505,24 @@ fn analyzeInstDeclRef(self: *Module, scope: *Scope, inst: *zir.Inst.DeclRef) Inn
15011505 return self.analyzeDeclRef(scope, inst.base.src, decl);
15021506}
15031507
1508fn analyzeDeclVal(self: *Module, scope: *Scope, inst: *zir.Inst.DeclVal) InnerError!*Decl {
1509 const decl_name = inst.positionals.name;
1510 // This will need to get more fleshed out when there are proper structs & namespaces.
1511 const zir_module = scope.namespace();
1512 const src_decl = zir_module.contents.module.findDecl(decl_name) orelse
1513 return self.fail(scope, inst.base.src, "use of undeclared identifier '{}'", .{decl_name});
1514
1515 const decl = try self.resolveCompleteDecl(scope, src_decl);
1516
1517 return decl;
1518}
1519
1520fn analyzeInstDeclVal(self: *Module, scope: *Scope, inst: *zir.Inst.DeclVal) InnerError!*Inst {
1521 const decl = try self.analyzeDeclVal(scope, inst);
1522 const ptr = try self.analyzeDeclRef(scope, inst.base.src, decl);
1523 return self.analyzeDeref(scope, inst.base.src, ptr, inst.base.src);
1524}
1525
15041526fn analyzeDeclRef(self: *Module, scope: *Scope, src: usize, decl: *Decl) InnerError!*Inst {
15051527 const decl_tv = try decl.typedValue();
15061528 const ty_payload = try scope.arena().create(Type.Payload.SingleConstPointer);
......@@ -1621,7 +1643,7 @@ fn analyzeInstFnType(self: *Module, scope: *Scope, fntype: *zir.Inst.FnType) Inn
16211643}
16221644
16231645fn analyzeInstPrimitive(self: *Module, scope: *Scope, primitive: *zir.Inst.Primitive) InnerError!*Inst {
1624 return self.constType(scope, primitive.base.src, primitive.positionals.tag.toType());
1646 return self.constInst(scope, primitive.base.src, primitive.positionals.tag.toTypedValue());
16251647}
16261648
16271649fn analyzeInstAs(self: *Module, scope: *Scope, as: *zir.Inst.As) InnerError!*Inst {
src-self-hosted/type.zig+22
......@@ -51,6 +51,7 @@ pub const Type = extern union {
5151 .comptime_float => return .ComptimeFloat,
5252 .noreturn => return .NoReturn,
5353 .@"null" => return .Null,
54 .@"undefined" => return .Undefined,
5455
5556 .fn_noreturn_no_args => return .Fn,
5657 .fn_naked_noreturn_no_args => return .Fn,
......@@ -201,6 +202,7 @@ pub const Type = extern union {
201202 => return out_stream.writeAll(@tagName(t)),
202203
203204 .@"null" => return out_stream.writeAll("@TypeOf(null)"),
205 .@"undefined" => return out_stream.writeAll("@TypeOf(undefined)"),
204206
205207 .const_slice_u8 => return out_stream.writeAll("[]const u8"),
206208 .fn_noreturn_no_args => return out_stream.writeAll("fn() noreturn"),
......@@ -265,6 +267,7 @@ pub const Type = extern union {
265267 .comptime_float => return Value.initTag(.comptime_float_type),
266268 .noreturn => return Value.initTag(.noreturn_type),
267269 .@"null" => return Value.initTag(.null_type),
270 .@"undefined" => return Value.initTag(.undefined_type),
268271 .fn_noreturn_no_args => return Value.initTag(.fn_noreturn_no_args_type),
269272 .fn_naked_noreturn_no_args => return Value.initTag(.fn_naked_noreturn_no_args_type),
270273 .fn_ccc_void_no_args => return Value.initTag(.fn_ccc_void_no_args_type),
......@@ -318,6 +321,7 @@ pub const Type = extern union {
318321 .comptime_float,
319322 .noreturn,
320323 .@"null",
324 .@"undefined",
321325 => false,
322326 };
323327 }
......@@ -378,6 +382,7 @@ pub const Type = extern union {
378382 .comptime_float,
379383 .noreturn,
380384 .@"null",
385 .@"undefined",
381386 => unreachable,
382387 };
383388 }
......@@ -410,6 +415,7 @@ pub const Type = extern union {
410415 .comptime_float,
411416 .noreturn,
412417 .@"null",
418 .@"undefined",
413419 .array,
414420 .array_u8_sentinel_0,
415421 .const_slice_u8,
......@@ -454,6 +460,7 @@ pub const Type = extern union {
454460 .comptime_float,
455461 .noreturn,
456462 .@"null",
463 .@"undefined",
457464 .array,
458465 .array_u8_sentinel_0,
459466 .single_const_pointer,
......@@ -498,6 +505,7 @@ pub const Type = extern union {
498505 .comptime_float,
499506 .noreturn,
500507 .@"null",
508 .@"undefined",
501509 .array,
502510 .array_u8_sentinel_0,
503511 .fn_noreturn_no_args,
......@@ -543,6 +551,7 @@ pub const Type = extern union {
543551 .comptime_float,
544552 .noreturn,
545553 .@"null",
554 .@"undefined",
546555 .fn_noreturn_no_args,
547556 .fn_naked_noreturn_no_args,
548557 .fn_ccc_void_no_args,
......@@ -586,6 +595,7 @@ pub const Type = extern union {
586595 .comptime_float,
587596 .noreturn,
588597 .@"null",
598 .@"undefined",
589599 .fn_noreturn_no_args,
590600 .fn_naked_noreturn_no_args,
591601 .fn_ccc_void_no_args,
......@@ -630,6 +640,7 @@ pub const Type = extern union {
630640 .comptime_float,
631641 .noreturn,
632642 .@"null",
643 .@"undefined",
633644 .fn_noreturn_no_args,
634645 .fn_naked_noreturn_no_args,
635646 .fn_ccc_void_no_args,
......@@ -662,6 +673,7 @@ pub const Type = extern union {
662673 .comptime_float,
663674 .noreturn,
664675 .@"null",
676 .@"undefined",
665677 .fn_noreturn_no_args,
666678 .fn_naked_noreturn_no_args,
667679 .fn_ccc_void_no_args,
......@@ -707,6 +719,7 @@ pub const Type = extern union {
707719 .comptime_float,
708720 .noreturn,
709721 .@"null",
722 .@"undefined",
710723 .fn_noreturn_no_args,
711724 .fn_naked_noreturn_no_args,
712725 .fn_ccc_void_no_args,
......@@ -781,6 +794,7 @@ pub const Type = extern union {
781794 .comptime_float,
782795 .noreturn,
783796 .@"null",
797 .@"undefined",
784798 .array,
785799 .single_const_pointer,
786800 .single_const_pointer_to_comptime_int,
......@@ -826,6 +840,7 @@ pub const Type = extern union {
826840 .comptime_float,
827841 .noreturn,
828842 .@"null",
843 .@"undefined",
829844 .array,
830845 .single_const_pointer,
831846 .single_const_pointer_to_comptime_int,
......@@ -870,6 +885,7 @@ pub const Type = extern union {
870885 .comptime_float,
871886 .noreturn,
872887 .@"null",
888 .@"undefined",
873889 .array,
874890 .single_const_pointer,
875891 .single_const_pointer_to_comptime_int,
......@@ -914,6 +930,7 @@ pub const Type = extern union {
914930 .comptime_float,
915931 .noreturn,
916932 .@"null",
933 .@"undefined",
917934 .array,
918935 .single_const_pointer,
919936 .single_const_pointer_to_comptime_int,
......@@ -958,6 +975,7 @@ pub const Type = extern union {
958975 .comptime_float,
959976 .noreturn,
960977 .@"null",
978 .@"undefined",
961979 .array,
962980 .single_const_pointer,
963981 .single_const_pointer_to_comptime_int,
......@@ -1013,6 +1031,7 @@ pub const Type = extern union {
10131031 .anyerror,
10141032 .noreturn,
10151033 .@"null",
1034 .@"undefined",
10161035 .fn_noreturn_no_args,
10171036 .fn_naked_noreturn_no_args,
10181037 .fn_ccc_void_no_args,
......@@ -1062,6 +1081,7 @@ pub const Type = extern union {
10621081 .void,
10631082 .noreturn,
10641083 .@"null",
1084 .@"undefined",
10651085 => return true,
10661086
10671087 .int_unsigned => return ty.cast(Payload.IntUnsigned).?.bits == 0,
......@@ -1115,6 +1135,7 @@ pub const Type = extern union {
11151135 .void,
11161136 .noreturn,
11171137 .@"null",
1138 .@"undefined",
11181139 .int_unsigned,
11191140 .int_signed,
11201141 .array,
......@@ -1157,6 +1178,7 @@ pub const Type = extern union {
11571178 comptime_float,
11581179 noreturn,
11591180 @"null",
1181 @"undefined",
11601182 fn_noreturn_no_args,
11611183 fn_naked_noreturn_no_args,
11621184 fn_ccc_void_no_args,
src-self-hosted/value.zig+12
......@@ -47,6 +47,7 @@ pub const Value = extern union {
4747 comptime_float_type,
4848 noreturn_type,
4949 null_type,
50 undefined_type,
5051 fn_noreturn_no_args_type,
5152 fn_naked_noreturn_no_args_type,
5253 fn_ccc_void_no_args_type,
......@@ -141,6 +142,7 @@ pub const Value = extern union {
141142 .comptime_float_type => return out_stream.writeAll("comptime_float"),
142143 .noreturn_type => return out_stream.writeAll("noreturn"),
143144 .null_type => return out_stream.writeAll("@TypeOf(null)"),
145 .undefined_type => return out_stream.writeAll("@TypeOf(undefined)"),
144146 .fn_noreturn_no_args_type => return out_stream.writeAll("fn() noreturn"),
145147 .fn_naked_noreturn_no_args_type => return out_stream.writeAll("fn() callconv(.Naked) noreturn"),
146148 .fn_ccc_void_no_args_type => return out_stream.writeAll("fn() callconv(.C) void"),
......@@ -225,6 +227,7 @@ pub const Value = extern union {
225227 .comptime_float_type => Type.initTag(.comptime_float),
226228 .noreturn_type => Type.initTag(.noreturn),
227229 .null_type => Type.initTag(.@"null"),
230 .undefined_type => Type.initTag(.@"undefined"),
228231 .fn_noreturn_no_args_type => Type.initTag(.fn_noreturn_no_args),
229232 .fn_naked_noreturn_no_args_type => Type.initTag(.fn_naked_noreturn_no_args),
230233 .fn_ccc_void_no_args_type => Type.initTag(.fn_ccc_void_no_args),
......@@ -281,6 +284,7 @@ pub const Value = extern union {
281284 .comptime_float_type,
282285 .noreturn_type,
283286 .null_type,
287 .undefined_type,
284288 .fn_noreturn_no_args_type,
285289 .fn_naked_noreturn_no_args_type,
286290 .fn_ccc_void_no_args_type,
......@@ -339,6 +343,7 @@ pub const Value = extern union {
339343 .comptime_float_type,
340344 .noreturn_type,
341345 .null_type,
346 .undefined_type,
342347 .fn_noreturn_no_args_type,
343348 .fn_naked_noreturn_no_args_type,
344349 .fn_ccc_void_no_args_type,
......@@ -398,6 +403,7 @@ pub const Value = extern union {
398403 .comptime_float_type,
399404 .noreturn_type,
400405 .null_type,
406 .undefined_type,
401407 .fn_noreturn_no_args_type,
402408 .fn_naked_noreturn_no_args_type,
403409 .fn_ccc_void_no_args_type,
......@@ -462,6 +468,7 @@ pub const Value = extern union {
462468 .comptime_float_type,
463469 .noreturn_type,
464470 .null_type,
471 .undefined_type,
465472 .fn_noreturn_no_args_type,
466473 .fn_naked_noreturn_no_args_type,
467474 .fn_ccc_void_no_args_type,
......@@ -555,6 +562,7 @@ pub const Value = extern union {
555562 .comptime_float_type,
556563 .noreturn_type,
557564 .null_type,
565 .undefined_type,
558566 .fn_noreturn_no_args_type,
559567 .fn_naked_noreturn_no_args_type,
560568 .fn_ccc_void_no_args_type,
......@@ -610,6 +618,7 @@ pub const Value = extern union {
610618 .comptime_float_type,
611619 .noreturn_type,
612620 .null_type,
621 .undefined_type,
613622 .fn_noreturn_no_args_type,
614623 .fn_naked_noreturn_no_args_type,
615624 .fn_ccc_void_no_args_type,
......@@ -710,6 +719,7 @@ pub const Value = extern union {
710719 .comptime_float_type,
711720 .noreturn_type,
712721 .null_type,
722 .undefined_type,
713723 .fn_noreturn_no_args_type,
714724 .fn_naked_noreturn_no_args_type,
715725 .fn_ccc_void_no_args_type,
......@@ -771,6 +781,7 @@ pub const Value = extern union {
771781 .comptime_float_type,
772782 .noreturn_type,
773783 .null_type,
784 .undefined_type,
774785 .fn_noreturn_no_args_type,
775786 .fn_naked_noreturn_no_args_type,
776787 .fn_ccc_void_no_args_type,
......@@ -849,6 +860,7 @@ pub const Value = extern union {
849860 .comptime_float_type,
850861 .noreturn_type,
851862 .null_type,
863 .undefined_type,
852864 .fn_noreturn_no_args_type,
853865 .fn_naked_noreturn_no_args_type,
854866 .fn_ccc_void_no_args_type,
src-self-hosted/zir.zig+250-140
......@@ -27,9 +27,11 @@ pub const Inst = struct {
2727 pub const Tag = enum {
2828 breakpoint,
2929 call,
30 /// Represents a reference to a global decl by name.
31 /// The syntax `@foo` is equivalent to `declref("foo")`.
30 /// Represents a pointer to a global decl by name.
3231 declref,
32 /// The syntax `@foo` is equivalent to `declval("foo")`.
33 /// declval is equivalent to declref followed by deref.
34 declval,
3335 str,
3436 int,
3537 ptrtoint,
......@@ -59,6 +61,7 @@ pub const Inst = struct {
5961 .breakpoint => Breakpoint,
6062 .call => Call,
6163 .declref => DeclRef,
64 .declval => DeclVal,
6265 .str => Str,
6366 .int => Int,
6467 .ptrtoint => PtrToInt,
......@@ -122,6 +125,16 @@ pub const Inst = struct {
122125 kw_args: struct {},
123126 };
124127
128 pub const DeclVal = struct {
129 pub const base_tag = Tag.declval;
130 base: Inst,
131
132 positionals: struct {
133 name: []const u8,
134 },
135 kw_args: struct {},
136 };
137
125138 pub const Str = struct {
126139 pub const base_tag = Tag.str;
127140 base: Inst,
......@@ -254,11 +267,11 @@ pub const Inst = struct {
254267 base: Inst,
255268
256269 positionals: struct {
257 tag: BuiltinType,
270 tag: Builtin,
258271 },
259272 kw_args: struct {},
260273
261 pub const BuiltinType = enum {
274 pub const Builtin = enum {
262275 isize,
263276 usize,
264277 c_short,
......@@ -282,32 +295,42 @@ pub const Inst = struct {
282295 anyerror,
283296 comptime_int,
284297 comptime_float,
298 @"true",
299 @"false",
300 @"null",
301 @"undefined",
302 void_value,
285303
286 pub fn toType(self: BuiltinType) Type {
304 pub fn toTypedValue(self: Builtin) TypedValue {
287305 return switch (self) {
288 .isize => Type.initTag(.isize),
289 .usize => Type.initTag(.usize),
290 .c_short => Type.initTag(.c_short),
291 .c_ushort => Type.initTag(.c_ushort),
292 .c_int => Type.initTag(.c_int),
293 .c_uint => Type.initTag(.c_uint),
294 .c_long => Type.initTag(.c_long),
295 .c_ulong => Type.initTag(.c_ulong),
296 .c_longlong => Type.initTag(.c_longlong),
297 .c_ulonglong => Type.initTag(.c_ulonglong),
298 .c_longdouble => Type.initTag(.c_longdouble),
299 .c_void => Type.initTag(.c_void),
300 .f16 => Type.initTag(.f16),
301 .f32 => Type.initTag(.f32),
302 .f64 => Type.initTag(.f64),
303 .f128 => Type.initTag(.f128),
304 .bool => Type.initTag(.bool),
305 .void => Type.initTag(.void),
306 .noreturn => Type.initTag(.noreturn),
307 .type => Type.initTag(.type),
308 .anyerror => Type.initTag(.anyerror),
309 .comptime_int => Type.initTag(.comptime_int),
310 .comptime_float => Type.initTag(.comptime_float),
306 .isize => .{ .ty = Type.initTag(.type), .val = Value.initTag(.isize_type) },
307 .usize => .{ .ty = Type.initTag(.type), .val = Value.initTag(.usize_type) },
308 .c_short => .{ .ty = Type.initTag(.type), .val = Value.initTag(.c_short_type) },
309 .c_ushort => .{ .ty = Type.initTag(.type), .val = Value.initTag(.c_ushort_type) },
310 .c_int => .{ .ty = Type.initTag(.type), .val = Value.initTag(.c_int_type) },
311 .c_uint => .{ .ty = Type.initTag(.type), .val = Value.initTag(.c_uint_type) },
312 .c_long => .{ .ty = Type.initTag(.type), .val = Value.initTag(.c_long_type) },
313 .c_ulong => .{ .ty = Type.initTag(.type), .val = Value.initTag(.c_ulong_type) },
314 .c_longlong => .{ .ty = Type.initTag(.type), .val = Value.initTag(.c_longlong_type) },
315 .c_ulonglong => .{ .ty = Type.initTag(.type), .val = Value.initTag(.c_ulonglong_type) },
316 .c_longdouble => .{ .ty = Type.initTag(.type), .val = Value.initTag(.c_longdouble_type) },
317 .c_void => .{ .ty = Type.initTag(.type), .val = Value.initTag(.c_void_type) },
318 .f16 => .{ .ty = Type.initTag(.type), .val = Value.initTag(.f16_type) },
319 .f32 => .{ .ty = Type.initTag(.type), .val = Value.initTag(.f32_type) },
320 .f64 => .{ .ty = Type.initTag(.type), .val = Value.initTag(.f64_type) },
321 .f128 => .{ .ty = Type.initTag(.type), .val = Value.initTag(.f128_type) },
322 .bool => .{ .ty = Type.initTag(.type), .val = Value.initTag(.bool_type) },
323 .void => .{ .ty = Type.initTag(.type), .val = Value.initTag(.void_type) },
324 .noreturn => .{ .ty = Type.initTag(.type), .val = Value.initTag(.noreturn_type) },
325 .type => .{ .ty = Type.initTag(.type), .val = Value.initTag(.type_type) },
326 .anyerror => .{ .ty = Type.initTag(.type), .val = Value.initTag(.anyerror_type) },
327 .comptime_int => .{ .ty = Type.initTag(.type), .val = Value.initTag(.comptime_int_type) },
328 .comptime_float => .{ .ty = Type.initTag(.type), .val = Value.initTag(.comptime_float_type) },
329 .@"true" => .{ .ty = Type.initTag(.bool), .val = Value.initTag(.bool_true) },
330 .@"false" => .{ .ty = Type.initTag(.bool), .val = Value.initTag(.bool_false) },
331 .@"null" => .{ .ty = Type.initTag(.@"null"), .val = Value.initTag(.null_value) },
332 .@"undefined" => .{ .ty = Type.initTag(.@"undefined"), .val = Value.initTag(.undef) },
333 .void_value => .{ .ty = Type.initTag(.void), .val = Value.initTag(.the_one_possible_value) },
311334 };
312335 }
313336 };
......@@ -440,7 +463,7 @@ pub const Module = struct {
440463 self.writeToStream(std.heap.page_allocator, std.io.getStdErr().outStream()) catch {};
441464 }
442465
443 const InstPtrTable = std.AutoHashMap(*Inst, struct { index: usize, fn_body: ?*Module.Body });
466 const InstPtrTable = std.AutoHashMap(*Inst, struct { inst: *Inst, index: ?usize });
444467
445468 /// TODO Look into making a table to speed this up.
446469 pub fn findDecl(self: Module, name: []const u8) ?*Inst {
......@@ -462,17 +485,17 @@ pub const Module = struct {
462485 try inst_table.ensureCapacity(self.decls.len);
463486
464487 for (self.decls) |decl, decl_i| {
465 try inst_table.putNoClobber(decl, .{ .index = decl_i, .fn_body = null });
488 try inst_table.putNoClobber(decl, .{ .inst = decl, .index = null });
466489
467490 if (decl.cast(Inst.Fn)) |fn_inst| {
468491 for (fn_inst.positionals.body.instructions) |inst, inst_i| {
469 try inst_table.putNoClobber(inst, .{ .index = inst_i, .fn_body = &fn_inst.positionals.body });
492 try inst_table.putNoClobber(inst, .{ .inst = inst, .index = inst_i });
470493 }
471494 }
472495 }
473496
474497 for (self.decls) |decl, i| {
475 try stream.print("@{} ", .{i});
498 try stream.print("@{} ", .{decl.name});
476499 try self.writeInstToStream(stream, decl, &inst_table);
477500 try stream.writeByte('\n');
478501 }
......@@ -489,6 +512,7 @@ pub const Module = struct {
489512 .breakpoint => return self.writeInstToStreamGeneric(stream, .breakpoint, decl, inst_table),
490513 .call => return self.writeInstToStreamGeneric(stream, .call, decl, inst_table),
491514 .declref => return self.writeInstToStreamGeneric(stream, .declref, decl, inst_table),
515 .declval => return self.writeInstToStreamGeneric(stream, .declval, decl, inst_table),
492516 .str => return self.writeInstToStreamGeneric(stream, .str, decl, inst_table),
493517 .int => return self.writeInstToStreamGeneric(stream, .int, decl, inst_table),
494518 .ptrtoint => return self.writeInstToStreamGeneric(stream, .ptrtoint, decl, inst_table),
......@@ -587,9 +611,18 @@ pub const Module = struct {
587611 }
588612
589613 fn writeInstParamToStream(self: Module, stream: var, inst: *Inst, inst_table: *const InstPtrTable) !void {
590 const info = inst_table.getValue(inst).?;
591 const prefix = if (info.fn_body == null) "@" else "%";
592 try stream.print("{}{}", .{ prefix, info.index });
614 if (inst_table.getValue(inst)) |info| {
615 if (info.index) |i| {
616 try stream.print("%{}", .{info.index});
617 } else {
618 try stream.print("@{}", .{info.inst.name});
619 }
620 } else if (inst.cast(Inst.DeclVal)) |decl_val| {
621 try stream.print("@{}", .{decl_val.positionals.name});
622 } else {
623 //try stream.print("?", .{});
624 unreachable;
625 }
593626 }
594627};
595628
......@@ -964,47 +997,17 @@ const Parser = struct {
964997 self.i = src;
965998 return self.fail("unrecognized identifier: {}", .{bad_name});
966999 } else {
967 const name_array = try self.arena.allocator.create(Inst.Str);
968 name_array.* = .{
969 .base = .{
970 .name = try self.generateName(),
971 .src = src,
972 .tag = Inst.Str.base_tag,
973 },
974 .positionals = .{ .bytes = ident },
975 .kw_args = .{},
976 };
977 const name = try self.arena.allocator.create(Inst.Ref);
978 name.* = .{
979 .base = .{
980 .name = try self.generateName(),
981 .src = src,
982 .tag = Inst.Ref.base_tag,
983 },
984 .positionals = .{ .operand = &name_array.base },
985 .kw_args = .{},
986 };
987 const declref = try self.arena.allocator.create(Inst.DeclRef);
988 declref.* = .{
989 .base = .{
990 .name = try self.generateName(),
991 .src = src,
992 .tag = Inst.DeclRef.base_tag,
993 },
994 .positionals = .{ .name = &name.base },
995 .kw_args = .{},
996 };
997 const deref = try self.arena.allocator.create(Inst.Deref);
998 deref.* = .{
1000 const declval = try self.arena.allocator.create(Inst.DeclVal);
1001 declval.* = .{
9991002 .base = .{
10001003 .name = try self.generateName(),
10011004 .src = src,
1002 .tag = Inst.Deref.base_tag,
1005 .tag = Inst.DeclVal.base_tag,
10031006 },
1004 .positionals = .{ .ptr = &declref.base },
1007 .positionals = .{ .name = ident },
10051008 .kw_args = .{},
10061009 };
1007 return &deref.base;
1010 return &declval.base;
10081011 }
10091012 };
10101013 if (local_ref) {
......@@ -1025,12 +1028,15 @@ pub fn emit(allocator: *Allocator, old_module: IrModule) !Module {
10251028 var ctx: EmitZIR = .{
10261029 .allocator = allocator,
10271030 .decls = .{},
1028 .decl_table = std.AutoHashMap(*ir.Inst, *Inst).init(allocator),
10291031 .arena = std.heap.ArenaAllocator.init(allocator),
10301032 .old_module = &old_module,
1033 .next_auto_name = 0,
1034 .names = std.StringHashMap(void).init(allocator),
1035 .primitive_table = std.AutoHashMap(Inst.Primitive.Builtin, *Inst).init(allocator),
10311036 };
10321037 defer ctx.decls.deinit(allocator);
1033 defer ctx.decl_table.deinit();
1038 defer ctx.names.deinit();
1039 defer ctx.primitive_table.deinit();
10341040 errdefer ctx.arena.deinit();
10351041
10361042 try ctx.emit();
......@@ -1046,47 +1052,90 @@ const EmitZIR = struct {
10461052 arena: std.heap.ArenaAllocator,
10471053 old_module: *const IrModule,
10481054 decls: std.ArrayListUnmanaged(*Inst),
1049 decl_table: std.AutoHashMap(*ir.Inst, *Inst),
1055 names: std.StringHashMap(void),
1056 next_auto_name: usize,
1057 primitive_table: std.AutoHashMap(Inst.Primitive.Builtin, *Inst),
10501058
10511059 fn emit(self: *EmitZIR) !void {
1052 var it = self.old_module.decl_exports.iterator();
1053 while (it.next()) |kv| {
1054 const decl = kv.key;
1055 const exports = kv.value;
1056 const export_value = try self.emitTypedValue(decl.src, decl.typed_value.most_recent.typed_value);
1057 for (exports) |module_export| {
1058 const symbol_name = try self.emitStringLiteral(module_export.src, module_export.options.name);
1059 const export_inst = try self.arena.allocator.create(Inst.Export);
1060 export_inst.* = .{
1061 .base = .{
1062 .name = try self.autoName(),
1063 .src = module_export.src,
1064 .tag = Inst.Export.base_tag,
1065 },
1066 .positionals = .{
1067 .symbol_name = symbol_name,
1068 .value = export_value,
1069 },
1070 .kw_args = .{},
1071 };
1072 try self.decls.append(self.allocator, &export_inst.base);
1060 // Put all the Decls in a list and sort them by name to avoid nondeterminism introduced
1061 // by the hash table.
1062 var src_decls = std.ArrayList(*IrModule.Decl).init(self.allocator);
1063 defer src_decls.deinit();
1064 try src_decls.ensureCapacity(self.old_module.decl_table.size);
1065 try self.decls.ensureCapacity(self.allocator, self.old_module.decl_table.size);
1066 try self.names.ensureCapacity(self.old_module.decl_table.size);
1067
1068 var decl_it = self.old_module.decl_table.iterator();
1069 while (decl_it.next()) |kv| {
1070 const decl = kv.value;
1071 src_decls.appendAssumeCapacity(decl);
1072 self.names.putAssumeCapacityNoClobber(mem.spanZ(decl.name), {});
1073 }
1074 std.sort.sort(*IrModule.Decl, src_decls.items, {}, (struct {
1075 fn lessThan(context: void, a: *IrModule.Decl, b: *IrModule.Decl) bool {
1076 return a.src < b.src;
1077 }
1078 }).lessThan);
1079
1080 // Emit all the decls.
1081 for (src_decls.items) |ir_decl| {
1082 if (self.old_module.export_owners.getValue(ir_decl)) |exports| {
1083 for (exports) |module_export| {
1084 const declval = try self.emitDeclVal(ir_decl.src, mem.spanZ(module_export.exported_decl.name));
1085 const symbol_name = try self.emitStringLiteral(module_export.src, module_export.options.name);
1086 const export_inst = try self.arena.allocator.create(Inst.Export);
1087 export_inst.* = .{
1088 .base = .{
1089 .name = try self.autoName(),
1090 .src = module_export.src,
1091 .tag = Inst.Export.base_tag,
1092 },
1093 .positionals = .{
1094 .symbol_name = symbol_name,
1095 .value = declval,
1096 },
1097 .kw_args = .{},
1098 };
1099 try self.decls.append(self.allocator, &export_inst.base);
1100 }
1101 } else {
1102 const new_decl = try self.emitTypedValue(ir_decl.src, ir_decl.typed_value.most_recent.typed_value);
1103 new_decl.name = try self.arena.allocator.dupe(u8, mem.spanZ(ir_decl.name));
10731104 }
10741105 }
10751106 }
10761107
1077 fn resolveInst(self: *EmitZIR, inst_table: *const std.AutoHashMap(*ir.Inst, *Inst), inst: *ir.Inst) !*Inst {
1108 fn resolveInst(self: *EmitZIR, inst_table: *std.AutoHashMap(*ir.Inst, *Inst), inst: *ir.Inst) !*Inst {
10781109 if (inst.cast(ir.Inst.Constant)) |const_inst| {
1079 if (self.decl_table.getValue(inst)) |decl| {
1080 return decl;
1081 }
1082 const new_decl = try self.emitTypedValue(inst.src, .{ .ty = inst.ty, .val = const_inst.val });
1083 try self.decl_table.putNoClobber(inst, new_decl);
1110 const new_decl = if (const_inst.val.cast(Value.Payload.Function)) |func_pl| blk: {
1111 const owner_decl = func_pl.func.owner_decl;
1112 break :blk try self.emitDeclVal(inst.src, mem.spanZ(owner_decl.name));
1113 } else if (const_inst.val.cast(Value.Payload.DeclRef)) |declref| blk: {
1114 break :blk try self.emitDeclRef(inst.src, declref.decl);
1115 } else blk: {
1116 break :blk try self.emitTypedValue(inst.src, .{ .ty = inst.ty, .val = const_inst.val });
1117 };
1118 try inst_table.putNoClobber(inst, new_decl);
10841119 return new_decl;
10851120 } else {
10861121 return inst_table.getValue(inst).?;
10871122 }
10881123 }
10891124
1125 fn emitDeclVal(self: *EmitZIR, src: usize, decl_name: []const u8) !*Inst {
1126 const declval = try self.arena.allocator.create(Inst.DeclVal);
1127 declval.* = .{
1128 .base = .{
1129 .name = try self.autoName(),
1130 .src = src,
1131 .tag = Inst.DeclVal.base_tag,
1132 },
1133 .positionals = .{ .name = try self.arena.allocator.dupe(u8, decl_name) },
1134 .kw_args = .{},
1135 };
1136 return &declval.base;
1137 }
1138
10901139 fn emitComptimeIntVal(self: *EmitZIR, src: usize, val: Value) !*Inst {
10911140 const big_int_space = try self.arena.allocator.create(Value.BigIntSpace);
10921141 const int_inst = try self.arena.allocator.create(Inst.Int);
......@@ -1105,8 +1154,31 @@ const EmitZIR = struct {
11051154 return &int_inst.base;
11061155 }
11071156
1157 fn emitDeclRef(self: *EmitZIR, src: usize, decl: *IrModule.Decl) !*Inst {
1158 const declval = try self.emitDeclVal(src, mem.spanZ(decl.name));
1159 const ref_inst = try self.arena.allocator.create(Inst.Ref);
1160 ref_inst.* = .{
1161 .base = .{
1162 .name = try self.autoName(),
1163 .src = src,
1164 .tag = Inst.Ref.base_tag,
1165 },
1166 .positionals = .{
1167 .operand = declval,
1168 },
1169 .kw_args = .{},
1170 };
1171 try self.decls.append(self.allocator, &ref_inst.base);
1172
1173 return &ref_inst.base;
1174 }
1175
11081176 fn emitTypedValue(self: *EmitZIR, src: usize, typed_value: TypedValue) Allocator.Error!*Inst {
11091177 const allocator = &self.arena.allocator;
1178 if (typed_value.val.cast(Value.Payload.DeclRef)) |decl_ref| {
1179 const decl = decl_ref.decl;
1180 return self.emitDeclRef(src, decl);
1181 }
11101182 switch (typed_value.ty.zigTypeTag()) {
11111183 .Pointer => {
11121184 const ptr_elem_type = typed_value.ty.elemType();
......@@ -1142,7 +1214,6 @@ const EmitZIR = struct {
11421214 },
11431215 .kw_args = .{},
11441216 };
1145 try self.decls.append(self.allocator, &as_inst.base);
11461217
11471218 return &as_inst.base;
11481219 },
......@@ -1182,6 +1253,33 @@ const EmitZIR = struct {
11821253 try self.decls.append(self.allocator, &fn_inst.base);
11831254 return &fn_inst.base;
11841255 },
1256 .Array => {
1257 // TODO more checks to make sure this can be emitted as a string literal
1258 //const array_elem_type = ptr_elem_type.elemType();
1259 //if (array_elem_type.eql(Type.initTag(.u8)) and
1260 // ptr_elem_type.hasSentinel(Value.initTag(.zero)))
1261 //{
1262 //}
1263 const bytes = typed_value.val.toAllocatedBytes(allocator) catch |err| switch (err) {
1264 error.AnalysisFail => unreachable,
1265 else => |e| return e,
1266 };
1267 const str_inst = try self.arena.allocator.create(Inst.Str);
1268 str_inst.* = .{
1269 .base = .{
1270 .name = try self.autoName(),
1271 .src = src,
1272 .tag = Inst.Str.base_tag,
1273 },
1274 .positionals = .{
1275 .bytes = bytes,
1276 },
1277 .kw_args = .{},
1278 };
1279 try self.decls.append(self.allocator, &str_inst.base);
1280 return &str_inst.base;
1281 },
1282 .Void => return self.emitPrimitive(src, .void_value),
11851283 else => |t| std.debug.panic("TODO implement emitTypedValue for {}", .{@tagName(t)}),
11861284 }
11871285 }
......@@ -1395,30 +1493,30 @@ const EmitZIR = struct {
13951493
13961494 fn emitType(self: *EmitZIR, src: usize, ty: Type) Allocator.Error!*Inst {
13971495 switch (ty.tag()) {
1398 .isize => return self.emitPrimitiveType(src, .isize),
1399 .usize => return self.emitPrimitiveType(src, .usize),
1400 .c_short => return self.emitPrimitiveType(src, .c_short),
1401 .c_ushort => return self.emitPrimitiveType(src, .c_ushort),
1402 .c_int => return self.emitPrimitiveType(src, .c_int),
1403 .c_uint => return self.emitPrimitiveType(src, .c_uint),
1404 .c_long => return self.emitPrimitiveType(src, .c_long),
1405 .c_ulong => return self.emitPrimitiveType(src, .c_ulong),
1406 .c_longlong => return self.emitPrimitiveType(src, .c_longlong),
1407 .c_ulonglong => return self.emitPrimitiveType(src, .c_ulonglong),
1408 .c_longdouble => return self.emitPrimitiveType(src, .c_longdouble),
1409 .c_void => return self.emitPrimitiveType(src, .c_void),
1410 .f16 => return self.emitPrimitiveType(src, .f16),
1411 .f32 => return self.emitPrimitiveType(src, .f32),
1412 .f64 => return self.emitPrimitiveType(src, .f64),
1413 .f128 => return self.emitPrimitiveType(src, .f128),
1414 .anyerror => return self.emitPrimitiveType(src, .anyerror),
1496 .isize => return self.emitPrimitive(src, .isize),
1497 .usize => return self.emitPrimitive(src, .usize),
1498 .c_short => return self.emitPrimitive(src, .c_short),
1499 .c_ushort => return self.emitPrimitive(src, .c_ushort),
1500 .c_int => return self.emitPrimitive(src, .c_int),
1501 .c_uint => return self.emitPrimitive(src, .c_uint),
1502 .c_long => return self.emitPrimitive(src, .c_long),
1503 .c_ulong => return self.emitPrimitive(src, .c_ulong),
1504 .c_longlong => return self.emitPrimitive(src, .c_longlong),
1505 .c_ulonglong => return self.emitPrimitive(src, .c_ulonglong),
1506 .c_longdouble => return self.emitPrimitive(src, .c_longdouble),
1507 .c_void => return self.emitPrimitive(src, .c_void),
1508 .f16 => return self.emitPrimitive(src, .f16),
1509 .f32 => return self.emitPrimitive(src, .f32),
1510 .f64 => return self.emitPrimitive(src, .f64),
1511 .f128 => return self.emitPrimitive(src, .f128),
1512 .anyerror => return self.emitPrimitive(src, .anyerror),
14151513 else => switch (ty.zigTypeTag()) {
1416 .Bool => return self.emitPrimitiveType(src, .bool),
1417 .Void => return self.emitPrimitiveType(src, .void),
1418 .NoReturn => return self.emitPrimitiveType(src, .noreturn),
1419 .Type => return self.emitPrimitiveType(src, .type),
1420 .ComptimeInt => return self.emitPrimitiveType(src, .comptime_int),
1421 .ComptimeFloat => return self.emitPrimitiveType(src, .comptime_float),
1514 .Bool => return self.emitPrimitive(src, .bool),
1515 .Void => return self.emitPrimitive(src, .void),
1516 .NoReturn => return self.emitPrimitive(src, .noreturn),
1517 .Type => return self.emitPrimitive(src, .type),
1518 .ComptimeInt => return self.emitPrimitive(src, .comptime_int),
1519 .ComptimeFloat => return self.emitPrimitive(src, .comptime_float),
14221520 .Fn => {
14231521 const param_types = try self.allocator.alloc(Type, ty.fnParamLen());
14241522 defer self.allocator.free(param_types);
......@@ -1453,24 +1551,36 @@ const EmitZIR = struct {
14531551 }
14541552
14551553 fn autoName(self: *EmitZIR) ![]u8 {
1456 return std.fmt.allocPrint(&self.arena.allocator, "{}", .{self.decls.items.len});
1554 while (true) {
1555 const proposed_name = try std.fmt.allocPrint(&self.arena.allocator, "unnamed${}", .{self.next_auto_name});
1556 self.next_auto_name += 1;
1557 const gop = try self.names.getOrPut(proposed_name);
1558 if (!gop.found_existing) {
1559 gop.kv.value = {};
1560 return proposed_name;
1561 }
1562 }
14571563 }
14581564
1459 fn emitPrimitiveType(self: *EmitZIR, src: usize, tag: Inst.Primitive.BuiltinType) !*Inst {
1460 const primitive_inst = try self.arena.allocator.create(Inst.Primitive);
1461 primitive_inst.* = .{
1462 .base = .{
1463 .name = try self.autoName(),
1464 .src = src,
1465 .tag = Inst.Primitive.base_tag,
1466 },
1467 .positionals = .{
1468 .tag = tag,
1469 },
1470 .kw_args = .{},
1471 };
1472 try self.decls.append(self.allocator, &primitive_inst.base);
1473 return &primitive_inst.base;
1565 fn emitPrimitive(self: *EmitZIR, src: usize, tag: Inst.Primitive.Builtin) !*Inst {
1566 const gop = try self.primitive_table.getOrPut(tag);
1567 if (!gop.found_existing) {
1568 const primitive_inst = try self.arena.allocator.create(Inst.Primitive);
1569 primitive_inst.* = .{
1570 .base = .{
1571 .name = try self.autoName(),
1572 .src = src,
1573 .tag = Inst.Primitive.base_tag,
1574 },
1575 .positionals = .{
1576 .tag = tag,
1577 },
1578 .kw_args = .{},
1579 };
1580 try self.decls.append(self.allocator, &primitive_inst.base);
1581 gop.kv.value = &primitive_inst.base;
1582 }
1583 return gop.kv.value;
14741584 }
14751585
14761586 fn emitStringLiteral(self: *EmitZIR, src: usize, str: []const u8) !*Inst {
test/stage2/zir.zig+23-12
......@@ -21,14 +21,17 @@ pub fn addCases(ctx: *TestContext) void {
2121 \\ %11 = return()
2222 \\})
2323 ,
24 \\@0 = primitive(void)
25 \\@1 = fntype([], @0, cc=C)
26 \\@2 = fn(@1, {
24 \\@void = primitive(void)
25 \\@fnty = fntype([], @void, cc=C)
26 \\@9 = str("entry")
27 \\@10 = ref(@9)
28 \\@unnamed$6 = str("entry")
29 \\@unnamed$7 = ref(@unnamed$6)
30 \\@unnamed$8 = export(@unnamed$7, @entry)
31 \\@unnamed$10 = fntype([], @void, cc=C)
32 \\@entry = fn(@unnamed$10, {
2733 \\ %0 = return()
2834 \\})
29 \\@3 = str("entry")
30 \\@4 = ref(@3)
31 \\@5 = export(@4, @2)
3235 \\
3336 );
3437 ctx.addZIRTransform("elemptr, add, cmp, condbr, return, breakpoint", linux_x64,
......@@ -68,14 +71,22 @@ pub fn addCases(ctx: *TestContext) void {
6871 \\@10 = ref(@9)
6972 \\@11 = export(@10, @entry)
7073 ,
71 \\@0 = primitive(void)
72 \\@1 = fntype([], @0, cc=C)
73 \\@2 = fn(@1, {
74 \\@void = primitive(void)
75 \\@fnty = fntype([], @void, cc=C)
76 \\@0 = int(0)
77 \\@1 = int(1)
78 \\@2 = int(2)
79 \\@3 = int(3)
80 \\@unnamed$7 = fntype([], @void, cc=C)
81 \\@entry = fn(@unnamed$7, {
7482 \\ %0 = return()
7583 \\})
76 \\@3 = str("entry")
77 \\@4 = ref(@3)
78 \\@5 = export(@4, @2)
84 \\@a = str("2\x08\x01\n")
85 \\@9 = str("entry")
86 \\@10 = ref(@9)
87 \\@unnamed$14 = str("entry")
88 \\@unnamed$15 = ref(@unnamed$14)
89 \\@unnamed$16 = export(@unnamed$15, @entry)
7990 \\
8091 );
8192