| ... | @@ -422,8 +422,12 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionFrameAddress *) | ... | @@ -422,8 +422,12 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionFrameAddress *) |
| 422 | return IrInstructionIdFrameAddress; | 422 | return IrInstructionIdFrameAddress; |
| 423 | } | 423 | } |
| 424 | | 424 | |
| 425 | static constexpr IrInstructionId ir_instruction_id(IrInstructionAlignOf *) { | 425 | static constexpr IrInstructionId ir_instruction_id(IrInstructionPreferredAlignOf *) { |
| 426 | return IrInstructionIdAlignOf; | 426 | return IrInstructionIdPreferredAlignOf; |
| | 427 | } |
| | 428 | |
| | 429 | static constexpr IrInstructionId ir_instruction_id(IrInstructionAbiAlignOf *) { |
| | 430 | return IrInstructionIdAbiAlignOf; |
| 427 | } | 431 | } |
| 428 | | 432 | |
| 429 | static constexpr IrInstructionId ir_instruction_id(IrInstructionOverflowOp *) { | 433 | static constexpr IrInstructionId ir_instruction_id(IrInstructionOverflowOp *) { |
| ... | @@ -1806,8 +1810,17 @@ static IrInstruction *ir_build_overflow_op_from(IrBuilder *irb, IrInstruction *o | ... | @@ -1806,8 +1810,17 @@ static IrInstruction *ir_build_overflow_op_from(IrBuilder *irb, IrInstruction *o |
| 1806 | return new_instruction; | 1810 | return new_instruction; |
| 1807 | } | 1811 | } |
| 1808 | | 1812 | |
| 1809 | static IrInstruction *ir_build_alignof(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value) { | 1813 | static IrInstruction *ir_build_preferred_align_of(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value) { |
| 1810 | IrInstructionAlignOf *instruction = ir_build_instruction<IrInstructionAlignOf>(irb, scope, source_node); | 1814 | IrInstructionPreferredAlignOf *instruction = ir_build_instruction<IrInstructionPreferredAlignOf>(irb, scope, source_node); |
| | 1815 | instruction->type_value = type_value; |
| | 1816 | |
| | 1817 | ir_ref_instruction(type_value, irb->current_basic_block); |
| | 1818 | |
| | 1819 | return &instruction->base; |
| | 1820 | } |
| | 1821 | |
| | 1822 | static IrInstruction *ir_build_abi_align_of(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value) { |
| | 1823 | IrInstructionAbiAlignOf *instruction = ir_build_instruction<IrInstructionAbiAlignOf>(irb, scope, source_node); |
| 1811 | instruction->type_value = type_value; | 1824 | instruction->type_value = type_value; |
| 1812 | | 1825 | |
| 1813 | ir_ref_instruction(type_value, irb->current_basic_block); | 1826 | ir_ref_instruction(type_value, irb->current_basic_block); |
| ... | @@ -2658,7 +2671,14 @@ static IrInstruction *ir_instruction_frameaddress_get_dep(IrInstructionFrameAddr | ... | @@ -2658,7 +2671,14 @@ static IrInstruction *ir_instruction_frameaddress_get_dep(IrInstructionFrameAddr |
| 2658 | return nullptr; | 2671 | return nullptr; |
| 2659 | } | 2672 | } |
| 2660 | | 2673 | |
| 2661 | static IrInstruction *ir_instruction_alignof_get_dep(IrInstructionAlignOf *instruction, size_t index) { | 2674 | static IrInstruction *ir_instruction_preferredalignof_get_dep(IrInstructionPreferredAlignOf *instruction, size_t index) { |
| | 2675 | switch (index) { |
| | 2676 | case 0: return instruction->type_value; |
| | 2677 | default: return nullptr; |
| | 2678 | } |
| | 2679 | } |
| | 2680 | |
| | 2681 | static IrInstruction *ir_instruction_abialignof_get_dep(IrInstructionAbiAlignOf *instruction, size_t index) { |
| 2662 | switch (index) { | 2682 | switch (index) { |
| 2663 | case 0: return instruction->type_value; | 2683 | case 0: return instruction->type_value; |
| 2664 | default: return nullptr; | 2684 | default: return nullptr; |
| ... | @@ -3036,8 +3056,10 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t | ... | @@ -3036,8 +3056,10 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t |
| 3036 | return ir_instruction_returnaddress_get_dep((IrInstructionReturnAddress *) instruction, index); | 3056 | return ir_instruction_returnaddress_get_dep((IrInstructionReturnAddress *) instruction, index); |
| 3037 | case IrInstructionIdFrameAddress: | 3057 | case IrInstructionIdFrameAddress: |
| 3038 | return ir_instruction_frameaddress_get_dep((IrInstructionFrameAddress *) instruction, index); | 3058 | return ir_instruction_frameaddress_get_dep((IrInstructionFrameAddress *) instruction, index); |
| 3039 | case IrInstructionIdAlignOf: | 3059 | case IrInstructionIdPreferredAlignOf: |
| 3040 | return ir_instruction_alignof_get_dep((IrInstructionAlignOf *) instruction, index); | 3060 | return ir_instruction_preferredalignof_get_dep((IrInstructionPreferredAlignOf *) instruction, index); |
| | 3061 | case IrInstructionIdAbiAlignOf: |
| | 3062 | return ir_instruction_abialignof_get_dep((IrInstructionAbiAlignOf *) instruction, index); |
| 3041 | case IrInstructionIdOverflowOp: | 3063 | case IrInstructionIdOverflowOp: |
| 3042 | return ir_instruction_overflowop_get_dep((IrInstructionOverflowOp *) instruction, index); | 3064 | return ir_instruction_overflowop_get_dep((IrInstructionOverflowOp *) instruction, index); |
| 3043 | case IrInstructionIdTestErr: | 3065 | case IrInstructionIdTestErr: |
| ... | @@ -4264,14 +4286,23 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4264,14 +4286,23 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4264 | return ir_build_return_address(irb, scope, node); | 4286 | return ir_build_return_address(irb, scope, node); |
| 4265 | case BuiltinFnIdFrameAddress: | 4287 | case BuiltinFnIdFrameAddress: |
| 4266 | return ir_build_frame_address(irb, scope, node); | 4288 | return ir_build_frame_address(irb, scope, node); |
| 4267 | case BuiltinFnIdAlignof: | 4289 | case BuiltinFnIdPreferredAlignOf: |
| 4268 | { | 4290 | { |
| 4269 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | 4291 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| 4270 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); | 4292 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); |
| 4271 | if (arg0_value == irb->codegen->invalid_instruction) | 4293 | if (arg0_value == irb->codegen->invalid_instruction) |
| 4272 | return arg0_value; | 4294 | return arg0_value; |
| 4273 | | 4295 | |
| 4274 | return ir_build_alignof(irb, scope, node, arg0_value); | 4296 | return ir_build_preferred_align_of(irb, scope, node, arg0_value); |
| | 4297 | } |
| | 4298 | case BuiltinFnIdAbiAlignOf: |
| | 4299 | { |
| | 4300 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| | 4301 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); |
| | 4302 | if (arg0_value == irb->codegen->invalid_instruction) |
| | 4303 | return arg0_value; |
| | 4304 | |
| | 4305 | return ir_build_abi_align_of(irb, scope, node, arg0_value); |
| 4275 | } | 4306 | } |
| 4276 | case BuiltinFnIdAddWithOverflow: | 4307 | case BuiltinFnIdAddWithOverflow: |
| 4277 | return ir_gen_overflow_op(irb, scope, node, IrOverflowOpAdd); | 4308 | return ir_gen_overflow_op(irb, scope, node, IrOverflowOpAdd); |
| ... | @@ -13829,25 +13860,108 @@ static TypeTableEntry *ir_analyze_instruction_frame_address(IrAnalyze *ira, IrIn | ... | @@ -13829,25 +13860,108 @@ static TypeTableEntry *ir_analyze_instruction_frame_address(IrAnalyze *ira, IrIn |
| 13829 | return u8_ptr_const; | 13860 | return u8_ptr_const; |
| 13830 | } | 13861 | } |
| 13831 | | 13862 | |
| 13832 | static TypeTableEntry *ir_analyze_instruction_alignof(IrAnalyze *ira, IrInstructionAlignOf *instruction) { | 13863 | static TypeTableEntry *ir_analyze_instruction_preferred_align_of(IrAnalyze *ira, IrInstructionPreferredAlignOf *instruction) { |
| 13833 | IrInstruction *type_value = instruction->type_value->other; | 13864 | IrInstruction *type_value = instruction->type_value->other; |
| 13834 | if (type_is_invalid(type_value->value.type)) | 13865 | if (type_is_invalid(type_value->value.type)) |
| 13835 | return ira->codegen->builtin_types.entry_invalid; | 13866 | return ira->codegen->builtin_types.entry_invalid; |
| 13836 | TypeTableEntry *type_entry = ir_resolve_type(ira, type_value); | 13867 | TypeTableEntry *type_entry = ir_resolve_type(ira, type_value); |
| 13837 | | 13868 | |
| 13838 | ensure_complete_type(ira->codegen, type_entry); | 13869 | ensure_complete_type(ira->codegen, type_entry); |
| 13839 | if (type_is_invalid(type_entry)) { | 13870 | if (type_is_invalid(type_entry)) |
| | 13871 | return ira->codegen->builtin_types.entry_invalid; |
| | 13872 | |
| | 13873 | switch (type_entry->id) { |
| | 13874 | case TypeTableEntryIdInvalid: |
| | 13875 | case TypeTableEntryIdVar: |
| | 13876 | zig_unreachable(); |
| | 13877 | case TypeTableEntryIdMetaType: |
| | 13878 | case TypeTableEntryIdUnreachable: |
| | 13879 | case TypeTableEntryIdNumLitFloat: |
| | 13880 | case TypeTableEntryIdNumLitInt: |
| | 13881 | case TypeTableEntryIdUndefLit: |
| | 13882 | case TypeTableEntryIdNullLit: |
| | 13883 | case TypeTableEntryIdNamespace: |
| | 13884 | case TypeTableEntryIdBlock: |
| | 13885 | case TypeTableEntryIdBoundFn: |
| | 13886 | case TypeTableEntryIdArgTuple: |
| | 13887 | ir_add_error(ira, instruction->type_value, |
| | 13888 | buf_sprintf("no align available for type '%s'", buf_ptr(&type_entry->name))); |
| | 13889 | return ira->codegen->builtin_types.entry_invalid; |
| | 13890 | case TypeTableEntryIdVoid: |
| | 13891 | case TypeTableEntryIdBool: |
| | 13892 | case TypeTableEntryIdInt: |
| | 13893 | case TypeTableEntryIdFloat: |
| | 13894 | case TypeTableEntryIdPointer: |
| | 13895 | case TypeTableEntryIdArray: |
| | 13896 | case TypeTableEntryIdStruct: |
| | 13897 | case TypeTableEntryIdMaybe: |
| | 13898 | case TypeTableEntryIdErrorUnion: |
| | 13899 | case TypeTableEntryIdPureError: |
| | 13900 | case TypeTableEntryIdEnum: |
| | 13901 | case TypeTableEntryIdEnumTag: |
| | 13902 | case TypeTableEntryIdUnion: |
| | 13903 | case TypeTableEntryIdFn: |
| | 13904 | case TypeTableEntryIdOpaque: |
| | 13905 | { |
| | 13906 | uint64_t align_in_bytes = LLVMPreferredAlignmentOfType(ira->codegen->target_data_ref, type_entry->type_ref); |
| | 13907 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); |
| | 13908 | bigint_init_unsigned(&out_val->data.x_bigint, align_in_bytes); |
| | 13909 | return ira->codegen->builtin_types.entry_num_lit_int; |
| | 13910 | } |
| | 13911 | } |
| | 13912 | zig_unreachable(); |
| | 13913 | } |
| | 13914 | |
| | 13915 | static TypeTableEntry *ir_analyze_instruction_abi_align_of(IrAnalyze *ira, IrInstructionAbiAlignOf *instruction) { |
| | 13916 | IrInstruction *type_value = instruction->type_value->other; |
| | 13917 | if (type_is_invalid(type_value->value.type)) |
| 13840 | return ira->codegen->builtin_types.entry_invalid; | 13918 | return ira->codegen->builtin_types.entry_invalid; |
| 13841 | } else if (type_entry->id == TypeTableEntryIdUnreachable) { | 13919 | TypeTableEntry *type_entry = ir_resolve_type(ira, type_value); |
| 13842 | ir_add_error(ira, instruction->type_value, | 13920 | |
| 13843 | buf_sprintf("no align available for type '%s'", buf_ptr(&type_entry->name))); | 13921 | ensure_complete_type(ira->codegen, type_entry); |
| | 13922 | if (type_is_invalid(type_entry)) |
| 13844 | return ira->codegen->builtin_types.entry_invalid; | 13923 | return ira->codegen->builtin_types.entry_invalid; |
| 13845 | } else { | 13924 | |
| 13846 | uint64_t align_in_bytes = LLVMABIAlignmentOfType(ira->codegen->target_data_ref, type_entry->type_ref); | 13925 | switch (type_entry->id) { |
| 13847 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); | 13926 | case TypeTableEntryIdInvalid: |
| 13848 | bigint_init_unsigned(&out_val->data.x_bigint, align_in_bytes); | 13927 | case TypeTableEntryIdVar: |
| 13849 | return ira->codegen->builtin_types.entry_num_lit_int; | 13928 | zig_unreachable(); |
| | 13929 | case TypeTableEntryIdMetaType: |
| | 13930 | case TypeTableEntryIdUnreachable: |
| | 13931 | case TypeTableEntryIdNumLitFloat: |
| | 13932 | case TypeTableEntryIdNumLitInt: |
| | 13933 | case TypeTableEntryIdUndefLit: |
| | 13934 | case TypeTableEntryIdNullLit: |
| | 13935 | case TypeTableEntryIdNamespace: |
| | 13936 | case TypeTableEntryIdBlock: |
| | 13937 | case TypeTableEntryIdBoundFn: |
| | 13938 | case TypeTableEntryIdArgTuple: |
| | 13939 | ir_add_error(ira, instruction->type_value, |
| | 13940 | buf_sprintf("no align available for type '%s'", buf_ptr(&type_entry->name))); |
| | 13941 | return ira->codegen->builtin_types.entry_invalid; |
| | 13942 | case TypeTableEntryIdVoid: |
| | 13943 | case TypeTableEntryIdBool: |
| | 13944 | case TypeTableEntryIdInt: |
| | 13945 | case TypeTableEntryIdFloat: |
| | 13946 | case TypeTableEntryIdPointer: |
| | 13947 | case TypeTableEntryIdArray: |
| | 13948 | case TypeTableEntryIdStruct: |
| | 13949 | case TypeTableEntryIdMaybe: |
| | 13950 | case TypeTableEntryIdErrorUnion: |
| | 13951 | case TypeTableEntryIdPureError: |
| | 13952 | case TypeTableEntryIdEnum: |
| | 13953 | case TypeTableEntryIdEnumTag: |
| | 13954 | case TypeTableEntryIdUnion: |
| | 13955 | case TypeTableEntryIdFn: |
| | 13956 | case TypeTableEntryIdOpaque: |
| | 13957 | { |
| | 13958 | uint64_t align_in_bytes = LLVMABIAlignmentOfType(ira->codegen->target_data_ref, type_entry->type_ref); |
| | 13959 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); |
| | 13960 | bigint_init_unsigned(&out_val->data.x_bigint, align_in_bytes); |
| | 13961 | return ira->codegen->builtin_types.entry_num_lit_int; |
| | 13962 | } |
| 13850 | } | 13963 | } |
| | 13964 | zig_unreachable(); |
| 13851 | } | 13965 | } |
| 13852 | | 13966 | |
| 13853 | static TypeTableEntry *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstructionOverflowOp *instruction) { | 13967 | static TypeTableEntry *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstructionOverflowOp *instruction) { |
| ... | @@ -14838,8 +14952,10 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi | ... | @@ -14838,8 +14952,10 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 14838 | return ir_analyze_instruction_return_address(ira, (IrInstructionReturnAddress *)instruction); | 14952 | return ir_analyze_instruction_return_address(ira, (IrInstructionReturnAddress *)instruction); |
| 14839 | case IrInstructionIdFrameAddress: | 14953 | case IrInstructionIdFrameAddress: |
| 14840 | return ir_analyze_instruction_frame_address(ira, (IrInstructionFrameAddress *)instruction); | 14954 | return ir_analyze_instruction_frame_address(ira, (IrInstructionFrameAddress *)instruction); |
| 14841 | case IrInstructionIdAlignOf: | 14955 | case IrInstructionIdPreferredAlignOf: |
| 14842 | return ir_analyze_instruction_alignof(ira, (IrInstructionAlignOf *)instruction); | 14956 | return ir_analyze_instruction_preferred_align_of(ira, (IrInstructionPreferredAlignOf *)instruction); |
| | 14957 | case IrInstructionIdAbiAlignOf: |
| | 14958 | return ir_analyze_instruction_abi_align_of(ira, (IrInstructionAbiAlignOf *)instruction); |
| 14843 | case IrInstructionIdOverflowOp: | 14959 | case IrInstructionIdOverflowOp: |
| 14844 | return ir_analyze_instruction_overflow_op(ira, (IrInstructionOverflowOp *)instruction); | 14960 | return ir_analyze_instruction_overflow_op(ira, (IrInstructionOverflowOp *)instruction); |
| 14845 | case IrInstructionIdTestErr: | 14961 | case IrInstructionIdTestErr: |
| ... | @@ -15035,7 +15151,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -15035,7 +15151,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 15035 | case IrInstructionIdBoolNot: | 15151 | case IrInstructionIdBoolNot: |
| 15036 | case IrInstructionIdSlice: | 15152 | case IrInstructionIdSlice: |
| 15037 | case IrInstructionIdMemberCount: | 15153 | case IrInstructionIdMemberCount: |
| 15038 | case IrInstructionIdAlignOf: | 15154 | case IrInstructionIdPreferredAlignOf: |
| | 15155 | case IrInstructionIdAbiAlignOf: |
| 15039 | case IrInstructionIdReturnAddress: | 15156 | case IrInstructionIdReturnAddress: |
| 15040 | case IrInstructionIdFrameAddress: | 15157 | case IrInstructionIdFrameAddress: |
| 15041 | case IrInstructionIdTestErr: | 15158 | case IrInstructionIdTestErr: |