| ... | @@ -6958,6 +6958,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6958,6 +6958,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6958 | peer_parent->peers = allocate<ResultLocPeer>(prong_count); | 6958 | peer_parent->peers = allocate<ResultLocPeer>(prong_count); |
| 6959 | peer_parent->peer_count = 0; | 6959 | peer_parent->peer_count = 0; |
| 6960 | | 6960 | |
| | 6961 | ir_build_reset_result(irb, scope, node, &peer_parent->base); |
| | 6962 | |
| 6961 | // First do the else and the ranges | 6963 | // First do the else and the ranges |
| 6962 | Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); | 6964 | Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); |
| 6963 | Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); | 6965 | Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); |
| ... | @@ -7117,8 +7119,6 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -7117,8 +7119,6 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 7117 | IrInstruction *switch_prongs_void = ir_build_check_switch_prongs(irb, scope, node, target_value, | 7119 | IrInstruction *switch_prongs_void = ir_build_check_switch_prongs(irb, scope, node, target_value, |
| 7118 | check_ranges.items, check_ranges.length, else_prong != nullptr); | 7120 | check_ranges.items, check_ranges.length, else_prong != nullptr); |
| 7119 | | 7121 | |
| 7120 | ir_build_reset_result(irb, scope, node, &peer_parent->base); | | |
| 7121 | | | |
| 7122 | IrInstruction *br_instruction; | 7122 | IrInstruction *br_instruction; |
| 7123 | if (cases.length == 0) { | 7123 | if (cases.length == 0) { |
| 7124 | br_instruction = ir_build_br(irb, scope, node, else_block, is_comptime); | 7124 | br_instruction = ir_build_br(irb, scope, node, else_block, is_comptime); |
| ... | @@ -10880,6 +10880,7 @@ static IrBasicBlock *ir_get_new_bb_runtime(IrAnalyze *ira, IrBasicBlock *old_bb, | ... | @@ -10880,6 +10880,7 @@ static IrBasicBlock *ir_get_new_bb_runtime(IrAnalyze *ira, IrBasicBlock *old_bb, |
| 10880 | } | 10880 | } |
| 10881 | | 10881 | |
| 10882 | static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *const_predecessor_bb) { | 10882 | static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *const_predecessor_bb) { |
| | 10883 | assert(!old_bb->suspended); |
| 10883 | ira->instruction_index = 0; | 10884 | ira->instruction_index = 0; |
| 10884 | ira->old_irb.current_basic_block = old_bb; | 10885 | ira->old_irb.current_basic_block = old_bb; |
| 10885 | ira->const_predecessor_bb = const_predecessor_bb; | 10886 | ira->const_predecessor_bb = const_predecessor_bb; |
| ... | @@ -10889,20 +10890,14 @@ static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *cons | ... | @@ -10889,20 +10890,14 @@ static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *cons |
| 10889 | static IrInstruction *ira_suspend(IrAnalyze *ira, IrInstruction *old_instruction, IrBasicBlock *next_bb, | 10890 | static IrInstruction *ira_suspend(IrAnalyze *ira, IrInstruction *old_instruction, IrBasicBlock *next_bb, |
| 10890 | IrSuspendPosition *suspend_pos) | 10891 | IrSuspendPosition *suspend_pos) |
| 10891 | { | 10892 | { |
| 10892 | // reserve block position | 10893 | if (ira->codegen->verbose_ir) { |
| 10893 | if (!ira->new_irb.current_basic_block->already_appended) { | 10894 | fprintf(stderr, "suspend %s_%zu %s_%zu #%zu (%zu,%zu)\n", ira->old_irb.current_basic_block->name_hint, |
| 10894 | ira->new_irb.current_basic_block->already_appended = true; | 10895 | ira->old_irb.current_basic_block->debug_id, |
| 10895 | ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block); | 10896 | ira->old_irb.exec->basic_block_list.at(ira->old_bb_index)->name_hint, |
| | 10897 | ira->old_irb.exec->basic_block_list.at(ira->old_bb_index)->debug_id, |
| | 10898 | ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index)->debug_id, |
| | 10899 | ira->old_bb_index, ira->instruction_index); |
| 10896 | } | 10900 | } |
| 10897 | | | |
| 10898 | //if (ira->codegen->verbose_ir) { | | |
| 10899 | // fprintf(stderr, "suspend %s_%zu %s_%zu #%zu (%zu,%zu)\n", ira->old_irb.current_basic_block->name_hint, | | |
| 10900 | // ira->old_irb.current_basic_block->debug_id, | | |
| 10901 | // ira->old_irb.exec->basic_block_list.at(ira->old_bb_index)->name_hint, | | |
| 10902 | // ira->old_irb.exec->basic_block_list.at(ira->old_bb_index)->debug_id, | | |
| 10903 | // ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index)->debug_id, | | |
| 10904 | // ira->old_bb_index, ira->instruction_index); | | |
| 10905 | //} | | |
| 10906 | suspend_pos->basic_block_index = ira->old_bb_index; | 10901 | suspend_pos->basic_block_index = ira->old_bb_index; |
| 10907 | suspend_pos->instruction_index = ira->instruction_index; | 10902 | suspend_pos->instruction_index = ira->instruction_index; |
| 10908 | | 10903 | |
| ... | @@ -10923,19 +10918,21 @@ static IrInstruction *ira_suspend(IrAnalyze *ira, IrInstruction *old_instruction | ... | @@ -10923,19 +10918,21 @@ static IrInstruction *ira_suspend(IrAnalyze *ira, IrInstruction *old_instruction |
| 10923 | | 10918 | |
| 10924 | static IrInstruction *ira_resume(IrAnalyze *ira) { | 10919 | static IrInstruction *ira_resume(IrAnalyze *ira) { |
| 10925 | IrSuspendPosition pos = ira->resume_stack.pop(); | 10920 | IrSuspendPosition pos = ira->resume_stack.pop(); |
| 10926 | //if (ira->codegen->verbose_ir) { | 10921 | if (ira->codegen->verbose_ir) { |
| 10927 | // fprintf(stderr, "resume (%zu,%zu) ", pos.basic_block_index, pos.instruction_index); | 10922 | fprintf(stderr, "resume (%zu,%zu) ", pos.basic_block_index, pos.instruction_index); |
| 10928 | //} | 10923 | } |
| 10929 | ira->old_bb_index = pos.basic_block_index; | 10924 | ira->old_bb_index = pos.basic_block_index; |
| 10930 | ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); | 10925 | ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); |
| | 10926 | assert(ira->old_irb.current_basic_block->in_resume_stack); |
| | 10927 | ira->old_irb.current_basic_block->in_resume_stack = false; |
| 10931 | ira->old_irb.current_basic_block->suspended = false; | 10928 | ira->old_irb.current_basic_block->suspended = false; |
| 10932 | ira->instruction_index = pos.instruction_index; | 10929 | ira->instruction_index = pos.instruction_index; |
| 10933 | assert(pos.instruction_index < ira->old_irb.current_basic_block->instruction_list.length); | 10930 | assert(pos.instruction_index < ira->old_irb.current_basic_block->instruction_list.length); |
| 10934 | //if (ira->codegen->verbose_ir) { | 10931 | if (ira->codegen->verbose_ir) { |
| 10935 | // fprintf(stderr, "%s_%zu #%zu\n", ira->old_irb.current_basic_block->name_hint, | 10932 | fprintf(stderr, "%s_%zu #%zu\n", ira->old_irb.current_basic_block->name_hint, |
| 10936 | // ira->old_irb.current_basic_block->debug_id, | 10933 | ira->old_irb.current_basic_block->debug_id, |
| 10937 | // ira->old_irb.current_basic_block->instruction_list.at(pos.instruction_index)->debug_id); | 10934 | ira->old_irb.current_basic_block->instruction_list.at(pos.instruction_index)->debug_id); |
| 10938 | //} | 10935 | } |
| 10939 | ira->const_predecessor_bb = nullptr; | 10936 | ira->const_predecessor_bb = nullptr; |
| 10940 | ira->new_irb.current_basic_block = ira->old_irb.current_basic_block->other; | 10937 | ira->new_irb.current_basic_block = ira->old_irb.current_basic_block->other; |
| 10941 | assert(ira->new_irb.current_basic_block != nullptr); | 10938 | assert(ira->new_irb.current_basic_block != nullptr); |
| ... | @@ -10945,6 +10942,10 @@ static IrInstruction *ira_resume(IrAnalyze *ira) { | ... | @@ -10945,6 +10942,10 @@ static IrInstruction *ira_resume(IrAnalyze *ira) { |
| 10945 | static void ir_finish_bb(IrAnalyze *ira) { | 10942 | static void ir_finish_bb(IrAnalyze *ira) { |
| 10946 | if (!ira->new_irb.current_basic_block->already_appended) { | 10943 | if (!ira->new_irb.current_basic_block->already_appended) { |
| 10947 | ira->new_irb.current_basic_block->already_appended = true; | 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 | } |
| 10948 | ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block); | 10949 | ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block); |
| 10949 | } | 10950 | } |
| 10950 | ira->instruction_index += 1; | 10951 | ira->instruction_index += 1; |
| ... | @@ -10957,7 +10958,6 @@ static void ir_finish_bb(IrAnalyze *ira) { | ... | @@ -10957,7 +10958,6 @@ static void ir_finish_bb(IrAnalyze *ira) { |
| 10957 | ira->instruction_index += 1; | 10958 | ira->instruction_index += 1; |
| 10958 | } | 10959 | } |
| 10959 | | 10960 | |
| 10960 | size_t my_old_bb_index = ira->old_bb_index; | | |
| 10961 | ira->old_bb_index += 1; | 10961 | ira->old_bb_index += 1; |
| 10962 | | 10962 | |
| 10963 | bool need_repeat = true; | 10963 | bool need_repeat = true; |
| ... | @@ -10968,17 +10968,17 @@ static void ir_finish_bb(IrAnalyze *ira) { | ... | @@ -10968,17 +10968,17 @@ static void ir_finish_bb(IrAnalyze *ira) { |
| 10968 | ira->old_bb_index += 1; | 10968 | ira->old_bb_index += 1; |
| 10969 | continue; | 10969 | continue; |
| 10970 | } | 10970 | } |
| 10971 | // If it's the block we just finished, or | 10971 | // if it's already started, or |
| 10972 | // if it's already a finished block, or | | |
| 10973 | // if it's a suspended block, | 10972 | // if it's a suspended block, |
| 10974 | // then skip it | 10973 | // then skip it |
| 10975 | if (ira->old_bb_index == my_old_bb_index || | 10974 | if (old_bb->suspended || |
| 10976 | old_bb->suspended || | 10975 | (old_bb->other != nullptr && old_bb->other->instruction_list.length != 0) || |
| 10977 | (old_bb->other != nullptr && old_bb->other->instruction_list.length != 0)) | 10976 | (old_bb->other != nullptr && old_bb->other->already_appended)) |
| 10978 | { | 10977 | { |
| 10979 | ira->old_bb_index += 1; | 10978 | ira->old_bb_index += 1; |
| 10980 | continue; | 10979 | continue; |
| 10981 | } | 10980 | } |
| | 10981 | |
| 10982 | // if there is a resume_stack, pop one from there rather than moving on. | 10982 | // if there is a resume_stack, pop one from there rather than moving on. |
| 10983 | // the last item of the resume stack will be a basic block that will | 10983 | // the last item of the resume stack will be a basic block that will |
| 10984 | // move on to the next one below | 10984 | // move on to the next one below |
| ... | @@ -15520,7 +15520,9 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source | ... | @@ -15520,7 +15520,9 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source |
| 15520 | // ConstPtrMutComptimeVar, thus defeating the logic below. | 15520 | // ConstPtrMutComptimeVar, thus defeating the logic below. |
| 15521 | bool same_global_refs = ptr->value.data.x_ptr.mut != ConstPtrMutComptimeVar; | 15521 | bool same_global_refs = ptr->value.data.x_ptr.mut != ConstPtrMutComptimeVar; |
| 15522 | copy_const_val(dest_val, &value->value, same_global_refs); | 15522 | copy_const_val(dest_val, &value->value, same_global_refs); |
| 15523 | if (!ira->new_irb.current_basic_block->must_be_comptime_source_instr) { | 15523 | if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar && |
| | 15524 | !ira->new_irb.current_basic_block->must_be_comptime_source_instr) |
| | 15525 | { |
| 15524 | ira->new_irb.current_basic_block->must_be_comptime_source_instr = source_instr; | 15526 | ira->new_irb.current_basic_block->must_be_comptime_source_instr = source_instr; |
| 15525 | } | 15527 | } |
| 15526 | return ir_const_void(ira, source_instr); | 15528 | return ir_const_void(ira, source_instr); |
| ... | @@ -16484,6 +16486,19 @@ static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstruction | ... | @@ -16484,6 +16486,19 @@ static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstruction |
| 16484 | zig_unreachable(); | 16486 | zig_unreachable(); |
| 16485 | } | 16487 | } |
| 16486 | | 16488 | |
| | 16489 | static void ir_push_resume(IrAnalyze *ira, IrSuspendPosition pos) { |
| | 16490 | IrBasicBlock *old_bb = ira->old_irb.exec->basic_block_list.at(pos.basic_block_index); |
| | 16491 | if (old_bb->in_resume_stack) return; |
| | 16492 | ira->resume_stack.append(pos); |
| | 16493 | old_bb->in_resume_stack = true; |
| | 16494 | } |
| | 16495 | |
| | 16496 | static void ir_push_resume_block(IrAnalyze *ira, IrBasicBlock *old_bb) { |
| | 16497 | if (ira->resume_stack.length != 0) { |
| | 16498 | ir_push_resume(ira, {old_bb->index, 0}); |
| | 16499 | } |
| | 16500 | } |
| | 16501 | |
| 16487 | static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr *br_instruction) { | 16502 | static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr *br_instruction) { |
| 16488 | IrBasicBlock *old_dest_block = br_instruction->dest_block; | 16503 | IrBasicBlock *old_dest_block = br_instruction->dest_block; |
| 16489 | | 16504 | |
| ... | @@ -16498,6 +16513,8 @@ static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr | ... | @@ -16498,6 +16513,8 @@ static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr |
| 16498 | if (new_bb == nullptr) | 16513 | if (new_bb == nullptr) |
| 16499 | return ir_unreach_error(ira); | 16514 | return ir_unreach_error(ira); |
| 16500 | | 16515 | |
| | 16516 | ir_push_resume_block(ira, old_dest_block); |
| | 16517 | |
| 16501 | IrInstruction *result = ir_build_br(&ira->new_irb, | 16518 | IrInstruction *result = ir_build_br(&ira->new_irb, |
| 16502 | br_instruction->base.scope, br_instruction->base.source_node, new_bb, nullptr); | 16519 | br_instruction->base.scope, br_instruction->base.source_node, new_bb, nullptr); |
| 16503 | result->value.type = ira->codegen->builtin_types.entry_unreachable; | 16520 | result->value.type = ira->codegen->builtin_types.entry_unreachable; |
| ... | @@ -16526,13 +16543,15 @@ static IrInstruction *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructi | ... | @@ -16526,13 +16543,15 @@ static IrInstruction *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructi |
| 16526 | IrBasicBlock *old_dest_block = cond_is_true ? | 16543 | IrBasicBlock *old_dest_block = cond_is_true ? |
| 16527 | cond_br_instruction->then_block : cond_br_instruction->else_block; | 16544 | cond_br_instruction->then_block : cond_br_instruction->else_block; |
| 16528 | | 16545 | |
| 16529 | if (is_comptime || old_dest_block->ref_count == 1) | 16546 | if (is_comptime || (old_dest_block->ref_count == 1 && old_dest_block->suspend_instruction_ref == nullptr)) |
| 16530 | return ir_inline_bb(ira, &cond_br_instruction->base, old_dest_block); | 16547 | return ir_inline_bb(ira, &cond_br_instruction->base, old_dest_block); |
| 16531 | | 16548 | |
| 16532 | IrBasicBlock *new_dest_block = ir_get_new_bb_runtime(ira, old_dest_block, &cond_br_instruction->base); | 16549 | IrBasicBlock *new_dest_block = ir_get_new_bb_runtime(ira, old_dest_block, &cond_br_instruction->base); |
| 16533 | if (new_dest_block == nullptr) | 16550 | if (new_dest_block == nullptr) |
| 16534 | return ir_unreach_error(ira); | 16551 | return ir_unreach_error(ira); |
| 16535 | | 16552 | |
| | 16553 | ir_push_resume_block(ira, old_dest_block); |
| | 16554 | |
| 16536 | IrInstruction *result = ir_build_br(&ira->new_irb, | 16555 | IrInstruction *result = ir_build_br(&ira->new_irb, |
| 16537 | cond_br_instruction->base.scope, cond_br_instruction->base.source_node, new_dest_block, nullptr); | 16556 | cond_br_instruction->base.scope, cond_br_instruction->base.source_node, new_dest_block, nullptr); |
| 16538 | result->value.type = ira->codegen->builtin_types.entry_unreachable; | 16557 | result->value.type = ira->codegen->builtin_types.entry_unreachable; |
| ... | @@ -16548,6 +16567,9 @@ static IrInstruction *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructi | ... | @@ -16548,6 +16567,9 @@ static IrInstruction *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructi |
| 16548 | if (new_else_block == nullptr) | 16567 | if (new_else_block == nullptr) |
| 16549 | return ir_unreach_error(ira); | 16568 | return ir_unreach_error(ira); |
| 16550 | | 16569 | |
| | 16570 | ir_push_resume_block(ira, cond_br_instruction->else_block); |
| | 16571 | ir_push_resume_block(ira, cond_br_instruction->then_block); |
| | 16572 | |
| 16551 | IrInstruction *result = ir_build_cond_br(&ira->new_irb, | 16573 | IrInstruction *result = ir_build_cond_br(&ira->new_irb, |
| 16552 | cond_br_instruction->base.scope, cond_br_instruction->base.source_node, | 16574 | cond_br_instruction->base.scope, cond_br_instruction->base.source_node, |
| 16553 | casted_condition, new_then_block, new_else_block, nullptr); | 16575 | casted_condition, new_then_block, new_else_block, nullptr); |
| ... | @@ -16643,14 +16665,14 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh | ... | @@ -16643,14 +16665,14 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh |
| 16643 | | 16665 | |
| 16644 | IrSuspendPosition suspend_pos; | 16666 | IrSuspendPosition suspend_pos; |
| 16645 | ira_suspend(ira, &phi_instruction->base, nullptr, &suspend_pos); | 16667 | ira_suspend(ira, &phi_instruction->base, nullptr, &suspend_pos); |
| 16646 | ira->resume_stack.append(suspend_pos); | 16668 | ir_push_resume(ira, suspend_pos); |
| 16647 | | 16669 | |
| 16648 | for (size_t i = 0; i < peer_parent->peer_count; i += 1) { | 16670 | for (size_t i = 0; i < peer_parent->peer_count; i += 1) { |
| 16649 | ResultLocPeer *opposite_peer = &peer_parent->peers[peer_parent->peer_count - i - 1]; | 16671 | ResultLocPeer *opposite_peer = &peer_parent->peers[peer_parent->peer_count - i - 1]; |
| 16650 | if (opposite_peer->base.implicit_elem_type != nullptr && | 16672 | if (opposite_peer->base.implicit_elem_type != nullptr && |
| 16651 | opposite_peer->base.implicit_elem_type->id != ZigTypeIdUnreachable) | 16673 | opposite_peer->base.implicit_elem_type->id != ZigTypeIdUnreachable) |
| 16652 | { | 16674 | { |
| 16653 | ira->resume_stack.append(opposite_peer->suspend_pos); | 16675 | ir_push_resume(ira, opposite_peer->suspend_pos); |
| 16654 | } | 16676 | } |
| 16655 | } | 16677 | } |
| 16656 | | 16678 | |
| ... | @@ -25017,9 +25039,9 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ | ... | @@ -25017,9 +25039,9 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ |
| 25017 | continue; | 25039 | continue; |
| 25018 | } | 25040 | } |
| 25019 | | 25041 | |
| 25020 | //if (ira->codegen->verbose_ir) { | 25042 | if (ira->codegen->verbose_ir) { |
| 25021 | // fprintf(stderr, "analyze #%zu\n", old_instruction->debug_id); | 25043 | fprintf(stderr, "analyze #%zu\n", old_instruction->debug_id); |
| 25022 | //} | 25044 | } |
| 25023 | IrInstruction *new_instruction = ir_analyze_instruction_base(ira, old_instruction); | 25045 | IrInstruction *new_instruction = ir_analyze_instruction_base(ira, old_instruction); |
| 25024 | if (new_instruction != nullptr) { | 25046 | if (new_instruction != nullptr) { |
| 25025 | ir_assert(new_instruction->value.type != nullptr || new_instruction->value.type != nullptr, old_instruction); | 25047 | ir_assert(new_instruction->value.type != nullptr || new_instruction->value.type != nullptr, old_instruction); |