Commit 59fe13772f

Andrew Kelley <andrew@ziglang.org>
2019-06-09 18:03:15
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 } ```
1 parent 3ec766a
Changed files (2)
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<IrInstructionContainerInitFieldsField>(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<ResultLocInstruction>(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<ResultLocInstruction>(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<IrInstruction *>(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<ResultLocInstruction>(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) {
BRANCH_TODO
@@ -1,7 +1,6 @@
 Scratch pad for stuff to do before merging master
 =================================================
 
- * array initializations
  * union initializations
  * bitCast