authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-10 16:55:07-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-10 16:55:07-04:00
log4f085b8d2c8ffb03dd15b789ad5867904faae13d
tree85d72c0cba9b4a6d6803e3e5dd83210a1699033e
parenteaa9d8bdac7f64e38a39607e5d5574f88f8fe875
signaturelock-open Commit is signed but in an unrecognized format.

result location semantics for error union wrapping a payload


5 files changed, 43 insertions(+), 39 deletions(-)

BRANCH_TODO+1-13
......@@ -6,17 +6,5 @@ look at all the ir_gen_node ir_gen_node_extra calls and make sure result locatio
66
77migrate all the alloca_list to alloca_gen_list
88
9inferred comptime
10
11
12 if (lval == LValNone) {
13 if (result_loc->id == ResultLocIdNone)
14 return value;
15 }
16
17 assert(lval == LValPtr);
18
19 // We needed a pointer to a value, but we got a value. So we create
20 // an instruction which just makes a pointer of it.
21 return ir_build_ref(irb, scope, value->source_node, value, false, false);
9comptime expressions
2210
src/all_types.hpp+2-2
......@@ -3102,8 +3102,8 @@ struct IrInstructionOptionalWrap {
31023102struct IrInstructionErrWrapPayload {
31033103 IrInstruction base;
31043104
3105 IrInstruction *value;
3106 LLVMValueRef tmp_ptr;
3105 IrInstruction *operand;
3106 IrInstruction *result_loc;
31073107};
31083108
31093109struct IrInstructionErrWrapCode {
src/codegen.cpp+7-9
......@@ -5002,7 +5002,7 @@ static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executa
50025002 ZigType *err_set_type = wanted_type->data.error_union.err_set_type;
50035003
50045004 if (!type_has_bits(err_set_type)) {
5005 return ir_llvm_value(g, instruction->value);
5005 return ir_llvm_value(g, instruction->operand);
50065006 }
50075007
50085008 LLVMValueRef ok_err_val = LLVMConstNull(get_llvm_type(g, g->err_tag_type));
......@@ -5010,17 +5010,18 @@ static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executa
50105010 if (!type_has_bits(payload_type))
50115011 return ok_err_val;
50125012
5013 assert(instruction->tmp_ptr);
50145013
5015 LLVMValueRef payload_val = ir_llvm_value(g, instruction->value);
5014 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
50165015
5017 LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_err_index, "");
5016 LLVMValueRef payload_val = ir_llvm_value(g, instruction->operand);
5017
5018 LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_err_index, "");
50185019 gen_store_untyped(g, ok_err_val, err_tag_ptr, 0, false);
50195020
5020 LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_payload_index, "");
5021 LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_payload_index, "");
50215022 gen_assign_raw(g, payload_ptr, get_pointer_to_type(g, payload_type, false), payload_val);
50225023
5023 return instruction->tmp_ptr;
5024 return result_loc;
50245025}
50255026
50265027static LLVMValueRef ir_render_union_tag(CodeGen *g, IrExecutable *executable, IrInstructionUnionTag *instruction) {
......@@ -6840,9 +6841,6 @@ static void do_code_gen(CodeGen *g) {
68406841 slot = &ref_instruction->tmp_ptr;
68416842 assert(instruction->value.type->id == ZigTypeIdPointer);
68426843 slot_type = instruction->value.type->data.pointer.child_type;
6843 } else if (instruction->id == IrInstructionIdErrWrapPayload) {
6844 IrInstructionErrWrapPayload *err_wrap_payload_instruction = (IrInstructionErrWrapPayload *)instruction;
6845 slot = &err_wrap_payload_instruction->tmp_ptr;
68466844 } else if (instruction->id == IrInstructionIdErrWrapCode) {
68476845 IrInstructionErrWrapCode *err_wrap_code_instruction = (IrInstructionErrWrapCode *)instruction;
68486846 slot = &err_wrap_code_instruction->tmp_ptr;
src/ir.cpp+30-13
......@@ -1773,11 +1773,17 @@ static IrInstruction *ir_build_optional_wrap(IrAnalyze *ira, IrInstruction *sour
17731773 return &instruction->base;
17741774}
17751775
1776static IrInstruction *ir_build_err_wrap_payload(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) {
1777 IrInstructionErrWrapPayload *instruction = ir_build_instruction<IrInstructionErrWrapPayload>(irb, scope, source_node);
1778 instruction->value = value;
1776static IrInstruction *ir_build_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instruction,
1777 ZigType *result_type, IrInstruction *operand, IrInstruction *result_loc)
1778{
1779 IrInstructionErrWrapPayload *instruction = ir_build_instruction<IrInstructionErrWrapPayload>(
1780 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
1781 instruction->base.value.type = result_type;
1782 instruction->operand = operand;
1783 instruction->result_loc = result_loc;
17791784
1780 ir_ref_instruction(value, irb->current_basic_block);
1785 ir_ref_instruction(operand, ira->new_irb.current_basic_block);
1786 if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block);
17811787
17821788 return &instruction->base;
17831789}
......@@ -11078,12 +11084,13 @@ static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *so
1107811084}
1107911085
1108011086static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instr,
11081 IrInstruction *value, ZigType *wanted_type)
11087 IrInstruction *value, ZigType *wanted_type, ResultLoc *result_loc)
1108211088{
1108311089 assert(wanted_type->id == ZigTypeIdErrorUnion);
1108411090
11091 ZigType *payload_type = wanted_type->data.error_union.payload_type;
11092 ZigType *err_set_type = wanted_type->data.error_union.err_set_type;
1108511093 if (instr_is_comptime(value)) {
11086 ZigType *payload_type = wanted_type->data.error_union.payload_type;
1108711094 IrInstruction *casted_payload = ir_implicit_cast(ira, value, payload_type);
1108811095 if (type_is_invalid(casted_payload->value.type))
1108911096 return ira->codegen->invalid_instruction;
......@@ -11093,7 +11100,7 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction
1109311100 return ira->codegen->invalid_instruction;
1109411101
1109511102 ConstExprValue *err_set_val = create_const_vals(1);
11096 err_set_val->type = wanted_type->data.error_union.err_set_type;
11103 err_set_val->type = err_set_type;
1109711104 err_set_val->special = ConstValSpecialStatic;
1109811105 err_set_val->data.x_err_set = nullptr;
1109911106
......@@ -11106,10 +11113,19 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction
1110611113 return &const_instruction->base;
1110711114 }
1110811115
11109 IrInstruction *result = ir_build_err_wrap_payload(&ira->new_irb, source_instr->scope, source_instr->source_node, value);
11110 result->value.type = wanted_type;
11116 IrInstruction *result_loc_inst;
11117 if (handle_is_ptr(wanted_type)) {
11118 if (result_loc == nullptr) result_loc = no_result_loc();
11119 result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr);
11120 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
11121 return result_loc_inst;
11122 }
11123 } else {
11124 result_loc_inst = nullptr;
11125 }
11126
11127 IrInstruction *result = ir_build_err_wrap_payload(ira, source_instr, wanted_type, value, result_loc_inst);
1111111128 result->value.data.rh_error_union = RuntimeHintErrorUnionNonError;
11112 ir_add_alloca(ira, result, wanted_type);
1111311129 return result;
1111411130}
1111511131
......@@ -12057,12 +12073,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1205712073 if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type,
1205812074 source_node, false).id == ConstCastResultIdOk)
1205912075 {
12060 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type);
12076 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type, result_loc);
1206112077 } else if (actual_type->id == ZigTypeIdComptimeInt ||
1206212078 actual_type->id == ZigTypeIdComptimeFloat)
1206312079 {
1206412080 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error_union.payload_type, true)) {
12065 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type);
12081 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type, result_loc);
1206612082 } else {
1206712083 return ira->codegen->invalid_instruction;
1206812084 }
......@@ -24447,7 +24463,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
2444724463 case IrInstructionIdTestErr:
2444824464 case IrInstructionIdUnwrapErrCode:
2444924465 case IrInstructionIdErrWrapCode:
24450 case IrInstructionIdErrWrapPayload:
2445124466 case IrInstructionIdFnProto:
2445224467 case IrInstructionIdTestComptime:
2445324468 case IrInstructionIdPtrCastSrc:
......@@ -24512,6 +24527,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
2451224527 (IrInstructionUnwrapErrPayload *)instruction;
2451324528 return unwrap_err_payload_instruction->safety_check_on;
2451424529 }
24530 case IrInstructionIdErrWrapPayload:
24531 return reinterpret_cast<IrInstructionErrWrapPayload *>(instruction)->result_loc != nullptr;
2451524532 }
2451624533 zig_unreachable();
2451724534}
src/ir_print.cpp+3-2
......@@ -985,8 +985,9 @@ static void ir_print_err_wrap_code(IrPrint *irp, IrInstructionErrWrapCode *instr
985985
986986static void ir_print_err_wrap_payload(IrPrint *irp, IrInstructionErrWrapPayload *instruction) {
987987 fprintf(irp->f, "@errWrapPayload(");
988 ir_print_other_instruction(irp, instruction->value);
989 fprintf(irp->f, ")");
988 ir_print_other_instruction(irp, instruction->operand);
989 fprintf(irp->f, ")result=");
990 ir_print_other_instruction(irp, instruction->result_loc);
990991}
991992
992993static void ir_print_fn_proto(IrPrint *irp, IrInstructionFnProto *instruction) {