| ... | @@ -5732,6 +5732,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -5732,6 +5732,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5732 | if (!instr_is_unreachable(is_err)) { | 5732 | if (!instr_is_unreachable(is_err)) { |
| 5733 | cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_err, | 5733 | cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_err, |
| 5734 | else_block, body_block, is_comptime); | 5734 | else_block, body_block, is_comptime); |
| | 5735 | cond_br_inst->is_gen = true; |
| 5735 | } else { | 5736 | } else { |
| 5736 | cond_br_inst = is_err; // for the purposes of the source instruction to create_binary_result_peers | 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,11 +5828,17 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5827 | IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node->data.while_expr.condition, maybe_val); | 5828 | IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node->data.while_expr.condition, maybe_val); |
| 5828 | IrBasicBlock *after_cond_block = irb->current_basic_block; | 5829 | IrBasicBlock *after_cond_block = irb->current_basic_block; |
| 5829 | IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); | 5830 | IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); |
| | 5831 | IrInstruction *cond_br_inst; |
| 5830 | if (!instr_is_unreachable(is_non_null)) { | 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, | 5833 | cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_non_null, |
| 5832 | body_block, else_block, is_comptime)); | 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 | ir_set_cursor_at_end_and_append_block(irb, body_block); | 5842 | ir_set_cursor_at_end_and_append_block(irb, body_block); |
| 5836 | IrInstruction *payload_ptr = ir_build_optional_unwrap_ptr(irb, child_scope, symbol_node, maybe_val_ptr, false); | 5843 | IrInstruction *payload_ptr = ir_build_optional_unwrap_ptr(irb, child_scope, symbol_node, maybe_val_ptr, false); |
| 5837 | IrInstruction *var_ptr = node->data.while_expr.var_is_ptr ? | 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,7 +5854,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5847 | loop_scope->is_comptime = is_comptime; | 5854 | loop_scope->is_comptime = is_comptime; |
| 5848 | loop_scope->incoming_blocks = &incoming_blocks; | 5855 | loop_scope->incoming_blocks = &incoming_blocks; |
| 5849 | loop_scope->incoming_values = &incoming_values; | 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 | IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); | 5863 | IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); |
| 5852 | if (body_result == irb->codegen->invalid_instruction) | 5864 | if (body_result == irb->codegen->invalid_instruction) |
| 5853 | return body_result; | 5865 | return body_result; |
| ... | @@ -5872,7 +5884,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -5872,7 +5884,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5872 | if (else_node) { | 5884 | if (else_node) { |
| 5873 | ir_set_cursor_at_end_and_append_block(irb, else_block); | 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 | if (else_result == irb->codegen->invalid_instruction) | 5888 | if (else_result == irb->codegen->invalid_instruction) |
| 5877 | return else_result; | 5889 | return else_result; |
| 5878 | if (!instr_is_unreachable(else_result)) | 5890 | if (!instr_is_unreachable(else_result)) |
| ... | @@ -5888,7 +5900,8 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -5888,7 +5900,8 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5888 | incoming_values.append(void_else_result); | 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 | } else { | 5905 | } else { |
| 5893 | ir_set_cursor_at_end_and_append_block(irb, cond_block); | 5906 | ir_set_cursor_at_end_and_append_block(irb, cond_block); |
| 5894 | IrInstruction *cond_val = ir_gen_node(irb, node->data.while_expr.condition, scope); | 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,11 +5909,16 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5896 | return cond_val; | 5909 | return cond_val; |
| 5897 | IrBasicBlock *after_cond_block = irb->current_basic_block; | 5910 | IrBasicBlock *after_cond_block = irb->current_basic_block; |
| 5898 | IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); | 5911 | IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); |
| | 5912 | IrInstruction *cond_br_inst; |
| 5899 | if (!instr_is_unreachable(cond_val)) { | 5913 | if (!instr_is_unreachable(cond_val)) { |
| 5900 | ir_mark_gen(ir_build_cond_br(irb, scope, node->data.while_expr.condition, cond_val, | 5914 | cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, cond_val, |
| 5901 | body_block, else_block, is_comptime)); | 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 | ir_set_cursor_at_end_and_append_block(irb, body_block); | 5922 | ir_set_cursor_at_end_and_append_block(irb, body_block); |
| 5905 | | 5923 | |
| 5906 | ZigList<IrInstruction *> incoming_values = {0}; | 5924 | ZigList<IrInstruction *> incoming_values = {0}; |
| ... | @@ -5914,7 +5932,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -5914,7 +5932,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5914 | loop_scope->is_comptime = is_comptime; | 5932 | loop_scope->is_comptime = is_comptime; |
| 5915 | loop_scope->incoming_blocks = &incoming_blocks; | 5933 | loop_scope->incoming_blocks = &incoming_blocks; |
| 5916 | loop_scope->incoming_values = &incoming_values; | 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 | IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); | 5941 | IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); |
| 5919 | if (body_result == irb->codegen->invalid_instruction) | 5942 | if (body_result == irb->codegen->invalid_instruction) |
| 5920 | return body_result; | 5943 | return body_result; |
| ... | @@ -5939,7 +5962,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -5939,7 +5962,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5939 | if (else_node) { | 5962 | if (else_node) { |
| 5940 | ir_set_cursor_at_end_and_append_block(irb, else_block); | 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 | if (else_result == irb->codegen->invalid_instruction) | 5966 | if (else_result == irb->codegen->invalid_instruction) |
| 5944 | return else_result; | 5967 | return else_result; |
| 5945 | if (!instr_is_unreachable(else_result)) | 5968 | if (!instr_is_unreachable(else_result)) |
| ... | @@ -5955,7 +5978,8 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -5955,7 +5978,8 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5955 | incoming_values.append(void_else_result); | 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 | |