From e726925e802eddab53cbfd9aacbc5eefe95c356f Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sat, 26 Aug 2017 13:29:24 -0400 Subject: remove @alignOf and add @cAbiAlignOf and @preferredAlignOf See #396 --- src/all_types.hpp | 14 ++++- src/codegen.cpp | 6 +- src/ir.cpp | 161 ++++++++++++++++++++++++++++++++++++++++++++++-------- src/ir_print.cpp | 17 ++++-- 4 files changed, 167 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/all_types.hpp b/src/all_types.hpp index 834024e5cf..85fd6b696f 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1184,7 +1184,8 @@ enum BuiltinFnId { BuiltinFnIdMemcpy, BuiltinFnIdMemset, BuiltinFnIdSizeof, - BuiltinFnIdAlignof, + BuiltinFnIdPreferredAlignOf, + BuiltinFnIdAbiAlignOf, BuiltinFnIdMaxValue, BuiltinFnIdMinValue, BuiltinFnIdMemberCount, @@ -1805,7 +1806,8 @@ enum IrInstructionId { IrInstructionIdBreakpoint, IrInstructionIdReturnAddress, IrInstructionIdFrameAddress, - IrInstructionIdAlignOf, + IrInstructionIdPreferredAlignOf, + IrInstructionIdAbiAlignOf, IrInstructionIdOverflowOp, IrInstructionIdTestErr, IrInstructionIdUnwrapErrCode, @@ -2389,7 +2391,13 @@ struct IrInstructionOverflowOp { TypeTableEntry *result_ptr_type; }; -struct IrInstructionAlignOf { +struct IrInstructionPreferredAlignOf { + IrInstruction base; + + IrInstruction *type_value; +}; + +struct IrInstructionAbiAlignOf { IrInstruction base; IrInstruction *type_value; diff --git a/src/codegen.cpp b/src/codegen.cpp index 640bece896..ad014e9e19 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -3233,7 +3233,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, case IrInstructionIdEmbedFile: case IrInstructionIdIntType: case IrInstructionIdMemberCount: - case IrInstructionIdAlignOf: + case IrInstructionIdPreferredAlignOf: + case IrInstructionIdAbiAlignOf: case IrInstructionIdFnProto: case IrInstructionIdTestComptime: case IrInstructionIdCheckSwitchProngs: @@ -4594,7 +4595,8 @@ static void define_builtin_fns(CodeGen *g) { create_builtin_fn(g, BuiltinFnIdMemcpy, "memcpy", 3); create_builtin_fn(g, BuiltinFnIdMemset, "memset", 3); create_builtin_fn(g, BuiltinFnIdSizeof, "sizeOf", 1); - create_builtin_fn(g, BuiltinFnIdAlignof, "alignOf", 1); + create_builtin_fn(g, BuiltinFnIdPreferredAlignOf, "preferredAlignOf", 1); + create_builtin_fn(g, BuiltinFnIdAbiAlignOf, "cAbiAlignOf", 1); create_builtin_fn(g, BuiltinFnIdMaxValue, "maxValue", 1); create_builtin_fn(g, BuiltinFnIdMinValue, "minValue", 1); create_builtin_fn(g, BuiltinFnIdMemberCount, "memberCount", 1); diff --git a/src/ir.cpp b/src/ir.cpp index 39ff969dd6..4256afa9b7 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -422,8 +422,12 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionFrameAddress *) return IrInstructionIdFrameAddress; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionAlignOf *) { - return IrInstructionIdAlignOf; +static constexpr IrInstructionId ir_instruction_id(IrInstructionPreferredAlignOf *) { + return IrInstructionIdPreferredAlignOf; +} + +static constexpr IrInstructionId ir_instruction_id(IrInstructionAbiAlignOf *) { + return IrInstructionIdAbiAlignOf; } static constexpr IrInstructionId ir_instruction_id(IrInstructionOverflowOp *) { @@ -1806,8 +1810,17 @@ static IrInstruction *ir_build_overflow_op_from(IrBuilder *irb, IrInstruction *o return new_instruction; } -static IrInstruction *ir_build_alignof(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value) { - IrInstructionAlignOf *instruction = ir_build_instruction(irb, scope, source_node); +static IrInstruction *ir_build_preferred_align_of(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value) { + IrInstructionPreferredAlignOf *instruction = ir_build_instruction(irb, scope, source_node); + instruction->type_value = type_value; + + ir_ref_instruction(type_value, irb->current_basic_block); + + return &instruction->base; +} + +static IrInstruction *ir_build_abi_align_of(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value) { + IrInstructionAbiAlignOf *instruction = ir_build_instruction(irb, scope, source_node); instruction->type_value = type_value; ir_ref_instruction(type_value, irb->current_basic_block); @@ -2658,7 +2671,14 @@ static IrInstruction *ir_instruction_frameaddress_get_dep(IrInstructionFrameAddr return nullptr; } -static IrInstruction *ir_instruction_alignof_get_dep(IrInstructionAlignOf *instruction, size_t index) { +static IrInstruction *ir_instruction_preferredalignof_get_dep(IrInstructionPreferredAlignOf *instruction, size_t index) { + switch (index) { + case 0: return instruction->type_value; + default: return nullptr; + } +} + +static IrInstruction *ir_instruction_abialignof_get_dep(IrInstructionAbiAlignOf *instruction, size_t index) { switch (index) { case 0: return instruction->type_value; default: return nullptr; @@ -3036,8 +3056,10 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t return ir_instruction_returnaddress_get_dep((IrInstructionReturnAddress *) instruction, index); case IrInstructionIdFrameAddress: return ir_instruction_frameaddress_get_dep((IrInstructionFrameAddress *) instruction, index); - case IrInstructionIdAlignOf: - return ir_instruction_alignof_get_dep((IrInstructionAlignOf *) instruction, index); + case IrInstructionIdPreferredAlignOf: + return ir_instruction_preferredalignof_get_dep((IrInstructionPreferredAlignOf *) instruction, index); + case IrInstructionIdAbiAlignOf: + return ir_instruction_abialignof_get_dep((IrInstructionAbiAlignOf *) instruction, index); case IrInstructionIdOverflowOp: return ir_instruction_overflowop_get_dep((IrInstructionOverflowOp *) instruction, index); case IrInstructionIdTestErr: @@ -4264,14 +4286,23 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo return ir_build_return_address(irb, scope, node); case BuiltinFnIdFrameAddress: return ir_build_frame_address(irb, scope, node); - case BuiltinFnIdAlignof: + case BuiltinFnIdPreferredAlignOf: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); if (arg0_value == irb->codegen->invalid_instruction) return arg0_value; - return ir_build_alignof(irb, scope, node, arg0_value); + return ir_build_preferred_align_of(irb, scope, node, arg0_value); + } + case BuiltinFnIdAbiAlignOf: + { + AstNode *arg0_node = node->data.fn_call_expr.params.at(0); + IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_instruction) + return arg0_value; + + return ir_build_abi_align_of(irb, scope, node, arg0_value); } case BuiltinFnIdAddWithOverflow: return ir_gen_overflow_op(irb, scope, node, IrOverflowOpAdd); @@ -13829,25 +13860,108 @@ static TypeTableEntry *ir_analyze_instruction_frame_address(IrAnalyze *ira, IrIn return u8_ptr_const; } -static TypeTableEntry *ir_analyze_instruction_alignof(IrAnalyze *ira, IrInstructionAlignOf *instruction) { +static TypeTableEntry *ir_analyze_instruction_preferred_align_of(IrAnalyze *ira, IrInstructionPreferredAlignOf *instruction) { IrInstruction *type_value = instruction->type_value->other; if (type_is_invalid(type_value->value.type)) return ira->codegen->builtin_types.entry_invalid; TypeTableEntry *type_entry = ir_resolve_type(ira, type_value); ensure_complete_type(ira->codegen, type_entry); - if (type_is_invalid(type_entry)) { + if (type_is_invalid(type_entry)) + return ira->codegen->builtin_types.entry_invalid; + + switch (type_entry->id) { + case TypeTableEntryIdInvalid: + case TypeTableEntryIdVar: + zig_unreachable(); + case TypeTableEntryIdMetaType: + case TypeTableEntryIdUnreachable: + case TypeTableEntryIdNumLitFloat: + case TypeTableEntryIdNumLitInt: + case TypeTableEntryIdUndefLit: + case TypeTableEntryIdNullLit: + case TypeTableEntryIdNamespace: + case TypeTableEntryIdBlock: + case TypeTableEntryIdBoundFn: + case TypeTableEntryIdArgTuple: + ir_add_error(ira, instruction->type_value, + buf_sprintf("no align available for type '%s'", buf_ptr(&type_entry->name))); + return ira->codegen->builtin_types.entry_invalid; + case TypeTableEntryIdVoid: + case TypeTableEntryIdBool: + case TypeTableEntryIdInt: + case TypeTableEntryIdFloat: + case TypeTableEntryIdPointer: + case TypeTableEntryIdArray: + case TypeTableEntryIdStruct: + case TypeTableEntryIdMaybe: + case TypeTableEntryIdErrorUnion: + case TypeTableEntryIdPureError: + case TypeTableEntryIdEnum: + case TypeTableEntryIdEnumTag: + case TypeTableEntryIdUnion: + case TypeTableEntryIdFn: + case TypeTableEntryIdOpaque: + { + uint64_t align_in_bytes = LLVMPreferredAlignmentOfType(ira->codegen->target_data_ref, type_entry->type_ref); + ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); + bigint_init_unsigned(&out_val->data.x_bigint, align_in_bytes); + return ira->codegen->builtin_types.entry_num_lit_int; + } + } + zig_unreachable(); +} + +static TypeTableEntry *ir_analyze_instruction_abi_align_of(IrAnalyze *ira, IrInstructionAbiAlignOf *instruction) { + IrInstruction *type_value = instruction->type_value->other; + if (type_is_invalid(type_value->value.type)) return ira->codegen->builtin_types.entry_invalid; - } else if (type_entry->id == TypeTableEntryIdUnreachable) { - ir_add_error(ira, instruction->type_value, - buf_sprintf("no align available for type '%s'", buf_ptr(&type_entry->name))); + TypeTableEntry *type_entry = ir_resolve_type(ira, type_value); + + ensure_complete_type(ira->codegen, type_entry); + if (type_is_invalid(type_entry)) return ira->codegen->builtin_types.entry_invalid; - } else { - uint64_t align_in_bytes = LLVMABIAlignmentOfType(ira->codegen->target_data_ref, type_entry->type_ref); - ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); - bigint_init_unsigned(&out_val->data.x_bigint, align_in_bytes); - return ira->codegen->builtin_types.entry_num_lit_int; + + switch (type_entry->id) { + case TypeTableEntryIdInvalid: + case TypeTableEntryIdVar: + zig_unreachable(); + case TypeTableEntryIdMetaType: + case TypeTableEntryIdUnreachable: + case TypeTableEntryIdNumLitFloat: + case TypeTableEntryIdNumLitInt: + case TypeTableEntryIdUndefLit: + case TypeTableEntryIdNullLit: + case TypeTableEntryIdNamespace: + case TypeTableEntryIdBlock: + case TypeTableEntryIdBoundFn: + case TypeTableEntryIdArgTuple: + ir_add_error(ira, instruction->type_value, + buf_sprintf("no align available for type '%s'", buf_ptr(&type_entry->name))); + return ira->codegen->builtin_types.entry_invalid; + case TypeTableEntryIdVoid: + case TypeTableEntryIdBool: + case TypeTableEntryIdInt: + case TypeTableEntryIdFloat: + case TypeTableEntryIdPointer: + case TypeTableEntryIdArray: + case TypeTableEntryIdStruct: + case TypeTableEntryIdMaybe: + case TypeTableEntryIdErrorUnion: + case TypeTableEntryIdPureError: + case TypeTableEntryIdEnum: + case TypeTableEntryIdEnumTag: + case TypeTableEntryIdUnion: + case TypeTableEntryIdFn: + case TypeTableEntryIdOpaque: + { + uint64_t align_in_bytes = LLVMABIAlignmentOfType(ira->codegen->target_data_ref, type_entry->type_ref); + ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); + bigint_init_unsigned(&out_val->data.x_bigint, align_in_bytes); + return ira->codegen->builtin_types.entry_num_lit_int; + } } + zig_unreachable(); } static TypeTableEntry *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstructionOverflowOp *instruction) { @@ -14838,8 +14952,10 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi return ir_analyze_instruction_return_address(ira, (IrInstructionReturnAddress *)instruction); case IrInstructionIdFrameAddress: return ir_analyze_instruction_frame_address(ira, (IrInstructionFrameAddress *)instruction); - case IrInstructionIdAlignOf: - return ir_analyze_instruction_alignof(ira, (IrInstructionAlignOf *)instruction); + case IrInstructionIdPreferredAlignOf: + return ir_analyze_instruction_preferred_align_of(ira, (IrInstructionPreferredAlignOf *)instruction); + case IrInstructionIdAbiAlignOf: + return ir_analyze_instruction_abi_align_of(ira, (IrInstructionAbiAlignOf *)instruction); case IrInstructionIdOverflowOp: return ir_analyze_instruction_overflow_op(ira, (IrInstructionOverflowOp *)instruction); case IrInstructionIdTestErr: @@ -15035,7 +15151,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { case IrInstructionIdBoolNot: case IrInstructionIdSlice: case IrInstructionIdMemberCount: - case IrInstructionIdAlignOf: + case IrInstructionIdPreferredAlignOf: + case IrInstructionIdAbiAlignOf: case IrInstructionIdReturnAddress: case IrInstructionIdFrameAddress: case IrInstructionIdTestErr: diff --git a/src/ir_print.cpp b/src/ir_print.cpp index 291211668e..16afc192e0 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -664,8 +664,14 @@ static void ir_print_return_address(IrPrint *irp, IrInstructionReturnAddress *in fprintf(irp->f, "@returnAddress()"); } -static void ir_print_alignof(IrPrint *irp, IrInstructionAlignOf *instruction) { - fprintf(irp->f, "@alignOf("); +static void ir_print_preferred_align_of(IrPrint *irp, IrInstructionPreferredAlignOf *instruction) { + fprintf(irp->f, "@preferredAlignOf("); + ir_print_other_instruction(irp, instruction->type_value); + fprintf(irp->f, ")"); +} + +static void ir_print_abi_align_of(IrPrint *irp, IrInstructionAbiAlignOf *instruction) { + fprintf(irp->f, "@abiAlignOf("); ir_print_other_instruction(irp, instruction->type_value); fprintf(irp->f, ")"); } @@ -1110,8 +1116,11 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { case IrInstructionIdFrameAddress: ir_print_frame_address(irp, (IrInstructionFrameAddress *)instruction); break; - case IrInstructionIdAlignOf: - ir_print_alignof(irp, (IrInstructionAlignOf *)instruction); + case IrInstructionIdPreferredAlignOf: + ir_print_preferred_align_of(irp, (IrInstructionPreferredAlignOf *)instruction); + break; + case IrInstructionIdAbiAlignOf: + ir_print_abi_align_of(irp, (IrInstructionAbiAlignOf *)instruction); break; case IrInstructionIdOverflowOp: ir_print_overflow_op(irp, (IrInstructionOverflowOp *)instruction); -- cgit v1.2.3