Commit c362895116
Changed files (5)
src/all_types.hpp
@@ -2248,7 +2248,8 @@ enum IrInstructionId {
IrInstructionIdBoolNot,
IrInstructionIdMemset,
IrInstructionIdMemcpy,
- IrInstructionIdSlice,
+ IrInstructionIdSliceSrc,
+ IrInstructionIdSliceGen,
IrInstructionIdMemberCount,
IrInstructionIdMemberType,
IrInstructionIdMemberName,
@@ -2334,6 +2335,7 @@ enum IrInstructionId {
IrInstructionIdAllocaSrc,
IrInstructionIdAllocaGen,
IrInstructionIdEndExpr,
+ IrInstructionIdPtrOfArrayToSlice,
};
struct IrInstruction {
@@ -2617,7 +2619,6 @@ enum CastOp {
CastOpNumLitToConcrete,
CastOpErrSet,
CastOpBitCast,
- CastOpPtrOfArrayToSlice,
};
// TODO get rid of this instruction, replace with instructions for each op code
@@ -2989,14 +2990,24 @@ struct IrInstructionMemcpy {
IrInstruction *count;
};
-struct IrInstructionSlice {
+struct IrInstructionSliceSrc {
IrInstruction base;
+ bool safety_check_on;
IrInstruction *ptr;
IrInstruction *start;
IrInstruction *end;
+ ResultLoc *result_loc;
+};
+
+struct IrInstructionSliceGen {
+ IrInstruction base;
+
bool safety_check_on;
- LLVMValueRef tmp_ptr;
+ IrInstruction *ptr;
+ IrInstruction *start;
+ IrInstruction *end;
+ IrInstruction *result_loc;
};
struct IrInstructionMemberCount {
@@ -3563,6 +3574,7 @@ struct IrInstructionImplicitCast {
IrInstruction *dest_type;
IrInstruction *target;
+ ResultLoc *result_loc;
};
struct IrInstructionResolveResult {
@@ -3572,6 +3584,13 @@ struct IrInstructionResolveResult {
IrInstruction *ty;
};
+struct IrInstructionPtrOfArrayToSlice {
+ IrInstruction base;
+
+ IrInstruction *operand;
+ IrInstruction *result_loc;
+};
+
enum ResultLocId {
ResultLocIdInvalid,
ResultLocIdNone,
src/codegen.cpp
@@ -3072,33 +3072,39 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
return expr_val;
case CastOpBitCast:
return LLVMBuildBitCast(g->builder, expr_val, get_llvm_type(g, wanted_type), "");
- case CastOpPtrOfArrayToSlice: {
- assert(cast_instruction->tmp_ptr);
- assert(actual_type->id == ZigTypeIdPointer);
- ZigType *array_type = actual_type->data.pointer.child_type;
- assert(array_type->id == ZigTypeIdArray);
-
- LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr,
- slice_ptr_index, "");
- LLVMValueRef indices[] = {
- LLVMConstNull(g->builtin_types.entry_usize->llvm_type),
- LLVMConstInt(g->builtin_types.entry_usize->llvm_type, 0, false),
- };
- LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, expr_val, indices, 2, "");
- gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false);
-
- LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr,
- slice_len_index, "");
- LLVMValueRef len_value = LLVMConstInt(g->builtin_types.entry_usize->llvm_type,
- array_type->data.array.len, false);
- gen_store_untyped(g, len_value, len_field_ptr, 0, false);
-
- return cast_instruction->tmp_ptr;
- }
}
zig_unreachable();
}
+static LLVMValueRef ir_render_ptr_of_array_to_slice(CodeGen *g, IrExecutable *executable,
+ IrInstructionPtrOfArrayToSlice *instruction)
+{
+ ZigType *actual_type = instruction->operand->value.type;
+ LLVMValueRef expr_val = ir_llvm_value(g, instruction->operand);
+ assert(expr_val);
+
+ LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
+
+ assert(actual_type->id == ZigTypeIdPointer);
+ ZigType *array_type = actual_type->data.pointer.child_type;
+ assert(array_type->id == ZigTypeIdArray);
+
+ LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, slice_ptr_index, "");
+ LLVMValueRef indices[] = {
+ LLVMConstNull(g->builtin_types.entry_usize->llvm_type),
+ LLVMConstInt(g->builtin_types.entry_usize->llvm_type, 0, false),
+ };
+ LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, expr_val, indices, 2, "");
+ gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false);
+
+ LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, slice_len_index, "");
+ LLVMValueRef len_value = LLVMConstInt(g->builtin_types.entry_usize->llvm_type,
+ array_type->data.array.len, false);
+ gen_store_untyped(g, len_value, len_field_ptr, 0, false);
+
+ return result_loc;
+}
+
static LLVMValueRef ir_render_ptr_cast(CodeGen *g, IrExecutable *executable,
IrInstructionPtrCastGen *instruction)
{
@@ -4603,16 +4609,14 @@ static LLVMValueRef ir_render_memcpy(CodeGen *g, IrExecutable *executable, IrIns
return nullptr;
}
-static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInstructionSlice *instruction) {
- assert(instruction->tmp_ptr);
-
+static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInstructionSliceGen *instruction) {
LLVMValueRef array_ptr_ptr = ir_llvm_value(g, instruction->ptr);
ZigType *array_ptr_type = instruction->ptr->value.type;
assert(array_ptr_type->id == ZigTypeIdPointer);
ZigType *array_type = array_ptr_type->data.pointer.child_type;
LLVMValueRef array_ptr = get_handle_value(g, array_ptr_ptr, array_type, array_ptr_type);
- LLVMValueRef tmp_struct_ptr = instruction->tmp_ptr;
+ LLVMValueRef tmp_struct_ptr = ir_llvm_value(g, instruction->result_loc);
bool want_runtime_safety = instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base);
@@ -4630,7 +4634,9 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
end_val = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, array_type->data.array.len, false);
}
if (want_runtime_safety) {
- add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val);
+ if (instruction->start->value.special == ConstValSpecialRuntime || instruction->end) {
+ add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val);
+ }
if (instruction->end) {
LLVMValueRef array_end = LLVMConstInt(g->builtin_types.entry_usize->llvm_type,
array_type->data.array.len, false);
@@ -5525,6 +5531,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
case IrInstructionIdImplicitCast:
case IrInstructionIdResolveResult:
case IrInstructionIdContainerInitList:
+ case IrInstructionIdSliceSrc:
zig_unreachable();
case IrInstructionIdDeclVarGen:
@@ -5595,8 +5602,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
return ir_render_memset(g, executable, (IrInstructionMemset *)instruction);
case IrInstructionIdMemcpy:
return ir_render_memcpy(g, executable, (IrInstructionMemcpy *)instruction);
- case IrInstructionIdSlice:
- return ir_render_slice(g, executable, (IrInstructionSlice *)instruction);
+ case IrInstructionIdSliceGen:
+ return ir_render_slice(g, executable, (IrInstructionSliceGen *)instruction);
case IrInstructionIdBreakpoint:
return ir_render_breakpoint(g, executable, (IrInstructionBreakpoint *)instruction);
case IrInstructionIdReturnAddress:
@@ -5697,6 +5704,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
return ir_render_assert_non_null(g, executable, (IrInstructionAssertNonNull *)instruction);
case IrInstructionIdResizeSlice:
return ir_render_resize_slice(g, executable, (IrInstructionResizeSlice *)instruction);
+ case IrInstructionIdPtrOfArrayToSlice:
+ return ir_render_ptr_of_array_to_slice(g, executable, (IrInstructionPtrOfArrayToSlice *)instruction);
}
zig_unreachable();
}
@@ -6831,9 +6840,6 @@ static void do_code_gen(CodeGen *g) {
slot = &ref_instruction->tmp_ptr;
assert(instruction->value.type->id == ZigTypeIdPointer);
slot_type = instruction->value.type->data.pointer.child_type;
- } else if (instruction->id == IrInstructionIdSlice) {
- IrInstructionSlice *slice_instruction = (IrInstructionSlice *)instruction;
- slot = &slice_instruction->tmp_ptr;
} else if (instruction->id == IrInstructionIdOptionalWrap) {
IrInstructionOptionalWrap *maybe_wrap_instruction = (IrInstructionOptionalWrap *)instruction;
slot = &maybe_wrap_instruction->tmp_ptr;
src/ir.cpp
@@ -700,8 +700,12 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionMemcpy *) {
return IrInstructionIdMemcpy;
}
-static constexpr IrInstructionId ir_instruction_id(IrInstructionSlice *) {
- return IrInstructionIdSlice;
+static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceSrc *) {
+ return IrInstructionIdSliceSrc;
+}
+
+static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceGen *) {
+ return IrInstructionIdSliceGen;
}
static constexpr IrInstructionId ir_instruction_id(IrInstructionMemberCount *) {
@@ -880,6 +884,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionResolveResult *)
return IrInstructionIdResolveResult;
}
+static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrOfArrayToSlice *) {
+ return IrInstructionIdPtrOfArrayToSlice;
+}
+
static constexpr IrInstructionId ir_instruction_id(IrInstructionOpaqueType *) {
return IrInstructionIdOpaqueType;
}
@@ -2216,14 +2224,15 @@ static IrInstruction *ir_build_memcpy(IrBuilder *irb, Scope *scope, AstNode *sou
return &instruction->base;
}
-static IrInstruction *ir_build_slice(IrBuilder *irb, Scope *scope, AstNode *source_node,
- IrInstruction *ptr, IrInstruction *start, IrInstruction *end, bool safety_check_on)
+static IrInstruction *ir_build_slice_src(IrBuilder *irb, Scope *scope, AstNode *source_node,
+ IrInstruction *ptr, IrInstruction *start, IrInstruction *end, bool safety_check_on, ResultLoc *result_loc)
{
- IrInstructionSlice *instruction = ir_build_instruction<IrInstructionSlice>(irb, scope, source_node);
+ IrInstructionSliceSrc *instruction = ir_build_instruction<IrInstructionSliceSrc>(irb, scope, source_node);
instruction->ptr = ptr;
instruction->start = start;
instruction->end = end;
instruction->safety_check_on = safety_check_on;
+ instruction->result_loc = result_loc;
ir_ref_instruction(ptr, irb->current_basic_block);
ir_ref_instruction(start, irb->current_basic_block);
@@ -2232,6 +2241,26 @@ static IrInstruction *ir_build_slice(IrBuilder *irb, Scope *scope, AstNode *sour
return &instruction->base;
}
+static IrInstruction *ir_build_slice_gen(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *slice_type,
+ IrInstruction *ptr, IrInstruction *start, IrInstruction *end, bool safety_check_on, IrInstruction *result_loc)
+{
+ IrInstructionSliceGen *instruction = ir_build_instruction<IrInstructionSliceGen>(
+ &ira->new_irb, source_instruction->scope, source_instruction->source_node);
+ instruction->base.value.type = slice_type;
+ instruction->ptr = ptr;
+ instruction->start = start;
+ instruction->end = end;
+ instruction->safety_check_on = safety_check_on;
+ instruction->result_loc = result_loc;
+
+ ir_ref_instruction(ptr, ira->new_irb.current_basic_block);
+ ir_ref_instruction(start, ira->new_irb.current_basic_block);
+ if (end) ir_ref_instruction(end, ira->new_irb.current_basic_block);
+ ir_ref_instruction(result_loc, ira->new_irb.current_basic_block);
+
+ return &instruction->base;
+}
+
static IrInstruction *ir_build_member_count(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *container) {
IrInstructionMemberCount *instruction = ir_build_instruction<IrInstructionMemberCount>(irb, scope, source_node);
instruction->container = container;
@@ -2705,11 +2734,12 @@ static IrInstruction *ir_build_align_cast(IrBuilder *irb, Scope *scope, AstNode
}
static IrInstruction *ir_build_implicit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node,
- IrInstruction *dest_type, IrInstruction *target)
+ IrInstruction *dest_type, IrInstruction *target, ResultLoc *result_loc)
{
IrInstructionImplicitCast *instruction = ir_build_instruction<IrInstructionImplicitCast>(irb, scope, source_node);
instruction->dest_type = dest_type;
instruction->target = target;
+ instruction->result_loc = result_loc;
ir_ref_instruction(dest_type, irb->current_basic_block);
ir_ref_instruction(target, irb->current_basic_block);
@@ -3082,6 +3112,21 @@ static IrInstruction *ir_build_vector_to_array(IrAnalyze *ira, IrInstruction *so
return &instruction->base;
}
+static IrInstruction *ir_build_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruction *source_instruction,
+ ZigType *result_type, IrInstruction *operand, IrInstruction *result_loc)
+{
+ IrInstructionPtrOfArrayToSlice *instruction = ir_build_instruction<IrInstructionPtrOfArrayToSlice>(&ira->new_irb,
+ source_instruction->scope, source_instruction->source_node);
+ instruction->base.value.type = result_type;
+ instruction->operand = operand;
+ instruction->result_loc = result_loc;
+
+ ir_ref_instruction(operand, ira->new_irb.current_basic_block);
+ ir_ref_instruction(result_loc, ira->new_irb.current_basic_block);
+
+ return &instruction->base;
+}
+
static IrInstruction *ir_build_array_to_vector(IrAnalyze *ira, IrInstruction *source_instruction,
IrInstruction *array, ZigType *result_type)
{
@@ -5717,7 +5762,8 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
return irb->codegen->invalid_instruction;
if (type_instruction != nullptr) {
- IrInstruction *implicit_cast = ir_build_implicit_cast(irb, scope, node, type_instruction, init_value);
+ IrInstruction *implicit_cast = ir_build_implicit_cast(irb, scope, node, type_instruction, init_value,
+ &result_loc_var->base);
ir_build_end_expr(irb, scope, node, implicit_cast, &result_loc_var->base);
}
@@ -7086,7 +7132,7 @@ static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode
return ir_build_const_void(irb, parent_scope, node);
}
-static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node) {
+static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) {
assert(node->type == NodeTypeSliceExpr);
AstNodeSliceExpr *slice_expr = &node->data.slice_expr;
@@ -7111,7 +7157,8 @@ static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node)
end_value = nullptr;
}
- return ir_build_slice(irb, scope, node, ptr_value, start_value, end_value, true);
+ IrInstruction *slice = ir_build_slice_src(irb, scope, node, ptr_value, start_value, end_value, true, result_loc);
+ return ir_lval_wrap(irb, scope, slice, lval, result_loc);
}
static 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
IrInstruction *target_promise_type = ir_build_typeof(irb, scope, node, target_inst);
IrInstruction *promise_result_type = ir_build_promise_result_type(irb, scope, node, target_promise_type);
ir_build_await_bookkeeping(irb, scope, node, promise_result_type);
- IrInstruction *undef_promise_result = ir_build_implicit_cast(irb, scope, node, promise_result_type, undef);
+ IrInstruction *undef_promise_result = ir_build_implicit_cast(irb, scope, node, promise_result_type, undef, nullptr);
build_decl_var_and_init(irb, scope, node, result_var, undef_promise_result, "result", const_bool_false);
IrInstruction *my_result_var_ptr = ir_build_var_ptr(irb, scope, node, result_var);
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
case NodeTypeDefer:
return ir_lval_wrap(irb, scope, ir_gen_defer(irb, scope, node), lval, result_loc);
case NodeTypeSliceExpr:
- return ir_lval_wrap(irb, scope, ir_gen_slice(irb, scope, node), lval, result_loc);
+ return ir_gen_slice(irb, scope, node, lval, result_loc);
case NodeTypeCatchExpr:
return ir_gen_catch(irb, scope, node, lval, result_loc);
case NodeTypeContainerDecl:
@@ -8028,15 +8075,19 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
zig_unreachable();
}
+static ResultLoc *no_result_loc(void) {
+ ResultLocNone *result_loc_none = allocate<ResultLocNone>(1);
+ result_loc_none->base.id = ResultLocIdNone;
+ return &result_loc_none->base;
+}
+
static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval,
ResultLoc *result_loc)
{
if (result_loc == nullptr) {
// Create a result location indicating there is none - but if one gets created
// it will be properly distributed.
- ResultLocNone *result_loc_none = allocate<ResultLocNone>(1);
- result_loc_none->base.id = ResultLocIdNone;
- result_loc = &result_loc_none->base;
+ result_loc = no_result_loc();
}
IrInstruction *result = ir_gen_node_raw(irb, node, scope, lval, result_loc);
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
// TODO mark this var decl as "no safety" e.g. disable initializing the undef value to 0xaa
ZigType *coro_frame_type = get_promise_frame_type(irb->codegen, return_type);
IrInstruction *coro_frame_type_value = ir_build_const_type(irb, coro_scope, node, coro_frame_type);
- IrInstruction *undef_coro_frame = ir_build_implicit_cast(irb, coro_scope, node, coro_frame_type_value, undef);
+ IrInstruction *undef_coro_frame = ir_build_implicit_cast(irb, coro_scope, node, coro_frame_type_value, undef, nullptr);
build_decl_var_and_init(irb, coro_scope, node, promise_var, undef_coro_frame, "promise", const_bool_false);
coro_promise_ptr = ir_build_var_ptr(irb, coro_scope, node, promise_var);
@@ -8106,7 +8157,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
IrInstruction *null_value = ir_build_const_null(irb, coro_scope, node);
IrInstruction *await_handle_type_val = ir_build_const_type(irb, coro_scope, node,
get_optional_type(irb->codegen, irb->codegen->builtin_types.entry_promise));
- IrInstruction *null_await_handle = ir_build_implicit_cast(irb, coro_scope, node, await_handle_type_val, null_value);
+ IrInstruction *null_await_handle = ir_build_implicit_cast(irb, coro_scope, node, await_handle_type_val, null_value, nullptr);
build_decl_var_and_init(irb, coro_scope, node, await_handle_var, null_await_handle, "await_handle", const_bool_false);
irb->exec->await_handle_var_ptr = ir_build_var_ptr(irb, coro_scope, node, await_handle_var);
@@ -8169,7 +8220,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
Buf *instruction_addresses_name = buf_create_from_str("instruction_addresses");
IrInstruction *addrs_slice_ptr = ir_build_field_ptr(irb, scope, node, err_ret_trace_ptr, instruction_addresses_name, false);
- IrInstruction *slice_value = ir_build_slice(irb, scope, node, return_addresses_ptr, zero, nullptr, false);
+ IrInstruction *slice_value = ir_build_slice_src(irb, scope, node, return_addresses_ptr, zero, nullptr, false, no_result_loc());
ir_build_store_ptr(irb, scope, node, addrs_slice_ptr, slice_value);
}
@@ -8275,7 +8326,8 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
IrInstruction *coro_mem_ptr_ref = ir_build_ref(irb, scope, node, coro_mem_ptr, true, false);
IrInstruction *coro_size_ptr = ir_build_var_ptr(irb, scope, node, coro_size_var);
IrInstruction *coro_size = ir_build_load_ptr(irb, scope, node, coro_size_ptr);
- IrInstruction *mem_slice = ir_build_slice(irb, scope, node, coro_mem_ptr_ref, zero, coro_size, false);
+ IrInstruction *mem_slice = ir_build_slice_src(irb, scope, node, coro_mem_ptr_ref, zero, coro_size, false,
+ no_result_loc());
size_t arg_count = 5;
IrInstruction **args = allocate<IrInstruction *>(arg_count);
args[0] = implicit_allocator_ptr; // self
@@ -10417,7 +10469,6 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_
zig_unreachable();
case CastOpErrSet:
case CastOpBitCast:
- case CastOpPtrOfArrayToSlice:
zig_panic("TODO");
case CastOpNoop:
{
@@ -10574,7 +10625,7 @@ static IrInstruction *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira,
}
static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr,
- IrInstruction *value, ZigType *wanted_type)
+ IrInstruction *value, ZigType *wanted_type, ResultLoc *result_loc)
{
Error err;
@@ -10605,11 +10656,12 @@ static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruc
}
}
- IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node,
- wanted_type, value, CastOpPtrOfArrayToSlice);
- result->value.type = wanted_type;
- ir_add_alloca(ira, result, wanted_type);
- return result;
+ if (result_loc == nullptr) result_loc = no_result_loc();
+ IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr);
+ if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
+ return result_loc_inst;
+ }
+ return ir_build_ptr_of_array_to_slice(ira, source_instr, wanted_type, value, result_loc_inst);
}
static 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
}
static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr,
- IrInstruction *array_arg, ZigType *wanted_type)
+ IrInstruction *array_arg, ZigType *wanted_type, ResultLoc *result_loc)
{
assert(is_slice(wanted_type));
// 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
if (!array_ptr) array_ptr = ir_get_ref(ira, source_instr, array, true, false);
- IrInstruction *result = ir_build_slice(&ira->new_irb, source_instr->scope,
- source_instr->source_node, array_ptr, start, end, false);
- result->value.type = wanted_type;
+ if (result_loc == nullptr) result_loc = no_result_loc();
+ IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr);
+ if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
+ return result_loc_inst;
+ }
+ IrInstruction *result = ir_build_slice_gen(ira, source_instr, wanted_type, array_ptr, start, end, false, result_loc_inst);
result->value.data.rh_slice.id = RuntimeHintSliceIdLen;
result->value.data.rh_slice.len = array_type->data.array.len;
- ir_add_alloca(ira, result, result->value.type);
return result;
}
@@ -11929,7 +11983,7 @@ static bool is_pointery_and_elem_is_not_pointery(ZigType *ty) {
}
static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr,
- ZigType *wanted_type, IrInstruction *value)
+ ZigType *wanted_type, IrInstruction *value, ResultLoc *result_loc)
{
Error err;
ZigType *actual_type = value->value.type;
@@ -12017,11 +12071,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
actual_type->id == ZigTypeIdComptimeInt ||
actual_type->id == ZigTypeIdComptimeFloat)
{
- IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value);
+ IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value, nullptr);
if (type_is_invalid(cast1->value.type))
return ira->codegen->invalid_instruction;
- IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1);
+ IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1, result_loc);
if (type_is_invalid(cast2->value.type))
return ira->codegen->invalid_instruction;
@@ -12103,7 +12157,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,
source_node, false).id == ConstCastResultIdOk)
{
- return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type);
+ return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type, result_loc);
}
}
@@ -12120,11 +12174,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,
source_node, false).id == ConstCastResultIdOk)
{
- IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value);
+ IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value, nullptr);
if (type_is_invalid(cast1->value.type))
return ira->codegen->invalid_instruction;
- IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1);
+ IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1, result_loc);
if (type_is_invalid(cast2->value.type))
return ira->codegen->invalid_instruction;
@@ -12167,7 +12221,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
array_type->data.array.child_type, source_node,
!slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk)
{
- return ir_resolve_ptr_of_array_to_slice(ira, source_instr, value, wanted_type);
+ return ir_resolve_ptr_of_array_to_slice(ira, source_instr, value, wanted_type, result_loc);
}
}
@@ -12198,11 +12252,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,
source_node, false).id == ConstCastResultIdOk)
{
- IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value);
+ IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value, nullptr);
if (type_is_invalid(cast1->value.type))
return ira->codegen->invalid_instruction;
- IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1);
+ IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1, result_loc);
if (type_is_invalid(cast2->value.type))
return ira->codegen->invalid_instruction;
@@ -12380,7 +12434,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
return ira->codegen->invalid_instruction;
}
-static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type) {
+static IrInstruction *ir_implicit_cast_with_result(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type,
+ ResultLoc *result_loc)
+{
assert(value);
assert(value != ira->codegen->invalid_instruction);
assert(!expected_type || !type_is_invalid(expected_type));
@@ -12393,7 +12449,11 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Zig
if (value->value.type->id == ZigTypeIdUnreachable)
return value;
- return ir_analyze_cast(ira, value, expected_type, value);
+ return ir_analyze_cast(ira, value, expected_type, value, result_loc);
+}
+
+static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type) {
+ return ir_implicit_cast_with_result(ira, value, expected_type, nullptr);
}
static 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
if (type_is_invalid(target->value.type))
return ira->codegen->invalid_instruction;
- return ir_implicit_cast(ira, target, dest_type);
+ return ir_implicit_cast_with_result(ira, target, dest_type, instruction->result_loc);
}
static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrInstructionResolveResult *instruction) {
@@ -15687,7 +15747,8 @@ static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionC
IrInstruction *arg = call_instruction->args[0]->child;
- IrInstruction *cast_instruction = ir_analyze_cast(ira, &call_instruction->base, dest_type, arg);
+ IrInstruction *cast_instruction = ir_analyze_cast(ira, &call_instruction->base, dest_type, arg,
+ call_instruction->result_loc);
if (type_is_invalid(cast_instruction->value.type))
return ira->codegen->invalid_instruction;
return ir_finish_anal(ira, cast_instruction);
@@ -21165,7 +21226,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio
return result;
}
-static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructionSlice *instruction) {
+static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructionSliceSrc *instruction) {
IrInstruction *ptr_ptr = instruction->ptr->child;
if (type_is_invalid(ptr_ptr->value.type))
return ira->codegen->invalid_instruction;
@@ -21454,12 +21515,13 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction
return result;
}
- IrInstruction *new_instruction = ir_build_slice(&ira->new_irb,
- instruction->base.scope, instruction->base.source_node,
- ptr_ptr, casted_start, end, instruction->safety_check_on);
- new_instruction->value.type = return_type;
- ir_add_alloca(ira, new_instruction, return_type);
- return new_instruction;
+ IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
+ return_type, nullptr);
+ if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) {
+ return result_loc;
+ }
+ return ir_build_slice_gen(ira, &instruction->base, return_type,
+ ptr_ptr, casted_start, end, instruction->safety_check_on, result_loc);
}
static IrInstruction *ir_analyze_instruction_member_count(IrAnalyze *ira, IrInstructionMemberCount *instruction) {
@@ -23900,6 +23962,7 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction
case IrInstructionIdCmpxchgGen:
case IrInstructionIdArrayToVector:
case IrInstructionIdVectorToArray:
+ case IrInstructionIdPtrOfArrayToSlice:
case IrInstructionIdAssertZero:
case IrInstructionIdAssertNonNull:
case IrInstructionIdResizeSlice:
@@ -23908,6 +23971,7 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction
case IrInstructionIdCallGen:
case IrInstructionIdReturnPtr:
case IrInstructionIdAllocaGen:
+ case IrInstructionIdSliceGen:
zig_unreachable();
case IrInstructionIdReturn:
@@ -24042,8 +24106,8 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction
return ir_analyze_instruction_memset(ira, (IrInstructionMemset *)instruction);
case IrInstructionIdMemcpy:
return ir_analyze_instruction_memcpy(ira, (IrInstructionMemcpy *)instruction);
- case IrInstructionIdSlice:
- return ir_analyze_instruction_slice(ira, (IrInstructionSlice *)instruction);
+ case IrInstructionIdSliceSrc:
+ return ir_analyze_instruction_slice(ira, (IrInstructionSliceSrc *)instruction);
case IrInstructionIdMemberCount:
return ir_analyze_instruction_member_count(ira, (IrInstructionMemberCount *)instruction);
case IrInstructionIdMemberType:
@@ -24321,6 +24385,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdGlobalAsm:
case IrInstructionIdUndeclaredIdent:
case IrInstructionIdEndExpr:
+ case IrInstructionIdPtrOfArrayToSlice:
+ case IrInstructionIdSliceGen:
return true;
case IrInstructionIdPhi:
@@ -24360,7 +24426,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdIntType:
case IrInstructionIdVectorType:
case IrInstructionIdBoolNot:
- case IrInstructionIdSlice:
+ case IrInstructionIdSliceSrc:
case IrInstructionIdMemberCount:
case IrInstructionIdMemberType:
case IrInstructionIdMemberName:
src/ir_print.cpp
@@ -858,14 +858,26 @@ static void ir_print_memcpy(IrPrint *irp, IrInstructionMemcpy *instruction) {
fprintf(irp->f, ")");
}
-static void ir_print_slice(IrPrint *irp, IrInstructionSlice *instruction) {
+static void ir_print_slice_src(IrPrint *irp, IrInstructionSliceSrc *instruction) {
ir_print_other_instruction(irp, instruction->ptr);
fprintf(irp->f, "[");
ir_print_other_instruction(irp, instruction->start);
fprintf(irp->f, "..");
if (instruction->end)
ir_print_other_instruction(irp, instruction->end);
- fprintf(irp->f, "]");
+ fprintf(irp->f, "]result=");
+ ir_print_result_loc(irp, instruction->result_loc);
+}
+
+static void ir_print_slice_gen(IrPrint *irp, IrInstructionSliceGen *instruction) {
+ ir_print_other_instruction(irp, instruction->ptr);
+ fprintf(irp->f, "[");
+ ir_print_other_instruction(irp, instruction->start);
+ fprintf(irp->f, "..");
+ if (instruction->end)
+ ir_print_other_instruction(irp, instruction->end);
+ fprintf(irp->f, "]result=");
+ ir_print_other_instruction(irp, instruction->result_loc);
}
static void ir_print_member_count(IrPrint *irp, IrInstructionMemberCount *instruction) {
@@ -1086,6 +1098,13 @@ static void ir_print_vector_to_array(IrPrint *irp, IrInstructionVectorToArray *i
fprintf(irp->f, ")");
}
+static void ir_print_ptr_of_array_to_slice(IrPrint *irp, IrInstructionPtrOfArrayToSlice *instruction) {
+ fprintf(irp->f, "PtrOfArrayToSlice(");
+ ir_print_other_instruction(irp, instruction->operand);
+ fprintf(irp->f, ")result=");
+ ir_print_other_instruction(irp, instruction->result_loc);
+}
+
static void ir_print_assert_zero(IrPrint *irp, IrInstructionAssertZero *instruction) {
fprintf(irp->f, "AssertZero(");
ir_print_other_instruction(irp, instruction->target);
@@ -1758,8 +1777,11 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
case IrInstructionIdMemcpy:
ir_print_memcpy(irp, (IrInstructionMemcpy *)instruction);
break;
- case IrInstructionIdSlice:
- ir_print_slice(irp, (IrInstructionSlice *)instruction);
+ case IrInstructionIdSliceSrc:
+ ir_print_slice_src(irp, (IrInstructionSliceSrc *)instruction);
+ break;
+ case IrInstructionIdSliceGen:
+ ir_print_slice_gen(irp, (IrInstructionSliceGen *)instruction);
break;
case IrInstructionIdMemberCount:
ir_print_member_count(irp, (IrInstructionMemberCount *)instruction);
@@ -1992,6 +2014,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
case IrInstructionIdVectorToArray:
ir_print_vector_to_array(irp, (IrInstructionVectorToArray *)instruction);
break;
+ case IrInstructionIdPtrOfArrayToSlice:
+ ir_print_ptr_of_array_to_slice(irp, (IrInstructionPtrOfArrayToSlice *)instruction);
+ break;
case IrInstructionIdAssertZero:
ir_print_assert_zero(irp, (IrInstructionAssertZero *)instruction);
break;
BRANCH_TODO
@@ -20,6 +20,3 @@ inferred comptime
// an instruction which just makes a pointer of it.
return ir_build_ref(irb, scope, value->source_node, value, false, false);
-handle if with no else
-
-