| ... | ... | @@ -523,14 +523,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeOf *) { |
| 523 | 523 | return IrInstructionIdTypeOf; |
| 524 | 524 | } |
| 525 | 525 | |
| 526 | | static constexpr IrInstructionId ir_instruction_id(IrInstructionToPtrType *) { |
| 527 | | return IrInstructionIdToPtrType; |
| 528 | | } |
| 529 | | |
| 530 | | static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrTypeChild *) { |
| 531 | | return IrInstructionIdPtrTypeChild; |
| 532 | | } |
| 533 | | |
| 534 | 526 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSetCold *) { |
| 535 | 527 | return IrInstructionIdSetCold; |
| 536 | 528 | } |
| ... | ... | @@ -1657,27 +1649,6 @@ static IrInstruction *ir_build_typeof(IrBuilder *irb, Scope *scope, AstNode *sou |
| 1657 | 1649 | return &instruction->base; |
| 1658 | 1650 | } |
| 1659 | 1651 | |
| 1660 | | static IrInstruction *ir_build_to_ptr_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *ptr) { |
| 1661 | | IrInstructionToPtrType *instruction = ir_build_instruction<IrInstructionToPtrType>(irb, scope, source_node); |
| 1662 | | instruction->ptr = ptr; |
| 1663 | | |
| 1664 | | ir_ref_instruction(ptr, irb->current_basic_block); |
| 1665 | | |
| 1666 | | return &instruction->base; |
| 1667 | | } |
| 1668 | | |
| 1669 | | static IrInstruction *ir_build_ptr_type_child(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1670 | | IrInstruction *value) |
| 1671 | | { |
| 1672 | | IrInstructionPtrTypeChild *instruction = ir_build_instruction<IrInstructionPtrTypeChild>( |
| 1673 | | irb, scope, source_node); |
| 1674 | | instruction->value = value; |
| 1675 | | |
| 1676 | | ir_ref_instruction(value, irb->current_basic_block); |
| 1677 | | |
| 1678 | | return &instruction->base; |
| 1679 | | } |
| 1680 | | |
| 1681 | 1652 | static IrInstruction *ir_build_set_cold(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *is_cold) { |
| 1682 | 1653 | IrInstructionSetCold *instruction = ir_build_instruction<IrInstructionSetCold>(irb, scope, source_node); |
| 1683 | 1654 | instruction->is_cold = is_cold; |
| ... | ... | @@ -5611,6 +5582,14 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A |
| 5611 | 5582 | } |
| 5612 | 5583 | } |
| 5613 | 5584 | |
| 5585 | static ResultLocVar *create_var_result_loc(IrInstruction *alloca, ZigVar *var) { |
| 5586 | ResultLocVar *result_loc_var = allocate<ResultLocVar>(1); |
| 5587 | result_loc_var->base.id = ResultLocIdVar; |
| 5588 | result_loc_var->base.source_instruction = alloca; |
| 5589 | result_loc_var->var = var; |
| 5590 | return result_loc_var; |
| 5591 | } |
| 5592 | |
| 5614 | 5593 | static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 5615 | 5594 | assert(node->type == NodeTypeVariableDeclaration); |
| 5616 | 5595 | |
| ... | ... | @@ -5669,10 +5648,7 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod |
| 5669 | 5648 | buf_ptr(variable_declaration->symbol), is_comptime); |
| 5670 | 5649 | |
| 5671 | 5650 | // Create a result location for the initialization expression. |
| 5672 | | ResultLocVar *result_loc_var = allocate<ResultLocVar>(1); |
| 5673 | | result_loc_var->base.id = ResultLocIdVar; |
| 5674 | | result_loc_var->base.source_instruction = alloca; |
| 5675 | | result_loc_var->var = var; |
| 5651 | ResultLocVar *result_loc_var = create_var_result_loc(alloca, var); |
| 5676 | 5652 | ResultLoc *init_result_loc = (type_instruction == nullptr) ? &result_loc_var->base : nullptr; |
| 5677 | 5653 | |
| 5678 | 5654 | // Temporarily set the name of the IrExecutable to the VariableDeclaration |
| ... | ... | @@ -5975,73 +5951,62 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo |
| 5975 | 5951 | if (array_val_ptr == irb->codegen->invalid_instruction) |
| 5976 | 5952 | return array_val_ptr; |
| 5977 | 5953 | |
| 5978 | | IrInstruction *pointer_type = ir_build_to_ptr_type(irb, parent_scope, array_node, array_val_ptr); |
| 5979 | | |
| 5980 | | IrInstruction *elem_var_type; |
| 5981 | | if (node->data.for_expr.elem_is_ptr) { |
| 5982 | | elem_var_type = pointer_type; |
| 5983 | | } else { |
| 5984 | | elem_var_type = ir_build_ptr_type_child(irb, parent_scope, elem_node, pointer_type); |
| 5985 | | } |
| 5986 | | |
| 5987 | 5954 | IrInstruction *is_comptime = ir_build_const_bool(irb, parent_scope, node, |
| 5988 | 5955 | ir_should_inline(irb->exec, parent_scope) || node->data.for_expr.is_inline); |
| 5989 | 5956 | |
| 5990 | | // TODO make it an error to write to element variable or i variable. |
| 5991 | | Buf *elem_var_name = elem_node->data.symbol_expr.symbol; |
| 5992 | | ZigVar *elem_var = ir_create_var(irb, elem_node, parent_scope, elem_var_name, true, false, false, is_comptime); |
| 5993 | | Scope *child_scope = elem_var->child_scope; |
| 5994 | | |
| 5995 | | IrInstruction *undef = ir_build_const_undefined(irb, parent_scope, elem_node); |
| 5996 | | IrInstruction *undef_elem_var_type = ir_build_implicit_cast(irb, parent_scope, elem_node, elem_var_type, undef); |
| 5997 | | ir_build_var_decl_src(irb, child_scope, elem_node, elem_var, nullptr, undef_elem_var_type); |
| 5998 | | IrInstruction *elem_var_ptr = ir_build_var_ptr(irb, child_scope, node, elem_var); |
| 5999 | | |
| 6000 | 5957 | AstNode *index_var_source_node; |
| 6001 | 5958 | ZigVar *index_var; |
| 5959 | const char *index_var_name; |
| 6002 | 5960 | if (index_node) { |
| 6003 | 5961 | index_var_source_node = index_node; |
| 6004 | | Buf *index_var_name = index_node->data.symbol_expr.symbol; |
| 6005 | | index_var = ir_create_var(irb, index_node, child_scope, index_var_name, true, false, false, is_comptime); |
| 5962 | Buf *index_var_name_buf = index_node->data.symbol_expr.symbol; |
| 5963 | index_var = ir_create_var(irb, index_node, parent_scope, index_var_name_buf, true, false, false, is_comptime); |
| 5964 | index_var_name = buf_ptr(index_var_name_buf); |
| 6006 | 5965 | } else { |
| 6007 | 5966 | index_var_source_node = node; |
| 6008 | | index_var = ir_create_var(irb, node, child_scope, nullptr, true, false, true, is_comptime); |
| 5967 | index_var = ir_create_var(irb, node, parent_scope, nullptr, true, false, true, is_comptime); |
| 5968 | index_var_name = "i"; |
| 6009 | 5969 | } |
| 6010 | | child_scope = index_var->child_scope; |
| 5970 | parent_scope = index_var->parent_scope; |
| 6011 | 5971 | |
| 6012 | | IrInstruction *zero = ir_build_const_usize(irb, child_scope, node, 0); |
| 6013 | | IrInstruction *one = ir_build_const_usize(irb, child_scope, node, 1); |
| 6014 | | ir_build_var_decl_src(irb, child_scope, index_var_source_node, index_var, nullptr, zero); |
| 6015 | | IrInstruction *index_ptr = ir_build_var_ptr(irb, child_scope, node, index_var); |
| 5972 | IrInstruction *index_alloca = ir_build_alloca_src(irb, parent_scope, node, nullptr, index_var_name, is_comptime); |
| 5973 | ResultLocVar *var_result_loc = create_var_result_loc(index_alloca, index_var); |
| 5974 | IrInstruction *zero = ir_build_const_usize(irb, parent_scope, node, 0); |
| 5975 | ir_build_end_expr(irb, parent_scope, node, zero, &var_result_loc->base); |
| 5976 | ir_build_var_decl_src(irb, parent_scope, index_var_source_node, index_var, nullptr, index_alloca); |
| 6016 | 5977 | |
| 5978 | IrInstruction *one = ir_build_const_usize(irb, parent_scope, node, 1); |
| 5979 | IrInstruction *index_ptr = ir_build_var_ptr(irb, parent_scope, node, index_var); |
| 6017 | 5980 | |
| 6018 | | IrBasicBlock *cond_block = ir_create_basic_block(irb, child_scope, "ForCond"); |
| 6019 | | IrBasicBlock *body_block = ir_create_basic_block(irb, child_scope, "ForBody"); |
| 6020 | | IrBasicBlock *end_block = ir_create_basic_block(irb, child_scope, "ForEnd"); |
| 6021 | | IrBasicBlock *else_block = else_node ? ir_create_basic_block(irb, child_scope, "ForElse") : end_block; |
| 6022 | | IrBasicBlock *continue_block = ir_create_basic_block(irb, child_scope, "ForContinue"); |
| 5981 | |
| 5982 | IrBasicBlock *cond_block = ir_create_basic_block(irb, parent_scope, "ForCond"); |
| 5983 | IrBasicBlock *body_block = ir_create_basic_block(irb, parent_scope, "ForBody"); |
| 5984 | IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "ForEnd"); |
| 5985 | IrBasicBlock *else_block = else_node ? ir_create_basic_block(irb, parent_scope, "ForElse") : end_block; |
| 5986 | IrBasicBlock *continue_block = ir_create_basic_block(irb, parent_scope, "ForContinue"); |
| 6023 | 5987 | |
| 6024 | 5988 | Buf *len_field_name = buf_create_from_str("len"); |
| 6025 | | IrInstruction *len_ref = ir_build_field_ptr(irb, child_scope, node, array_val_ptr, len_field_name); |
| 6026 | | IrInstruction *len_val = ir_build_load_ptr(irb, child_scope, node, len_ref); |
| 6027 | | ir_build_br(irb, child_scope, node, cond_block, is_comptime); |
| 5989 | IrInstruction *len_ref = ir_build_field_ptr(irb, parent_scope, node, array_val_ptr, len_field_name); |
| 5990 | IrInstruction *len_val = ir_build_load_ptr(irb, parent_scope, node, len_ref); |
| 5991 | ir_build_br(irb, parent_scope, node, cond_block, is_comptime); |
| 6028 | 5992 | |
| 6029 | 5993 | ir_set_cursor_at_end_and_append_block(irb, cond_block); |
| 6030 | | IrInstruction *index_val = ir_build_load_ptr(irb, child_scope, node, index_ptr); |
| 6031 | | IrInstruction *cond = ir_build_bin_op(irb, child_scope, node, IrBinOpCmpLessThan, index_val, len_val, false); |
| 5994 | IrInstruction *index_val = ir_build_load_ptr(irb, parent_scope, node, index_ptr); |
| 5995 | IrInstruction *cond = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpLessThan, index_val, len_val, false); |
| 6032 | 5996 | IrBasicBlock *after_cond_block = irb->current_basic_block; |
| 6033 | 5997 | IrInstruction *void_else_value = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, parent_scope, node)); |
| 6034 | | ir_mark_gen(ir_build_cond_br(irb, child_scope, node, cond, body_block, else_block, is_comptime)); |
| 5998 | ir_mark_gen(ir_build_cond_br(irb, parent_scope, node, cond, body_block, else_block, is_comptime)); |
| 6035 | 5999 | |
| 6036 | 6000 | ir_set_cursor_at_end_and_append_block(irb, body_block); |
| 6037 | | IrInstruction *elem_ptr = ir_build_elem_ptr(irb, child_scope, node, array_val_ptr, index_val, false, PtrLenSingle); |
| 6038 | | IrInstruction *elem_val; |
| 6039 | | if (node->data.for_expr.elem_is_ptr) { |
| 6040 | | elem_val = elem_ptr; |
| 6041 | | } else { |
| 6042 | | elem_val = ir_build_load_ptr(irb, child_scope, node, elem_ptr); |
| 6043 | | } |
| 6044 | | ir_mark_gen(ir_build_store_ptr(irb, child_scope, node, elem_var_ptr, elem_val)); |
| 6001 | IrInstruction *elem_ptr = ir_build_elem_ptr(irb, parent_scope, node, array_val_ptr, index_val, false, PtrLenSingle); |
| 6002 | // TODO make it an error to write to element variable or i variable. |
| 6003 | Buf *elem_var_name = elem_node->data.symbol_expr.symbol; |
| 6004 | ZigVar *elem_var = ir_create_var(irb, elem_node, parent_scope, elem_var_name, true, false, false, is_comptime); |
| 6005 | Scope *child_scope = elem_var->child_scope; |
| 6006 | |
| 6007 | IrInstruction *var_ptr = node->data.for_expr.elem_is_ptr ? |
| 6008 | ir_build_ref(irb, parent_scope, elem_node, elem_ptr, true, false) : elem_ptr; |
| 6009 | ir_build_var_decl_src(irb, parent_scope, elem_node, elem_var, nullptr, var_ptr); |
| 6045 | 6010 | |
| 6046 | 6011 | ZigList<IrInstruction *> incoming_values = {0}; |
| 6047 | 6012 | ZigList<IrBasicBlock *> incoming_blocks = {0}; |
| ... | ... | @@ -16901,64 +16866,6 @@ static IrInstruction *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructio |
| 16901 | 16866 | return ir_const_type(ira, &typeof_instruction->base, type_entry); |
| 16902 | 16867 | } |
| 16903 | 16868 | |
| 16904 | | static IrInstruction *ir_analyze_instruction_to_ptr_type(IrAnalyze *ira, |
| 16905 | | IrInstructionToPtrType *to_ptr_type_instruction) |
| 16906 | | { |
| 16907 | | Error err; |
| 16908 | | IrInstruction *ptr_ptr = to_ptr_type_instruction->ptr->child; |
| 16909 | | if (type_is_invalid(ptr_ptr->value.type)) |
| 16910 | | return ira->codegen->invalid_instruction; |
| 16911 | | |
| 16912 | | ZigType *ptr_ptr_type = ptr_ptr->value.type; |
| 16913 | | assert(ptr_ptr_type->id == ZigTypeIdPointer); |
| 16914 | | ZigType *type_entry = ptr_ptr_type->data.pointer.child_type; |
| 16915 | | |
| 16916 | | ZigType *ptr_type; |
| 16917 | | if (type_entry->id == ZigTypeIdArray) { |
| 16918 | | ptr_type = get_pointer_to_type(ira->codegen, type_entry->data.array.child_type, ptr_ptr_type->data.pointer.is_const); |
| 16919 | | } else if (is_array_ref(type_entry)) { |
| 16920 | | ptr_type = get_pointer_to_type(ira->codegen, |
| 16921 | | type_entry->data.pointer.child_type->data.array.child_type, type_entry->data.pointer.is_const); |
| 16922 | | } else if (is_slice(type_entry)) { |
| 16923 | | ZigType *slice_ptr_type = type_entry->data.structure.fields[0].type_entry; |
| 16924 | | ptr_type = adjust_ptr_len(ira->codegen, slice_ptr_type, PtrLenSingle); |
| 16925 | | // If the pointer is over-aligned, we may have to reduce it based on the alignment of the element type. |
| 16926 | | if (slice_ptr_type->data.pointer.explicit_alignment != 0) { |
| 16927 | | ZigType *elem_type = slice_ptr_type->data.pointer.child_type; |
| 16928 | | if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusAlignmentKnown))) |
| 16929 | | return ira->codegen->invalid_instruction; |
| 16930 | | uint32_t elem_align = get_abi_alignment(ira->codegen, elem_type); |
| 16931 | | uint32_t reduced_align = min(elem_align, slice_ptr_type->data.pointer.explicit_alignment); |
| 16932 | | ptr_type = adjust_ptr_align(ira->codegen, ptr_type, reduced_align); |
| 16933 | | } |
| 16934 | | } else if (type_entry->id == ZigTypeIdArgTuple) { |
| 16935 | | zig_panic("TODO for loop on var args"); |
| 16936 | | } else { |
| 16937 | | ir_add_error_node(ira, to_ptr_type_instruction->base.source_node, |
| 16938 | | buf_sprintf("expected array type, found '%s'", buf_ptr(&type_entry->name))); |
| 16939 | | return ira->codegen->invalid_instruction; |
| 16940 | | } |
| 16941 | | |
| 16942 | | return ir_const_type(ira, &to_ptr_type_instruction->base, ptr_type); |
| 16943 | | } |
| 16944 | | |
| 16945 | | static IrInstruction *ir_analyze_instruction_ptr_type_child(IrAnalyze *ira, |
| 16946 | | IrInstructionPtrTypeChild *ptr_type_child_instruction) |
| 16947 | | { |
| 16948 | | IrInstruction *type_value = ptr_type_child_instruction->value->child; |
| 16949 | | ZigType *type_entry = ir_resolve_type(ira, type_value); |
| 16950 | | if (type_is_invalid(type_entry)) |
| 16951 | | return ira->codegen->invalid_instruction; |
| 16952 | | |
| 16953 | | if (type_entry->id != ZigTypeIdPointer) { |
| 16954 | | ir_add_error_node(ira, ptr_type_child_instruction->base.source_node, |
| 16955 | | buf_sprintf("expected pointer type, found '%s'", buf_ptr(&type_entry->name))); |
| 16956 | | return ira->codegen->invalid_instruction; |
| 16957 | | } |
| 16958 | | |
| 16959 | | return ir_const_type(ira, &ptr_type_child_instruction->base, type_entry->data.pointer.child_type); |
| 16960 | | } |
| 16961 | | |
| 16962 | 16869 | static IrInstruction *ir_analyze_instruction_set_cold(IrAnalyze *ira, IrInstructionSetCold *instruction) { |
| 16963 | 16870 | if (ira->new_irb.exec->is_inline) { |
| 16964 | 16871 | // ignore setCold when running functions at compile time |
| ... | ... | @@ -23751,10 +23658,6 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction |
| 23751 | 23658 | return ir_analyze_instruction_phi(ira, (IrInstructionPhi *)instruction); |
| 23752 | 23659 | case IrInstructionIdTypeOf: |
| 23753 | 23660 | return ir_analyze_instruction_typeof(ira, (IrInstructionTypeOf *)instruction); |
| 23754 | | case IrInstructionIdToPtrType: |
| 23755 | | return ir_analyze_instruction_to_ptr_type(ira, (IrInstructionToPtrType *)instruction); |
| 23756 | | case IrInstructionIdPtrTypeChild: |
| 23757 | | return ir_analyze_instruction_ptr_type_child(ira, (IrInstructionPtrTypeChild *)instruction); |
| 23758 | 23661 | case IrInstructionIdSetCold: |
| 23759 | 23662 | return ir_analyze_instruction_set_cold(ira, (IrInstructionSetCold *)instruction); |
| 23760 | 23663 | case IrInstructionIdSetRuntimeSafety: |
| ... | ... | @@ -24152,8 +24055,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 24152 | 24055 | case IrInstructionIdVarPtr: |
| 24153 | 24056 | case IrInstructionIdReturnPtr: |
| 24154 | 24057 | case IrInstructionIdTypeOf: |
| 24155 | | case IrInstructionIdToPtrType: |
| 24156 | | case IrInstructionIdPtrTypeChild: |
| 24157 | 24058 | case IrInstructionIdStructFieldPtr: |
| 24158 | 24059 | case IrInstructionIdUnionFieldPtr: |
| 24159 | 24060 | case IrInstructionIdArrayType: |