authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-07-14 22:44:57-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-07-20 12:19:16-07:00
log1294ebe1f5eaca1f11d68284d1b96419d53253be
tree8c01f0969b0c4a8be40a6bf3b89d2ec736bd46ae
parentc020a302960c499ffe811dd0601a2d386c191b91

Sema: AIR memory layout reworking for noreturn instructions


2 files changed, 41 insertions(+), 49 deletions(-)

src/Module.zig+1-1
......@@ -1255,7 +1255,7 @@ pub const Scope = struct {
12551255 pub fn addNoOp(block: *Block, tag: Air.Inst.Tag) error{OutOfMemory}!Air.Inst.Ref {
12561256 return block.addInst(.{
12571257 .tag = tag,
1258 .data = .no_op,
1258 .data = .{ .no_op = {} },
12591259 });
12601260 }
12611261
src/Sema.zig+40-48
......@@ -381,20 +381,20 @@ pub fn analyzeBody(
381381 .sub => try sema.zirArithmetic(block, inst),
382382 .subwrap => try sema.zirArithmetic(block, inst),
383383
384 //// Instructions that we know to *always* be noreturn based solely on their tag.
385 //// These functions match the return type of analyzeBody so that we can
386 //// tail call them here.
387 //.break_inline => return inst,
388 //.condbr => return sema.zirCondbr(block, inst),
389 //.@"break" => return sema.zirBreak(block, inst),
390 //.compile_error => return sema.zirCompileError(block, inst),
391 //.ret_coerce => return sema.zirRetCoerce(block, inst, true),
392 //.ret_node => return sema.zirRetNode(block, inst),
393 //.ret_err_value => return sema.zirRetErrValue(block, inst),
394 //.@"unreachable" => return sema.zirUnreachable(block, inst),
395 //.repeat => return sema.zirRepeat(block, inst),
396 //.panic => return sema.zirPanic(block, inst),
397 //// zig fmt: on
384 // Instructions that we know to *always* be noreturn based solely on their tag.
385 // These functions match the return type of analyzeBody so that we can
386 // tail call them here.
387 .break_inline => return inst,
388 .condbr => return sema.zirCondbr(block, inst),
389 .@"break" => return sema.zirBreak(block, inst),
390 .compile_error => return sema.zirCompileError(block, inst),
391 .ret_coerce => return sema.zirRetCoerce(block, inst, true),
392 .ret_node => return sema.zirRetNode(block, inst),
393 .ret_err_value => return sema.zirRetErrValue(block, inst),
394 .@"unreachable" => return sema.zirUnreachable(block, inst),
395 .repeat => return sema.zirRepeat(block, inst),
396 .panic => return sema.zirPanic(block, inst),
397 // zig fmt: on
398398
399399 //// Instructions that we know can *never* be noreturn based solely on
400400 //// their tag. We avoid needlessly checking if they are noreturn and
......@@ -534,7 +534,7 @@ pub fn analyzeBody(
534534 return break_inst;
535535 }
536536 },
537 else => @panic("TODO finish updating Sema for AIR memory layout changes and then remove this else prong"),
537 else => |t| @panic(@tagName(t)),
538538 };
539539 if (sema.getTypeOf(air_inst).isNoReturn())
540540 return always_noreturn;
......@@ -2128,7 +2128,6 @@ fn zirBreak(sema: *Sema, start_block: *Scope.Block, inst: Zir.Inst.Index) Compil
21282128 defer tracy.end();
21292129
21302130 const inst_data = sema.code.instructions.items(.data)[inst].@"break";
2131 const src = sema.src;
21322131 const operand = sema.resolveInst(inst_data.operand);
21332132 const zir_block = inst_data.block_inst;
21342133
......@@ -2136,26 +2135,9 @@ fn zirBreak(sema: *Sema, start_block: *Scope.Block, inst: Zir.Inst.Index) Compil
21362135 while (true) {
21372136 if (block.label) |label| {
21382137 if (label.zir_block == zir_block) {
2139 // Here we add a br instruction, but we over-allocate a little bit
2140 // (if necessary) to make it possible to convert the instruction into
2141 // a br_block_flat instruction later.
2142 const br = @ptrCast(*Inst.Br, try sema.arena.alignedAlloc(
2143 u8,
2144 Inst.convertable_br_align,
2145 Inst.convertable_br_size,
2146 ));
2147 br.* = .{
2148 .base = .{
2149 .tag = .br,
2150 .ty = Type.initTag(.noreturn),
2151 .src = src,
2152 },
2153 .operand = operand,
2154 .block = label.merges.block_inst,
2155 };
2156 try start_block.instructions.append(sema.gpa, &br.base);
2138 const br_ref = try start_block.addBr(label.merges.block_inst, operand);
21572139 try label.merges.results.append(sema.gpa, operand);
2158 try label.merges.br_list.append(sema.gpa, br);
2140 try label.merges.br_list.append(sema.gpa, refToIndex(br_ref).?);
21592141 return inst;
21602142 }
21612143 }
......@@ -5391,25 +5373,35 @@ fn zirCondbr(
53915373 return always_noreturn;
53925374 }
53935375
5376 const gpa = sema.gpa;
5377
5378 // We'll re-use the sub block to save on memory bandwidth, and yank out the
5379 // instructions array in between using it for the then block and else block.
53945380 var sub_block = parent_block.makeSubBlock();
53955381 sub_block.runtime_loop = null;
5396 sub_block.runtime_cond = cond.src;
5382 sub_block.runtime_cond = cond_src;
53975383 sub_block.runtime_index += 1;
5398 defer sub_block.instructions.deinit(sema.gpa);
5384 defer sub_block.instructions.deinit(gpa);
53995385
54005386 _ = try sema.analyzeBody(&sub_block, then_body);
5401 const air_then_body: ir.Body = .{
5402 .instructions = try sema.arena.dupe(Air.Inst.Index, sub_block.instructions.items),
5403 };
5404
5405 sub_block.instructions.shrinkRetainingCapacity(0);
5387 const true_instructions = sub_block.instructions.toOwnedSlice(gpa);
5388 defer gpa.free(true_instructions);
54065389
54075390 _ = try sema.analyzeBody(&sub_block, else_body);
5408 const air_else_body: ir.Body = .{
5409 .instructions = try sema.arena.dupe(Air.Inst.Index, sub_block.instructions.items),
5410 };
5411
5412 _ = try parent_block.addCondBr(src, cond, air_then_body, air_else_body);
5391 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.CondBr).Struct.fields.len +
5392 true_instructions.len + sub_block.instructions.items.len);
5393 _ = try parent_block.addInst(.{
5394 .tag = .cond_br,
5395 .data = .{ .pl_op = .{
5396 .operand = cond,
5397 .payload = sema.addExtraAssumeCapacity(Air.CondBr{
5398 .then_body_len = @intCast(u32, true_instructions.len),
5399 .else_body_len = @intCast(u32, sub_block.instructions.items.len),
5400 }),
5401 } },
5402 });
5403 sema.air_extra.appendSliceAssumeCapacity(true_instructions);
5404 sema.air_extra.appendSliceAssumeCapacity(sub_block.instructions.items);
54135405 return always_noreturn;
54145406}
54155407
......@@ -6443,7 +6435,7 @@ fn panicWithMsg(
64436435 try mod.optionalType(arena, ptr_stack_trace_ty),
64446436 Value.initTag(.null_value),
64456437 );
6446 const args = try arena.create([2]Air.Inst.Index);
6438 const args = try arena.create([2]Air.Inst.Ref);
64476439 args.* = .{ msg_inst, null_stack_trace };
64486440 _ = try sema.analyzeCall(block, panic_fn, src, src, .auto, false, args);
64496441 return always_noreturn;