diff --git a/src/Module.zig b/src/Module.zig index 0601245db3..4a4f0206d7 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -1088,7 +1088,7 @@ pub const Scope = struct { /// for the one that will be the same for all Block instances. src_decl: *Decl, instructions: ArrayListUnmanaged(*ir.Inst), - label: ?Label = null, + label: ?*Label = null, inlining: ?*Inlining, is_comptime: bool, diff --git a/src/Sema.zig b/src/Sema.zig index 2645a6b2a0..3a5de5c789 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -1610,8 +1610,7 @@ fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) InnerE .body = undefined, }; - var child_block = parent_block.makeSubBlock(); - child_block.label = Scope.Block.Label{ + var label: Scope.Block.Label = .{ .zir_block = inst, .merges = .{ .results = .{}, @@ -1619,6 +1618,8 @@ fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) InnerE .block_inst = block_inst, }, }; + var child_block = parent_block.makeSubBlock(); + child_block.label = &label; const merges = &child_block.label.?.merges; defer child_block.instructions.deinit(sema.gpa); @@ -1689,20 +1690,21 @@ fn zirBlock(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Inner .body = undefined, }; + var label: Scope.Block.Label = .{ + .zir_block = inst, + .merges = .{ + .results = .{}, + .br_list = .{}, + .block_inst = block_inst, + }, + }; + var child_block: Scope.Block = .{ .parent = parent_block, .sema = sema, .src_decl = parent_block.src_decl, .instructions = .{}, - // TODO @as here is working around a stage1 miscompilation bug :( - .label = @as(?Scope.Block.Label, Scope.Block.Label{ - .zir_block = inst, - .merges = .{ - .results = .{}, - .br_list = .{}, - .block_inst = block_inst, - }, - }), + .label = &label, .inlining = parent_block.inlining, .is_comptime = parent_block.is_comptime, }; @@ -1895,7 +1897,7 @@ fn zirBreak(sema: *Sema, start_block: *Scope.Block, inst: Zir.Inst.Index) InnerE var block = start_block; while (true) { - if (block.label) |*label| { + if (block.label) |label| { if (label.zir_block == zir_block) { // Here we add a br instruction, but we over-allocate a little bit // (if necessary) to make it possible to convert the instruction into @@ -2084,26 +2086,38 @@ fn analyzeCall( .block_inst = block_inst, }, }; - const callee_zir = module_fn.owner_decl.namespace.file_scope.zir; - var inline_sema: Sema = .{ - .mod = sema.mod, - .gpa = sema.mod.gpa, - .arena = sema.arena, - .code = callee_zir, - .inst_map = try sema.gpa.alloc(*ir.Inst, callee_zir.instructions.len), - .owner_decl = sema.owner_decl, - .namespace = sema.owner_decl.namespace, - .owner_func = sema.owner_func, - .func = module_fn, - .param_inst_list = casted_args, - .branch_quota = sema.branch_quota, - .branch_count = sema.branch_count, - }; - defer sema.gpa.free(inline_sema.inst_map); + // In order to save a bit of stack space, directly modify Sema rather + // than create a child one. + const parent_zir = sema.code; + sema.code = module_fn.owner_decl.namespace.file_scope.zir; + defer sema.code = parent_zir; + + const parent_inst_map = sema.inst_map; + sema.inst_map = try sema.gpa.alloc(*ir.Inst, sema.code.instructions.len); + defer { + sema.gpa.free(sema.inst_map); + sema.inst_map = parent_inst_map; + } + + const parent_namespace = sema.namespace; + sema.namespace = module_fn.owner_decl.namespace; + defer sema.namespace = parent_namespace; + + const parent_func = sema.func; + sema.func = module_fn; + defer sema.func = parent_func; + + const parent_param_inst_list = sema.param_inst_list; + sema.param_inst_list = casted_args; + defer sema.param_inst_list = parent_param_inst_list; + + const parent_next_arg_index = sema.next_arg_index; + sema.next_arg_index = 0; + defer sema.next_arg_index = parent_next_arg_index; var child_block: Scope.Block = .{ .parent = null, - .sema = &inline_sema, + .sema = sema, .src_decl = module_fn.owner_decl, .instructions = .{}, .label = null, @@ -2117,16 +2131,13 @@ fn analyzeCall( defer merges.results.deinit(sema.gpa); defer merges.br_list.deinit(sema.gpa); - try inline_sema.emitBackwardBranch(&child_block, call_src); + try sema.emitBackwardBranch(&child_block, call_src); // This will have return instructions analyzed as break instructions to // the block_inst above. - try inline_sema.analyzeFnBody(&child_block, module_fn.zir_body_inst); + try sema.analyzeFnBody(&child_block, module_fn.zir_body_inst); - const result = try inline_sema.analyzeBlockBody(block, call_src, &child_block, merges); - - sema.branch_quota = inline_sema.branch_quota; - sema.branch_count = inline_sema.branch_count; + const result = try sema.analyzeBlockBody(block, call_src, &child_block, merges); break :res result; } else res: { @@ -3797,20 +3808,21 @@ fn analyzeSwitch( .body = undefined, }; + var label: Scope.Block.Label = .{ + .zir_block = switch_inst, + .merges = .{ + .results = .{}, + .br_list = .{}, + .block_inst = block_inst, + }, + }; + var child_block: Scope.Block = .{ .parent = block, .sema = sema, .src_decl = block.src_decl, .instructions = .{}, - // TODO @as here is working around a stage1 miscompilation bug :( - .label = @as(?Scope.Block.Label, Scope.Block.Label{ - .zir_block = switch_inst, - .merges = .{ - .results = .{}, - .br_list = .{}, - .block_inst = block_inst, - }, - }), + .label = &label, .inlining = block.inlining, .is_comptime = block.is_comptime, }; diff --git a/src/main.zig b/src/main.zig index 01be971602..ae7c8995a3 100644 --- a/src/main.zig +++ b/src/main.zig @@ -180,6 +180,18 @@ pub fn mainArgs(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !v defer log_scopes.deinit(gpa); + if (@import("builtin").target.os.tag == .linux) { + // Linux does not respect the stack size specified in the ELF, so we + // have to do this at runtime. TODO move this code to start.zig using + // the GNU_STACK program header. + std.os.setrlimit(.STACK, .{ + .cur = 16 * 1024 * 1024, + .max = 16 * 1024 * 1024, + }) catch |err| { + warn("unable to increase stack size to 16 MiB", .{}); + }; + } + const cmd = args[1]; const cmd_args = args[2..]; if (mem.eql(u8, cmd, "build-exe")) {