| ... | ... | @@ -2373,8 +2373,8 @@ fn labeledBlockExpr( |
| 2373 | 2373 | try astgen.appendErrorTok(label_token, "unused block label", .{}); |
| 2374 | 2374 | } |
| 2375 | 2375 | |
| 2376 | | const zir_datas = gz.astgen.instructions.items(.data); |
| 2377 | | const zir_tags = gz.astgen.instructions.items(.tag); |
| 2376 | const zir_datas = astgen.instructions.items(.data); |
| 2377 | const zir_tags = astgen.instructions.items(.tag); |
| 2378 | 2378 | const strat = ri.rl.strategy(&block_scope); |
| 2379 | 2379 | switch (strat.tag) { |
| 2380 | 2380 | .break_void => { |
| ... | ... | @@ -2396,6 +2396,10 @@ fn labeledBlockExpr( |
| 2396 | 2396 | // it as the break operand. |
| 2397 | 2397 | // This corresponds to similar code in `setCondBrPayloadElideBlockStorePtr`. |
| 2398 | 2398 | if (block_scope.rl_ty_inst != .none) { |
| 2399 | try astgen.extra.ensureUnusedCapacity( |
| 2400 | astgen.gpa, |
| 2401 | @typeInfo(Zir.Inst.As).Struct.fields.len * block_scope.labeled_breaks.items.len, |
| 2402 | ); |
| 2399 | 2403 | for (block_scope.labeled_breaks.items) |br| { |
| 2400 | 2404 | // We expect the `store_to_block_ptr` to be created between 1-3 instructions |
| 2401 | 2405 | // prior to the break. |
| ... | ... | @@ -2404,12 +2408,28 @@ fn labeledBlockExpr( |
| 2404 | 2408 | if (zir_tags[search_index] == .store_to_block_ptr and |
| 2405 | 2409 | zir_datas[search_index].bin.lhs == block_scope.rl_ptr) |
| 2406 | 2410 | { |
| 2407 | | zir_tags[search_index] = .as; |
| 2408 | | zir_datas[search_index].bin = .{ |
| 2409 | | .lhs = block_scope.rl_ty_inst, |
| 2410 | | .rhs = zir_datas[br.br].@"break".operand, |
| 2411 | | }; |
| 2412 | | zir_datas[br.br].@"break".operand = indexToRef(search_index); |
| 2411 | const break_data = &zir_datas[br.br].@"break"; |
| 2412 | const break_src: i32 = @bitCast(astgen.extra.items[ |
| 2413 | break_data.payload_index + |
| 2414 | std.meta.fieldIndex(Zir.Inst.Break, "operand_src_node").? |
| 2415 | ]); |
| 2416 | if (break_src == Zir.Inst.Break.no_src_node) { |
| 2417 | zir_tags[search_index] = .as; |
| 2418 | zir_datas[search_index].bin = .{ |
| 2419 | .lhs = block_scope.rl_ty_inst, |
| 2420 | .rhs = break_data.operand, |
| 2421 | }; |
| 2422 | } else { |
| 2423 | zir_tags[search_index] = .as_node; |
| 2424 | zir_datas[search_index] = .{ .pl_node = .{ |
| 2425 | .src_node = break_src, |
| 2426 | .payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.As{ |
| 2427 | .dest_type = block_scope.rl_ty_inst, |
| 2428 | .operand = break_data.operand, |
| 2429 | }), |
| 2430 | } }; |
| 2431 | } |
| 2432 | break_data.operand = indexToRef(search_index); |
| 2413 | 2433 | break; |
| 2414 | 2434 | } |
| 2415 | 2435 | } else unreachable; |
| ... | ... | @@ -2530,19 +2550,21 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As |
| 2530 | 2550 | // For some instructions, modify the zir data |
| 2531 | 2551 | // so we can avoid a separate ensure_result_used instruction. |
| 2532 | 2552 | .call, .field_call => { |
| 2533 | | const extra_index = gz.astgen.instructions.items(.data)[inst].pl_node.payload_index; |
| 2534 | | const slot = &gz.astgen.extra.items[extra_index]; |
| 2535 | | var flags = @as(Zir.Inst.Call.Flags, @bitCast(slot.*)); |
| 2553 | const break_extra = gz.astgen.instructions.items(.data)[inst].pl_node.payload_index; |
| 2554 | comptime assert(std.meta.fieldIndex(Zir.Inst.Call, "flags") == |
| 2555 | std.meta.fieldIndex(Zir.Inst.FieldCall, "flags")); |
| 2556 | const flags: *Zir.Inst.Call.Flags = @ptrCast(&gz.astgen.extra.items[ |
| 2557 | break_extra + std.meta.fieldIndex(Zir.Inst.Call, "flags").? |
| 2558 | ]); |
| 2536 | 2559 | flags.ensure_result_used = true; |
| 2537 | | slot.* = @as(u32, @bitCast(flags)); |
| 2538 | 2560 | break :b true; |
| 2539 | 2561 | }, |
| 2540 | 2562 | .builtin_call => { |
| 2541 | | const extra_index = gz.astgen.instructions.items(.data)[inst].pl_node.payload_index; |
| 2542 | | const slot = &gz.astgen.extra.items[extra_index]; |
| 2543 | | var flags = @as(Zir.Inst.BuiltinCall.Flags, @bitCast(slot.*)); |
| 2563 | const break_extra = gz.astgen.instructions.items(.data)[inst].pl_node.payload_index; |
| 2564 | const flags: *Zir.Inst.BuiltinCall.Flags = @ptrCast(&gz.astgen.extra.items[ |
| 2565 | break_extra + std.meta.fieldIndex(Zir.Inst.BuiltinCall, "flags").? |
| 2566 | ]); |
| 2544 | 2567 | flags.ensure_result_used = true; |
| 2545 | | slot.* = @as(u32, @bitCast(flags)); |
| 2546 | 2568 | break :b true; |
| 2547 | 2569 | }, |
| 2548 | 2570 | |
| ... | ... | @@ -6106,14 +6128,12 @@ fn setCondBrPayloadElideBlockStorePtr( |
| 6106 | 6128 | const zir_tags = astgen.instructions.items(.tag); |
| 6107 | 6129 | const zir_datas = astgen.instructions.items(.data); |
| 6108 | 6130 | |
| 6109 | | const condbr_pl = astgen.addExtraAssumeCapacity(Zir.Inst.CondBr{ |
| 6131 | const condbr_extra = astgen.addExtraAssumeCapacity(Zir.Inst.CondBr{ |
| 6110 | 6132 | .condition = cond, |
| 6111 | 6133 | .then_body_len = then_body_len, |
| 6112 | 6134 | .else_body_len = else_body_len, |
| 6113 | 6135 | }); |
| 6114 | | zir_datas[condbr].pl_node.payload_index = condbr_pl; |
| 6115 | | const then_body_len_index = condbr_pl + 1; |
| 6116 | | const else_body_len_index = condbr_pl + 2; |
| 6136 | zir_datas[condbr].pl_node.payload_index = condbr_extra; |
| 6117 | 6137 | |
| 6118 | 6138 | // The break instructions need to have their operands coerced if the |
| 6119 | 6139 | // switch's result location is a `ty`. In this case we overwrite the |
| ... | ... | @@ -6128,7 +6148,9 @@ fn setCondBrPayloadElideBlockStorePtr( |
| 6128 | 6148 | if (then_scope.rl_ty_inst != .none and has_then_break) { |
| 6129 | 6149 | then_as_inst = src_inst; |
| 6130 | 6150 | } else { |
| 6131 | | astgen.extra.items[then_body_len_index] -= 1; |
| 6151 | astgen.extra.items[ |
| 6152 | condbr_extra + std.meta.fieldIndex(Zir.Inst.CondBr, "then_body_len").? |
| 6153 | ] -= 1; |
| 6132 | 6154 | continue; |
| 6133 | 6155 | } |
| 6134 | 6156 | } |
| ... | ... | @@ -6144,7 +6166,9 @@ fn setCondBrPayloadElideBlockStorePtr( |
| 6144 | 6166 | if (else_scope.rl_ty_inst != .none and has_else_break) { |
| 6145 | 6167 | else_as_inst = src_inst; |
| 6146 | 6168 | } else { |
| 6147 | | astgen.extra.items[else_body_len_index] -= 1; |
| 6169 | astgen.extra.items[ |
| 6170 | condbr_extra + std.meta.fieldIndex(Zir.Inst.CondBr, "else_body_len").? |
| 6171 | ] -= 1; |
| 6148 | 6172 | continue; |
| 6149 | 6173 | } |
| 6150 | 6174 | } |
| ... | ... | @@ -7247,11 +7271,11 @@ fn switchExpr( |
| 7247 | 7271 | assert(!strat.elide_store_to_block_ptr_instructions); |
| 7248 | 7272 | const last_inst = payloads.items[end_index - 1]; |
| 7249 | 7273 | if (zir_tags[last_inst] == .@"break") { |
| 7250 | | const inst_data = zir_datas[last_inst].@"break"; |
| 7251 | | const block_inst = astgen.extra.items[inst_data.payload_index]; |
| 7252 | | if (block_inst == switch_block) { |
| 7253 | | zir_datas[last_inst].@"break".operand = .void_value; |
| 7254 | | } |
| 7274 | const break_data = &zir_datas[last_inst].@"break"; |
| 7275 | const block_inst = astgen.extra.items[ |
| 7276 | break_data.payload_index + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").? |
| 7277 | ]; |
| 7278 | if (block_inst == switch_block) break_data.operand = .void_value; |
| 7255 | 7279 | } |
| 7256 | 7280 | }, |
| 7257 | 7281 | } |
| ... | ... | @@ -11648,40 +11672,47 @@ const GenZir = struct { |
| 11648 | 11672 | if (align_body.len != 0) { |
| 11649 | 11673 | astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, align_body)); |
| 11650 | 11674 | astgen.appendBodyWithFixups(align_body); |
| 11651 | | const inst_data = zir_datas[align_body[align_body.len - 1]].@"break"; |
| 11652 | | astgen.extra.items[inst_data.payload_index] = new_index; |
| 11675 | const break_extra = zir_datas[align_body[align_body.len - 1]].@"break".payload_index; |
| 11676 | astgen.extra.items[break_extra + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").?] = |
| 11677 | new_index; |
| 11653 | 11678 | } else if (args.align_ref != .none) { |
| 11654 | 11679 | astgen.extra.appendAssumeCapacity(@intFromEnum(args.align_ref)); |
| 11655 | 11680 | } |
| 11656 | 11681 | if (addrspace_body.len != 0) { |
| 11657 | 11682 | astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, addrspace_body)); |
| 11658 | 11683 | astgen.appendBodyWithFixups(addrspace_body); |
| 11659 | | const inst_data = zir_datas[addrspace_body[addrspace_body.len - 1]].@"break"; |
| 11660 | | astgen.extra.items[inst_data.payload_index] = new_index; |
| 11684 | const break_extra = |
| 11685 | zir_datas[addrspace_body[addrspace_body.len - 1]].@"break".payload_index; |
| 11686 | astgen.extra.items[break_extra + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").?] = |
| 11687 | new_index; |
| 11661 | 11688 | } else if (args.addrspace_ref != .none) { |
| 11662 | 11689 | astgen.extra.appendAssumeCapacity(@intFromEnum(args.addrspace_ref)); |
| 11663 | 11690 | } |
| 11664 | 11691 | if (section_body.len != 0) { |
| 11665 | 11692 | astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, section_body)); |
| 11666 | 11693 | astgen.appendBodyWithFixups(section_body); |
| 11667 | | const inst_data = zir_datas[section_body[section_body.len - 1]].@"break"; |
| 11668 | | astgen.extra.items[inst_data.payload_index] = new_index; |
| 11694 | const break_extra = |
| 11695 | zir_datas[section_body[section_body.len - 1]].@"break".payload_index; |
| 11696 | astgen.extra.items[break_extra + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").?] = |
| 11697 | new_index; |
| 11669 | 11698 | } else if (args.section_ref != .none) { |
| 11670 | 11699 | astgen.extra.appendAssumeCapacity(@intFromEnum(args.section_ref)); |
| 11671 | 11700 | } |
| 11672 | 11701 | if (cc_body.len != 0) { |
| 11673 | 11702 | astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, cc_body)); |
| 11674 | 11703 | astgen.appendBodyWithFixups(cc_body); |
| 11675 | | const inst_data = zir_datas[cc_body[cc_body.len - 1]].@"break"; |
| 11676 | | astgen.extra.items[inst_data.payload_index] = new_index; |
| 11704 | const break_extra = zir_datas[cc_body[cc_body.len - 1]].@"break".payload_index; |
| 11705 | astgen.extra.items[break_extra + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").?] = |
| 11706 | new_index; |
| 11677 | 11707 | } else if (args.cc_ref != .none) { |
| 11678 | 11708 | astgen.extra.appendAssumeCapacity(@intFromEnum(args.cc_ref)); |
| 11679 | 11709 | } |
| 11680 | 11710 | if (ret_body.len != 0) { |
| 11681 | 11711 | astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, ret_body)); |
| 11682 | 11712 | astgen.appendBodyWithFixups(ret_body); |
| 11683 | | const inst_data = zir_datas[ret_body[ret_body.len - 1]].@"break"; |
| 11684 | | astgen.extra.items[inst_data.payload_index] = new_index; |
| 11713 | const break_extra = zir_datas[ret_body[ret_body.len - 1]].@"break".payload_index; |
| 11714 | astgen.extra.items[break_extra + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").?] = |
| 11715 | new_index; |
| 11685 | 11716 | } else if (ret_ref != .none) { |
| 11686 | 11717 | astgen.extra.appendAssumeCapacity(@intFromEnum(ret_ref)); |
| 11687 | 11718 | } |
| ... | ... | @@ -11736,8 +11767,9 @@ const GenZir = struct { |
| 11736 | 11767 | if (ret_body.len != 0) { |
| 11737 | 11768 | astgen.appendBodyWithFixups(ret_body); |
| 11738 | 11769 | |
| 11739 | | const inst_data = zir_datas[ret_body[ret_body.len - 1]].@"break"; |
| 11740 | | astgen.extra.items[inst_data.payload_index] = new_index; |
| 11770 | const break_extra = zir_datas[ret_body[ret_body.len - 1]].@"break".payload_index; |
| 11771 | astgen.extra.items[break_extra + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").?] = |
| 11772 | new_index; |
| 11741 | 11773 | } else if (ret_ref != .none) { |
| 11742 | 11774 | astgen.extra.appendAssumeCapacity(@intFromEnum(ret_ref)); |
| 11743 | 11775 | } |
| ... | ... | @@ -12191,21 +12223,8 @@ const GenZir = struct { |
| 12191 | 12223 | ) !Zir.Inst.Index { |
| 12192 | 12224 | const gpa = gz.astgen.gpa; |
| 12193 | 12225 | try gz.instructions.ensureUnusedCapacity(gpa, 1); |
| 12194 | | try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1); |
| 12195 | 12226 | |
| 12196 | | const extra: Zir.Inst.Break = .{ |
| 12197 | | .block_inst = block_inst, |
| 12198 | | .operand_src_node = Zir.Inst.Break.no_src_node, |
| 12199 | | }; |
| 12200 | | const payload_index = try gz.astgen.addExtra(extra); |
| 12201 | | const new_index = @as(Zir.Inst.Index, @intCast(gz.astgen.instructions.len)); |
| 12202 | | gz.astgen.instructions.appendAssumeCapacity(.{ |
| 12203 | | .tag = tag, |
| 12204 | | .data = .{ .@"break" = .{ |
| 12205 | | .operand = operand, |
| 12206 | | .payload_index = payload_index, |
| 12207 | | } }, |
| 12208 | | }); |
| 12227 | const new_index = try gz.makeBreak(tag, block_inst, operand); |
| 12209 | 12228 | gz.instructions.appendAssumeCapacity(new_index); |
| 12210 | 12229 | return new_index; |
| 12211 | 12230 | } |
| ... | ... | @@ -12216,23 +12235,7 @@ const GenZir = struct { |
| 12216 | 12235 | block_inst: Zir.Inst.Index, |
| 12217 | 12236 | operand: Zir.Inst.Ref, |
| 12218 | 12237 | ) !Zir.Inst.Index { |
| 12219 | | const gpa = gz.astgen.gpa; |
| 12220 | | try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1); |
| 12221 | | |
| 12222 | | const extra: Zir.Inst.Break = .{ |
| 12223 | | .block_inst = block_inst, |
| 12224 | | .operand_src_node = Zir.Inst.Break.no_src_node, |
| 12225 | | }; |
| 12226 | | const payload_index = try gz.astgen.addExtra(extra); |
| 12227 | | const new_index = @as(Zir.Inst.Index, @intCast(gz.astgen.instructions.len)); |
| 12228 | | gz.astgen.instructions.appendAssumeCapacity(.{ |
| 12229 | | .tag = tag, |
| 12230 | | .data = .{ .@"break" = .{ |
| 12231 | | .operand = operand, |
| 12232 | | .payload_index = payload_index, |
| 12233 | | } }, |
| 12234 | | }); |
| 12235 | | return new_index; |
| 12238 | return gz.makeBreakCommon(tag, block_inst, operand, null); |
| 12236 | 12239 | } |
| 12237 | 12240 | |
| 12238 | 12241 | fn addBreakWithSrcNode( |
| ... | ... | @@ -12244,21 +12247,8 @@ const GenZir = struct { |
| 12244 | 12247 | ) !Zir.Inst.Index { |
| 12245 | 12248 | const gpa = gz.astgen.gpa; |
| 12246 | 12249 | try gz.instructions.ensureUnusedCapacity(gpa, 1); |
| 12247 | | try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1); |
| 12248 | 12250 | |
| 12249 | | const extra: Zir.Inst.Break = .{ |
| 12250 | | .block_inst = block_inst, |
| 12251 | | .operand_src_node = gz.nodeIndexToRelative(operand_src_node), |
| 12252 | | }; |
| 12253 | | const payload_index = try gz.astgen.addExtra(extra); |
| 12254 | | const new_index = @as(Zir.Inst.Index, @intCast(gz.astgen.instructions.len)); |
| 12255 | | gz.astgen.instructions.appendAssumeCapacity(.{ |
| 12256 | | .tag = tag, |
| 12257 | | .data = .{ .@"break" = .{ |
| 12258 | | .operand = operand, |
| 12259 | | .payload_index = payload_index, |
| 12260 | | } }, |
| 12261 | | }); |
| 12251 | const new_index = try gz.makeBreakWithSrcNode(tag, block_inst, operand, operand_src_node); |
| 12262 | 12252 | gz.instructions.appendAssumeCapacity(new_index); |
| 12263 | 12253 | return new_index; |
| 12264 | 12254 | } |
| ... | ... | @@ -12269,21 +12259,33 @@ const GenZir = struct { |
| 12269 | 12259 | block_inst: Zir.Inst.Index, |
| 12270 | 12260 | operand: Zir.Inst.Ref, |
| 12271 | 12261 | operand_src_node: Ast.Node.Index, |
| 12262 | ) !Zir.Inst.Index { |
| 12263 | return gz.makeBreakCommon(tag, block_inst, operand, operand_src_node); |
| 12264 | } |
| 12265 | |
| 12266 | fn makeBreakCommon( |
| 12267 | gz: *GenZir, |
| 12268 | tag: Zir.Inst.Tag, |
| 12269 | block_inst: Zir.Inst.Index, |
| 12270 | operand: Zir.Inst.Ref, |
| 12271 | operand_src_node: ?Ast.Node.Index, |
| 12272 | 12272 | ) !Zir.Inst.Index { |
| 12273 | 12273 | const gpa = gz.astgen.gpa; |
| 12274 | 12274 | try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1); |
| 12275 | try gz.astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.Break).Struct.fields.len); |
| 12275 | 12276 | |
| 12276 | | const extra: Zir.Inst.Break = .{ |
| 12277 | | .block_inst = block_inst, |
| 12278 | | .operand_src_node = gz.nodeIndexToRelative(operand_src_node), |
| 12279 | | }; |
| 12280 | | const payload_index = try gz.astgen.addExtra(extra); |
| 12281 | | const new_index = @as(Zir.Inst.Index, @intCast(gz.astgen.instructions.len)); |
| 12277 | const new_index: Zir.Inst.Index = @intCast(gz.astgen.instructions.len); |
| 12282 | 12278 | gz.astgen.instructions.appendAssumeCapacity(.{ |
| 12283 | 12279 | .tag = tag, |
| 12284 | 12280 | .data = .{ .@"break" = .{ |
| 12285 | 12281 | .operand = operand, |
| 12286 | | .payload_index = payload_index, |
| 12282 | .payload_index = gz.astgen.addExtraAssumeCapacity(Zir.Inst.Break{ |
| 12283 | .operand_src_node = if (operand_src_node) |src_node| |
| 12284 | gz.nodeIndexToRelative(src_node) |
| 12285 | else |
| 12286 | Zir.Inst.Break.no_src_node, |
| 12287 | .block_inst = block_inst, |
| 12288 | }), |
| 12287 | 12289 | } }, |
| 12288 | 12290 | }); |
| 12289 | 12291 | return new_index; |