From 59fe13772f63838a84ac1786c0dc8361cd14b99d Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 9 Jun 2019 12:03:15 -0400 Subject: result loc semantics for array initialization ```zig export fn entry() void { var x = [3]Bar{ bar(), bar(), Bar{ .y = 12 } }; } ``` ```llvm define void @entry() #2 !dbg !35 { Entry: %x = alloca [3 x %Bar], align 4 %0 = getelementptr inbounds [3 x %Bar], [3 x %Bar]* %x, i64 0, i64 0, !dbg !48 call fastcc void @bar(%Bar* sret %0), !dbg !48 %1 = getelementptr inbounds [3 x %Bar], [3 x %Bar]* %x, i64 0, i64 1, !dbg !49 call fastcc void @bar(%Bar* sret %1), !dbg !49 %2 = getelementptr inbounds [3 x %Bar], [3 x %Bar]* %x, i64 0, i64 2, !dbg !50 %3 = bitcast %Bar* %2 to i8*, !dbg !50 call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %3, i8* align 4 bitcast (%Bar* @0 to i8*), i64 4, i1 false), !dbg !50 call void @llvm.dbg.declare(metadata [3 x %Bar]* %x, metadata !39, metadata !DIExpression()), !dbg !51 ret void, !dbg !52 } ``` --- src/ir.cpp | 52 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 18 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index bea6d2702d..2ad36a81f2 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -5565,6 +5565,11 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A case ContainerInitKindStruct: { src_assert(result_loc->scope_elide == nullptr, node); result_loc->scope_elide = create_elide_scope(irb->codegen, node, scope); + + src_assert(result_loc != nullptr, node); + IrInstruction *container_ptr = ir_build_resolve_result(irb, &result_loc->scope_elide->base, + node, result_loc, container_type); + size_t field_count = container_init_expr->entries.length; IrInstructionContainerInitFieldsField *fields = allocate(field_count); for (size_t i = 0; i < field_count; i += 1) { @@ -5574,18 +5579,13 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A Buf *name = entry_node->data.struct_val_field.name; AstNode *expr_node = entry_node->data.struct_val_field.expr; - ResultLoc *child_result_loc = nullptr; - if (result_loc != nullptr) { - IrInstruction *container_ptr = ir_build_resolve_result(irb, &result_loc->scope_elide->base, - expr_node, result_loc, container_type); - IrInstruction *field_ptr = ir_build_field_ptr(irb, &result_loc->scope_elide->base, expr_node, - container_ptr, name); - ResultLocInstruction *result_loc_inst = allocate(1); - result_loc_inst->base.id = ResultLocIdInstruction; - result_loc_inst->base.source_instruction = field_ptr; - ir_ref_instruction(field_ptr, irb->current_basic_block); - child_result_loc = &result_loc_inst->base; - } + IrInstruction *field_ptr = ir_build_field_ptr(irb, &result_loc->scope_elide->base, expr_node, + container_ptr, name); + ResultLocInstruction *result_loc_inst = allocate(1); + result_loc_inst->base.id = ResultLocIdInstruction; + result_loc_inst->base.source_instruction = field_ptr; + ir_ref_instruction(field_ptr, irb->current_basic_block); + ResultLoc *child_result_loc = &result_loc_inst->base; IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, &result_loc->scope_elide->base, LValNone, child_result_loc); @@ -5601,11 +5601,28 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A return ir_lval_wrap(irb, scope, init_fields, lval, result_loc); } case ContainerInitKindArray: { + src_assert(result_loc->scope_elide == nullptr, node); + result_loc->scope_elide = create_elide_scope(irb->codegen, node, scope); + + src_assert(result_loc != nullptr, node); + IrInstruction *container_ptr = ir_build_resolve_result(irb, &result_loc->scope_elide->base, + node, result_loc, container_type); + size_t item_count = container_init_expr->entries.length; IrInstruction **values = allocate(item_count); for (size_t i = 0; i < item_count; i += 1) { AstNode *expr_node = container_init_expr->entries.at(i); - IrInstruction *expr_value = ir_gen_node(irb, expr_node, scope); + + IrInstruction *elem_index = ir_build_const_usize(irb, &result_loc->scope_elide->base, expr_node, i); + IrInstruction *elem_ptr = ir_build_elem_ptr(irb, &result_loc->scope_elide->base, expr_node, + container_ptr, elem_index, false, PtrLenSingle); + ResultLocInstruction *result_loc_inst = allocate(1); + result_loc_inst->base.id = ResultLocIdInstruction; + result_loc_inst->base.source_instruction = elem_ptr; + ir_ref_instruction(elem_ptr, irb->current_basic_block); + ResultLoc *child_result_loc = &result_loc_inst->base; + + IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, child_result_loc); if (expr_value == irb->codegen->invalid_instruction) return expr_value; @@ -18594,11 +18611,10 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, return ira->codegen->invalid_instruction; } - IrInstruction *new_instruction = ir_build_container_init_list(&ira->new_irb, - instruction->base.scope, instruction->base.source_node, - nullptr, elem_count, new_items); - new_instruction->value.type = fixed_size_array_type; - ir_add_alloca(ira, new_instruction, fixed_size_array_type); + // this instruction should not get to codegen + IrInstruction *new_instruction = ir_const(ira, &instruction->base, fixed_size_array_type); + // this is how we signal to EndExpr the value is not comptime known + new_instruction->value.special = ConstValSpecialRuntime; return new_instruction; } else if (container_type->id == ZigTypeIdVoid) { if (elem_count != 0) { -- cgit v1.2.3