| ... | ... | @@ -26,6 +26,7 @@ struct IrAnalyze { |
| 26 | 26 | size_t instruction_index; |
| 27 | 27 | TypeTableEntry *explicit_return_type; |
| 28 | 28 | ZigList<IrInstruction *> implicit_return_type_list; |
| 29 | IrBasicBlock *const_predecessor_bb; |
| 29 | 30 | }; |
| 30 | 31 | |
| 31 | 32 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, BlockContext *scope); |
| ... | ... | @@ -397,6 +398,8 @@ static IrInstruction *ir_build_phi_from(IrBuilder *irb, IrInstruction *old_instr |
| 397 | 398 | |
| 398 | 399 | static IrInstruction *ir_build_br(IrBuilder *irb, AstNode *source_node, IrBasicBlock *dest_block) { |
| 399 | 400 | IrInstructionBr *br_instruction = ir_build_instruction<IrInstructionBr>(irb, source_node); |
| 401 | br_instruction->base.type_entry = irb->codegen->builtin_types.entry_unreachable; |
| 402 | br_instruction->base.static_value.ok = true; |
| 400 | 403 | br_instruction->dest_block = dest_block; |
| 401 | 404 | |
| 402 | 405 | ir_ref_bb(dest_block); |
| ... | ... | @@ -1618,12 +1621,13 @@ static void ir_finish_bb(IrAnalyze *ira) { |
| 1618 | 1621 | ira->instruction_index = 0; |
| 1619 | 1622 | ira->new_irb.current_basic_block = ir_get_new_bb(ira, old_bb); |
| 1620 | 1623 | ira->old_irb.current_basic_block = old_bb; |
| 1624 | ira->const_predecessor_bb = nullptr; |
| 1621 | 1625 | } |
| 1622 | 1626 | } |
| 1623 | 1627 | |
| 1624 | 1628 | static void ir_inline_bb(IrAnalyze *ira, IrBasicBlock *old_bb) { |
| 1625 | 1629 | ira->instruction_index = 0; |
| 1626 | | |
| 1630 | ira->const_predecessor_bb = ira->old_irb.current_basic_block; |
| 1627 | 1631 | ira->old_irb.current_basic_block = old_bb; |
| 1628 | 1632 | } |
| 1629 | 1633 | |
| ... | ... | @@ -2470,7 +2474,10 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction |
| 2470 | 2474 | |
| 2471 | 2475 | ir_build_call_from(&ira->new_irb, &call_instruction->base, |
| 2472 | 2476 | call_instruction->fn, call_instruction->arg_count, call_instruction->args); |
| 2473 | | return fn_table_entry->type_entry; |
| 2477 | |
| 2478 | TypeTableEntry *fn_type = fn_table_entry->type_entry; |
| 2479 | TypeTableEntry *return_type = fn_type->data.fn.fn_type_id.return_type; |
| 2480 | return return_type; |
| 2474 | 2481 | } else { |
| 2475 | 2482 | zig_panic("TODO analyze more fn call types"); |
| 2476 | 2483 | } |
| ... | ... | @@ -3946,6 +3953,24 @@ static TypeTableEntry *ir_analyze_instruction_unreachable(IrAnalyze *ira, |
| 3946 | 3953 | } |
| 3947 | 3954 | |
| 3948 | 3955 | static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPhi *phi_instruction) { |
| 3956 | if (ira->const_predecessor_bb) { |
| 3957 | for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) { |
| 3958 | IrBasicBlock *predecessor = phi_instruction->incoming_blocks[i]; |
| 3959 | if (predecessor != ira->const_predecessor_bb) |
| 3960 | continue; |
| 3961 | IrInstruction *value = phi_instruction->incoming_values[i]->other; |
| 3962 | assert(value->type_entry); |
| 3963 | if (value->static_value.ok) { |
| 3964 | ConstExprValue *out_val = ir_get_out_val(&phi_instruction->base); |
| 3965 | *out_val = value->static_value; |
| 3966 | } else { |
| 3967 | phi_instruction->base.other = value; |
| 3968 | } |
| 3969 | return value->type_entry; |
| 3970 | } |
| 3971 | zig_unreachable(); |
| 3972 | } |
| 3973 | |
| 3949 | 3974 | ZigList<IrBasicBlock*> new_incoming_blocks = {0}; |
| 3950 | 3975 | ZigList<IrInstruction*> new_incoming_values = {0}; |
| 3951 | 3976 | |
| ... | ... | @@ -4094,6 +4119,8 @@ static TypeTableEntry *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *ins |
| 4094 | 4119 | { |
| 4095 | 4120 | TypeTableEntry *instruction_type = ir_analyze_instruction_nocast(ira, instruction); |
| 4096 | 4121 | instruction->type_entry = instruction_type; |
| 4122 | if (instruction->other) |
| 4123 | instruction->other->type_entry = instruction_type; |
| 4097 | 4124 | |
| 4098 | 4125 | IrInstruction *casted_instruction = ir_get_casted_value(ira, instruction, expected_type); |
| 4099 | 4126 | return casted_instruction->type_entry; |
| ... | ... | @@ -4128,6 +4155,11 @@ TypeTableEntry *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutabl |
| 4128 | 4155 | |
| 4129 | 4156 | while (ira->block_queue_index < ira->block_queue.length) { |
| 4130 | 4157 | IrInstruction *old_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); |
| 4158 | if (old_instruction->ref_count == 0 && !ir_has_side_effects(old_instruction)) { |
| 4159 | ira->instruction_index += 1; |
| 4160 | continue; |
| 4161 | } |
| 4162 | |
| 4131 | 4163 | TypeTableEntry *return_type = ir_analyze_instruction(ira, old_instruction, nullptr); |
| 4132 | 4164 | |
| 4133 | 4165 | // unreachable instructions do their own control flow. |