authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-10 15:49:45-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-10 15:49:45-04:00
logc36289511629e01bbd32bc5f1133f5ed5997d1e0
treec527aacbe9af5abc3c400bc0b5d412e94f08027f
parent17b1ac5d03cd32e047d917a88e029c143cb5d119
signaturelock-open Commit is signed but in an unrecognized format.

result location semantics for slices

```zig export fn entry() void { var buf: [10]u8 = undefined; const slice1: []const u8 = &buf; const slice2 = buf[0..]; } ``` ```llvm define void @entry() #2 !dbg !35 { Entry: %buf = alloca [10 x i8], align 1 %slice1 = alloca %"[]u8", align 8 %slice2 = alloca %"[]u8", align 8 %0 = bitcast [10 x i8]* %buf to i8*, !dbg !46 call void @llvm.memset.p0i8.i64(i8* align 1 %0, i8 -86, i64 10, i1 false), !dbg !46 call void @llvm.dbg.declare(metadata [10 x i8]* %buf, metadata !39, metadata !DIExpression()), !dbg !46 %1 = getelementptr inbounds %"[]u8", %"[]u8"* %slice1, i32 0, i32 0, !dbg !47 %2 = getelementptr inbounds [10 x i8], [10 x i8]* %buf, i64 0, i64 0, !dbg !47 store i8* %2, i8** %1, align 8, !dbg !47 %3 = getelementptr inbounds %"[]u8", %"[]u8"* %slice1, i32 0, i32 1, !dbg !47 store i64 10, i64* %3, align 8, !dbg !47 call void @llvm.dbg.declare(metadata %"[]u8"* %slice1, metadata !44, metadata !DIExpression()), !dbg !48 %4 = getelementptr inbounds %"[]u8", %"[]u8"* %slice2, i32 0, i32 0, !dbg !49 %5 = getelementptr inbounds [10 x i8], [10 x i8]* %buf, i64 0, i64 0, !dbg !49 store i8* %5, i8** %4, align 8, !dbg !49 %6 = getelementptr inbounds %"[]u8", %"[]u8"* %slice2, i32 0, i32 1, !dbg !49 store i64 10, i64* %6, align 8, !dbg !49 call void @llvm.dbg.declare(metadata %"[]u8"* %slice2, metadata !45, metadata !DIExpression()), !dbg !50 ret void, !dbg !51 } ```

5 files changed, 210 insertions(+), 97 deletions(-)

