authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-20 11:16:50-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-20 11:16:50-07:00
logb4baa9eda2b4398d9fe0ea5847a8bb8dfdd16ba4
tree59ae577a349cb951e9548f1b3dd8f952ebcabf7b
parentee3c1c763c8201d31321643f72cd1506c369dd71

AstGen: `try` fixups

Primarily this required fixing `setCondBrPayloadElideBlockStorePtr` to not assume there would always be two `store_to_block_ptr` instructions in each of the condbr prongs.

1 files changed, 56 insertions(+), 57 deletions(-)

src/AstGen.zig+56-57
......@@ -3162,43 +3162,33 @@ fn tryExpr(
31623162) InnerError!Zir.Inst.Ref {
31633163 const astgen = parent_gz.astgen;
31643164 const tree = &astgen.file.tree;
3165 const main_tokens = tree.nodes.items(.main_token);
3166 const token_tags = tree.tokens.items(.tag);
3167 const node_datas = tree.nodes.items(.data);
3168 const node_tags = tree.nodes.items(.tag);
31693165
31703166 var block_scope: GenZir = .{
31713167 .parent = scope,
31723168 .decl_node_index = parent_gz.decl_node_index,
3173 .astgen = parent_gz.astgen,
3169 .astgen = astgen,
31743170 .force_comptime = parent_gz.force_comptime,
31753171 .instructions = .{},
31763172 };
31773173 block_scope.setBreakResultLoc(rl);
31783174 defer block_scope.instructions.deinit(astgen.gpa);
31793175
3180 // This could be a pointer or value depending on the `operand_rl` parameter.
3181 // We cannot use `block_scope.break_result_loc` because that has the bare
3182 // type, whereas this expression has the optional type. Later we make
3183 // up for this fact by calling rvalue on the else branch.
3184 block_scope.break_count += 1;
3185
31863176 const operand_rl: ResultLoc = switch (block_scope.break_result_loc) {
31873177 .ref => .ref,
3188 .discard, .none, .none_or_ref, .block_ptr, .inferred_ptr => .none,
3189 .ty => |elem_ty| {
3190 @panic("TODO");
3191 },
3192 .ptr => |ptr_ty| {
3193 @panic("TODO");
3194 },
3178 else => .none,
31953179 };
3196 const ops = switch (rl) {
3180 const err_ops = switch (rl) {
3181 // zig fmt: off
31973182 .ref => [3]Zir.Inst.Tag{ .is_err_ptr, .err_union_code_ptr, .err_union_payload_unsafe_ptr },
3198 else => [3]Zir.Inst.Tag{ .is_err, .err_union_code, .err_union_payload_unsafe },
3183 else => [3]Zir.Inst.Tag{ .is_err, .err_union_code, .err_union_payload_unsafe },
3184 // zig fmt: on
31993185 };
3186 // This could be a pointer or value depending on the `operand_rl` parameter.
3187 // We cannot use `block_scope.break_result_loc` because that has the bare
3188 // type, whereas this expression has the optional type. Later we make
3189 // up for this fact by calling rvalue on the else branch.
32003190 const operand = try expr(&block_scope, &block_scope.base, operand_rl, node);
3201 const cond = try block_scope.addUnNode(ops[0], operand, node);
3191 const cond = try block_scope.addUnNode(err_ops[0], operand, node);
32023192 const condbr = try block_scope.addCondBr(.condbr, node);
32033193
32043194 const block = try parent_gz.addBlock(.block, node);
......@@ -3208,31 +3198,27 @@ fn tryExpr(
32083198 var then_scope: GenZir = .{
32093199 .parent = scope,
32103200 .decl_node_index = parent_gz.decl_node_index,
3211 .astgen = parent_gz.astgen,
3201 .astgen = astgen,
32123202 .force_comptime = block_scope.force_comptime,
32133203 .instructions = .{},
32143204 };
32153205 defer then_scope.instructions.deinit(astgen.gpa);
32163206
3217 const then_result = try then_scope.addUnNode(ops[1], operand, node);
3218 const to_return = try then_scope.addUnNode(.ret_node, then_result, node);
3219
3220 block_scope.break_count += 1;
3221 // We hold off on the break instructions as well as copying the then/else
3222 // instructions into place until we know whether to keep store_to_block_ptr
3223 // instructions or not.
3207 const err_code = try then_scope.addUnNode(err_ops[1], operand, node);
3208 const then_result = try then_scope.addUnNode(.ret_node, err_code, node);
32243209
32253210 var else_scope: GenZir = .{
32263211 .parent = scope,
32273212 .decl_node_index = parent_gz.decl_node_index,
3228 .astgen = parent_gz.astgen,
3213 .astgen = astgen,
32293214 .force_comptime = block_scope.force_comptime,
32303215 .instructions = .{},
32313216 };
32323217 defer else_scope.instructions.deinit(astgen.gpa);
32333218
3234 // This could be a pointer or value depending on `unwrap_op`.
3235 const unwrapped_payload = try else_scope.addUnNode(ops[2], operand, node);
3219 block_scope.break_count += 1;
3220 // This could be a pointer or value depending on `err_ops[2]`.
3221 const unwrapped_payload = try else_scope.addUnNode(err_ops[2], operand, node);
32363222 const else_result = switch (rl) {
32373223 .ref => unwrapped_payload,
32383224 else => try rvalue(&else_scope, &else_scope.base, block_scope.break_result_loc, unwrapped_payload, node),
......@@ -3250,7 +3236,7 @@ fn tryExpr(
32503236 cond,
32513237 node,
32523238 node,
3253 to_return,
3239 then_result,
32543240 else_result,
32553241 block,
32563242 block,
......@@ -3276,19 +3262,13 @@ fn orelseCatchExpr(
32763262 var block_scope: GenZir = .{
32773263 .parent = scope,
32783264 .decl_node_index = parent_gz.decl_node_index,
3279 .astgen = parent_gz.astgen,
3265 .astgen = astgen,
32803266 .force_comptime = parent_gz.force_comptime,
32813267 .instructions = .{},
32823268 };
32833269 block_scope.setBreakResultLoc(rl);
32843270 defer block_scope.instructions.deinit(astgen.gpa);
32853271
3286 // This could be a pointer or value depending on the `operand_rl` parameter.
3287 // We cannot use `block_scope.break_result_loc` because that has the bare
3288 // type, whereas this expression has the optional type. Later we make
3289 // up for this fact by calling rvalue on the else branch.
3290 block_scope.break_count += 1;
3291
32923272 // TODO handle catch
32933273 const operand_rl: ResultLoc = switch (block_scope.break_result_loc) {
32943274 .ref => .ref,
......@@ -3302,6 +3282,11 @@ fn orelseCatchExpr(
33023282 break :blk .{ .ty = wrapped_ty };
33033283 },
33043284 };
3285 block_scope.break_count += 1;
3286 // This could be a pointer or value depending on the `operand_rl` parameter.
3287 // We cannot use `block_scope.break_result_loc` because that has the bare
3288 // type, whereas this expression has the optional type. Later we make
3289 // up for this fact by calling rvalue on the else branch.
33053290 const operand = try expr(&block_scope, &block_scope.base, operand_rl, lhs);
33063291 const cond = try block_scope.addUnNode(cond_op, operand, node);
33073292 const condbr = try block_scope.addCondBr(.condbr, node);
......@@ -3313,7 +3298,7 @@ fn orelseCatchExpr(
33133298 var then_scope: GenZir = .{
33143299 .parent = scope,
33153300 .decl_node_index = parent_gz.decl_node_index,
3316 .astgen = parent_gz.astgen,
3301 .astgen = astgen,
33173302 .force_comptime = block_scope.force_comptime,
33183303 .instructions = .{},
33193304 };
......@@ -3345,7 +3330,7 @@ fn orelseCatchExpr(
33453330 var else_scope: GenZir = .{
33463331 .parent = scope,
33473332 .decl_node_index = parent_gz.decl_node_index,
3348 .astgen = parent_gz.astgen,
3333 .astgen = astgen,
33493334 .force_comptime = block_scope.force_comptime,
33503335 .instructions = .{},
33513336 };
......@@ -3424,12 +3409,12 @@ fn finishThenElseBlock(
34243409 } else {
34253410 _ = try else_scope.addBreak(break_tag, main_block, .void_value);
34263411 }
3412 const block_ref = parent_gz.indexToRef(main_block);
34273413 if (strat.elide_store_to_block_ptr_instructions) {
3428 try setCondBrPayloadElideBlockStorePtr(condbr, cond, then_scope, else_scope);
3414 try setCondBrPayloadElideBlockStorePtr(condbr, cond, then_scope, else_scope, block_ref);
34293415 } else {
34303416 try setCondBrPayload(condbr, cond, then_scope, else_scope);
34313417 }
3432 const block_ref = parent_gz.indexToRef(main_block);
34333418 switch (rl) {
34343419 .ref => return block_ref,
34353420 else => return rvalue(parent_gz, parent_scope, rl, block_ref, node),
......@@ -3758,33 +3743,47 @@ fn setCondBrPayload(
37583743 astgen.extra.appendSliceAssumeCapacity(else_scope.instructions.items);
37593744}
37603745
3761/// If `elide_block_store_ptr` is set, expects to find exactly 1 .store_to_block_ptr instruction.
37623746fn setCondBrPayloadElideBlockStorePtr(
37633747 condbr: Zir.Inst.Index,
37643748 cond: Zir.Inst.Ref,
37653749 then_scope: *GenZir,
37663750 else_scope: *GenZir,
3751 main_block: Zir.Inst.Ref,
37673752) !void {
37683753 const astgen = then_scope.astgen;
37693754
3770 try astgen.extra.ensureCapacity(astgen.gpa, astgen.extra.items.len +
3771 @typeInfo(Zir.Inst.CondBr).Struct.fields.len +
3772 then_scope.instructions.items.len + else_scope.instructions.items.len - 2);
3755 try astgen.extra.ensureUnusedCapacity(astgen.gpa, @typeInfo(Zir.Inst.CondBr).Struct.fields.len +
3756 then_scope.instructions.items.len + else_scope.instructions.items.len);
37733757
3758 const zir_tags = astgen.instructions.items(.tag);
37743759 const zir_datas = astgen.instructions.items(.data);
3775 zir_datas[condbr].pl_node.payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.CondBr{
3760
3761 const condbr_pl = astgen.addExtraAssumeCapacity(Zir.Inst.CondBr{
37763762 .condition = cond,
3777 .then_body_len = @intCast(u32, then_scope.instructions.items.len - 1),
3778 .else_body_len = @intCast(u32, else_scope.instructions.items.len - 1),
3763 .then_body_len = @intCast(u32, then_scope.instructions.items.len),
3764 .else_body_len = @intCast(u32, else_scope.instructions.items.len),
37793765 });
3780
3781 const zir_tags = astgen.instructions.items(.tag);
3782 for ([_]*GenZir{ then_scope, else_scope }) |scope| {
3783 for (scope.instructions.items) |src_inst| {
3784 if (zir_tags[src_inst] != .store_to_block_ptr) {
3785 astgen.extra.appendAssumeCapacity(src_inst);
3766 zir_datas[condbr].pl_node.payload_index = condbr_pl;
3767 const then_body_len_index = condbr_pl + 1;
3768 const else_body_len_index = condbr_pl + 2;
3769
3770 for (then_scope.instructions.items) |src_inst| {
3771 if (zir_tags[src_inst] == .store_to_block_ptr) {
3772 if (zir_datas[src_inst].bin.lhs == main_block) {
3773 astgen.extra.items[then_body_len_index] -= 1;
3774 continue;
3775 }
3776 }
3777 astgen.extra.appendAssumeCapacity(src_inst);
3778 }
3779 for (else_scope.instructions.items) |src_inst| {
3780 if (zir_tags[src_inst] == .store_to_block_ptr) {
3781 if (zir_datas[src_inst].bin.lhs == main_block) {
3782 astgen.extra.items[else_body_len_index] -= 1;
3783 continue;
37863784 }
37873785 }
3786 astgen.extra.appendAssumeCapacity(src_inst);
37883787 }
37893788}
37903789