| ... | ... | @@ -6958,6 +6958,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6958 | 6958 | peer_parent->peers = allocate<ResultLocPeer>(prong_count); |
| 6959 | 6959 | peer_parent->peer_count = 0; |
| 6960 | 6960 | |
| 6961 | ir_build_reset_result(irb, scope, node, &peer_parent->base); |
| 6962 | |
| 6961 | 6963 | // First do the else and the ranges |
| 6962 | 6964 | Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); |
| 6963 | 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 | 7119 | IrInstruction *switch_prongs_void = ir_build_check_switch_prongs(irb, scope, node, target_value, |
| 7118 | 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 | 7122 | IrInstruction *br_instruction; |
| 7123 | 7123 | if (cases.length == 0) { |
| 7124 | 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 | 10880 | } |
| 10881 | 10881 | |
| 10882 | 10882 | static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *const_predecessor_bb) { |
| 10883 | assert(!old_bb->suspended); |
| 10883 | 10884 | ira->instruction_index = 0; |
| 10884 | 10885 | ira->old_irb.current_basic_block = old_bb; |
| 10885 | 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 | 10890 | static IrInstruction *ira_suspend(IrAnalyze *ira, IrInstruction *old_instruction, IrBasicBlock *next_bb, |
| 10890 | 10891 | IrSuspendPosition *suspend_pos) |
| 10891 | 10892 | { |
| 10892 | | // reserve block position |
| 10893 | | if (!ira->new_irb.current_basic_block->already_appended) { |
| 10894 | | ira->new_irb.current_basic_block->already_appended = true; |
| 10895 | | ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block); |
| 10893 | if (ira->codegen->verbose_ir) { |
| 10894 | fprintf(stderr, "suspend %s_%zu %s_%zu #%zu (%zu,%zu)\n", ira->old_irb.current_basic_block->name_hint, |
| 10895 | ira->old_irb.current_basic_block->debug_id, |
| 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 | 10901 | suspend_pos->basic_block_index = ira->old_bb_index; |
| 10907 | 10902 | suspend_pos->instruction_index = ira->instruction_index; |
| 10908 | 10903 | |
| ... | ... | @@ -10923,19 +10918,21 @@ static IrInstruction *ira_suspend(IrAnalyze *ira, IrInstruction *old_instruction |
| 10923 | 10918 | |
| 10924 | 10919 | static IrInstruction *ira_resume(IrAnalyze *ira) { |
| 10925 | 10920 | IrSuspendPosition pos = ira->resume_stack.pop(); |
| 10926 | | //if (ira->codegen->verbose_ir) { |
| 10927 | | // fprintf(stderr, "resume (%zu,%zu) ", pos.basic_block_index, pos.instruction_index); |
| 10928 | | //} |
| 10921 | if (ira->codegen->verbose_ir) { |
| 10922 | fprintf(stderr, "resume (%zu,%zu) ", pos.basic_block_index, pos.instruction_index); |
| 10923 | } |
| 10929 | 10924 | ira->old_bb_index = pos.basic_block_index; |
| 10930 | 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 | 10928 | ira->old_irb.current_basic_block->suspended = false; |
| 10932 | 10929 | ira->instruction_index = pos.instruction_index; |
| 10933 | 10930 | assert(pos.instruction_index < ira->old_irb.current_basic_block->instruction_list.length); |
| 10934 | | //if (ira->codegen->verbose_ir) { |
| 10935 | | // fprintf(stderr, "%s_%zu #%zu\n", ira->old_irb.current_basic_block->name_hint, |
| 10936 | | // ira->old_irb.current_basic_block->debug_id, |
| 10937 | | // ira->old_irb.current_basic_block->instruction_list.at(pos.instruction_index)->debug_id); |
| 10938 | | //} |
| 10931 | if (ira->codegen->verbose_ir) { |
| 10932 | fprintf(stderr, "%s_%zu #%zu\n", ira->old_irb.current_basic_block->name_hint, |
| 10933 | ira->old_irb.current_basic_block->debug_id, |
| 10934 | ira->old_irb.current_basic_block->instruction_list.at(pos.instruction_index)->debug_id); |
| 10935 | } |
| 10939 | 10936 | ira->const_predecessor_bb = nullptr; |
| 10940 | 10937 | ira->new_irb.current_basic_block = ira->old_irb.current_basic_block->other; |
| 10941 | 10938 | assert(ira->new_irb.current_basic_block != nullptr); |
| ... | ... | @@ -10945,6 +10942,10 @@ static IrInstruction *ira_resume(IrAnalyze *ira) { |
| 10945 | 10942 | static void ir_finish_bb(IrAnalyze *ira) { |
| 10946 | 10943 | if (!ira->new_irb.current_basic_block->already_appended) { |
| 10947 | 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 | 10949 | ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block); |
| 10949 | 10950 | } |
| 10950 | 10951 | ira->instruction_index += 1; |
| ... | ... | @@ -10957,7 +10958,6 @@ static void ir_finish_bb(IrAnalyze *ira) { |
| 10957 | 10958 | ira->instruction_index += 1; |
| 10958 | 10959 | } |
| 10959 | 10960 | |
| 10960 | | size_t my_old_bb_index = ira->old_bb_index; |
| 10961 | 10961 | ira->old_bb_index += 1; |
| 10962 | 10962 | |
| 10963 | 10963 | bool need_repeat = true; |
| ... | ... | @@ -10968,17 +10968,17 @@ static void ir_finish_bb(IrAnalyze *ira) { |
| 10968 | 10968 | ira->old_bb_index += 1; |
| 10969 | 10969 | continue; |
| 10970 | 10970 | } |
| 10971 | | // If it's the block we just finished, or |
| 10972 | | // if it's already a finished block, or |
| 10971 | // if it's already started, or |
| 10973 | 10972 | // if it's a suspended block, |
| 10974 | 10973 | // then skip it |
| 10975 | | if (ira->old_bb_index == my_old_bb_index || |
| 10976 | | old_bb->suspended || |
| 10977 | | (old_bb->other != nullptr && old_bb->other->instruction_list.length != 0)) |
| 10974 | if (old_bb->suspended || |
| 10975 | (old_bb->other != nullptr && old_bb->other->instruction_list.length != 0) || |
| 10976 | (old_bb->other != nullptr && old_bb->other->already_appended)) |
| 10978 | 10977 | { |
| 10979 | 10978 | ira->old_bb_index += 1; |
| 10980 | 10979 | continue; |
| 10981 | 10980 | } |
| 10981 | |
| 10982 | 10982 | // if there is a resume_stack, pop one from there rather than moving on. |
| 10983 | 10983 | // the last item of the resume stack will be a basic block that will |
| 10984 | 10984 | // move on to the next one below |
| ... | ... | @@ -15520,7 +15520,9 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source |
| 15520 | 15520 | // ConstPtrMutComptimeVar, thus defeating the logic below. |
| 15521 | 15521 | bool same_global_refs = ptr->value.data.x_ptr.mut != ConstPtrMutComptimeVar; |
| 15522 | 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 | 15526 | ira->new_irb.current_basic_block->must_be_comptime_source_instr = source_instr; |
| 15525 | 15527 | } |
| 15526 | 15528 | return ir_const_void(ira, source_instr); |
| ... | ... | @@ -16484,6 +16486,19 @@ static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstruction |
| 16484 | 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 | 16502 | static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr *br_instruction) { |
| 16488 | 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 | 16513 | if (new_bb == nullptr) |
| 16499 | 16514 | return ir_unreach_error(ira); |
| 16500 | 16515 | |
| 16516 | ir_push_resume_block(ira, old_dest_block); |
| 16517 | |
| 16501 | 16518 | IrInstruction *result = ir_build_br(&ira->new_irb, |
| 16502 | 16519 | br_instruction->base.scope, br_instruction->base.source_node, new_bb, nullptr); |
| 16503 | 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 | 16543 | IrBasicBlock *old_dest_block = cond_is_true ? |
| 16527 | 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 | 16547 | return ir_inline_bb(ira, &cond_br_instruction->base, old_dest_block); |
| 16531 | 16548 | |
| 16532 | 16549 | IrBasicBlock *new_dest_block = ir_get_new_bb_runtime(ira, old_dest_block, &cond_br_instruction->base); |
| 16533 | 16550 | if (new_dest_block == nullptr) |
| 16534 | 16551 | return ir_unreach_error(ira); |
| 16535 | 16552 | |
| 16553 | ir_push_resume_block(ira, old_dest_block); |
| 16554 | |
| 16536 | 16555 | IrInstruction *result = ir_build_br(&ira->new_irb, |
| 16537 | 16556 | cond_br_instruction->base.scope, cond_br_instruction->base.source_node, new_dest_block, nullptr); |
| 16538 | 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 | 16567 | if (new_else_block == nullptr) |
| 16549 | 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 | 16573 | IrInstruction *result = ir_build_cond_br(&ira->new_irb, |
| 16552 | 16574 | cond_br_instruction->base.scope, cond_br_instruction->base.source_node, |
| 16553 | 16575 | casted_condition, new_then_block, new_else_block, nullptr); |
| ... | ... | @@ -16643,14 +16665,14 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh |
| 16643 | 16665 | |
| 16644 | 16666 | IrSuspendPosition suspend_pos; |
| 16645 | 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 | 16670 | for (size_t i = 0; i < peer_parent->peer_count; i += 1) { |
| 16649 | 16671 | ResultLocPeer *opposite_peer = &peer_parent->peers[peer_parent->peer_count - i - 1]; |
| 16650 | 16672 | if (opposite_peer->base.implicit_elem_type != nullptr && |
| 16651 | 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 | 25039 | continue; |
| 25018 | 25040 | } |
| 25019 | 25041 | |
| 25020 | | //if (ira->codegen->verbose_ir) { |
| 25021 | | // fprintf(stderr, "analyze #%zu\n", old_instruction->debug_id); |
| 25022 | | //} |
| 25042 | if (ira->codegen->verbose_ir) { |
| 25043 | fprintf(stderr, "analyze #%zu\n", old_instruction->debug_id); |
| 25044 | } |
| 25023 | 25045 | IrInstruction *new_instruction = ir_analyze_instruction_base(ira, old_instruction); |
| 25024 | 25046 | if (new_instruction != nullptr) { |
| 25025 | 25047 | ir_assert(new_instruction->value.type != nullptr || new_instruction->value.type != nullptr, old_instruction); |