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
signature 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...@@ -20,6 +20,3 @@ inferred comptime
20 // an instruction which just makes a pointer of it.20 // an instruction which just makes a pointer of it.
21 return ir_build_ref(irb, scope, value->source_node, value, false, false);21 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 {...@@ -2248,7 +2248,8 @@ enum IrInstructionId {
2248 IrInstructionIdBoolNot,2248 IrInstructionIdBoolNot,
2249 IrInstructionIdMemset,2249 IrInstructionIdMemset,
2250 IrInstructionIdMemcpy,2250 IrInstructionIdMemcpy,
2251 IrInstructionIdSlice,2251 IrInstructionIdSliceSrc,
2252 IrInstructionIdSliceGen,
2252 IrInstructionIdMemberCount,2253 IrInstructionIdMemberCount,
2253 IrInstructionIdMemberType,2254 IrInstructionIdMemberType,
2254 IrInstructionIdMemberName,2255 IrInstructionIdMemberName,
...@@ -2334,6 +2335,7 @@ enum IrInstructionId {...@@ -2334,6 +2335,7 @@ enum IrInstructionId {
2334 IrInstructionIdAllocaSrc,2335 IrInstructionIdAllocaSrc,
2335 IrInstructionIdAllocaGen,2336 IrInstructionIdAllocaGen,
2336 IrInstructionIdEndExpr,2337 IrInstructionIdEndExpr,
2338 IrInstructionIdPtrOfArrayToSlice,
2337};2339};
23382340
2339struct IrInstruction {2341struct IrInstruction {
...@@ -2617,7 +2619,6 @@ enum CastOp {...@@ -2617,7 +2619,6 @@ enum CastOp {
2617 CastOpNumLitToConcrete,2619 CastOpNumLitToConcrete,
2618 CastOpErrSet,2620 CastOpErrSet,
2619 CastOpBitCast,2621 CastOpBitCast,
2620 CastOpPtrOfArrayToSlice,
2621};2622};
26222623
2623// TODO get rid of this instruction, replace with instructions for each op code2624// TODO get rid of this instruction, replace with instructions for each op code
...@@ -2989,14 +2990,24 @@ struct IrInstructionMemcpy {...@@ -2989,14 +2990,24 @@ struct IrInstructionMemcpy {
2989 IrInstruction *count;2990 IrInstruction *count;
2990};2991};
29912992
2992struct IrInstructionSlice {2993struct IrInstructionSliceSrc {
2993 IrInstruction base;2994 IrInstruction base;
29942995
2996 bool safety_check_on;
2995 IrInstruction *ptr;2997 IrInstruction *ptr;
2996 IrInstruction *start;2998 IrInstruction *start;
2997 IrInstruction *end;2999 IrInstruction *end;
3000 ResultLoc *result_loc;
3001};
3002
3003struct IrInstructionSliceGen {
3004 IrInstruction base;
3005
2998 bool safety_check_on;3006 bool safety_check_on;
2999 LLVMValueRef tmp_ptr;3007 IrInstruction *ptr;
3008 IrInstruction *start;
3009 IrInstruction *end;
3010 IrInstruction *result_loc;
3000};3011};
30013012
3002struct IrInstructionMemberCount {3013struct IrInstructionMemberCount {
...@@ -3563,6 +3574,7 @@ struct IrInstructionImplicitCast {...@@ -3563,6 +3574,7 @@ struct IrInstructionImplicitCast {
35633574
3564 IrInstruction *dest_type;3575 IrInstruction *dest_type;
3565 IrInstruction *target;3576 IrInstruction *target;
3577 ResultLoc *result_loc;
3566};3578};
35673579
3568struct IrInstructionResolveResult {3580struct IrInstructionResolveResult {
...@@ -3572,6 +3584,13 @@ struct IrInstructionResolveResult {...@@ -3572,6 +3584,13 @@ struct IrInstructionResolveResult {
3572 IrInstruction *ty;3584 IrInstruction *ty;
3573};3585};
35743586
3587struct IrInstructionPtrOfArrayToSlice {
3588 IrInstruction base;
3589
3590 IrInstruction *operand;
3591 IrInstruction *result_loc;
3592};
3593
3575enum ResultLocId {3594enum ResultLocId {
3576 ResultLocIdInvalid,3595 ResultLocIdInvalid,
3577 ResultLocIdNone,3596 ResultLocIdNone,
src/codegen.cpp+39-33
...@@ -3072,33 +3072,39 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,...@@ -3072,33 +3072,39 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
3072 return expr_val;3072 return expr_val;
3073 case CastOpBitCast:3073 case CastOpBitCast:
3074 return LLVMBuildBitCast(g->builder, expr_val, get_llvm_type(g, wanted_type), "");3074 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 }
3098 }3075 }
3099 zig_unreachable();3076 zig_unreachable();
3100}3077}
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
3102static LLVMValueRef ir_render_ptr_cast(CodeGen *g, IrExecutable *executable,3108static LLVMValueRef ir_render_ptr_cast(CodeGen *g, IrExecutable *executable,
3103 IrInstructionPtrCastGen *instruction)3109 IrInstructionPtrCastGen *instruction)
3104{3110{
...@@ -4603,16 +4609,14 @@ static LLVMValueRef ir_render_memcpy(CodeGen *g, IrExecutable *executable, IrIns...@@ -4603,16 +4609,14 @@ static LLVMValueRef ir_render_memcpy(CodeGen *g, IrExecutable *executable, IrIns
4603 return nullptr;4609 return nullptr;
4604}4610}
46054611
4606static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInstructionSlice *instruction) {4612static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInstructionSliceGen *instruction) {
4607 assert(instruction->tmp_ptr);
4608
4609 LLVMValueRef array_ptr_ptr = ir_llvm_value(g, instruction->ptr);4613 LLVMValueRef array_ptr_ptr = ir_llvm_value(g, instruction->ptr);
4610 ZigType *array_ptr_type = instruction->ptr->value.type;4614 ZigType *array_ptr_type = instruction->ptr->value.type;
4611 assert(array_ptr_type->id == ZigTypeIdPointer);4615 assert(array_ptr_type->id == ZigTypeIdPointer);
4612 ZigType *array_type = array_ptr_type->data.pointer.child_type;4616 ZigType *array_type = array_ptr_type->data.pointer.child_type;
4613 LLVMValueRef array_ptr = get_handle_value(g, array_ptr_ptr, array_type, array_ptr_type);4617 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
4617 bool want_runtime_safety = instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base);4621 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...@@ -4630,7 +4634,9 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
4630 end_val = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, array_type->data.array.len, false);4634 end_val = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, array_type->data.array.len, false);
4631 }4635 }
4632 if (want_runtime_safety) {4636 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 }
4634 if (instruction->end) {4640 if (instruction->end) {
4635 LLVMValueRef array_end = LLVMConstInt(g->builtin_types.entry_usize->llvm_type,4641 LLVMValueRef array_end = LLVMConstInt(g->builtin_types.entry_usize->llvm_type,
4636 array_type->data.array.len, false);4642 array_type->data.array.len, false);
...@@ -5525,6 +5531,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -5525,6 +5531,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
5525 case IrInstructionIdImplicitCast:5531 case IrInstructionIdImplicitCast:
5526 case IrInstructionIdResolveResult:5532 case IrInstructionIdResolveResult:
5527 case IrInstructionIdContainerInitList:5533 case IrInstructionIdContainerInitList:
5534 case IrInstructionIdSliceSrc:
5528 zig_unreachable();5535 zig_unreachable();
55295536
5530 case IrInstructionIdDeclVarGen:5537 case IrInstructionIdDeclVarGen:
...@@ -5595,8 +5602,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -5595,8 +5602,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
5595 return ir_render_memset(g, executable, (IrInstructionMemset *)instruction);5602 return ir_render_memset(g, executable, (IrInstructionMemset *)instruction);
5596 case IrInstructionIdMemcpy:5603 case IrInstructionIdMemcpy:
5597 return ir_render_memcpy(g, executable, (IrInstructionMemcpy *)instruction);5604 return ir_render_memcpy(g, executable, (IrInstructionMemcpy *)instruction);
5598 case IrInstructionIdSlice:5605 case IrInstructionIdSliceGen:
5599 return ir_render_slice(g, executable, (IrInstructionSlice *)instruction);5606 return ir_render_slice(g, executable, (IrInstructionSliceGen *)instruction);
5600 case IrInstructionIdBreakpoint:5607 case IrInstructionIdBreakpoint:
5601 return ir_render_breakpoint(g, executable, (IrInstructionBreakpoint *)instruction);5608 return ir_render_breakpoint(g, executable, (IrInstructionBreakpoint *)instruction);
5602 case IrInstructionIdReturnAddress:5609 case IrInstructionIdReturnAddress:
...@@ -5697,6 +5704,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -5697,6 +5704,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
5697 return ir_render_assert_non_null(g, executable, (IrInstructionAssertNonNull *)instruction);5704 return ir_render_assert_non_null(g, executable, (IrInstructionAssertNonNull *)instruction);
5698 case IrInstructionIdResizeSlice:5705 case IrInstructionIdResizeSlice:
5699 return ir_render_resize_slice(g, executable, (IrInstructionResizeSlice *)instruction);5706 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);
5700 }5709 }
5701 zig_unreachable();5710 zig_unreachable();
5702}5711}
...@@ -6831,9 +6840,6 @@ static void do_code_gen(CodeGen *g) {...@@ -6831,9 +6840,6 @@ static void do_code_gen(CodeGen *g) {
6831 slot = &ref_instruction->tmp_ptr;6840 slot = &ref_instruction->tmp_ptr;
6832 assert(instruction->value.type->id == ZigTypeIdPointer);6841 assert(instruction->value.type->id == ZigTypeIdPointer);
6833 slot_type = instruction->value.type->data.pointer.child_type;6842 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;
6837 } else if (instruction->id == IrInstructionIdOptionalWrap) {6843 } else if (instruction->id == IrInstructionIdOptionalWrap) {
6838 IrInstructionOptionalWrap *maybe_wrap_instruction = (IrInstructionOptionalWrap *)instruction;6844 IrInstructionOptionalWrap *maybe_wrap_instruction = (IrInstructionOptionalWrap *)instruction;
6839 slot = &maybe_wrap_instruction->tmp_ptr;6845 slot = &maybe_wrap_instruction->tmp_ptr;
src/ir.cpp+119-53
...@@ -700,8 +700,12 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionMemcpy *) {...@@ -700,8 +700,12 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionMemcpy *) {
700 return IrInstructionIdMemcpy;700 return IrInstructionIdMemcpy;
701}701}
702702
703static constexpr IrInstructionId ir_instruction_id(IrInstructionSlice *) {703static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceSrc *) {
704 return IrInstructionIdSlice;704 return IrInstructionIdSliceSrc;
705}
706
707static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceGen *) {
708 return IrInstructionIdSliceGen;
705}709}
706710
707static constexpr IrInstructionId ir_instruction_id(IrInstructionMemberCount *) {711static constexpr IrInstructionId ir_instruction_id(IrInstructionMemberCount *) {
...@@ -880,6 +884,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionResolveResult *)...@@ -880,6 +884,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionResolveResult *)
880 return IrInstructionIdResolveResult;884 return IrInstructionIdResolveResult;
881}885}
882886
887static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrOfArrayToSlice *) {
888 return IrInstructionIdPtrOfArrayToSlice;
889}
890
883static constexpr IrInstructionId ir_instruction_id(IrInstructionOpaqueType *) {891static constexpr IrInstructionId ir_instruction_id(IrInstructionOpaqueType *) {
884 return IrInstructionIdOpaqueType;892 return IrInstructionIdOpaqueType;
885}893}
...@@ -2216,14 +2224,15 @@ static IrInstruction *ir_build_memcpy(IrBuilder *irb, Scope *scope, AstNode *sou...@@ -2216,14 +2224,15 @@ static IrInstruction *ir_build_memcpy(IrBuilder *irb, Scope *scope, AstNode *sou
2216 return &instruction->base;2224 return &instruction->base;
2217}2225}
22182226
2219static IrInstruction *ir_build_slice(IrBuilder *irb, Scope *scope, AstNode *source_node,2227static IrInstruction *ir_build_slice_src(IrBuilder *irb, Scope *scope, AstNode *source_node,
2220 IrInstruction *ptr, IrInstruction *start, IrInstruction *end, bool safety_check_on)2228 IrInstruction *ptr, IrInstruction *start, IrInstruction *end, bool safety_check_on, ResultLoc *result_loc)
2221{2229{
2222 IrInstructionSlice *instruction = ir_build_instruction<IrInstructionSlice>(irb, scope, source_node);2230 IrInstructionSliceSrc *instruction = ir_build_instruction<IrInstructionSliceSrc>(irb, scope, source_node);
2223 instruction->ptr = ptr;2231 instruction->ptr = ptr;
2224 instruction->start = start;2232 instruction->start = start;
2225 instruction->end = end;2233 instruction->end = end;
2226 instruction->safety_check_on = safety_check_on;2234 instruction->safety_check_on = safety_check_on;
2235 instruction->result_loc = result_loc;
22272236
2228 ir_ref_instruction(ptr, irb->current_basic_block);2237 ir_ref_instruction(ptr, irb->current_basic_block);
2229 ir_ref_instruction(start, irb->current_basic_block);2238 ir_ref_instruction(start, irb->current_basic_block);
...@@ -2232,6 +2241,26 @@ static IrInstruction *ir_build_slice(IrBuilder *irb, Scope *scope, AstNode *sour...@@ -2232,6 +2241,26 @@ static IrInstruction *ir_build_slice(IrBuilder *irb, Scope *scope, AstNode *sour
2232 return &instruction->base;2241 return &instruction->base;
2233}2242}
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
2235static IrInstruction *ir_build_member_count(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *container) {2264static IrInstruction *ir_build_member_count(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *container) {
2236 IrInstructionMemberCount *instruction = ir_build_instruction<IrInstructionMemberCount>(irb, scope, source_node);2265 IrInstructionMemberCount *instruction = ir_build_instruction<IrInstructionMemberCount>(irb, scope, source_node);
2237 instruction->container = container;2266 instruction->container = container;
...@@ -2705,11 +2734,12 @@ static IrInstruction *ir_build_align_cast(IrBuilder *irb, Scope *scope, AstNode...@@ -2705,11 +2734,12 @@ static IrInstruction *ir_build_align_cast(IrBuilder *irb, Scope *scope, AstNode
2705}2734}
27062735
2707static IrInstruction *ir_build_implicit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node,2736static 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)
2709{2738{
2710 IrInstructionImplicitCast *instruction = ir_build_instruction<IrInstructionImplicitCast>(irb, scope, source_node);2739 IrInstructionImplicitCast *instruction = ir_build_instruction<IrInstructionImplicitCast>(irb, scope, source_node);
2711 instruction->dest_type = dest_type;2740 instruction->dest_type = dest_type;
2712 instruction->target = target;2741 instruction->target = target;
2742 instruction->result_loc = result_loc;
27132743
2714 ir_ref_instruction(dest_type, irb->current_basic_block);2744 ir_ref_instruction(dest_type, irb->current_basic_block);
2715 ir_ref_instruction(target, irb->current_basic_block);2745 ir_ref_instruction(target, irb->current_basic_block);
...@@ -3082,6 +3112,21 @@ static IrInstruction *ir_build_vector_to_array(IrAnalyze *ira, IrInstruction *so...@@ -3082,6 +3112,21 @@ static IrInstruction *ir_build_vector_to_array(IrAnalyze *ira, IrInstruction *so
3082 return &instruction->base;3112 return &instruction->base;
3083}3113}
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
3085static IrInstruction *ir_build_array_to_vector(IrAnalyze *ira, IrInstruction *source_instruction,3130static IrInstruction *ir_build_array_to_vector(IrAnalyze *ira, IrInstruction *source_instruction,
3086 IrInstruction *array, ZigType *result_type)3131 IrInstruction *array, ZigType *result_type)
3087{3132{
...@@ -5717,7 +5762,8 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod...@@ -5717,7 +5762,8 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
5717 return irb->codegen->invalid_instruction;5762 return irb->codegen->invalid_instruction;
57185763
5719 if (type_instruction != nullptr) {5764 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);
5721 ir_build_end_expr(irb, scope, node, implicit_cast, &result_loc_var->base);5767 ir_build_end_expr(irb, scope, node, implicit_cast, &result_loc_var->base);
5722 }5768 }
57235769
...@@ -7086,7 +7132,7 @@ static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode...@@ -7086,7 +7132,7 @@ static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode
7086 return ir_build_const_void(irb, parent_scope, node);7132 return ir_build_const_void(irb, parent_scope, node);
7087}7133}
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) {
7090 assert(node->type == NodeTypeSliceExpr);7136 assert(node->type == NodeTypeSliceExpr);
70917137
7092 AstNodeSliceExpr *slice_expr = &node->data.slice_expr;7138 AstNodeSliceExpr *slice_expr = &node->data.slice_expr;
...@@ -7111,7 +7157,8 @@ static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node)...@@ -7111,7 +7157,8 @@ static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node)
7111 end_value = nullptr;7157 end_value = nullptr;
7112 }7158 }
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);
7115}7162}
71167163
7117static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval,7164static 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...@@ -7659,7 +7706,7 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n
7659 IrInstruction *target_promise_type = ir_build_typeof(irb, scope, node, target_inst);7706 IrInstruction *target_promise_type = ir_build_typeof(irb, scope, node, target_inst);
7660 IrInstruction *promise_result_type = ir_build_promise_result_type(irb, scope, node, target_promise_type);7707 IrInstruction *promise_result_type = ir_build_promise_result_type(irb, scope, node, target_promise_type);
7661 ir_build_await_bookkeeping(irb, scope, node, promise_result_type);7708 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);
7663 build_decl_var_and_init(irb, scope, node, result_var, undef_promise_result, "result", const_bool_false);7710 build_decl_var_and_init(irb, scope, node, result_var, undef_promise_result, "result", const_bool_false);
7664 IrInstruction *my_result_var_ptr = ir_build_var_ptr(irb, scope, node, result_var);7711 IrInstruction *my_result_var_ptr = ir_build_var_ptr(irb, scope, node, result_var);
7665 ir_build_store_ptr(irb, scope, node, result_ptr_field_ptr, my_result_var_ptr);7712 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...@@ -8001,7 +8048,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
8001 case NodeTypeDefer:8048 case NodeTypeDefer:
8002 return ir_lval_wrap(irb, scope, ir_gen_defer(irb, scope, node), lval, result_loc);8049 return ir_lval_wrap(irb, scope, ir_gen_defer(irb, scope, node), lval, result_loc);
8003 case NodeTypeSliceExpr:8050 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);
8005 case NodeTypeCatchExpr:8052 case NodeTypeCatchExpr:
8006 return ir_gen_catch(irb, scope, node, lval, result_loc);8053 return ir_gen_catch(irb, scope, node, lval, result_loc);
8007 case NodeTypeContainerDecl:8054 case NodeTypeContainerDecl:
...@@ -8028,15 +8075,19 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop...@@ -8028,15 +8075,19 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
8028 zig_unreachable();8075 zig_unreachable();
8029}8076}
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
8031static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval,8084static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval,
8032 ResultLoc *result_loc)8085 ResultLoc *result_loc)
8033{8086{
8034 if (result_loc == nullptr) {8087 if (result_loc == nullptr) {
8035 // Create a result location indicating there is none - but if one gets created8088 // Create a result location indicating there is none - but if one gets created
8036 // it will be properly distributed.8089 // it will be properly distributed.
8037 ResultLocNone *result_loc_none = allocate<ResultLocNone>(1);8090 result_loc = no_result_loc();
8038 result_loc_none->base.id = ResultLocIdNone;
8039 result_loc = &result_loc_none->base;
8040 }8091 }
8041 IrInstruction *result = ir_gen_node_raw(irb, node, scope, lval, result_loc);8092 IrInstruction *result = ir_gen_node_raw(irb, node, scope, lval, result_loc);
8042 irb->exec->invalid = irb->exec->invalid || (result == irb->codegen->invalid_instruction);8093 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...@@ -8098,7 +8149,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
8098 // TODO mark this var decl as "no safety" e.g. disable initializing the undef value to 0xaa8149 // TODO mark this var decl as "no safety" e.g. disable initializing the undef value to 0xaa
8099 ZigType *coro_frame_type = get_promise_frame_type(irb->codegen, return_type);8150 ZigType *coro_frame_type = get_promise_frame_type(irb->codegen, return_type);
8100 IrInstruction *coro_frame_type_value = ir_build_const_type(irb, coro_scope, node, coro_frame_type);8151 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);
8102 build_decl_var_and_init(irb, coro_scope, node, promise_var, undef_coro_frame, "promise", const_bool_false);8153 build_decl_var_and_init(irb, coro_scope, node, promise_var, undef_coro_frame, "promise", const_bool_false);
8103 coro_promise_ptr = ir_build_var_ptr(irb, coro_scope, node, promise_var);8154 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...@@ -8106,7 +8157,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
8106 IrInstruction *null_value = ir_build_const_null(irb, coro_scope, node);8157 IrInstruction *null_value = ir_build_const_null(irb, coro_scope, node);
8107 IrInstruction *await_handle_type_val = ir_build_const_type(irb, coro_scope, node,8158 IrInstruction *await_handle_type_val = ir_build_const_type(irb, coro_scope, node,
8108 get_optional_type(irb->codegen, irb->codegen->builtin_types.entry_promise));8159 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);
8110 build_decl_var_and_init(irb, coro_scope, node, await_handle_var, null_await_handle, "await_handle", const_bool_false);8161 build_decl_var_and_init(irb, coro_scope, node, await_handle_var, null_await_handle, "await_handle", const_bool_false);
8111 irb->exec->await_handle_var_ptr = ir_build_var_ptr(irb, coro_scope, node, await_handle_var);8162 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...@@ -8169,7 +8220,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
8169 Buf *instruction_addresses_name = buf_create_from_str("instruction_addresses");8220 Buf *instruction_addresses_name = buf_create_from_str("instruction_addresses");
8170 IrInstruction *addrs_slice_ptr = ir_build_field_ptr(irb, scope, node, err_ret_trace_ptr, instruction_addresses_name, false);8221 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());
8173 ir_build_store_ptr(irb, scope, node, addrs_slice_ptr, slice_value);8224 ir_build_store_ptr(irb, scope, node, addrs_slice_ptr, slice_value);
8174 }8225 }
81758226
...@@ -8275,7 +8326,8 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec...@@ -8275,7 +8326,8 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
8275 IrInstruction *coro_mem_ptr_ref = ir_build_ref(irb, scope, node, coro_mem_ptr, true, false);8326 IrInstruction *coro_mem_ptr_ref = ir_build_ref(irb, scope, node, coro_mem_ptr, true, false);
8276 IrInstruction *coro_size_ptr = ir_build_var_ptr(irb, scope, node, coro_size_var);8327 IrInstruction *coro_size_ptr = ir_build_var_ptr(irb, scope, node, coro_size_var);
8277 IrInstruction *coro_size = ir_build_load_ptr(irb, scope, node, coro_size_ptr);8328 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());
8279 size_t arg_count = 5;8331 size_t arg_count = 5;
8280 IrInstruction **args = allocate<IrInstruction *>(arg_count);8332 IrInstruction **args = allocate<IrInstruction *>(arg_count);
8281 args[0] = implicit_allocator_ptr; // self8333 args[0] = implicit_allocator_ptr; // self
...@@ -10417,7 +10469,6 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_...@@ -10417,7 +10469,6 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_
10417 zig_unreachable();10469 zig_unreachable();
10418 case CastOpErrSet:10470 case CastOpErrSet:
10419 case CastOpBitCast:10471 case CastOpBitCast:
10420 case CastOpPtrOfArrayToSlice:
10421 zig_panic("TODO");10472 zig_panic("TODO");
10422 case CastOpNoop:10473 case CastOpNoop:
10423 {10474 {
...@@ -10574,7 +10625,7 @@ static IrInstruction *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira,...@@ -10574,7 +10625,7 @@ static IrInstruction *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira,
10574}10625}
1057510626
10576static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr,10627static 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)
10578{10629{
10579 Error err;10630 Error err;
1058010631
...@@ -10605,11 +10656,12 @@ static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruc...@@ -10605,11 +10656,12 @@ static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruc
10605 }10656 }
10606 }10657 }
1060710658
10608 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node,10659 if (result_loc == nullptr) result_loc = no_result_loc();
10609 wanted_type, value, CastOpPtrOfArrayToSlice);10660 IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr);
10610 result->value.type = wanted_type;10661 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
10611 ir_add_alloca(ira, result, wanted_type);10662 return result_loc_inst;
10612 return result;10663 }
10664 return ir_build_ptr_of_array_to_slice(ira, source_instr, wanted_type, value, result_loc_inst);
10613}10665}
1061410666
10615static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrInstruction *ref_old_instruction) {10667static 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...@@ -11195,7 +11247,7 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi
11195}11247}
1119611248
11197static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr,11249static 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)
11199{11251{
11200 assert(is_slice(wanted_type));11252 assert(is_slice(wanted_type));
11201 // In this function we honor the const-ness of wanted_type, because11253 // 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...@@ -11227,12 +11279,14 @@ static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *s
1122711279
11228 if (!array_ptr) array_ptr = ir_get_ref(ira, source_instr, array, true, false);11280 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,11282 if (result_loc == nullptr) result_loc = no_result_loc();
11231 source_instr->source_node, array_ptr, start, end, false);11283 IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr);
11232 result->value.type = wanted_type;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);
11233 result->value.data.rh_slice.id = RuntimeHintSliceIdLen;11288 result->value.data.rh_slice.id = RuntimeHintSliceIdLen;
11234 result->value.data.rh_slice.len = array_type->data.array.len;11289 result->value.data.rh_slice.len = array_type->data.array.len;
11235 ir_add_alloca(ira, result, result->value.type);
1123611290
11237 return result;11291 return result;
11238}11292}
...@@ -11929,7 +11983,7 @@ static bool is_pointery_and_elem_is_not_pointery(ZigType *ty) {...@@ -11929,7 +11983,7 @@ static bool is_pointery_and_elem_is_not_pointery(ZigType *ty) {
11929}11983}
1193011984
11931static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr,11985static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr,
11932 ZigType *wanted_type, IrInstruction *value)11986 ZigType *wanted_type, IrInstruction *value, ResultLoc *result_loc)
11933{11987{
11934 Error err;11988 Error err;
11935 ZigType *actual_type = value->value.type;11989 ZigType *actual_type = value->value.type;
...@@ -12017,11 +12071,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -12017,11 +12071,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
12017 actual_type->id == ZigTypeIdComptimeInt ||12071 actual_type->id == ZigTypeIdComptimeInt ||
12018 actual_type->id == ZigTypeIdComptimeFloat)12072 actual_type->id == ZigTypeIdComptimeFloat)
12019 {12073 {
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);
12021 if (type_is_invalid(cast1->value.type))12075 if (type_is_invalid(cast1->value.type))
12022 return ira->codegen->invalid_instruction;12076 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);
12025 if (type_is_invalid(cast2->value.type))12079 if (type_is_invalid(cast2->value.type))
12026 return ira->codegen->invalid_instruction;12080 return ira->codegen->invalid_instruction;
1202712081
...@@ -12103,7 +12157,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -12103,7 +12157,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
12103 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,12157 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,
12104 source_node, false).id == ConstCastResultIdOk)12158 source_node, false).id == ConstCastResultIdOk)
12105 {12159 {
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);
12107 }12161 }
12108 }12162 }
1210912163
...@@ -12120,11 +12174,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -12120,11 +12174,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
12120 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,12174 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,
12121 source_node, false).id == ConstCastResultIdOk)12175 source_node, false).id == ConstCastResultIdOk)
12122 {12176 {
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);
12124 if (type_is_invalid(cast1->value.type))12178 if (type_is_invalid(cast1->value.type))
12125 return ira->codegen->invalid_instruction;12179 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);
12128 if (type_is_invalid(cast2->value.type))12182 if (type_is_invalid(cast2->value.type))
12129 return ira->codegen->invalid_instruction;12183 return ira->codegen->invalid_instruction;
1213012184
...@@ -12167,7 +12221,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -12167,7 +12221,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
12167 array_type->data.array.child_type, source_node,12221 array_type->data.array.child_type, source_node,
12168 !slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk)12222 !slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk)
12169 {12223 {
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);
12171 }12225 }
12172 }12226 }
1217312227
...@@ -12198,11 +12252,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -12198,11 +12252,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
12198 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,12252 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,
12199 source_node, false).id == ConstCastResultIdOk)12253 source_node, false).id == ConstCastResultIdOk)
12200 {12254 {
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);
12202 if (type_is_invalid(cast1->value.type))12256 if (type_is_invalid(cast1->value.type))
12203 return ira->codegen->invalid_instruction;12257 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);
12206 if (type_is_invalid(cast2->value.type))12260 if (type_is_invalid(cast2->value.type))
12207 return ira->codegen->invalid_instruction;12261 return ira->codegen->invalid_instruction;
1220812262
...@@ -12380,7 +12434,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -12380,7 +12434,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
12380 return ira->codegen->invalid_instruction;12434 return ira->codegen->invalid_instruction;
12381}12435}
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{
12384 assert(value);12440 assert(value);
12385 assert(value != ira->codegen->invalid_instruction);12441 assert(value != ira->codegen->invalid_instruction);
12386 assert(!expected_type || !type_is_invalid(expected_type));12442 assert(!expected_type || !type_is_invalid(expected_type));
...@@ -12393,7 +12449,11 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Zig...@@ -12393,7 +12449,11 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Zig
12393 if (value->value.type->id == ZigTypeIdUnreachable)12449 if (value->value.type->id == ZigTypeIdUnreachable)
12394 return value;12450 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);
12397}12457}
1239812458
12399static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr) {12459static 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...@@ -14744,7 +14804,7 @@ static IrInstruction *ir_analyze_instruction_implicit_cast(IrAnalyze *ira, IrIns
14744 if (type_is_invalid(target->value.type))14804 if (type_is_invalid(target->value.type))
14745 return ira->codegen->invalid_instruction;14805 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);
14748}14808}
1474914809
14750static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrInstructionResolveResult *instruction) {14810static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrInstructionResolveResult *instruction) {
...@@ -15687,7 +15747,8 @@ static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionC...@@ -15687,7 +15747,8 @@ static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionC
1568715747
15688 IrInstruction *arg = call_instruction->args[0]->child;15748 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);
15691 if (type_is_invalid(cast_instruction->value.type))15752 if (type_is_invalid(cast_instruction->value.type))
15692 return ira->codegen->invalid_instruction;15753 return ira->codegen->invalid_instruction;
15693 return ir_finish_anal(ira, cast_instruction);15754 return ir_finish_anal(ira, cast_instruction);
...@@ -21165,7 +21226,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio...@@ -21165,7 +21226,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio
21165 return result;21226 return result;
21166}21227}
2116721228
21168static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructionSlice *instruction) {21229static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructionSliceSrc *instruction) {
21169 IrInstruction *ptr_ptr = instruction->ptr->child;21230 IrInstruction *ptr_ptr = instruction->ptr->child;
21170 if (type_is_invalid(ptr_ptr->value.type))21231 if (type_is_invalid(ptr_ptr->value.type))
21171 return ira->codegen->invalid_instruction;21232 return ira->codegen->invalid_instruction;
...@@ -21454,12 +21515,13 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction...@@ -21454,12 +21515,13 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction
21454 return result;21515 return result;
21455 }21516 }
2145621517
21457 IrInstruction *new_instruction = ir_build_slice(&ira->new_irb,21518 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
21458 instruction->base.scope, instruction->base.source_node,21519 return_type, nullptr);
21459 ptr_ptr, casted_start, end, instruction->safety_check_on);21520 if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) {
21460 new_instruction->value.type = return_type;21521 return result_loc;
21461 ir_add_alloca(ira, new_instruction, return_type);21522 }
21462 return new_instruction;21523 return ir_build_slice_gen(ira, &instruction->base, return_type,
21524 ptr_ptr, casted_start, end, instruction->safety_check_on, result_loc);
21463}21525}
2146421526
21465static IrInstruction *ir_analyze_instruction_member_count(IrAnalyze *ira, IrInstructionMemberCount *instruction) {21527static IrInstruction *ir_analyze_instruction_member_count(IrAnalyze *ira, IrInstructionMemberCount *instruction) {
...@@ -23900,6 +23962,7 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction...@@ -23900,6 +23962,7 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction
23900 case IrInstructionIdCmpxchgGen:23962 case IrInstructionIdCmpxchgGen:
23901 case IrInstructionIdArrayToVector:23963 case IrInstructionIdArrayToVector:
23902 case IrInstructionIdVectorToArray:23964 case IrInstructionIdVectorToArray:
23965 case IrInstructionIdPtrOfArrayToSlice:
23903 case IrInstructionIdAssertZero:23966 case IrInstructionIdAssertZero:
23904 case IrInstructionIdAssertNonNull:23967 case IrInstructionIdAssertNonNull:
23905 case IrInstructionIdResizeSlice:23968 case IrInstructionIdResizeSlice:
...@@ -23908,6 +23971,7 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction...@@ -23908,6 +23971,7 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction
23908 case IrInstructionIdCallGen:23971 case IrInstructionIdCallGen:
23909 case IrInstructionIdReturnPtr:23972 case IrInstructionIdReturnPtr:
23910 case IrInstructionIdAllocaGen:23973 case IrInstructionIdAllocaGen:
23974 case IrInstructionIdSliceGen:
23911 zig_unreachable();23975 zig_unreachable();
2391223976
23913 case IrInstructionIdReturn:23977 case IrInstructionIdReturn:
...@@ -24042,8 +24106,8 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction...@@ -24042,8 +24106,8 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction
24042 return ir_analyze_instruction_memset(ira, (IrInstructionMemset *)instruction);24106 return ir_analyze_instruction_memset(ira, (IrInstructionMemset *)instruction);
24043 case IrInstructionIdMemcpy:24107 case IrInstructionIdMemcpy:
24044 return ir_analyze_instruction_memcpy(ira, (IrInstructionMemcpy *)instruction);24108 return ir_analyze_instruction_memcpy(ira, (IrInstructionMemcpy *)instruction);
24045 case IrInstructionIdSlice:24109 case IrInstructionIdSliceSrc:
24046 return ir_analyze_instruction_slice(ira, (IrInstructionSlice *)instruction);24110 return ir_analyze_instruction_slice(ira, (IrInstructionSliceSrc *)instruction);
24047 case IrInstructionIdMemberCount:24111 case IrInstructionIdMemberCount:
24048 return ir_analyze_instruction_member_count(ira, (IrInstructionMemberCount *)instruction);24112 return ir_analyze_instruction_member_count(ira, (IrInstructionMemberCount *)instruction);
24049 case IrInstructionIdMemberType:24113 case IrInstructionIdMemberType:
...@@ -24321,6 +24385,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -24321,6 +24385,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
24321 case IrInstructionIdGlobalAsm:24385 case IrInstructionIdGlobalAsm:
24322 case IrInstructionIdUndeclaredIdent:24386 case IrInstructionIdUndeclaredIdent:
24323 case IrInstructionIdEndExpr:24387 case IrInstructionIdEndExpr:
24388 case IrInstructionIdPtrOfArrayToSlice:
24389 case IrInstructionIdSliceGen:
24324 return true;24390 return true;
2432524391
24326 case IrInstructionIdPhi:24392 case IrInstructionIdPhi:
...@@ -24360,7 +24426,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -24360,7 +24426,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
24360 case IrInstructionIdIntType:24426 case IrInstructionIdIntType:
24361 case IrInstructionIdVectorType:24427 case IrInstructionIdVectorType:
24362 case IrInstructionIdBoolNot:24428 case IrInstructionIdBoolNot:
24363 case IrInstructionIdSlice:24429 case IrInstructionIdSliceSrc:
24364 case IrInstructionIdMemberCount:24430 case IrInstructionIdMemberCount:
24365 case IrInstructionIdMemberType:24431 case IrInstructionIdMemberType:
24366 case IrInstructionIdMemberName:24432 case IrInstructionIdMemberName:
src/ir_print.cpp+29-4
...@@ -858,14 +858,26 @@ static void ir_print_memcpy(IrPrint *irp, IrInstructionMemcpy *instruction) {...@@ -858,14 +858,26 @@ static void ir_print_memcpy(IrPrint *irp, IrInstructionMemcpy *instruction) {
858 fprintf(irp->f, ")");858 fprintf(irp->f, ")");
859}859}
860860
861static void ir_print_slice(IrPrint *irp, IrInstructionSlice *instruction) {861static void ir_print_slice_src(IrPrint *irp, IrInstructionSliceSrc *instruction) {
862 ir_print_other_instruction(irp, instruction->ptr);862 ir_print_other_instruction(irp, instruction->ptr);
863 fprintf(irp->f, "[");863 fprintf(irp->f, "[");
864 ir_print_other_instruction(irp, instruction->start);864 ir_print_other_instruction(irp, instruction->start);
865 fprintf(irp->f, "..");865 fprintf(irp->f, "..");
866 if (instruction->end)866 if (instruction->end)
867 ir_print_other_instruction(irp, instruction->end);867 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);
869}881}
870882
871static void ir_print_member_count(IrPrint *irp, IrInstructionMemberCount *instruction) {883static void ir_print_member_count(IrPrint *irp, IrInstructionMemberCount *instruction) {
...@@ -1086,6 +1098,13 @@ static void ir_print_vector_to_array(IrPrint *irp, IrInstructionVectorToArray *i...@@ -1086,6 +1098,13 @@ static void ir_print_vector_to_array(IrPrint *irp, IrInstructionVectorToArray *i
1086 fprintf(irp->f, ")");1098 fprintf(irp->f, ")");
1087}1099}
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
1089static void ir_print_assert_zero(IrPrint *irp, IrInstructionAssertZero *instruction) {1108static void ir_print_assert_zero(IrPrint *irp, IrInstructionAssertZero *instruction) {
1090 fprintf(irp->f, "AssertZero(");1109 fprintf(irp->f, "AssertZero(");
1091 ir_print_other_instruction(irp, instruction->target);1110 ir_print_other_instruction(irp, instruction->target);
...@@ -1758,8 +1777,11 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1758,8 +1777,11 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1758 case IrInstructionIdMemcpy:1777 case IrInstructionIdMemcpy:
1759 ir_print_memcpy(irp, (IrInstructionMemcpy *)instruction);1778 ir_print_memcpy(irp, (IrInstructionMemcpy *)instruction);
1760 break;1779 break;
1761 case IrInstructionIdSlice:1780 case IrInstructionIdSliceSrc:
1762 ir_print_slice(irp, (IrInstructionSlice *)instruction);1781 ir_print_slice_src(irp, (IrInstructionSliceSrc *)instruction);
1782 break;
1783 case IrInstructionIdSliceGen:
1784 ir_print_slice_gen(irp, (IrInstructionSliceGen *)instruction);
1763 break;1785 break;
1764 case IrInstructionIdMemberCount:1786 case IrInstructionIdMemberCount:
1765 ir_print_member_count(irp, (IrInstructionMemberCount *)instruction);1787 ir_print_member_count(irp, (IrInstructionMemberCount *)instruction);
...@@ -1992,6 +2014,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1992,6 +2014,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1992 case IrInstructionIdVectorToArray:2014 case IrInstructionIdVectorToArray:
1993 ir_print_vector_to_array(irp, (IrInstructionVectorToArray *)instruction);2015 ir_print_vector_to_array(irp, (IrInstructionVectorToArray *)instruction);
1994 break;2016 break;
2017 case IrInstructionIdPtrOfArrayToSlice:
2018 ir_print_ptr_of_array_to_slice(irp, (IrInstructionPtrOfArrayToSlice *)instruction);
2019 break;
1995 case IrInstructionIdAssertZero:2020 case IrInstructionIdAssertZero:
1996 ir_print_assert_zero(irp, (IrInstructionAssertZero *)instruction);2021 ir_print_assert_zero(irp, (IrInstructionAssertZero *)instruction);
1997 break;2022 break;