authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-11-13 16:02:18-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-11-13 16:02:18-05:00
log04c047463b2679c588c3fb09f3dace80aebd5723
tree9ed852c7288ffba0500ae0d15da3dc51957d1ffc
parente2fd3b2b1b512197e100af0a6b6e5bd96707d792

IR: fix hang for unreachable functions


1 files changed, 26 insertions(+), 27 deletions(-)

src/ir.cpp+26-27
...@@ -2074,6 +2074,11 @@ static void ir_inline_bb(IrAnalyze *ira, IrBasicBlock *old_bb) {...@@ -2074,6 +2074,11 @@ static void ir_inline_bb(IrAnalyze *ira, IrBasicBlock *old_bb) {
2074 ira->old_irb.current_basic_block = old_bb;2074 ira->old_irb.current_basic_block = old_bb;
2075}2075}
20762076
2077static TypeTableEntry *ir_finish_anal(IrAnalyze *ira, TypeTableEntry *result_type) {
2078 if (result_type->id == TypeTableEntryIdUnreachable)
2079 ir_finish_bb(ira);
2080 return result_type;
2081}
20772082
2078static ConstExprValue *ir_build_const_from(IrAnalyze *ira, IrInstruction *old_instruction,2083static ConstExprValue *ir_build_const_from(IrAnalyze *ira, IrInstruction *old_instruction,
2079 bool depends_on_compile_var)2084 bool depends_on_compile_var)
...@@ -2485,21 +2490,16 @@ static TypeTableEntry *ir_analyze_instruction_return(IrAnalyze *ira,...@@ -2485,21 +2490,16 @@ static TypeTableEntry *ir_analyze_instruction_return(IrAnalyze *ira,
2485 IrInstructionReturn *return_instruction)2490 IrInstructionReturn *return_instruction)
2486{2491{
2487 IrInstruction *value = return_instruction->value->other;2492 IrInstruction *value = return_instruction->value->other;
2488 if (value == ira->codegen->invalid_instruction) {2493 if (value == ira->codegen->invalid_instruction)
2489 ir_finish_bb(ira);2494 return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable);
2490 return ira->codegen->builtin_types.entry_unreachable;
2491 }
2492 ira->implicit_return_type_list.append(value);2495 ira->implicit_return_type_list.append(value);
24932496
2494 IrInstruction *casted_value = ir_get_casted_value(ira, value, ira->explicit_return_type);2497 IrInstruction *casted_value = ir_get_casted_value(ira, value, ira->explicit_return_type);
2495 if (casted_value == ira->codegen->invalid_instruction) {2498 if (casted_value == ira->codegen->invalid_instruction)
2496 ir_finish_bb(ira);2499 return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable);
2497 return ira->codegen->builtin_types.entry_unreachable;
2498 }
24992500
2500 ir_build_return_from(&ira->new_irb, &return_instruction->base, casted_value);2501 ir_build_return_from(&ira->new_irb, &return_instruction->base, casted_value);
2501 ir_finish_bb(ira);2502 return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable);
2502 return ira->codegen->builtin_types.entry_unreachable;
2503}2503}
25042504
2505static TypeTableEntry *ir_analyze_instruction_const(IrAnalyze *ira, IrInstructionConst *const_instruction) {2505static TypeTableEntry *ir_analyze_instruction_const(IrAnalyze *ira, IrInstructionConst *const_instruction) {
...@@ -2975,7 +2975,7 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction...@@ -2975,7 +2975,7 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction
2975 return ira->codegen->builtin_types.entry_invalid;2975 return ira->codegen->builtin_types.entry_invalid;
29762976
2977 ir_link_new_instruction(cast_instruction, &call_instruction->base);2977 ir_link_new_instruction(cast_instruction, &call_instruction->base);
2978 return cast_instruction->type_entry;2978 return ir_finish_anal(ira, cast_instruction->type_entry);
2979 } else if (fn_ref->type_entry->id == TypeTableEntryIdFn) {2979 } else if (fn_ref->type_entry->id == TypeTableEntryIdFn) {
2980 // TODO fully port over the fn call analyze code to IR2980 // TODO fully port over the fn call analyze code to IR
2981 FnTableEntry *fn_table_entry = fn_ref->static_value.data.x_fn;2981 FnTableEntry *fn_table_entry = fn_ref->static_value.data.x_fn;
...@@ -2985,14 +2985,15 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction...@@ -2985,14 +2985,15 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction
2985 for (size_t i = 0; i < call_instruction->arg_count; i += 1) {2985 for (size_t i = 0; i < call_instruction->arg_count; i += 1) {
2986 TypeTableEntry *param_type = fn_type->data.fn.fn_type_id.param_info[i].type;2986 TypeTableEntry *param_type = fn_type->data.fn.fn_type_id.param_info[i].type;
2987 IrInstruction *old_arg = call_instruction->args[i]->other;2987 IrInstruction *old_arg = call_instruction->args[i]->other;
2988 if (old_arg->type_entry->id == TypeTableEntryIdInvalid)
2989 return ira->codegen->builtin_types.entry_invalid;
2988 casted_args[i] = ir_get_casted_value(ira, old_arg, param_type);2990 casted_args[i] = ir_get_casted_value(ira, old_arg, param_type);
2989 }2991 }
29902992
2991 ir_build_call_from(&ira->new_irb, &call_instruction->base,2993 ir_build_call_from(&ira->new_irb, &call_instruction->base,
2992 call_instruction->fn, call_instruction->arg_count, casted_args);2994 call_instruction->fn, call_instruction->arg_count, casted_args);
29932995
2994 TypeTableEntry *return_type = fn_type->data.fn.fn_type_id.return_type;2996 return ir_finish_anal(ira, fn_type->data.fn.fn_type_id.return_type);
2995 return return_type;
2996 } else {2997 } else {
2997 zig_panic("TODO analyze more fn call types");2998 zig_panic("TODO analyze more fn call types");
2998 }2999 }
...@@ -3298,17 +3299,14 @@ static TypeTableEntry *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr...@@ -3298,17 +3299,14 @@ static TypeTableEntry *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr
32983299
3299 IrBasicBlock *new_bb = ir_get_new_bb(ira, old_dest_block);3300 IrBasicBlock *new_bb = ir_get_new_bb(ira, old_dest_block);
3300 ir_build_br_from(&ira->new_irb, &br_instruction->base, new_bb);3301 ir_build_br_from(&ira->new_irb, &br_instruction->base, new_bb);
3301 ir_finish_bb(ira);3302 return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable);
3302 return ira->codegen->builtin_types.entry_unreachable;
3303}3303}
33043304
3305static TypeTableEntry *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructionCondBr *cond_br_instruction) {3305static TypeTableEntry *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructionCondBr *cond_br_instruction) {
3306 TypeTableEntry *bool_type = ira->codegen->builtin_types.entry_bool;3306 TypeTableEntry *bool_type = ira->codegen->builtin_types.entry_bool;
3307 IrInstruction *condition = ir_get_casted_value(ira, cond_br_instruction->condition->other, bool_type);3307 IrInstruction *condition = ir_get_casted_value(ira, cond_br_instruction->condition->other, bool_type);
3308 if (condition == ira->codegen->invalid_instruction) {3308 if (condition == ira->codegen->invalid_instruction)
3309 ir_finish_bb(ira);3309 return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable);
3310 return ira->codegen->builtin_types.entry_unreachable;
3311 }
33123310
3313 // TODO detect backward jumps3311 // TODO detect backward jumps
3314 if (condition->static_value.ok) {3312 if (condition->static_value.ok) {
...@@ -3322,23 +3320,20 @@ static TypeTableEntry *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstruct...@@ -3322,23 +3320,20 @@ static TypeTableEntry *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstruct
3322 } else if (cond_br_instruction->is_inline) {3320 } else if (cond_br_instruction->is_inline) {
3323 add_node_error(ira->codegen, condition->source_node,3321 add_node_error(ira->codegen, condition->source_node,
3324 buf_sprintf("unable to evaluate constant expression"));3322 buf_sprintf("unable to evaluate constant expression"));
3325 ir_finish_bb(ira);3323 return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable);
3326 return ira->codegen->builtin_types.entry_unreachable;
3327 }3324 }
33283325
3329 IrBasicBlock *new_then_block = ir_get_new_bb(ira, cond_br_instruction->then_block);3326 IrBasicBlock *new_then_block = ir_get_new_bb(ira, cond_br_instruction->then_block);
3330 IrBasicBlock *new_else_block = ir_get_new_bb(ira, cond_br_instruction->else_block);3327 IrBasicBlock *new_else_block = ir_get_new_bb(ira, cond_br_instruction->else_block);
3331 ir_build_cond_br_from(&ira->new_irb, &cond_br_instruction->base, condition, new_then_block, new_else_block, false);3328 ir_build_cond_br_from(&ira->new_irb, &cond_br_instruction->base, condition, new_then_block, new_else_block, false);
3332 ir_finish_bb(ira);3329 return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable);
3333 return ira->codegen->builtin_types.entry_unreachable;
3334}3330}
33353331
3336static TypeTableEntry *ir_analyze_instruction_unreachable(IrAnalyze *ira,3332static TypeTableEntry *ir_analyze_instruction_unreachable(IrAnalyze *ira,
3337 IrInstructionUnreachable *unreachable_instruction)3333 IrInstructionUnreachable *unreachable_instruction)
3338{3334{
3339 ir_build_unreachable_from(&ira->new_irb, &unreachable_instruction->base);3335 ir_build_unreachable_from(&ira->new_irb, &unreachable_instruction->base);
3340 ir_finish_bb(ira);3336 return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable);
3341 return ira->codegen->builtin_types.entry_unreachable;
3342}3337}
33433338
3344static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPhi *phi_instruction) {3339static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPhi *phi_instruction) {
...@@ -3984,8 +3979,12 @@ TypeTableEntry *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutabl...@@ -3984,8 +3979,12 @@ TypeTableEntry *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutabl
3984 ira->instruction_index += 1;3979 ira->instruction_index += 1;
3985 }3980 }
39863981
3987 return ir_resolve_peer_types(ira, expected_type_source_node, ira->implicit_return_type_list.items,3982 if (ira->implicit_return_type_list.length == 0) {
3988 ira->implicit_return_type_list.length);3983 return codegen->builtin_types.entry_unreachable;
3984 } else {
3985 return ir_resolve_peer_types(ira, expected_type_source_node, ira->implicit_return_type_list.items,
3986 ira->implicit_return_type_list.length);
3987 }
3989}3988}
39903989
3991bool ir_has_side_effects(IrInstruction *instruction) {3990bool ir_has_side_effects(IrInstruction *instruction) {