| ... | ... | @@ -5732,6 +5732,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5732 | 5732 | if (!instr_is_unreachable(is_err)) { |
| 5733 | 5733 | cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_err, |
| 5734 | 5734 | else_block, body_block, is_comptime); |
| 5735 | cond_br_inst->is_gen = true; |
| 5735 | 5736 | } else { |
| 5736 | 5737 | cond_br_inst = is_err; // for the purposes of the source instruction to create_binary_result_peers |
| 5737 | 5738 | } |
| ... | ... | @@ -5827,11 +5828,17 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5827 | 5828 | IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node->data.while_expr.condition, maybe_val); |
| 5828 | 5829 | IrBasicBlock *after_cond_block = irb->current_basic_block; |
| 5829 | 5830 | IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); |
| 5831 | IrInstruction *cond_br_inst; |
| 5830 | 5832 | if (!instr_is_unreachable(is_non_null)) { |
| 5831 | | ir_mark_gen(ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_non_null, |
| 5832 | | body_block, else_block, is_comptime)); |
| 5833 | cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_non_null, |
| 5834 | body_block, else_block, is_comptime); |
| 5835 | cond_br_inst->is_gen = true; |
| 5836 | } else { |
| 5837 | cond_br_inst = is_non_null; // for the purposes of source instruction for create_binary_result_peers |
| 5833 | 5838 | } |
| 5834 | 5839 | |
| 5840 | ResultLocPeerParent *peer_parent = create_binary_result_peers(cond_br_inst, else_block, end_block, result_loc); |
| 5841 | |
| 5835 | 5842 | ir_set_cursor_at_end_and_append_block(irb, body_block); |
| 5836 | 5843 | IrInstruction *payload_ptr = ir_build_optional_unwrap_ptr(irb, child_scope, symbol_node, maybe_val_ptr, false); |
| 5837 | 5844 | IrInstruction *var_ptr = node->data.while_expr.var_is_ptr ? |
| ... | ... | @@ -5847,7 +5854,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5847 | 5854 | loop_scope->is_comptime = is_comptime; |
| 5848 | 5855 | loop_scope->incoming_blocks = &incoming_blocks; |
| 5849 | 5856 | loop_scope->incoming_values = &incoming_values; |
| 5857 | loop_scope->lval = lval; |
| 5858 | loop_scope->result_loc = &peer_parent->peers[0].base; |
| 5850 | 5859 | |
| 5860 | // Note the body block of the loop is not the place that lval and result_loc are used - |
| 5861 | // it's actually in break statements, handled similarly to return statements. |
| 5862 | // That is why we set those values in loop_scope above and not in this ir_gen_node call. |
| 5851 | 5863 | IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); |
| 5852 | 5864 | if (body_result == irb->codegen->invalid_instruction) |
| 5853 | 5865 | return body_result; |
| ... | ... | @@ -5872,7 +5884,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5872 | 5884 | if (else_node) { |
| 5873 | 5885 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 5874 | 5886 | |
| 5875 | | else_result = ir_gen_node(irb, else_node, scope); |
| 5887 | else_result = ir_gen_node_extra(irb, else_node, scope, lval, &peer_parent->peers[1].base); |
| 5876 | 5888 | if (else_result == irb->codegen->invalid_instruction) |
| 5877 | 5889 | return else_result; |
| 5878 | 5890 | if (!instr_is_unreachable(else_result)) |
| ... | ... | @@ -5888,7 +5900,8 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5888 | 5900 | incoming_values.append(void_else_result); |
| 5889 | 5901 | } |
| 5890 | 5902 | |
| 5891 | | return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); |
| 5903 | IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); |
| 5904 | return ir_expr_wrap(irb, scope, phi, result_loc); |
| 5892 | 5905 | } else { |
| 5893 | 5906 | ir_set_cursor_at_end_and_append_block(irb, cond_block); |
| 5894 | 5907 | IrInstruction *cond_val = ir_gen_node(irb, node->data.while_expr.condition, scope); |
| ... | ... | @@ -5896,11 +5909,16 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5896 | 5909 | return cond_val; |
| 5897 | 5910 | IrBasicBlock *after_cond_block = irb->current_basic_block; |
| 5898 | 5911 | IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); |
| 5912 | IrInstruction *cond_br_inst; |
| 5899 | 5913 | if (!instr_is_unreachable(cond_val)) { |
| 5900 | | ir_mark_gen(ir_build_cond_br(irb, scope, node->data.while_expr.condition, cond_val, |
| 5901 | | body_block, else_block, is_comptime)); |
| 5914 | cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, cond_val, |
| 5915 | body_block, else_block, is_comptime); |
| 5916 | cond_br_inst->is_gen = true; |
| 5917 | } else { |
| 5918 | cond_br_inst = cond_val; // for the source instruction arg to create_binary_result_peers |
| 5902 | 5919 | } |
| 5903 | 5920 | |
| 5921 | ResultLocPeerParent *peer_parent = create_binary_result_peers(cond_br_inst, else_block, end_block, result_loc); |
| 5904 | 5922 | ir_set_cursor_at_end_and_append_block(irb, body_block); |
| 5905 | 5923 | |
| 5906 | 5924 | ZigList<IrInstruction *> incoming_values = {0}; |
| ... | ... | @@ -5914,7 +5932,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5914 | 5932 | loop_scope->is_comptime = is_comptime; |
| 5915 | 5933 | loop_scope->incoming_blocks = &incoming_blocks; |
| 5916 | 5934 | loop_scope->incoming_values = &incoming_values; |
| 5935 | loop_scope->lval = lval; |
| 5936 | loop_scope->result_loc = &peer_parent->peers[0].base; |
| 5917 | 5937 | |
| 5938 | // Note the body block of the loop is not the place that lval and result_loc are used - |
| 5939 | // it's actually in break statements, handled similarly to return statements. |
| 5940 | // That is why we set those values in loop_scope above and not in this ir_gen_node call. |
| 5918 | 5941 | IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); |
| 5919 | 5942 | if (body_result == irb->codegen->invalid_instruction) |
| 5920 | 5943 | return body_result; |
| ... | ... | @@ -5939,7 +5962,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5939 | 5962 | if (else_node) { |
| 5940 | 5963 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 5941 | 5964 | |
| 5942 | | else_result = ir_gen_node(irb, else_node, subexpr_scope); |
| 5965 | else_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_parent->peers[1].base); |
| 5943 | 5966 | if (else_result == irb->codegen->invalid_instruction) |
| 5944 | 5967 | return else_result; |
| 5945 | 5968 | if (!instr_is_unreachable(else_result)) |
| ... | ... | @@ -5955,7 +5978,8 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5955 | 5978 | incoming_values.append(void_else_result); |
| 5956 | 5979 | } |
| 5957 | 5980 | |
| 5958 | | return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); |
| 5981 | IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); |
| 5982 | return ir_expr_wrap(irb, scope, phi, result_loc); |
| 5959 | 5983 | } |
| 5960 | 5984 | } |
| 5961 | 5985 | |