| ... | @@ -3964,25 +3964,23 @@ static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *nod | ... | @@ -3964,25 +3964,23 @@ static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *nod |
| 3964 | return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr); | 3964 | return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr); |
| 3965 | } | 3965 | } |
| 3966 | | 3966 | |
| 3967 | static ResultLocPeerParent *ir_build_binary_result_peers(IrBuilder *irb, IrInstruction *cond_br_inst, | 3967 | static ResultLocPeer *create_peer_result(ResultLocPeerParent *peer_parent) { |
| 3968 | IrBasicBlock *else_block, IrBasicBlock *endif_block, ResultLoc *parent, IrInstruction *is_comptime) | 3968 | ResultLocPeer *result = allocate<ResultLocPeer>(1); |
| | 3969 | result->base.id = ResultLocIdPeer; |
| | 3970 | result->base.source_instruction = peer_parent->base.source_instruction; |
| | 3971 | result->parent = peer_parent; |
| | 3972 | return result; |
| | 3973 | } |
| | 3974 | |
| | 3975 | static ResultLocPeerParent *ir_build_result_peers(IrBuilder *irb, IrInstruction *cond_br_inst, |
| | 3976 | IrBasicBlock *end_block, ResultLoc *parent, IrInstruction *is_comptime) |
| 3969 | { | 3977 | { |
| 3970 | ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1); | 3978 | ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1); |
| 3971 | peer_parent->base.id = ResultLocIdPeerParent; | 3979 | peer_parent->base.id = ResultLocIdPeerParent; |
| 3972 | peer_parent->base.source_instruction = cond_br_inst; | 3980 | peer_parent->base.source_instruction = cond_br_inst; |
| 3973 | peer_parent->end_bb = endif_block; | 3981 | peer_parent->end_bb = end_block; |
| 3974 | peer_parent->is_comptime = is_comptime; | 3982 | peer_parent->is_comptime = is_comptime; |
| 3975 | peer_parent->parent = parent; | 3983 | peer_parent->parent = parent; |
| 3976 | peer_parent->peer_count = 2; | | |
| 3977 | peer_parent->peers = allocate<ResultLocPeer>(2); | | |
| 3978 | peer_parent->peers[0].base.id = ResultLocIdPeer; | | |
| 3979 | peer_parent->peers[0].base.source_instruction = cond_br_inst; | | |
| 3980 | peer_parent->peers[0].parent = peer_parent; | | |
| 3981 | peer_parent->peers[0].next_bb = else_block; | | |
| 3982 | peer_parent->peers[1].base.id = ResultLocIdPeer; | | |
| 3983 | peer_parent->peers[1].base.source_instruction = cond_br_inst; | | |
| 3984 | peer_parent->peers[1].parent = peer_parent; | | |
| 3985 | peer_parent->peers[1].next_bb = endif_block; | | |
| 3986 | | 3984 | |
| 3987 | IrInstruction *popped_inst = irb->current_basic_block->instruction_list.pop(); | 3985 | IrInstruction *popped_inst = irb->current_basic_block->instruction_list.pop(); |
| 3988 | ir_assert(popped_inst == cond_br_inst, cond_br_inst); | 3986 | ir_assert(popped_inst == cond_br_inst, cond_br_inst); |
| ... | @@ -3993,6 +3991,20 @@ static ResultLocPeerParent *ir_build_binary_result_peers(IrBuilder *irb, IrInstr | ... | @@ -3993,6 +3991,20 @@ static ResultLocPeerParent *ir_build_binary_result_peers(IrBuilder *irb, IrInstr |
| 3993 | return peer_parent; | 3991 | return peer_parent; |
| 3994 | } | 3992 | } |
| 3995 | | 3993 | |
| | 3994 | static ResultLocPeerParent *ir_build_binary_result_peers(IrBuilder *irb, IrInstruction *cond_br_inst, |
| | 3995 | IrBasicBlock *else_block, IrBasicBlock *end_block, ResultLoc *parent, IrInstruction *is_comptime) |
| | 3996 | { |
| | 3997 | ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, parent, is_comptime); |
| | 3998 | |
| | 3999 | peer_parent->peers.append(create_peer_result(peer_parent)); |
| | 4000 | peer_parent->peers.last()->next_bb = else_block; |
| | 4001 | |
| | 4002 | peer_parent->peers.append(create_peer_result(peer_parent)); |
| | 4003 | peer_parent->peers.last()->next_bb = end_block; |
| | 4004 | |
| | 4005 | return peer_parent; |
| | 4006 | } |
| | 4007 | |
| 3996 | static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval, | 4008 | static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval, |
| 3997 | ResultLoc *result_loc) | 4009 | ResultLoc *result_loc) |
| 3998 | { | 4010 | { |
| ... | @@ -4024,7 +4036,8 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode | ... | @@ -4024,7 +4036,8 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode |
| 4024 | result_loc, is_comptime); | 4036 | result_loc, is_comptime); |
| 4025 | | 4037 | |
| 4026 | ir_set_cursor_at_end_and_append_block(irb, null_block); | 4038 | ir_set_cursor_at_end_and_append_block(irb, null_block); |
| 4027 | IrInstruction *null_result = ir_gen_node_extra(irb, op2_node, parent_scope, lval, &peer_parent->peers[0].base); | 4039 | IrInstruction *null_result = ir_gen_node_extra(irb, op2_node, parent_scope, lval, |
| | 4040 | &peer_parent->peers.at(0)->base); |
| 4028 | if (null_result == irb->codegen->invalid_instruction) | 4041 | if (null_result == irb->codegen->invalid_instruction) |
| 4029 | return irb->codegen->invalid_instruction; | 4042 | return irb->codegen->invalid_instruction; |
| 4030 | IrBasicBlock *after_null_block = irb->current_basic_block; | 4043 | IrBasicBlock *after_null_block = irb->current_basic_block; |
| ... | @@ -4034,7 +4047,7 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode | ... | @@ -4034,7 +4047,7 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode |
| 4034 | ir_set_cursor_at_end_and_append_block(irb, ok_block); | 4047 | ir_set_cursor_at_end_and_append_block(irb, ok_block); |
| 4035 | IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, parent_scope, node, maybe_ptr, false, false); | 4048 | IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, parent_scope, node, maybe_ptr, false, false); |
| 4036 | IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); | 4049 | IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); |
| 4037 | ir_build_end_expr(irb, parent_scope, node, unwrapped_payload, &peer_parent->peers[1].base); | 4050 | ir_build_end_expr(irb, parent_scope, node, unwrapped_payload, &peer_parent->peers.at(1)->base); |
| 4038 | IrBasicBlock *after_ok_block = irb->current_basic_block; | 4051 | IrBasicBlock *after_ok_block = irb->current_basic_block; |
| 4039 | ir_build_br(irb, parent_scope, node, end_block, is_comptime); | 4052 | ir_build_br(irb, parent_scope, node, end_block, is_comptime); |
| 4040 | | 4053 | |
| ... | @@ -5545,7 +5558,7 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -5545,7 +5558,7 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode |
| 5545 | | 5558 | |
| 5546 | Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); | 5559 | Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); |
| 5547 | IrInstruction *then_expr_result = ir_gen_node_extra(irb, then_node, subexpr_scope, lval, | 5560 | IrInstruction *then_expr_result = ir_gen_node_extra(irb, then_node, subexpr_scope, lval, |
| 5548 | &peer_parent->peers[0].base); | 5561 | &peer_parent->peers.at(0)->base); |
| 5549 | if (then_expr_result == irb->codegen->invalid_instruction) | 5562 | if (then_expr_result == irb->codegen->invalid_instruction) |
| 5550 | return irb->codegen->invalid_instruction; | 5563 | return irb->codegen->invalid_instruction; |
| 5551 | IrBasicBlock *after_then_block = irb->current_basic_block; | 5564 | IrBasicBlock *after_then_block = irb->current_basic_block; |
| ... | @@ -5555,12 +5568,12 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -5555,12 +5568,12 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode |
| 5555 | ir_set_cursor_at_end_and_append_block(irb, else_block); | 5568 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 5556 | IrInstruction *else_expr_result; | 5569 | IrInstruction *else_expr_result; |
| 5557 | if (else_node) { | 5570 | if (else_node) { |
| 5558 | else_expr_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_parent->peers[1].base); | 5571 | else_expr_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_parent->peers.at(1)->base); |
| 5559 | if (else_expr_result == irb->codegen->invalid_instruction) | 5572 | if (else_expr_result == irb->codegen->invalid_instruction) |
| 5560 | return irb->codegen->invalid_instruction; | 5573 | return irb->codegen->invalid_instruction; |
| 5561 | } else { | 5574 | } else { |
| 5562 | else_expr_result = ir_build_const_void(irb, scope, node); | 5575 | else_expr_result = ir_build_const_void(irb, scope, node); |
| 5563 | ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers[1].base); | 5576 | ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base); |
| 5564 | } | 5577 | } |
| 5565 | IrBasicBlock *after_else_block = irb->current_basic_block; | 5578 | IrBasicBlock *after_else_block = irb->current_basic_block; |
| 5566 | if (!instr_is_unreachable(else_expr_result)) | 5579 | if (!instr_is_unreachable(else_expr_result)) |
| ... | @@ -6004,12 +6017,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -6004,12 +6017,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 6004 | else_block, body_block, is_comptime); | 6017 | else_block, body_block, is_comptime); |
| 6005 | cond_br_inst->is_gen = true; | 6018 | cond_br_inst->is_gen = true; |
| 6006 | } else { | 6019 | } else { |
| 6007 | // for the purposes of the source instruction to ir_build_binary_result_peers | 6020 | // for the purposes of the source instruction to ir_build_result_peers |
| 6008 | cond_br_inst = irb->current_basic_block->instruction_list.last(); | 6021 | cond_br_inst = irb->current_basic_block->instruction_list.last(); |
| 6009 | } | 6022 | } |
| 6010 | | 6023 | |
| 6011 | ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, end_block, | 6024 | ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, |
| 6012 | result_loc, is_comptime); | 6025 | is_comptime); |
| 6013 | | 6026 | |
| 6014 | ir_set_cursor_at_end_and_append_block(irb, body_block); | 6027 | ir_set_cursor_at_end_and_append_block(irb, body_block); |
| 6015 | if (var_symbol) { | 6028 | if (var_symbol) { |
| ... | @@ -6030,7 +6043,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -6030,7 +6043,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 6030 | loop_scope->incoming_blocks = &incoming_blocks; | 6043 | loop_scope->incoming_blocks = &incoming_blocks; |
| 6031 | loop_scope->incoming_values = &incoming_values; | 6044 | loop_scope->incoming_values = &incoming_values; |
| 6032 | loop_scope->lval = lval; | 6045 | loop_scope->lval = lval; |
| 6033 | loop_scope->result_loc = &peer_parent->peers[0].base; | 6046 | loop_scope->peer_parent = peer_parent; |
| 6034 | | 6047 | |
| 6035 | // Note the body block of the loop is not the place that lval and result_loc are used - | 6048 | // Note the body block of the loop is not the place that lval and result_loc are used - |
| 6036 | // it's actually in break statements, handled similarly to return statements. | 6049 | // it's actually in break statements, handled similarly to return statements. |
| ... | @@ -6066,7 +6079,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -6066,7 +6079,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 6066 | IrInstruction *err_ptr = ir_build_unwrap_err_code(irb, err_scope, err_symbol_node, err_val_ptr); | 6079 | IrInstruction *err_ptr = ir_build_unwrap_err_code(irb, err_scope, err_symbol_node, err_val_ptr); |
| 6067 | ir_build_var_decl_src(irb, err_scope, symbol_node, err_var, nullptr, err_ptr); | 6080 | ir_build_var_decl_src(irb, err_scope, symbol_node, err_var, nullptr, err_ptr); |
| 6068 | | 6081 | |
| 6069 | IrInstruction *else_result = ir_gen_node_extra(irb, else_node, err_scope, lval, &peer_parent->peers[1].base); | 6082 | if (peer_parent->peers.length != 0) { |
| | 6083 | peer_parent->peers.last()->next_bb = else_block; |
| | 6084 | } |
| | 6085 | ResultLocPeer *peer_result = create_peer_result(peer_parent); |
| | 6086 | peer_parent->peers.append(peer_result); |
| | 6087 | IrInstruction *else_result = ir_gen_node_extra(irb, else_node, err_scope, lval, &peer_result->base); |
| 6070 | if (else_result == irb->codegen->invalid_instruction) | 6088 | if (else_result == irb->codegen->invalid_instruction) |
| 6071 | return else_result; | 6089 | return else_result; |
| 6072 | if (!instr_is_unreachable(else_result)) | 6090 | if (!instr_is_unreachable(else_result)) |
| ... | @@ -6080,6 +6098,9 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -6080,6 +6098,9 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 6080 | incoming_blocks.append(after_cond_block); | 6098 | incoming_blocks.append(after_cond_block); |
| 6081 | incoming_values.append(void_else_result); | 6099 | incoming_values.append(void_else_result); |
| 6082 | } | 6100 | } |
| | 6101 | if (peer_parent->peers.length != 0) { |
| | 6102 | peer_parent->peers.last()->next_bb = end_block; |
| | 6103 | } |
| 6083 | | 6104 | |
| 6084 | IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, | 6105 | IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, |
| 6085 | incoming_blocks.items, incoming_values.items, peer_parent); | 6106 | incoming_blocks.items, incoming_values.items, peer_parent); |
| ... | @@ -6107,12 +6128,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -6107,12 +6128,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 6107 | body_block, else_block, is_comptime); | 6128 | body_block, else_block, is_comptime); |
| 6108 | cond_br_inst->is_gen = true; | 6129 | cond_br_inst->is_gen = true; |
| 6109 | } else { | 6130 | } else { |
| 6110 | // for the purposes of the source instruction to ir_build_binary_result_peers | 6131 | // for the purposes of the source instruction to ir_build_result_peers |
| 6111 | cond_br_inst = irb->current_basic_block->instruction_list.last(); | 6132 | cond_br_inst = irb->current_basic_block->instruction_list.last(); |
| 6112 | } | 6133 | } |
| 6113 | | 6134 | |
| 6114 | ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, end_block, | 6135 | ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, |
| 6115 | result_loc, is_comptime); | 6136 | is_comptime); |
| 6116 | | 6137 | |
| 6117 | ir_set_cursor_at_end_and_append_block(irb, body_block); | 6138 | ir_set_cursor_at_end_and_append_block(irb, body_block); |
| 6118 | IrInstruction *payload_ptr = ir_build_optional_unwrap_ptr(irb, child_scope, symbol_node, maybe_val_ptr, false, false); | 6139 | IrInstruction *payload_ptr = ir_build_optional_unwrap_ptr(irb, child_scope, symbol_node, maybe_val_ptr, false, false); |
| ... | @@ -6130,7 +6151,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -6130,7 +6151,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 6130 | loop_scope->incoming_blocks = &incoming_blocks; | 6151 | loop_scope->incoming_blocks = &incoming_blocks; |
| 6131 | loop_scope->incoming_values = &incoming_values; | 6152 | loop_scope->incoming_values = &incoming_values; |
| 6132 | loop_scope->lval = lval; | 6153 | loop_scope->lval = lval; |
| 6133 | loop_scope->result_loc = &peer_parent->peers[0].base; | 6154 | loop_scope->peer_parent = peer_parent; |
| 6134 | | 6155 | |
| 6135 | // Note the body block of the loop is not the place that lval and result_loc are used - | 6156 | // Note the body block of the loop is not the place that lval and result_loc are used - |
| 6136 | // it's actually in break statements, handled similarly to return statements. | 6157 | // it's actually in break statements, handled similarly to return statements. |
| ... | @@ -6159,7 +6180,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -6159,7 +6180,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 6159 | if (else_node) { | 6180 | if (else_node) { |
| 6160 | ir_set_cursor_at_end_and_append_block(irb, else_block); | 6181 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 6161 | | 6182 | |
| 6162 | else_result = ir_gen_node_extra(irb, else_node, scope, lval, &peer_parent->peers[1].base); | 6183 | if (peer_parent->peers.length != 0) { |
| | 6184 | peer_parent->peers.last()->next_bb = else_block; |
| | 6185 | } |
| | 6186 | ResultLocPeer *peer_result = create_peer_result(peer_parent); |
| | 6187 | peer_parent->peers.append(peer_result); |
| | 6188 | else_result = ir_gen_node_extra(irb, else_node, scope, lval, &peer_result->base); |
| 6163 | if (else_result == irb->codegen->invalid_instruction) | 6189 | if (else_result == irb->codegen->invalid_instruction) |
| 6164 | return else_result; | 6190 | return else_result; |
| 6165 | if (!instr_is_unreachable(else_result)) | 6191 | if (!instr_is_unreachable(else_result)) |
| ... | @@ -6174,6 +6200,9 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -6174,6 +6200,9 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 6174 | incoming_blocks.append(after_cond_block); | 6200 | incoming_blocks.append(after_cond_block); |
| 6175 | incoming_values.append(void_else_result); | 6201 | incoming_values.append(void_else_result); |
| 6176 | } | 6202 | } |
| | 6203 | if (peer_parent->peers.length != 0) { |
| | 6204 | peer_parent->peers.last()->next_bb = end_block; |
| | 6205 | } |
| 6177 | | 6206 | |
| 6178 | IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, | 6207 | IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, |
| 6179 | incoming_blocks.items, incoming_values.items, peer_parent); | 6208 | incoming_blocks.items, incoming_values.items, peer_parent); |
| ... | @@ -6191,12 +6220,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -6191,12 +6220,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 6191 | body_block, else_block, is_comptime); | 6220 | body_block, else_block, is_comptime); |
| 6192 | cond_br_inst->is_gen = true; | 6221 | cond_br_inst->is_gen = true; |
| 6193 | } else { | 6222 | } else { |
| 6194 | // for the purposes of the source instruction to ir_build_binary_result_peers | 6223 | // for the purposes of the source instruction to ir_build_result_peers |
| 6195 | cond_br_inst = irb->current_basic_block->instruction_list.last(); | 6224 | cond_br_inst = irb->current_basic_block->instruction_list.last(); |
| 6196 | } | 6225 | } |
| 6197 | | 6226 | |
| 6198 | ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, end_block, | 6227 | ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, |
| 6199 | result_loc, is_comptime); | 6228 | is_comptime); |
| 6200 | ir_set_cursor_at_end_and_append_block(irb, body_block); | 6229 | ir_set_cursor_at_end_and_append_block(irb, body_block); |
| 6201 | | 6230 | |
| 6202 | ZigList<IrInstruction *> incoming_values = {0}; | 6231 | ZigList<IrInstruction *> incoming_values = {0}; |
| ... | @@ -6211,7 +6240,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -6211,7 +6240,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 6211 | loop_scope->incoming_blocks = &incoming_blocks; | 6240 | loop_scope->incoming_blocks = &incoming_blocks; |
| 6212 | loop_scope->incoming_values = &incoming_values; | 6241 | loop_scope->incoming_values = &incoming_values; |
| 6213 | loop_scope->lval = lval; | 6242 | loop_scope->lval = lval; |
| 6214 | loop_scope->result_loc = &peer_parent->peers[0].base; | 6243 | loop_scope->peer_parent = peer_parent; |
| 6215 | | 6244 | |
| 6216 | // Note the body block of the loop is not the place that lval and result_loc are used - | 6245 | // Note the body block of the loop is not the place that lval and result_loc are used - |
| 6217 | // it's actually in break statements, handled similarly to return statements. | 6246 | // it's actually in break statements, handled similarly to return statements. |
| ... | @@ -6240,7 +6269,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -6240,7 +6269,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 6240 | if (else_node) { | 6269 | if (else_node) { |
| 6241 | ir_set_cursor_at_end_and_append_block(irb, else_block); | 6270 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 6242 | | 6271 | |
| 6243 | else_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_parent->peers[1].base); | 6272 | if (peer_parent->peers.length != 0) { |
| | 6273 | peer_parent->peers.last()->next_bb = else_block; |
| | 6274 | } |
| | 6275 | ResultLocPeer *peer_result = create_peer_result(peer_parent); |
| | 6276 | peer_parent->peers.append(peer_result); |
| | 6277 | |
| | 6278 | else_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_result->base); |
| 6244 | if (else_result == irb->codegen->invalid_instruction) | 6279 | if (else_result == irb->codegen->invalid_instruction) |
| 6245 | return else_result; | 6280 | return else_result; |
| 6246 | if (!instr_is_unreachable(else_result)) | 6281 | if (!instr_is_unreachable(else_result)) |
| ... | @@ -6255,6 +6290,9 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -6255,6 +6290,9 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 6255 | incoming_blocks.append(after_cond_block); | 6290 | incoming_blocks.append(after_cond_block); |
| 6256 | incoming_values.append(void_else_result); | 6291 | incoming_values.append(void_else_result); |
| 6257 | } | 6292 | } |
| | 6293 | if (peer_parent->peers.length != 0) { |
| | 6294 | peer_parent->peers.last()->next_bb = end_block; |
| | 6295 | } |
| 6258 | | 6296 | |
| 6259 | IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, | 6297 | IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, |
| 6260 | incoming_blocks.items, incoming_values.items, peer_parent); | 6298 | incoming_blocks.items, incoming_values.items, peer_parent); |
| ... | @@ -6327,8 +6365,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo | ... | @@ -6327,8 +6365,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo |
| 6327 | IrInstruction *cond_br_inst = ir_mark_gen(ir_build_cond_br(irb, parent_scope, node, cond, | 6365 | IrInstruction *cond_br_inst = ir_mark_gen(ir_build_cond_br(irb, parent_scope, node, cond, |
| 6328 | body_block, else_block, is_comptime)); | 6366 | body_block, else_block, is_comptime)); |
| 6329 | | 6367 | |
| 6330 | ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, end_block, | 6368 | ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, is_comptime); |
| 6331 | result_loc, is_comptime); | | |
| 6332 | | 6369 | |
| 6333 | ir_set_cursor_at_end_and_append_block(irb, body_block); | 6370 | ir_set_cursor_at_end_and_append_block(irb, body_block); |
| 6334 | IrInstruction *elem_ptr = ir_build_elem_ptr(irb, parent_scope, node, array_val_ptr, index_val, false, | 6371 | IrInstruction *elem_ptr = ir_build_elem_ptr(irb, parent_scope, node, array_val_ptr, index_val, false, |
| ... | @@ -6351,7 +6388,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo | ... | @@ -6351,7 +6388,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo |
| 6351 | loop_scope->incoming_blocks = &incoming_blocks; | 6388 | loop_scope->incoming_blocks = &incoming_blocks; |
| 6352 | loop_scope->incoming_values = &incoming_values; | 6389 | loop_scope->incoming_values = &incoming_values; |
| 6353 | loop_scope->lval = lval; | 6390 | loop_scope->lval = lval; |
| 6354 | loop_scope->result_loc = &peer_parent->peers[0].base; | 6391 | loop_scope->peer_parent = peer_parent; |
| 6355 | | 6392 | |
| 6356 | // Note the body block of the loop is not the place that lval and result_loc are used - | 6393 | // Note the body block of the loop is not the place that lval and result_loc are used - |
| 6357 | // it's actually in break statements, handled similarly to return statements. | 6394 | // it's actually in break statements, handled similarly to return statements. |
| ... | @@ -6372,7 +6409,12 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo | ... | @@ -6372,7 +6409,12 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo |
| 6372 | if (else_node) { | 6409 | if (else_node) { |
| 6373 | ir_set_cursor_at_end_and_append_block(irb, else_block); | 6410 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 6374 | | 6411 | |
| 6375 | else_result = ir_gen_node_extra(irb, else_node, parent_scope, lval, &peer_parent->peers[1].base); | 6412 | if (peer_parent->peers.length != 0) { |
| | 6413 | peer_parent->peers.last()->next_bb = else_block; |
| | 6414 | } |
| | 6415 | ResultLocPeer *peer_result = create_peer_result(peer_parent); |
| | 6416 | peer_parent->peers.append(peer_result); |
| | 6417 | else_result = ir_gen_node_extra(irb, else_node, parent_scope, lval, &peer_result->base); |
| 6376 | if (else_result == irb->codegen->invalid_instruction) | 6418 | if (else_result == irb->codegen->invalid_instruction) |
| 6377 | return else_result; | 6419 | return else_result; |
| 6378 | if (!instr_is_unreachable(else_result)) | 6420 | if (!instr_is_unreachable(else_result)) |
| ... | @@ -6388,6 +6430,9 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo | ... | @@ -6388,6 +6430,9 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo |
| 6388 | incoming_blocks.append(after_cond_block); | 6430 | incoming_blocks.append(after_cond_block); |
| 6389 | incoming_values.append(void_else_value); | 6431 | incoming_values.append(void_else_value); |
| 6390 | } | 6432 | } |
| | 6433 | if (peer_parent->peers.length != 0) { |
| | 6434 | peer_parent->peers.last()->next_bb = end_block; |
| | 6435 | } |
| 6391 | | 6436 | |
| 6392 | IrInstruction *phi = ir_build_phi(irb, parent_scope, node, incoming_blocks.length, | 6437 | IrInstruction *phi = ir_build_phi(irb, parent_scope, node, incoming_blocks.length, |
| 6393 | incoming_blocks.items, incoming_values.items, peer_parent); | 6438 | incoming_blocks.items, incoming_values.items, peer_parent); |
| ... | @@ -6728,7 +6773,7 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN | ... | @@ -6728,7 +6773,7 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN |
| 6728 | var_scope = subexpr_scope; | 6773 | var_scope = subexpr_scope; |
| 6729 | } | 6774 | } |
| 6730 | IrInstruction *then_expr_result = ir_gen_node_extra(irb, then_node, var_scope, lval, | 6775 | IrInstruction *then_expr_result = ir_gen_node_extra(irb, then_node, var_scope, lval, |
| 6731 | &peer_parent->peers[0].base); | 6776 | &peer_parent->peers.at(0)->base); |
| 6732 | if (then_expr_result == irb->codegen->invalid_instruction) | 6777 | if (then_expr_result == irb->codegen->invalid_instruction) |
| 6733 | return then_expr_result; | 6778 | return then_expr_result; |
| 6734 | IrBasicBlock *after_then_block = irb->current_basic_block; | 6779 | IrBasicBlock *after_then_block = irb->current_basic_block; |
| ... | @@ -6738,12 +6783,12 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN | ... | @@ -6738,12 +6783,12 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN |
| 6738 | ir_set_cursor_at_end_and_append_block(irb, else_block); | 6783 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 6739 | IrInstruction *else_expr_result; | 6784 | IrInstruction *else_expr_result; |
| 6740 | if (else_node) { | 6785 | if (else_node) { |
| 6741 | else_expr_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_parent->peers[1].base); | 6786 | else_expr_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_parent->peers.at(1)->base); |
| 6742 | if (else_expr_result == irb->codegen->invalid_instruction) | 6787 | if (else_expr_result == irb->codegen->invalid_instruction) |
| 6743 | return else_expr_result; | 6788 | return else_expr_result; |
| 6744 | } else { | 6789 | } else { |
| 6745 | else_expr_result = ir_build_const_void(irb, scope, node); | 6790 | else_expr_result = ir_build_const_void(irb, scope, node); |
| 6746 | ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers[1].base); | 6791 | ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base); |
| 6747 | } | 6792 | } |
| 6748 | IrBasicBlock *after_else_block = irb->current_basic_block; | 6793 | IrBasicBlock *after_else_block = irb->current_basic_block; |
| 6749 | if (!instr_is_unreachable(else_expr_result)) | 6794 | if (!instr_is_unreachable(else_expr_result)) |
| ... | @@ -6811,7 +6856,7 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6811,7 +6856,7 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6811 | var_scope = subexpr_scope; | 6856 | var_scope = subexpr_scope; |
| 6812 | } | 6857 | } |
| 6813 | IrInstruction *then_expr_result = ir_gen_node_extra(irb, then_node, var_scope, lval, | 6858 | IrInstruction *then_expr_result = ir_gen_node_extra(irb, then_node, var_scope, lval, |
| 6814 | &peer_parent->peers[0].base); | 6859 | &peer_parent->peers.at(0)->base); |
| 6815 | if (then_expr_result == irb->codegen->invalid_instruction) | 6860 | if (then_expr_result == irb->codegen->invalid_instruction) |
| 6816 | return then_expr_result; | 6861 | return then_expr_result; |
| 6817 | IrBasicBlock *after_then_block = irb->current_basic_block; | 6862 | IrBasicBlock *after_then_block = irb->current_basic_block; |
| ... | @@ -6835,12 +6880,12 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6835,12 +6880,12 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6835 | } else { | 6880 | } else { |
| 6836 | err_var_scope = subexpr_scope; | 6881 | err_var_scope = subexpr_scope; |
| 6837 | } | 6882 | } |
| 6838 | else_expr_result = ir_gen_node_extra(irb, else_node, err_var_scope, lval, &peer_parent->peers[1].base); | 6883 | else_expr_result = ir_gen_node_extra(irb, else_node, err_var_scope, lval, &peer_parent->peers.at(1)->base); |
| 6839 | if (else_expr_result == irb->codegen->invalid_instruction) | 6884 | if (else_expr_result == irb->codegen->invalid_instruction) |
| 6840 | return else_expr_result; | 6885 | return else_expr_result; |
| 6841 | } else { | 6886 | } else { |
| 6842 | else_expr_result = ir_build_const_void(irb, scope, node); | 6887 | else_expr_result = ir_build_const_void(irb, scope, node); |
| 6843 | ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers[1].base); | 6888 | ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base); |
| 6844 | } | 6889 | } |
| 6845 | IrBasicBlock *after_else_block = irb->current_basic_block; | 6890 | IrBasicBlock *after_else_block = irb->current_basic_block; |
| 6846 | if (!instr_is_unreachable(else_expr_result)) | 6891 | if (!instr_is_unreachable(else_expr_result)) |
| ... | @@ -6910,13 +6955,6 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *swit | ... | @@ -6910,13 +6955,6 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *swit |
| 6910 | return true; | 6955 | return true; |
| 6911 | } | 6956 | } |
| 6912 | | 6957 | |
| 6913 | static void next_peer_block(ResultLocPeerParent *peer_parent, IrBasicBlock *next_bb) { | | |
| 6914 | if (peer_parent->peer_count > 0) { | | |
| 6915 | peer_parent->peers[peer_parent->peer_count - 1].next_bb = next_bb; | | |
| 6916 | } | | |
| 6917 | peer_parent->peer_count += 1; | | |
| 6918 | } | | |
| 6919 | | | |
| 6920 | static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, | 6958 | static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| 6921 | ResultLoc *result_loc) | 6959 | ResultLoc *result_loc) |
| 6922 | { | 6960 | { |
| ... | @@ -6955,8 +6993,6 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6955,8 +6993,6 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6955 | peer_parent->end_bb = end_block; | 6993 | peer_parent->end_bb = end_block; |
| 6956 | peer_parent->is_comptime = is_comptime; | 6994 | peer_parent->is_comptime = is_comptime; |
| 6957 | peer_parent->parent = result_loc; | 6995 | peer_parent->parent = result_loc; |
| 6958 | peer_parent->peers = allocate<ResultLocPeer>(prong_count); | | |
| 6959 | peer_parent->peer_count = 0; | | |
| 6960 | | 6996 | |
| 6961 | ir_build_reset_result(irb, scope, node, &peer_parent->base); | 6997 | ir_build_reset_result(irb, scope, node, &peer_parent->base); |
| 6962 | | 6998 | |
| ... | @@ -6968,9 +7004,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6968,9 +7004,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6968 | AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i); | 7004 | AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i); |
| 6969 | size_t prong_item_count = prong_node->data.switch_prong.items.length; | 7005 | size_t prong_item_count = prong_node->data.switch_prong.items.length; |
| 6970 | if (prong_item_count == 0) { | 7006 | if (prong_item_count == 0) { |
| 6971 | ResultLocPeer *this_peer_result_loc = &peer_parent->peers[peer_parent->peer_count]; | 7007 | ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent); |
| 6972 | this_peer_result_loc->base.id = ResultLocIdPeer; | | |
| 6973 | this_peer_result_loc->parent = peer_parent; | | |
| 6974 | if (else_prong) { | 7008 | if (else_prong) { |
| 6975 | ErrorMsg *msg = add_node_error(irb->codegen, prong_node, | 7009 | ErrorMsg *msg = add_node_error(irb->codegen, prong_node, |
| 6976 | buf_sprintf("multiple else prongs in switch expression")); | 7010 | buf_sprintf("multiple else prongs in switch expression")); |
| ... | @@ -6981,7 +7015,10 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6981,7 +7015,10 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6981 | else_prong = prong_node; | 7015 | else_prong = prong_node; |
| 6982 | | 7016 | |
| 6983 | IrBasicBlock *prev_block = irb->current_basic_block; | 7017 | IrBasicBlock *prev_block = irb->current_basic_block; |
| 6984 | next_peer_block(peer_parent, else_block); | 7018 | if (peer_parent->peers.length > 0) { |
| | 7019 | peer_parent->peers.last()->next_bb = else_block; |
| | 7020 | } |
| | 7021 | peer_parent->peers.append(this_peer_result_loc); |
| 6985 | ir_set_cursor_at_end_and_append_block(irb, else_block); | 7022 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 6986 | if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, | 7023 | if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, |
| 6987 | is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, &incoming_blocks, &incoming_values, | 7024 | is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, &incoming_blocks, &incoming_values, |
| ... | @@ -6991,9 +7028,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6991,9 +7028,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6991 | } | 7028 | } |
| 6992 | ir_set_cursor_at_end(irb, prev_block); | 7029 | ir_set_cursor_at_end(irb, prev_block); |
| 6993 | } else if (prong_node->data.switch_prong.any_items_are_range) { | 7030 | } else if (prong_node->data.switch_prong.any_items_are_range) { |
| 6994 | ResultLocPeer *this_peer_result_loc = &peer_parent->peers[peer_parent->peer_count]; | 7031 | ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent); |
| 6995 | this_peer_result_loc->base.id = ResultLocIdPeer; | | |
| 6996 | this_peer_result_loc->parent = peer_parent; | | |
| 6997 | | 7032 | |
| 6998 | IrInstruction *ok_bit = nullptr; | 7033 | IrInstruction *ok_bit = nullptr; |
| 6999 | AstNode *last_item_node = nullptr; | 7034 | AstNode *last_item_node = nullptr; |
| ... | @@ -7054,7 +7089,10 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -7054,7 +7089,10 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 7054 | ir_mark_gen(ir_build_cond_br(irb, scope, last_item_node, ok_bit, range_block_yes, | 7089 | ir_mark_gen(ir_build_cond_br(irb, scope, last_item_node, ok_bit, range_block_yes, |
| 7055 | range_block_no, is_comptime)); | 7090 | range_block_no, is_comptime)); |
| 7056 | | 7091 | |
| 7057 | next_peer_block(peer_parent, range_block_yes); | 7092 | if (peer_parent->peers.length > 0) { |
| | 7093 | peer_parent->peers.last()->next_bb = range_block_yes; |
| | 7094 | } |
| | 7095 | peer_parent->peers.append(this_peer_result_loc); |
| 7058 | ir_set_cursor_at_end_and_append_block(irb, range_block_yes); | 7096 | ir_set_cursor_at_end_and_append_block(irb, range_block_yes); |
| 7059 | if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, | 7097 | if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, |
| 7060 | is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, | 7098 | is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, |
| ... | @@ -7076,9 +7114,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -7076,9 +7114,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 7076 | if (prong_node->data.switch_prong.any_items_are_range) | 7114 | if (prong_node->data.switch_prong.any_items_are_range) |
| 7077 | continue; | 7115 | continue; |
| 7078 | | 7116 | |
| 7079 | ResultLocPeer *this_peer_result_loc = &peer_parent->peers[peer_parent->peer_count]; | 7117 | ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent); |
| 7080 | this_peer_result_loc->base.id = ResultLocIdPeer; | | |
| 7081 | this_peer_result_loc->parent = peer_parent; | | |
| 7082 | | 7118 | |
| 7083 | IrBasicBlock *prong_block = ir_create_basic_block(irb, scope, "SwitchProng"); | 7119 | IrBasicBlock *prong_block = ir_create_basic_block(irb, scope, "SwitchProng"); |
| 7084 | IrInstruction **items = allocate<IrInstruction *>(prong_item_count); | 7120 | IrInstruction **items = allocate<IrInstruction *>(prong_item_count); |
| ... | @@ -7103,7 +7139,10 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -7103,7 +7139,10 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 7103 | } | 7139 | } |
| 7104 | | 7140 | |
| 7105 | IrBasicBlock *prev_block = irb->current_basic_block; | 7141 | IrBasicBlock *prev_block = irb->current_basic_block; |
| 7106 | next_peer_block(peer_parent, prong_block); | 7142 | if (peer_parent->peers.length > 0) { |
| | 7143 | peer_parent->peers.last()->next_bb = prong_block; |
| | 7144 | } |
| | 7145 | peer_parent->peers.append(this_peer_result_loc); |
| 7107 | ir_set_cursor_at_end_and_append_block(irb, prong_block); | 7146 | ir_set_cursor_at_end_and_append_block(irb, prong_block); |
| 7108 | if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, | 7147 | if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, |
| 7109 | is_comptime, var_is_comptime, target_value_ptr, items, prong_item_count, | 7148 | is_comptime, var_is_comptime, target_value_ptr, items, prong_item_count, |
| ... | @@ -7130,20 +7169,20 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -7130,20 +7169,20 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 7130 | } | 7169 | } |
| 7131 | br_instruction = &switch_br->base; | 7170 | br_instruction = &switch_br->base; |
| 7132 | } | 7171 | } |
| 7133 | for (size_t i = 0; i < peer_parent->peer_count; i += 1) { | 7172 | for (size_t i = 0; i < peer_parent->peers.length; i += 1) { |
| 7134 | peer_parent->peers[i].base.source_instruction = br_instruction; | 7173 | peer_parent->peers.at(i)->base.source_instruction = br_instruction; |
| 7135 | } | 7174 | } |
| 7136 | peer_parent->base.source_instruction = br_instruction; | 7175 | peer_parent->base.source_instruction = br_instruction; |
| 7137 | | 7176 | |
| 7138 | if (!else_prong) { | 7177 | if (!else_prong) { |
| 7139 | if (peer_parent->peer_count != 0) { | 7178 | if (peer_parent->peers.length != 0) { |
| 7140 | peer_parent->peers[peer_parent->peer_count - 1].next_bb = else_block; | 7179 | peer_parent->peers.last()->next_bb = else_block; |
| 7141 | } | 7180 | } |
| 7142 | ir_set_cursor_at_end_and_append_block(irb, else_block); | 7181 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 7143 | ir_build_unreachable(irb, scope, node); | 7182 | ir_build_unreachable(irb, scope, node); |
| 7144 | } else { | 7183 | } else { |
| 7145 | if (peer_parent->peer_count != 0) { | 7184 | if (peer_parent->peers.length != 0) { |
| 7146 | peer_parent->peers[peer_parent->peer_count - 1].next_bb = end_block; | 7185 | peer_parent->peers.last()->next_bb = end_block; |
| 7147 | } | 7186 | } |
| 7148 | } | 7187 | } |
| 7149 | | 7188 | |
| ... | @@ -7247,8 +7286,11 @@ static IrInstruction *ir_gen_break(IrBuilder *irb, Scope *break_scope, AstNode * | ... | @@ -7247,8 +7286,11 @@ static IrInstruction *ir_gen_break(IrBuilder *irb, Scope *break_scope, AstNode * |
| 7247 | | 7286 | |
| 7248 | IrInstruction *result_value; | 7287 | IrInstruction *result_value; |
| 7249 | if (node->data.break_expr.expr) { | 7288 | if (node->data.break_expr.expr) { |
| | 7289 | ResultLocPeer *peer_result = create_peer_result(loop_scope->peer_parent); |
| | 7290 | loop_scope->peer_parent->peers.append(peer_result); |
| | 7291 | |
| 7250 | result_value = ir_gen_node_extra(irb, node->data.break_expr.expr, break_scope, | 7292 | result_value = ir_gen_node_extra(irb, node->data.break_expr.expr, break_scope, |
| 7251 | loop_scope->lval, loop_scope->result_loc); | 7293 | loop_scope->lval, &peer_result->base); |
| 7252 | if (result_value == irb->codegen->invalid_instruction) | 7294 | if (result_value == irb->codegen->invalid_instruction) |
| 7253 | return irb->codegen->invalid_instruction; | 7295 | return irb->codegen->invalid_instruction; |
| 7254 | } else { | 7296 | } else { |
| ... | @@ -7421,7 +7463,7 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode | ... | @@ -7421,7 +7463,7 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode |
| 7421 | } else { | 7463 | } else { |
| 7422 | err_scope = parent_scope; | 7464 | err_scope = parent_scope; |
| 7423 | } | 7465 | } |
| 7424 | IrInstruction *err_result = ir_gen_node_extra(irb, op2_node, err_scope, lval, &peer_parent->peers[0].base); | 7466 | IrInstruction *err_result = ir_gen_node_extra(irb, op2_node, err_scope, lval, &peer_parent->peers.at(0)->base); |
| 7425 | if (err_result == irb->codegen->invalid_instruction) | 7467 | if (err_result == irb->codegen->invalid_instruction) |
| 7426 | return irb->codegen->invalid_instruction; | 7468 | return irb->codegen->invalid_instruction; |
| 7427 | IrBasicBlock *after_err_block = irb->current_basic_block; | 7469 | IrBasicBlock *after_err_block = irb->current_basic_block; |
| ... | @@ -7431,7 +7473,7 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode | ... | @@ -7431,7 +7473,7 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode |
| 7431 | ir_set_cursor_at_end_and_append_block(irb, ok_block); | 7473 | ir_set_cursor_at_end_and_append_block(irb, ok_block); |
| 7432 | IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, parent_scope, node, err_union_ptr, false, false); | 7474 | IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, parent_scope, node, err_union_ptr, false, false); |
| 7433 | IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); | 7475 | IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); |
| 7434 | ir_build_end_expr(irb, parent_scope, node, unwrapped_payload, &peer_parent->peers[1].base); | 7476 | ir_build_end_expr(irb, parent_scope, node, unwrapped_payload, &peer_parent->peers.at(1)->base); |
| 7435 | IrBasicBlock *after_ok_block = irb->current_basic_block; | 7477 | IrBasicBlock *after_ok_block = irb->current_basic_block; |
| 7436 | ir_build_br(irb, parent_scope, node, end_block, is_comptime); | 7478 | ir_build_br(irb, parent_scope, node, end_block, is_comptime); |
| 7437 | | 7479 | |
| ... | @@ -10939,25 +10981,7 @@ static IrInstruction *ira_resume(IrAnalyze *ira) { | ... | @@ -10939,25 +10981,7 @@ static IrInstruction *ira_resume(IrAnalyze *ira) { |
| 10939 | return ira->codegen->unreach_instruction; | 10981 | return ira->codegen->unreach_instruction; |
| 10940 | } | 10982 | } |
| 10941 | | 10983 | |
| 10942 | static void ir_finish_bb(IrAnalyze *ira) { | 10984 | static void ir_start_next_bb(IrAnalyze *ira) { |
| 10943 | if (!ira->new_irb.current_basic_block->already_appended) { | | |
| 10944 | ira->new_irb.current_basic_block->already_appended = true; | | |
| 10945 | if (ira->codegen->verbose_ir) { | | |
| 10946 | fprintf(stderr, "append new bb %s_%zu\n", ira->new_irb.current_basic_block->name_hint, | | |
| 10947 | ira->new_irb.current_basic_block->debug_id); | | |
| 10948 | } | | |
| 10949 | ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block); | | |
| 10950 | } | | |
| 10951 | ira->instruction_index += 1; | | |
| 10952 | while (ira->instruction_index < ira->old_irb.current_basic_block->instruction_list.length) { | | |
| 10953 | IrInstruction *next_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); | | |
| 10954 | if (!next_instruction->is_gen) { | | |
| 10955 | ir_add_error(ira, next_instruction, buf_sprintf("unreachable code")); | | |
| 10956 | break; | | |
| 10957 | } | | |
| 10958 | ira->instruction_index += 1; | | |
| 10959 | } | | |
| 10960 | | | |
| 10961 | ira->old_bb_index += 1; | 10985 | ira->old_bb_index += 1; |
| 10962 | | 10986 | |
| 10963 | bool need_repeat = true; | 10987 | bool need_repeat = true; |
| ... | @@ -11006,6 +11030,28 @@ static void ir_finish_bb(IrAnalyze *ira) { | ... | @@ -11006,6 +11030,28 @@ static void ir_finish_bb(IrAnalyze *ira) { |
| 11006 | } | 11030 | } |
| 11007 | } | 11031 | } |
| 11008 | | 11032 | |
| | 11033 | static void ir_finish_bb(IrAnalyze *ira) { |
| | 11034 | if (!ira->new_irb.current_basic_block->already_appended) { |
| | 11035 | ira->new_irb.current_basic_block->already_appended = true; |
| | 11036 | if (ira->codegen->verbose_ir) { |
| | 11037 | fprintf(stderr, "append new bb %s_%zu\n", ira->new_irb.current_basic_block->name_hint, |
| | 11038 | ira->new_irb.current_basic_block->debug_id); |
| | 11039 | } |
| | 11040 | ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block); |
| | 11041 | } |
| | 11042 | ira->instruction_index += 1; |
| | 11043 | while (ira->instruction_index < ira->old_irb.current_basic_block->instruction_list.length) { |
| | 11044 | IrInstruction *next_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); |
| | 11045 | if (!next_instruction->is_gen) { |
| | 11046 | ir_add_error(ira, next_instruction, buf_sprintf("unreachable code")); |
| | 11047 | break; |
| | 11048 | } |
| | 11049 | ira->instruction_index += 1; |
| | 11050 | } |
| | 11051 | |
| | 11052 | ir_start_next_bb(ira); |
| | 11053 | } |
| | 11054 | |
| 11009 | static IrInstruction *ir_unreach_error(IrAnalyze *ira) { | 11055 | static IrInstruction *ir_unreach_error(IrAnalyze *ira) { |
| 11010 | ira->old_bb_index = SIZE_MAX; | 11056 | ira->old_bb_index = SIZE_MAX; |
| 11011 | ira->new_irb.exec->invalid = true; | 11057 | ira->new_irb.exec->invalid = true; |
| ... | @@ -15036,7 +15082,12 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe | ... | @@ -15036,7 +15082,12 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe |
| 15036 | if (peer_parent->end_bb->suspend_instruction_ref == nullptr) { | 15082 | if (peer_parent->end_bb->suspend_instruction_ref == nullptr) { |
| 15037 | peer_parent->end_bb->suspend_instruction_ref = suspend_source_instr; | 15083 | peer_parent->end_bb->suspend_instruction_ref = suspend_source_instr; |
| 15038 | } | 15084 | } |
| 15039 | return ira_suspend(ira, suspend_source_instr, result_peer->next_bb, &result_peer->suspend_pos); | 15085 | IrInstruction *unreach_inst = ira_suspend(ira, suspend_source_instr, result_peer->next_bb, |
| | 15086 | &result_peer->suspend_pos); |
| | 15087 | if (result_peer->next_bb == nullptr) { |
| | 15088 | ir_start_next_bb(ira); |
| | 15089 | } |
| | 15090 | return unreach_inst; |
| 15040 | } | 15091 | } |
| 15041 | | 15092 | |
| 15042 | IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, | 15093 | IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, |
| ... | @@ -15194,8 +15245,8 @@ static void ir_reset_result(ResultLoc *result_loc) { | ... | @@ -15194,8 +15245,8 @@ static void ir_reset_result(ResultLoc *result_loc) { |
| 15194 | peer_parent->skipped = false; | 15245 | peer_parent->skipped = false; |
| 15195 | peer_parent->done_resuming = false; | 15246 | peer_parent->done_resuming = false; |
| 15196 | peer_parent->resolved_type = nullptr; | 15247 | peer_parent->resolved_type = nullptr; |
| 15197 | for (size_t i = 0; i < peer_parent->peer_count; i += 1) { | 15248 | for (size_t i = 0; i < peer_parent->peers.length; i += 1) { |
| 15198 | ir_reset_result(&peer_parent->peers[i].base); | 15249 | ir_reset_result(&peer_parent->peers.at(i)->base); |
| 15199 | } | 15250 | } |
| 15200 | break; | 15251 | break; |
| 15201 | } | 15252 | } |
| ... | @@ -16615,11 +16666,13 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh | ... | @@ -16615,11 +16666,13 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh |
| 16615 | } | 16666 | } |
| 16616 | | 16667 | |
| 16617 | ResultLocPeerParent *peer_parent = phi_instruction->peer_parent; | 16668 | ResultLocPeerParent *peer_parent = phi_instruction->peer_parent; |
| 16618 | if (peer_parent != nullptr && !peer_parent->skipped && !peer_parent->done_resuming) { | 16669 | if (peer_parent != nullptr && !peer_parent->skipped && !peer_parent->done_resuming && |
| | 16670 | peer_parent->peers.length != 0) |
| | 16671 | { |
| 16619 | if (peer_parent->resolved_type == nullptr) { | 16672 | if (peer_parent->resolved_type == nullptr) { |
| 16620 | IrInstruction **instructions = allocate<IrInstruction *>(peer_parent->peer_count); | 16673 | IrInstruction **instructions = allocate<IrInstruction *>(peer_parent->peers.length); |
| 16621 | for (size_t i = 0; i < peer_parent->peer_count; i += 1) { | 16674 | for (size_t i = 0; i < peer_parent->peers.length; i += 1) { |
| 16622 | ResultLocPeer *this_peer = &peer_parent->peers[i]; | 16675 | ResultLocPeer *this_peer = peer_parent->peers.at(i); |
| 16623 | | 16676 | |
| 16624 | IrInstruction *gen_instruction = this_peer->base.gen_instruction; | 16677 | IrInstruction *gen_instruction = this_peer->base.gen_instruction; |
| 16625 | if (gen_instruction == nullptr) { | 16678 | if (gen_instruction == nullptr) { |
| ... | @@ -16639,7 +16692,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh | ... | @@ -16639,7 +16692,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh |
| 16639 | ZigType *expected_type = ir_result_loc_expected_type(ira, &phi_instruction->base, peer_parent->parent); | 16692 | ZigType *expected_type = ir_result_loc_expected_type(ira, &phi_instruction->base, peer_parent->parent); |
| 16640 | peer_parent->resolved_type = ir_resolve_peer_types(ira, | 16693 | peer_parent->resolved_type = ir_resolve_peer_types(ira, |
| 16641 | peer_parent->base.source_instruction->source_node, expected_type, instructions, | 16694 | peer_parent->base.source_instruction->source_node, expected_type, instructions, |
| 16642 | peer_parent->peer_count); | 16695 | peer_parent->peers.length); |
| 16643 | | 16696 | |
| 16644 | // the logic below assumes there are no instructions in the new current basic block yet | 16697 | // the logic below assumes there are no instructions in the new current basic block yet |
| 16645 | ir_assert(ira->new_irb.current_basic_block->instruction_list.length == 0, &phi_instruction->base); | 16698 | ir_assert(ira->new_irb.current_basic_block->instruction_list.length == 0, &phi_instruction->base); |
| ... | @@ -16673,8 +16726,8 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh | ... | @@ -16673,8 +16726,8 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh |
| 16673 | ira_suspend(ira, &phi_instruction->base, nullptr, &suspend_pos); | 16726 | ira_suspend(ira, &phi_instruction->base, nullptr, &suspend_pos); |
| 16674 | ir_push_resume(ira, suspend_pos); | 16727 | ir_push_resume(ira, suspend_pos); |
| 16675 | | 16728 | |
| 16676 | for (size_t i = 0; i < peer_parent->peer_count; i += 1) { | 16729 | for (size_t i = 0; i < peer_parent->peers.length; i += 1) { |
| 16677 | ResultLocPeer *opposite_peer = &peer_parent->peers[peer_parent->peer_count - i - 1]; | 16730 | ResultLocPeer *opposite_peer = peer_parent->peers.at(peer_parent->peers.length - i - 1); |
| 16678 | if (opposite_peer->base.implicit_elem_type != nullptr && | 16731 | if (opposite_peer->base.implicit_elem_type != nullptr && |
| 16679 | opposite_peer->base.implicit_elem_type->id != ZigTypeIdUnreachable) | 16732 | opposite_peer->base.implicit_elem_type->id != ZigTypeIdUnreachable) |
| 16680 | { | 16733 | { |