| ... | ... | @@ -2957,8 +2957,24 @@ static void ir_finish_bb(IrAnalyze *ira) { |
| 2957 | 2957 | } |
| 2958 | 2958 | } |
| 2959 | 2959 | |
| 2960 | | static void ir_inline_bb(IrAnalyze *ira, IrBasicBlock *old_bb) { |
| 2960 | static TypeTableEntry *ir_unreach_error(IrAnalyze *ira) { |
| 2961 | ira->block_queue_index = SIZE_MAX; |
| 2962 | ira->new_irb.exec->invalid = true; |
| 2963 | return ira->codegen->builtin_types.entry_unreachable; |
| 2964 | } |
| 2965 | |
| 2966 | static TypeTableEntry *ir_inline_bb(IrAnalyze *ira, IrInstruction *source_instruction, IrBasicBlock *old_bb) { |
| 2967 | if (old_bb->debug_id <= ira->old_irb.current_basic_block->debug_id) { |
| 2968 | ira->new_irb.exec->backward_branch_count += 1; |
| 2969 | if (ira->new_irb.exec->backward_branch_count > ira->new_irb.exec->backward_branch_quota) { |
| 2970 | add_node_error(ira->codegen, source_instruction->source_node, |
| 2971 | buf_sprintf("evaluation exceeded %zu backwards branches", ira->new_irb.exec->backward_branch_quota)); |
| 2972 | return ir_unreach_error(ira); |
| 2973 | } |
| 2974 | } |
| 2975 | |
| 2961 | 2976 | ir_start_bb(ira, old_bb, ira->old_irb.current_basic_block); |
| 2977 | return ira->codegen->builtin_types.entry_unreachable; |
| 2962 | 2978 | } |
| 2963 | 2979 | |
| 2964 | 2980 | static TypeTableEntry *ir_finish_anal(IrAnalyze *ira, TypeTableEntry *result_type) { |
| ... | ... | @@ -3439,12 +3455,12 @@ static TypeTableEntry *ir_analyze_instruction_return(IrAnalyze *ira, |
| 3439 | 3455 | { |
| 3440 | 3456 | IrInstruction *value = return_instruction->value->other; |
| 3441 | 3457 | if (value->type_entry->id == TypeTableEntryIdInvalid) |
| 3442 | | return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); |
| 3458 | return ir_unreach_error(ira); |
| 3443 | 3459 | ira->implicit_return_type_list.append(value); |
| 3444 | 3460 | |
| 3445 | 3461 | IrInstruction *casted_value = ir_get_casted_value(ira, value, ira->explicit_return_type); |
| 3446 | 3462 | if (casted_value == ira->codegen->invalid_instruction) |
| 3447 | | return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); |
| 3463 | return ir_unreach_error(ira); |
| 3448 | 3464 | |
| 3449 | 3465 | ir_build_return_from(&ira->new_irb, &return_instruction->base, casted_value); |
| 3450 | 3466 | return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); |
| ... | ... | @@ -4302,11 +4318,8 @@ static TypeTableEntry *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstructio |
| 4302 | 4318 | static TypeTableEntry *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr *br_instruction) { |
| 4303 | 4319 | IrBasicBlock *old_dest_block = br_instruction->dest_block; |
| 4304 | 4320 | |
| 4305 | | // TODO detect backward jumps |
| 4306 | | |
| 4307 | 4321 | if (br_instruction->is_inline || old_dest_block->ref_count == 1) { |
| 4308 | | ir_inline_bb(ira, old_dest_block); |
| 4309 | | return ira->codegen->builtin_types.entry_unreachable; |
| 4322 | return ir_inline_bb(ira, &br_instruction->base, old_dest_block); |
| 4310 | 4323 | } |
| 4311 | 4324 | |
| 4312 | 4325 | IrBasicBlock *new_bb = ir_get_new_bb(ira, old_dest_block); |
| ... | ... | @@ -4317,28 +4330,24 @@ static TypeTableEntry *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr |
| 4317 | 4330 | static TypeTableEntry *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructionCondBr *cond_br_instruction) { |
| 4318 | 4331 | IrInstruction *condition = cond_br_instruction->condition->other; |
| 4319 | 4332 | if (condition->type_entry->id == TypeTableEntryIdInvalid) |
| 4320 | | return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); |
| 4321 | | |
| 4322 | | // TODO detect backward jumps |
| 4333 | return ir_unreach_error(ira); |
| 4323 | 4334 | |
| 4324 | 4335 | if (cond_br_instruction->is_inline || condition->static_value.special != ConstValSpecialRuntime) { |
| 4325 | 4336 | bool cond_is_true; |
| 4326 | 4337 | if (!ir_resolve_bool(ira, condition, &cond_is_true)) |
| 4327 | | return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); |
| 4338 | return ir_unreach_error(ira); |
| 4328 | 4339 | |
| 4329 | 4340 | IrBasicBlock *old_dest_block = cond_is_true ? |
| 4330 | 4341 | cond_br_instruction->then_block : cond_br_instruction->else_block; |
| 4331 | 4342 | |
| 4332 | | if (cond_br_instruction->is_inline || old_dest_block->ref_count == 1) { |
| 4333 | | ir_inline_bb(ira, old_dest_block); |
| 4334 | | return ira->codegen->builtin_types.entry_unreachable; |
| 4335 | | } |
| 4343 | if (cond_br_instruction->is_inline || old_dest_block->ref_count == 1) |
| 4344 | return ir_inline_bb(ira, &cond_br_instruction->base, old_dest_block); |
| 4336 | 4345 | } |
| 4337 | 4346 | |
| 4338 | 4347 | TypeTableEntry *bool_type = ira->codegen->builtin_types.entry_bool; |
| 4339 | 4348 | IrInstruction *casted_condition = ir_get_casted_value(ira, condition, bool_type); |
| 4340 | 4349 | if (casted_condition == ira->codegen->invalid_instruction) |
| 4341 | | return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); |
| 4350 | return ir_unreach_error(ira); |
| 4342 | 4351 | |
| 4343 | 4352 | IrBasicBlock *new_then_block = ir_get_new_bb(ira, cond_br_instruction->then_block); |
| 4344 | 4353 | IrBasicBlock *new_else_block = ir_get_new_bb(ira, cond_br_instruction->else_block); |
| ... | ... | @@ -5418,9 +5427,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_br(IrAnalyze *ira, |
| 5418 | 5427 | { |
| 5419 | 5428 | IrInstruction *target_value = switch_br_instruction->target_value->other; |
| 5420 | 5429 | if (target_value->type_entry->id == TypeTableEntryIdInvalid) |
| 5421 | | return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); |
| 5422 | | |
| 5423 | | // TODO detect backward jumps |
| 5430 | return ir_unreach_error(ira); |
| 5424 | 5431 | |
| 5425 | 5432 | size_t case_count = switch_br_instruction->case_count; |
| 5426 | 5433 | bool is_inline = switch_br_instruction->is_inline; |
| ... | ... | @@ -5428,27 +5435,26 @@ static TypeTableEntry *ir_analyze_instruction_switch_br(IrAnalyze *ira, |
| 5428 | 5435 | if (is_inline || target_value->static_value.special != ConstValSpecialRuntime) { |
| 5429 | 5436 | ConstExprValue *target_val = ir_resolve_const(ira, target_value); |
| 5430 | 5437 | if (!target_val) |
| 5431 | | return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); |
| 5438 | return ir_unreach_error(ira); |
| 5432 | 5439 | |
| 5433 | 5440 | for (size_t i = 0; i < case_count; i += 1) { |
| 5434 | 5441 | IrInstructionSwitchBrCase *old_case = &switch_br_instruction->cases[i]; |
| 5435 | 5442 | IrInstruction *case_value = old_case->value->other; |
| 5436 | 5443 | if (case_value->type_entry->id == TypeTableEntryIdInvalid) |
| 5437 | | return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); |
| 5444 | return ir_unreach_error(ira); |
| 5438 | 5445 | |
| 5439 | 5446 | IrInstruction *casted_case_value = ir_get_casted_value(ira, case_value, target_value->type_entry); |
| 5440 | 5447 | if (casted_case_value->type_entry->id == TypeTableEntryIdInvalid) |
| 5441 | | return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); |
| 5448 | return ir_unreach_error(ira); |
| 5442 | 5449 | |
| 5443 | 5450 | ConstExprValue *case_val = ir_resolve_const(ira, casted_case_value); |
| 5444 | 5451 | if (!case_val) |
| 5445 | | return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); |
| 5452 | return ir_unreach_error(ira); |
| 5446 | 5453 | |
| 5447 | 5454 | if (const_values_equal(target_val, case_val, target_value->type_entry)) { |
| 5448 | 5455 | IrBasicBlock *old_dest_block = old_case->block; |
| 5449 | 5456 | if (is_inline || old_dest_block->ref_count == 1) { |
| 5450 | | ir_inline_bb(ira, old_dest_block); |
| 5451 | | return ira->codegen->builtin_types.entry_unreachable; |
| 5457 | return ir_inline_bb(ira, &switch_br_instruction->base, old_dest_block); |
| 5452 | 5458 | } else { |
| 5453 | 5459 | IrBasicBlock *new_dest_block = ir_get_new_bb(ira, old_dest_block); |
| 5454 | 5460 | ir_build_br_from(&ira->new_irb, &switch_br_instruction->base, new_dest_block); |
| ... | ... | @@ -5840,7 +5846,9 @@ TypeTableEntry *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutabl |
| 5840 | 5846 | ira->instruction_index += 1; |
| 5841 | 5847 | } |
| 5842 | 5848 | |
| 5843 | | if (ira->implicit_return_type_list.length == 0) { |
| 5849 | if (new_exec->invalid) { |
| 5850 | return ira->codegen->builtin_types.entry_invalid; |
| 5851 | } else if (ira->implicit_return_type_list.length == 0) { |
| 5844 | 5852 | return codegen->builtin_types.entry_unreachable; |
| 5845 | 5853 | } else { |
| 5846 | 5854 | return ir_resolve_peer_types(ira, expected_type_source_node, ira->implicit_return_type_list.items, |