authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-12-10 18:38:53-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-12-10 18:38:53-05:00
log6feae8a4e90118df26738316ab1fb49882ba6431
tree89c113d87eca49f10681c0b6c18c66f51ff0d6fb
parent443e14afbd0615bd4902e53a31f70550a8d4497e

IR: support error union type


3 files changed, 40 insertions(+), 20 deletions(-)

src/codegen.cpp+8-6
...@@ -680,11 +680,6 @@ static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) {...@@ -680,11 +680,6 @@ static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) {
680 }680 }
681 assert(instruction->llvm_value);681 assert(instruction->llvm_value);
682 }682 }
683 if (instruction->static_value.special != ConstValSpecialRuntime) {
684 if (instruction->type_entry->id == TypeTableEntryIdPointer) {
685 return LLVMBuildLoad(g->builder, instruction->static_value.llvm_global, "");
686 }
687 }
688 return instruction->llvm_value;683 return instruction->llvm_value;
689}684}
690685
...@@ -1794,7 +1789,14 @@ static LLVMValueRef ir_render_switch_br(CodeGen *g, IrExecutable *executable, Ir...@@ -1794,7 +1789,14 @@ static LLVMValueRef ir_render_switch_br(CodeGen *g, IrExecutable *executable, Ir
1794}1789}
17951790
1796static LLVMValueRef ir_render_phi(CodeGen *g, IrExecutable *executable, IrInstructionPhi *instruction) {1791static LLVMValueRef ir_render_phi(CodeGen *g, IrExecutable *executable, IrInstructionPhi *instruction) {
1797 LLVMValueRef phi = LLVMBuildPhi(g->builder, instruction->base.type_entry->type_ref, "");1792 LLVMTypeRef phi_type;
1793 if (handle_is_ptr(instruction->base.type_entry)) {
1794 phi_type = LLVMPointerType(instruction->base.type_entry->type_ref, 0);
1795 } else {
1796 phi_type = instruction->base.type_entry->type_ref;
1797 }
1798
1799 LLVMValueRef phi = LLVMBuildPhi(g->builder, phi_type, "");
1798 LLVMValueRef *incoming_values = allocate<LLVMValueRef>(instruction->incoming_count);1800 LLVMValueRef *incoming_values = allocate<LLVMValueRef>(instruction->incoming_count);
1799 LLVMBasicBlockRef *incoming_blocks = allocate<LLVMBasicBlockRef>(instruction->incoming_count);1801 LLVMBasicBlockRef *incoming_blocks = allocate<LLVMBasicBlockRef>(instruction->incoming_count);
1800 for (size_t i = 0; i < instruction->incoming_count; i += 1) {1802 for (size_t i = 0; i < instruction->incoming_count; i += 1) {
src/ir.cpp+26-14
...@@ -3135,12 +3135,19 @@ static TypeTableEntry *ir_determine_peer_types(IrAnalyze *ira, AstNode *source_n...@@ -3135,12 +3135,19 @@ static TypeTableEntry *ir_determine_peer_types(IrAnalyze *ira, AstNode *source_n
3135 if (prev_inst->type_entry->id == TypeTableEntryIdInvalid) {3135 if (prev_inst->type_entry->id == TypeTableEntryIdInvalid) {
3136 return ira->codegen->builtin_types.entry_invalid;3136 return ira->codegen->builtin_types.entry_invalid;
3137 }3137 }
3138 bool any_are_pure_error = (prev_inst->type_entry->id == TypeTableEntryIdPureError);
3138 for (size_t i = 1; i < instruction_count; i += 1) {3139 for (size_t i = 1; i < instruction_count; i += 1) {
3139 IrInstruction *cur_inst = instructions[i];3140 IrInstruction *cur_inst = instructions[i];
3140 TypeTableEntry *cur_type = cur_inst->type_entry;3141 TypeTableEntry *cur_type = cur_inst->type_entry;
3141 TypeTableEntry *prev_type = prev_inst->type_entry;3142 TypeTableEntry *prev_type = prev_inst->type_entry;
3142 if (cur_type->id == TypeTableEntryIdInvalid) {3143 if (cur_type->id == TypeTableEntryIdInvalid) {
3143 return cur_type;3144 return cur_type;
3145 } else if (prev_type->id == TypeTableEntryIdPureError) {
3146 prev_inst = cur_inst;
3147 continue;
3148 } else if (cur_type->id == TypeTableEntryIdPureError) {
3149 any_are_pure_error = true;
3150 continue;
3144 } else if (types_match_const_cast_only(prev_type, cur_type)) {3151 } else if (types_match_const_cast_only(prev_type, cur_type)) {
3145 continue;3152 continue;
3146 } else if (types_match_const_cast_only(cur_type, prev_type)) {3153 } else if (types_match_const_cast_only(cur_type, prev_type)) {
...@@ -3198,7 +3205,11 @@ static TypeTableEntry *ir_determine_peer_types(IrAnalyze *ira, AstNode *source_n...@@ -3198,7 +3205,11 @@ static TypeTableEntry *ir_determine_peer_types(IrAnalyze *ira, AstNode *source_n
3198 return ira->codegen->builtin_types.entry_invalid;3205 return ira->codegen->builtin_types.entry_invalid;
3199 }3206 }
3200 }3207 }
3201 return prev_inst->type_entry;3208 if (any_are_pure_error && prev_inst->type_entry->id != TypeTableEntryIdPureError) {
3209 return get_error_type(ira->codegen, prev_inst->type_entry);
3210 } else {
3211 return prev_inst->type_entry;
3212 }
3202}3213}
32033214
3204enum ImplicitCastMatchResult {3215enum ImplicitCastMatchResult {
...@@ -3304,6 +3315,14 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -3304,6 +3315,14 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
3304 return ir_determine_peer_types(ira, source_node, instructions, instruction_count);3315 return ir_determine_peer_types(ira, source_node, instructions, instruction_count);
3305}3316}
33063317
3318static void ir_add_alloca(IrAnalyze *ira, IrInstruction *instruction, TypeTableEntry *type_entry) {
3319 if (type_has_bits(type_entry) && handle_is_ptr(type_entry)) {
3320 FnTableEntry *fn_entry = exec_fn_entry(ira->new_irb.exec);
3321 assert(fn_entry);
3322 fn_entry->alloca_list.append(instruction);
3323 }
3324}
3325
3307static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,3326static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,
3308 TypeTableEntry *wanted_type, CastOp cast_op, bool need_alloca)3327 TypeTableEntry *wanted_type, CastOp cast_op, bool need_alloca)
3309{3328{
...@@ -4696,11 +4715,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal...@@ -4696,11 +4715,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
4696 impl_fn, nullptr, impl_param_count, casted_args);4715 impl_fn, nullptr, impl_param_count, casted_args);
46974716
4698 TypeTableEntry *return_type = impl_fn->type_entry->data.fn.fn_type_id.return_type;4717 TypeTableEntry *return_type = impl_fn->type_entry->data.fn.fn_type_id.return_type;
4699 if (type_has_bits(return_type) && handle_is_ptr(return_type)) {4718 ir_add_alloca(ira, new_call_instruction, return_type);
4700 FnTableEntry *callsite_fn = exec_fn_entry(ira->new_irb.exec);
4701 assert(callsite_fn);
4702 callsite_fn->alloca_list.append(new_call_instruction);
4703 }
47044719
4705 return ir_finish_anal(ira, return_type);4720 return ir_finish_anal(ira, return_type);
4706 }4721 }
...@@ -4752,12 +4767,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal...@@ -4752,12 +4767,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
4752 IrInstruction *new_call_instruction = ir_build_call_from(&ira->new_irb, &call_instruction->base,4767 IrInstruction *new_call_instruction = ir_build_call_from(&ira->new_irb, &call_instruction->base,
4753 fn_entry, fn_ref, call_param_count, casted_args);4768 fn_entry, fn_ref, call_param_count, casted_args);
47544769
4755 if (type_has_bits(return_type) && handle_is_ptr(return_type)) {4770 ir_add_alloca(ira, new_call_instruction, return_type);
4756 FnTableEntry *callsite_fn = exec_fn_entry(ira->new_irb.exec);
4757 assert(callsite_fn);
4758 callsite_fn->alloca_list.append(new_call_instruction);
4759 }
4760
4761 return ir_finish_anal(ira, return_type);4771 return ir_finish_anal(ira, return_type);
4762}4772}
47634773
...@@ -5280,6 +5290,7 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP...@@ -5280,6 +5290,7 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP
52805290
5281 ir_build_phi_from(&ira->new_irb, &phi_instruction->base, new_incoming_blocks.length,5291 ir_build_phi_from(&ira->new_irb, &phi_instruction->base, new_incoming_blocks.length,
5282 new_incoming_blocks.items, new_incoming_values.items);5292 new_incoming_blocks.items, new_incoming_values.items);
5293
5283 return resolved_type;5294 return resolved_type;
5284}5295}
52855296
...@@ -6684,7 +6695,8 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru...@@ -6684,7 +6695,8 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru
66846695
6685 IrInstruction *new_instruction = ir_build_struct_init_from(&ira->new_irb, instruction,6696 IrInstruction *new_instruction = ir_build_struct_init_from(&ira->new_irb, instruction,
6686 container_type, actual_field_count, new_fields);6697 container_type, actual_field_count, new_fields);
6687 fn_entry->alloca_list.append(new_instruction);6698
6699 ir_add_alloca(ira, new_instruction, container_type);
6688 return container_type;6700 return container_type;
6689}6701}
66906702
...@@ -6754,7 +6766,7 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira...@@ -6754,7 +6766,7 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira
67546766
6755 IrInstruction *new_instruction = ir_build_container_init_list_from(&ira->new_irb, &instruction->base,6767 IrInstruction *new_instruction = ir_build_container_init_list_from(&ira->new_irb, &instruction->base,
6756 container_type_value, elem_count, new_items);6768 container_type_value, elem_count, new_items);
6757 fn_entry->alloca_list.append(new_instruction);6769 ir_add_alloca(ira, new_instruction, fixed_size_array_type);
6758 return fixed_size_array_type;6770 return fixed_size_array_type;
6759 } else if (container_type->id == TypeTableEntryIdArray) {6771 } else if (container_type->id == TypeTableEntryIdArray) {
6760 // same as slice init but we make a compile error if the length is wrong6772 // same as slice init but we make a compile error if the length is wrong
test/self_hosted2.zig+6
...@@ -267,6 +267,12 @@ fn testErrorName() {...@@ -267,6 +267,12 @@ fn testErrorName() {
267 assert(memeql(@errorName(error.ItBroke), "ItBroke"));267 assert(memeql(@errorName(error.ItBroke), "ItBroke"));
268}268}
269269
270//error One;
271//fn getAnErrorValue (b: bool) -> %i32 {
272// const result = if (b) error.One else i32(1234);
273// return result;
274//}
275
270fn assert(ok: bool) {276fn assert(ok: bool) {
271 if (!ok)277 if (!ok)
272 @unreachable();278 @unreachable();