| ... | @@ -582,7 +582,7 @@ pub const Object = struct { | ... | @@ -582,7 +582,7 @@ pub const Object = struct { |
| 582 | const mod = self.module; | 582 | const mod = self.module; |
| 583 | const target = mod.getTarget(); | 583 | const target = mod.getTarget(); |
| 584 | | 584 | |
| 585 | const llvm_ptr_ty = self.context.intType(8).pointerType(0); // TODO: Address space | 585 | const llvm_ptr_ty = self.context.pointerType(0); // TODO: Address space |
| 586 | const llvm_usize_ty = self.context.intType(target.cpu.arch.ptrBitWidth()); | 586 | const llvm_usize_ty = self.context.intType(target.cpu.arch.ptrBitWidth()); |
| 587 | const type_fields = [_]*llvm.Type{ | 587 | const type_fields = [_]*llvm.Type{ |
| 588 | llvm_ptr_ty, | 588 | llvm_ptr_ty, |
| ... | @@ -608,7 +608,7 @@ pub const Object = struct { | ... | @@ -608,7 +608,7 @@ pub const Object = struct { |
| 608 | str_global.setAlignment(1); | 608 | str_global.setAlignment(1); |
| 609 | | 609 | |
| 610 | const slice_fields = [_]*llvm.Value{ | 610 | const slice_fields = [_]*llvm.Value{ |
| 611 | str_global.constBitCast(llvm_ptr_ty), | 611 | str_global, |
| 612 | llvm_usize_ty.constInt(name.len, .False), | 612 | llvm_usize_ty.constInt(name.len, .False), |
| 613 | }; | 613 | }; |
| 614 | llvm_error.* = llvm_slice_ty.constNamedStruct(&slice_fields, slice_fields.len); | 614 | llvm_error.* = llvm_slice_ty.constNamedStruct(&slice_fields, slice_fields.len); |
| ... | @@ -623,7 +623,7 @@ pub const Object = struct { | ... | @@ -623,7 +623,7 @@ pub const Object = struct { |
| 623 | error_name_table_global.setUnnamedAddr(.True); | 623 | error_name_table_global.setUnnamedAddr(.True); |
| 624 | error_name_table_global.setAlignment(slice_alignment); // TODO: Dont hardcode | 624 | error_name_table_global.setAlignment(slice_alignment); // TODO: Dont hardcode |
| 625 | | 625 | |
| 626 | const error_name_table_ptr = error_name_table_global.constBitCast(llvm_slice_ty.pointerType(0)); // TODO: Address space | 626 | const error_name_table_ptr = error_name_table_global; |
| 627 | error_name_table_ptr_global.setInitializer(error_name_table_ptr); | 627 | error_name_table_ptr_global.setInitializer(error_name_table_ptr); |
| 628 | } | 628 | } |
| 629 | | 629 | |
| ... | @@ -681,10 +681,9 @@ pub const Object = struct { | ... | @@ -681,10 +681,9 @@ pub const Object = struct { |
| 681 | const other_global = object.getLlvmGlobal(decl.name) orelse continue; | 681 | const other_global = object.getLlvmGlobal(decl.name) orelse continue; |
| 682 | if (other_global == llvm_global) continue; | 682 | if (other_global == llvm_global) continue; |
| 683 | | 683 | |
| 684 | const new_global_ptr = other_global.constBitCast(llvm_global.typeOf()); | 684 | llvm_global.replaceAllUsesWith(other_global); |
| 685 | llvm_global.replaceAllUsesWith(new_global_ptr); | | |
| 686 | deleteLlvmGlobal(llvm_global); | 685 | deleteLlvmGlobal(llvm_global); |
| 687 | entry.value_ptr.* = new_global_ptr; | 686 | entry.value_ptr.* = other_global; |
| 688 | } | 687 | } |
| 689 | object.extern_collisions.clearRetainingCapacity(); | 688 | object.extern_collisions.clearRetainingCapacity(); |
| 690 | | 689 | |
| ... | @@ -703,11 +702,7 @@ pub const Object = struct { | ... | @@ -703,11 +702,7 @@ pub const Object = struct { |
| 703 | const other_global = object.getLlvmGlobal(exp_name_z.ptr) orelse continue; | 702 | const other_global = object.getLlvmGlobal(exp_name_z.ptr) orelse continue; |
| 704 | if (other_global == llvm_global) continue; | 703 | if (other_global == llvm_global) continue; |
| 705 | | 704 | |
| 706 | // replaceAllUsesWith requires the type to be unchanged. So we bitcast | 705 | other_global.replaceAllUsesWith(llvm_global); |
| 707 | // the new global to the old type and use that as the thing to replace | | |
| 708 | // old uses. | | |
| 709 | const new_global_ptr = llvm_global.constBitCast(other_global.typeOf()); | | |
| 710 | other_global.replaceAllUsesWith(new_global_ptr); | | |
| 711 | llvm_global.takeName(other_global); | 706 | llvm_global.takeName(other_global); |
| 712 | deleteLlvmGlobal(other_global); | 707 | deleteLlvmGlobal(other_global); |
| 713 | // Problem: now we need to replace in the decl_map that | 708 | // Problem: now we need to replace in the decl_map that |
| ... | @@ -962,7 +957,7 @@ pub const Object = struct { | ... | @@ -962,7 +957,7 @@ pub const Object = struct { |
| 962 | if (isByRef(param_ty)) { | 957 | if (isByRef(param_ty)) { |
| 963 | const alignment = param_ty.abiAlignment(target); | 958 | const alignment = param_ty.abiAlignment(target); |
| 964 | const param_llvm_ty = param.typeOf(); | 959 | const param_llvm_ty = param.typeOf(); |
| 965 | const arg_ptr = buildAllocaInner(builder, llvm_func, false, param_llvm_ty, alignment, target); | 960 | const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, alignment, target); |
| 966 | const store_inst = builder.buildStore(param, arg_ptr); | 961 | const store_inst = builder.buildStore(param, arg_ptr); |
| 967 | store_inst.setAlignment(alignment); | 962 | store_inst.setAlignment(alignment); |
| 968 | args.appendAssumeCapacity(arg_ptr); | 963 | args.appendAssumeCapacity(arg_ptr); |
| ... | @@ -1020,14 +1015,12 @@ pub const Object = struct { | ... | @@ -1020,14 +1015,12 @@ pub const Object = struct { |
| 1020 | const param_llvm_ty = try dg.lowerType(param_ty); | 1015 | const param_llvm_ty = try dg.lowerType(param_ty); |
| 1021 | const abi_size = @intCast(c_uint, param_ty.abiSize(target)); | 1016 | const abi_size = @intCast(c_uint, param_ty.abiSize(target)); |
| 1022 | const int_llvm_ty = dg.context.intType(abi_size * 8); | 1017 | const int_llvm_ty = dg.context.intType(abi_size * 8); |
| 1023 | const int_ptr_llvm_ty = int_llvm_ty.pointerType(0); | | |
| 1024 | const alignment = @max( | 1018 | const alignment = @max( |
| 1025 | param_ty.abiAlignment(target), | 1019 | param_ty.abiAlignment(target), |
| 1026 | dg.object.target_data.abiAlignmentOfType(int_llvm_ty), | 1020 | dg.object.target_data.abiAlignmentOfType(int_llvm_ty), |
| 1027 | ); | 1021 | ); |
| 1028 | const arg_ptr = buildAllocaInner(builder, llvm_func, false, param_llvm_ty, alignment, target); | 1022 | const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, alignment, target); |
| 1029 | const casted_ptr = builder.buildBitCast(arg_ptr, int_ptr_llvm_ty, ""); | 1023 | const store_inst = builder.buildStore(param, arg_ptr); |
| 1030 | const store_inst = builder.buildStore(param, casted_ptr); | | |
| 1031 | store_inst.setAlignment(alignment); | 1024 | store_inst.setAlignment(alignment); |
| 1032 | | 1025 | |
| 1033 | try args.ensureUnusedCapacity(1); | 1026 | try args.ensureUnusedCapacity(1); |
| ... | @@ -1078,14 +1071,13 @@ pub const Object = struct { | ... | @@ -1078,14 +1071,13 @@ pub const Object = struct { |
| 1078 | const param_ty = fn_info.param_types[it.zig_index - 1]; | 1071 | const param_ty = fn_info.param_types[it.zig_index - 1]; |
| 1079 | const param_llvm_ty = try dg.lowerType(param_ty); | 1072 | const param_llvm_ty = try dg.lowerType(param_ty); |
| 1080 | const param_alignment = param_ty.abiAlignment(target); | 1073 | const param_alignment = param_ty.abiAlignment(target); |
| 1081 | const arg_ptr = buildAllocaInner(builder, llvm_func, false, param_llvm_ty, param_alignment, target); | 1074 | const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, param_alignment, target); |
| 1082 | const llvm_ty = dg.context.structType(field_types.ptr, @intCast(c_uint, field_types.len), .False); | 1075 | const llvm_ty = dg.context.structType(field_types.ptr, @intCast(c_uint, field_types.len), .False); |
| 1083 | const casted_ptr = builder.buildBitCast(arg_ptr, llvm_ty.pointerType(0), ""); | | |
| 1084 | for (field_types) |_, field_i_usize| { | 1076 | for (field_types) |_, field_i_usize| { |
| 1085 | const field_i = @intCast(c_uint, field_i_usize); | 1077 | const field_i = @intCast(c_uint, field_i_usize); |
| 1086 | const param = llvm_func.getParam(llvm_arg_i); | 1078 | const param = llvm_func.getParam(llvm_arg_i); |
| 1087 | llvm_arg_i += 1; | 1079 | llvm_arg_i += 1; |
| 1088 | const field_ptr = builder.buildStructGEP(llvm_ty, casted_ptr, field_i, ""); | 1080 | const field_ptr = builder.buildStructGEP(llvm_ty, arg_ptr, field_i, ""); |
| 1089 | const store_inst = builder.buildStore(param, field_ptr); | 1081 | const store_inst = builder.buildStore(param, field_ptr); |
| 1090 | store_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8); | 1082 | store_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8); |
| 1091 | } | 1083 | } |
| ... | @@ -1113,9 +1105,8 @@ pub const Object = struct { | ... | @@ -1113,9 +1105,8 @@ pub const Object = struct { |
| 1113 | llvm_arg_i += 1; | 1105 | llvm_arg_i += 1; |
| 1114 | | 1106 | |
| 1115 | const alignment = param_ty.abiAlignment(target); | 1107 | const alignment = param_ty.abiAlignment(target); |
| 1116 | const arg_ptr = buildAllocaInner(builder, llvm_func, false, param_llvm_ty, alignment, target); | 1108 | const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, alignment, target); |
| 1117 | const casted_ptr = builder.buildBitCast(arg_ptr, param.typeOf().pointerType(0), ""); | 1109 | _ = builder.buildStore(param, arg_ptr); |
| 1118 | _ = builder.buildStore(param, casted_ptr); | | |
| 1119 | | 1110 | |
| 1120 | if (isByRef(param_ty)) { | 1111 | if (isByRef(param_ty)) { |
| 1121 | try args.append(arg_ptr); | 1112 | try args.append(arg_ptr); |
| ... | @@ -1132,9 +1123,8 @@ pub const Object = struct { | ... | @@ -1132,9 +1123,8 @@ pub const Object = struct { |
| 1132 | llvm_arg_i += 1; | 1123 | llvm_arg_i += 1; |
| 1133 | | 1124 | |
| 1134 | const alignment = param_ty.abiAlignment(target); | 1125 | const alignment = param_ty.abiAlignment(target); |
| 1135 | const arg_ptr = buildAllocaInner(builder, llvm_func, false, param_llvm_ty, alignment, target); | 1126 | const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, alignment, target); |
| 1136 | const casted_ptr = builder.buildBitCast(arg_ptr, param.typeOf().pointerType(0), ""); | 1127 | _ = builder.buildStore(param, arg_ptr); |
| 1137 | _ = builder.buildStore(param, casted_ptr); | | |
| 1138 | | 1128 | |
| 1139 | if (isByRef(param_ty)) { | 1129 | if (isByRef(param_ty)) { |
| 1140 | try args.append(arg_ptr); | 1130 | try args.append(arg_ptr); |
| ... | @@ -1938,6 +1928,7 @@ pub const Object = struct { | ... | @@ -1938,6 +1928,7 @@ pub const Object = struct { |
| 1938 | if (ty.castTag(.@"struct")) |payload| { | 1928 | if (ty.castTag(.@"struct")) |payload| { |
| 1939 | const struct_obj = payload.data; | 1929 | const struct_obj = payload.data; |
| 1940 | if (struct_obj.layout == .Packed and struct_obj.haveFieldTypes()) { | 1930 | if (struct_obj.layout == .Packed and struct_obj.haveFieldTypes()) { |
| | 1931 | assert(struct_obj.haveLayout()); |
| 1941 | const info = struct_obj.backing_int_ty.intInfo(target); | 1932 | const info = struct_obj.backing_int_ty.intInfo(target); |
| 1942 | const dwarf_encoding: c_uint = switch (info.signedness) { | 1933 | const dwarf_encoding: c_uint = switch (info.signedness) { |
| 1943 | .signed => DW.ATE.signed, | 1934 | .signed => DW.ATE.signed, |
| ... | @@ -2477,12 +2468,8 @@ pub const DeclGen = struct { | ... | @@ -2477,12 +2468,8 @@ pub const DeclGen = struct { |
| 2477 | new_global.setAlignment(global.getAlignment()); | 2468 | new_global.setAlignment(global.getAlignment()); |
| 2478 | if (decl.@"linksection") |section| new_global.setSection(section); | 2469 | if (decl.@"linksection") |section| new_global.setSection(section); |
| 2479 | new_global.setInitializer(llvm_init); | 2470 | new_global.setInitializer(llvm_init); |
| 2480 | // replaceAllUsesWith requires the type to be unchanged. So we convert | | |
| 2481 | // the new global to the old type and use that as the thing to replace | | |
| 2482 | // old uses. | | |
| 2483 | // TODO: How should this work then the address space of a global changed? | 2471 | // TODO: How should this work then the address space of a global changed? |
| 2484 | const new_global_ptr = new_global.constBitCast(global.typeOf()); | 2472 | global.replaceAllUsesWith(new_global); |
| 2485 | global.replaceAllUsesWith(new_global_ptr); | | |
| 2486 | dg.object.decl_map.putAssumeCapacity(decl_index, new_global); | 2473 | dg.object.decl_map.putAssumeCapacity(decl_index, new_global); |
| 2487 | new_global.takeName(global); | 2474 | new_global.takeName(global); |
| 2488 | global.deleteGlobal(); | 2475 | global.deleteGlobal(); |
| ... | @@ -2781,11 +2768,7 @@ pub const DeclGen = struct { | ... | @@ -2781,11 +2768,7 @@ pub const DeclGen = struct { |
| 2781 | } | 2768 | } |
| 2782 | const ptr_info = t.ptrInfo().data; | 2769 | const ptr_info = t.ptrInfo().data; |
| 2783 | const llvm_addrspace = toLlvmAddressSpace(ptr_info.@"addrspace", target); | 2770 | const llvm_addrspace = toLlvmAddressSpace(ptr_info.@"addrspace", target); |
| 2784 | if (ptr_info.host_size != 0) { | 2771 | return dg.context.pointerType(llvm_addrspace); |
| 2785 | return dg.context.intType(ptr_info.host_size * 8).pointerType(llvm_addrspace); | | |
| 2786 | } | | |
| 2787 | const llvm_elem_ty = try dg.lowerPtrElemTy(ptr_info.pointee_type); | | |
| 2788 | return llvm_elem_ty.pointerType(llvm_addrspace); | | |
| 2789 | }, | 2772 | }, |
| 2790 | .Opaque => switch (t.tag()) { | 2773 | .Opaque => switch (t.tag()) { |
| 2791 | .@"opaque" => { | 2774 | .@"opaque" => { |
| ... | @@ -2949,6 +2932,7 @@ pub const DeclGen = struct { | ... | @@ -2949,6 +2932,7 @@ pub const DeclGen = struct { |
| 2949 | const struct_obj = t.castTag(.@"struct").?.data; | 2932 | const struct_obj = t.castTag(.@"struct").?.data; |
| 2950 | | 2933 | |
| 2951 | if (struct_obj.layout == .Packed) { | 2934 | if (struct_obj.layout == .Packed) { |
| | 2935 | assert(struct_obj.haveLayout()); |
| 2952 | const int_llvm_ty = try dg.lowerType(struct_obj.backing_int_ty); | 2936 | const int_llvm_ty = try dg.lowerType(struct_obj.backing_int_ty); |
| 2953 | gop.value_ptr.* = int_llvm_ty; | 2937 | gop.value_ptr.* = int_llvm_ty; |
| 2954 | return int_llvm_ty; | 2938 | return int_llvm_ty; |
| ... | @@ -3108,8 +3092,7 @@ pub const DeclGen = struct { | ... | @@ -3108,8 +3092,7 @@ pub const DeclGen = struct { |
| 3108 | defer llvm_params.deinit(); | 3092 | defer llvm_params.deinit(); |
| 3109 | | 3093 | |
| 3110 | if (firstParamSRet(fn_info, target)) { | 3094 | if (firstParamSRet(fn_info, target)) { |
| 3111 | const llvm_sret_ty = try dg.lowerType(fn_info.return_type); | 3095 | try llvm_params.append(dg.context.pointerType(0)); |
| 3112 | try llvm_params.append(llvm_sret_ty.pointerType(0)); | | |
| 3113 | } | 3096 | } |
| 3114 | | 3097 | |
| 3115 | if (fn_info.return_type.isError() and | 3098 | if (fn_info.return_type.isError() and |
| ... | @@ -3131,9 +3114,7 @@ pub const DeclGen = struct { | ... | @@ -3131,9 +3114,7 @@ pub const DeclGen = struct { |
| 3131 | try llvm_params.append(try dg.lowerType(param_ty)); | 3114 | try llvm_params.append(try dg.lowerType(param_ty)); |
| 3132 | }, | 3115 | }, |
| 3133 | .byref, .byref_mut => { | 3116 | .byref, .byref_mut => { |
| 3134 | const param_ty = fn_info.param_types[it.zig_index - 1]; | 3117 | try llvm_params.append(dg.context.pointerType(0)); |
| 3135 | const raw_llvm_ty = try dg.lowerType(param_ty); | | |
| 3136 | try llvm_params.append(raw_llvm_ty.pointerType(0)); | | |
| 3137 | }, | 3118 | }, |
| 3138 | .abi_sized_int => { | 3119 | .abi_sized_int => { |
| 3139 | const param_ty = fn_info.param_types[it.zig_index - 1]; | 3120 | const param_ty = fn_info.param_types[it.zig_index - 1]; |
| ... | @@ -3323,16 +3304,12 @@ pub const DeclGen = struct { | ... | @@ -3323,16 +3304,12 @@ pub const DeclGen = struct { |
| 3323 | const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target); | 3304 | const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target); |
| 3324 | const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target); | 3305 | const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target); |
| 3325 | | 3306 | |
| 3326 | const llvm_var_type = try dg.lowerType(tv.ty); | | |
| 3327 | const llvm_actual_ptr_type = llvm_var_type.pointerType(llvm_actual_addrspace); | | |
| 3328 | | | |
| 3329 | const val = try dg.resolveGlobalDecl(decl_index); | 3307 | const val = try dg.resolveGlobalDecl(decl_index); |
| 3330 | const val_ptr = val.constBitCast(llvm_actual_ptr_type); | 3308 | const addrspace_casted_ptr = if (llvm_actual_addrspace != llvm_wanted_addrspace) |
| 3331 | if (llvm_actual_addrspace != llvm_wanted_addrspace) { | 3309 | val.constAddrSpaceCast(dg.context.pointerType(llvm_wanted_addrspace)) |
| 3332 | const llvm_wanted_ptr_type = llvm_var_type.pointerType(llvm_wanted_addrspace); | 3310 | else |
| 3333 | return val_ptr.constAddrSpaceCast(llvm_wanted_ptr_type); | 3311 | val; |
| 3334 | } | 3312 | return addrspace_casted_ptr; |
| 3335 | return val_ptr; | | |
| 3336 | }, | 3313 | }, |
| 3337 | .slice => { | 3314 | .slice => { |
| 3338 | const slice = tv.val.castTag(.slice).?.data; | 3315 | const slice = tv.val.castTag(.slice).?.data; |
| ... | @@ -3355,7 +3332,7 @@ pub const DeclGen = struct { | ... | @@ -3355,7 +3332,7 @@ pub const DeclGen = struct { |
| 3355 | return llvm_int.constIntToPtr(try dg.lowerType(tv.ty)); | 3332 | return llvm_int.constIntToPtr(try dg.lowerType(tv.ty)); |
| 3356 | }, | 3333 | }, |
| 3357 | .field_ptr, .opt_payload_ptr, .eu_payload_ptr, .elem_ptr => { | 3334 | .field_ptr, .opt_payload_ptr, .eu_payload_ptr, .elem_ptr => { |
| 3358 | return dg.lowerParentPtr(tv.val, tv.ty.childType()); | 3335 | return dg.lowerParentPtr(tv.val); |
| 3359 | }, | 3336 | }, |
| 3360 | .null_value, .zero => { | 3337 | .null_value, .zero => { |
| 3361 | const llvm_type = try dg.lowerType(tv.ty); | 3338 | const llvm_type = try dg.lowerType(tv.ty); |
| ... | @@ -3363,7 +3340,7 @@ pub const DeclGen = struct { | ... | @@ -3363,7 +3340,7 @@ pub const DeclGen = struct { |
| 3363 | }, | 3340 | }, |
| 3364 | .opt_payload => { | 3341 | .opt_payload => { |
| 3365 | const payload = tv.val.castTag(.opt_payload).?.data; | 3342 | const payload = tv.val.castTag(.opt_payload).?.data; |
| 3366 | return dg.lowerParentPtr(payload, tv.ty); | 3343 | return dg.lowerParentPtr(payload); |
| 3367 | }, | 3344 | }, |
| 3368 | else => |tag| return dg.todo("implement const of pointer type '{}' ({})", .{ | 3345 | else => |tag| return dg.todo("implement const of pointer type '{}' ({})", .{ |
| 3369 | tv.ty.fmtDebug(), tag, | 3346 | tv.ty.fmtDebug(), tag, |
| ... | @@ -3657,6 +3634,7 @@ pub const DeclGen = struct { | ... | @@ -3657,6 +3634,7 @@ pub const DeclGen = struct { |
| 3657 | const struct_obj = tv.ty.castTag(.@"struct").?.data; | 3634 | const struct_obj = tv.ty.castTag(.@"struct").?.data; |
| 3658 | | 3635 | |
| 3659 | if (struct_obj.layout == .Packed) { | 3636 | if (struct_obj.layout == .Packed) { |
| | 3637 | assert(struct_obj.haveLayout()); |
| 3660 | const big_bits = struct_obj.backing_int_ty.bitSize(target); | 3638 | const big_bits = struct_obj.backing_int_ty.bitSize(target); |
| 3661 | const int_llvm_ty = dg.context.intType(@intCast(c_uint, big_bits)); | 3639 | const int_llvm_ty = dg.context.intType(@intCast(c_uint, big_bits)); |
| 3662 | const fields = struct_obj.fields.values(); | 3640 | const fields = struct_obj.fields.values(); |
| ... | @@ -3940,7 +3918,6 @@ pub const DeclGen = struct { | ... | @@ -3940,7 +3918,6 @@ pub const DeclGen = struct { |
| 3940 | dg: *DeclGen, | 3918 | dg: *DeclGen, |
| 3941 | ptr_val: Value, | 3919 | ptr_val: Value, |
| 3942 | decl_index: Module.Decl.Index, | 3920 | decl_index: Module.Decl.Index, |
| 3943 | ptr_child_ty: Type, | | |
| 3944 | ) Error!*llvm.Value { | 3921 | ) Error!*llvm.Value { |
| 3945 | const decl = dg.module.declPtr(decl_index); | 3922 | const decl = dg.module.declPtr(decl_index); |
| 3946 | dg.module.markDeclAlive(decl); | 3923 | dg.module.markDeclAlive(decl); |
| ... | @@ -3949,62 +3926,54 @@ pub const DeclGen = struct { | ... | @@ -3949,62 +3926,54 @@ pub const DeclGen = struct { |
| 3949 | .data = decl.ty, | 3926 | .data = decl.ty, |
| 3950 | }; | 3927 | }; |
| 3951 | const ptr_ty = Type.initPayload(&ptr_ty_payload.base); | 3928 | const ptr_ty = Type.initPayload(&ptr_ty_payload.base); |
| 3952 | const llvm_ptr = try dg.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl_index); | 3929 | return try dg.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl_index); |
| 3953 | | | |
| 3954 | if (ptr_child_ty.eql(decl.ty, dg.module)) { | | |
| 3955 | return llvm_ptr; | | |
| 3956 | } else { | | |
| 3957 | return llvm_ptr.constBitCast((try dg.lowerType(ptr_child_ty)).pointerType(0)); | | |
| 3958 | } | | |
| 3959 | } | 3930 | } |
| 3960 | | 3931 | |
| 3961 | fn lowerParentPtr(dg: *DeclGen, ptr_val: Value, ptr_child_ty: Type) Error!*llvm.Value { | 3932 | fn lowerParentPtr(dg: *DeclGen, ptr_val: Value) Error!*llvm.Value { |
| 3962 | const target = dg.module.getTarget(); | 3933 | const target = dg.module.getTarget(); |
| 3963 | var bitcast_needed: bool = undefined; | 3934 | switch (ptr_val.tag()) { |
| 3964 | const llvm_ptr = switch (ptr_val.tag()) { | | |
| 3965 | .decl_ref_mut => { | 3935 | .decl_ref_mut => { |
| 3966 | const decl = ptr_val.castTag(.decl_ref_mut).?.data.decl_index; | 3936 | const decl = ptr_val.castTag(.decl_ref_mut).?.data.decl_index; |
| 3967 | return dg.lowerParentPtrDecl(ptr_val, decl, ptr_child_ty); | 3937 | return dg.lowerParentPtrDecl(ptr_val, decl); |
| 3968 | }, | 3938 | }, |
| 3969 | .decl_ref => { | 3939 | .decl_ref => { |
| 3970 | const decl = ptr_val.castTag(.decl_ref).?.data; | 3940 | const decl = ptr_val.castTag(.decl_ref).?.data; |
| 3971 | return dg.lowerParentPtrDecl(ptr_val, decl, ptr_child_ty); | 3941 | return dg.lowerParentPtrDecl(ptr_val, decl); |
| 3972 | }, | 3942 | }, |
| 3973 | .variable => { | 3943 | .variable => { |
| 3974 | const decl = ptr_val.castTag(.variable).?.data.owner_decl; | 3944 | const decl = ptr_val.castTag(.variable).?.data.owner_decl; |
| 3975 | return dg.lowerParentPtrDecl(ptr_val, decl, ptr_child_ty); | 3945 | return dg.lowerParentPtrDecl(ptr_val, decl); |
| 3976 | }, | 3946 | }, |
| 3977 | .int_i64 => { | 3947 | .int_i64 => { |
| 3978 | const int = ptr_val.castTag(.int_i64).?.data; | 3948 | const int = ptr_val.castTag(.int_i64).?.data; |
| 3979 | const llvm_usize = try dg.lowerType(Type.usize); | 3949 | const llvm_usize = try dg.lowerType(Type.usize); |
| 3980 | const llvm_int = llvm_usize.constInt(@bitCast(u64, int), .False); | 3950 | const llvm_int = llvm_usize.constInt(@bitCast(u64, int), .False); |
| 3981 | return llvm_int.constIntToPtr((try dg.lowerType(ptr_child_ty)).pointerType(0)); | 3951 | return llvm_int.constIntToPtr(dg.context.pointerType(0)); |
| 3982 | }, | 3952 | }, |
| 3983 | .int_u64 => { | 3953 | .int_u64 => { |
| 3984 | const int = ptr_val.castTag(.int_u64).?.data; | 3954 | const int = ptr_val.castTag(.int_u64).?.data; |
| 3985 | const llvm_usize = try dg.lowerType(Type.usize); | 3955 | const llvm_usize = try dg.lowerType(Type.usize); |
| 3986 | const llvm_int = llvm_usize.constInt(int, .False); | 3956 | const llvm_int = llvm_usize.constInt(int, .False); |
| 3987 | return llvm_int.constIntToPtr((try dg.lowerType(ptr_child_ty)).pointerType(0)); | 3957 | return llvm_int.constIntToPtr(dg.context.pointerType(0)); |
| 3988 | }, | 3958 | }, |
| 3989 | .field_ptr => blk: { | 3959 | .field_ptr => { |
| 3990 | const field_ptr = ptr_val.castTag(.field_ptr).?.data; | 3960 | const field_ptr = ptr_val.castTag(.field_ptr).?.data; |
| 3991 | const parent_llvm_ptr = try dg.lowerParentPtr(field_ptr.container_ptr, field_ptr.container_ty); | 3961 | const parent_llvm_ptr = try dg.lowerParentPtr(field_ptr.container_ptr); |
| 3992 | const parent_ty = field_ptr.container_ty; | 3962 | const parent_ty = field_ptr.container_ty; |
| 3993 | | 3963 | |
| 3994 | const field_index = @intCast(u32, field_ptr.field_index); | 3964 | const field_index = @intCast(u32, field_ptr.field_index); |
| 3995 | const llvm_u32 = dg.context.intType(32); | 3965 | const llvm_u32 = dg.context.intType(32); |
| 3996 | switch (parent_ty.zigTypeTag()) { | 3966 | switch (parent_ty.zigTypeTag()) { |
| 3997 | .Union => { | 3967 | .Union => { |
| 3998 | bitcast_needed = true; | | |
| 3999 | if (parent_ty.containerLayout() == .Packed) { | 3968 | if (parent_ty.containerLayout() == .Packed) { |
| 4000 | break :blk parent_llvm_ptr; | 3969 | return parent_llvm_ptr; |
| 4001 | } | 3970 | } |
| 4002 | | 3971 | |
| 4003 | const layout = parent_ty.unionGetLayout(target); | 3972 | const layout = parent_ty.unionGetLayout(target); |
| 4004 | if (layout.payload_size == 0) { | 3973 | if (layout.payload_size == 0) { |
| 4005 | // In this case a pointer to the union and a pointer to any | 3974 | // In this case a pointer to the union and a pointer to any |
| 4006 | // (void) payload is the same. | 3975 | // (void) payload is the same. |
| 4007 | break :blk parent_llvm_ptr; | 3976 | return parent_llvm_ptr; |
| 4008 | } | 3977 | } |
| 4009 | const llvm_pl_index = if (layout.tag_size == 0) | 3978 | const llvm_pl_index = if (layout.tag_size == 0) |
| 4010 | 0 | 3979 | 0 |
| ... | @@ -4015,10 +3984,9 @@ pub const DeclGen = struct { | ... | @@ -4015,10 +3984,9 @@ pub const DeclGen = struct { |
| 4015 | llvm_u32.constInt(llvm_pl_index, .False), | 3984 | llvm_u32.constInt(llvm_pl_index, .False), |
| 4016 | }; | 3985 | }; |
| 4017 | const parent_llvm_ty = try dg.lowerType(parent_ty); | 3986 | const parent_llvm_ty = try dg.lowerType(parent_ty); |
| 4018 | break :blk parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); | 3987 | return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 4019 | }, | 3988 | }, |
| 4020 | .Struct => { | 3989 | .Struct => { |
| 4021 | const field_ty = parent_ty.structFieldType(field_index); | | |
| 4022 | if (parent_ty.containerLayout() == .Packed) { | 3990 | if (parent_ty.containerLayout() == .Packed) { |
| 4023 | const llvm_usize = dg.context.intType(target.cpu.arch.ptrBitWidth()); | 3991 | const llvm_usize = dg.context.intType(target.cpu.arch.ptrBitWidth()); |
| 4024 | const base_addr = parent_llvm_ptr.constPtrToInt(llvm_usize); | 3992 | const base_addr = parent_llvm_ptr.constPtrToInt(llvm_usize); |
| ... | @@ -4033,26 +4001,23 @@ pub const DeclGen = struct { | ... | @@ -4033,26 +4001,23 @@ pub const DeclGen = struct { |
| 4033 | }; | 4001 | }; |
| 4034 | const byte_offset = llvm_usize.constInt(prev_bits / 8, .False); | 4002 | const byte_offset = llvm_usize.constInt(prev_bits / 8, .False); |
| 4035 | const field_addr = base_addr.constAdd(byte_offset); | 4003 | const field_addr = base_addr.constAdd(byte_offset); |
| 4036 | bitcast_needed = false; | 4004 | const final_llvm_ty = dg.context.pointerType(0); |
| 4037 | const final_llvm_ty = (try dg.lowerType(ptr_child_ty)).pointerType(0); | 4005 | return field_addr.constIntToPtr(final_llvm_ty); |
| 4038 | break :blk field_addr.constIntToPtr(final_llvm_ty); | | |
| 4039 | } | 4006 | } |
| 4040 | | 4007 | |
| 4041 | var ty_buf: Type.Payload.Pointer = undefined; | 4008 | var ty_buf: Type.Payload.Pointer = undefined; |
| 4042 | | 4009 | |
| 4043 | const parent_llvm_ty = try dg.lowerType(parent_ty); | 4010 | const parent_llvm_ty = try dg.lowerType(parent_ty); |
| 4044 | if (llvmFieldIndex(parent_ty, field_index, target, &ty_buf)) |llvm_field_index| { | 4011 | if (llvmFieldIndex(parent_ty, field_index, target, &ty_buf)) |llvm_field_index| { |
| 4045 | bitcast_needed = !field_ty.eql(ptr_child_ty, dg.module); | | |
| 4046 | const indices: [2]*llvm.Value = .{ | 4012 | const indices: [2]*llvm.Value = .{ |
| 4047 | llvm_u32.constInt(0, .False), | 4013 | llvm_u32.constInt(0, .False), |
| 4048 | llvm_u32.constInt(llvm_field_index, .False), | 4014 | llvm_u32.constInt(llvm_field_index, .False), |
| 4049 | }; | 4015 | }; |
| 4050 | break :blk parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); | 4016 | return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 4051 | } else { | 4017 | } else { |
| 4052 | bitcast_needed = !parent_ty.eql(ptr_child_ty, dg.module); | | |
| 4053 | const llvm_index = llvm_u32.constInt(@boolToInt(parent_ty.hasRuntimeBitsIgnoreComptime()), .False); | 4018 | const llvm_index = llvm_u32.constInt(@boolToInt(parent_ty.hasRuntimeBitsIgnoreComptime()), .False); |
| 4054 | const indices: [1]*llvm.Value = .{llvm_index}; | 4019 | const indices: [1]*llvm.Value = .{llvm_index}; |
| 4055 | break :blk parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); | 4020 | return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 4056 | } | 4021 | } |
| 4057 | }, | 4022 | }, |
| 4058 | .Pointer => { | 4023 | .Pointer => { |
| ... | @@ -4062,37 +4027,34 @@ pub const DeclGen = struct { | ... | @@ -4062,37 +4027,34 @@ pub const DeclGen = struct { |
| 4062 | llvm_u32.constInt(field_index, .False), | 4027 | llvm_u32.constInt(field_index, .False), |
| 4063 | }; | 4028 | }; |
| 4064 | const parent_llvm_ty = try dg.lowerType(parent_ty); | 4029 | const parent_llvm_ty = try dg.lowerType(parent_ty); |
| 4065 | break :blk parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); | 4030 | return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 4066 | }, | 4031 | }, |
| 4067 | else => unreachable, | 4032 | else => unreachable, |
| 4068 | } | 4033 | } |
| 4069 | }, | 4034 | }, |
| 4070 | .elem_ptr => blk: { | 4035 | .elem_ptr => { |
| 4071 | const elem_ptr = ptr_val.castTag(.elem_ptr).?.data; | 4036 | const elem_ptr = ptr_val.castTag(.elem_ptr).?.data; |
| 4072 | const parent_llvm_ptr = try dg.lowerParentPtr(elem_ptr.array_ptr, elem_ptr.elem_ty); | 4037 | const parent_llvm_ptr = try dg.lowerParentPtr(elem_ptr.array_ptr); |
| 4073 | bitcast_needed = !elem_ptr.elem_ty.eql(ptr_child_ty, dg.module); | | |
| 4074 | | 4038 | |
| 4075 | const llvm_usize = try dg.lowerType(Type.usize); | 4039 | const llvm_usize = try dg.lowerType(Type.usize); |
| 4076 | const indices: [1]*llvm.Value = .{ | 4040 | const indices: [1]*llvm.Value = .{ |
| 4077 | llvm_usize.constInt(elem_ptr.index, .False), | 4041 | llvm_usize.constInt(elem_ptr.index, .False), |
| 4078 | }; | 4042 | }; |
| 4079 | const elem_llvm_ty = try dg.lowerType(elem_ptr.elem_ty); | 4043 | const elem_llvm_ty = try dg.lowerType(elem_ptr.elem_ty); |
| 4080 | break :blk elem_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); | 4044 | return elem_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 4081 | }, | 4045 | }, |
| 4082 | .opt_payload_ptr => blk: { | 4046 | .opt_payload_ptr => { |
| 4083 | const opt_payload_ptr = ptr_val.castTag(.opt_payload_ptr).?.data; | 4047 | const opt_payload_ptr = ptr_val.castTag(.opt_payload_ptr).?.data; |
| 4084 | const parent_llvm_ptr = try dg.lowerParentPtr(opt_payload_ptr.container_ptr, opt_payload_ptr.container_ty); | 4048 | const parent_llvm_ptr = try dg.lowerParentPtr(opt_payload_ptr.container_ptr); |
| 4085 | var buf: Type.Payload.ElemType = undefined; | 4049 | var buf: Type.Payload.ElemType = undefined; |
| 4086 | | 4050 | |
| 4087 | const payload_ty = opt_payload_ptr.container_ty.optionalChild(&buf); | 4051 | const payload_ty = opt_payload_ptr.container_ty.optionalChild(&buf); |
| 4088 | bitcast_needed = !payload_ty.eql(ptr_child_ty, dg.module); | | |
| 4089 | | | |
| 4090 | if (!payload_ty.hasRuntimeBitsIgnoreComptime() or | 4052 | if (!payload_ty.hasRuntimeBitsIgnoreComptime() or |
| 4091 | payload_ty.optionalReprIsPayload()) | 4053 | payload_ty.optionalReprIsPayload()) |
| 4092 | { | 4054 | { |
| 4093 | // In this case, we represent pointer to optional the same as pointer | 4055 | // In this case, we represent pointer to optional the same as pointer |
| 4094 | // to the payload. | 4056 | // to the payload. |
| 4095 | break :blk parent_llvm_ptr; | 4057 | return parent_llvm_ptr; |
| 4096 | } | 4058 | } |
| 4097 | | 4059 | |
| 4098 | const llvm_u32 = dg.context.intType(32); | 4060 | const llvm_u32 = dg.context.intType(32); |
| ... | @@ -4101,19 +4063,17 @@ pub const DeclGen = struct { | ... | @@ -4101,19 +4063,17 @@ pub const DeclGen = struct { |
| 4101 | llvm_u32.constInt(0, .False), | 4063 | llvm_u32.constInt(0, .False), |
| 4102 | }; | 4064 | }; |
| 4103 | const opt_llvm_ty = try dg.lowerType(opt_payload_ptr.container_ty); | 4065 | const opt_llvm_ty = try dg.lowerType(opt_payload_ptr.container_ty); |
| 4104 | break :blk opt_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); | 4066 | return opt_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 4105 | }, | 4067 | }, |
| 4106 | .eu_payload_ptr => blk: { | 4068 | .eu_payload_ptr => { |
| 4107 | const eu_payload_ptr = ptr_val.castTag(.eu_payload_ptr).?.data; | 4069 | const eu_payload_ptr = ptr_val.castTag(.eu_payload_ptr).?.data; |
| 4108 | const parent_llvm_ptr = try dg.lowerParentPtr(eu_payload_ptr.container_ptr, eu_payload_ptr.container_ty); | 4070 | const parent_llvm_ptr = try dg.lowerParentPtr(eu_payload_ptr.container_ptr); |
| 4109 | | 4071 | |
| 4110 | const payload_ty = eu_payload_ptr.container_ty.errorUnionPayload(); | 4072 | const payload_ty = eu_payload_ptr.container_ty.errorUnionPayload(); |
| 4111 | bitcast_needed = !payload_ty.eql(ptr_child_ty, dg.module); | | |
| 4112 | | | |
| 4113 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { | 4073 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 4114 | // In this case, we represent pointer to error union the same as pointer | 4074 | // In this case, we represent pointer to error union the same as pointer |
| 4115 | // to the payload. | 4075 | // to the payload. |
| 4116 | break :blk parent_llvm_ptr; | 4076 | return parent_llvm_ptr; |
| 4117 | } | 4077 | } |
| 4118 | | 4078 | |
| 4119 | const payload_offset: u8 = if (payload_ty.abiAlignment(target) > Type.anyerror.abiSize(target)) 2 else 1; | 4079 | const payload_offset: u8 = if (payload_ty.abiAlignment(target) > Type.anyerror.abiSize(target)) 2 else 1; |
| ... | @@ -4123,14 +4083,9 @@ pub const DeclGen = struct { | ... | @@ -4123,14 +4083,9 @@ pub const DeclGen = struct { |
| 4123 | llvm_u32.constInt(payload_offset, .False), | 4083 | llvm_u32.constInt(payload_offset, .False), |
| 4124 | }; | 4084 | }; |
| 4125 | const eu_llvm_ty = try dg.lowerType(eu_payload_ptr.container_ty); | 4085 | const eu_llvm_ty = try dg.lowerType(eu_payload_ptr.container_ty); |
| 4126 | break :blk eu_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); | 4086 | return eu_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 4127 | }, | 4087 | }, |
| 4128 | else => unreachable, | 4088 | else => unreachable, |
| 4129 | }; | | |
| 4130 | if (bitcast_needed) { | | |
| 4131 | return llvm_ptr.constBitCast((try dg.lowerPtrElemTy(ptr_child_ty)).pointerType(0)); | | |
| 4132 | } else { | | |
| 4133 | return llvm_ptr; | | |
| 4134 | } | 4089 | } |
| 4135 | } | 4090 | } |
| 4136 | | 4091 | |
| ... | @@ -4189,8 +4144,7 @@ pub const DeclGen = struct { | ... | @@ -4189,8 +4144,7 @@ pub const DeclGen = struct { |
| 4189 | const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target); | 4144 | const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target); |
| 4190 | const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target); | 4145 | const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target); |
| 4191 | const llvm_val = if (llvm_wanted_addrspace != llvm_actual_addrspace) blk: { | 4146 | const llvm_val = if (llvm_wanted_addrspace != llvm_actual_addrspace) blk: { |
| 4192 | const llvm_decl_ty = try self.lowerType(decl.ty); | 4147 | const llvm_decl_wanted_ptr_ty = self.context.pointerType(llvm_wanted_addrspace); |
| 4193 | const llvm_decl_wanted_ptr_ty = llvm_decl_ty.pointerType(llvm_wanted_addrspace); | | |
| 4194 | break :blk llvm_decl_val.constAddrSpaceCast(llvm_decl_wanted_ptr_ty); | 4148 | break :blk llvm_decl_val.constAddrSpaceCast(llvm_decl_wanted_ptr_ty); |
| 4195 | } else llvm_decl_val; | 4149 | } else llvm_decl_val; |
| 4196 | | 4150 | |
| ... | @@ -4471,18 +4425,11 @@ pub const FuncGen = struct { | ... | @@ -4471,18 +4425,11 @@ pub const FuncGen = struct { |
| 4471 | global.setGlobalConstant(.True); | 4425 | global.setGlobalConstant(.True); |
| 4472 | global.setUnnamedAddr(.True); | 4426 | global.setUnnamedAddr(.True); |
| 4473 | global.setAlignment(tv.ty.abiAlignment(target)); | 4427 | global.setAlignment(tv.ty.abiAlignment(target)); |
| 4474 | // Because of LLVM limitations for lowering certain types such as unions, | 4428 | const addrspace_casted_ptr = if (llvm_actual_addrspace != llvm_wanted_addrspace) |
| 4475 | // the type of global constants might not match the type it is supposed to | 4429 | global.constAddrSpaceCast(self.context.pointerType(llvm_wanted_addrspace)) |
| 4476 | // be, and so we must bitcast the pointer at the usage sites. | | |
| 4477 | const wanted_llvm_ty = try self.dg.lowerType(tv.ty); | | |
| 4478 | const wanted_bitcasted_llvm_ptr_ty = wanted_llvm_ty.pointerType(llvm_actual_addrspace); | | |
| 4479 | const bitcasted_ptr = global.constBitCast(wanted_bitcasted_llvm_ptr_ty); | | |
| 4480 | const wanted_llvm_ptr_ty = wanted_llvm_ty.pointerType(llvm_wanted_addrspace); | | |
| 4481 | const casted_ptr = if (llvm_wanted_addrspace != llvm_actual_addrspace) | | |
| 4482 | bitcasted_ptr.constAddrSpaceCast(wanted_llvm_ptr_ty) | | |
| 4483 | else | 4430 | else |
| 4484 | bitcasted_ptr; | 4431 | global; |
| 4485 | return casted_ptr; | 4432 | return addrspace_casted_ptr; |
| 4486 | } | 4433 | } |
| 4487 | | 4434 | |
| 4488 | fn genBody(self: *FuncGen, body: []const Air.Inst.Index) Error!void { | 4435 | fn genBody(self: *FuncGen, body: []const Air.Inst.Index) Error!void { |
| ... | @@ -4770,17 +4717,7 @@ pub const FuncGen = struct { | ... | @@ -4770,17 +4717,7 @@ pub const FuncGen = struct { |
| 4770 | load_inst.setAlignment(alignment); | 4717 | load_inst.setAlignment(alignment); |
| 4771 | try llvm_args.append(load_inst); | 4718 | try llvm_args.append(load_inst); |
| 4772 | } else { | 4719 | } else { |
| 4773 | if (param_ty.zigTypeTag() == .Pointer) { | 4720 | try llvm_args.append(llvm_arg); |
| 4774 | // We need a bitcast in case of two possibilities: | | |
| 4775 | // 1. The parameter type is a pointer to zero-sized type, | | |
| 4776 | // which is always lowered to an LLVM type of `*i8`. | | |
| 4777 | // 2. The argument is a global which does act as a pointer, however | | |
| 4778 | // a bitcast is needed in order for the LLVM types to match. | | |
| 4779 | const casted_ptr = self.builder.buildBitCast(llvm_arg, llvm_param_ty, ""); | | |
| 4780 | try llvm_args.append(casted_ptr); | | |
| 4781 | } else { | | |
| 4782 | try llvm_args.append(llvm_arg); | | |
| 4783 | } | | |
| 4784 | } | 4721 | } |
| 4785 | }, | 4722 | }, |
| 4786 | .byref => { | 4723 | .byref => { |
| ... | @@ -4824,26 +4761,22 @@ pub const FuncGen = struct { | ... | @@ -4824,26 +4761,22 @@ pub const FuncGen = struct { |
| 4824 | const param_ty = self.air.typeOf(arg); | 4761 | const param_ty = self.air.typeOf(arg); |
| 4825 | const llvm_arg = try self.resolveInst(arg); | 4762 | const llvm_arg = try self.resolveInst(arg); |
| 4826 | const abi_size = @intCast(c_uint, param_ty.abiSize(target)); | 4763 | const abi_size = @intCast(c_uint, param_ty.abiSize(target)); |
| 4827 | const int_llvm_ty = self.dg.context.intType(abi_size * 8); | 4764 | const int_llvm_ty = self.context.intType(abi_size * 8); |
| 4828 | const int_ptr_llvm_ty = int_llvm_ty.pointerType(0); | | |
| 4829 | | 4765 | |
| 4830 | if (isByRef(param_ty)) { | 4766 | if (isByRef(param_ty)) { |
| 4831 | const alignment = param_ty.abiAlignment(target); | 4767 | const alignment = param_ty.abiAlignment(target); |
| 4832 | const casted_ptr = self.builder.buildBitCast(llvm_arg, int_ptr_llvm_ty, ""); | 4768 | const load_inst = self.builder.buildLoad(int_llvm_ty, llvm_arg, ""); |
| 4833 | const load_inst = self.builder.buildLoad(int_llvm_ty, casted_ptr, ""); | | |
| 4834 | load_inst.setAlignment(alignment); | 4769 | load_inst.setAlignment(alignment); |
| 4835 | try llvm_args.append(load_inst); | 4770 | try llvm_args.append(load_inst); |
| 4836 | } else { | 4771 | } else { |
| 4837 | // LLVM does not allow bitcasting structs so we must allocate | 4772 | // LLVM does not allow bitcasting structs so we must allocate |
| 4838 | // a local, bitcast its pointer, store, and then load. | 4773 | // a local, store as one type, and then load as another type. |
| 4839 | const alignment = @max( | 4774 | const alignment = @max( |
| 4840 | param_ty.abiAlignment(target), | 4775 | param_ty.abiAlignment(target), |
| 4841 | self.dg.object.target_data.abiAlignmentOfType(int_llvm_ty), | 4776 | self.dg.object.target_data.abiAlignmentOfType(int_llvm_ty), |
| 4842 | ); | 4777 | ); |
| 4843 | const int_ptr = self.buildAlloca(int_llvm_ty, alignment); | 4778 | const int_ptr = self.buildAlloca(int_llvm_ty, alignment); |
| 4844 | const param_llvm_ty = try self.dg.lowerType(param_ty); | 4779 | const store_inst = self.builder.buildStore(llvm_arg, int_ptr); |
| 4845 | const casted_ptr = self.builder.buildBitCast(int_ptr, param_llvm_ty.pointerType(0), ""); | | |
| 4846 | const store_inst = self.builder.buildStore(llvm_arg, casted_ptr); | | |
| 4847 | store_inst.setAlignment(alignment); | 4780 | store_inst.setAlignment(alignment); |
| 4848 | const load_inst = self.builder.buildLoad(int_llvm_ty, int_ptr, ""); | 4781 | const load_inst = self.builder.buildLoad(int_llvm_ty, int_ptr, ""); |
| 4849 | load_inst.setAlignment(alignment); | 4782 | load_inst.setAlignment(alignment); |
| ... | @@ -4872,12 +4805,11 @@ pub const FuncGen = struct { | ... | @@ -4872,12 +4805,11 @@ pub const FuncGen = struct { |
| 4872 | break :p p; | 4805 | break :p p; |
| 4873 | }; | 4806 | }; |
| 4874 | | 4807 | |
| 4875 | const llvm_ty = self.dg.context.structType(llvm_types.ptr, @intCast(c_uint, llvm_types.len), .False); | 4808 | const llvm_ty = self.context.structType(llvm_types.ptr, @intCast(c_uint, llvm_types.len), .False); |
| 4876 | const casted_ptr = self.builder.buildBitCast(arg_ptr, llvm_ty.pointerType(0), ""); | | |
| 4877 | try llvm_args.ensureUnusedCapacity(it.llvm_types_len); | 4809 | try llvm_args.ensureUnusedCapacity(it.llvm_types_len); |
| 4878 | for (llvm_types) |field_ty, i_usize| { | 4810 | for (llvm_types) |field_ty, i_usize| { |
| 4879 | const i = @intCast(c_uint, i_usize); | 4811 | const i = @intCast(c_uint, i_usize); |
| 4880 | const field_ptr = self.builder.buildStructGEP(llvm_ty, casted_ptr, i, ""); | 4812 | const field_ptr = self.builder.buildStructGEP(llvm_ty, arg_ptr, i, ""); |
| 4881 | const load_inst = self.builder.buildLoad(field_ty, field_ptr, ""); | 4813 | const load_inst = self.builder.buildLoad(field_ty, field_ptr, ""); |
| 4882 | load_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8); | 4814 | load_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8); |
| 4883 | llvm_args.appendAssumeCapacity(load_inst); | 4815 | llvm_args.appendAssumeCapacity(load_inst); |
| ... | @@ -4886,7 +4818,7 @@ pub const FuncGen = struct { | ... | @@ -4886,7 +4818,7 @@ pub const FuncGen = struct { |
| 4886 | .as_u16 => { | 4818 | .as_u16 => { |
| 4887 | const arg = args[it.zig_index - 1]; | 4819 | const arg = args[it.zig_index - 1]; |
| 4888 | const llvm_arg = try self.resolveInst(arg); | 4820 | const llvm_arg = try self.resolveInst(arg); |
| 4889 | const casted = self.builder.buildBitCast(llvm_arg, self.dg.context.intType(16), ""); | 4821 | const casted = self.builder.buildBitCast(llvm_arg, self.context.intType(16), ""); |
| 4890 | try llvm_args.append(casted); | 4822 | try llvm_args.append(casted); |
| 4891 | }, | 4823 | }, |
| 4892 | .float_array => |count| { | 4824 | .float_array => |count| { |
| ... | @@ -4903,9 +4835,8 @@ pub const FuncGen = struct { | ... | @@ -4903,9 +4835,8 @@ pub const FuncGen = struct { |
| 4903 | const float_ty = try self.dg.lowerType(aarch64_c_abi.getFloatArrayType(arg_ty).?); | 4835 | const float_ty = try self.dg.lowerType(aarch64_c_abi.getFloatArrayType(arg_ty).?); |
| 4904 | const array_llvm_ty = float_ty.arrayType(count); | 4836 | const array_llvm_ty = float_ty.arrayType(count); |
| 4905 | | 4837 | |
| 4906 | const casted = self.builder.buildBitCast(llvm_arg, array_llvm_ty.pointerType(0), ""); | | |
| 4907 | const alignment = arg_ty.abiAlignment(target); | 4838 | const alignment = arg_ty.abiAlignment(target); |
| 4908 | const load_inst = self.builder.buildLoad(array_llvm_ty, casted, ""); | 4839 | const load_inst = self.builder.buildLoad(array_llvm_ty, llvm_arg, ""); |
| 4909 | load_inst.setAlignment(alignment); | 4840 | load_inst.setAlignment(alignment); |
| 4910 | try llvm_args.append(load_inst); | 4841 | try llvm_args.append(load_inst); |
| 4911 | }, | 4842 | }, |
| ... | @@ -4921,10 +4852,9 @@ pub const FuncGen = struct { | ... | @@ -4921,10 +4852,9 @@ pub const FuncGen = struct { |
| 4921 | llvm_arg = store_inst; | 4852 | llvm_arg = store_inst; |
| 4922 | } | 4853 | } |
| 4923 | | 4854 | |
| 4924 | const array_llvm_ty = self.dg.context.intType(elem_size).arrayType(arr_len); | 4855 | const array_llvm_ty = self.context.intType(elem_size).arrayType(arr_len); |
| 4925 | const casted = self.builder.buildBitCast(llvm_arg, array_llvm_ty.pointerType(0), ""); | | |
| 4926 | const alignment = arg_ty.abiAlignment(target); | 4856 | const alignment = arg_ty.abiAlignment(target); |
| 4927 | const load_inst = self.builder.buildLoad(array_llvm_ty, casted, ""); | 4857 | const load_inst = self.builder.buildLoad(array_llvm_ty, llvm_arg, ""); |
| 4928 | load_inst.setAlignment(alignment); | 4858 | load_inst.setAlignment(alignment); |
| 4929 | try llvm_args.append(load_inst); | 4859 | try llvm_args.append(load_inst); |
| 4930 | }, | 4860 | }, |
| ... | @@ -5028,12 +4958,10 @@ pub const FuncGen = struct { | ... | @@ -5028,12 +4958,10 @@ pub const FuncGen = struct { |
| 5028 | if (abi_ret_ty != llvm_ret_ty) { | 4958 | if (abi_ret_ty != llvm_ret_ty) { |
| 5029 | // In this case the function return type is honoring the calling convention by having | 4959 | // In this case the function return type is honoring the calling convention by having |
| 5030 | // a different LLVM type than the usual one. We solve this here at the callsite | 4960 | // a different LLVM type than the usual one. We solve this here at the callsite |
| 5031 | // by bitcasting a pointer to our canonical type, then loading it if necessary. | 4961 | // by using our canonical type, then loading it if necessary. |
| 5032 | const alignment = self.dg.object.target_data.abiAlignmentOfType(abi_ret_ty); | 4962 | const alignment = self.dg.object.target_data.abiAlignmentOfType(abi_ret_ty); |
| 5033 | const rp = self.buildAlloca(llvm_ret_ty, alignment); | 4963 | const rp = self.buildAlloca(llvm_ret_ty, alignment); |
| 5034 | const ptr_abi_ty = abi_ret_ty.pointerType(0); | 4964 | const store_inst = self.builder.buildStore(call, rp); |
| 5035 | const casted_ptr = self.builder.buildBitCast(rp, ptr_abi_ty, ""); | | |
| 5036 | const store_inst = self.builder.buildStore(call, casted_ptr); | | |
| 5037 | store_inst.setAlignment(alignment); | 4965 | store_inst.setAlignment(alignment); |
| 5038 | if (isByRef(return_type)) { | 4966 | if (isByRef(return_type)) { |
| 5039 | return rp; | 4967 | return rp; |
| ... | @@ -5086,7 +5014,6 @@ pub const FuncGen = struct { | ... | @@ -5086,7 +5014,6 @@ pub const FuncGen = struct { |
| 5086 | } | 5014 | } |
| 5087 | | 5015 | |
| 5088 | const abi_ret_ty = try lowerFnRetTy(self.dg, fn_info); | 5016 | const abi_ret_ty = try lowerFnRetTy(self.dg, fn_info); |
| 5089 | const ptr_abi_ty = abi_ret_ty.pointerType(0); | | |
| 5090 | const operand = try self.resolveInst(un_op); | 5017 | const operand = try self.resolveInst(un_op); |
| 5091 | const target = self.dg.module.getTarget(); | 5018 | const target = self.dg.module.getTarget(); |
| 5092 | const alignment = ret_ty.abiAlignment(target); | 5019 | const alignment = ret_ty.abiAlignment(target); |
| ... | @@ -5094,8 +5021,7 @@ pub const FuncGen = struct { | ... | @@ -5094,8 +5021,7 @@ pub const FuncGen = struct { |
| 5094 | if (isByRef(ret_ty)) { | 5021 | if (isByRef(ret_ty)) { |
| 5095 | // operand is a pointer however self.ret_ptr is null so that means | 5022 | // operand is a pointer however self.ret_ptr is null so that means |
| 5096 | // we need to return a value. | 5023 | // we need to return a value. |
| 5097 | const casted_ptr = self.builder.buildBitCast(operand, ptr_abi_ty, ""); | 5024 | const load_inst = self.builder.buildLoad(abi_ret_ty, operand, ""); |
| 5098 | const load_inst = self.builder.buildLoad(abi_ret_ty, casted_ptr, ""); | | |
| 5099 | load_inst.setAlignment(alignment); | 5025 | load_inst.setAlignment(alignment); |
| 5100 | _ = self.builder.buildRet(load_inst); | 5026 | _ = self.builder.buildRet(load_inst); |
| 5101 | return null; | 5027 | return null; |
| ... | @@ -5110,8 +5036,7 @@ pub const FuncGen = struct { | ... | @@ -5110,8 +5036,7 @@ pub const FuncGen = struct { |
| 5110 | const rp = self.buildAlloca(llvm_ret_ty, alignment); | 5036 | const rp = self.buildAlloca(llvm_ret_ty, alignment); |
| 5111 | const store_inst = self.builder.buildStore(operand, rp); | 5037 | const store_inst = self.builder.buildStore(operand, rp); |
| 5112 | store_inst.setAlignment(alignment); | 5038 | store_inst.setAlignment(alignment); |
| 5113 | const casted_ptr = self.builder.buildBitCast(rp, ptr_abi_ty, ""); | 5039 | const load_inst = self.builder.buildLoad(abi_ret_ty, rp, ""); |
| 5114 | const load_inst = self.builder.buildLoad(abi_ret_ty, casted_ptr, ""); | | |
| 5115 | load_inst.setAlignment(alignment); | 5040 | load_inst.setAlignment(alignment); |
| 5116 | _ = self.builder.buildRet(load_inst); | 5041 | _ = self.builder.buildRet(load_inst); |
| 5117 | return null; | 5042 | return null; |
| ... | @@ -5141,12 +5066,7 @@ pub const FuncGen = struct { | ... | @@ -5141,12 +5066,7 @@ pub const FuncGen = struct { |
| 5141 | const ptr = try self.resolveInst(un_op); | 5066 | const ptr = try self.resolveInst(un_op); |
| 5142 | const target = self.dg.module.getTarget(); | 5067 | const target = self.dg.module.getTarget(); |
| 5143 | const abi_ret_ty = try lowerFnRetTy(self.dg, fn_info); | 5068 | const abi_ret_ty = try lowerFnRetTy(self.dg, fn_info); |
| 5144 | const llvm_ret_ty = try self.dg.lowerType(ret_ty); | 5069 | const loaded = self.builder.buildLoad(abi_ret_ty, ptr, ""); |
| 5145 | const casted_ptr = if (abi_ret_ty == llvm_ret_ty) ptr else p: { | | |
| 5146 | const ptr_abi_ty = abi_ret_ty.pointerType(0); | | |
| 5147 | break :p self.builder.buildBitCast(ptr, ptr_abi_ty, ""); | | |
| 5148 | }; | | |
| 5149 | const loaded = self.builder.buildLoad(abi_ret_ty, casted_ptr, ""); | | |
| 5150 | loaded.setAlignment(ret_ty.abiAlignment(target)); | 5070 | loaded.setAlignment(ret_ty.abiAlignment(target)); |
| 5151 | _ = self.builder.buildRet(loaded); | 5071 | _ = self.builder.buildRet(loaded); |
| 5152 | return null; | 5072 | return null; |
| ... | @@ -5178,8 +5098,8 @@ pub const FuncGen = struct { | ... | @@ -5178,8 +5098,8 @@ pub const FuncGen = struct { |
| 5178 | const llvm_fn_name = "llvm.va_copy"; | 5098 | const llvm_fn_name = "llvm.va_copy"; |
| 5179 | const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: { | 5099 | const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: { |
| 5180 | const param_types = [_]*llvm.Type{ | 5100 | const param_types = [_]*llvm.Type{ |
| 5181 | self.dg.context.intType(8).pointerType(0), | 5101 | self.context.pointerType(0), |
| 5182 | self.dg.context.intType(8).pointerType(0), | 5102 | self.context.pointerType(0), |
| 5183 | }; | 5103 | }; |
| 5184 | const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False); | 5104 | const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False); |
| 5185 | break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type); | 5105 | break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type); |
| ... | @@ -5203,7 +5123,7 @@ pub const FuncGen = struct { | ... | @@ -5203,7 +5123,7 @@ pub const FuncGen = struct { |
| 5203 | | 5123 | |
| 5204 | const llvm_fn_name = "llvm.va_end"; | 5124 | const llvm_fn_name = "llvm.va_end"; |
| 5205 | const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: { | 5125 | const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: { |
| 5206 | const param_types = [_]*llvm.Type{self.dg.context.intType(8).pointerType(0)}; | 5126 | const param_types = [_]*llvm.Type{self.context.pointerType(0)}; |
| 5207 | const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False); | 5127 | const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False); |
| 5208 | break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type); | 5128 | break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type); |
| 5209 | }; | 5129 | }; |
| ... | @@ -5224,7 +5144,7 @@ pub const FuncGen = struct { | ... | @@ -5224,7 +5144,7 @@ pub const FuncGen = struct { |
| 5224 | | 5144 | |
| 5225 | const llvm_fn_name = "llvm.va_start"; | 5145 | const llvm_fn_name = "llvm.va_start"; |
| 5226 | const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: { | 5146 | const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: { |
| 5227 | const param_types = [_]*llvm.Type{self.dg.context.intType(8).pointerType(0)}; | 5147 | const param_types = [_]*llvm.Type{self.context.pointerType(0)}; |
| 5228 | const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False); | 5148 | const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False); |
| 5229 | break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type); | 5149 | break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type); |
| 5230 | }; | 5150 | }; |
| ... | @@ -5417,7 +5337,7 @@ pub const FuncGen = struct { | ... | @@ -5417,7 +5337,7 @@ pub const FuncGen = struct { |
| 5417 | // of function pointers, however the phi makes it a runtime value and therefore | 5337 | // of function pointers, however the phi makes it a runtime value and therefore |
| 5418 | // the LLVM type has to be wrapped in a pointer. | 5338 | // the LLVM type has to be wrapped in a pointer. |
| 5419 | if (is_body or isByRef(inst_ty)) { | 5339 | if (is_body or isByRef(inst_ty)) { |
| 5420 | break :ty raw_llvm_ty.pointerType(0); | 5340 | break :ty self.context.pointerType(0); |
| 5421 | } | 5341 | } |
| 5422 | break :ty raw_llvm_ty; | 5342 | break :ty raw_llvm_ty; |
| 5423 | }; | 5343 | }; |
| ... | @@ -5482,7 +5402,7 @@ pub const FuncGen = struct { | ... | @@ -5482,7 +5402,7 @@ pub const FuncGen = struct { |
| 5482 | const payload_ty = self.air.typeOfIndex(inst); | 5402 | const payload_ty = self.air.typeOfIndex(inst); |
| 5483 | const can_elide_load = if (isByRef(payload_ty)) self.canElideLoad(body_tail) else false; | 5403 | const can_elide_load = if (isByRef(payload_ty)) self.canElideLoad(body_tail) else false; |
| 5484 | const is_unused = self.liveness.isUnused(inst); | 5404 | const is_unused = self.liveness.isUnused(inst); |
| 5485 | return lowerTry(self, err_union, body, err_union_ty, false, can_elide_load, is_unused, payload_ty); | 5405 | return lowerTry(self, err_union, body, err_union_ty, false, can_elide_load, is_unused); |
| 5486 | } | 5406 | } |
| 5487 | | 5407 | |
| 5488 | fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { | 5408 | fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| ... | @@ -5491,9 +5411,8 @@ pub const FuncGen = struct { | ... | @@ -5491,9 +5411,8 @@ pub const FuncGen = struct { |
| 5491 | const err_union_ptr = try self.resolveInst(extra.data.ptr); | 5411 | const err_union_ptr = try self.resolveInst(extra.data.ptr); |
| 5492 | const body = self.air.extra[extra.end..][0..extra.data.body_len]; | 5412 | const body = self.air.extra[extra.end..][0..extra.data.body_len]; |
| 5493 | const err_union_ty = self.air.typeOf(extra.data.ptr).childType(); | 5413 | const err_union_ty = self.air.typeOf(extra.data.ptr).childType(); |
| 5494 | const payload_ty = self.air.typeOfIndex(inst); | | |
| 5495 | const is_unused = self.liveness.isUnused(inst); | 5414 | const is_unused = self.liveness.isUnused(inst); |
| 5496 | return lowerTry(self, err_union_ptr, body, err_union_ty, true, true, is_unused, payload_ty); | 5415 | return lowerTry(self, err_union_ptr, body, err_union_ty, true, true, is_unused); |
| 5497 | } | 5416 | } |
| 5498 | | 5417 | |
| 5499 | fn lowerTry( | 5418 | fn lowerTry( |
| ... | @@ -5504,7 +5423,6 @@ pub const FuncGen = struct { | ... | @@ -5504,7 +5423,6 @@ pub const FuncGen = struct { |
| 5504 | operand_is_ptr: bool, | 5423 | operand_is_ptr: bool, |
| 5505 | can_elide_load: bool, | 5424 | can_elide_load: bool, |
| 5506 | is_unused: bool, | 5425 | is_unused: bool, |
| 5507 | result_ty: Type, | | |
| 5508 | ) !?*llvm.Value { | 5426 | ) !?*llvm.Value { |
| 5509 | const payload_ty = err_union_ty.errorUnionPayload(); | 5427 | const payload_ty = err_union_ty.errorUnionPayload(); |
| 5510 | const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(); | 5428 | const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(); |
| ... | @@ -5547,12 +5465,7 @@ pub const FuncGen = struct { | ... | @@ -5547,12 +5465,7 @@ pub const FuncGen = struct { |
| 5547 | return null; | 5465 | return null; |
| 5548 | } | 5466 | } |
| 5549 | if (!payload_has_bits) { | 5467 | if (!payload_has_bits) { |
| 5550 | if (!operand_is_ptr) return null; | 5468 | return if (operand_is_ptr) err_union else null; |
| 5551 | | | |
| 5552 | // TODO once we update to an LLVM version with opaque pointers | | |
| 5553 | // this bitcast won't be necessary. | | |
| 5554 | const res_ptr_ty = try fg.dg.lowerType(result_ty); | | |
| 5555 | return fg.builder.buildBitCast(err_union, res_ptr_ty, ""); | | |
| 5556 | } | 5469 | } |
| 5557 | const offset = errUnionPayloadOffset(payload_ty, target); | 5470 | const offset = errUnionPayloadOffset(payload_ty, target); |
| 5558 | if (operand_is_ptr) { | 5471 | if (operand_is_ptr) { |
| ... | @@ -6038,9 +5951,8 @@ pub const FuncGen = struct { | ... | @@ -6038,9 +5951,8 @@ pub const FuncGen = struct { |
| 6038 | const union_llvm_ty = try self.dg.lowerType(struct_ty); | 5951 | const union_llvm_ty = try self.dg.lowerType(struct_ty); |
| 6039 | const layout = struct_ty.unionGetLayout(target); | 5952 | const layout = struct_ty.unionGetLayout(target); |
| 6040 | const payload_index = @boolToInt(layout.tag_align >= layout.payload_align); | 5953 | const payload_index = @boolToInt(layout.tag_align >= layout.payload_align); |
| 6041 | const union_field_ptr = self.builder.buildStructGEP(union_llvm_ty, struct_llvm_val, payload_index, ""); | 5954 | const field_ptr = self.builder.buildStructGEP(union_llvm_ty, struct_llvm_val, payload_index, ""); |
| 6042 | const llvm_field_ty = try self.dg.lowerType(field_ty); | 5955 | const llvm_field_ty = try self.dg.lowerType(field_ty); |
| 6043 | const field_ptr = self.builder.buildBitCast(union_field_ptr, llvm_field_ty.pointerType(0), ""); | | |
| 6044 | if (isByRef(field_ty)) { | 5956 | if (isByRef(field_ty)) { |
| 6045 | if (canElideLoad(self, body_tail)) | 5957 | if (canElideLoad(self, body_tail)) |
| 6046 | return field_ptr; | 5958 | return field_ptr; |
| ... | @@ -6068,7 +5980,7 @@ pub const FuncGen = struct { | ... | @@ -6068,7 +5980,7 @@ pub const FuncGen = struct { |
| 6068 | | 5980 | |
| 6069 | const res_ty = try self.dg.lowerType(self.air.getRefType(ty_pl.ty)); | 5981 | const res_ty = try self.dg.lowerType(self.air.getRefType(ty_pl.ty)); |
| 6070 | if (field_offset == 0) { | 5982 | if (field_offset == 0) { |
| 6071 | return self.builder.buildBitCast(field_ptr, res_ty, ""); | 5983 | return field_ptr; |
| 6072 | } | 5984 | } |
| 6073 | const llvm_usize_ty = self.context.intType(target.cpu.arch.ptrBitWidth()); | 5985 | const llvm_usize_ty = self.context.intType(target.cpu.arch.ptrBitWidth()); |
| 6074 | | 5986 | |
| ... | @@ -6635,7 +6547,7 @@ pub const FuncGen = struct { | ... | @@ -6635,7 +6547,7 @@ pub const FuncGen = struct { |
| 6635 | self.builder.buildLoad(optional_llvm_ty, operand, "") | 6547 | self.builder.buildLoad(optional_llvm_ty, operand, "") |
| 6636 | else | 6548 | else |
| 6637 | operand; | 6549 | operand; |
| 6638 | const llvm_i8 = self.dg.context.intType(8); | 6550 | const llvm_i8 = self.context.intType(8); |
| 6639 | return self.builder.buildICmp(pred, loaded, llvm_i8.constNull(), ""); | 6551 | return self.builder.buildICmp(pred, loaded, llvm_i8.constNull(), ""); |
| 6640 | } | 6552 | } |
| 6641 | | 6553 | |
| ... | @@ -6701,16 +6613,12 @@ pub const FuncGen = struct { | ... | @@ -6701,16 +6613,12 @@ pub const FuncGen = struct { |
| 6701 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 6613 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 6702 | const operand = try self.resolveInst(ty_op.operand); | 6614 | const operand = try self.resolveInst(ty_op.operand); |
| 6703 | const optional_ty = self.air.typeOf(ty_op.operand).childType(); | 6615 | const optional_ty = self.air.typeOf(ty_op.operand).childType(); |
| 6704 | const result_ty = self.air.getRefType(ty_op.ty); | | |
| 6705 | var buf: Type.Payload.ElemType = undefined; | 6616 | var buf: Type.Payload.ElemType = undefined; |
| 6706 | const payload_ty = optional_ty.optionalChild(&buf); | 6617 | const payload_ty = optional_ty.optionalChild(&buf); |
| 6707 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { | 6618 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 6708 | // We have a pointer to a zero-bit value and we need to return | 6619 | // We have a pointer to a zero-bit value and we need to return |
| 6709 | // a pointer to a zero-bit value. | 6620 | // a pointer to a zero-bit value. |
| 6710 | | 6621 | return operand; |
| 6711 | // TODO once we update to LLVM 16 this bitcast won't be necessary. | | |
| 6712 | const res_ptr_ty = try self.dg.lowerType(result_ty); | | |
| 6713 | return self.builder.buildBitCast(operand, res_ptr_ty, ""); | | |
| 6714 | } | 6622 | } |
| 6715 | if (optional_ty.optionalReprIsPayload()) { | 6623 | if (optional_ty.optionalReprIsPayload()) { |
| 6716 | // The payload and the optional are the same value. | 6624 | // The payload and the optional are the same value. |
| ... | @@ -6726,17 +6634,13 @@ pub const FuncGen = struct { | ... | @@ -6726,17 +6634,13 @@ pub const FuncGen = struct { |
| 6726 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 6634 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 6727 | const operand = try self.resolveInst(ty_op.operand); | 6635 | const operand = try self.resolveInst(ty_op.operand); |
| 6728 | const optional_ty = self.air.typeOf(ty_op.operand).childType(); | 6636 | const optional_ty = self.air.typeOf(ty_op.operand).childType(); |
| 6729 | const result_ty = self.air.getRefType(ty_op.ty); | | |
| 6730 | var buf: Type.Payload.ElemType = undefined; | 6637 | var buf: Type.Payload.ElemType = undefined; |
| 6731 | const payload_ty = optional_ty.optionalChild(&buf); | 6638 | const payload_ty = optional_ty.optionalChild(&buf); |
| 6732 | const non_null_bit = self.context.intType(8).constInt(1, .False); | 6639 | const non_null_bit = self.context.intType(8).constInt(1, .False); |
| 6733 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { | 6640 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 6734 | // We have a pointer to a i8. We need to set it to 1 and then return the same pointer. | 6641 | // We have a pointer to a i8. We need to set it to 1 and then return the same pointer. |
| 6735 | _ = self.builder.buildStore(non_null_bit, operand); | 6642 | _ = self.builder.buildStore(non_null_bit, operand); |
| 6736 | | 6643 | return operand; |
| 6737 | // TODO once we update to LLVM 16 this bitcast won't be necessary. | | |
| 6738 | const res_ptr_ty = try self.dg.lowerType(result_ty); | | |
| 6739 | return self.builder.buildBitCast(operand, res_ptr_ty, ""); | | |
| 6740 | } | 6644 | } |
| 6741 | if (optional_ty.optionalReprIsPayload()) { | 6645 | if (optional_ty.optionalReprIsPayload()) { |
| 6742 | // The payload and the optional are the same value. | 6646 | // The payload and the optional are the same value. |
| ... | @@ -6794,11 +6698,7 @@ pub const FuncGen = struct { | ... | @@ -6794,11 +6698,7 @@ pub const FuncGen = struct { |
| 6794 | const target = self.dg.module.getTarget(); | 6698 | const target = self.dg.module.getTarget(); |
| 6795 | | 6699 | |
| 6796 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { | 6700 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 6797 | if (!operand_is_ptr) return null; | 6701 | return if (operand_is_ptr) operand else null; |
| 6798 | | | |
| 6799 | // TODO once we update to LLVM 14 this bitcast won't be necessary. | | |
| 6800 | const res_ptr_ty = try self.dg.lowerType(result_ty); | | |
| 6801 | return self.builder.buildBitCast(operand, res_ptr_ty, ""); | | |
| 6802 | } | 6702 | } |
| 6803 | const offset = errUnionPayloadOffset(payload_ty, target); | 6703 | const offset = errUnionPayloadOffset(payload_ty, target); |
| 6804 | const err_union_llvm_ty = try self.dg.lowerType(err_union_ty); | 6704 | const err_union_llvm_ty = try self.dg.lowerType(err_union_ty); |
| ... | @@ -6834,7 +6734,7 @@ pub const FuncGen = struct { | ... | @@ -6834,7 +6734,7 @@ pub const FuncGen = struct { |
| 6834 | if (err_union_ty.errorUnionSet().errorSetIsEmpty()) { | 6734 | if (err_union_ty.errorUnionSet().errorSetIsEmpty()) { |
| 6835 | const err_llvm_ty = try self.dg.lowerType(Type.anyerror); | 6735 | const err_llvm_ty = try self.dg.lowerType(Type.anyerror); |
| 6836 | if (operand_is_ptr) { | 6736 | if (operand_is_ptr) { |
| 6837 | return self.builder.buildBitCast(operand, err_llvm_ty.pointerType(0), ""); | 6737 | return operand; |
| 6838 | } else { | 6738 | } else { |
| 6839 | return err_llvm_ty.constInt(0, .False); | 6739 | return err_llvm_ty.constInt(0, .False); |
| 6840 | } | 6740 | } |
| ... | @@ -7104,14 +7004,8 @@ pub const FuncGen = struct { | ... | @@ -7104,14 +7004,8 @@ pub const FuncGen = struct { |
| 7104 | const llvm_slice_ty = try self.dg.lowerType(inst_ty); | 7004 | const llvm_slice_ty = try self.dg.lowerType(inst_ty); |
| 7105 | | 7005 | |
| 7106 | // In case of slicing a global, the result type looks something like `{ i8*, i64 }` | 7006 | // In case of slicing a global, the result type looks something like `{ i8*, i64 }` |
| 7107 | // but `ptr` is pointing to the global directly. If it's an array, we would want to | 7007 | // but `ptr` is pointing to the global directly. |
| 7108 | // do GEP(0,0), or we can just bitcast it to be correct, like we do here. | 7008 | const partial = self.builder.buildInsertValue(llvm_slice_ty.getUndef(), ptr, 0, ""); |
| 7109 | // This prevents an assertion failure. | | |
| 7110 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | | |
| 7111 | const ptr_ty = inst_ty.slicePtrFieldType(&buf); | | |
| 7112 | const ptr_llvm_ty = try self.dg.lowerType(ptr_ty); | | |
| 7113 | const casted_ptr = self.builder.buildBitCast(ptr, ptr_llvm_ty, ""); | | |
| 7114 | const partial = self.builder.buildInsertValue(llvm_slice_ty.getUndef(), casted_ptr, 0, ""); | | |
| 7115 | return self.builder.buildInsertValue(partial, len, 1, ""); | 7009 | return self.builder.buildInsertValue(partial, len, 1, ""); |
| 7116 | } | 7010 | } |
| 7117 | | 7011 | |
| ... | @@ -7636,7 +7530,7 @@ pub const FuncGen = struct { | ... | @@ -7636,7 +7530,7 @@ pub const FuncGen = struct { |
| 7636 | .neg => { | 7530 | .neg => { |
| 7637 | // In this case we can generate a softfloat negation by XORing the | 7531 | // In this case we can generate a softfloat negation by XORing the |
| 7638 | // bits with a constant. | 7532 | // bits with a constant. |
| 7639 | const int_llvm_ty = self.dg.context.intType(float_bits); | 7533 | const int_llvm_ty = self.context.intType(float_bits); |
| 7640 | const one = int_llvm_ty.constInt(1, .False); | 7534 | const one = int_llvm_ty.constInt(1, .False); |
| 7641 | const shift_amt = int_llvm_ty.constInt(float_bits - 1, .False); | 7535 | const shift_amt = int_llvm_ty.constInt(float_bits - 1, .False); |
| 7642 | const sign_mask = one.constShl(shift_amt); | 7536 | const sign_mask = one.constShl(shift_amt); |
| ... | @@ -8045,8 +7939,8 @@ pub const FuncGen = struct { | ... | @@ -8045,8 +7939,8 @@ pub const FuncGen = struct { |
| 8045 | const target = self.dg.module.getTarget(); | 7939 | const target = self.dg.module.getTarget(); |
| 8046 | | 7940 | |
| 8047 | if (operand_is_ref and result_is_ref) { | 7941 | if (operand_is_ref and result_is_ref) { |
| 8048 | // They are both pointers; just do a bitcast on the pointers :) | 7942 | // They are both pointers, so just return the same opaque pointer :) |
| 8049 | return self.builder.buildBitCast(operand, llvm_dest_ty.pointerType(0), ""); | 7943 | return operand; |
| 8050 | } | 7944 | } |
| 8051 | | 7945 | |
| 8052 | if (operand_ty.zigTypeTag() == .Int and inst_ty.isPtrAtRuntime()) { | 7946 | if (operand_ty.zigTypeTag() == .Int and inst_ty.isPtrAtRuntime()) { |
| ... | @@ -8061,9 +7955,7 @@ pub const FuncGen = struct { | ... | @@ -8061,9 +7955,7 @@ pub const FuncGen = struct { |
| 8061 | const array_ptr = self.buildAlloca(llvm_dest_ty, null); | 7955 | const array_ptr = self.buildAlloca(llvm_dest_ty, null); |
| 8062 | const bitcast_ok = elem_ty.bitSize(target) == elem_ty.abiSize(target) * 8; | 7956 | const bitcast_ok = elem_ty.bitSize(target) == elem_ty.abiSize(target) * 8; |
| 8063 | if (bitcast_ok) { | 7957 | if (bitcast_ok) { |
| 8064 | const llvm_vector_ty = try self.dg.lowerType(operand_ty); | 7958 | const llvm_store = self.builder.buildStore(operand, array_ptr); |
| 8065 | const casted_ptr = self.builder.buildBitCast(array_ptr, llvm_vector_ty.pointerType(0), ""); | | |
| 8066 | const llvm_store = self.builder.buildStore(operand, casted_ptr); | | |
| 8067 | llvm_store.setAlignment(inst_ty.abiAlignment(target)); | 7959 | llvm_store.setAlignment(inst_ty.abiAlignment(target)); |
| 8068 | } else { | 7960 | } else { |
| 8069 | // If the ABI size of the element type is not evenly divisible by size in bits; | 7961 | // If the ABI size of the element type is not evenly divisible by size in bits; |
| ... | @@ -8092,9 +7984,7 @@ pub const FuncGen = struct { | ... | @@ -8092,9 +7984,7 @@ pub const FuncGen = struct { |
| 8092 | | 7984 | |
| 8093 | const bitcast_ok = elem_ty.bitSize(target) == elem_ty.abiSize(target) * 8; | 7985 | const bitcast_ok = elem_ty.bitSize(target) == elem_ty.abiSize(target) * 8; |
| 8094 | if (bitcast_ok) { | 7986 | if (bitcast_ok) { |
| 8095 | const llvm_vector_ptr_ty = llvm_vector_ty.pointerType(0); | 7987 | const vector = self.builder.buildLoad(llvm_vector_ty, operand, ""); |
| 8096 | const casted_ptr = self.builder.buildBitCast(operand, llvm_vector_ptr_ty, ""); | | |
| 8097 | const vector = self.builder.buildLoad(llvm_vector_ty, casted_ptr, ""); | | |
| 8098 | // The array is aligned to the element's alignment, while the vector might have a completely | 7988 | // The array is aligned to the element's alignment, while the vector might have a completely |
| 8099 | // different alignment. This means we need to enforce the alignment of this load. | 7989 | // different alignment. This means we need to enforce the alignment of this load. |
| 8100 | vector.setAlignment(elem_ty.abiAlignment(target)); | 7990 | vector.setAlignment(elem_ty.abiAlignment(target)); |
| ... | @@ -8124,20 +8014,15 @@ pub const FuncGen = struct { | ... | @@ -8124,20 +8014,15 @@ pub const FuncGen = struct { |
| 8124 | } | 8014 | } |
| 8125 | | 8015 | |
| 8126 | if (operand_is_ref) { | 8016 | if (operand_is_ref) { |
| 8127 | // Bitcast the operand pointer, then load. | 8017 | const load_inst = self.builder.buildLoad(llvm_dest_ty, operand, ""); |
| 8128 | const casted_ptr = self.builder.buildBitCast(operand, llvm_dest_ty.pointerType(0), ""); | | |
| 8129 | const load_inst = self.builder.buildLoad(llvm_dest_ty, casted_ptr, ""); | | |
| 8130 | load_inst.setAlignment(operand_ty.abiAlignment(target)); | 8018 | load_inst.setAlignment(operand_ty.abiAlignment(target)); |
| 8131 | return load_inst; | 8019 | return load_inst; |
| 8132 | } | 8020 | } |
| 8133 | | 8021 | |
| 8134 | if (result_is_ref) { | 8022 | if (result_is_ref) { |
| 8135 | // Bitcast the result pointer, then store. | | |
| 8136 | const alignment = @max(operand_ty.abiAlignment(target), inst_ty.abiAlignment(target)); | 8023 | const alignment = @max(operand_ty.abiAlignment(target), inst_ty.abiAlignment(target)); |
| 8137 | const result_ptr = self.buildAlloca(llvm_dest_ty, alignment); | 8024 | const result_ptr = self.buildAlloca(llvm_dest_ty, alignment); |
| 8138 | const operand_llvm_ty = try self.dg.lowerType(operand_ty); | 8025 | const store_inst = self.builder.buildStore(operand, result_ptr); |
| 8139 | const casted_ptr = self.builder.buildBitCast(result_ptr, operand_llvm_ty.pointerType(0), ""); | | |
| 8140 | const store_inst = self.builder.buildStore(operand, casted_ptr); | | |
| 8141 | store_inst.setAlignment(alignment); | 8026 | store_inst.setAlignment(alignment); |
| 8142 | return result_ptr; | 8027 | return result_ptr; |
| 8143 | } | 8028 | } |
| ... | @@ -8145,12 +8030,10 @@ pub const FuncGen = struct { | ... | @@ -8145,12 +8030,10 @@ pub const FuncGen = struct { |
| 8145 | if (llvm_dest_ty.getTypeKind() == .Struct) { | 8030 | if (llvm_dest_ty.getTypeKind() == .Struct) { |
| 8146 | // Both our operand and our result are values, not pointers, | 8031 | // Both our operand and our result are values, not pointers, |
| 8147 | // but LLVM won't let us bitcast struct values. | 8032 | // but LLVM won't let us bitcast struct values. |
| 8148 | // Therefore, we store operand to bitcasted alloca, then load for result. | 8033 | // Therefore, we store operand to alloca, then load for result. |
| 8149 | const alignment = @max(operand_ty.abiAlignment(target), inst_ty.abiAlignment(target)); | 8034 | const alignment = @max(operand_ty.abiAlignment(target), inst_ty.abiAlignment(target)); |
| 8150 | const result_ptr = self.buildAlloca(llvm_dest_ty, alignment); | 8035 | const result_ptr = self.buildAlloca(llvm_dest_ty, alignment); |
| 8151 | const operand_llvm_ty = try self.dg.lowerType(operand_ty); | 8036 | const store_inst = self.builder.buildStore(operand, result_ptr); |
| 8152 | const casted_ptr = self.builder.buildBitCast(result_ptr, operand_llvm_ty.pointerType(0), ""); | | |
| 8153 | const store_inst = self.builder.buildStore(operand, casted_ptr); | | |
| 8154 | store_inst.setAlignment(alignment); | 8037 | store_inst.setAlignment(alignment); |
| 8155 | const load_inst = self.builder.buildLoad(llvm_dest_ty, result_ptr, ""); | 8038 | const load_inst = self.builder.buildLoad(llvm_dest_ty, result_ptr, ""); |
| 8156 | load_inst.setAlignment(alignment); | 8039 | load_inst.setAlignment(alignment); |
| ... | @@ -8248,7 +8131,7 @@ pub const FuncGen = struct { | ... | @@ -8248,7 +8131,7 @@ pub const FuncGen = struct { |
| 8248 | /// Use this instead of builder.buildAlloca, because this function makes sure to | 8131 | /// Use this instead of builder.buildAlloca, because this function makes sure to |
| 8249 | /// put the alloca instruction at the top of the function! | 8132 | /// put the alloca instruction at the top of the function! |
| 8250 | fn buildAlloca(self: *FuncGen, llvm_ty: *llvm.Type, alignment: ?c_uint) *llvm.Value { | 8133 | fn buildAlloca(self: *FuncGen, llvm_ty: *llvm.Type, alignment: ?c_uint) *llvm.Value { |
| 8251 | return buildAllocaInner(self.builder, self.llvm_func, self.di_scope != null, llvm_ty, alignment, self.dg.module.getTarget()); | 8134 | return buildAllocaInner(self.context, self.builder, self.llvm_func, self.di_scope != null, llvm_ty, alignment, self.dg.module.getTarget()); |
| 8252 | } | 8135 | } |
| 8253 | | 8136 | |
| 8254 | fn airStore(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { | 8137 | fn airStore(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| ... | @@ -8282,13 +8165,11 @@ pub const FuncGen = struct { | ... | @@ -8282,13 +8165,11 @@ pub const FuncGen = struct { |
| 8282 | const target = self.dg.module.getTarget(); | 8165 | const target = self.dg.module.getTarget(); |
| 8283 | const operand_size = operand_ty.abiSize(target); | 8166 | const operand_size = operand_ty.abiSize(target); |
| 8284 | const u8_llvm_ty = self.context.intType(8); | 8167 | const u8_llvm_ty = self.context.intType(8); |
| 8285 | const ptr_u8_llvm_ty = u8_llvm_ty.pointerType(0); | | |
| 8286 | const dest_ptr_u8 = self.builder.buildBitCast(dest_ptr, ptr_u8_llvm_ty, ""); | | |
| 8287 | const fill_char = u8_llvm_ty.constInt(0xaa, .False); | 8168 | const fill_char = u8_llvm_ty.constInt(0xaa, .False); |
| 8288 | const dest_ptr_align = ptr_ty.ptrAlignment(target); | 8169 | const dest_ptr_align = ptr_ty.ptrAlignment(target); |
| 8289 | const usize_llvm_ty = try self.dg.lowerType(Type.usize); | 8170 | const usize_llvm_ty = try self.dg.lowerType(Type.usize); |
| 8290 | const len = usize_llvm_ty.constInt(operand_size, .False); | 8171 | const len = usize_llvm_ty.constInt(operand_size, .False); |
| 8291 | _ = self.builder.buildMemSet(dest_ptr_u8, fill_char, len, dest_ptr_align, ptr_ty.isVolatilePtr()); | 8172 | _ = self.builder.buildMemSet(dest_ptr, fill_char, len, dest_ptr_align, ptr_ty.isVolatilePtr()); |
| 8292 | if (self.dg.module.comp.bin_file.options.valgrind) { | 8173 | if (self.dg.module.comp.bin_file.options.valgrind) { |
| 8293 | self.valgrindMarkUndef(dest_ptr, len); | 8174 | self.valgrindMarkUndef(dest_ptr, len); |
| 8294 | } | 8175 | } |
| ... | @@ -8365,7 +8246,7 @@ pub const FuncGen = struct { | ... | @@ -8365,7 +8246,7 @@ pub const FuncGen = struct { |
| 8365 | const llvm_i32 = self.context.intType(32); | 8246 | const llvm_i32 = self.context.intType(32); |
| 8366 | const llvm_fn_name = "llvm.frameaddress.p0"; | 8247 | const llvm_fn_name = "llvm.frameaddress.p0"; |
| 8367 | const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: { | 8248 | const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: { |
| 8368 | const llvm_p0i8 = self.context.intType(8).pointerType(0); | 8249 | const llvm_p0i8 = self.context.pointerType(0); |
| 8369 | const param_types = [_]*llvm.Type{llvm_i32}; | 8250 | const param_types = [_]*llvm.Type{llvm_i32}; |
| 8370 | const fn_type = llvm.functionType(llvm_p0i8, &param_types, param_types.len, .False); | 8251 | const fn_type = llvm.functionType(llvm_p0i8, &param_types, param_types.len, .False); |
| 8371 | break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type); | 8252 | break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type); |
| ... | @@ -8388,14 +8269,13 @@ pub const FuncGen = struct { | ... | @@ -8388,14 +8269,13 @@ pub const FuncGen = struct { |
| 8388 | fn airCmpxchg(self: *FuncGen, inst: Air.Inst.Index, is_weak: bool) !?*llvm.Value { | 8269 | fn airCmpxchg(self: *FuncGen, inst: Air.Inst.Index, is_weak: bool) !?*llvm.Value { |
| 8389 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 8270 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 8390 | const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data; | 8271 | const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data; |
| 8391 | var ptr = try self.resolveInst(extra.ptr); | 8272 | const ptr = try self.resolveInst(extra.ptr); |
| 8392 | var expected_value = try self.resolveInst(extra.expected_value); | 8273 | var expected_value = try self.resolveInst(extra.expected_value); |
| 8393 | var new_value = try self.resolveInst(extra.new_value); | 8274 | var new_value = try self.resolveInst(extra.new_value); |
| 8394 | const operand_ty = self.air.typeOf(extra.ptr).elemType(); | 8275 | const operand_ty = self.air.typeOf(extra.ptr).elemType(); |
| 8395 | const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false); | 8276 | const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false); |
| 8396 | if (opt_abi_ty) |abi_ty| { | 8277 | if (opt_abi_ty) |abi_ty| { |
| 8397 | // operand needs widening and truncating | 8278 | // operand needs widening and truncating |
| 8398 | ptr = self.builder.buildBitCast(ptr, abi_ty.pointerType(0), ""); | | |
| 8399 | if (operand_ty.isSignedInt()) { | 8279 | if (operand_ty.isSignedInt()) { |
| 8400 | expected_value = self.builder.buildSExt(expected_value, abi_ty, ""); | 8280 | expected_value = self.builder.buildSExt(expected_value, abi_ty, ""); |
| 8401 | new_value = self.builder.buildSExt(new_value, abi_ty, ""); | 8281 | new_value = self.builder.buildSExt(new_value, abi_ty, ""); |
| ... | @@ -8447,7 +8327,6 @@ pub const FuncGen = struct { | ... | @@ -8447,7 +8327,6 @@ pub const FuncGen = struct { |
| 8447 | const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, op == .Xchg); | 8327 | const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, op == .Xchg); |
| 8448 | if (opt_abi_ty) |abi_ty| { | 8328 | if (opt_abi_ty) |abi_ty| { |
| 8449 | // operand needs widening and truncating or bitcasting. | 8329 | // operand needs widening and truncating or bitcasting. |
| 8450 | const casted_ptr = self.builder.buildBitCast(ptr, abi_ty.pointerType(0), ""); | | |
| 8451 | const casted_operand = if (is_float) | 8330 | const casted_operand = if (is_float) |
| 8452 | self.builder.buildBitCast(operand, abi_ty, "") | 8331 | self.builder.buildBitCast(operand, abi_ty, "") |
| 8453 | else if (is_signed_int) | 8332 | else if (is_signed_int) |
| ... | @@ -8457,7 +8336,7 @@ pub const FuncGen = struct { | ... | @@ -8457,7 +8336,7 @@ pub const FuncGen = struct { |
| 8457 | | 8336 | |
| 8458 | const uncasted_result = self.builder.buildAtomicRmw( | 8337 | const uncasted_result = self.builder.buildAtomicRmw( |
| 8459 | op, | 8338 | op, |
| 8460 | casted_ptr, | 8339 | ptr, |
| 8461 | casted_operand, | 8340 | casted_operand, |
| 8462 | ordering, | 8341 | ordering, |
| 8463 | single_threaded, | 8342 | single_threaded, |
| ... | @@ -8476,11 +8355,10 @@ pub const FuncGen = struct { | ... | @@ -8476,11 +8355,10 @@ pub const FuncGen = struct { |
| 8476 | | 8355 | |
| 8477 | // It's a pointer but we need to treat it as an int. | 8356 | // It's a pointer but we need to treat it as an int. |
| 8478 | const usize_llvm_ty = try self.dg.lowerType(Type.usize); | 8357 | const usize_llvm_ty = try self.dg.lowerType(Type.usize); |
| 8479 | const casted_ptr = self.builder.buildBitCast(ptr, usize_llvm_ty.pointerType(0), ""); | | |
| 8480 | const casted_operand = self.builder.buildPtrToInt(operand, usize_llvm_ty, ""); | 8358 | const casted_operand = self.builder.buildPtrToInt(operand, usize_llvm_ty, ""); |
| 8481 | const uncasted_result = self.builder.buildAtomicRmw( | 8359 | const uncasted_result = self.builder.buildAtomicRmw( |
| 8482 | op, | 8360 | op, |
| 8483 | casted_ptr, | 8361 | ptr, |
| 8484 | casted_operand, | 8362 | casted_operand, |
| 8485 | ordering, | 8363 | ordering, |
| 8486 | single_threaded, | 8364 | single_threaded, |
| ... | @@ -8508,8 +8386,7 @@ pub const FuncGen = struct { | ... | @@ -8508,8 +8386,7 @@ pub const FuncGen = struct { |
| 8508 | | 8386 | |
| 8509 | if (opt_abi_llvm_ty) |abi_llvm_ty| { | 8387 | if (opt_abi_llvm_ty) |abi_llvm_ty| { |
| 8510 | // operand needs widening and truncating | 8388 | // operand needs widening and truncating |
| 8511 | const casted_ptr = self.builder.buildBitCast(ptr, abi_llvm_ty.pointerType(0), ""); | 8389 | const load_inst = self.builder.buildLoad(abi_llvm_ty, ptr, ""); |
| 8512 | const load_inst = self.builder.buildLoad(abi_llvm_ty, casted_ptr, ""); | | |
| 8513 | load_inst.setAlignment(ptr_alignment); | 8390 | load_inst.setAlignment(ptr_alignment); |
| 8514 | load_inst.setVolatile(ptr_volatile); | 8391 | load_inst.setVolatile(ptr_volatile); |
| 8515 | load_inst.setOrdering(ordering); | 8392 | load_inst.setOrdering(ordering); |
| ... | @@ -8531,13 +8408,12 @@ pub const FuncGen = struct { | ... | @@ -8531,13 +8408,12 @@ pub const FuncGen = struct { |
| 8531 | const ptr_ty = self.air.typeOf(bin_op.lhs); | 8408 | const ptr_ty = self.air.typeOf(bin_op.lhs); |
| 8532 | const operand_ty = ptr_ty.childType(); | 8409 | const operand_ty = ptr_ty.childType(); |
| 8533 | if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime()) return null; | 8410 | if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime()) return null; |
| 8534 | var ptr = try self.resolveInst(bin_op.lhs); | 8411 | const ptr = try self.resolveInst(bin_op.lhs); |
| 8535 | var element = try self.resolveInst(bin_op.rhs); | 8412 | var element = try self.resolveInst(bin_op.rhs); |
| 8536 | const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false); | 8413 | const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false); |
| 8537 | | 8414 | |
| 8538 | if (opt_abi_ty) |abi_ty| { | 8415 | if (opt_abi_ty) |abi_ty| { |
| 8539 | // operand needs widening | 8416 | // operand needs widening |
| 8540 | ptr = self.builder.buildBitCast(ptr, abi_ty.pointerType(0), ""); | | |
| 8541 | if (operand_ty.isSignedInt()) { | 8417 | if (operand_ty.isSignedInt()) { |
| 8542 | element = self.builder.buildSExt(element, abi_ty, ""); | 8418 | element = self.builder.buildSExt(element, abi_ty, ""); |
| 8543 | } else { | 8419 | } else { |
| ... | @@ -8557,15 +8433,13 @@ pub const FuncGen = struct { | ... | @@ -8557,15 +8433,13 @@ pub const FuncGen = struct { |
| 8557 | const val_is_undef = if (self.air.value(extra.lhs)) |val| val.isUndefDeep() else false; | 8433 | const val_is_undef = if (self.air.value(extra.lhs)) |val| val.isUndefDeep() else false; |
| 8558 | const len = try self.resolveInst(extra.rhs); | 8434 | const len = try self.resolveInst(extra.rhs); |
| 8559 | const u8_llvm_ty = self.context.intType(8); | 8435 | const u8_llvm_ty = self.context.intType(8); |
| 8560 | const ptr_u8_llvm_ty = u8_llvm_ty.pointerType(0); | | |
| 8561 | const dest_ptr_u8 = self.builder.buildBitCast(dest_ptr, ptr_u8_llvm_ty, ""); | | |
| 8562 | const fill_char = if (val_is_undef) u8_llvm_ty.constInt(0xaa, .False) else value; | 8436 | const fill_char = if (val_is_undef) u8_llvm_ty.constInt(0xaa, .False) else value; |
| 8563 | const target = self.dg.module.getTarget(); | 8437 | const target = self.dg.module.getTarget(); |
| 8564 | const dest_ptr_align = ptr_ty.ptrAlignment(target); | 8438 | const dest_ptr_align = ptr_ty.ptrAlignment(target); |
| 8565 | _ = self.builder.buildMemSet(dest_ptr_u8, fill_char, len, dest_ptr_align, ptr_ty.isVolatilePtr()); | 8439 | _ = self.builder.buildMemSet(dest_ptr, fill_char, len, dest_ptr_align, ptr_ty.isVolatilePtr()); |
| 8566 | | 8440 | |
| 8567 | if (val_is_undef and self.dg.module.comp.bin_file.options.valgrind) { | 8441 | if (val_is_undef and self.dg.module.comp.bin_file.options.valgrind) { |
| 8568 | self.valgrindMarkUndef(dest_ptr_u8, len); | 8442 | self.valgrindMarkUndef(dest_ptr, len); |
| 8569 | } | 8443 | } |
| 8570 | return null; | 8444 | return null; |
| 8571 | } | 8445 | } |
| ... | @@ -8578,15 +8452,12 @@ pub const FuncGen = struct { | ... | @@ -8578,15 +8452,12 @@ pub const FuncGen = struct { |
| 8578 | const src_ptr = try self.resolveInst(extra.lhs); | 8452 | const src_ptr = try self.resolveInst(extra.lhs); |
| 8579 | const src_ptr_ty = self.air.typeOf(extra.lhs); | 8453 | const src_ptr_ty = self.air.typeOf(extra.lhs); |
| 8580 | const len = try self.resolveInst(extra.rhs); | 8454 | const len = try self.resolveInst(extra.rhs); |
| 8581 | const llvm_ptr_u8 = self.context.intType(8).pointerType(0); | | |
| 8582 | const dest_ptr_u8 = self.builder.buildBitCast(dest_ptr, llvm_ptr_u8, ""); | | |
| 8583 | const src_ptr_u8 = self.builder.buildBitCast(src_ptr, llvm_ptr_u8, ""); | | |
| 8584 | const is_volatile = src_ptr_ty.isVolatilePtr() or dest_ptr_ty.isVolatilePtr(); | 8455 | const is_volatile = src_ptr_ty.isVolatilePtr() or dest_ptr_ty.isVolatilePtr(); |
| 8585 | const target = self.dg.module.getTarget(); | 8456 | const target = self.dg.module.getTarget(); |
| 8586 | _ = self.builder.buildMemCpy( | 8457 | _ = self.builder.buildMemCpy( |
| 8587 | dest_ptr_u8, | 8458 | dest_ptr, |
| 8588 | dest_ptr_ty.ptrAlignment(target), | 8459 | dest_ptr_ty.ptrAlignment(target), |
| 8589 | src_ptr_u8, | 8460 | src_ptr, |
| 8590 | src_ptr_ty.ptrAlignment(target), | 8461 | src_ptr_ty.ptrAlignment(target), |
| 8591 | len, | 8462 | len, |
| 8592 | is_volatile, | 8463 | is_volatile, |
| ... | @@ -8780,8 +8651,8 @@ pub const FuncGen = struct { | ... | @@ -8780,8 +8651,8 @@ pub const FuncGen = struct { |
| 8780 | const error_set_ty = self.air.getRefType(ty_op.ty); | 8651 | const error_set_ty = self.air.getRefType(ty_op.ty); |
| 8781 | | 8652 | |
| 8782 | const names = error_set_ty.errorSetNames(); | 8653 | const names = error_set_ty.errorSetNames(); |
| 8783 | const valid_block = self.dg.context.appendBasicBlock(self.llvm_func, "Valid"); | 8654 | const valid_block = self.context.appendBasicBlock(self.llvm_func, "Valid"); |
| 8784 | const invalid_block = self.dg.context.appendBasicBlock(self.llvm_func, "Invalid"); | 8655 | const invalid_block = self.context.appendBasicBlock(self.llvm_func, "Invalid"); |
| 8785 | const end_block = self.context.appendBasicBlock(self.llvm_func, "End"); | 8656 | const end_block = self.context.appendBasicBlock(self.llvm_func, "End"); |
| 8786 | const switch_instr = self.builder.buildSwitch(operand, invalid_block, @intCast(c_uint, names.len)); | 8657 | const switch_instr = self.builder.buildSwitch(operand, invalid_block, @intCast(c_uint, names.len)); |
| 8787 | | 8658 | |
| ... | @@ -8807,7 +8678,7 @@ pub const FuncGen = struct { | ... | @@ -8807,7 +8678,7 @@ pub const FuncGen = struct { |
| 8807 | | 8678 | |
| 8808 | self.builder.positionBuilderAtEnd(end_block); | 8679 | self.builder.positionBuilderAtEnd(end_block); |
| 8809 | | 8680 | |
| 8810 | const llvm_type = self.dg.context.intType(1); | 8681 | const llvm_type = self.context.intType(1); |
| 8811 | const incoming_values: [2]*llvm.Value = .{ | 8682 | const incoming_values: [2]*llvm.Value = .{ |
| 8812 | llvm_type.constInt(1, .False), llvm_type.constInt(0, .False), | 8683 | llvm_type.constInt(1, .False), llvm_type.constInt(0, .False), |
| 8813 | }; | 8684 | }; |
| ... | @@ -8869,13 +8740,13 @@ pub const FuncGen = struct { | ... | @@ -8869,13 +8740,13 @@ pub const FuncGen = struct { |
| 8869 | } | 8740 | } |
| 8870 | } | 8741 | } |
| 8871 | | 8742 | |
| 8872 | const entry_block = self.dg.context.appendBasicBlock(fn_val, "Entry"); | 8743 | const entry_block = self.context.appendBasicBlock(fn_val, "Entry"); |
| 8873 | self.builder.positionBuilderAtEnd(entry_block); | 8744 | self.builder.positionBuilderAtEnd(entry_block); |
| 8874 | self.builder.clearCurrentDebugLocation(); | 8745 | self.builder.clearCurrentDebugLocation(); |
| 8875 | | 8746 | |
| 8876 | const fields = enum_ty.enumFields(); | 8747 | const fields = enum_ty.enumFields(); |
| 8877 | const named_block = self.dg.context.appendBasicBlock(fn_val, "Named"); | 8748 | const named_block = self.context.appendBasicBlock(fn_val, "Named"); |
| 8878 | const unnamed_block = self.dg.context.appendBasicBlock(fn_val, "Unnamed"); | 8749 | const unnamed_block = self.context.appendBasicBlock(fn_val, "Unnamed"); |
| 8879 | const tag_int_value = fn_val.getParam(0); | 8750 | const tag_int_value = fn_val.getParam(0); |
| 8880 | const switch_instr = self.builder.buildSwitch(tag_int_value, unnamed_block, @intCast(c_uint, fields.count())); | 8751 | const switch_instr = self.builder.buildSwitch(tag_int_value, unnamed_block, @intCast(c_uint, fields.count())); |
| 8881 | | 8752 | |
| ... | @@ -8893,10 +8764,10 @@ pub const FuncGen = struct { | ... | @@ -8893,10 +8764,10 @@ pub const FuncGen = struct { |
| 8893 | switch_instr.addCase(this_tag_int_value, named_block); | 8764 | switch_instr.addCase(this_tag_int_value, named_block); |
| 8894 | } | 8765 | } |
| 8895 | self.builder.positionBuilderAtEnd(named_block); | 8766 | self.builder.positionBuilderAtEnd(named_block); |
| 8896 | _ = self.builder.buildRet(self.dg.context.intType(1).constInt(1, .False)); | 8767 | _ = self.builder.buildRet(self.context.intType(1).constInt(1, .False)); |
| 8897 | | 8768 | |
| 8898 | self.builder.positionBuilderAtEnd(unnamed_block); | 8769 | self.builder.positionBuilderAtEnd(unnamed_block); |
| 8899 | _ = self.builder.buildRet(self.dg.context.intType(1).constInt(0, .False)); | 8770 | _ = self.builder.buildRet(self.context.intType(1).constInt(0, .False)); |
| 8900 | return fn_val; | 8771 | return fn_val; |
| 8901 | } | 8772 | } |
| 8902 | | 8773 | |
| ... | @@ -8955,12 +8826,12 @@ pub const FuncGen = struct { | ... | @@ -8955,12 +8826,12 @@ pub const FuncGen = struct { |
| 8955 | } | 8826 | } |
| 8956 | } | 8827 | } |
| 8957 | | 8828 | |
| 8958 | const entry_block = self.dg.context.appendBasicBlock(fn_val, "Entry"); | 8829 | const entry_block = self.context.appendBasicBlock(fn_val, "Entry"); |
| 8959 | self.builder.positionBuilderAtEnd(entry_block); | 8830 | self.builder.positionBuilderAtEnd(entry_block); |
| 8960 | self.builder.clearCurrentDebugLocation(); | 8831 | self.builder.clearCurrentDebugLocation(); |
| 8961 | | 8832 | |
| 8962 | const fields = enum_ty.enumFields(); | 8833 | const fields = enum_ty.enumFields(); |
| 8963 | const bad_value_block = self.dg.context.appendBasicBlock(fn_val, "BadValue"); | 8834 | const bad_value_block = self.context.appendBasicBlock(fn_val, "BadValue"); |
| 8964 | const tag_int_value = fn_val.getParam(0); | 8835 | const tag_int_value = fn_val.getParam(0); |
| 8965 | const switch_instr = self.builder.buildSwitch(tag_int_value, bad_value_block, @intCast(c_uint, fields.count())); | 8836 | const switch_instr = self.builder.buildSwitch(tag_int_value, bad_value_block, @intCast(c_uint, fields.count())); |
| 8966 | | 8837 | |
| ... | @@ -8969,7 +8840,7 @@ pub const FuncGen = struct { | ... | @@ -8969,7 +8840,7 @@ pub const FuncGen = struct { |
| 8969 | }; | 8840 | }; |
| 8970 | | 8841 | |
| 8971 | for (fields.keys()) |name, field_index| { | 8842 | for (fields.keys()) |name, field_index| { |
| 8972 | const str_init = self.dg.context.constString(name.ptr, @intCast(c_uint, name.len), .False); | 8843 | const str_init = self.context.constString(name.ptr, @intCast(c_uint, name.len), .False); |
| 8973 | const str_init_llvm_ty = str_init.typeOf(); | 8844 | const str_init_llvm_ty = str_init.typeOf(); |
| 8974 | const str_global = self.dg.object.llvm_module.addGlobal(str_init_llvm_ty, ""); | 8845 | const str_global = self.dg.object.llvm_module.addGlobal(str_init_llvm_ty, ""); |
| 8975 | str_global.setInitializer(str_init); | 8846 | str_global.setInitializer(str_init); |
| ... | @@ -8990,7 +8861,7 @@ pub const FuncGen = struct { | ... | @@ -8990,7 +8861,7 @@ pub const FuncGen = struct { |
| 8990 | slice_global.setUnnamedAddr(.True); | 8861 | slice_global.setUnnamedAddr(.True); |
| 8991 | slice_global.setAlignment(slice_alignment); | 8862 | slice_global.setAlignment(slice_alignment); |
| 8992 | | 8863 | |
| 8993 | const return_block = self.dg.context.appendBasicBlock(fn_val, "Name"); | 8864 | const return_block = self.context.appendBasicBlock(fn_val, "Name"); |
| 8994 | const this_tag_int_value = int: { | 8865 | const this_tag_int_value = int: { |
| 8995 | var tag_val_payload: Value.Payload.U32 = .{ | 8866 | var tag_val_payload: Value.Payload.U32 = .{ |
| 8996 | .base = .{ .tag = .enum_field_index }, | 8867 | .base = .{ .tag = .enum_field_index }, |
| ... | @@ -9042,7 +8913,7 @@ pub const FuncGen = struct { | ... | @@ -9042,7 +8913,7 @@ pub const FuncGen = struct { |
| 9042 | const slice_llvm_ty = try self.dg.lowerType(slice_ty); | 8913 | const slice_llvm_ty = try self.dg.lowerType(slice_ty); |
| 9043 | | 8914 | |
| 9044 | const error_name_table_ptr = try self.getErrorNameTable(); | 8915 | const error_name_table_ptr = try self.getErrorNameTable(); |
| 9045 | const ptr_slice_llvm_ty = slice_llvm_ty.pointerType(0); | 8916 | const ptr_slice_llvm_ty = self.context.pointerType(0); |
| 9046 | const error_name_table = self.builder.buildLoad(ptr_slice_llvm_ty, error_name_table_ptr, ""); | 8917 | const error_name_table = self.builder.buildLoad(ptr_slice_llvm_ty, error_name_table_ptr, ""); |
| 9047 | const indices = [_]*llvm.Value{operand}; | 8918 | const indices = [_]*llvm.Value{operand}; |
| 9048 | const error_name_ptr = self.builder.buildInBoundsGEP(slice_llvm_ty, error_name_table, &indices, indices.len, ""); | 8919 | const error_name_ptr = self.builder.buildInBoundsGEP(slice_llvm_ty, error_name_table, &indices, indices.len, ""); |
| ... | @@ -9284,8 +9155,9 @@ pub const FuncGen = struct { | ... | @@ -9284,8 +9155,9 @@ pub const FuncGen = struct { |
| 9284 | .Struct => { | 9155 | .Struct => { |
| 9285 | if (result_ty.containerLayout() == .Packed) { | 9156 | if (result_ty.containerLayout() == .Packed) { |
| 9286 | const struct_obj = result_ty.castTag(.@"struct").?.data; | 9157 | const struct_obj = result_ty.castTag(.@"struct").?.data; |
| | 9158 | assert(struct_obj.haveLayout()); |
| 9287 | const big_bits = struct_obj.backing_int_ty.bitSize(target); | 9159 | const big_bits = struct_obj.backing_int_ty.bitSize(target); |
| 9288 | const int_llvm_ty = self.dg.context.intType(@intCast(c_uint, big_bits)); | 9160 | const int_llvm_ty = self.context.intType(@intCast(c_uint, big_bits)); |
| 9289 | const fields = struct_obj.fields.values(); | 9161 | const fields = struct_obj.fields.values(); |
| 9290 | comptime assert(Type.packed_struct_layout_version == 2); | 9162 | comptime assert(Type.packed_struct_layout_version == 2); |
| 9291 | var running_int: *llvm.Value = int_llvm_ty.constNull(); | 9163 | var running_int: *llvm.Value = int_llvm_ty.constNull(); |
| ... | @@ -9296,7 +9168,7 @@ pub const FuncGen = struct { | ... | @@ -9296,7 +9168,7 @@ pub const FuncGen = struct { |
| 9296 | | 9168 | |
| 9297 | const non_int_val = try self.resolveInst(elem); | 9169 | const non_int_val = try self.resolveInst(elem); |
| 9298 | const ty_bit_size = @intCast(u16, field.ty.bitSize(target)); | 9170 | const ty_bit_size = @intCast(u16, field.ty.bitSize(target)); |
| 9299 | const small_int_ty = self.dg.context.intType(ty_bit_size); | 9171 | const small_int_ty = self.context.intType(ty_bit_size); |
| 9300 | const small_int_val = if (field.ty.isPtrAtRuntime()) | 9172 | const small_int_val = if (field.ty.isPtrAtRuntime()) |
| 9301 | self.builder.buildPtrToInt(non_int_val, small_int_ty, "") | 9173 | self.builder.buildPtrToInt(non_int_val, small_int_ty, "") |
| 9302 | else | 9174 | else |
| ... | @@ -9410,11 +9282,11 @@ pub const FuncGen = struct { | ... | @@ -9410,11 +9282,11 @@ pub const FuncGen = struct { |
| 9410 | | 9282 | |
| 9411 | if (union_obj.layout == .Packed) { | 9283 | if (union_obj.layout == .Packed) { |
| 9412 | const big_bits = union_ty.bitSize(target); | 9284 | const big_bits = union_ty.bitSize(target); |
| 9413 | const int_llvm_ty = self.dg.context.intType(@intCast(c_uint, big_bits)); | 9285 | const int_llvm_ty = self.context.intType(@intCast(c_uint, big_bits)); |
| 9414 | const field = union_obj.fields.values()[extra.field_index]; | 9286 | const field = union_obj.fields.values()[extra.field_index]; |
| 9415 | const non_int_val = try self.resolveInst(extra.init); | 9287 | const non_int_val = try self.resolveInst(extra.init); |
| 9416 | const ty_bit_size = @intCast(u16, field.ty.bitSize(target)); | 9288 | const ty_bit_size = @intCast(u16, field.ty.bitSize(target)); |
| 9417 | const small_int_ty = self.dg.context.intType(ty_bit_size); | 9289 | const small_int_ty = self.context.intType(ty_bit_size); |
| 9418 | const small_int_val = if (field.ty.isPtrAtRuntime()) | 9290 | const small_int_val = if (field.ty.isPtrAtRuntime()) |
| 9419 | self.builder.buildPtrToInt(non_int_val, small_int_ty, "") | 9291 | self.builder.buildPtrToInt(non_int_val, small_int_ty, "") |
| 9420 | else | 9292 | else |
| ... | @@ -9444,9 +9316,9 @@ pub const FuncGen = struct { | ... | @@ -9444,9 +9316,9 @@ pub const FuncGen = struct { |
| 9444 | } | 9316 | } |
| 9445 | assert(isByRef(union_ty)); | 9317 | assert(isByRef(union_ty)); |
| 9446 | // The llvm type of the alloca will be the named LLVM union type, and will not | 9318 | // The llvm type of the alloca will be the named LLVM union type, and will not |
| 9447 | // necessarily match the format that we need, depending on which tag is active. We | 9319 | // necessarily match the format that we need, depending on which tag is active. |
| 9448 | // must construct the correct unnamed struct type here and bitcast, in order to | 9320 | // We must construct the correct unnamed struct type here, in order to then set |
| 9449 | // then set the fields appropriately. | 9321 | // the fields appropriately. |
| 9450 | const result_ptr = self.buildAlloca(union_llvm_ty, layout.abi_align); | 9322 | const result_ptr = self.buildAlloca(union_llvm_ty, layout.abi_align); |
| 9451 | const llvm_payload = try self.resolveInst(extra.init); | 9323 | const llvm_payload = try self.resolveInst(extra.init); |
| 9452 | assert(union_obj.haveFieldTypes()); | 9324 | assert(union_obj.haveFieldTypes()); |
| ... | @@ -9489,8 +9361,6 @@ pub const FuncGen = struct { | ... | @@ -9489,8 +9361,6 @@ pub const FuncGen = struct { |
| 9489 | break :t self.context.structType(&fields, fields_len, .False); | 9361 | break :t self.context.structType(&fields, fields_len, .False); |
| 9490 | }; | 9362 | }; |
| 9491 | | 9363 | |
| 9492 | const casted_ptr = self.builder.buildBitCast(result_ptr, llvm_union_ty.pointerType(0), ""); | | |
| 9493 | | | |
| 9494 | // Now we follow the layout as expressed above with GEP instructions to set the | 9364 | // Now we follow the layout as expressed above with GEP instructions to set the |
| 9495 | // tag and the payload. | 9365 | // tag and the payload. |
| 9496 | const index_type = self.context.intType(32); | 9366 | const index_type = self.context.intType(32); |
| ... | @@ -9510,7 +9380,7 @@ pub const FuncGen = struct { | ... | @@ -9510,7 +9380,7 @@ pub const FuncGen = struct { |
| 9510 | index_type.constNull(), | 9380 | index_type.constNull(), |
| 9511 | }; | 9381 | }; |
| 9512 | const len: c_uint = if (field_size == layout.payload_size) 2 else 3; | 9382 | const len: c_uint = if (field_size == layout.payload_size) 2 else 3; |
| 9513 | const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, casted_ptr, &indices, len, ""); | 9383 | const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, result_ptr, &indices, len, ""); |
| 9514 | try self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic); | 9384 | try self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic); |
| 9515 | return result_ptr; | 9385 | return result_ptr; |
| 9516 | } | 9386 | } |
| ... | @@ -9522,7 +9392,7 @@ pub const FuncGen = struct { | ... | @@ -9522,7 +9392,7 @@ pub const FuncGen = struct { |
| 9522 | index_type.constNull(), | 9392 | index_type.constNull(), |
| 9523 | }; | 9393 | }; |
| 9524 | const len: c_uint = if (field_size == layout.payload_size) 2 else 3; | 9394 | const len: c_uint = if (field_size == layout.payload_size) 2 else 3; |
| 9525 | const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, casted_ptr, &indices, len, ""); | 9395 | const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, result_ptr, &indices, len, ""); |
| 9526 | try self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic); | 9396 | try self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic); |
| 9527 | } | 9397 | } |
| 9528 | { | 9398 | { |
| ... | @@ -9530,7 +9400,7 @@ pub const FuncGen = struct { | ... | @@ -9530,7 +9400,7 @@ pub const FuncGen = struct { |
| 9530 | index_type.constNull(), | 9400 | index_type.constNull(), |
| 9531 | index_type.constInt(@boolToInt(layout.tag_align < layout.payload_align), .False), | 9401 | index_type.constInt(@boolToInt(layout.tag_align < layout.payload_align), .False), |
| 9532 | }; | 9402 | }; |
| 9533 | const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, casted_ptr, &indices, indices.len, ""); | 9403 | const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, result_ptr, &indices, indices.len, ""); |
| 9534 | const tag_llvm_ty = try self.dg.lowerType(union_obj.tag_ty); | 9404 | const tag_llvm_ty = try self.dg.lowerType(union_obj.tag_ty); |
| 9535 | const llvm_tag = tag_llvm_ty.constInt(tag_int, .False); | 9405 | const llvm_tag = tag_llvm_ty.constInt(tag_int, .False); |
| 9536 | const store_inst = self.builder.buildStore(llvm_tag, field_ptr); | 9406 | const store_inst = self.builder.buildStore(llvm_tag, field_ptr); |
| ... | @@ -9579,8 +9449,7 @@ pub const FuncGen = struct { | ... | @@ -9579,8 +9449,7 @@ pub const FuncGen = struct { |
| 9579 | .data => {}, | 9449 | .data => {}, |
| 9580 | } | 9450 | } |
| 9581 | | 9451 | |
| 9582 | const llvm_u8 = self.context.intType(8); | 9452 | const llvm_ptr_u8 = self.context.pointerType(0); |
| 9583 | const llvm_ptr_u8 = llvm_u8.pointerType(0); | | |
| 9584 | const llvm_u32 = self.context.intType(32); | 9453 | const llvm_u32 = self.context.intType(32); |
| 9585 | | 9454 | |
| 9586 | const llvm_fn_name = "llvm.prefetch.p0"; | 9455 | const llvm_fn_name = "llvm.prefetch.p0"; |
| ... | @@ -9595,10 +9464,9 @@ pub const FuncGen = struct { | ... | @@ -9595,10 +9464,9 @@ pub const FuncGen = struct { |
| 9595 | }; | 9464 | }; |
| 9596 | | 9465 | |
| 9597 | const ptr = try self.resolveInst(prefetch.ptr); | 9466 | const ptr = try self.resolveInst(prefetch.ptr); |
| 9598 | const ptr_u8 = self.builder.buildBitCast(ptr, llvm_ptr_u8, ""); | | |
| 9599 | | 9467 | |
| 9600 | const params = [_]*llvm.Value{ | 9468 | const params = [_]*llvm.Value{ |
| 9601 | ptr_u8, | 9469 | ptr, |
| 9602 | llvm_u32.constInt(@enumToInt(prefetch.rw), .False), | 9470 | llvm_u32.constInt(@enumToInt(prefetch.rw), .False), |
| 9603 | llvm_u32.constInt(prefetch.locality, .False), | 9471 | llvm_u32.constInt(prefetch.locality, .False), |
| 9604 | llvm_u32.constInt(@enumToInt(prefetch.cache), .False), | 9472 | llvm_u32.constInt(@enumToInt(prefetch.cache), .False), |
| ... | @@ -9625,8 +9493,7 @@ pub const FuncGen = struct { | ... | @@ -9625,8 +9493,7 @@ pub const FuncGen = struct { |
| 9625 | | 9493 | |
| 9626 | const slice_ty = Type.initTag(.const_slice_u8_sentinel_0); | 9494 | const slice_ty = Type.initTag(.const_slice_u8_sentinel_0); |
| 9627 | const slice_alignment = slice_ty.abiAlignment(self.dg.module.getTarget()); | 9495 | const slice_alignment = slice_ty.abiAlignment(self.dg.module.getTarget()); |
| 9628 | const llvm_slice_ty = try self.dg.lowerType(slice_ty); | 9496 | const llvm_slice_ptr_ty = self.context.pointerType(0); // TODO: Address space |
| 9629 | const llvm_slice_ptr_ty = llvm_slice_ty.pointerType(0); // TODO: Address space | | |
| 9630 | | 9497 | |
| 9631 | const error_name_table_global = self.dg.object.llvm_module.addGlobal(llvm_slice_ptr_ty, "__zig_err_name_table"); | 9498 | const error_name_table_global = self.dg.object.llvm_module.addGlobal(llvm_slice_ptr_ty, "__zig_err_name_table"); |
| 9632 | error_name_table_global.setInitializer(llvm_slice_ptr_ty.getUndef()); | 9499 | error_name_table_global.setInitializer(llvm_slice_ptr_ty.getUndef()); |
| ... | @@ -9699,7 +9566,7 @@ pub const FuncGen = struct { | ... | @@ -9699,7 +9566,7 @@ pub const FuncGen = struct { |
| 9699 | non_null_bit: *llvm.Value, | 9566 | non_null_bit: *llvm.Value, |
| 9700 | ) !?*llvm.Value { | 9567 | ) !?*llvm.Value { |
| 9701 | const optional_llvm_ty = try self.dg.lowerType(optional_ty); | 9568 | const optional_llvm_ty = try self.dg.lowerType(optional_ty); |
| 9702 | const non_null_field = self.builder.buildZExt(non_null_bit, self.dg.context.intType(8), ""); | 9569 | const non_null_field = self.builder.buildZExt(non_null_bit, self.context.intType(8), ""); |
| 9703 | | 9570 | |
| 9704 | if (isByRef(optional_ty)) { | 9571 | if (isByRef(optional_ty)) { |
| 9705 | const target = self.dg.module.getTarget(); | 9572 | const target = self.dg.module.getTarget(); |
| ... | @@ -9740,31 +9607,24 @@ pub const FuncGen = struct { | ... | @@ -9740,31 +9607,24 @@ pub const FuncGen = struct { |
| 9740 | .Packed => { | 9607 | .Packed => { |
| 9741 | const result_ty = self.air.typeOfIndex(inst); | 9608 | const result_ty = self.air.typeOfIndex(inst); |
| 9742 | const result_ty_info = result_ty.ptrInfo().data; | 9609 | const result_ty_info = result_ty.ptrInfo().data; |
| 9743 | const result_llvm_ty = try self.dg.lowerType(result_ty); | | |
| 9744 | | 9610 | |
| 9745 | if (result_ty_info.host_size != 0) { | 9611 | if (result_ty_info.host_size != 0) { |
| 9746 | // From LLVM's perspective, a pointer to a packed struct and a pointer | 9612 | // From LLVM's perspective, a pointer to a packed struct and a pointer |
| 9747 | // to a field of a packed struct are the same. The difference is in the | 9613 | // to a field of a packed struct are the same. The difference is in the |
| 9748 | // Zig pointer type which provides information for how to mask and shift | 9614 | // Zig pointer type which provides information for how to mask and shift |
| 9749 | // out the relevant bits when accessing the pointee. | 9615 | // out the relevant bits when accessing the pointee. |
| 9750 | // Here we perform a bitcast because we want to use the host_size | 9616 | return struct_ptr; |
| 9751 | // as the llvm pointer element type. | | |
| 9752 | return self.builder.buildBitCast(struct_ptr, result_llvm_ty, ""); | | |
| 9753 | } | 9617 | } |
| 9754 | | 9618 | |
| 9755 | // We have a pointer to a packed struct field that happens to be byte-aligned. | 9619 | // We have a pointer to a packed struct field that happens to be byte-aligned. |
| 9756 | // Offset our operand pointer by the correct number of bytes. | 9620 | // Offset our operand pointer by the correct number of bytes. |
| 9757 | const byte_offset = struct_ty.packedStructFieldByteOffset(field_index, target); | 9621 | const byte_offset = struct_ty.packedStructFieldByteOffset(field_index, target); |
| 9758 | if (byte_offset == 0) { | 9622 | if (byte_offset == 0) return struct_ptr; |
| 9759 | return self.builder.buildBitCast(struct_ptr, result_llvm_ty, ""); | | |
| 9760 | } | | |
| 9761 | const byte_llvm_ty = self.context.intType(8); | 9623 | const byte_llvm_ty = self.context.intType(8); |
| 9762 | const ptr_as_bytes = self.builder.buildBitCast(struct_ptr, byte_llvm_ty.pointerType(0), ""); | | |
| 9763 | const llvm_usize = try self.dg.lowerType(Type.usize); | 9624 | const llvm_usize = try self.dg.lowerType(Type.usize); |
| 9764 | const llvm_index = llvm_usize.constInt(byte_offset, .False); | 9625 | const llvm_index = llvm_usize.constInt(byte_offset, .False); |
| 9765 | const indices: [1]*llvm.Value = .{llvm_index}; | 9626 | const indices: [1]*llvm.Value = .{llvm_index}; |
| 9766 | const new_ptr = self.builder.buildInBoundsGEP(byte_llvm_ty, ptr_as_bytes, &indices, indices.len, ""); | 9627 | return self.builder.buildInBoundsGEP(byte_llvm_ty, struct_ptr, &indices, indices.len, ""); |
| 9767 | return self.builder.buildBitCast(new_ptr, result_llvm_ty, ""); | | |
| 9768 | }, | 9628 | }, |
| 9769 | else => { | 9629 | else => { |
| 9770 | const struct_llvm_ty = try self.dg.lowerPtrElemTy(struct_ty); | 9630 | const struct_llvm_ty = try self.dg.lowerPtrElemTy(struct_ty); |
| ... | @@ -9777,39 +9637,25 @@ pub const FuncGen = struct { | ... | @@ -9777,39 +9637,25 @@ pub const FuncGen = struct { |
| 9777 | // end of the struct. Treat our struct pointer as an array of two and get | 9637 | // end of the struct. Treat our struct pointer as an array of two and get |
| 9778 | // the index to the element at index `1` to get a pointer to the end of | 9638 | // the index to the element at index `1` to get a pointer to the end of |
| 9779 | // the struct. | 9639 | // the struct. |
| 9780 | const llvm_u32 = self.dg.context.intType(32); | 9640 | const llvm_u32 = self.context.intType(32); |
| 9781 | const llvm_index = llvm_u32.constInt(@boolToInt(struct_ty.hasRuntimeBitsIgnoreComptime()), .False); | 9641 | const llvm_index = llvm_u32.constInt(@boolToInt(struct_ty.hasRuntimeBitsIgnoreComptime()), .False); |
| 9782 | const indices: [1]*llvm.Value = .{llvm_index}; | 9642 | const indices: [1]*llvm.Value = .{llvm_index}; |
| 9783 | return self.builder.buildInBoundsGEP(struct_llvm_ty, struct_ptr, &indices, indices.len, ""); | 9643 | return self.builder.buildInBoundsGEP(struct_llvm_ty, struct_ptr, &indices, indices.len, ""); |
| 9784 | } | 9644 | } |
| 9785 | }, | 9645 | }, |
| 9786 | }, | 9646 | }, |
| 9787 | .Union => return self.unionFieldPtr(inst, struct_ptr, struct_ty), | 9647 | .Union => { |
| | 9648 | const layout = struct_ty.unionGetLayout(target); |
| | 9649 | if (layout.payload_size == 0 or struct_ty.containerLayout() == .Packed) return struct_ptr; |
| | 9650 | const payload_index = @boolToInt(layout.tag_align >= layout.payload_align); |
| | 9651 | const union_llvm_ty = try self.dg.lowerType(struct_ty); |
| | 9652 | const union_field_ptr = self.builder.buildStructGEP(union_llvm_ty, struct_ptr, payload_index, ""); |
| | 9653 | return union_field_ptr; |
| | 9654 | }, |
| 9788 | else => unreachable, | 9655 | else => unreachable, |
| 9789 | } | 9656 | } |
| 9790 | } | 9657 | } |
| 9791 | | 9658 | |
| 9792 | fn unionFieldPtr( | | |
| 9793 | self: *FuncGen, | | |
| 9794 | inst: Air.Inst.Index, | | |
| 9795 | union_ptr: *llvm.Value, | | |
| 9796 | union_ty: Type, | | |
| 9797 | ) !?*llvm.Value { | | |
| 9798 | const target = self.dg.module.getTarget(); | | |
| 9799 | const layout = union_ty.unionGetLayout(target); | | |
| 9800 | const result_llvm_ty = try self.dg.lowerType(self.air.typeOfIndex(inst)); | | |
| 9801 | if (layout.payload_size == 0) { | | |
| 9802 | return self.builder.buildBitCast(union_ptr, result_llvm_ty, ""); | | |
| 9803 | } | | |
| 9804 | if (union_ty.containerLayout() == .Packed) { | | |
| 9805 | return self.builder.buildBitCast(union_ptr, result_llvm_ty, ""); | | |
| 9806 | } | | |
| 9807 | const payload_index = @boolToInt(layout.tag_align >= layout.payload_align); | | |
| 9808 | const union_llvm_ty = try self.dg.lowerType(union_ty); | | |
| 9809 | const union_field_ptr = self.builder.buildStructGEP(union_llvm_ty, union_ptr, payload_index, ""); | | |
| 9810 | return self.builder.buildBitCast(union_field_ptr, result_llvm_ty, ""); | | |
| 9811 | } | | |
| 9812 | | | |
| 9813 | fn getIntrinsic(self: *FuncGen, name: []const u8, types: []const *llvm.Type) *llvm.Value { | 9659 | fn getIntrinsic(self: *FuncGen, name: []const u8, types: []const *llvm.Type) *llvm.Value { |
| 9814 | const id = llvm.lookupIntrinsicID(name.ptr, name.len); | 9660 | const id = llvm.lookupIntrinsicID(name.ptr, name.len); |
| 9815 | assert(id != 0); | 9661 | assert(id != 0); |
| ... | @@ -9828,13 +9674,12 @@ pub const FuncGen = struct { | ... | @@ -9828,13 +9674,12 @@ pub const FuncGen = struct { |
| 9828 | const target = fg.dg.module.getTarget(); | 9674 | const target = fg.dg.module.getTarget(); |
| 9829 | const result_align = @max(ptr_alignment, pointee_type.abiAlignment(target)); | 9675 | const result_align = @max(ptr_alignment, pointee_type.abiAlignment(target)); |
| 9830 | const result_ptr = fg.buildAlloca(pointee_llvm_ty, result_align); | 9676 | const result_ptr = fg.buildAlloca(pointee_llvm_ty, result_align); |
| 9831 | const llvm_ptr_u8 = fg.context.intType(8).pointerType(0); | | |
| 9832 | const llvm_usize = fg.context.intType(Type.usize.intInfo(target).bits); | 9677 | const llvm_usize = fg.context.intType(Type.usize.intInfo(target).bits); |
| 9833 | const size_bytes = pointee_type.abiSize(target); | 9678 | const size_bytes = pointee_type.abiSize(target); |
| 9834 | _ = fg.builder.buildMemCpy( | 9679 | _ = fg.builder.buildMemCpy( |
| 9835 | fg.builder.buildBitCast(result_ptr, llvm_ptr_u8, ""), | 9680 | result_ptr, |
| 9836 | result_align, | 9681 | result_align, |
| 9837 | fg.builder.buildBitCast(ptr, llvm_ptr_u8, ""), | 9682 | ptr, |
| 9838 | ptr_alignment, | 9683 | ptr_alignment, |
| 9839 | llvm_usize.constInt(size_bytes, .False), | 9684 | llvm_usize.constInt(size_bytes, .False), |
| 9840 | is_volatile, | 9685 | is_volatile, |
| ... | @@ -9855,7 +9700,7 @@ pub const FuncGen = struct { | ... | @@ -9855,7 +9700,7 @@ pub const FuncGen = struct { |
| 9855 | | 9700 | |
| 9856 | assert(info.vector_index != .runtime); | 9701 | assert(info.vector_index != .runtime); |
| 9857 | if (info.vector_index != .none) { | 9702 | if (info.vector_index != .none) { |
| 9858 | const index_u32 = self.dg.context.intType(32).constInt(@enumToInt(info.vector_index), .False); | 9703 | const index_u32 = self.context.intType(32).constInt(@enumToInt(info.vector_index), .False); |
| 9859 | const vec_elem_ty = try self.dg.lowerType(info.pointee_type); | 9704 | const vec_elem_ty = try self.dg.lowerType(info.pointee_type); |
| 9860 | const vec_ty = vec_elem_ty.vectorType(info.host_size); | 9705 | const vec_ty = vec_elem_ty.vectorType(info.host_size); |
| 9861 | | 9706 | |
| ... | @@ -9878,8 +9723,7 @@ pub const FuncGen = struct { | ... | @@ -9878,8 +9723,7 @@ pub const FuncGen = struct { |
| 9878 | } | 9723 | } |
| 9879 | | 9724 | |
| 9880 | const int_elem_ty = self.context.intType(info.host_size * 8); | 9725 | const int_elem_ty = self.context.intType(info.host_size * 8); |
| 9881 | const int_ptr = self.builder.buildBitCast(ptr, int_elem_ty.pointerType(0), ""); | 9726 | const containing_int = self.builder.buildLoad(int_elem_ty, ptr, ""); |
| 9882 | const containing_int = self.builder.buildLoad(int_elem_ty, int_ptr, ""); | | |
| 9883 | containing_int.setAlignment(ptr_alignment); | 9727 | containing_int.setAlignment(ptr_alignment); |
| 9884 | containing_int.setVolatile(ptr_volatile); | 9728 | containing_int.setVolatile(ptr_volatile); |
| 9885 | | 9729 | |
| ... | @@ -9894,8 +9738,7 @@ pub const FuncGen = struct { | ... | @@ -9894,8 +9738,7 @@ pub const FuncGen = struct { |
| 9894 | | 9738 | |
| 9895 | const same_size_int = self.context.intType(elem_bits); | 9739 | const same_size_int = self.context.intType(elem_bits); |
| 9896 | const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, ""); | 9740 | const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, ""); |
| 9897 | const bitcasted_ptr = self.builder.buildBitCast(result_ptr, same_size_int.pointerType(0), ""); | 9741 | const store_inst = self.builder.buildStore(truncated_int, result_ptr); |
| 9898 | const store_inst = self.builder.buildStore(truncated_int, bitcasted_ptr); | | |
| 9899 | store_inst.setAlignment(result_align); | 9742 | store_inst.setAlignment(result_align); |
| 9900 | return result_ptr; | 9743 | return result_ptr; |
| 9901 | } | 9744 | } |
| ... | @@ -9933,7 +9776,7 @@ pub const FuncGen = struct { | ... | @@ -9933,7 +9776,7 @@ pub const FuncGen = struct { |
| 9933 | | 9776 | |
| 9934 | assert(info.vector_index != .runtime); | 9777 | assert(info.vector_index != .runtime); |
| 9935 | if (info.vector_index != .none) { | 9778 | if (info.vector_index != .none) { |
| 9936 | const index_u32 = self.dg.context.intType(32).constInt(@enumToInt(info.vector_index), .False); | 9779 | const index_u32 = self.context.intType(32).constInt(@enumToInt(info.vector_index), .False); |
| 9937 | const vec_elem_ty = try self.dg.lowerType(elem_ty); | 9780 | const vec_elem_ty = try self.dg.lowerType(elem_ty); |
| 9938 | const vec_ty = vec_elem_ty.vectorType(info.host_size); | 9781 | const vec_ty = vec_elem_ty.vectorType(info.host_size); |
| 9939 | | 9782 | |
| ... | @@ -9952,8 +9795,7 @@ pub const FuncGen = struct { | ... | @@ -9952,8 +9795,7 @@ pub const FuncGen = struct { |
| 9952 | | 9795 | |
| 9953 | if (info.host_size != 0) { | 9796 | if (info.host_size != 0) { |
| 9954 | const int_elem_ty = self.context.intType(info.host_size * 8); | 9797 | const int_elem_ty = self.context.intType(info.host_size * 8); |
| 9955 | const int_ptr = self.builder.buildBitCast(ptr, int_elem_ty.pointerType(0), ""); | 9798 | const containing_int = self.builder.buildLoad(int_elem_ty, ptr, ""); |
| 9956 | const containing_int = self.builder.buildLoad(int_elem_ty, int_ptr, ""); | | |
| 9957 | assert(ordering == .NotAtomic); | 9799 | assert(ordering == .NotAtomic); |
| 9958 | containing_int.setAlignment(ptr_alignment); | 9800 | containing_int.setAlignment(ptr_alignment); |
| 9959 | containing_int.setVolatile(ptr_volatile); | 9801 | containing_int.setVolatile(ptr_volatile); |
| ... | @@ -9978,7 +9820,7 @@ pub const FuncGen = struct { | ... | @@ -9978,7 +9820,7 @@ pub const FuncGen = struct { |
| 9978 | const shifted_value = self.builder.buildShl(extended_value, shift_amt, ""); | 9820 | const shifted_value = self.builder.buildShl(extended_value, shift_amt, ""); |
| 9979 | const ored_value = self.builder.buildOr(shifted_value, anded_containing_int, ""); | 9821 | const ored_value = self.builder.buildOr(shifted_value, anded_containing_int, ""); |
| 9980 | | 9822 | |
| 9981 | const store_inst = self.builder.buildStore(ored_value, int_ptr); | 9823 | const store_inst = self.builder.buildStore(ored_value, ptr); |
| 9982 | assert(ordering == .NotAtomic); | 9824 | assert(ordering == .NotAtomic); |
| 9983 | store_inst.setAlignment(ptr_alignment); | 9825 | store_inst.setAlignment(ptr_alignment); |
| 9984 | store_inst.setVolatile(ptr_volatile); | 9826 | store_inst.setVolatile(ptr_volatile); |
| ... | @@ -9992,12 +9834,11 @@ pub const FuncGen = struct { | ... | @@ -9992,12 +9834,11 @@ pub const FuncGen = struct { |
| 9992 | return; | 9834 | return; |
| 9993 | } | 9835 | } |
| 9994 | assert(ordering == .NotAtomic); | 9836 | assert(ordering == .NotAtomic); |
| 9995 | const llvm_ptr_u8 = self.context.intType(8).pointerType(0); | | |
| 9996 | const size_bytes = elem_ty.abiSize(target); | 9837 | const size_bytes = elem_ty.abiSize(target); |
| 9997 | _ = self.builder.buildMemCpy( | 9838 | _ = self.builder.buildMemCpy( |
| 9998 | self.builder.buildBitCast(ptr, llvm_ptr_u8, ""), | 9839 | ptr, |
| 9999 | ptr_alignment, | 9840 | ptr_alignment, |
| 10000 | self.builder.buildBitCast(elem, llvm_ptr_u8, ""), | 9841 | elem, |
| 10001 | elem_ty.abiAlignment(target), | 9842 | elem_ty.abiAlignment(target), |
| 10002 | self.context.intType(Type.usize.intInfo(target).bits).constInt(size_bytes, .False), | 9843 | self.context.intType(Type.usize.intInfo(target).bits).constInt(size_bytes, .False), |
| 10003 | info.@"volatile", | 9844 | info.@"volatile", |
| ... | @@ -11187,6 +11028,7 @@ fn compilerRtIntBits(bits: u16) u16 { | ... | @@ -11187,6 +11028,7 @@ fn compilerRtIntBits(bits: u16) u16 { |
| 11187 | } | 11028 | } |
| 11188 | | 11029 | |
| 11189 | fn buildAllocaInner( | 11030 | fn buildAllocaInner( |
| | 11031 | context: *llvm.Context, |
| 11190 | builder: *llvm.Builder, | 11032 | builder: *llvm.Builder, |
| 11191 | llvm_func: *llvm.Value, | 11033 | llvm_func: *llvm.Value, |
| 11192 | di_scope_non_null: bool, | 11034 | di_scope_non_null: bool, |
| ... | @@ -11224,7 +11066,7 @@ fn buildAllocaInner( | ... | @@ -11224,7 +11066,7 @@ fn buildAllocaInner( |
| 11224 | // The pointer returned from this function should have the generic address space, | 11066 | // The pointer returned from this function should have the generic address space, |
| 11225 | // if this isn't the case then cast it to the generic address space. | 11067 | // if this isn't the case then cast it to the generic address space. |
| 11226 | if (address_space != llvm.address_space.default) { | 11068 | if (address_space != llvm.address_space.default) { |
| 11227 | return builder.buildAddrSpaceCast(alloca, llvm_ty.pointerType(llvm.address_space.default), ""); | 11069 | return builder.buildAddrSpaceCast(alloca, context.pointerType(llvm.address_space.default), ""); |
| 11228 | } | 11070 | } |
| 11229 | | 11071 | |
| 11230 | return alloca; | 11072 | return alloca; |