authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-05-12 23:59:46-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-05-12 23:59:46-04:00
loga3da584248c1152c01a1a7f878c164fb19b8e04a
treedb3b48c29d15f3c324ec9452740d99e99b265436
parente3a0fac1a77a8c637c790670ff749879298becad

self-hosted: ir: implement separated analysis of Decl and Fn


3 files changed, 209 insertions(+), 148 deletions(-)

src-self-hosted/ir.zig+197-136
...@@ -2,7 +2,6 @@ const std = @import("std");...@@ -2,7 +2,6 @@ const std = @import("std");
2const mem = std.mem;2const mem = std.mem;
3const Allocator = std.mem.Allocator;3const Allocator = std.mem.Allocator;
4const ArrayListUnmanaged = std.ArrayListUnmanaged;4const ArrayListUnmanaged = std.ArrayListUnmanaged;
5const LinkedList = std.TailQueue;
6const Value = @import("value.zig").Value;5const Value = @import("value.zig").Value;
7const Type = @import("type.zig").Type;6const Type = @import("type.zig").Type;
8const TypedValue = @import("TypedValue.zig");7const TypedValue = @import("TypedValue.zig");
...@@ -168,17 +167,6 @@ pub const Inst = struct {...@@ -168,17 +167,6 @@ pub const Inst = struct {
168 };167 };
169};168};
170169
171fn swapRemoveElem(allocator: *Allocator, comptime T: type, item: T, list: *ArrayListUnmanaged(T)) void {
172 var i: usize = 0;
173 while (i < list.items.len) {
174 if (list.items[i] == item) {
175 list.swapRemove(allocator, i);
176 continue;
177 }
178 i += 1;
179 }
180}
181
182pub const Module = struct {170pub const Module = struct {
183 /// General-purpose allocator.171 /// General-purpose allocator.
184 allocator: *Allocator,172 allocator: *Allocator,
...@@ -203,6 +191,8 @@ pub const Module = struct {...@@ -203,6 +191,8 @@ pub const Module = struct {
203 optimize_mode: std.builtin.Mode,191 optimize_mode: std.builtin.Mode,
204 link_error_flags: link.ElfFile.ErrorFlags = link.ElfFile.ErrorFlags{},192 link_error_flags: link.ElfFile.ErrorFlags = link.ElfFile.ErrorFlags{},
205193
194 work_stack: ArrayListUnmanaged(WorkItem) = ArrayListUnmanaged(WorkItem){},
195
206 /// We optimize memory usage for a compilation with no compile errors by storing the196 /// We optimize memory usage for a compilation with no compile errors by storing the
207 /// error messages and mapping outside of `Decl`.197 /// error messages and mapping outside of `Decl`.
208 /// The ErrorMsg memory is owned by the decl, using Module's allocator.198 /// The ErrorMsg memory is owned by the decl, using Module's allocator.
...@@ -218,6 +208,11 @@ pub const Module = struct {...@@ -218,6 +208,11 @@ pub const Module = struct {
218 /// The ErrorMsg memory is owned by the `Export`, using Module's allocator.208 /// The ErrorMsg memory is owned by the `Export`, using Module's allocator.
219 failed_exports: std.AutoHashMap(*Export, *ErrorMsg),209 failed_exports: std.AutoHashMap(*Export, *ErrorMsg),
220210
211 pub const WorkItem = union(enum) {
212 /// Write the machine code for a Decl to the output file.
213 codegen_decl: *Decl,
214 };
215
221 pub const Export = struct {216 pub const Export = struct {
222 options: std.builtin.ExportOptions,217 options: std.builtin.ExportOptions,
223 /// Byte offset into the file that contains the export directive.218 /// Byte offset into the file that contains the export directive.
...@@ -322,11 +317,13 @@ pub const Module = struct {...@@ -322,11 +317,13 @@ pub const Module = struct {
322 }317 }
323 };318 };
324319
325 /// Memory is managed by the arena of the owning Decl.320 /// Fn struct memory is owned by the Decl's TypedValue.Managed arena allocator.
326 pub const Fn = struct {321 pub const Fn = struct {
322 /// This memory owned by the Decl's TypedValue.Managed arena allocator.
327 fn_type: Type,323 fn_type: Type,
328 analysis: union(enum) {324 analysis: union(enum) {
329 queued,325 /// The value is the source instruction.
326 queued: *text.Inst.Fn,
330 in_progress: *Analysis,327 in_progress: *Analysis,
331 /// There will be a corresponding ErrorMsg in Module.failed_fns328 /// There will be a corresponding ErrorMsg in Module.failed_fns
332 failure,329 failure,
...@@ -336,11 +333,14 @@ pub const Module = struct {...@@ -336,11 +333,14 @@ pub const Module = struct {
336 /// self-hosted supports proper struct types and Zig AST => ZIR.333 /// self-hosted supports proper struct types and Zig AST => ZIR.
337 scope: *Scope.ZIRModule,334 scope: *Scope.ZIRModule,
338335
339 /// This memory managed by the general purpose allocator.336 /// This memory is temporary and points to stack memory for the duration
337 /// of Fn analysis.
340 pub const Analysis = struct {338 pub const Analysis = struct {
341 inner_block: Scope.Block,339 inner_block: Scope.Block,
342 /// null value means a semantic analysis error happened.340 /// null value means a semantic analysis error happened.
343 inst_table: std.AutoHashMap(*text.Inst, ?*Inst),341 inst_table: std.AutoHashMap(*text.Inst, ?*Inst),
342 /// Owns the memory for instructions
343 arena: std.heap.ArenaAllocator,
344 };344 };
345 };345 };
346346
...@@ -354,6 +354,26 @@ pub const Module = struct {...@@ -354,6 +354,26 @@ pub const Module = struct {
354 return @fieldParentPtr(T, "base", base);354 return @fieldParentPtr(T, "base", base);
355 }355 }
356356
357 /// Asserts the scope has a parent which is a DeclAnalysis and
358 /// returns the arena Allocator.
359 pub fn arena(self: *Scope) *Allocator {
360 switch (self.tag) {
361 .block => return self.cast(Block).?.arena,
362 .decl => return &self.cast(DeclAnalysis).?.arena.allocator,
363 .zir_module => unreachable,
364 }
365 }
366
367 /// Asserts the scope has a parent which is a DeclAnalysis and
368 /// returns the Decl.
369 pub fn decl(self: *Scope) *Decl {
370 switch (self.tag) {
371 .block => return self.cast(Block).?.decl,
372 .decl => return self.cast(DeclAnalysis).?.decl,
373 .zir_module => unreachable,
374 }
375 }
376
357 pub const Tag = enum {377 pub const Tag = enum {
358 zir_module,378 zir_module,
359 block,379 block,
...@@ -404,7 +424,10 @@ pub const Module = struct {...@@ -404,7 +424,10 @@ pub const Module = struct {
404 pub const base_tag: Tag = .block;424 pub const base_tag: Tag = .block;
405 base: Scope = Scope{ .tag = base_tag },425 base: Scope = Scope{ .tag = base_tag },
406 func: *Fn,426 func: *Fn,
427 decl: *Decl,
407 instructions: ArrayListUnmanaged(*Inst),428 instructions: ArrayListUnmanaged(*Inst),
429 /// Points to the arena allocator of DeclAnalysis
430 arena: *Allocator,
408 };431 };
409432
410 /// This is a temporary structure, references to it are valid only433 /// This is a temporary structure, references to it are valid only
...@@ -413,6 +436,7 @@ pub const Module = struct {...@@ -413,6 +436,7 @@ pub const Module = struct {
413 pub const base_tag: Tag = .decl;436 pub const base_tag: Tag = .decl;
414 base: Scope = Scope{ .tag = base_tag },437 base: Scope = Scope{ .tag = base_tag },
415 decl: *Decl,438 decl: *Decl,
439 arena: std.heap.ArenaAllocator,
416 };440 };
417 };441 };
418442
...@@ -616,21 +640,62 @@ pub const Module = struct {...@@ -616,21 +640,62 @@ pub const Module = struct {
616640
617 // Here we ensure enough queue capacity to store all the decls, so that later we can use641 // Here we ensure enough queue capacity to store all the decls, so that later we can use
618 // appendAssumeCapacity.642 // appendAssumeCapacity.
619 try self.analysis_queue.ensureCapacity(self.analysis_queue.items.len + contents.module.decls.len);643 try self.work_stack.ensureCapacity(
644 self.allocator,
645 self.work_stack.items.len + src_module.decls.len,
646 );
620647
621 for (contents.module.decls) |decl| {648 for (src_module.decls) |decl| {
622 if (decl.cast(text.Inst.Export)) |export_inst| {649 if (decl.cast(text.Inst.Export)) |export_inst| {
623 try analyzeExport(self, &root_scope.base, export_inst);650 try analyzeExport(self, &root_scope.base, export_inst);
624 }651 }
625 }652 }
626653
627 while (self.analysis_queue.popOrNull()) |work_item| {654 while (self.work_stack.pop()) |work_item| switch (work_item) {
628 switch (work_item) {655 .codegen_decl => |decl| switch (decl.analysis) {
629 .decl => |decl| switch (decl.analysis) {656 .success => {
630 .success => try self.bin_file.updateDecl(self, decl),657 if (decl.typed_value.most_recent.typed_value.val.cast(Value.Function)) |payload| {
658 switch (payload.func.analysis) {
659 .queued => self.analyzeFnBody(decl, payload.func) catch |err| switch (err) {
660 error.AnalysisFail => {
661 assert(func_payload.func.analysis == .failure);
662 continue;
663 },
664 else => |e| return e,
665 },
666 .in_progress => unreachable,
667 .failure => continue,
668 .success => {},
669 }
670 }
671 try self.bin_file.updateDecl(self, decl);
631 },672 },
632 }673 },
633 }674 };
675 }
676
677 fn analyzeFnBody(self: *Module, decl: *Decl, func: *Fn) !void {
678 // Use the Decl's arena for function memory.
679 var arena = decl.typed_value.most_recent.arena.?.promote(self.allocator);
680 defer decl.typed_value.most_recent.arena.?.* = arena.state;
681 var analysis: Analysis = .{
682 .inner_block = .{
683 .func = func,
684 .decl = decl,
685 .instructions = .{},
686 .arena = &arena.allocator,
687 },
688 .inst_table = std.AutoHashMap(*text.Inst, ?*Inst).init(self.allocator),
689 };
690 defer analysis.inner_block.instructions.deinit();
691 defer analysis.inst_table.deinit();
692
693 const fn_inst = func.analysis.queued;
694 func.analysis = .{ .in_progress = &analysis };
695
696 try self.analyzeBody(&analysis.inner_block, fn_inst.positionals.body);
697
698 func.analysis = .{ .success = .{ .instructions = analysis.inner_block.instructions.toOwnedSlice() } };
634 }699 }
635700
636 fn resolveDecl(self: *Module, scope: *Scope, old_inst: *text.Inst) InnerError!*Decl {701 fn resolveDecl(self: *Module, scope: *Scope, old_inst: *text.Inst) InnerError!*Decl {
...@@ -656,19 +721,27 @@ pub const Module = struct {...@@ -656,19 +721,27 @@ pub const Module = struct {
656 };721 };
657722
658 var decl_scope: Scope.DeclAnalysis = .{723 var decl_scope: Scope.DeclAnalysis = .{
659 .base = .{ .parent = scope },
660 .decl = new_decl,724 .decl = new_decl,
725 .arena = std.heap.ArenaAllocator.init(self.allocator),
661 };726 };
662 const typed_value = self.analyzeInstConst(&decl_scope.base, old_inst) catch |err| switch (err) {727 errdefer decl_scope.arena.deinit();
663 error.AnalysisFail => {728
664 assert(new_decl.analysis == .failure);729 const arena_state = try self.allocator.create(std.heap.ArenaAllocator.State);
665 return error.AnalysisFail;730 errdefer self.allocator.destroy(arena_state);
731
732 const typed_value = try self.analyzeInstConst(&decl_scope.base, old_inst);
733
734 arena_state.* = decl_scope.arena;
735
736 new_decl.typed_value = .{
737 .most_recent = .{
738 .typed_value = typed_value,
739 .arena = arena_state,
666 },740 },
667 else => |e| return e,
668 };741 };
669 new_decl.analysis = .{ .success = typed_value };742 new_decl.analysis = .complete;
670 // We ensureCapacity when scanning for decls.743 // We ensureCapacity when scanning for decls.
671 self.analysis_queue.appendAssumeCapacity(.{ .decl = new_decl });744 self.work_stack.appendAssumeCapacity(self.allocator, .{ .codegen_decl = new_decl });
672 return new_decl;745 return new_decl;
673 }746 }
674 }747 }
...@@ -708,7 +781,7 @@ pub const Module = struct {...@@ -708,7 +781,7 @@ pub const Module = struct {
708781
709 fn resolveInstConst(self: *Module, scope: *Scope, old_inst: *text.Inst) InnerError!TypedValue {782 fn resolveInstConst(self: *Module, scope: *Scope, old_inst: *text.Inst) InnerError!TypedValue {
710 const new_inst = try self.resolveInst(scope, old_inst);783 const new_inst = try self.resolveInst(scope, old_inst);
711 const val = try self.resolveConstValue(new_inst);784 const val = try self.resolveConstValue(scope, new_inst);
712 return TypedValue{785 return TypedValue{
713 .ty = new_inst.ty,786 .ty = new_inst.ty,
714 .val = val,787 .val = val,
...@@ -716,7 +789,7 @@ pub const Module = struct {...@@ -716,7 +789,7 @@ pub const Module = struct {
716 }789 }
717790
718 fn resolveConstValue(self: *Module, scope: *Scope, base: *Inst) !Value {791 fn resolveConstValue(self: *Module, scope: *Scope, base: *Inst) !Value {
719 return (try self.resolveDefinedValue(base)) orelse792 return (try self.resolveDefinedValue(scope, base)) orelse
720 return self.fail(scope, base.src, "unable to resolve comptime value", .{});793 return self.fail(scope, base.src, "unable to resolve comptime value", .{});
721 }794 }
722795
...@@ -734,15 +807,15 @@ pub const Module = struct {...@@ -734,15 +807,15 @@ pub const Module = struct {
734 const new_inst = try self.resolveInst(scope, old_inst);807 const new_inst = try self.resolveInst(scope, old_inst);
735 const wanted_type = Type.initTag(.const_slice_u8);808 const wanted_type = Type.initTag(.const_slice_u8);
736 const coerced_inst = try self.coerce(scope, wanted_type, new_inst);809 const coerced_inst = try self.coerce(scope, wanted_type, new_inst);
737 const val = try self.resolveConstValue(coerced_inst);810 const val = try self.resolveConstValue(scope, coerced_inst);
738 return val.toAllocatedBytes(&self.arena.allocator);811 return val.toAllocatedBytes(scope.arena());
739 }812 }
740813
741 fn resolveType(self: *Module, scope: *Scope, old_inst: *text.Inst) !Type {814 fn resolveType(self: *Module, scope: *Scope, old_inst: *text.Inst) !Type {
742 const new_inst = try self.resolveInst(scope, old_inst);815 const new_inst = try self.resolveInst(scope, old_inst);
743 const wanted_type = Type.initTag(.@"type");816 const wanted_type = Type.initTag(.@"type");
744 const coerced_inst = try self.coerce(scope, wanted_type, new_inst);817 const coerced_inst = try self.coerce(scope, wanted_type, new_inst);
745 const val = try self.resolveConstValue(coerced_inst);818 const val = try self.resolveConstValue(scope, coerced_inst);
746 return val.toType();819 return val.toType();
747 }820 }
748821
...@@ -764,7 +837,7 @@ pub const Module = struct {...@@ -764,7 +837,7 @@ pub const Module = struct {
764 const new_export = try self.allocator.create(Export);837 const new_export = try self.allocator.create(Export);
765 errdefer self.allocator.destroy(new_export);838 errdefer self.allocator.destroy(new_export);
766839
767 const owner_decl = scope.getDecl();840 const owner_decl = scope.decl();
768841
769 new_export.* = .{842 new_export.* = .{
770 .options = .{ .data = .{ .name = symbol_name } },843 .options = .{ .data = .{ .name = symbol_name } },
...@@ -810,7 +883,7 @@ pub const Module = struct {...@@ -810,7 +883,7 @@ pub const Module = struct {
810 }883 }
811884
812 fn addNewInst(self: *Module, block: *Scope.Block, src: usize, ty: Type, comptime T: type) !*T {885 fn addNewInst(self: *Module, block: *Scope.Block, src: usize, ty: Type, comptime T: type) !*T {
813 const inst = try self.arena.allocator.create(T);886 const inst = try block.arena.create(T);
814 inst.* = .{887 inst.* = .{
815 .base = .{888 .base = .{
816 .tag = T.base_tag,889 .tag = T.base_tag,
...@@ -823,8 +896,8 @@ pub const Module = struct {...@@ -823,8 +896,8 @@ pub const Module = struct {
823 return inst;896 return inst;
824 }897 }
825898
826 fn constInst(self: *Module, src: usize, typed_value: TypedValue) !*Inst {899 fn constInst(self: *Module, scope: *Scope, src: usize, typed_value: TypedValue) !*Inst {
827 const const_inst = try self.arena.allocator.create(Inst.Constant);900 const const_inst = try scope.arena().create(Inst.Constant);
828 const_inst.* = .{901 const_inst.* = .{
829 .base = .{902 .base = .{
830 .tag = Inst.Constant.base_tag,903 .tag = Inst.Constant.base_tag,
...@@ -836,71 +909,71 @@ pub const Module = struct {...@@ -836,71 +909,71 @@ pub const Module = struct {
836 return &const_inst.base;909 return &const_inst.base;
837 }910 }
838911
839 fn constStr(self: *Module, src: usize, str: []const u8) !*Inst {912 fn constStr(self: *Module, scope: *Scope, src: usize, str: []const u8) !*Inst {
840 const array_payload = try self.arena.allocator.create(Type.Payload.Array_u8_Sentinel0);913 const array_payload = try scope.arena().create(Type.Payload.Array_u8_Sentinel0);
841 array_payload.* = .{ .len = str.len };914 array_payload.* = .{ .len = str.len };
842915
843 const ty_payload = try self.arena.allocator.create(Type.Payload.SingleConstPointer);916 const ty_payload = try scope.arena().create(Type.Payload.SingleConstPointer);
844 ty_payload.* = .{ .pointee_type = Type.initPayload(&array_payload.base) };917 ty_payload.* = .{ .pointee_type = Type.initPayload(&array_payload.base) };
845918
846 const bytes_payload = try self.arena.allocator.create(Value.Payload.Bytes);919 const bytes_payload = try scope.arena().create(Value.Payload.Bytes);
847 bytes_payload.* = .{ .data = str };920 bytes_payload.* = .{ .data = str };
848921
849 return self.constInst(src, .{922 return self.constInst(scope, src, .{
850 .ty = Type.initPayload(&ty_payload.base),923 .ty = Type.initPayload(&ty_payload.base),
851 .val = Value.initPayload(&bytes_payload.base),924 .val = Value.initPayload(&bytes_payload.base),
852 });925 });
853 }926 }
854927
855 fn constType(self: *Module, src: usize, ty: Type) !*Inst {928 fn constType(self: *Module, scope: *Scope, src: usize, ty: Type) !*Inst {
856 return self.constInst(src, .{929 return self.constInst(scope, src, .{
857 .ty = Type.initTag(.type),930 .ty = Type.initTag(.type),
858 .val = try ty.toValue(&self.arena.allocator),931 .val = try ty.toValue(scope.arena()),
859 });932 });
860 }933 }
861934
862 fn constVoid(self: *Module, src: usize) !*Inst {935 fn constVoid(self: *Module, scope: *Scope, src: usize) !*Inst {
863 return self.constInst(src, .{936 return self.constInst(scope, src, .{
864 .ty = Type.initTag(.void),937 .ty = Type.initTag(.void),
865 .val = Value.initTag(.the_one_possible_value),938 .val = Value.initTag(.the_one_possible_value),
866 });939 });
867 }940 }
868941
869 fn constUndef(self: *Module, src: usize, ty: Type) !*Inst {942 fn constUndef(self: *Module, scope: *Scope, src: usize, ty: Type) !*Inst {
870 return self.constInst(src, .{943 return self.constInst(scope, src, .{
871 .ty = ty,944 .ty = ty,
872 .val = Value.initTag(.undef),945 .val = Value.initTag(.undef),
873 });946 });
874 }947 }
875948
876 fn constBool(self: *Module, src: usize, v: bool) !*Inst {949 fn constBool(self: *Module, scope: *Scope, src: usize, v: bool) !*Inst {
877 return self.constInst(src, .{950 return self.constInst(scope, src, .{
878 .ty = Type.initTag(.bool),951 .ty = Type.initTag(.bool),
879 .val = ([2]Value{ Value.initTag(.bool_false), Value.initTag(.bool_true) })[@boolToInt(v)],952 .val = ([2]Value{ Value.initTag(.bool_false), Value.initTag(.bool_true) })[@boolToInt(v)],
880 });953 });
881 }954 }
882955
883 fn constIntUnsigned(self: *Module, src: usize, ty: Type, int: u64) !*Inst {956 fn constIntUnsigned(self: *Module, scope: *Scope, src: usize, ty: Type, int: u64) !*Inst {
884 const int_payload = try self.arena.allocator.create(Value.Payload.Int_u64);957 const int_payload = try scope.arena().create(Value.Payload.Int_u64);
885 int_payload.* = .{ .int = int };958 int_payload.* = .{ .int = int };
886959
887 return self.constInst(src, .{960 return self.constInst(scope, src, .{
888 .ty = ty,961 .ty = ty,
889 .val = Value.initPayload(&int_payload.base),962 .val = Value.initPayload(&int_payload.base),
890 });963 });
891 }964 }
892965
893 fn constIntSigned(self: *Module, src: usize, ty: Type, int: i64) !*Inst {966 fn constIntSigned(self: *Module, scope: *Scope, src: usize, ty: Type, int: i64) !*Inst {
894 const int_payload = try self.arena.allocator.create(Value.Payload.Int_i64);967 const int_payload = try scope.arena().create(Value.Payload.Int_i64);
895 int_payload.* = .{ .int = int };968 int_payload.* = .{ .int = int };
896969
897 return self.constInst(src, .{970 return self.constInst(scope, src, .{
898 .ty = ty,971 .ty = ty,
899 .val = Value.initPayload(&int_payload.base),972 .val = Value.initPayload(&int_payload.base),
900 });973 });
901 }974 }
902975
903 fn constIntBig(self: *Module, src: usize, ty: Type, big_int: BigIntConst) !*Inst {976 fn constIntBig(self: *Module, scope: *Scope, src: usize, ty: Type, big_int: BigIntConst) !*Inst {
904 const val_payload = if (big_int.positive) blk: {977 const val_payload = if (big_int.positive) blk: {
905 if (big_int.to(u64)) |x| {978 if (big_int.to(u64)) |x| {
906 return self.constIntUnsigned(src, ty, x);979 return self.constIntUnsigned(src, ty, x);
...@@ -908,7 +981,7 @@ pub const Module = struct {...@@ -908,7 +981,7 @@ pub const Module = struct {
908 error.NegativeIntoUnsigned => unreachable,981 error.NegativeIntoUnsigned => unreachable,
909 error.TargetTooSmall => {}, // handled below982 error.TargetTooSmall => {}, // handled below
910 }983 }
911 const big_int_payload = try self.arena.allocator.create(Value.Payload.IntBigPositive);984 const big_int_payload = try scope.arena().create(Value.Payload.IntBigPositive);
912 big_int_payload.* = .{ .limbs = big_int.limbs };985 big_int_payload.* = .{ .limbs = big_int.limbs };
913 break :blk &big_int_payload.base;986 break :blk &big_int_payload.base;
914 } else blk: {987 } else blk: {
...@@ -918,12 +991,12 @@ pub const Module = struct {...@@ -918,12 +991,12 @@ pub const Module = struct {
918 error.NegativeIntoUnsigned => unreachable,991 error.NegativeIntoUnsigned => unreachable,
919 error.TargetTooSmall => {}, // handled below992 error.TargetTooSmall => {}, // handled below
920 }993 }
921 const big_int_payload = try self.arena.allocator.create(Value.Payload.IntBigNegative);994 const big_int_payload = try scope.arena().create(Value.Payload.IntBigNegative);
922 big_int_payload.* = .{ .limbs = big_int.limbs };995 big_int_payload.* = .{ .limbs = big_int.limbs };
923 break :blk &big_int_payload.base;996 break :blk &big_int_payload.base;
924 };997 };
925998
926 return self.constInst(src, .{999 return self.constInst(scope, src, .{
927 .ty = ty,1000 .ty = ty,
928 .val = Value.initPayload(val_payload),1001 .val = Value.initPayload(val_payload),
929 });1002 });
...@@ -958,11 +1031,10 @@ pub const Module = struct {...@@ -958,11 +1031,10 @@ pub const Module = struct {
958 .@"asm" => return self.analyzeInstAsm(scope, old_inst.cast(text.Inst.Asm).?),1031 .@"asm" => return self.analyzeInstAsm(scope, old_inst.cast(text.Inst.Asm).?),
959 .@"unreachable" => return self.analyzeInstUnreachable(scope, old_inst.cast(text.Inst.Unreachable).?),1032 .@"unreachable" => return self.analyzeInstUnreachable(scope, old_inst.cast(text.Inst.Unreachable).?),
960 .@"return" => return self.analyzeInstRet(scope, old_inst.cast(text.Inst.Return).?),1033 .@"return" => return self.analyzeInstRet(scope, old_inst.cast(text.Inst.Return).?),
961 // TODO postpone function analysis until later
962 .@"fn" => return self.analyzeInstFn(scope, old_inst.cast(text.Inst.Fn).?),1034 .@"fn" => return self.analyzeInstFn(scope, old_inst.cast(text.Inst.Fn).?),
963 .@"export" => {1035 .@"export" => {
964 try self.analyzeExport(scope, old_inst.cast(text.Inst.Export).?);1036 try self.analyzeExport(scope, old_inst.cast(text.Inst.Export).?);
965 return self.constVoid(old_inst.src);1037 return self.constVoid(scope, old_inst.src);
966 },1038 },
967 .primitive => return self.analyzeInstPrimitive(old_inst.cast(text.Inst.Primitive).?),1039 .primitive => return self.analyzeInstPrimitive(old_inst.cast(text.Inst.Primitive).?),
968 .fntype => return self.analyzeInstFnType(scope, old_inst.cast(text.Inst.FnType).?),1040 .fntype => return self.analyzeInstFnType(scope, old_inst.cast(text.Inst.FnType).?),
...@@ -1033,7 +1105,7 @@ pub const Module = struct {...@@ -1033,7 +1105,7 @@ pub const Module = struct {
1033 defer self.allocator.free(fn_param_types);1105 defer self.allocator.free(fn_param_types);
1034 func.ty.fnParamTypes(fn_param_types);1106 func.ty.fnParamTypes(fn_param_types);
10351107
1036 const casted_args = try self.arena.allocator.alloc(*Inst, fn_params_len);1108 const casted_args = try scope.arena().alloc(*Inst, fn_params_len);
1037 for (inst.positionals.args) |src_arg, i| {1109 for (inst.positionals.args) |src_arg, i| {
1038 const uncasted_arg = try self.resolveInst(scope, src_arg);1110 const uncasted_arg = try self.resolveInst(scope, src_arg);
1039 casted_args[i] = try self.coerce(scope, fn_param_types[i], uncasted_arg);1111 casted_args[i] = try self.coerce(scope, fn_param_types[i], uncasted_arg);
...@@ -1048,36 +1120,15 @@ pub const Module = struct {...@@ -1048,36 +1120,15 @@ pub const Module = struct {
10481120
1049 fn analyzeInstFn(self: *Module, scope: *Scope, fn_inst: *text.Inst.Fn) InnerError!*Inst {1121 fn analyzeInstFn(self: *Module, scope: *Scope, fn_inst: *text.Inst.Fn) InnerError!*Inst {
1050 const fn_type = try self.resolveType(scope, fn_inst.positionals.fn_type);1122 const fn_type = try self.resolveType(scope, fn_inst.positionals.fn_type);
10511123 const new_func = try scope.arena().create(Fn);
1052 var new_func: Fn = .{1124 new_func.* = .{
1053 .fn_index = self.fns.items.len,
1054 .inner_block = .{
1055 .func = undefined,
1056 .instructions = .{},
1057 },
1058 .inst_table = std.AutoHashMap(*text.Inst, ?*Inst).init(self.allocator),
1059 };
1060 new_func.inner_block.func = &new_func;
1061 defer new_func.inner_block.instructions.deinit();
1062 defer new_func.inst_table.deinit();
1063 // Don't hang on to a reference to this when analyzing body instructions, since the memory
1064 // could become invalid.
1065 (try self.fns.addOne(self.allocator)).* = .{
1066 .analysis_status = .in_progress,
1067 .fn_type = fn_type,1125 .fn_type = fn_type,
1068 .body = undefined,1126 .analysis = .{ .queued = fn_inst.positionals.body },
1127 .scope = scope.namespace(),
1069 };1128 };
10701129 const fn_payload = try scope.arena().create(Value.Payload.Function);
1071 try self.analyzeBody(&new_func.inner_block, fn_inst.positionals.body);1130 fn_payload.* = .{ .func = new_func };
10721131 return self.constInst(scope, fn_inst.base.src, .{
1073 const f = &self.fns.items[new_func.fn_index];
1074 f.analysis_status = .success;
1075 f.body = .{ .instructions = new_func.inner_block.instructions.toOwnedSlice() };
1076
1077 const fn_payload = try self.arena.allocator.create(Value.Payload.Function);
1078 fn_payload.* = .{ .index = new_func.fn_index };
1079
1080 return self.constInst(fn_inst.base.src, .{
1081 .ty = fn_type,1132 .ty = fn_type,
1082 .val = Value.initPayload(&fn_payload.base),1133 .val = Value.initPayload(&fn_payload.base),
1083 });1134 });
...@@ -1142,13 +1193,13 @@ pub const Module = struct {...@@ -1142,13 +1193,13 @@ pub const Module = struct {
1142 switch (elem_ty.zigTypeTag()) {1193 switch (elem_ty.zigTypeTag()) {
1143 .Array => {1194 .Array => {
1144 if (mem.eql(u8, field_name, "len")) {1195 if (mem.eql(u8, field_name, "len")) {
1145 const len_payload = try self.arena.allocator.create(Value.Payload.Int_u64);1196 const len_payload = try scope.arena().create(Value.Payload.Int_u64);
1146 len_payload.* = .{ .int = elem_ty.arrayLen() };1197 len_payload.* = .{ .int = elem_ty.arrayLen() };
11471198
1148 const ref_payload = try self.arena.allocator.create(Value.Payload.RefVal);1199 const ref_payload = try scope.arena().create(Value.Payload.RefVal);
1149 ref_payload.* = .{ .val = Value.initPayload(&len_payload.base) };1200 ref_payload.* = .{ .val = Value.initPayload(&len_payload.base) };
11501201
1151 return self.constInst(fieldptr.base.src, .{1202 return self.constInst(scope, fieldptr.base.src, .{
1152 .ty = Type.initTag(.single_const_pointer_to_comptime_int),1203 .ty = Type.initTag(.single_const_pointer_to_comptime_int),
1153 .val = Value.initPayload(&ref_payload.base),1204 .val = Value.initPayload(&ref_payload.base),
1154 });1205 });
...@@ -1217,12 +1268,12 @@ pub const Module = struct {...@@ -1217,12 +1268,12 @@ pub const Module = struct {
1217 const index_u64 = index_val.toUnsignedInt();1268 const index_u64 = index_val.toUnsignedInt();
1218 // @intCast here because it would have been impossible to construct a value that1269 // @intCast here because it would have been impossible to construct a value that
1219 // required a larger index.1270 // required a larger index.
1220 const elem_ptr = try array_ptr_val.elemPtr(&self.arena.allocator, @intCast(usize, index_u64));1271 const elem_ptr = try array_ptr_val.elemPtr(scope.arena(), @intCast(usize, index_u64));
12211272
1222 const type_payload = try self.arena.allocator.create(Type.Payload.SingleConstPointer);1273 const type_payload = try scope.arena().create(Type.Payload.SingleConstPointer);
1223 type_payload.* = .{ .pointee_type = array_ptr.ty.elemType().elemType() };1274 type_payload.* = .{ .pointee_type = array_ptr.ty.elemType().elemType() };
12241275
1225 return self.constInst(inst.base.src, .{1276 return self.constInst(scope, inst.base.src, .{
1226 .ty = Type.initPayload(&type_payload.base),1277 .ty = Type.initPayload(&type_payload.base),
1227 .val = elem_ptr,1278 .val = elem_ptr,
1228 });1279 });
...@@ -1246,7 +1297,7 @@ pub const Module = struct {...@@ -1246,7 +1297,7 @@ pub const Module = struct {
1246 var rhs_space: Value.BigIntSpace = undefined;1297 var rhs_space: Value.BigIntSpace = undefined;
1247 const lhs_bigint = lhs_val.toBigInt(&lhs_space);1298 const lhs_bigint = lhs_val.toBigInt(&lhs_space);
1248 const rhs_bigint = rhs_val.toBigInt(&rhs_space);1299 const rhs_bigint = rhs_val.toBigInt(&rhs_space);
1249 const limbs = try self.arena.allocator.alloc(1300 const limbs = try scope.arena().alloc(
1250 std.math.big.Limb,1301 std.math.big.Limb,
1251 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,1302 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,
1252 );1303 );
...@@ -1259,16 +1310,16 @@ pub const Module = struct {...@@ -1259,16 +1310,16 @@ pub const Module = struct {
1259 }1310 }
12601311
1261 const val_payload = if (result_bigint.positive) blk: {1312 const val_payload = if (result_bigint.positive) blk: {
1262 const val_payload = try self.arena.allocator.create(Value.Payload.IntBigPositive);1313 const val_payload = try scope.arena().create(Value.Payload.IntBigPositive);
1263 val_payload.* = .{ .limbs = result_limbs };1314 val_payload.* = .{ .limbs = result_limbs };
1264 break :blk &val_payload.base;1315 break :blk &val_payload.base;
1265 } else blk: {1316 } else blk: {
1266 const val_payload = try self.arena.allocator.create(Value.Payload.IntBigNegative);1317 const val_payload = try scope.arena().create(Value.Payload.IntBigNegative);
1267 val_payload.* = .{ .limbs = result_limbs };1318 val_payload.* = .{ .limbs = result_limbs };
1268 break :blk &val_payload.base;1319 break :blk &val_payload.base;
1269 };1320 };
12701321
1271 return self.constInst(inst.base.src, .{1322 return self.constInst(scope, inst.base.src, .{
1272 .ty = lhs.ty,1323 .ty = lhs.ty,
1273 .val = Value.initPayload(val_payload),1324 .val = Value.initPayload(val_payload),
1274 });1325 });
...@@ -1286,7 +1337,7 @@ pub const Module = struct {...@@ -1286,7 +1337,7 @@ pub const Module = struct {
1286 else => return self.fail(scope, deref.positionals.ptr.src, "expected pointer, found '{}'", .{ptr.ty}),1337 else => return self.fail(scope, deref.positionals.ptr.src, "expected pointer, found '{}'", .{ptr.ty}),
1287 };1338 };
1288 if (ptr.value()) |val| {1339 if (ptr.value()) |val| {
1289 return self.constInst(deref.base.src, .{1340 return self.constInst(scope, deref.base.src, .{
1290 .ty = elem_ty,1341 .ty = elem_ty,
1291 .val = val.pointerDeref(),1342 .val = val.pointerDeref(),
1292 });1343 });
...@@ -1300,9 +1351,9 @@ pub const Module = struct {...@@ -1300,9 +1351,9 @@ pub const Module = struct {
1300 const asm_source = try self.resolveConstString(scope, assembly.positionals.asm_source);1351 const asm_source = try self.resolveConstString(scope, assembly.positionals.asm_source);
1301 const output = if (assembly.kw_args.output) |o| try self.resolveConstString(scope, o) else null;1352 const output = if (assembly.kw_args.output) |o| try self.resolveConstString(scope, o) else null;
13021353
1303 const inputs = try self.arena.allocator.alloc([]const u8, assembly.kw_args.inputs.len);1354 const inputs = try scope.arena().alloc([]const u8, assembly.kw_args.inputs.len);
1304 const clobbers = try self.arena.allocator.alloc([]const u8, assembly.kw_args.clobbers.len);1355 const clobbers = try scope.arena().alloc([]const u8, assembly.kw_args.clobbers.len);
1305 const args = try self.arena.allocator.alloc(*Inst, assembly.kw_args.args.len);1356 const args = try scope.arena().alloc(*Inst, assembly.kw_args.args.len);
13061357
1307 for (inputs) |*elem, i| {1358 for (inputs) |*elem, i| {
1308 elem.* = try self.resolveConstString(scope, assembly.kw_args.inputs[i]);1359 elem.* = try self.resolveConstString(scope, assembly.kw_args.inputs[i]);
...@@ -1408,15 +1459,16 @@ pub const Module = struct {...@@ -1408,15 +1459,16 @@ pub const Module = struct {
1408 const uncasted_cond = try self.resolveInst(scope, inst.positionals.condition);1459 const uncasted_cond = try self.resolveInst(scope, inst.positionals.condition);
1409 const cond = try self.coerce(scope, Type.initTag(.bool), uncasted_cond);1460 const cond = try self.coerce(scope, Type.initTag(.bool), uncasted_cond);
14101461
1411 if (try self.resolveDefinedValue(cond)) |cond_val| {1462 if (try self.resolveDefinedValue(scope, cond)) |cond_val| {
1412 const body = if (cond_val.toBool()) &inst.positionals.true_body else &inst.positionals.false_body;1463 const body = if (cond_val.toBool()) &inst.positionals.true_body else &inst.positionals.false_body;
1413 try self.analyzeBody(scope, body.*);1464 try self.analyzeBody(scope, body.*);
1414 return self.constVoid(inst.base.src);1465 return self.constVoid(scope, inst.base.src);
1415 }1466 }
14161467
1417 const parent_block = try self.requireRuntimeBlock(scope, inst.base.src);1468 const parent_block = try self.requireRuntimeBlock(scope, inst.base.src);
14181469
1419 var true_block: Scope.Block = .{1470 var true_block: Scope.Block = .{
1471 .base = .{ .parent = scope },
1420 .func = parent_block.func,1472 .func = parent_block.func,
1421 .instructions = .{},1473 .instructions = .{},
1422 };1474 };
...@@ -1424,6 +1476,7 @@ pub const Module = struct {...@@ -1424,6 +1476,7 @@ pub const Module = struct {
1424 try self.analyzeBody(&true_block.base, inst.positionals.true_body);1476 try self.analyzeBody(&true_block.base, inst.positionals.true_body);
14251477
1426 var false_block: Scope.Block = .{1478 var false_block: Scope.Block = .{
1479 .base = .{ .parent = scope },
1427 .func = parent_block.func,1480 .func = parent_block.func,
1428 .instructions = .{},1481 .instructions = .{},
1429 };1482 };
...@@ -1431,8 +1484,8 @@ pub const Module = struct {...@@ -1431,8 +1484,8 @@ pub const Module = struct {
1431 try self.analyzeBody(&false_block.base, inst.positionals.false_body);1484 try self.analyzeBody(&false_block.base, inst.positionals.false_body);
14321485
1433 // Copy the instruction pointers to the arena memory1486 // Copy the instruction pointers to the arena memory
1434 const true_instructions = try self.arena.allocator.alloc(*Inst, true_block.instructions.items.len);1487 const true_instructions = try scope.arena().alloc(*Inst, true_block.instructions.items.len);
1435 const false_instructions = try self.arena.allocator.alloc(*Inst, false_block.instructions.items.len);1488 const false_instructions = try scope.arena().alloc(*Inst, false_block.instructions.items.len);
14361489
1437 mem.copy(*Inst, true_instructions, true_block.instructions.items);1490 mem.copy(*Inst, true_instructions, true_block.instructions.items);
1438 mem.copy(*Inst, false_instructions, false_block.instructions.items);1491 mem.copy(*Inst, false_instructions, false_block.instructions.items);
...@@ -1586,7 +1639,7 @@ pub const Module = struct {...@@ -1586,7 +1639,7 @@ pub const Module = struct {
1586 var lhs_bits: usize = undefined;1639 var lhs_bits: usize = undefined;
1587 if (lhs.value()) |lhs_val| {1640 if (lhs.value()) |lhs_val| {
1588 if (lhs_val.isUndef())1641 if (lhs_val.isUndef())
1589 return self.constUndef(src, Type.initTag(.bool));1642 return self.constUndef(scope, src, Type.initTag(.bool));
1590 const is_unsigned = if (lhs_is_float) x: {1643 const is_unsigned = if (lhs_is_float) x: {
1591 var bigint_space: Value.BigIntSpace = undefined;1644 var bigint_space: Value.BigIntSpace = undefined;
1592 var bigint = try lhs_val.toBigInt(&bigint_space).toManaged(self.allocator);1645 var bigint = try lhs_val.toBigInt(&bigint_space).toManaged(self.allocator);
...@@ -1621,7 +1674,7 @@ pub const Module = struct {...@@ -1621,7 +1674,7 @@ pub const Module = struct {
1621 var rhs_bits: usize = undefined;1674 var rhs_bits: usize = undefined;
1622 if (rhs.value()) |rhs_val| {1675 if (rhs.value()) |rhs_val| {
1623 if (rhs_val.isUndef())1676 if (rhs_val.isUndef())
1624 return self.constUndef(src, Type.initTag(.bool));1677 return self.constUndef(scope, src, Type.initTag(.bool));
1625 const is_unsigned = if (rhs_is_float) x: {1678 const is_unsigned = if (rhs_is_float) x: {
1626 var bigint_space: Value.BigIntSpace = undefined;1679 var bigint_space: Value.BigIntSpace = undefined;
1627 var bigint = try rhs_val.toBigInt(&bigint_space).toManaged(self.allocator);1680 var bigint = try rhs_val.toBigInt(&bigint_space).toManaged(self.allocator);
...@@ -1670,13 +1723,13 @@ pub const Module = struct {...@@ -1670,13 +1723,13 @@ pub const Module = struct {
1670 });1723 });
1671 }1724 }
16721725
1673 fn makeIntType(self: *Module, signed: bool, bits: u16) !Type {1726 fn makeIntType(self: *Module, scope: *Scope, signed: bool, bits: u16) !Type {
1674 if (signed) {1727 if (signed) {
1675 const int_payload = try self.arena.allocator.create(Type.Payload.IntSigned);1728 const int_payload = try scope.arena().create(Type.Payload.IntSigned);
1676 int_payload.* = .{ .bits = bits };1729 int_payload.* = .{ .bits = bits };
1677 return Type.initPayload(&int_payload.base);1730 return Type.initPayload(&int_payload.base);
1678 } else {1731 } else {
1679 const int_payload = try self.arena.allocator.create(Type.Payload.IntUnsigned);1732 const int_payload = try scope.arena().create(Type.Payload.IntUnsigned);
1680 int_payload.* = .{ .bits = bits };1733 int_payload.* = .{ .bits = bits };
1681 return Type.initPayload(&int_payload.base);1734 return Type.initPayload(&int_payload.base);
1682 }1735 }
...@@ -1701,7 +1754,7 @@ pub const Module = struct {...@@ -1701,7 +1754,7 @@ pub const Module = struct {
1701 if (array_type.zigTypeTag() == .Array and1754 if (array_type.zigTypeTag() == .Array and
1702 coerceInMemoryAllowed(dst_elem_type, array_type.elemType()) == .ok)1755 coerceInMemoryAllowed(dst_elem_type, array_type.elemType()) == .ok)
1703 {1756 {
1704 return self.coerceArrayPtrToSlice(dest_type, inst);1757 return self.coerceArrayPtrToSlice(scope, dest_type, inst);
1705 }1758 }
1706 }1759 }
17071760
...@@ -1712,7 +1765,7 @@ pub const Module = struct {...@@ -1712,7 +1765,7 @@ pub const Module = struct {
1712 if (!val.intFitsInType(dest_type, self.target())) {1765 if (!val.intFitsInType(dest_type, self.target())) {
1713 return self.fail(scope, inst.src, "type {} cannot represent integer value {}", .{ inst.ty, val });1766 return self.fail(scope, inst.src, "type {} cannot represent integer value {}", .{ inst.ty, val });
1714 }1767 }
1715 return self.constInst(inst.src, .{ .ty = dest_type, .val = val });1768 return self.constInst(scope, inst.src, .{ .ty = dest_type, .val = val });
1716 }1769 }
17171770
1718 // integer widening1771 // integer widening
...@@ -1721,7 +1774,7 @@ pub const Module = struct {...@@ -1721,7 +1774,7 @@ pub const Module = struct {
1721 const dst_info = dest_type.intInfo(self.target());1774 const dst_info = dest_type.intInfo(self.target());
1722 if (src_info.signed == dst_info.signed and dst_info.bits >= src_info.bits) {1775 if (src_info.signed == dst_info.signed and dst_info.bits >= src_info.bits) {
1723 if (inst.value()) |val| {1776 if (inst.value()) |val| {
1724 return self.constInst(inst.src, .{ .ty = dest_type, .val = val });1777 return self.constInst(scope, inst.src, .{ .ty = dest_type, .val = val });
1725 } else {1778 } else {
1726 return self.fail(scope, inst.src, "TODO implement runtime integer widening", .{});1779 return self.fail(scope, inst.src, "TODO implement runtime integer widening", .{});
1727 }1780 }
...@@ -1736,33 +1789,41 @@ pub const Module = struct {...@@ -1736,33 +1789,41 @@ pub const Module = struct {
1736 fn bitcast(self: *Module, scope: *Scope, dest_type: Type, inst: *Inst) !*Inst {1789 fn bitcast(self: *Module, scope: *Scope, dest_type: Type, inst: *Inst) !*Inst {
1737 if (inst.value()) |val| {1790 if (inst.value()) |val| {
1738 // Keep the comptime Value representation; take the new type.1791 // Keep the comptime Value representation; take the new type.
1739 return self.constInst(inst.src, .{ .ty = dest_type, .val = val });1792 return self.constInst(scope, inst.src, .{ .ty = dest_type, .val = val });
1740 }1793 }
1741 // TODO validate the type size and other compile errors1794 // TODO validate the type size and other compile errors
1742 const b = try self.requireRuntimeBlock(scope, inst.src);1795 const b = try self.requireRuntimeBlock(scope, inst.src);
1743 return self.addNewInstArgs(b, inst.src, dest_type, Inst.BitCast, Inst.Args(Inst.BitCast){ .operand = inst });1796 return self.addNewInstArgs(b, inst.src, dest_type, Inst.BitCast, Inst.Args(Inst.BitCast){ .operand = inst });
1744 }1797 }
17451798
1746 fn coerceArrayPtrToSlice(self: *Module, dest_type: Type, inst: *Inst) !*Inst {1799 fn coerceArrayPtrToSlice(self: *Module, scope: *Scope, dest_type: Type, inst: *Inst) !*Inst {
1747 if (inst.value()) |val| {1800 if (inst.value()) |val| {
1748 // The comptime Value representation is compatible with both types.1801 // The comptime Value representation is compatible with both types.
1749 return self.constInst(inst.src, .{ .ty = dest_type, .val = val });1802 return self.constInst(scope, inst.src, .{ .ty = dest_type, .val = val });
1750 }1803 }
1751 return self.fail(scope, inst.src, "TODO implement coerceArrayPtrToSlice runtime instruction", .{});1804 return self.fail(scope, inst.src, "TODO implement coerceArrayPtrToSlice runtime instruction", .{});
1752 }1805 }
17531806
1754 fn fail(self: *Module, scope: *Scope, src: usize, comptime format: []const u8, args: var) InnerError {1807 fn fail(self: *Module, scope: *Scope, src: usize, comptime format: []const u8, args: var) InnerError {
1755 @setCold(true);1808 @setCold(true);
1756 const err_msg = ErrorMsg{1809 try self.failed_decls.ensureCapacity(self.failed_decls.size + 1);
1757 .byte_offset = src,1810 try self.failed_fns.ensureCapacity(self.failed_fns.size + 1);
1758 .msg = try std.fmt.allocPrint(self.allocator, format, args),1811 const err_msg = try ErrorMsg.create(self.allocator, src, format, args);
1759 };1812 switch (scope.tag) {
1760 if (scope.cast(Scope.Block)) |block| {1813 .decl => {
1761 block.func.analysis = .{ .failure = err_msg };1814 const decl = scope.cast(Scope.DeclAnalysis).?.decl;
1762 } else if (scope.cast(Scope.Decl)) |scope_decl| {1815 switch (decl.analysis) {
1763 scope_decl.decl.analysis = .{ .failure = err_msg };1816 .initial_in_progress => decl.analysis = .initial_sema_failure,
1764 } else {1817 .repeat_in_progress => decl.analysis = .repeat_sema_failure,
1765 unreachable;1818 else => unreachable,
1819 }
1820 self.failed_decls.putAssumeCapacityNoClobber(decl, err_msg);
1821 },
1822 .block => {
1823 const func = scope.cast(Scope.Block).?.func;
1824 func.analysis = .failure;
1825 self.failed_fns.putAssumeCapacityNoClobber(func, err_msg);
1826 },
1766 }1827 }
1767 return error.AnalysisFail;1828 return error.AnalysisFail;
1768 }1829 }
...@@ -1788,8 +1849,8 @@ pub const ErrorMsg = struct {...@@ -1788,8 +1849,8 @@ pub const ErrorMsg = struct {
17881849
1789 pub fn create(allocator: *Allocator, byte_offset: usize, comptime format: []const u8, args: var) !*ErrorMsg {1850 pub fn create(allocator: *Allocator, byte_offset: usize, comptime format: []const u8, args: var) !*ErrorMsg {
1790 const self = try allocator.create(ErrorMsg);1851 const self = try allocator.create(ErrorMsg);
1791 errdefer allocator.destroy(ErrorMsg);1852 errdefer allocator.destroy(self);
1792 self.* = init(allocator, byte_offset, format, args);1853 self.* = try init(allocator, byte_offset, format, args);
1793 return self;1854 return self;
1794 }1855 }
17951856
src-self-hosted/ir/text.zig+11-11
...@@ -631,7 +631,7 @@ const Parser = struct {...@@ -631,7 +631,7 @@ const Parser = struct {
631 if (try body_context.name_map.put(ident, ident_index)) |_| {631 if (try body_context.name_map.put(ident, ident_index)) |_| {
632 return self.fail("redefinition of identifier '{}'", .{ident});632 return self.fail("redefinition of identifier '{}'", .{ident});
633 }633 }
634 try body_context.instructions.append(inst);634 try body_context.instructions.append(self.allocator, inst);
635 continue;635 continue;
636 },636 },
637 ' ', '\n' => continue,637 ' ', '\n' => continue,
...@@ -717,7 +717,7 @@ const Parser = struct {...@@ -717,7 +717,7 @@ const Parser = struct {
717 if (try self.global_name_map.put(ident, ident_index)) |_| {717 if (try self.global_name_map.put(ident, ident_index)) |_| {
718 return self.fail("redefinition of identifier '{}'", .{ident});718 return self.fail("redefinition of identifier '{}'", .{ident});
719 }719 }
720 try self.decls.append(inst);720 try self.decls.append(self.allocator, inst);
721 },721 },
722 ' ', '\n' => self.i += 1,722 ' ', '\n' => self.i += 1,
723 0 => break,723 0 => break,
...@@ -885,7 +885,7 @@ const Parser = struct {...@@ -885,7 +885,7 @@ const Parser = struct {
885 var instructions = std.ArrayList(*Inst).init(&self.arena.allocator);885 var instructions = std.ArrayList(*Inst).init(&self.arena.allocator);
886 while (true) {886 while (true) {
887 skipSpace(self);887 skipSpace(self);
888 try instructions.append(try parseParameterInst(self, body_ctx));888 try instructions.append(self.allocator, try parseParameterInst(self, body_ctx));
889 skipSpace(self);889 skipSpace(self);
890 if (!eatByte(self, ',')) break;890 if (!eatByte(self, ',')) break;
891 }891 }
...@@ -991,7 +991,7 @@ const EmitZIR = struct {...@@ -991,7 +991,7 @@ const EmitZIR = struct {
991 },991 },
992 .kw_args = .{},992 .kw_args = .{},
993 };993 };
994 try self.decls.append(&export_inst.base);994 try self.decls.append(self.allocator, &export_inst.base);
995 }995 }
996 }996 }
997997
...@@ -1018,7 +1018,7 @@ const EmitZIR = struct {...@@ -1018,7 +1018,7 @@ const EmitZIR = struct {
1018 },1018 },
1019 .kw_args = .{},1019 .kw_args = .{},
1020 };1020 };
1021 try self.decls.append(&int_inst.base);1021 try self.decls.append(self.allocator, &int_inst.base);
1022 return &int_inst.base;1022 return &int_inst.base;
1023 }1023 }
10241024
...@@ -1051,7 +1051,7 @@ const EmitZIR = struct {...@@ -1051,7 +1051,7 @@ const EmitZIR = struct {
1051 },1051 },
1052 .kw_args = .{},1052 .kw_args = .{},
1053 };1053 };
1054 try self.decls.append(&as_inst.base);1054 try self.decls.append(self.allocator, &as_inst.base);
10551055
1056 return &as_inst.base;1056 return &as_inst.base;
1057 },1057 },
...@@ -1085,7 +1085,7 @@ const EmitZIR = struct {...@@ -1085,7 +1085,7 @@ const EmitZIR = struct {
1085 },1085 },
1086 .kw_args = .{},1086 .kw_args = .{},
1087 };1087 };
1088 try self.decls.append(&fn_inst.base);1088 try self.decls.append(self.allocator, &fn_inst.base);
1089 return &fn_inst.base;1089 return &fn_inst.base;
1090 },1090 },
1091 else => |t| std.debug.panic("TODO implement emitTypedValue for {}", .{@tagName(t)}),1091 else => |t| std.debug.panic("TODO implement emitTypedValue for {}", .{@tagName(t)}),
...@@ -1258,7 +1258,7 @@ const EmitZIR = struct {...@@ -1258,7 +1258,7 @@ const EmitZIR = struct {
1258 break :blk &new_inst.base;1258 break :blk &new_inst.base;
1259 },1259 },
1260 };1260 };
1261 try instructions.append(new_inst);1261 try instructions.append(self.allocator, new_inst);
1262 try inst_table.putNoClobber(inst, new_inst);1262 try inst_table.putNoClobber(inst, new_inst);
1263 }1263 }
1264 }1264 }
...@@ -1310,7 +1310,7 @@ const EmitZIR = struct {...@@ -1310,7 +1310,7 @@ const EmitZIR = struct {
1310 .cc = ty.fnCallingConvention(),1310 .cc = ty.fnCallingConvention(),
1311 },1311 },
1312 };1312 };
1313 try self.decls.append(&fntype_inst.base);1313 try self.decls.append(self.allocator, &fntype_inst.base);
1314 return &fntype_inst.base;1314 return &fntype_inst.base;
1315 },1315 },
1316 else => std.debug.panic("TODO implement emitType for {}", .{ty}),1316 else => std.debug.panic("TODO implement emitType for {}", .{ty}),
...@@ -1327,7 +1327,7 @@ const EmitZIR = struct {...@@ -1327,7 +1327,7 @@ const EmitZIR = struct {
1327 },1327 },
1328 .kw_args = .{},1328 .kw_args = .{},
1329 };1329 };
1330 try self.decls.append(&primitive_inst.base);1330 try self.decls.append(self.allocator, &primitive_inst.base);
1331 return &primitive_inst.base;1331 return &primitive_inst.base;
1332 }1332 }
13331333
...@@ -1340,7 +1340,7 @@ const EmitZIR = struct {...@@ -1340,7 +1340,7 @@ const EmitZIR = struct {
1340 },1340 },
1341 .kw_args = .{},1341 .kw_args = .{},
1342 };1342 };
1343 try self.decls.append(&str_inst.base);1343 try self.decls.append(self.allocator, &str_inst.base);
1344 return &str_inst.base;1344 return &str_inst.base;
1345 }1345 }
1346};1346};
src-self-hosted/value.zig+1-1
...@@ -160,7 +160,7 @@ pub const Value = extern union {...@@ -160,7 +160,7 @@ pub const Value = extern union {
160 .function => return out_stream.writeAll("(function)"),160 .function => return out_stream.writeAll("(function)"),
161 .decl_ref => return out_stream.writeAll("(decl ref)"),161 .decl_ref => return out_stream.writeAll("(decl ref)"),
162 .elem_ptr => {162 .elem_ptr => {
163 const elem_ptr = val.cast(Payload.Int_u64).?;163 const elem_ptr = val.cast(Payload.ElemPtr).?;
164 try out_stream.print("&[{}] ", .{elem_ptr.index});164 try out_stream.print("&[{}] ", .{elem_ptr.index});
165 val = elem_ptr.array_ptr;165 val = elem_ptr.array_ptr;
166 },166 },