| ... | ... | @@ -5843,13 +5843,16 @@ static bool is_u8(TypeTableEntry *type) { |
| 5843 | 5843 | !type->data.integral.is_signed && type->data.integral.bit_count == 8; |
| 5844 | 5844 | } |
| 5845 | 5845 | |
| 5846 | | static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb) { |
| 5846 | static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrInstruction *ref_old_instruction) { |
| 5847 | 5847 | assert(old_bb); |
| 5848 | 5848 | |
| 5849 | | if (old_bb->other) |
| 5850 | | return old_bb->other; |
| 5849 | if (old_bb->other) { |
| 5850 | if (ref_old_instruction == nullptr || old_bb->other->ref_instruction != ref_old_instruction) |
| 5851 | return old_bb->other; |
| 5852 | } |
| 5851 | 5853 | |
| 5852 | 5854 | IrBasicBlock *new_bb = ir_build_bb_from(&ira->new_irb, old_bb); |
| 5855 | new_bb->ref_instruction = ref_old_instruction; |
| 5853 | 5856 | |
| 5854 | 5857 | // We are about to enqueue old_bb for analysis. Before we do so, look over old_bb's |
| 5855 | 5858 | // instructions and make sure we have enqueued first the blocks which contain |
| ... | ... | @@ -5865,7 +5868,7 @@ static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb) { |
| 5865 | 5868 | continue; |
| 5866 | 5869 | if (dep_instruction->owner_bb == old_bb) |
| 5867 | 5870 | continue; |
| 5868 | | ir_get_new_bb(ira, dep_instruction->owner_bb); |
| 5871 | ir_get_new_bb(ira, dep_instruction->owner_bb, nullptr); |
| 5869 | 5872 | } |
| 5870 | 5873 | } |
| 5871 | 5874 | ira->old_bb_queue.append(old_bb); |
| ... | ... | @@ -5897,7 +5900,8 @@ static void ir_finish_bb(IrAnalyze *ira) { |
| 5897 | 5900 | |
| 5898 | 5901 | if (ira->block_queue_index < ira->old_bb_queue.length) { |
| 5899 | 5902 | IrBasicBlock *old_bb = ira->old_bb_queue.at(ira->block_queue_index); |
| 5900 | | ira->new_irb.current_basic_block = ir_get_new_bb(ira, old_bb); |
| 5903 | assert(old_bb->other); |
| 5904 | ira->new_irb.current_basic_block = old_bb->other; |
| 5901 | 5905 | |
| 5902 | 5906 | ir_start_bb(ira, old_bb, nullptr); |
| 5903 | 5907 | } |
| ... | ... | @@ -8274,7 +8278,7 @@ static TypeTableEntry *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr |
| 8274 | 8278 | if (is_comptime || old_dest_block->ref_count == 1) |
| 8275 | 8279 | return ir_inline_bb(ira, &br_instruction->base, old_dest_block); |
| 8276 | 8280 | |
| 8277 | | IrBasicBlock *new_bb = ir_get_new_bb(ira, old_dest_block); |
| 8281 | IrBasicBlock *new_bb = ir_get_new_bb(ira, old_dest_block, &br_instruction->base); |
| 8278 | 8282 | ir_build_br_from(&ira->new_irb, &br_instruction->base, new_bb); |
| 8279 | 8283 | return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); |
| 8280 | 8284 | } |
| ... | ... | @@ -8307,7 +8311,7 @@ static TypeTableEntry *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstruct |
| 8307 | 8311 | if (is_comptime || old_dest_block->ref_count == 1) |
| 8308 | 8312 | return ir_inline_bb(ira, &cond_br_instruction->base, old_dest_block); |
| 8309 | 8313 | |
| 8310 | | IrBasicBlock *new_dest_block = ir_get_new_bb(ira, old_dest_block); |
| 8314 | IrBasicBlock *new_dest_block = ir_get_new_bb(ira, old_dest_block, &cond_br_instruction->base); |
| 8311 | 8315 | ir_build_br_from(&ira->new_irb, &cond_br_instruction->base, new_dest_block); |
| 8312 | 8316 | return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); |
| 8313 | 8317 | } |
| ... | ... | @@ -8317,8 +8321,9 @@ static TypeTableEntry *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstruct |
| 8317 | 8321 | if (casted_condition == ira->codegen->invalid_instruction) |
| 8318 | 8322 | return ir_unreach_error(ira); |
| 8319 | 8323 | |
| 8320 | | IrBasicBlock *new_then_block = ir_get_new_bb(ira, cond_br_instruction->then_block); |
| 8321 | | IrBasicBlock *new_else_block = ir_get_new_bb(ira, cond_br_instruction->else_block); |
| 8324 | assert(cond_br_instruction->then_block != cond_br_instruction->else_block); |
| 8325 | IrBasicBlock *new_then_block = ir_get_new_bb(ira, cond_br_instruction->then_block, &cond_br_instruction->base); |
| 8326 | IrBasicBlock *new_else_block = ir_get_new_bb(ira, cond_br_instruction->else_block, &cond_br_instruction->base); |
| 8322 | 8327 | ir_build_cond_br_from(&ira->new_irb, &cond_br_instruction->base, |
| 8323 | 8328 | casted_condition, new_then_block, new_else_block, nullptr); |
| 8324 | 8329 | return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); |
| ... | ... | @@ -9683,7 +9688,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_br(IrAnalyze *ira, |
| 9683 | 9688 | if (is_comptime || old_dest_block->ref_count == 1) { |
| 9684 | 9689 | return ir_inline_bb(ira, &switch_br_instruction->base, old_dest_block); |
| 9685 | 9690 | } else { |
| 9686 | | IrBasicBlock *new_dest_block = ir_get_new_bb(ira, old_dest_block); |
| 9691 | IrBasicBlock *new_dest_block = ir_get_new_bb(ira, old_dest_block, &switch_br_instruction->base); |
| 9687 | 9692 | ir_build_br_from(&ira->new_irb, &switch_br_instruction->base, new_dest_block); |
| 9688 | 9693 | return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); |
| 9689 | 9694 | } |
| ... | ... | @@ -9693,9 +9698,15 @@ static TypeTableEntry *ir_analyze_instruction_switch_br(IrAnalyze *ira, |
| 9693 | 9698 | for (size_t i = 0; i < case_count; i += 1) { |
| 9694 | 9699 | IrInstructionSwitchBrCase *old_case = &switch_br_instruction->cases[i]; |
| 9695 | 9700 | IrInstructionSwitchBrCase *new_case = &cases[i]; |
| 9696 | | new_case->block = ir_get_new_bb(ira, old_case->block); |
| 9701 | new_case->block = ir_get_new_bb(ira, old_case->block, &switch_br_instruction->base); |
| 9697 | 9702 | new_case->value = ira->codegen->invalid_instruction; |
| 9698 | 9703 | |
| 9704 | // Calling ir_get_new_bb set the ref_instruction on the new basic block. |
| 9705 | // However a switch br may branch to the same basic block which would trigger an |
| 9706 | // incorrect re-generation of the block. So we set it to null here and assign |
| 9707 | // it back after the loop. |
| 9708 | new_case->block->ref_instruction = nullptr; |
| 9709 | |
| 9699 | 9710 | IrInstruction *old_value = old_case->value; |
| 9700 | 9711 | IrInstruction *new_value = old_value->other; |
| 9701 | 9712 | if (new_value->value.type->id == TypeTableEntryIdInvalid) |
| ... | ... | @@ -9717,7 +9728,12 @@ static TypeTableEntry *ir_analyze_instruction_switch_br(IrAnalyze *ira, |
| 9717 | 9728 | new_case->value = casted_new_value; |
| 9718 | 9729 | } |
| 9719 | 9730 | |
| 9720 | | IrBasicBlock *new_else_block = ir_get_new_bb(ira, switch_br_instruction->else_block); |
| 9731 | for (size_t i = 0; i < case_count; i += 1) { |
| 9732 | IrInstructionSwitchBrCase *new_case = &cases[i]; |
| 9733 | new_case->block->ref_instruction = &switch_br_instruction->base; |
| 9734 | } |
| 9735 | |
| 9736 | IrBasicBlock *new_else_block = ir_get_new_bb(ira, switch_br_instruction->else_block, &switch_br_instruction->base); |
| 9721 | 9737 | ir_build_switch_br_from(&ira->new_irb, &switch_br_instruction->base, |
| 9722 | 9738 | target_value, new_else_block, case_count, cases, nullptr); |
| 9723 | 9739 | return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); |
| ... | ... | @@ -11751,7 +11767,7 @@ TypeTableEntry *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutabl |
| 11751 | 11767 | ira->exec_context.mem_slot_list = allocate<ConstExprValue>(ira->exec_context.mem_slot_count); |
| 11752 | 11768 | |
| 11753 | 11769 | IrBasicBlock *old_entry_bb = ira->old_irb.exec->basic_block_list.at(0); |
| 11754 | | IrBasicBlock *new_entry_bb = ir_get_new_bb(ira, old_entry_bb); |
| 11770 | IrBasicBlock *new_entry_bb = ir_get_new_bb(ira, old_entry_bb, nullptr); |
| 11755 | 11771 | ir_ref_bb(new_entry_bb); |
| 11756 | 11772 | ira->new_irb.current_basic_block = new_entry_bb; |
| 11757 | 11773 | ira->block_queue_index = 0; |