BRANCH_TODO-3
......@@ -20,6 +20,3 @@ inferred comptime
2020 // an instruction which just makes a pointer of it.
2121 return ir_build_ref(irb, scope, value->source_node, value, false, false);
2222
23handle if with no else
24
25
src/all_types.hpp+23-4
......@@ -2248,7 +2248,8 @@ enum IrInstructionId {
22482248 IrInstructionIdBoolNot,
22492249 IrInstructionIdMemset,
22502250 IrInstructionIdMemcpy,
2251 IrInstructionIdSlice,
2251 IrInstructionIdSliceSrc,
2252 IrInstructionIdSliceGen,
22522253 IrInstructionIdMemberCount,
22532254 IrInstructionIdMemberType,
22542255 IrInstructionIdMemberName,
......@@ -2334,6 +2335,7 @@ enum IrInstructionId {
23342335 IrInstructionIdAllocaSrc,
23352336 IrInstructionIdAllocaGen,
23362337 IrInstructionIdEndExpr,
2338 IrInstructionIdPtrOfArrayToSlice,
23372339};
23382340
23392341struct IrInstruction {
......@@ -2617,7 +2619,6 @@ enum CastOp {
26172619 CastOpNumLitToConcrete,
26182620 CastOpErrSet,
26192621 CastOpBitCast,
2620 CastOpPtrOfArrayToSlice,
26212622};
26222623
26232624// TODO get rid of this instruction, replace with instructions for each op code
......@@ -2989,14 +2990,24 @@ struct IrInstructionMemcpy {
29892990 IrInstruction *count;
29902991};
29912992
2992struct IrInstructionSlice {
2993struct IrInstructionSliceSrc {
29932994 IrInstruction base;
29942995
2996 bool safety_check_on;
29952997 IrInstruction *ptr;
29962998 IrInstruction *start;
29972999 IrInstruction *end;
3000 ResultLoc *result_loc;
3001};
3002
3003struct IrInstructionSliceGen {
3004 IrInstruction base;
3005
29983006 bool safety_check_on;
2999 LLVMValueRef tmp_ptr;
3007 IrInstruction *ptr;
3008 IrInstruction *start;
3009 IrInstruction *end;
3010 IrInstruction *result_loc;
30003011};
30013012
30023013struct IrInstructionMemberCount {
......@@ -3563,6 +3574,7 @@ struct IrInstructionImplicitCast {
35633574
35643575 IrInstruction *dest_type;
35653576 IrInstruction *target;
3577 ResultLoc *result_loc;
35663578};
35673579
35683580struct IrInstructionResolveResult {
......@@ -3572,6 +3584,13 @@ struct IrInstructionResolveResult {
35723584 IrInstruction *ty;
35733585};
35743586
3587struct IrInstructionPtrOfArrayToSlice {
3588 IrInstruction base;
3589
3590 IrInstruction *operand;
3591 IrInstruction *result_loc;
3592};
3593
35753594enum ResultLocId {
35763595 ResultLocIdInvalid,
35773596 ResultLocIdNone,
src/codegen.cpp+39-33
......@@ -3072,33 +3072,39 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
30723072 return expr_val;
30733073 case CastOpBitCast:
30743074 return LLVMBuildBitCast(g->builder, expr_val, get_llvm_type(g, wanted_type), "");
3075 case CastOpPtrOfArrayToSlice: {
3076 assert(cast_instruction->tmp_ptr);
3077 assert(actual_type->id == ZigTypeIdPointer);
3078 ZigType *array_type = actual_type->data.pointer.child_type;
3079 assert(array_type->id == ZigTypeIdArray);
3080
3081 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr,
3082 slice_ptr_index, "");
3083 LLVMValueRef indices[] = {
3084 LLVMConstNull(g->builtin_types.entry_usize->llvm_type),
3085 LLVMConstInt(g->builtin_types.entry_usize->llvm_type, 0, false),
3086 };
3087 LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, expr_val, indices, 2, "");
3088 gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false);
3089
3090 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr,
3091 slice_len_index, "");
3092 LLVMValueRef len_value = LLVMConstInt(g->builtin_types.entry_usize->llvm_type,
3093 array_type->data.array.len, false);
3094 gen_store_untyped(g, len_value, len_field_ptr, 0, false);
3095
3096 return cast_instruction->tmp_ptr;
3097 }
30983075 }
30993076 zig_unreachable();
31003077}
31013078
3079static LLVMValueRef ir_render_ptr_of_array_to_slice(CodeGen *g, IrExecutable *executable,
3080 IrInstructionPtrOfArrayToSlice *instruction)
3081{
3082 ZigType *actual_type = instruction->operand->value.type;
3083 LLVMValueRef expr_val = ir_llvm_value(g, instruction->operand);
3084 assert(expr_val);
3085
3086 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
3087
3088 assert(actual_type->id == ZigTypeIdPointer);
3089 ZigType *array_type = actual_type->data.pointer.child_type;
3090 assert(array_type->id == ZigTypeIdArray);
3091
3092 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, slice_ptr_index, "");
3093 LLVMValueRef indices[] = {
3094 LLVMConstNull(g->builtin_types.entry_usize->llvm_type),
3095 LLVMConstInt(g->builtin_types.entry_usize->llvm_type, 0, false),
3096 };
3097 LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, expr_val, indices, 2, "");
3098 gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false);
3099
3100 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, slice_len_index, "");
3101 LLVMValueRef len_value = LLVMConstInt(g->builtin_types.entry_usize->llvm_type,
3102 array_type->data.array.len, false);
3103 gen_store_untyped(g, len_value, len_field_ptr, 0, false);
3104
3105 return result_loc;
3106}
3107
31023108static LLVMValueRef ir_render_ptr_cast(CodeGen *g, IrExecutable *executable,
31033109 IrInstructionPtrCastGen *instruction)
31043110{
......@@ -4603,16 +4609,14 @@ static LLVMValueRef ir_render_memcpy(CodeGen *g, IrExecutable *executable, IrIns
46034609 return nullptr;
46044610}
46054611
4606static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInstructionSlice *instruction) {
4607 assert(instruction->tmp_ptr);
4608
4612static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInstructionSliceGen *instruction) {
46094613 LLVMValueRef array_ptr_ptr = ir_llvm_value(g, instruction->ptr);
46104614 ZigType *array_ptr_type = instruction->ptr->value.type;
46114615 assert(array_ptr_type->id == ZigTypeIdPointer);
46124616 ZigType *array_type = array_ptr_type->data.pointer.child_type;
46134617 LLVMValueRef array_ptr = get_handle_value(g, array_ptr_ptr, array_type, array_ptr_type);
46144618
4615 LLVMValueRef tmp_struct_ptr = instruction->tmp_ptr;
4619 LLVMValueRef tmp_struct_ptr = ir_llvm_value(g, instruction->result_loc);
46164620
46174621 bool want_runtime_safety = instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base);
46184622
......@@ -4630,7 +4634,9 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
46304634 end_val = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, array_type->data.array.len, false);
46314635 }
46324636 if (want_runtime_safety) {
4633 add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val);
4637 if (instruction->start->value.special == ConstValSpecialRuntime || instruction->end) {
4638 add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val);
4639 }
46344640 if (instruction->end) {
46354641 LLVMValueRef array_end = LLVMConstInt(g->builtin_types.entry_usize->llvm_type,
46364642 array_type->data.array.len, false);
......@@ -5525,6 +5531,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
55255531 case IrInstructionIdImplicitCast:
55265532 case IrInstructionIdResolveResult:
55275533 case IrInstructionIdContainerInitList:
5534 case IrInstructionIdSliceSrc:
55285535 zig_unreachable();
55295536
55305537 case IrInstructionIdDeclVarGen:
......@@ -5595,8 +5602,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
55955602 return ir_render_memset(g, executable, (IrInstructionMemset *)instruction);
55965603 case IrInstructionIdMemcpy:
55975604 return ir_render_memcpy(g, executable, (IrInstructionMemcpy *)instruction);
5598 case IrInstructionIdSlice:
5599 return ir_render_slice(g, executable, (IrInstructionSlice *)instruction);
5605 case IrInstructionIdSliceGen:
5606 return ir_render_slice(g, executable, (IrInstructionSliceGen *)instruction);
56005607 case IrInstructionIdBreakpoint:
56015608 return ir_render_breakpoint(g, executable, (IrInstructionBreakpoint *)instruction);
56025609 case IrInstructionIdReturnAddress:
......@@ -5697,6 +5704,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
56975704 return ir_render_assert_non_null(g, executable, (IrInstructionAssertNonNull *)instruction);
56985705 case IrInstructionIdResizeSlice:
56995706 return ir_render_resize_slice(g, executable, (IrInstructionResizeSlice *)instruction);
5707 case IrInstructionIdPtrOfArrayToSlice:
5708 return ir_render_ptr_of_array_to_slice(g, executable, (IrInstructionPtrOfArrayToSlice *)instruction);
57005709 }
57015710 zig_unreachable();
57025711}
......@@ -6831,9 +6840,6 @@ static void do_code_gen(CodeGen *g) {
68316840 slot = &ref_instruction->tmp_ptr;
68326841 assert(instruction->value.type->id == ZigTypeIdPointer);
68336842 slot_type = instruction->value.type->data.pointer.child_type;
6834 } else if (instruction->id == IrInstructionIdSlice) {
6835 IrInstructionSlice *slice_instruction = (IrInstructionSlice *)instruction;
6836 slot = &slice_instruction->tmp_ptr;
68376843 } else if (instruction->id == IrInstructionIdOptionalWrap) {
68386844 IrInstructionOptionalWrap *maybe_wrap_instruction = (IrInstructionOptionalWrap *)instruction;
68396845 slot = &maybe_wrap_instruction->tmp_ptr;
src/ir.cpp+119-53
......@@ -700,8 +700,12 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionMemcpy *) {
700700 return IrInstructionIdMemcpy;
701701}
702702
703static constexpr IrInstructionId ir_instruction_id(IrInstructionSlice *) {
704 return IrInstructionIdSlice;
703static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceSrc *) {
704 return IrInstructionIdSliceSrc;
705}
706
707static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceGen *) {
708 return IrInstructionIdSliceGen;
705709}
706710
707711static constexpr IrInstructionId ir_instruction_id(IrInstructionMemberCount *) {
......@@ -880,6 +884,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionResolveResult *)
880884 return IrInstructionIdResolveResult;
881885}
882886
887static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrOfArrayToSlice *) {
888 return IrInstructionIdPtrOfArrayToSlice;
889}
890
883891static constexpr IrInstructionId ir_instruction_id(IrInstructionOpaqueType *) {
884892 return IrInstructionIdOpaqueType;
885893}
......@@ -2216,14 +2224,15 @@ static IrInstruction *ir_build_memcpy(IrBuilder *irb, Scope *scope, AstNode *sou
22162224 return &instruction->base;
22172225}
22182226
2219static IrInstruction *ir_build_slice(IrBuilder *irb, Scope *scope, AstNode *source_node,
2220 IrInstruction *ptr, IrInstruction *start, IrInstruction *end, bool safety_check_on)
2227static IrInstruction *ir_build_slice_src(IrBuilder *irb, Scope *scope, AstNode *source_node,
2228 IrInstruction *ptr, IrInstruction *start, IrInstruction *end, bool safety_check_on, ResultLoc *result_loc)
22212229{
2222 IrInstructionSlice *instruction = ir_build_instruction<IrInstructionSlice>(irb, scope, source_node);
2230 IrInstructionSliceSrc *instruction = ir_build_instruction<IrInstructionSliceSrc>(irb, scope, source_node);
22232231 instruction->ptr = ptr;
22242232 instruction->start = start;
22252233 instruction->end = end;
22262234 instruction->safety_check_on = safety_check_on;
2235 instruction->result_loc = result_loc;
22272236
22282237 ir_ref_instruction(ptr, irb->current_basic_block);
22292238 ir_ref_instruction(start, irb->current_basic_block);
......@@ -2232,6 +2241,26 @@ static IrInstruction *ir_build_slice(IrBuilder *irb, Scope *scope, AstNode *sour
22322241 return &instruction->base;
22332242}
22342243
2244static IrInstruction *ir_build_slice_gen(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *slice_type,
2245 IrInstruction *ptr, IrInstruction *start, IrInstruction *end, bool safety_check_on, IrInstruction *result_loc)
2246{
2247 IrInstructionSliceGen *instruction = ir_build_instruction<IrInstructionSliceGen>(
2248 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
2249 instruction->base.value.type = slice_type;
2250 instruction->ptr = ptr;
2251 instruction->start = start;
2252 instruction->end = end;
2253 instruction->safety_check_on = safety_check_on;
2254 instruction->result_loc = result_loc;
2255
2256 ir_ref_instruction(ptr, ira->new_irb.current_basic_block);
2257 ir_ref_instruction(start, ira->new_irb.current_basic_block);
2258 if (end) ir_ref_instruction(end, ira->new_irb.current_basic_block);
2259 ir_ref_instruction(result_loc, ira->new_irb.current_basic_block);
2260
2261 return &instruction->base;
2262}
2263
22352264static IrInstruction *ir_build_member_count(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *container) {
22362265 IrInstructionMemberCount *instruction = ir_build_instruction<IrInstructionMemberCount>(irb, scope, source_node);
22372266 instruction->container = container;
......@@ -2705,11 +2734,12 @@ static IrInstruction *ir_build_align_cast(IrBuilder *irb, Scope *scope, AstNode
27052734}
27062735
27072736static IrInstruction *ir_build_implicit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node,
2708 IrInstruction *dest_type, IrInstruction *target)
2737 IrInstruction *dest_type, IrInstruction *target, ResultLoc *result_loc)
27092738{
27102739 IrInstructionImplicitCast *instruction = ir_build_instruction<IrInstructionImplicitCast>(irb, scope, source_node);
27112740 instruction->dest_type = dest_type;
27122741 instruction->target = target;
2742 instruction->result_loc = result_loc;
27132743
27142744 ir_ref_instruction(dest_type, irb->current_basic_block);
27152745 ir_ref_instruction(target, irb->current_basic_block);
......@@ -3082,6 +3112,21 @@ static IrInstruction *ir_build_vector_to_array(IrAnalyze *ira, IrInstruction *so
30823112 return &instruction->base;
30833113}
30843114
3115static IrInstruction *ir_build_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruction *source_instruction,
3116 ZigType *result_type, IrInstruction *operand, IrInstruction *result_loc)
3117{
3118 IrInstructionPtrOfArrayToSlice *instruction = ir_build_instruction<IrInstructionPtrOfArrayToSlice>(&ira->new_irb,
3119 source_instruction->scope, source_instruction->source_node);
3120 instruction->base.value.type = result_type;
3121 instruction->operand = operand;
3122 instruction->result_loc = result_loc;
3123
3124 ir_ref_instruction(operand, ira->new_irb.current_basic_block);
3125 ir_ref_instruction(result_loc, ira->new_irb.current_basic_block);
3126
3127 return &instruction->base;
3128}
3129
30853130static IrInstruction *ir_build_array_to_vector(IrAnalyze *ira, IrInstruction *source_instruction,
30863131 IrInstruction *array, ZigType *result_type)
30873132{
......@@ -5717,7 +5762,8 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
57175762 return irb->codegen->invalid_instruction;
57185763
57195764 if (type_instruction != nullptr) {
5720 IrInstruction *implicit_cast = ir_build_implicit_cast(irb, scope, node, type_instruction, init_value);
5765 IrInstruction *implicit_cast = ir_build_implicit_cast(irb, scope, node, type_instruction, init_value,
5766 &result_loc_var->base);
57215767 ir_build_end_expr(irb, scope, node, implicit_cast, &result_loc_var->base);
57225768 }
57235769
......@@ -7086,7 +7132,7 @@ static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode
70867132 return ir_build_const_void(irb, parent_scope, node);
70877133}
70887134
7089static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node) {
7135static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) {
70907136 assert(node->type == NodeTypeSliceExpr);
70917137
70927138 AstNodeSliceExpr *slice_expr = &node->data.slice_expr;
......@@ -7111,7 +7157,8 @@ static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node)
71117157 end_value = nullptr;
71127158 }
71137159
7114 return ir_build_slice(irb, scope, node, ptr_value, start_value, end_value, true);
7160 IrInstruction *slice = ir_build_slice_src(irb, scope, node, ptr_value, start_value, end_value, true, result_loc);
7161 return ir_lval_wrap(irb, scope, slice, lval, result_loc);
71157162}
71167163
71177164static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval,
......@@ -7659,7 +7706,7 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n
76597706 IrInstruction *target_promise_type = ir_build_typeof(irb, scope, node, target_inst);
76607707 IrInstruction *promise_result_type = ir_build_promise_result_type(irb, scope, node, target_promise_type);
76617708 ir_build_await_bookkeeping(irb, scope, node, promise_result_type);
7662 IrInstruction *undef_promise_result = ir_build_implicit_cast(irb, scope, node, promise_result_type, undef);
7709 IrInstruction *undef_promise_result = ir_build_implicit_cast(irb, scope, node, promise_result_type, undef, nullptr);
76637710 build_decl_var_and_init(irb, scope, node, result_var, undef_promise_result, "result", const_bool_false);
76647711 IrInstruction *my_result_var_ptr = ir_build_var_ptr(irb, scope, node, result_var);
76657712 ir_build_store_ptr(irb, scope, node, result_ptr_field_ptr, my_result_var_ptr);
......@@ -8001,7 +8048,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
80018048 case NodeTypeDefer:
80028049 return ir_lval_wrap(irb, scope, ir_gen_defer(irb, scope, node), lval, result_loc);
80038050 case NodeTypeSliceExpr:
8004 return ir_lval_wrap(irb, scope, ir_gen_slice(irb, scope, node), lval, result_loc);
8051 return ir_gen_slice(irb, scope, node, lval, result_loc);
80058052 case NodeTypeCatchExpr:
80068053 return ir_gen_catch(irb, scope, node, lval, result_loc);
80078054 case NodeTypeContainerDecl:
......@@ -8028,15 +8075,19 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
80288075 zig_unreachable();
80298076}
80308077
8078static ResultLoc *no_result_loc(void) {
8079 ResultLocNone *result_loc_none = allocate<ResultLocNone>(1);
8080 result_loc_none->base.id = ResultLocIdNone;
8081 return &result_loc_none->base;
8082}
8083
80318084static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval,
80328085 ResultLoc *result_loc)
80338086{
80348087 if (result_loc == nullptr) {
80358088 // Create a result location indicating there is none - but if one gets created
80368089 // it will be properly distributed.
8037 ResultLocNone *result_loc_none = allocate<ResultLocNone>(1);
8038 result_loc_none->base.id = ResultLocIdNone;
8039 result_loc = &result_loc_none->base;
8090 result_loc = no_result_loc();
80408091 }
80418092 IrInstruction *result = ir_gen_node_raw(irb, node, scope, lval, result_loc);
80428093 irb->exec->invalid = irb->exec->invalid || (result == irb->codegen->invalid_instruction);
......@@ -8098,7 +8149,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
80988149 // TODO mark this var decl as "no safety" e.g. disable initializing the undef value to 0xaa
80998150 ZigType *coro_frame_type = get_promise_frame_type(irb->codegen, return_type);
81008151 IrInstruction *coro_frame_type_value = ir_build_const_type(irb, coro_scope, node, coro_frame_type);
8101 IrInstruction *undef_coro_frame = ir_build_implicit_cast(irb, coro_scope, node, coro_frame_type_value, undef);
8152 IrInstruction *undef_coro_frame = ir_build_implicit_cast(irb, coro_scope, node, coro_frame_type_value, undef, nullptr);
81028153 build_decl_var_and_init(irb, coro_scope, node, promise_var, undef_coro_frame, "promise", const_bool_false);
81038154 coro_promise_ptr = ir_build_var_ptr(irb, coro_scope, node, promise_var);
81048155
......@@ -8106,7 +8157,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
81068157 IrInstruction *null_value = ir_build_const_null(irb, coro_scope, node);
81078158 IrInstruction *await_handle_type_val = ir_build_const_type(irb, coro_scope, node,
81088159 get_optional_type(irb->codegen, irb->codegen->builtin_types.entry_promise));
8109 IrInstruction *null_await_handle = ir_build_implicit_cast(irb, coro_scope, node, await_handle_type_val, null_value);
8160 IrInstruction *null_await_handle = ir_build_implicit_cast(irb, coro_scope, node, await_handle_type_val, null_value, nullptr);
81108161 build_decl_var_and_init(irb, coro_scope, node, await_handle_var, null_await_handle, "await_handle", const_bool_false);
81118162 irb->exec->await_handle_var_ptr = ir_build_var_ptr(irb, coro_scope, node, await_handle_var);
81128163
......@@ -8169,7 +8220,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
81698220 Buf *instruction_addresses_name = buf_create_from_str("instruction_addresses");
81708221 IrInstruction *addrs_slice_ptr = ir_build_field_ptr(irb, scope, node, err_ret_trace_ptr, instruction_addresses_name, false);
81718222
8172 IrInstruction *slice_value = ir_build_slice(irb, scope, node, return_addresses_ptr, zero, nullptr, false);
8223 IrInstruction *slice_value = ir_build_slice_src(irb, scope, node, return_addresses_ptr, zero, nullptr, false, no_result_loc());
81738224 ir_build_store_ptr(irb, scope, node, addrs_slice_ptr, slice_value);
81748225 }
81758226
......@@ -8275,7 +8326,8 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
82758326 IrInstruction *coro_mem_ptr_ref = ir_build_ref(irb, scope, node, coro_mem_ptr, true, false);
82768327 IrInstruction *coro_size_ptr = ir_build_var_ptr(irb, scope, node, coro_size_var);
82778328 IrInstruction *coro_size = ir_build_load_ptr(irb, scope, node, coro_size_ptr);
8278 IrInstruction *mem_slice = ir_build_slice(irb, scope, node, coro_mem_ptr_ref, zero, coro_size, false);
8329 IrInstruction *mem_slice = ir_build_slice_src(irb, scope, node, coro_mem_ptr_ref, zero, coro_size, false,
8330 no_result_loc());
82798331 size_t arg_count = 5;
82808332 IrInstruction **args = allocate<IrInstruction *>(arg_count);
82818333 args[0] = implicit_allocator_ptr; // self
......@@ -10417,7 +10469,6 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_
1041710469 zig_unreachable();
1041810470 case CastOpErrSet:
1041910471 case CastOpBitCast:
10420 case CastOpPtrOfArrayToSlice:
1042110472 zig_panic("TODO");
1042210473 case CastOpNoop:
1042310474 {
......@@ -10574,7 +10625,7 @@ static IrInstruction *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira,
1057410625}
1057510626
1057610627static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr,
10577 IrInstruction *value, ZigType *wanted_type)
10628 IrInstruction *value, ZigType *wanted_type, ResultLoc *result_loc)
1057810629{
1057910630 Error err;
1058010631
......@@ -10605,11 +10656,12 @@ static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruc
1060510656 }
1060610657 }
1060710658
10608 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node,
10609 wanted_type, value, CastOpPtrOfArrayToSlice);
10610 result->value.type = wanted_type;
10611 ir_add_alloca(ira, result, wanted_type);
10612 return result;
10659 if (result_loc == nullptr) result_loc = no_result_loc();
10660 IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr);
10661 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
10662 return result_loc_inst;
10663 }
10664 return ir_build_ptr_of_array_to_slice(ira, source_instr, wanted_type, value, result_loc_inst);
1061310665}
1061410666
1061510667static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrInstruction *ref_old_instruction) {
......@@ -11195,7 +11247,7 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi
1119511247}
1119611248
1119711249static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr,
11198 IrInstruction *array_arg, ZigType *wanted_type)
11250 IrInstruction *array_arg, ZigType *wanted_type, ResultLoc *result_loc)
1119911251{
1120011252 assert(is_slice(wanted_type));
1120111253 // In this function we honor the const-ness of wanted_type, because
......@@ -11227,12 +11279,14 @@ static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *s
1122711279
1122811280 if (!array_ptr) array_ptr = ir_get_ref(ira, source_instr, array, true, false);
1122911281
11230 IrInstruction *result = ir_build_slice(&ira->new_irb, source_instr->scope,
11231 source_instr->source_node, array_ptr, start, end, false);
11232 result->value.type = wanted_type;
11282 if (result_loc == nullptr) result_loc = no_result_loc();
11283 IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr);
11284 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
11285 return result_loc_inst;
11286 }
11287 IrInstruction *result = ir_build_slice_gen(ira, source_instr, wanted_type, array_ptr, start, end, false, result_loc_inst);
1123311288 result->value.data.rh_slice.id = RuntimeHintSliceIdLen;
1123411289 result->value.data.rh_slice.len = array_type->data.array.len;
11235 ir_add_alloca(ira, result, result->value.type);
1123611290
1123711291 return result;
1123811292}
......@@ -11929,7 +11983,7 @@ static bool is_pointery_and_elem_is_not_pointery(ZigType *ty) {
1192911983}
1193011984
1193111985static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr,
11932 ZigType *wanted_type, IrInstruction *value)
11986 ZigType *wanted_type, IrInstruction *value, ResultLoc *result_loc)
1193311987{
1193411988 Error err;
1193511989 ZigType *actual_type = value->value.type;
......@@ -12017,11 +12071,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1201712071 actual_type->id == ZigTypeIdComptimeInt ||
1201812072 actual_type->id == ZigTypeIdComptimeFloat)
1201912073 {
12020 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value);
12074 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value, nullptr);
1202112075 if (type_is_invalid(cast1->value.type))
1202212076 return ira->codegen->invalid_instruction;
1202312077
12024 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1);
12078 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1, result_loc);
1202512079 if (type_is_invalid(cast2->value.type))
1202612080 return ira->codegen->invalid_instruction;
1202712081
......@@ -12103,7 +12157,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1210312157 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,
1210412158 source_node, false).id == ConstCastResultIdOk)
1210512159 {
12106 return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type);
12160 return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type, result_loc);
1210712161 }
1210812162 }
1210912163
......@@ -12120,11 +12174,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1212012174 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,
1212112175 source_node, false).id == ConstCastResultIdOk)
1212212176 {
12123 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value);
12177 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value, nullptr);
1212412178 if (type_is_invalid(cast1->value.type))
1212512179 return ira->codegen->invalid_instruction;
1212612180
12127 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1);
12181 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1, result_loc);
1212812182 if (type_is_invalid(cast2->value.type))
1212912183 return ira->codegen->invalid_instruction;
1213012184
......@@ -12167,7 +12221,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1216712221 array_type->data.array.child_type, source_node,
1216812222 !slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk)
1216912223 {
12170 return ir_resolve_ptr_of_array_to_slice(ira, source_instr, value, wanted_type);
12224 return ir_resolve_ptr_of_array_to_slice(ira, source_instr, value, wanted_type, result_loc);
1217112225 }
1217212226 }
1217312227
......@@ -12198,11 +12252,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1219812252 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,
1219912253 source_node, false).id == ConstCastResultIdOk)
1220012254 {
12201 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value);
12255 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value, nullptr);
1220212256 if (type_is_invalid(cast1->value.type))
1220312257 return ira->codegen->invalid_instruction;
1220412258
12205 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1);
12259 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1, result_loc);
1220612260 if (type_is_invalid(cast2->value.type))
1220712261 return ira->codegen->invalid_instruction;
1220812262
......@@ -12380,7 +12434,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1238012434 return ira->codegen->invalid_instruction;
1238112435}
1238212436
12383static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type) {
12437static IrInstruction *ir_implicit_cast_with_result(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type,
12438 ResultLoc *result_loc)
12439{
1238412440 assert(value);
1238512441 assert(value != ira->codegen->invalid_instruction);
1238612442 assert(!expected_type || !type_is_invalid(expected_type));
......@@ -12393,7 +12449,11 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Zig
1239312449 if (value->value.type->id == ZigTypeIdUnreachable)
1239412450 return value;
1239512451
12396 return ir_analyze_cast(ira, value, expected_type, value);
12452 return ir_analyze_cast(ira, value, expected_type, value, result_loc);
12453}
12454
12455static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type) {
12456 return ir_implicit_cast_with_result(ira, value, expected_type, nullptr);
1239712457}
1239812458
1239912459static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr) {
......@@ -14744,7 +14804,7 @@ static IrInstruction *ir_analyze_instruction_implicit_cast(IrAnalyze *ira, IrIns
1474414804 if (type_is_invalid(target->value.type))
1474514805 return ira->codegen->invalid_instruction;
1474614806
14747 return ir_implicit_cast(ira, target, dest_type);
14807 return ir_implicit_cast_with_result(ira, target, dest_type, instruction->result_loc);
1474814808}
1474914809
1475014810static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrInstructionResolveResult *instruction) {
......@@ -15687,7 +15747,8 @@ static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionC
1568715747
1568815748 IrInstruction *arg = call_instruction->args[0]->child;
1568915749
15690 IrInstruction *cast_instruction = ir_analyze_cast(ira, &call_instruction->base, dest_type, arg);
15750 IrInstruction *cast_instruction = ir_analyze_cast(ira, &call_instruction->base, dest_type, arg,
15751 call_instruction->result_loc);
1569115752 if (type_is_invalid(cast_instruction->value.type))
1569215753 return ira->codegen->invalid_instruction;
1569315754 return ir_finish_anal(ira, cast_instruction);
......@@ -21165,7 +21226,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio
2116521226 return result;
2116621227}
2116721228
21168static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructionSlice *instruction) {
21229static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructionSliceSrc *instruction) {
2116921230 IrInstruction *ptr_ptr = instruction->ptr->child;
2117021231 if (type_is_invalid(ptr_ptr->value.type))
2117121232 return ira->codegen->invalid_instruction;
......@@ -21454,12 +21515,13 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction
2145421515 return result;
2145521516 }
2145621517
21457 IrInstruction *new_instruction = ir_build_slice(&ira->new_irb,
21458 instruction->base.scope, instruction->base.source_node,
21459 ptr_ptr, casted_start, end, instruction->safety_check_on);
21460 new_instruction->value.type = return_type;
21461 ir_add_alloca(ira, new_instruction, return_type);
21462 return new_instruction;
21518 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
21519 return_type, nullptr);
21520 if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) {
21521 return result_loc;
21522 }
21523 return ir_build_slice_gen(ira, &instruction->base, return_type,
21524 ptr_ptr, casted_start, end, instruction->safety_check_on, result_loc);
2146321525}
2146421526
2146521527static IrInstruction *ir_analyze_instruction_member_count(IrAnalyze *ira, IrInstructionMemberCount *instruction) {
......@@ -23900,6 +23962,7 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction
2390023962 case IrInstructionIdCmpxchgGen:
2390123963 case IrInstructionIdArrayToVector:
2390223964 case IrInstructionIdVectorToArray:
23965 case IrInstructionIdPtrOfArrayToSlice:
2390323966 case IrInstructionIdAssertZero:
2390423967 case IrInstructionIdAssertNonNull:
2390523968 case IrInstructionIdResizeSlice:
......@@ -23908,6 +23971,7 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction
2390823971 case IrInstructionIdCallGen:
2390923972 case IrInstructionIdReturnPtr:
2391023973 case IrInstructionIdAllocaGen:
23974 case IrInstructionIdSliceGen:
2391123975 zig_unreachable();
2391223976
2391323977 case IrInstructionIdReturn:
......@@ -24042,8 +24106,8 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction
2404224106 return ir_analyze_instruction_memset(ira, (IrInstructionMemset *)instruction);
2404324107 case IrInstructionIdMemcpy:
2404424108 return ir_analyze_instruction_memcpy(ira, (IrInstructionMemcpy *)instruction);
24045 case IrInstructionIdSlice:
24046 return ir_analyze_instruction_slice(ira, (IrInstructionSlice *)instruction);
24109 case IrInstructionIdSliceSrc:
24110 return ir_analyze_instruction_slice(ira, (IrInstructionSliceSrc *)instruction);
2404724111 case IrInstructionIdMemberCount:
2404824112 return ir_analyze_instruction_member_count(ira, (IrInstructionMemberCount *)instruction);
2404924113 case IrInstructionIdMemberType:
......@@ -24321,6 +24385,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
2432124385 case IrInstructionIdGlobalAsm:
2432224386 case IrInstructionIdUndeclaredIdent:
2432324387 case IrInstructionIdEndExpr:
24388 case IrInstructionIdPtrOfArrayToSlice:
24389 case IrInstructionIdSliceGen:
2432424390 return true;
2432524391
2432624392 case IrInstructionIdPhi:
......@@ -24360,7 +24426,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
2436024426 case IrInstructionIdIntType:
2436124427 case IrInstructionIdVectorType:
2436224428 case IrInstructionIdBoolNot:
24363 case IrInstructionIdSlice:
24429 case IrInstructionIdSliceSrc:
2436424430 case IrInstructionIdMemberCount:
2436524431 case IrInstructionIdMemberType:
2436624432 case IrInstructionIdMemberName:
src/ir_print.cpp+29-4
......@@ -858,14 +858,26 @@ static void ir_print_memcpy(IrPrint *irp, IrInstructionMemcpy *instruction) {
858858 fprintf(irp->f, ")");
859859}
860860
861static void ir_print_slice(IrPrint *irp, IrInstructionSlice *instruction) {
861static void ir_print_slice_src(IrPrint *irp, IrInstructionSliceSrc *instruction) {
862862 ir_print_other_instruction(irp, instruction->ptr);
863863 fprintf(irp->f, "[");
864864 ir_print_other_instruction(irp, instruction->start);
865865 fprintf(irp->f, "..");
866866 if (instruction->end)
867867 ir_print_other_instruction(irp, instruction->end);
868 fprintf(irp->f, "]");
868 fprintf(irp->f, "]result=");
869 ir_print_result_loc(irp, instruction->result_loc);
870}
871
872static void ir_print_slice_gen(IrPrint *irp, IrInstructionSliceGen *instruction) {
873 ir_print_other_instruction(irp, instruction->ptr);
874 fprintf(irp->f, "[");
875 ir_print_other_instruction(irp, instruction->start);
876 fprintf(irp->f, "..");
877 if (instruction->end)
878 ir_print_other_instruction(irp, instruction->end);
879 fprintf(irp->f, "]result=");
880 ir_print_other_instruction(irp, instruction->result_loc);
869881}
870882
871883static void ir_print_member_count(IrPrint *irp, IrInstructionMemberCount *instruction) {
......@@ -1086,6 +1098,13 @@ static void ir_print_vector_to_array(IrPrint *irp, IrInstructionVectorToArray *i
10861098 fprintf(irp->f, ")");
10871099}
10881100
1101static void ir_print_ptr_of_array_to_slice(IrPrint *irp, IrInstructionPtrOfArrayToSlice *instruction) {
1102 fprintf(irp->f, "PtrOfArrayToSlice(");
1103 ir_print_other_instruction(irp, instruction->operand);
1104 fprintf(irp->f, ")result=");
1105 ir_print_other_instruction(irp, instruction->result_loc);
1106}
1107
10891108static void ir_print_assert_zero(IrPrint *irp, IrInstructionAssertZero *instruction) {
10901109 fprintf(irp->f, "AssertZero(");
10911110 ir_print_other_instruction(irp, instruction->target);
......@@ -1758,8 +1777,11 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
17581777 case IrInstructionIdMemcpy:
17591778 ir_print_memcpy(irp, (IrInstructionMemcpy *)instruction);
17601779 break;
1761 case IrInstructionIdSlice:
1762 ir_print_slice(irp, (IrInstructionSlice *)instruction);
1780 case IrInstructionIdSliceSrc:
1781 ir_print_slice_src(irp, (IrInstructionSliceSrc *)instruction);
1782 break;
1783 case IrInstructionIdSliceGen:
1784 ir_print_slice_gen(irp, (IrInstructionSliceGen *)instruction);
17631785 break;
17641786 case IrInstructionIdMemberCount:
17651787 ir_print_member_count(irp, (IrInstructionMemberCount *)instruction);
......@@ -1992,6 +2014,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
19922014 case IrInstructionIdVectorToArray:
19932015 ir_print_vector_to_array(irp, (IrInstructionVectorToArray *)instruction);
19942016 break;
2017 case IrInstructionIdPtrOfArrayToSlice:
2018 ir_print_ptr_of_array_to_slice(irp, (IrInstructionPtrOfArrayToSlice *)instruction);
2019 break;
19952020 case IrInstructionIdAssertZero:
19962021 ir_print_assert_zero(irp, (IrInstructionAssertZero *)instruction);
19972022 break;