authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-08-26 13:29:24-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-08-26 13:29:24-04:00
loge726925e802eddab53cbfd9aacbc5eefe95c356f
treedd32cbabb1e04929090761bb1129c8b27ee38ce1
parent3a4ea41fe891b5b0b9b50cb80200a392e20cc31f

remove @alignOf and add @cAbiAlignOf and @preferredAlignOf

See #396

5 files changed, 173 insertions(+), 34 deletions(-)

src/all_types.hpp+11-3
......@@ -1184,7 +1184,8 @@ enum BuiltinFnId {
11841184 BuiltinFnIdMemcpy,
11851185 BuiltinFnIdMemset,
11861186 BuiltinFnIdSizeof,
1187 BuiltinFnIdAlignof,
1187 BuiltinFnIdPreferredAlignOf,
1188 BuiltinFnIdAbiAlignOf,
11881189 BuiltinFnIdMaxValue,
11891190 BuiltinFnIdMinValue,
11901191 BuiltinFnIdMemberCount,
......@@ -1805,7 +1806,8 @@ enum IrInstructionId {
18051806 IrInstructionIdBreakpoint,
18061807 IrInstructionIdReturnAddress,
18071808 IrInstructionIdFrameAddress,
1808 IrInstructionIdAlignOf,
1809 IrInstructionIdPreferredAlignOf,
1810 IrInstructionIdAbiAlignOf,
18091811 IrInstructionIdOverflowOp,
18101812 IrInstructionIdTestErr,
18111813 IrInstructionIdUnwrapErrCode,
......@@ -2389,7 +2391,13 @@ struct IrInstructionOverflowOp {
23892391 TypeTableEntry *result_ptr_type;
23902392};
23912393
2392struct IrInstructionAlignOf {
2394struct IrInstructionPreferredAlignOf {
2395 IrInstruction base;
2396
2397 IrInstruction *type_value;
2398};
2399
2400struct IrInstructionAbiAlignOf {
23932401 IrInstruction base;
23942402
23952403 IrInstruction *type_value;
src/codegen.cpp+4-2
......@@ -3233,7 +3233,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
32333233 case IrInstructionIdEmbedFile:
32343234 case IrInstructionIdIntType:
32353235 case IrInstructionIdMemberCount:
3236 case IrInstructionIdAlignOf:
3236 case IrInstructionIdPreferredAlignOf:
3237 case IrInstructionIdAbiAlignOf:
32373238 case IrInstructionIdFnProto:
32383239 case IrInstructionIdTestComptime:
32393240 case IrInstructionIdCheckSwitchProngs:
......@@ -4594,7 +4595,8 @@ static void define_builtin_fns(CodeGen *g) {
45944595 create_builtin_fn(g, BuiltinFnIdMemcpy, "memcpy", 3);
45954596 create_builtin_fn(g, BuiltinFnIdMemset, "memset", 3);
45964597 create_builtin_fn(g, BuiltinFnIdSizeof, "sizeOf", 1);
4597 create_builtin_fn(g, BuiltinFnIdAlignof, "alignOf", 1);
4598 create_builtin_fn(g, BuiltinFnIdPreferredAlignOf, "preferredAlignOf", 1);
4599 create_builtin_fn(g, BuiltinFnIdAbiAlignOf, "cAbiAlignOf", 1);
45984600 create_builtin_fn(g, BuiltinFnIdMaxValue, "maxValue", 1);
45994601 create_builtin_fn(g, BuiltinFnIdMinValue, "minValue", 1);
46004602 create_builtin_fn(g, BuiltinFnIdMemberCount, "memberCount", 1);
src/ir.cpp+139-22
......@@ -422,8 +422,12 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionFrameAddress *)
422422 return IrInstructionIdFrameAddress;
423423}
424424
425static constexpr IrInstructionId ir_instruction_id(IrInstructionAlignOf *) {
426 return IrInstructionIdAlignOf;
425static constexpr IrInstructionId ir_instruction_id(IrInstructionPreferredAlignOf *) {
426 return IrInstructionIdPreferredAlignOf;
427}
428
429static constexpr IrInstructionId ir_instruction_id(IrInstructionAbiAlignOf *) {
430 return IrInstructionIdAbiAlignOf;
427431}
428432
429433static constexpr IrInstructionId ir_instruction_id(IrInstructionOverflowOp *) {
......@@ -1806,8 +1810,17 @@ static IrInstruction *ir_build_overflow_op_from(IrBuilder *irb, IrInstruction *o
18061810 return new_instruction;
18071811}
18081812
1809static IrInstruction *ir_build_alignof(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value) {
1810 IrInstructionAlignOf *instruction = ir_build_instruction<IrInstructionAlignOf>(irb, scope, source_node);
1813static IrInstruction *ir_build_preferred_align_of(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value) {
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
1822static 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);
18111824 instruction->type_value = type_value;
18121825
18131826 ir_ref_instruction(type_value, irb->current_basic_block);
......@@ -2658,7 +2671,14 @@ static IrInstruction *ir_instruction_frameaddress_get_dep(IrInstructionFrameAddr
26582671 return nullptr;
26592672}
26602673
2661static IrInstruction *ir_instruction_alignof_get_dep(IrInstructionAlignOf *instruction, size_t index) {
2674static 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
2681static IrInstruction *ir_instruction_abialignof_get_dep(IrInstructionAbiAlignOf *instruction, size_t index) {
26622682 switch (index) {
26632683 case 0: return instruction->type_value;
26642684 default: return nullptr;
......@@ -3036,8 +3056,10 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
30363056 return ir_instruction_returnaddress_get_dep((IrInstructionReturnAddress *) instruction, index);
30373057 case IrInstructionIdFrameAddress:
30383058 return ir_instruction_frameaddress_get_dep((IrInstructionFrameAddress *) instruction, index);
3039 case IrInstructionIdAlignOf:
3040 return ir_instruction_alignof_get_dep((IrInstructionAlignOf *) instruction, index);
3059 case IrInstructionIdPreferredAlignOf:
3060 return ir_instruction_preferredalignof_get_dep((IrInstructionPreferredAlignOf *) instruction, index);
3061 case IrInstructionIdAbiAlignOf:
3062 return ir_instruction_abialignof_get_dep((IrInstructionAbiAlignOf *) instruction, index);
30413063 case IrInstructionIdOverflowOp:
30423064 return ir_instruction_overflowop_get_dep((IrInstructionOverflowOp *) instruction, index);
30433065 case IrInstructionIdTestErr:
......@@ -4264,14 +4286,23 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
42644286 return ir_build_return_address(irb, scope, node);
42654287 case BuiltinFnIdFrameAddress:
42664288 return ir_build_frame_address(irb, scope, node);
4267 case BuiltinFnIdAlignof:
4289 case BuiltinFnIdPreferredAlignOf:
42684290 {
42694291 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
42704292 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
42714293 if (arg0_value == irb->codegen->invalid_instruction)
42724294 return arg0_value;
42734295
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);
42754306 }
42764307 case BuiltinFnIdAddWithOverflow:
42774308 return ir_gen_overflow_op(irb, scope, node, IrOverflowOpAdd);
......@@ -13829,25 +13860,108 @@ static TypeTableEntry *ir_analyze_instruction_frame_address(IrAnalyze *ira, IrIn
1382913860 return u8_ptr_const;
1383013861}
1383113862
13832static TypeTableEntry *ir_analyze_instruction_alignof(IrAnalyze *ira, IrInstructionAlignOf *instruction) {
13863static TypeTableEntry *ir_analyze_instruction_preferred_align_of(IrAnalyze *ira, IrInstructionPreferredAlignOf *instruction) {
1383313864 IrInstruction *type_value = instruction->type_value->other;
1383413865 if (type_is_invalid(type_value->value.type))
1383513866 return ira->codegen->builtin_types.entry_invalid;
1383613867 TypeTableEntry *type_entry = ir_resolve_type(ira, type_value);
1383713868
1383813869 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
13915static 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))
1384013918 return ira->codegen->builtin_types.entry_invalid;
13841 } else if (type_entry->id == TypeTableEntryIdUnreachable) {
13842 ir_add_error(ira, instruction->type_value,
13843 buf_sprintf("no align available for type '%s'", buf_ptr(&type_entry->name)));
13919 TypeTableEntry *type_entry = ir_resolve_type(ira, type_value);
13920
13921 ensure_complete_type(ira->codegen, type_entry);
13922 if (type_is_invalid(type_entry))
1384413923 return ira->codegen->builtin_types.entry_invalid;
13845 } else {
13846 uint64_t align_in_bytes = LLVMABIAlignmentOfType(ira->codegen->target_data_ref, type_entry->type_ref);
13847 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
13848 bigint_init_unsigned(&out_val->data.x_bigint, align_in_bytes);
13849 return ira->codegen->builtin_types.entry_num_lit_int;
13924
13925 switch (type_entry->id) {
13926 case TypeTableEntryIdInvalid:
13927 case TypeTableEntryIdVar:
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 }
1385013963 }
13964 zig_unreachable();
1385113965}
1385213966
1385313967static TypeTableEntry *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstructionOverflowOp *instruction) {
......@@ -14838,8 +14952,10 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
1483814952 return ir_analyze_instruction_return_address(ira, (IrInstructionReturnAddress *)instruction);
1483914953 case IrInstructionIdFrameAddress:
1484014954 return ir_analyze_instruction_frame_address(ira, (IrInstructionFrameAddress *)instruction);
14841 case IrInstructionIdAlignOf:
14842 return ir_analyze_instruction_alignof(ira, (IrInstructionAlignOf *)instruction);
14955 case IrInstructionIdPreferredAlignOf:
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);
1484314959 case IrInstructionIdOverflowOp:
1484414960 return ir_analyze_instruction_overflow_op(ira, (IrInstructionOverflowOp *)instruction);
1484514961 case IrInstructionIdTestErr:
......@@ -15035,7 +15151,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
1503515151 case IrInstructionIdBoolNot:
1503615152 case IrInstructionIdSlice:
1503715153 case IrInstructionIdMemberCount:
15038 case IrInstructionIdAlignOf:
15154 case IrInstructionIdPreferredAlignOf:
15155 case IrInstructionIdAbiAlignOf:
1503915156 case IrInstructionIdReturnAddress:
1504015157 case IrInstructionIdFrameAddress:
1504115158 case IrInstructionIdTestErr:
src/ir_print.cpp+13-4
......@@ -664,8 +664,14 @@ static void ir_print_return_address(IrPrint *irp, IrInstructionReturnAddress *in
664664 fprintf(irp->f, "@returnAddress()");
665665}
666666
667static void ir_print_alignof(IrPrint *irp, IrInstructionAlignOf *instruction) {
668 fprintf(irp->f, "@alignOf(");
667static void ir_print_preferred_align_of(IrPrint *irp, IrInstructionPreferredAlignOf *instruction) {
668 fprintf(irp->f, "@preferredAlignOf(");
669 ir_print_other_instruction(irp, instruction->type_value);
670 fprintf(irp->f, ")");
671}
672
673static void ir_print_abi_align_of(IrPrint *irp, IrInstructionAbiAlignOf *instruction) {
674 fprintf(irp->f, "@abiAlignOf(");
669675 ir_print_other_instruction(irp, instruction->type_value);
670676 fprintf(irp->f, ")");
671677}
......@@ -1110,8 +1116,11 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
11101116 case IrInstructionIdFrameAddress:
11111117 ir_print_frame_address(irp, (IrInstructionFrameAddress *)instruction);
11121118 break;
1113 case IrInstructionIdAlignOf:
1114 ir_print_alignof(irp, (IrInstructionAlignOf *)instruction);
1119 case IrInstructionIdPreferredAlignOf:
1120 ir_print_preferred_align_of(irp, (IrInstructionPreferredAlignOf *)instruction);
1121 break;
1122 case IrInstructionIdAbiAlignOf:
1123 ir_print_abi_align_of(irp, (IrInstructionAbiAlignOf *)instruction);
11151124 break;
11161125 case IrInstructionIdOverflowOp:
11171126 ir_print_overflow_op(irp, (IrInstructionOverflowOp *)instruction);
test/cases/alignof.zig+6-3
......@@ -3,9 +3,12 @@ const builtin = @import("builtin");
33
44const Foo = struct { x: u32, y: u32, z: u32, };
55
6test "@alignOf(T) before referencing T" {
7 comptime assert(@alignOf(Foo) != @maxValue(usize));
6test "@abiAlignOf(T) before referencing T" {
7 comptime assert(@cAbiAlignOf(Foo) != @maxValue(usize));
88 if (builtin.arch == builtin.Arch.x86_64) {
9 comptime assert(@alignOf(Foo) == 4);
9 comptime {
10 assert(@cAbiAlignOf(Foo) == 4);
11 assert(@preferredAlignOf(Foo) == 8);
12 }
1013 }
1114}