| ... | @@ -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); |
| ... | @@ -2477,12 +2467,8 @@ pub const DeclGen = struct { | ... | @@ -2477,12 +2467,8 @@ pub const DeclGen = struct { |
| 2477 | new_global.setAlignment(global.getAlignment()); | 2467 | new_global.setAlignment(global.getAlignment()); |
| 2478 | if (decl.@"linksection") |section| new_global.setSection(section); | 2468 | if (decl.@"linksection") |section| new_global.setSection(section); |
| 2479 | new_global.setInitializer(llvm_init); | 2469 | 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? | 2470 | // TODO: How should this work then the address space of a global changed? |
| 2484 | const new_global_ptr = new_global.constBitCast(global.typeOf()); | 2471 | global.replaceAllUsesWith(new_global); |
| 2485 | global.replaceAllUsesWith(new_global_ptr); | | |
| 2486 | dg.object.decl_map.putAssumeCapacity(decl_index, new_global); | 2472 | dg.object.decl_map.putAssumeCapacity(decl_index, new_global); |
| 2487 | new_global.takeName(global); | 2473 | new_global.takeName(global); |
| 2488 | global.deleteGlobal(); | 2474 | global.deleteGlobal(); |
| ... | @@ -2781,11 +2767,7 @@ pub const DeclGen = struct { | ... | @@ -2781,11 +2767,7 @@ pub const DeclGen = struct { |
| 2781 | } | 2767 | } |
| 2782 | const ptr_info = t.ptrInfo().data; | 2768 | const ptr_info = t.ptrInfo().data; |
| 2783 | const llvm_addrspace = toLlvmAddressSpace(ptr_info.@"addrspace", target); | 2769 | const llvm_addrspace = toLlvmAddressSpace(ptr_info.@"addrspace", target); |
| 2784 | if (ptr_info.host_size != 0) { | 2770 | 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 | }, | 2771 | }, |
| 2790 | .Opaque => switch (t.tag()) { | 2772 | .Opaque => switch (t.tag()) { |
| 2791 | .@"opaque" => { | 2773 | .@"opaque" => { |
| ... | @@ -3108,8 +3090,7 @@ pub const DeclGen = struct { | ... | @@ -3108,8 +3090,7 @@ pub const DeclGen = struct { |
| 3108 | defer llvm_params.deinit(); | 3090 | defer llvm_params.deinit(); |
| 3109 | | 3091 | |
| 3110 | if (firstParamSRet(fn_info, target)) { | 3092 | if (firstParamSRet(fn_info, target)) { |
| 3111 | const llvm_sret_ty = try dg.lowerType(fn_info.return_type); | 3093 | try llvm_params.append(dg.context.pointerType(0)); |
| 3112 | try llvm_params.append(llvm_sret_ty.pointerType(0)); | | |
| 3113 | } | 3094 | } |
| 3114 | | 3095 | |
| 3115 | if (fn_info.return_type.isError() and | 3096 | if (fn_info.return_type.isError() and |
| ... | @@ -3131,9 +3112,7 @@ pub const DeclGen = struct { | ... | @@ -3131,9 +3112,7 @@ pub const DeclGen = struct { |
| 3131 | try llvm_params.append(try dg.lowerType(param_ty)); | 3112 | try llvm_params.append(try dg.lowerType(param_ty)); |
| 3132 | }, | 3113 | }, |
| 3133 | .byref, .byref_mut => { | 3114 | .byref, .byref_mut => { |
| 3134 | const param_ty = fn_info.param_types[it.zig_index - 1]; | 3115 | 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 | }, | 3116 | }, |
| 3138 | .abi_sized_int => { | 3117 | .abi_sized_int => { |
| 3139 | const param_ty = fn_info.param_types[it.zig_index - 1]; | 3118 | const param_ty = fn_info.param_types[it.zig_index - 1]; |
| ... | @@ -3323,16 +3302,12 @@ pub const DeclGen = struct { | ... | @@ -3323,16 +3302,12 @@ pub const DeclGen = struct { |
| 3323 | const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target); | 3302 | const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target); |
| 3324 | const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target); | 3303 | const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target); |
| 3325 | | 3304 | |
| 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); | 3305 | const val = try dg.resolveGlobalDecl(decl_index); |
| 3330 | const val_ptr = val.constBitCast(llvm_actual_ptr_type); | 3306 | const addrspace_casted_ptr = if (llvm_actual_addrspace != llvm_wanted_addrspace) |
| 3331 | if (llvm_actual_addrspace != llvm_wanted_addrspace) { | 3307 | val.constAddrSpaceCast(dg.context.pointerType(llvm_wanted_addrspace)) |
| 3332 | const llvm_wanted_ptr_type = llvm_var_type.pointerType(llvm_wanted_addrspace); | 3308 | else |
| 3333 | return val_ptr.constAddrSpaceCast(llvm_wanted_ptr_type); | 3309 | val; |
| 3334 | } | 3310 | return addrspace_casted_ptr; |
| 3335 | return val_ptr; | | |
| 3336 | }, | 3311 | }, |
| 3337 | .slice => { | 3312 | .slice => { |
| 3338 | const slice = tv.val.castTag(.slice).?.data; | 3313 | const slice = tv.val.castTag(.slice).?.data; |
| ... | @@ -3355,7 +3330,7 @@ pub const DeclGen = struct { | ... | @@ -3355,7 +3330,7 @@ pub const DeclGen = struct { |
| 3355 | return llvm_int.constIntToPtr(try dg.lowerType(tv.ty)); | 3330 | return llvm_int.constIntToPtr(try dg.lowerType(tv.ty)); |
| 3356 | }, | 3331 | }, |
| 3357 | .field_ptr, .opt_payload_ptr, .eu_payload_ptr, .elem_ptr => { | 3332 | .field_ptr, .opt_payload_ptr, .eu_payload_ptr, .elem_ptr => { |
| 3358 | return dg.lowerParentPtr(tv.val, tv.ty.childType()); | 3333 | return dg.lowerParentPtr(tv.val); |
| 3359 | }, | 3334 | }, |
| 3360 | .null_value, .zero => { | 3335 | .null_value, .zero => { |
| 3361 | const llvm_type = try dg.lowerType(tv.ty); | 3336 | const llvm_type = try dg.lowerType(tv.ty); |
| ... | @@ -3363,7 +3338,7 @@ pub const DeclGen = struct { | ... | @@ -3363,7 +3338,7 @@ pub const DeclGen = struct { |
| 3363 | }, | 3338 | }, |
| 3364 | .opt_payload => { | 3339 | .opt_payload => { |
| 3365 | const payload = tv.val.castTag(.opt_payload).?.data; | 3340 | const payload = tv.val.castTag(.opt_payload).?.data; |
| 3366 | return dg.lowerParentPtr(payload, tv.ty); | 3341 | return dg.lowerParentPtr(payload); |
| 3367 | }, | 3342 | }, |
| 3368 | else => |tag| return dg.todo("implement const of pointer type '{}' ({})", .{ | 3343 | else => |tag| return dg.todo("implement const of pointer type '{}' ({})", .{ |
| 3369 | tv.ty.fmtDebug(), tag, | 3344 | tv.ty.fmtDebug(), tag, |
| ... | @@ -3940,7 +3915,6 @@ pub const DeclGen = struct { | ... | @@ -3940,7 +3915,6 @@ pub const DeclGen = struct { |
| 3940 | dg: *DeclGen, | 3915 | dg: *DeclGen, |
| 3941 | ptr_val: Value, | 3916 | ptr_val: Value, |
| 3942 | decl_index: Module.Decl.Index, | 3917 | decl_index: Module.Decl.Index, |
| 3943 | ptr_child_ty: Type, | | |
| 3944 | ) Error!*llvm.Value { | 3918 | ) Error!*llvm.Value { |
| 3945 | const decl = dg.module.declPtr(decl_index); | 3919 | const decl = dg.module.declPtr(decl_index); |
| 3946 | dg.module.markDeclAlive(decl); | 3920 | dg.module.markDeclAlive(decl); |
| ... | @@ -3949,62 +3923,54 @@ pub const DeclGen = struct { | ... | @@ -3949,62 +3923,54 @@ pub const DeclGen = struct { |
| 3949 | .data = decl.ty, | 3923 | .data = decl.ty, |
| 3950 | }; | 3924 | }; |
| 3951 | const ptr_ty = Type.initPayload(&ptr_ty_payload.base); | 3925 | const ptr_ty = Type.initPayload(&ptr_ty_payload.base); |
| 3952 | const llvm_ptr = try dg.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl_index); | 3926 | 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 | } | 3927 | } |
| 3960 | | 3928 | |
| 3961 | fn lowerParentPtr(dg: *DeclGen, ptr_val: Value, ptr_child_ty: Type) Error!*llvm.Value { | 3929 | fn lowerParentPtr(dg: *DeclGen, ptr_val: Value) Error!*llvm.Value { |
| 3962 | const target = dg.module.getTarget(); | 3930 | const target = dg.module.getTarget(); |
| 3963 | var bitcast_needed: bool = undefined; | 3931 | switch (ptr_val.tag()) { |
| 3964 | const llvm_ptr = switch (ptr_val.tag()) { | | |
| 3965 | .decl_ref_mut => { | 3932 | .decl_ref_mut => { |
| 3966 | const decl = ptr_val.castTag(.decl_ref_mut).?.data.decl_index; | 3933 | const decl = ptr_val.castTag(.decl_ref_mut).?.data.decl_index; |
| 3967 | return dg.lowerParentPtrDecl(ptr_val, decl, ptr_child_ty); | 3934 | return dg.lowerParentPtrDecl(ptr_val, decl); |
| 3968 | }, | 3935 | }, |
| 3969 | .decl_ref => { | 3936 | .decl_ref => { |
| 3970 | const decl = ptr_val.castTag(.decl_ref).?.data; | 3937 | const decl = ptr_val.castTag(.decl_ref).?.data; |
| 3971 | return dg.lowerParentPtrDecl(ptr_val, decl, ptr_child_ty); | 3938 | return dg.lowerParentPtrDecl(ptr_val, decl); |
| 3972 | }, | 3939 | }, |
| 3973 | .variable => { | 3940 | .variable => { |
| 3974 | const decl = ptr_val.castTag(.variable).?.data.owner_decl; | 3941 | const decl = ptr_val.castTag(.variable).?.data.owner_decl; |
| 3975 | return dg.lowerParentPtrDecl(ptr_val, decl, ptr_child_ty); | 3942 | return dg.lowerParentPtrDecl(ptr_val, decl); |
| 3976 | }, | 3943 | }, |
| 3977 | .int_i64 => { | 3944 | .int_i64 => { |
| 3978 | const int = ptr_val.castTag(.int_i64).?.data; | 3945 | const int = ptr_val.castTag(.int_i64).?.data; |
| 3979 | const llvm_usize = try dg.lowerType(Type.usize); | 3946 | const llvm_usize = try dg.lowerType(Type.usize); |
| 3980 | const llvm_int = llvm_usize.constInt(@bitCast(u64, int), .False); | 3947 | const llvm_int = llvm_usize.constInt(@bitCast(u64, int), .False); |
| 3981 | return llvm_int.constIntToPtr((try dg.lowerType(ptr_child_ty)).pointerType(0)); | 3948 | return llvm_int.constIntToPtr(dg.context.pointerType(0)); |
| 3982 | }, | 3949 | }, |
| 3983 | .int_u64 => { | 3950 | .int_u64 => { |
| 3984 | const int = ptr_val.castTag(.int_u64).?.data; | 3951 | const int = ptr_val.castTag(.int_u64).?.data; |
| 3985 | const llvm_usize = try dg.lowerType(Type.usize); | 3952 | const llvm_usize = try dg.lowerType(Type.usize); |
| 3986 | const llvm_int = llvm_usize.constInt(int, .False); | 3953 | const llvm_int = llvm_usize.constInt(int, .False); |
| 3987 | return llvm_int.constIntToPtr((try dg.lowerType(ptr_child_ty)).pointerType(0)); | 3954 | return llvm_int.constIntToPtr(dg.context.pointerType(0)); |
| 3988 | }, | 3955 | }, |
| 3989 | .field_ptr => blk: { | 3956 | .field_ptr => { |
| 3990 | const field_ptr = ptr_val.castTag(.field_ptr).?.data; | 3957 | 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); | 3958 | const parent_llvm_ptr = try dg.lowerParentPtr(field_ptr.container_ptr); |
| 3992 | const parent_ty = field_ptr.container_ty; | 3959 | const parent_ty = field_ptr.container_ty; |
| 3993 | | 3960 | |
| 3994 | const field_index = @intCast(u32, field_ptr.field_index); | 3961 | const field_index = @intCast(u32, field_ptr.field_index); |
| 3995 | const llvm_u32 = dg.context.intType(32); | 3962 | const llvm_u32 = dg.context.intType(32); |
| 3996 | switch (parent_ty.zigTypeTag()) { | 3963 | switch (parent_ty.zigTypeTag()) { |
| 3997 | .Union => { | 3964 | .Union => { |
| 3998 | bitcast_needed = true; | | |
| 3999 | if (parent_ty.containerLayout() == .Packed) { | 3965 | if (parent_ty.containerLayout() == .Packed) { |
| 4000 | break :blk parent_llvm_ptr; | 3966 | return parent_llvm_ptr; |
| 4001 | } | 3967 | } |
| 4002 | | 3968 | |
| 4003 | const layout = parent_ty.unionGetLayout(target); | 3969 | const layout = parent_ty.unionGetLayout(target); |
| 4004 | if (layout.payload_size == 0) { | 3970 | if (layout.payload_size == 0) { |
| 4005 | // In this case a pointer to the union and a pointer to any | 3971 | // In this case a pointer to the union and a pointer to any |
| 4006 | // (void) payload is the same. | 3972 | // (void) payload is the same. |
| 4007 | break :blk parent_llvm_ptr; | 3973 | return parent_llvm_ptr; |
| 4008 | } | 3974 | } |
| 4009 | const llvm_pl_index = if (layout.tag_size == 0) | 3975 | const llvm_pl_index = if (layout.tag_size == 0) |
| 4010 | 0 | 3976 | 0 |
| ... | @@ -4015,10 +3981,9 @@ pub const DeclGen = struct { | ... | @@ -4015,10 +3981,9 @@ pub const DeclGen = struct { |
| 4015 | llvm_u32.constInt(llvm_pl_index, .False), | 3981 | llvm_u32.constInt(llvm_pl_index, .False), |
| 4016 | }; | 3982 | }; |
| 4017 | const parent_llvm_ty = try dg.lowerType(parent_ty); | 3983 | const parent_llvm_ty = try dg.lowerType(parent_ty); |
| 4018 | break :blk parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); | 3984 | return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 4019 | }, | 3985 | }, |
| 4020 | .Struct => { | 3986 | .Struct => { |
| 4021 | const field_ty = parent_ty.structFieldType(field_index); | | |
| 4022 | if (parent_ty.containerLayout() == .Packed) { | 3987 | if (parent_ty.containerLayout() == .Packed) { |
| 4023 | const llvm_usize = dg.context.intType(target.cpu.arch.ptrBitWidth()); | 3988 | const llvm_usize = dg.context.intType(target.cpu.arch.ptrBitWidth()); |
| 4024 | const base_addr = parent_llvm_ptr.constPtrToInt(llvm_usize); | 3989 | const base_addr = parent_llvm_ptr.constPtrToInt(llvm_usize); |
| ... | @@ -4033,26 +3998,23 @@ pub const DeclGen = struct { | ... | @@ -4033,26 +3998,23 @@ pub const DeclGen = struct { |
| 4033 | }; | 3998 | }; |
| 4034 | const byte_offset = llvm_usize.constInt(prev_bits / 8, .False); | 3999 | const byte_offset = llvm_usize.constInt(prev_bits / 8, .False); |
| 4035 | const field_addr = base_addr.constAdd(byte_offset); | 4000 | const field_addr = base_addr.constAdd(byte_offset); |
| 4036 | bitcast_needed = false; | 4001 | const final_llvm_ty = dg.context.pointerType(0); |
| 4037 | const final_llvm_ty = (try dg.lowerType(ptr_child_ty)).pointerType(0); | 4002 | return field_addr.constIntToPtr(final_llvm_ty); |
| 4038 | break :blk field_addr.constIntToPtr(final_llvm_ty); | | |
| 4039 | } | 4003 | } |
| 4040 | | 4004 | |
| 4041 | var ty_buf: Type.Payload.Pointer = undefined; | 4005 | var ty_buf: Type.Payload.Pointer = undefined; |
| 4042 | | 4006 | |
| 4043 | const parent_llvm_ty = try dg.lowerType(parent_ty); | 4007 | const parent_llvm_ty = try dg.lowerType(parent_ty); |
| 4044 | if (llvmFieldIndex(parent_ty, field_index, target, &ty_buf)) |llvm_field_index| { | 4008 | 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 = .{ | 4009 | const indices: [2]*llvm.Value = .{ |
| 4047 | llvm_u32.constInt(0, .False), | 4010 | llvm_u32.constInt(0, .False), |
| 4048 | llvm_u32.constInt(llvm_field_index, .False), | 4011 | llvm_u32.constInt(llvm_field_index, .False), |
| 4049 | }; | 4012 | }; |
| 4050 | break :blk parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); | 4013 | return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 4051 | } else { | 4014 | } else { |
| 4052 | bitcast_needed = !parent_ty.eql(ptr_child_ty, dg.module); | | |
| 4053 | const llvm_index = llvm_u32.constInt(@boolToInt(parent_ty.hasRuntimeBitsIgnoreComptime()), .False); | 4015 | const llvm_index = llvm_u32.constInt(@boolToInt(parent_ty.hasRuntimeBitsIgnoreComptime()), .False); |
| 4054 | const indices: [1]*llvm.Value = .{llvm_index}; | 4016 | const indices: [1]*llvm.Value = .{llvm_index}; |
| 4055 | break :blk parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); | 4017 | return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 4056 | } | 4018 | } |
| 4057 | }, | 4019 | }, |
| 4058 | .Pointer => { | 4020 | .Pointer => { |
| ... | @@ -4062,37 +4024,34 @@ pub const DeclGen = struct { | ... | @@ -4062,37 +4024,34 @@ pub const DeclGen = struct { |
| 4062 | llvm_u32.constInt(field_index, .False), | 4024 | llvm_u32.constInt(field_index, .False), |
| 4063 | }; | 4025 | }; |
| 4064 | const parent_llvm_ty = try dg.lowerType(parent_ty); | 4026 | const parent_llvm_ty = try dg.lowerType(parent_ty); |
| 4065 | break :blk parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); | 4027 | return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 4066 | }, | 4028 | }, |
| 4067 | else => unreachable, | 4029 | else => unreachable, |
| 4068 | } | 4030 | } |
| 4069 | }, | 4031 | }, |
| 4070 | .elem_ptr => blk: { | 4032 | .elem_ptr => { |
| 4071 | const elem_ptr = ptr_val.castTag(.elem_ptr).?.data; | 4033 | 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); | 4034 | 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 | | 4035 | |
| 4075 | const llvm_usize = try dg.lowerType(Type.usize); | 4036 | const llvm_usize = try dg.lowerType(Type.usize); |
| 4076 | const indices: [1]*llvm.Value = .{ | 4037 | const indices: [1]*llvm.Value = .{ |
| 4077 | llvm_usize.constInt(elem_ptr.index, .False), | 4038 | llvm_usize.constInt(elem_ptr.index, .False), |
| 4078 | }; | 4039 | }; |
| 4079 | const elem_llvm_ty = try dg.lowerType(elem_ptr.elem_ty); | 4040 | const elem_llvm_ty = try dg.lowerType(elem_ptr.elem_ty); |
| 4080 | break :blk elem_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); | 4041 | return elem_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 4081 | }, | 4042 | }, |
| 4082 | .opt_payload_ptr => blk: { | 4043 | .opt_payload_ptr => { |
| 4083 | const opt_payload_ptr = ptr_val.castTag(.opt_payload_ptr).?.data; | 4044 | 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); | 4045 | const parent_llvm_ptr = try dg.lowerParentPtr(opt_payload_ptr.container_ptr); |
| 4085 | var buf: Type.Payload.ElemType = undefined; | 4046 | var buf: Type.Payload.ElemType = undefined; |
| 4086 | | 4047 | |
| 4087 | const payload_ty = opt_payload_ptr.container_ty.optionalChild(&buf); | 4048 | 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 | 4049 | if (!payload_ty.hasRuntimeBitsIgnoreComptime() or |
| 4091 | payload_ty.optionalReprIsPayload()) | 4050 | payload_ty.optionalReprIsPayload()) |
| 4092 | { | 4051 | { |
| 4093 | // In this case, we represent pointer to optional the same as pointer | 4052 | // In this case, we represent pointer to optional the same as pointer |
| 4094 | // to the payload. | 4053 | // to the payload. |
| 4095 | break :blk parent_llvm_ptr; | 4054 | return parent_llvm_ptr; |
| 4096 | } | 4055 | } |
| 4097 | | 4056 | |
| 4098 | const llvm_u32 = dg.context.intType(32); | 4057 | const llvm_u32 = dg.context.intType(32); |
| ... | @@ -4101,19 +4060,17 @@ pub const DeclGen = struct { | ... | @@ -4101,19 +4060,17 @@ pub const DeclGen = struct { |
| 4101 | llvm_u32.constInt(0, .False), | 4060 | llvm_u32.constInt(0, .False), |
| 4102 | }; | 4061 | }; |
| 4103 | const opt_llvm_ty = try dg.lowerType(opt_payload_ptr.container_ty); | 4062 | 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); | 4063 | return opt_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 4105 | }, | 4064 | }, |
| 4106 | .eu_payload_ptr => blk: { | 4065 | .eu_payload_ptr => { |
| 4107 | const eu_payload_ptr = ptr_val.castTag(.eu_payload_ptr).?.data; | 4066 | 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); | 4067 | const parent_llvm_ptr = try dg.lowerParentPtr(eu_payload_ptr.container_ptr); |
| 4109 | | 4068 | |
| 4110 | const payload_ty = eu_payload_ptr.container_ty.errorUnionPayload(); | 4069 | 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()) { | 4070 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 4114 | // In this case, we represent pointer to error union the same as pointer | 4071 | // In this case, we represent pointer to error union the same as pointer |
| 4115 | // to the payload. | 4072 | // to the payload. |
| 4116 | break :blk parent_llvm_ptr; | 4073 | return parent_llvm_ptr; |
| 4117 | } | 4074 | } |
| 4118 | | 4075 | |
| 4119 | const payload_offset: u8 = if (payload_ty.abiAlignment(target) > Type.anyerror.abiSize(target)) 2 else 1; | 4076 | const payload_offset: u8 = if (payload_ty.abiAlignment(target) > Type.anyerror.abiSize(target)) 2 else 1; |
| ... | @@ -4123,14 +4080,9 @@ pub const DeclGen = struct { | ... | @@ -4123,14 +4080,9 @@ pub const DeclGen = struct { |
| 4123 | llvm_u32.constInt(payload_offset, .False), | 4080 | llvm_u32.constInt(payload_offset, .False), |
| 4124 | }; | 4081 | }; |
| 4125 | const eu_llvm_ty = try dg.lowerType(eu_payload_ptr.container_ty); | 4082 | 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); | 4083 | return eu_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 4127 | }, | 4084 | }, |
| 4128 | else => unreachable, | 4085 | 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 | } | 4086 | } |
| 4135 | } | 4087 | } |
| 4136 | | 4088 | |
| ... | @@ -4189,8 +4141,7 @@ pub const DeclGen = struct { | ... | @@ -4189,8 +4141,7 @@ pub const DeclGen = struct { |
| 4189 | const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target); | 4141 | const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target); |
| 4190 | const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target); | 4142 | const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target); |
| 4191 | const llvm_val = if (llvm_wanted_addrspace != llvm_actual_addrspace) blk: { | 4143 | const llvm_val = if (llvm_wanted_addrspace != llvm_actual_addrspace) blk: { |
| 4192 | const llvm_decl_ty = try self.lowerType(decl.ty); | 4144 | 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); | 4145 | break :blk llvm_decl_val.constAddrSpaceCast(llvm_decl_wanted_ptr_ty); |
| 4195 | } else llvm_decl_val; | 4146 | } else llvm_decl_val; |
| 4196 | | 4147 | |
| ... | @@ -4471,18 +4422,11 @@ pub const FuncGen = struct { | ... | @@ -4471,18 +4422,11 @@ pub const FuncGen = struct { |
| 4471 | global.setGlobalConstant(.True); | 4422 | global.setGlobalConstant(.True); |
| 4472 | global.setUnnamedAddr(.True); | 4423 | global.setUnnamedAddr(.True); |
| 4473 | global.setAlignment(tv.ty.abiAlignment(target)); | 4424 | global.setAlignment(tv.ty.abiAlignment(target)); |
| 4474 | // Because of LLVM limitations for lowering certain types such as unions, | 4425 | 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 | 4426 | 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 | 4427 | else |
| 4484 | bitcasted_ptr; | 4428 | global; |
| 4485 | return casted_ptr; | 4429 | return addrspace_casted_ptr; |
| 4486 | } | 4430 | } |
| 4487 | | 4431 | |
| 4488 | fn genBody(self: *FuncGen, body: []const Air.Inst.Index) Error!void { | 4432 | fn genBody(self: *FuncGen, body: []const Air.Inst.Index) Error!void { |
| ... | @@ -4770,17 +4714,7 @@ pub const FuncGen = struct { | ... | @@ -4770,17 +4714,7 @@ pub const FuncGen = struct { |
| 4770 | load_inst.setAlignment(alignment); | 4714 | load_inst.setAlignment(alignment); |
| 4771 | try llvm_args.append(load_inst); | 4715 | try llvm_args.append(load_inst); |
| 4772 | } else { | 4716 | } else { |
| 4773 | if (param_ty.zigTypeTag() == .Pointer) { | 4717 | 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 | } | 4718 | } |
| 4785 | }, | 4719 | }, |
| 4786 | .byref => { | 4720 | .byref => { |
| ... | @@ -4824,26 +4758,22 @@ pub const FuncGen = struct { | ... | @@ -4824,26 +4758,22 @@ pub const FuncGen = struct { |
| 4824 | const param_ty = self.air.typeOf(arg); | 4758 | const param_ty = self.air.typeOf(arg); |
| 4825 | const llvm_arg = try self.resolveInst(arg); | 4759 | const llvm_arg = try self.resolveInst(arg); |
| 4826 | const abi_size = @intCast(c_uint, param_ty.abiSize(target)); | 4760 | const abi_size = @intCast(c_uint, param_ty.abiSize(target)); |
| 4827 | const int_llvm_ty = self.dg.context.intType(abi_size * 8); | 4761 | const int_llvm_ty = self.context.intType(abi_size * 8); |
| 4828 | const int_ptr_llvm_ty = int_llvm_ty.pointerType(0); | | |
| 4829 | | 4762 | |
| 4830 | if (isByRef(param_ty)) { | 4763 | if (isByRef(param_ty)) { |
| 4831 | const alignment = param_ty.abiAlignment(target); | 4764 | const alignment = param_ty.abiAlignment(target); |
| 4832 | const casted_ptr = self.builder.buildBitCast(llvm_arg, int_ptr_llvm_ty, ""); | 4765 | 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); | 4766 | load_inst.setAlignment(alignment); |
| 4835 | try llvm_args.append(load_inst); | 4767 | try llvm_args.append(load_inst); |
| 4836 | } else { | 4768 | } else { |
| 4837 | // LLVM does not allow bitcasting structs so we must allocate | 4769 | // LLVM does not allow bitcasting structs so we must allocate |
| 4838 | // a local, bitcast its pointer, store, and then load. | 4770 | // a local, store as one type, and then load as another type. |
| 4839 | const alignment = @max( | 4771 | const alignment = @max( |
| 4840 | param_ty.abiAlignment(target), | 4772 | param_ty.abiAlignment(target), |
| 4841 | self.dg.object.target_data.abiAlignmentOfType(int_llvm_ty), | 4773 | self.dg.object.target_data.abiAlignmentOfType(int_llvm_ty), |
| 4842 | ); | 4774 | ); |
| 4843 | const int_ptr = self.buildAlloca(int_llvm_ty, alignment); | 4775 | const int_ptr = self.buildAlloca(int_llvm_ty, alignment); |
| 4844 | const param_llvm_ty = try self.dg.lowerType(param_ty); | 4776 | 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); | 4777 | store_inst.setAlignment(alignment); |
| 4848 | const load_inst = self.builder.buildLoad(int_llvm_ty, int_ptr, ""); | 4778 | const load_inst = self.builder.buildLoad(int_llvm_ty, int_ptr, ""); |
| 4849 | load_inst.setAlignment(alignment); | 4779 | load_inst.setAlignment(alignment); |
| ... | @@ -4872,12 +4802,11 @@ pub const FuncGen = struct { | ... | @@ -4872,12 +4802,11 @@ pub const FuncGen = struct { |
| 4872 | break :p p; | 4802 | break :p p; |
| 4873 | }; | 4803 | }; |
| 4874 | | 4804 | |
| 4875 | const llvm_ty = self.dg.context.structType(llvm_types.ptr, @intCast(c_uint, llvm_types.len), .False); | 4805 | 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); | 4806 | try llvm_args.ensureUnusedCapacity(it.llvm_types_len); |
| 4878 | for (llvm_types) |field_ty, i_usize| { | 4807 | for (llvm_types) |field_ty, i_usize| { |
| 4879 | const i = @intCast(c_uint, i_usize); | 4808 | const i = @intCast(c_uint, i_usize); |
| 4880 | const field_ptr = self.builder.buildStructGEP(llvm_ty, casted_ptr, i, ""); | 4809 | const field_ptr = self.builder.buildStructGEP(llvm_ty, arg_ptr, i, ""); |
| 4881 | const load_inst = self.builder.buildLoad(field_ty, field_ptr, ""); | 4810 | const load_inst = self.builder.buildLoad(field_ty, field_ptr, ""); |
| 4882 | load_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8); | 4811 | load_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8); |
| 4883 | llvm_args.appendAssumeCapacity(load_inst); | 4812 | llvm_args.appendAssumeCapacity(load_inst); |
| ... | @@ -4886,7 +4815,7 @@ pub const FuncGen = struct { | ... | @@ -4886,7 +4815,7 @@ pub const FuncGen = struct { |
| 4886 | .as_u16 => { | 4815 | .as_u16 => { |
| 4887 | const arg = args[it.zig_index - 1]; | 4816 | const arg = args[it.zig_index - 1]; |
| 4888 | const llvm_arg = try self.resolveInst(arg); | 4817 | const llvm_arg = try self.resolveInst(arg); |
| 4889 | const casted = self.builder.buildBitCast(llvm_arg, self.dg.context.intType(16), ""); | 4818 | const casted = self.builder.buildBitCast(llvm_arg, self.context.intType(16), ""); |
| 4890 | try llvm_args.append(casted); | 4819 | try llvm_args.append(casted); |
| 4891 | }, | 4820 | }, |
| 4892 | .float_array => |count| { | 4821 | .float_array => |count| { |
| ... | @@ -4903,9 +4832,8 @@ pub const FuncGen = struct { | ... | @@ -4903,9 +4832,8 @@ pub const FuncGen = struct { |
| 4903 | const float_ty = try self.dg.lowerType(aarch64_c_abi.getFloatArrayType(arg_ty).?); | 4832 | const float_ty = try self.dg.lowerType(aarch64_c_abi.getFloatArrayType(arg_ty).?); |
| 4904 | const array_llvm_ty = float_ty.arrayType(count); | 4833 | const array_llvm_ty = float_ty.arrayType(count); |
| 4905 | | 4834 | |
| 4906 | const casted = self.builder.buildBitCast(llvm_arg, array_llvm_ty.pointerType(0), ""); | | |
| 4907 | const alignment = arg_ty.abiAlignment(target); | 4835 | const alignment = arg_ty.abiAlignment(target); |
| 4908 | const load_inst = self.builder.buildLoad(array_llvm_ty, casted, ""); | 4836 | const load_inst = self.builder.buildLoad(array_llvm_ty, llvm_arg, ""); |
| 4909 | load_inst.setAlignment(alignment); | 4837 | load_inst.setAlignment(alignment); |
| 4910 | try llvm_args.append(load_inst); | 4838 | try llvm_args.append(load_inst); |
| 4911 | }, | 4839 | }, |
| ... | @@ -4921,10 +4849,9 @@ pub const FuncGen = struct { | ... | @@ -4921,10 +4849,9 @@ pub const FuncGen = struct { |
| 4921 | llvm_arg = store_inst; | 4849 | llvm_arg = store_inst; |
| 4922 | } | 4850 | } |
| 4923 | | 4851 | |
| 4924 | const array_llvm_ty = self.dg.context.intType(elem_size).arrayType(arr_len); | 4852 | 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); | 4853 | const alignment = arg_ty.abiAlignment(target); |
| 4927 | const load_inst = self.builder.buildLoad(array_llvm_ty, casted, ""); | 4854 | const load_inst = self.builder.buildLoad(array_llvm_ty, llvm_arg, ""); |
| 4928 | load_inst.setAlignment(alignment); | 4855 | load_inst.setAlignment(alignment); |
| 4929 | try llvm_args.append(load_inst); | 4856 | try llvm_args.append(load_inst); |
| 4930 | }, | 4857 | }, |
| ... | @@ -5028,12 +4955,10 @@ pub const FuncGen = struct { | ... | @@ -5028,12 +4955,10 @@ pub const FuncGen = struct { |
| 5028 | if (abi_ret_ty != llvm_ret_ty) { | 4955 | if (abi_ret_ty != llvm_ret_ty) { |
| 5029 | // In this case the function return type is honoring the calling convention by having | 4956 | // 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 | 4957 | // 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. | 4958 | // by using our canonical type, then loading it if necessary. |
| 5032 | const alignment = self.dg.object.target_data.abiAlignmentOfType(abi_ret_ty); | 4959 | const alignment = self.dg.object.target_data.abiAlignmentOfType(abi_ret_ty); |
| 5033 | const rp = self.buildAlloca(llvm_ret_ty, alignment); | 4960 | const rp = self.buildAlloca(llvm_ret_ty, alignment); |
| 5034 | const ptr_abi_ty = abi_ret_ty.pointerType(0); | 4961 | 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); | 4962 | store_inst.setAlignment(alignment); |
| 5038 | if (isByRef(return_type)) { | 4963 | if (isByRef(return_type)) { |
| 5039 | return rp; | 4964 | return rp; |
| ... | @@ -5086,7 +5011,6 @@ pub const FuncGen = struct { | ... | @@ -5086,7 +5011,6 @@ pub const FuncGen = struct { |
| 5086 | } | 5011 | } |
| 5087 | | 5012 | |
| 5088 | const abi_ret_ty = try lowerFnRetTy(self.dg, fn_info); | 5013 | 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); | 5014 | const operand = try self.resolveInst(un_op); |
| 5091 | const target = self.dg.module.getTarget(); | 5015 | const target = self.dg.module.getTarget(); |
| 5092 | const alignment = ret_ty.abiAlignment(target); | 5016 | const alignment = ret_ty.abiAlignment(target); |
| ... | @@ -5094,8 +5018,7 @@ pub const FuncGen = struct { | ... | @@ -5094,8 +5018,7 @@ pub const FuncGen = struct { |
| 5094 | if (isByRef(ret_ty)) { | 5018 | if (isByRef(ret_ty)) { |
| 5095 | // operand is a pointer however self.ret_ptr is null so that means | 5019 | // operand is a pointer however self.ret_ptr is null so that means |
| 5096 | // we need to return a value. | 5020 | // we need to return a value. |
| 5097 | const casted_ptr = self.builder.buildBitCast(operand, ptr_abi_ty, ""); | 5021 | 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); | 5022 | load_inst.setAlignment(alignment); |
| 5100 | _ = self.builder.buildRet(load_inst); | 5023 | _ = self.builder.buildRet(load_inst); |
| 5101 | return null; | 5024 | return null; |
| ... | @@ -5110,8 +5033,7 @@ pub const FuncGen = struct { | ... | @@ -5110,8 +5033,7 @@ pub const FuncGen = struct { |
| 5110 | const rp = self.buildAlloca(llvm_ret_ty, alignment); | 5033 | const rp = self.buildAlloca(llvm_ret_ty, alignment); |
| 5111 | const store_inst = self.builder.buildStore(operand, rp); | 5034 | const store_inst = self.builder.buildStore(operand, rp); |
| 5112 | store_inst.setAlignment(alignment); | 5035 | store_inst.setAlignment(alignment); |
| 5113 | const casted_ptr = self.builder.buildBitCast(rp, ptr_abi_ty, ""); | 5036 | 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); | 5037 | load_inst.setAlignment(alignment); |
| 5116 | _ = self.builder.buildRet(load_inst); | 5038 | _ = self.builder.buildRet(load_inst); |
| 5117 | return null; | 5039 | return null; |
| ... | @@ -5141,12 +5063,7 @@ pub const FuncGen = struct { | ... | @@ -5141,12 +5063,7 @@ pub const FuncGen = struct { |
| 5141 | const ptr = try self.resolveInst(un_op); | 5063 | const ptr = try self.resolveInst(un_op); |
| 5142 | const target = self.dg.module.getTarget(); | 5064 | const target = self.dg.module.getTarget(); |
| 5143 | const abi_ret_ty = try lowerFnRetTy(self.dg, fn_info); | 5065 | const abi_ret_ty = try lowerFnRetTy(self.dg, fn_info); |
| 5144 | const llvm_ret_ty = try self.dg.lowerType(ret_ty); | 5066 | 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)); | 5067 | loaded.setAlignment(ret_ty.abiAlignment(target)); |
| 5151 | _ = self.builder.buildRet(loaded); | 5068 | _ = self.builder.buildRet(loaded); |
| 5152 | return null; | 5069 | return null; |
| ... | @@ -5178,8 +5095,8 @@ pub const FuncGen = struct { | ... | @@ -5178,8 +5095,8 @@ pub const FuncGen = struct { |
| 5178 | const llvm_fn_name = "llvm.va_copy"; | 5095 | const llvm_fn_name = "llvm.va_copy"; |
| 5179 | const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: { | 5096 | const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: { |
| 5180 | const param_types = [_]*llvm.Type{ | 5097 | const param_types = [_]*llvm.Type{ |
| 5181 | self.dg.context.intType(8).pointerType(0), | 5098 | self.context.pointerType(0), |
| 5182 | self.dg.context.intType(8).pointerType(0), | 5099 | self.context.pointerType(0), |
| 5183 | }; | 5100 | }; |
| 5184 | const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False); | 5101 | 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); | 5102 | break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type); |
| ... | @@ -5203,7 +5120,7 @@ pub const FuncGen = struct { | ... | @@ -5203,7 +5120,7 @@ pub const FuncGen = struct { |
| 5203 | | 5120 | |
| 5204 | const llvm_fn_name = "llvm.va_end"; | 5121 | const llvm_fn_name = "llvm.va_end"; |
| 5205 | const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: { | 5122 | 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)}; | 5123 | const param_types = [_]*llvm.Type{self.context.pointerType(0)}; |
| 5207 | const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False); | 5124 | 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); | 5125 | break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type); |
| 5209 | }; | 5126 | }; |
| ... | @@ -5224,7 +5141,7 @@ pub const FuncGen = struct { | ... | @@ -5224,7 +5141,7 @@ pub const FuncGen = struct { |
| 5224 | | 5141 | |
| 5225 | const llvm_fn_name = "llvm.va_start"; | 5142 | const llvm_fn_name = "llvm.va_start"; |
| 5226 | const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: { | 5143 | 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)}; | 5144 | const param_types = [_]*llvm.Type{self.context.pointerType(0)}; |
| 5228 | const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False); | 5145 | 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); | 5146 | break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type); |
| 5230 | }; | 5147 | }; |
| ... | @@ -5417,7 +5334,7 @@ pub const FuncGen = struct { | ... | @@ -5417,7 +5334,7 @@ pub const FuncGen = struct { |
| 5417 | // of function pointers, however the phi makes it a runtime value and therefore | 5334 | // of function pointers, however the phi makes it a runtime value and therefore |
| 5418 | // the LLVM type has to be wrapped in a pointer. | 5335 | // the LLVM type has to be wrapped in a pointer. |
| 5419 | if (is_body or isByRef(inst_ty)) { | 5336 | if (is_body or isByRef(inst_ty)) { |
| 5420 | break :ty raw_llvm_ty.pointerType(0); | 5337 | break :ty self.context.pointerType(0); |
| 5421 | } | 5338 | } |
| 5422 | break :ty raw_llvm_ty; | 5339 | break :ty raw_llvm_ty; |
| 5423 | }; | 5340 | }; |
| ... | @@ -5482,7 +5399,7 @@ pub const FuncGen = struct { | ... | @@ -5482,7 +5399,7 @@ pub const FuncGen = struct { |
| 5482 | const payload_ty = self.air.typeOfIndex(inst); | 5399 | const payload_ty = self.air.typeOfIndex(inst); |
| 5483 | const can_elide_load = if (isByRef(payload_ty)) self.canElideLoad(body_tail) else false; | 5400 | const can_elide_load = if (isByRef(payload_ty)) self.canElideLoad(body_tail) else false; |
| 5484 | const is_unused = self.liveness.isUnused(inst); | 5401 | 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); | 5402 | return lowerTry(self, err_union, body, err_union_ty, false, can_elide_load, is_unused); |
| 5486 | } | 5403 | } |
| 5487 | | 5404 | |
| 5488 | fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { | 5405 | fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| ... | @@ -5491,9 +5408,8 @@ pub const FuncGen = struct { | ... | @@ -5491,9 +5408,8 @@ pub const FuncGen = struct { |
| 5491 | const err_union_ptr = try self.resolveInst(extra.data.ptr); | 5408 | const err_union_ptr = try self.resolveInst(extra.data.ptr); |
| 5492 | const body = self.air.extra[extra.end..][0..extra.data.body_len]; | 5409 | const body = self.air.extra[extra.end..][0..extra.data.body_len]; |
| 5493 | const err_union_ty = self.air.typeOf(extra.data.ptr).childType(); | 5410 | 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); | 5411 | const is_unused = self.liveness.isUnused(inst); |
| 5496 | return lowerTry(self, err_union_ptr, body, err_union_ty, true, true, is_unused, payload_ty); | 5412 | return lowerTry(self, err_union_ptr, body, err_union_ty, true, true, is_unused); |
| 5497 | } | 5413 | } |
| 5498 | | 5414 | |
| 5499 | fn lowerTry( | 5415 | fn lowerTry( |
| ... | @@ -5504,7 +5420,6 @@ pub const FuncGen = struct { | ... | @@ -5504,7 +5420,6 @@ pub const FuncGen = struct { |
| 5504 | operand_is_ptr: bool, | 5420 | operand_is_ptr: bool, |
| 5505 | can_elide_load: bool, | 5421 | can_elide_load: bool, |
| 5506 | is_unused: bool, | 5422 | is_unused: bool, |
| 5507 | result_ty: Type, | | |
| 5508 | ) !?*llvm.Value { | 5423 | ) !?*llvm.Value { |
| 5509 | const payload_ty = err_union_ty.errorUnionPayload(); | 5424 | const payload_ty = err_union_ty.errorUnionPayload(); |
| 5510 | const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(); | 5425 | const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(); |
| ... | @@ -5547,12 +5462,7 @@ pub const FuncGen = struct { | ... | @@ -5547,12 +5462,7 @@ pub const FuncGen = struct { |
| 5547 | return null; | 5462 | return null; |
| 5548 | } | 5463 | } |
| 5549 | if (!payload_has_bits) { | 5464 | if (!payload_has_bits) { |
| 5550 | if (!operand_is_ptr) return null; | 5465 | 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 | } | 5466 | } |
| 5557 | const offset = errUnionPayloadOffset(payload_ty, target); | 5467 | const offset = errUnionPayloadOffset(payload_ty, target); |
| 5558 | if (operand_is_ptr) { | 5468 | if (operand_is_ptr) { |
| ... | @@ -6038,9 +5948,8 @@ pub const FuncGen = struct { | ... | @@ -6038,9 +5948,8 @@ pub const FuncGen = struct { |
| 6038 | const union_llvm_ty = try self.dg.lowerType(struct_ty); | 5948 | const union_llvm_ty = try self.dg.lowerType(struct_ty); |
| 6039 | const layout = struct_ty.unionGetLayout(target); | 5949 | const layout = struct_ty.unionGetLayout(target); |
| 6040 | const payload_index = @boolToInt(layout.tag_align >= layout.payload_align); | 5950 | 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, ""); | 5951 | 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); | 5952 | 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)) { | 5953 | if (isByRef(field_ty)) { |
| 6045 | if (canElideLoad(self, body_tail)) | 5954 | if (canElideLoad(self, body_tail)) |
| 6046 | return field_ptr; | 5955 | return field_ptr; |
| ... | @@ -6068,7 +5977,7 @@ pub const FuncGen = struct { | ... | @@ -6068,7 +5977,7 @@ pub const FuncGen = struct { |
| 6068 | | 5977 | |
| 6069 | const res_ty = try self.dg.lowerType(self.air.getRefType(ty_pl.ty)); | 5978 | const res_ty = try self.dg.lowerType(self.air.getRefType(ty_pl.ty)); |
| 6070 | if (field_offset == 0) { | 5979 | if (field_offset == 0) { |
| 6071 | return self.builder.buildBitCast(field_ptr, res_ty, ""); | 5980 | return field_ptr; |
| 6072 | } | 5981 | } |
| 6073 | const llvm_usize_ty = self.context.intType(target.cpu.arch.ptrBitWidth()); | 5982 | const llvm_usize_ty = self.context.intType(target.cpu.arch.ptrBitWidth()); |
| 6074 | | 5983 | |
| ... | @@ -6635,7 +6544,7 @@ pub const FuncGen = struct { | ... | @@ -6635,7 +6544,7 @@ pub const FuncGen = struct { |
| 6635 | self.builder.buildLoad(optional_llvm_ty, operand, "") | 6544 | self.builder.buildLoad(optional_llvm_ty, operand, "") |
| 6636 | else | 6545 | else |
| 6637 | operand; | 6546 | operand; |
| 6638 | const llvm_i8 = self.dg.context.intType(8); | 6547 | const llvm_i8 = self.context.intType(8); |
| 6639 | return self.builder.buildICmp(pred, loaded, llvm_i8.constNull(), ""); | 6548 | return self.builder.buildICmp(pred, loaded, llvm_i8.constNull(), ""); |
| 6640 | } | 6549 | } |
| 6641 | | 6550 | |
| ... | @@ -6701,16 +6610,12 @@ pub const FuncGen = struct { | ... | @@ -6701,16 +6610,12 @@ pub const FuncGen = struct { |
| 6701 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 6610 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 6702 | const operand = try self.resolveInst(ty_op.operand); | 6611 | const operand = try self.resolveInst(ty_op.operand); |
| 6703 | const optional_ty = self.air.typeOf(ty_op.operand).childType(); | 6612 | 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; | 6613 | var buf: Type.Payload.ElemType = undefined; |
| 6706 | const payload_ty = optional_ty.optionalChild(&buf); | 6614 | const payload_ty = optional_ty.optionalChild(&buf); |
| 6707 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { | 6615 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 6708 | // We have a pointer to a zero-bit value and we need to return | 6616 | // We have a pointer to a zero-bit value and we need to return |
| 6709 | // a pointer to a zero-bit value. | 6617 | // a pointer to a zero-bit value. |
| 6710 | | 6618 | 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 | } | 6619 | } |
| 6715 | if (optional_ty.optionalReprIsPayload()) { | 6620 | if (optional_ty.optionalReprIsPayload()) { |
| 6716 | // The payload and the optional are the same value. | 6621 | // The payload and the optional are the same value. |
| ... | @@ -6726,17 +6631,13 @@ pub const FuncGen = struct { | ... | @@ -6726,17 +6631,13 @@ pub const FuncGen = struct { |
| 6726 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 6631 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 6727 | const operand = try self.resolveInst(ty_op.operand); | 6632 | const operand = try self.resolveInst(ty_op.operand); |
| 6728 | const optional_ty = self.air.typeOf(ty_op.operand).childType(); | 6633 | 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; | 6634 | var buf: Type.Payload.ElemType = undefined; |
| 6731 | const payload_ty = optional_ty.optionalChild(&buf); | 6635 | const payload_ty = optional_ty.optionalChild(&buf); |
| 6732 | const non_null_bit = self.context.intType(8).constInt(1, .False); | 6636 | const non_null_bit = self.context.intType(8).constInt(1, .False); |
| 6733 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { | 6637 | 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. | 6638 | // 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); | 6639 | _ = self.builder.buildStore(non_null_bit, operand); |
| 6736 | | 6640 | 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 | } | 6641 | } |
| 6741 | if (optional_ty.optionalReprIsPayload()) { | 6642 | if (optional_ty.optionalReprIsPayload()) { |
| 6742 | // The payload and the optional are the same value. | 6643 | // The payload and the optional are the same value. |
| ... | @@ -6794,11 +6695,7 @@ pub const FuncGen = struct { | ... | @@ -6794,11 +6695,7 @@ pub const FuncGen = struct { |
| 6794 | const target = self.dg.module.getTarget(); | 6695 | const target = self.dg.module.getTarget(); |
| 6795 | | 6696 | |
| 6796 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { | 6697 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 6797 | if (!operand_is_ptr) return null; | 6698 | 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 | } | 6699 | } |
| 6803 | const offset = errUnionPayloadOffset(payload_ty, target); | 6700 | const offset = errUnionPayloadOffset(payload_ty, target); |
| 6804 | const err_union_llvm_ty = try self.dg.lowerType(err_union_ty); | 6701 | const err_union_llvm_ty = try self.dg.lowerType(err_union_ty); |
| ... | @@ -6834,7 +6731,7 @@ pub const FuncGen = struct { | ... | @@ -6834,7 +6731,7 @@ pub const FuncGen = struct { |
| 6834 | if (err_union_ty.errorUnionSet().errorSetIsEmpty()) { | 6731 | if (err_union_ty.errorUnionSet().errorSetIsEmpty()) { |
| 6835 | const err_llvm_ty = try self.dg.lowerType(Type.anyerror); | 6732 | const err_llvm_ty = try self.dg.lowerType(Type.anyerror); |
| 6836 | if (operand_is_ptr) { | 6733 | if (operand_is_ptr) { |
| 6837 | return self.builder.buildBitCast(operand, err_llvm_ty.pointerType(0), ""); | 6734 | return operand; |
| 6838 | } else { | 6735 | } else { |
| 6839 | return err_llvm_ty.constInt(0, .False); | 6736 | return err_llvm_ty.constInt(0, .False); |
| 6840 | } | 6737 | } |
| ... | @@ -7104,14 +7001,8 @@ pub const FuncGen = struct { | ... | @@ -7104,14 +7001,8 @@ pub const FuncGen = struct { |
| 7104 | const llvm_slice_ty = try self.dg.lowerType(inst_ty); | 7001 | const llvm_slice_ty = try self.dg.lowerType(inst_ty); |
| 7105 | | 7002 | |
| 7106 | // In case of slicing a global, the result type looks something like `{ i8*, i64 }` | 7003 | // 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 | 7004 | // 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. | 7005 | 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, ""); | 7006 | return self.builder.buildInsertValue(partial, len, 1, ""); |
| 7116 | } | 7007 | } |
| 7117 | | 7008 | |
| ... | @@ -7636,7 +7527,7 @@ pub const FuncGen = struct { | ... | @@ -7636,7 +7527,7 @@ pub const FuncGen = struct { |
| 7636 | .neg => { | 7527 | .neg => { |
| 7637 | // In this case we can generate a softfloat negation by XORing the | 7528 | // In this case we can generate a softfloat negation by XORing the |
| 7638 | // bits with a constant. | 7529 | // bits with a constant. |
| 7639 | const int_llvm_ty = self.dg.context.intType(float_bits); | 7530 | const int_llvm_ty = self.context.intType(float_bits); |
| 7640 | const one = int_llvm_ty.constInt(1, .False); | 7531 | const one = int_llvm_ty.constInt(1, .False); |
| 7641 | const shift_amt = int_llvm_ty.constInt(float_bits - 1, .False); | 7532 | const shift_amt = int_llvm_ty.constInt(float_bits - 1, .False); |
| 7642 | const sign_mask = one.constShl(shift_amt); | 7533 | const sign_mask = one.constShl(shift_amt); |
| ... | @@ -8045,8 +7936,8 @@ pub const FuncGen = struct { | ... | @@ -8045,8 +7936,8 @@ pub const FuncGen = struct { |
| 8045 | const target = self.dg.module.getTarget(); | 7936 | const target = self.dg.module.getTarget(); |
| 8046 | | 7937 | |
| 8047 | if (operand_is_ref and result_is_ref) { | 7938 | if (operand_is_ref and result_is_ref) { |
| 8048 | // They are both pointers; just do a bitcast on the pointers :) | 7939 | // They are both pointers, so just return the same opaque pointer :) |
| 8049 | return self.builder.buildBitCast(operand, llvm_dest_ty.pointerType(0), ""); | 7940 | return operand; |
| 8050 | } | 7941 | } |
| 8051 | | 7942 | |
| 8052 | if (operand_ty.zigTypeTag() == .Int and inst_ty.isPtrAtRuntime()) { | 7943 | if (operand_ty.zigTypeTag() == .Int and inst_ty.isPtrAtRuntime()) { |
| ... | @@ -8061,9 +7952,7 @@ pub const FuncGen = struct { | ... | @@ -8061,9 +7952,7 @@ pub const FuncGen = struct { |
| 8061 | const array_ptr = self.buildAlloca(llvm_dest_ty, null); | 7952 | const array_ptr = self.buildAlloca(llvm_dest_ty, null); |
| 8062 | const bitcast_ok = elem_ty.bitSize(target) == elem_ty.abiSize(target) * 8; | 7953 | const bitcast_ok = elem_ty.bitSize(target) == elem_ty.abiSize(target) * 8; |
| 8063 | if (bitcast_ok) { | 7954 | if (bitcast_ok) { |
| 8064 | const llvm_vector_ty = try self.dg.lowerType(operand_ty); | 7955 | 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)); | 7956 | llvm_store.setAlignment(inst_ty.abiAlignment(target)); |
| 8068 | } else { | 7957 | } else { |
| 8069 | // If the ABI size of the element type is not evenly divisible by size in bits; | 7958 | // If the ABI size of the element type is not evenly divisible by size in bits; |
| ... | @@ -8092,9 +7981,7 @@ pub const FuncGen = struct { | ... | @@ -8092,9 +7981,7 @@ pub const FuncGen = struct { |
| 8092 | | 7981 | |
| 8093 | const bitcast_ok = elem_ty.bitSize(target) == elem_ty.abiSize(target) * 8; | 7982 | const bitcast_ok = elem_ty.bitSize(target) == elem_ty.abiSize(target) * 8; |
| 8094 | if (bitcast_ok) { | 7983 | if (bitcast_ok) { |
| 8095 | const llvm_vector_ptr_ty = llvm_vector_ty.pointerType(0); | 7984 | 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 | 7985 | // 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. | 7986 | // different alignment. This means we need to enforce the alignment of this load. |
| 8100 | vector.setAlignment(elem_ty.abiAlignment(target)); | 7987 | vector.setAlignment(elem_ty.abiAlignment(target)); |
| ... | @@ -8124,20 +8011,15 @@ pub const FuncGen = struct { | ... | @@ -8124,20 +8011,15 @@ pub const FuncGen = struct { |
| 8124 | } | 8011 | } |
| 8125 | | 8012 | |
| 8126 | if (operand_is_ref) { | 8013 | if (operand_is_ref) { |
| 8127 | // Bitcast the operand pointer, then load. | 8014 | 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)); | 8015 | load_inst.setAlignment(operand_ty.abiAlignment(target)); |
| 8131 | return load_inst; | 8016 | return load_inst; |
| 8132 | } | 8017 | } |
| 8133 | | 8018 | |
| 8134 | if (result_is_ref) { | 8019 | if (result_is_ref) { |
| 8135 | // Bitcast the result pointer, then store. | | |
| 8136 | const alignment = @max(operand_ty.abiAlignment(target), inst_ty.abiAlignment(target)); | 8020 | const alignment = @max(operand_ty.abiAlignment(target), inst_ty.abiAlignment(target)); |
| 8137 | const result_ptr = self.buildAlloca(llvm_dest_ty, alignment); | 8021 | const result_ptr = self.buildAlloca(llvm_dest_ty, alignment); |
| 8138 | const operand_llvm_ty = try self.dg.lowerType(operand_ty); | 8022 | 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); | 8023 | store_inst.setAlignment(alignment); |
| 8142 | return result_ptr; | 8024 | return result_ptr; |
| 8143 | } | 8025 | } |
| ... | @@ -8145,12 +8027,10 @@ pub const FuncGen = struct { | ... | @@ -8145,12 +8027,10 @@ pub const FuncGen = struct { |
| 8145 | if (llvm_dest_ty.getTypeKind() == .Struct) { | 8027 | if (llvm_dest_ty.getTypeKind() == .Struct) { |
| 8146 | // Both our operand and our result are values, not pointers, | 8028 | // Both our operand and our result are values, not pointers, |
| 8147 | // but LLVM won't let us bitcast struct values. | 8029 | // but LLVM won't let us bitcast struct values. |
| 8148 | // Therefore, we store operand to bitcasted alloca, then load for result. | 8030 | // Therefore, we store operand to alloca, then load for result. |
| 8149 | const alignment = @max(operand_ty.abiAlignment(target), inst_ty.abiAlignment(target)); | 8031 | const alignment = @max(operand_ty.abiAlignment(target), inst_ty.abiAlignment(target)); |
| 8150 | const result_ptr = self.buildAlloca(llvm_dest_ty, alignment); | 8032 | const result_ptr = self.buildAlloca(llvm_dest_ty, alignment); |
| 8151 | const operand_llvm_ty = try self.dg.lowerType(operand_ty); | 8033 | 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); | 8034 | store_inst.setAlignment(alignment); |
| 8155 | const load_inst = self.builder.buildLoad(llvm_dest_ty, result_ptr, ""); | 8035 | const load_inst = self.builder.buildLoad(llvm_dest_ty, result_ptr, ""); |
| 8156 | load_inst.setAlignment(alignment); | 8036 | load_inst.setAlignment(alignment); |
| ... | @@ -8248,7 +8128,7 @@ pub const FuncGen = struct { | ... | @@ -8248,7 +8128,7 @@ pub const FuncGen = struct { |
| 8248 | /// Use this instead of builder.buildAlloca, because this function makes sure to | 8128 | /// Use this instead of builder.buildAlloca, because this function makes sure to |
| 8249 | /// put the alloca instruction at the top of the function! | 8129 | /// put the alloca instruction at the top of the function! |
| 8250 | fn buildAlloca(self: *FuncGen, llvm_ty: *llvm.Type, alignment: ?c_uint) *llvm.Value { | 8130 | 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()); | 8131 | return buildAllocaInner(self.context, self.builder, self.llvm_func, self.di_scope != null, llvm_ty, alignment, self.dg.module.getTarget()); |
| 8252 | } | 8132 | } |
| 8253 | | 8133 | |
| 8254 | fn airStore(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { | 8134 | fn airStore(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| ... | @@ -8282,13 +8162,11 @@ pub const FuncGen = struct { | ... | @@ -8282,13 +8162,11 @@ pub const FuncGen = struct { |
| 8282 | const target = self.dg.module.getTarget(); | 8162 | const target = self.dg.module.getTarget(); |
| 8283 | const operand_size = operand_ty.abiSize(target); | 8163 | const operand_size = operand_ty.abiSize(target); |
| 8284 | const u8_llvm_ty = self.context.intType(8); | 8164 | 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); | 8165 | const fill_char = u8_llvm_ty.constInt(0xaa, .False); |
| 8288 | const dest_ptr_align = ptr_ty.ptrAlignment(target); | 8166 | const dest_ptr_align = ptr_ty.ptrAlignment(target); |
| 8289 | const usize_llvm_ty = try self.dg.lowerType(Type.usize); | 8167 | const usize_llvm_ty = try self.dg.lowerType(Type.usize); |
| 8290 | const len = usize_llvm_ty.constInt(operand_size, .False); | 8168 | 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()); | 8169 | _ = self.builder.buildMemSet(dest_ptr, fill_char, len, dest_ptr_align, ptr_ty.isVolatilePtr()); |
| 8292 | if (self.dg.module.comp.bin_file.options.valgrind) { | 8170 | if (self.dg.module.comp.bin_file.options.valgrind) { |
| 8293 | self.valgrindMarkUndef(dest_ptr, len); | 8171 | self.valgrindMarkUndef(dest_ptr, len); |
| 8294 | } | 8172 | } |
| ... | @@ -8365,7 +8243,7 @@ pub const FuncGen = struct { | ... | @@ -8365,7 +8243,7 @@ pub const FuncGen = struct { |
| 8365 | const llvm_i32 = self.context.intType(32); | 8243 | const llvm_i32 = self.context.intType(32); |
| 8366 | const llvm_fn_name = "llvm.frameaddress.p0"; | 8244 | const llvm_fn_name = "llvm.frameaddress.p0"; |
| 8367 | const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: { | 8245 | const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: { |
| 8368 | const llvm_p0i8 = self.context.intType(8).pointerType(0); | 8246 | const llvm_p0i8 = self.context.pointerType(0); |
| 8369 | const param_types = [_]*llvm.Type{llvm_i32}; | 8247 | const param_types = [_]*llvm.Type{llvm_i32}; |
| 8370 | const fn_type = llvm.functionType(llvm_p0i8, &param_types, param_types.len, .False); | 8248 | 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); | 8249 | break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type); |
| ... | @@ -8388,14 +8266,13 @@ pub const FuncGen = struct { | ... | @@ -8388,14 +8266,13 @@ pub const FuncGen = struct { |
| 8388 | fn airCmpxchg(self: *FuncGen, inst: Air.Inst.Index, is_weak: bool) !?*llvm.Value { | 8266 | 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; | 8267 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 8390 | const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data; | 8268 | const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data; |
| 8391 | var ptr = try self.resolveInst(extra.ptr); | 8269 | const ptr = try self.resolveInst(extra.ptr); |
| 8392 | var expected_value = try self.resolveInst(extra.expected_value); | 8270 | var expected_value = try self.resolveInst(extra.expected_value); |
| 8393 | var new_value = try self.resolveInst(extra.new_value); | 8271 | var new_value = try self.resolveInst(extra.new_value); |
| 8394 | const operand_ty = self.air.typeOf(extra.ptr).elemType(); | 8272 | const operand_ty = self.air.typeOf(extra.ptr).elemType(); |
| 8395 | const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false); | 8273 | const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false); |
| 8396 | if (opt_abi_ty) |abi_ty| { | 8274 | if (opt_abi_ty) |abi_ty| { |
| 8397 | // operand needs widening and truncating | 8275 | // operand needs widening and truncating |
| 8398 | ptr = self.builder.buildBitCast(ptr, abi_ty.pointerType(0), ""); | | |
| 8399 | if (operand_ty.isSignedInt()) { | 8276 | if (operand_ty.isSignedInt()) { |
| 8400 | expected_value = self.builder.buildSExt(expected_value, abi_ty, ""); | 8277 | expected_value = self.builder.buildSExt(expected_value, abi_ty, ""); |
| 8401 | new_value = self.builder.buildSExt(new_value, abi_ty, ""); | 8278 | new_value = self.builder.buildSExt(new_value, abi_ty, ""); |
| ... | @@ -8447,7 +8324,6 @@ pub const FuncGen = struct { | ... | @@ -8447,7 +8324,6 @@ pub const FuncGen = struct { |
| 8447 | const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, op == .Xchg); | 8324 | const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, op == .Xchg); |
| 8448 | if (opt_abi_ty) |abi_ty| { | 8325 | if (opt_abi_ty) |abi_ty| { |
| 8449 | // operand needs widening and truncating or bitcasting. | 8326 | // 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) | 8327 | const casted_operand = if (is_float) |
| 8452 | self.builder.buildBitCast(operand, abi_ty, "") | 8328 | self.builder.buildBitCast(operand, abi_ty, "") |
| 8453 | else if (is_signed_int) | 8329 | else if (is_signed_int) |
| ... | @@ -8457,7 +8333,7 @@ pub const FuncGen = struct { | ... | @@ -8457,7 +8333,7 @@ pub const FuncGen = struct { |
| 8457 | | 8333 | |
| 8458 | const uncasted_result = self.builder.buildAtomicRmw( | 8334 | const uncasted_result = self.builder.buildAtomicRmw( |
| 8459 | op, | 8335 | op, |
| 8460 | casted_ptr, | 8336 | ptr, |
| 8461 | casted_operand, | 8337 | casted_operand, |
| 8462 | ordering, | 8338 | ordering, |
| 8463 | single_threaded, | 8339 | single_threaded, |
| ... | @@ -8476,11 +8352,10 @@ pub const FuncGen = struct { | ... | @@ -8476,11 +8352,10 @@ pub const FuncGen = struct { |
| 8476 | | 8352 | |
| 8477 | // It's a pointer but we need to treat it as an int. | 8353 | // It's a pointer but we need to treat it as an int. |
| 8478 | const usize_llvm_ty = try self.dg.lowerType(Type.usize); | 8354 | 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, ""); | 8355 | const casted_operand = self.builder.buildPtrToInt(operand, usize_llvm_ty, ""); |
| 8481 | const uncasted_result = self.builder.buildAtomicRmw( | 8356 | const uncasted_result = self.builder.buildAtomicRmw( |
| 8482 | op, | 8357 | op, |
| 8483 | casted_ptr, | 8358 | ptr, |
| 8484 | casted_operand, | 8359 | casted_operand, |
| 8485 | ordering, | 8360 | ordering, |
| 8486 | single_threaded, | 8361 | single_threaded, |
| ... | @@ -8508,8 +8383,7 @@ pub const FuncGen = struct { | ... | @@ -8508,8 +8383,7 @@ pub const FuncGen = struct { |
| 8508 | | 8383 | |
| 8509 | if (opt_abi_llvm_ty) |abi_llvm_ty| { | 8384 | if (opt_abi_llvm_ty) |abi_llvm_ty| { |
| 8510 | // operand needs widening and truncating | 8385 | // operand needs widening and truncating |
| 8511 | const casted_ptr = self.builder.buildBitCast(ptr, abi_llvm_ty.pointerType(0), ""); | 8386 | 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); | 8387 | load_inst.setAlignment(ptr_alignment); |
| 8514 | load_inst.setVolatile(ptr_volatile); | 8388 | load_inst.setVolatile(ptr_volatile); |
| 8515 | load_inst.setOrdering(ordering); | 8389 | load_inst.setOrdering(ordering); |
| ... | @@ -8531,13 +8405,12 @@ pub const FuncGen = struct { | ... | @@ -8531,13 +8405,12 @@ pub const FuncGen = struct { |
| 8531 | const ptr_ty = self.air.typeOf(bin_op.lhs); | 8405 | const ptr_ty = self.air.typeOf(bin_op.lhs); |
| 8532 | const operand_ty = ptr_ty.childType(); | 8406 | const operand_ty = ptr_ty.childType(); |
| 8533 | if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime()) return null; | 8407 | if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime()) return null; |
| 8534 | var ptr = try self.resolveInst(bin_op.lhs); | 8408 | const ptr = try self.resolveInst(bin_op.lhs); |
| 8535 | var element = try self.resolveInst(bin_op.rhs); | 8409 | var element = try self.resolveInst(bin_op.rhs); |
| 8536 | const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false); | 8410 | const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false); |
| 8537 | | 8411 | |
| 8538 | if (opt_abi_ty) |abi_ty| { | 8412 | if (opt_abi_ty) |abi_ty| { |
| 8539 | // operand needs widening | 8413 | // operand needs widening |
| 8540 | ptr = self.builder.buildBitCast(ptr, abi_ty.pointerType(0), ""); | | |
| 8541 | if (operand_ty.isSignedInt()) { | 8414 | if (operand_ty.isSignedInt()) { |
| 8542 | element = self.builder.buildSExt(element, abi_ty, ""); | 8415 | element = self.builder.buildSExt(element, abi_ty, ""); |
| 8543 | } else { | 8416 | } else { |
| ... | @@ -8557,15 +8430,13 @@ pub const FuncGen = struct { | ... | @@ -8557,15 +8430,13 @@ pub const FuncGen = struct { |
| 8557 | const val_is_undef = if (self.air.value(extra.lhs)) |val| val.isUndefDeep() else false; | 8430 | const val_is_undef = if (self.air.value(extra.lhs)) |val| val.isUndefDeep() else false; |
| 8558 | const len = try self.resolveInst(extra.rhs); | 8431 | const len = try self.resolveInst(extra.rhs); |
| 8559 | const u8_llvm_ty = self.context.intType(8); | 8432 | 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; | 8433 | const fill_char = if (val_is_undef) u8_llvm_ty.constInt(0xaa, .False) else value; |
| 8563 | const target = self.dg.module.getTarget(); | 8434 | const target = self.dg.module.getTarget(); |
| 8564 | const dest_ptr_align = ptr_ty.ptrAlignment(target); | 8435 | const dest_ptr_align = ptr_ty.ptrAlignment(target); |
| 8565 | _ = self.builder.buildMemSet(dest_ptr_u8, fill_char, len, dest_ptr_align, ptr_ty.isVolatilePtr()); | 8436 | _ = self.builder.buildMemSet(dest_ptr, fill_char, len, dest_ptr_align, ptr_ty.isVolatilePtr()); |
| 8566 | | 8437 | |
| 8567 | if (val_is_undef and self.dg.module.comp.bin_file.options.valgrind) { | 8438 | if (val_is_undef and self.dg.module.comp.bin_file.options.valgrind) { |
| 8568 | self.valgrindMarkUndef(dest_ptr_u8, len); | 8439 | self.valgrindMarkUndef(dest_ptr, len); |
| 8569 | } | 8440 | } |
| 8570 | return null; | 8441 | return null; |
| 8571 | } | 8442 | } |
| ... | @@ -8578,15 +8449,12 @@ pub const FuncGen = struct { | ... | @@ -8578,15 +8449,12 @@ pub const FuncGen = struct { |
| 8578 | const src_ptr = try self.resolveInst(extra.lhs); | 8449 | const src_ptr = try self.resolveInst(extra.lhs); |
| 8579 | const src_ptr_ty = self.air.typeOf(extra.lhs); | 8450 | const src_ptr_ty = self.air.typeOf(extra.lhs); |
| 8580 | const len = try self.resolveInst(extra.rhs); | 8451 | 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(); | 8452 | const is_volatile = src_ptr_ty.isVolatilePtr() or dest_ptr_ty.isVolatilePtr(); |
| 8585 | const target = self.dg.module.getTarget(); | 8453 | const target = self.dg.module.getTarget(); |
| 8586 | _ = self.builder.buildMemCpy( | 8454 | _ = self.builder.buildMemCpy( |
| 8587 | dest_ptr_u8, | 8455 | dest_ptr, |
| 8588 | dest_ptr_ty.ptrAlignment(target), | 8456 | dest_ptr_ty.ptrAlignment(target), |
| 8589 | src_ptr_u8, | 8457 | src_ptr, |
| 8590 | src_ptr_ty.ptrAlignment(target), | 8458 | src_ptr_ty.ptrAlignment(target), |
| 8591 | len, | 8459 | len, |
| 8592 | is_volatile, | 8460 | is_volatile, |
| ... | @@ -8780,8 +8648,8 @@ pub const FuncGen = struct { | ... | @@ -8780,8 +8648,8 @@ pub const FuncGen = struct { |
| 8780 | const error_set_ty = self.air.getRefType(ty_op.ty); | 8648 | const error_set_ty = self.air.getRefType(ty_op.ty); |
| 8781 | | 8649 | |
| 8782 | const names = error_set_ty.errorSetNames(); | 8650 | const names = error_set_ty.errorSetNames(); |
| 8783 | const valid_block = self.dg.context.appendBasicBlock(self.llvm_func, "Valid"); | 8651 | const valid_block = self.context.appendBasicBlock(self.llvm_func, "Valid"); |
| 8784 | const invalid_block = self.dg.context.appendBasicBlock(self.llvm_func, "Invalid"); | 8652 | const invalid_block = self.context.appendBasicBlock(self.llvm_func, "Invalid"); |
| 8785 | const end_block = self.context.appendBasicBlock(self.llvm_func, "End"); | 8653 | 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)); | 8654 | const switch_instr = self.builder.buildSwitch(operand, invalid_block, @intCast(c_uint, names.len)); |
| 8787 | | 8655 | |
| ... | @@ -8807,7 +8675,7 @@ pub const FuncGen = struct { | ... | @@ -8807,7 +8675,7 @@ pub const FuncGen = struct { |
| 8807 | | 8675 | |
| 8808 | self.builder.positionBuilderAtEnd(end_block); | 8676 | self.builder.positionBuilderAtEnd(end_block); |
| 8809 | | 8677 | |
| 8810 | const llvm_type = self.dg.context.intType(1); | 8678 | const llvm_type = self.context.intType(1); |
| 8811 | const incoming_values: [2]*llvm.Value = .{ | 8679 | const incoming_values: [2]*llvm.Value = .{ |
| 8812 | llvm_type.constInt(1, .False), llvm_type.constInt(0, .False), | 8680 | llvm_type.constInt(1, .False), llvm_type.constInt(0, .False), |
| 8813 | }; | 8681 | }; |
| ... | @@ -8869,13 +8737,13 @@ pub const FuncGen = struct { | ... | @@ -8869,13 +8737,13 @@ pub const FuncGen = struct { |
| 8869 | } | 8737 | } |
| 8870 | } | 8738 | } |
| 8871 | | 8739 | |
| 8872 | const entry_block = self.dg.context.appendBasicBlock(fn_val, "Entry"); | 8740 | const entry_block = self.context.appendBasicBlock(fn_val, "Entry"); |
| 8873 | self.builder.positionBuilderAtEnd(entry_block); | 8741 | self.builder.positionBuilderAtEnd(entry_block); |
| 8874 | self.builder.clearCurrentDebugLocation(); | 8742 | self.builder.clearCurrentDebugLocation(); |
| 8875 | | 8743 | |
| 8876 | const fields = enum_ty.enumFields(); | 8744 | const fields = enum_ty.enumFields(); |
| 8877 | const named_block = self.dg.context.appendBasicBlock(fn_val, "Named"); | 8745 | const named_block = self.context.appendBasicBlock(fn_val, "Named"); |
| 8878 | const unnamed_block = self.dg.context.appendBasicBlock(fn_val, "Unnamed"); | 8746 | const unnamed_block = self.context.appendBasicBlock(fn_val, "Unnamed"); |
| 8879 | const tag_int_value = fn_val.getParam(0); | 8747 | 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())); | 8748 | const switch_instr = self.builder.buildSwitch(tag_int_value, unnamed_block, @intCast(c_uint, fields.count())); |
| 8881 | | 8749 | |
| ... | @@ -8893,10 +8761,10 @@ pub const FuncGen = struct { | ... | @@ -8893,10 +8761,10 @@ pub const FuncGen = struct { |
| 8893 | switch_instr.addCase(this_tag_int_value, named_block); | 8761 | switch_instr.addCase(this_tag_int_value, named_block); |
| 8894 | } | 8762 | } |
| 8895 | self.builder.positionBuilderAtEnd(named_block); | 8763 | self.builder.positionBuilderAtEnd(named_block); |
| 8896 | _ = self.builder.buildRet(self.dg.context.intType(1).constInt(1, .False)); | 8764 | _ = self.builder.buildRet(self.context.intType(1).constInt(1, .False)); |
| 8897 | | 8765 | |
| 8898 | self.builder.positionBuilderAtEnd(unnamed_block); | 8766 | self.builder.positionBuilderAtEnd(unnamed_block); |
| 8899 | _ = self.builder.buildRet(self.dg.context.intType(1).constInt(0, .False)); | 8767 | _ = self.builder.buildRet(self.context.intType(1).constInt(0, .False)); |
| 8900 | return fn_val; | 8768 | return fn_val; |
| 8901 | } | 8769 | } |
| 8902 | | 8770 | |
| ... | @@ -8955,12 +8823,12 @@ pub const FuncGen = struct { | ... | @@ -8955,12 +8823,12 @@ pub const FuncGen = struct { |
| 8955 | } | 8823 | } |
| 8956 | } | 8824 | } |
| 8957 | | 8825 | |
| 8958 | const entry_block = self.dg.context.appendBasicBlock(fn_val, "Entry"); | 8826 | const entry_block = self.context.appendBasicBlock(fn_val, "Entry"); |
| 8959 | self.builder.positionBuilderAtEnd(entry_block); | 8827 | self.builder.positionBuilderAtEnd(entry_block); |
| 8960 | self.builder.clearCurrentDebugLocation(); | 8828 | self.builder.clearCurrentDebugLocation(); |
| 8961 | | 8829 | |
| 8962 | const fields = enum_ty.enumFields(); | 8830 | const fields = enum_ty.enumFields(); |
| 8963 | const bad_value_block = self.dg.context.appendBasicBlock(fn_val, "BadValue"); | 8831 | const bad_value_block = self.context.appendBasicBlock(fn_val, "BadValue"); |
| 8964 | const tag_int_value = fn_val.getParam(0); | 8832 | 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())); | 8833 | const switch_instr = self.builder.buildSwitch(tag_int_value, bad_value_block, @intCast(c_uint, fields.count())); |
| 8966 | | 8834 | |
| ... | @@ -8969,7 +8837,7 @@ pub const FuncGen = struct { | ... | @@ -8969,7 +8837,7 @@ pub const FuncGen = struct { |
| 8969 | }; | 8837 | }; |
| 8970 | | 8838 | |
| 8971 | for (fields.keys()) |name, field_index| { | 8839 | for (fields.keys()) |name, field_index| { |
| 8972 | const str_init = self.dg.context.constString(name.ptr, @intCast(c_uint, name.len), .False); | 8840 | const str_init = self.context.constString(name.ptr, @intCast(c_uint, name.len), .False); |
| 8973 | const str_init_llvm_ty = str_init.typeOf(); | 8841 | const str_init_llvm_ty = str_init.typeOf(); |
| 8974 | const str_global = self.dg.object.llvm_module.addGlobal(str_init_llvm_ty, ""); | 8842 | const str_global = self.dg.object.llvm_module.addGlobal(str_init_llvm_ty, ""); |
| 8975 | str_global.setInitializer(str_init); | 8843 | str_global.setInitializer(str_init); |
| ... | @@ -8990,7 +8858,7 @@ pub const FuncGen = struct { | ... | @@ -8990,7 +8858,7 @@ pub const FuncGen = struct { |
| 8990 | slice_global.setUnnamedAddr(.True); | 8858 | slice_global.setUnnamedAddr(.True); |
| 8991 | slice_global.setAlignment(slice_alignment); | 8859 | slice_global.setAlignment(slice_alignment); |
| 8992 | | 8860 | |
| 8993 | const return_block = self.dg.context.appendBasicBlock(fn_val, "Name"); | 8861 | const return_block = self.context.appendBasicBlock(fn_val, "Name"); |
| 8994 | const this_tag_int_value = int: { | 8862 | const this_tag_int_value = int: { |
| 8995 | var tag_val_payload: Value.Payload.U32 = .{ | 8863 | var tag_val_payload: Value.Payload.U32 = .{ |
| 8996 | .base = .{ .tag = .enum_field_index }, | 8864 | .base = .{ .tag = .enum_field_index }, |
| ... | @@ -9042,7 +8910,7 @@ pub const FuncGen = struct { | ... | @@ -9042,7 +8910,7 @@ pub const FuncGen = struct { |
| 9042 | const slice_llvm_ty = try self.dg.lowerType(slice_ty); | 8910 | const slice_llvm_ty = try self.dg.lowerType(slice_ty); |
| 9043 | | 8911 | |
| 9044 | const error_name_table_ptr = try self.getErrorNameTable(); | 8912 | const error_name_table_ptr = try self.getErrorNameTable(); |
| 9045 | const ptr_slice_llvm_ty = slice_llvm_ty.pointerType(0); | 8913 | 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, ""); | 8914 | const error_name_table = self.builder.buildLoad(ptr_slice_llvm_ty, error_name_table_ptr, ""); |
| 9047 | const indices = [_]*llvm.Value{operand}; | 8915 | const indices = [_]*llvm.Value{operand}; |
| 9048 | const error_name_ptr = self.builder.buildInBoundsGEP(slice_llvm_ty, error_name_table, &indices, indices.len, ""); | 8916 | const error_name_ptr = self.builder.buildInBoundsGEP(slice_llvm_ty, error_name_table, &indices, indices.len, ""); |
| ... | @@ -9285,7 +9153,7 @@ pub const FuncGen = struct { | ... | @@ -9285,7 +9153,7 @@ pub const FuncGen = struct { |
| 9285 | if (result_ty.containerLayout() == .Packed) { | 9153 | if (result_ty.containerLayout() == .Packed) { |
| 9286 | const struct_obj = result_ty.castTag(.@"struct").?.data; | 9154 | const struct_obj = result_ty.castTag(.@"struct").?.data; |
| 9287 | const big_bits = struct_obj.backing_int_ty.bitSize(target); | 9155 | const big_bits = struct_obj.backing_int_ty.bitSize(target); |
| 9288 | const int_llvm_ty = self.dg.context.intType(@intCast(c_uint, big_bits)); | 9156 | const int_llvm_ty = self.context.intType(@intCast(c_uint, big_bits)); |
| 9289 | const fields = struct_obj.fields.values(); | 9157 | const fields = struct_obj.fields.values(); |
| 9290 | comptime assert(Type.packed_struct_layout_version == 2); | 9158 | comptime assert(Type.packed_struct_layout_version == 2); |
| 9291 | var running_int: *llvm.Value = int_llvm_ty.constNull(); | 9159 | var running_int: *llvm.Value = int_llvm_ty.constNull(); |
| ... | @@ -9296,7 +9164,7 @@ pub const FuncGen = struct { | ... | @@ -9296,7 +9164,7 @@ pub const FuncGen = struct { |
| 9296 | | 9164 | |
| 9297 | const non_int_val = try self.resolveInst(elem); | 9165 | const non_int_val = try self.resolveInst(elem); |
| 9298 | const ty_bit_size = @intCast(u16, field.ty.bitSize(target)); | 9166 | const ty_bit_size = @intCast(u16, field.ty.bitSize(target)); |
| 9299 | const small_int_ty = self.dg.context.intType(ty_bit_size); | 9167 | const small_int_ty = self.context.intType(ty_bit_size); |
| 9300 | const small_int_val = if (field.ty.isPtrAtRuntime()) | 9168 | const small_int_val = if (field.ty.isPtrAtRuntime()) |
| 9301 | self.builder.buildPtrToInt(non_int_val, small_int_ty, "") | 9169 | self.builder.buildPtrToInt(non_int_val, small_int_ty, "") |
| 9302 | else | 9170 | else |
| ... | @@ -9410,11 +9278,11 @@ pub const FuncGen = struct { | ... | @@ -9410,11 +9278,11 @@ pub const FuncGen = struct { |
| 9410 | | 9278 | |
| 9411 | if (union_obj.layout == .Packed) { | 9279 | if (union_obj.layout == .Packed) { |
| 9412 | const big_bits = union_ty.bitSize(target); | 9280 | const big_bits = union_ty.bitSize(target); |
| 9413 | const int_llvm_ty = self.dg.context.intType(@intCast(c_uint, big_bits)); | 9281 | const int_llvm_ty = self.context.intType(@intCast(c_uint, big_bits)); |
| 9414 | const field = union_obj.fields.values()[extra.field_index]; | 9282 | const field = union_obj.fields.values()[extra.field_index]; |
| 9415 | const non_int_val = try self.resolveInst(extra.init); | 9283 | const non_int_val = try self.resolveInst(extra.init); |
| 9416 | const ty_bit_size = @intCast(u16, field.ty.bitSize(target)); | 9284 | const ty_bit_size = @intCast(u16, field.ty.bitSize(target)); |
| 9417 | const small_int_ty = self.dg.context.intType(ty_bit_size); | 9285 | const small_int_ty = self.context.intType(ty_bit_size); |
| 9418 | const small_int_val = if (field.ty.isPtrAtRuntime()) | 9286 | const small_int_val = if (field.ty.isPtrAtRuntime()) |
| 9419 | self.builder.buildPtrToInt(non_int_val, small_int_ty, "") | 9287 | self.builder.buildPtrToInt(non_int_val, small_int_ty, "") |
| 9420 | else | 9288 | else |
| ... | @@ -9444,9 +9312,9 @@ pub const FuncGen = struct { | ... | @@ -9444,9 +9312,9 @@ pub const FuncGen = struct { |
| 9444 | } | 9312 | } |
| 9445 | assert(isByRef(union_ty)); | 9313 | assert(isByRef(union_ty)); |
| 9446 | // The llvm type of the alloca will be the named LLVM union type, and will not | 9314 | // 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 | 9315 | // 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 | 9316 | // We must construct the correct unnamed struct type here, in order to then set |
| 9449 | // then set the fields appropriately. | 9317 | // the fields appropriately. |
| 9450 | const result_ptr = self.buildAlloca(union_llvm_ty, layout.abi_align); | 9318 | const result_ptr = self.buildAlloca(union_llvm_ty, layout.abi_align); |
| 9451 | const llvm_payload = try self.resolveInst(extra.init); | 9319 | const llvm_payload = try self.resolveInst(extra.init); |
| 9452 | assert(union_obj.haveFieldTypes()); | 9320 | assert(union_obj.haveFieldTypes()); |
| ... | @@ -9489,8 +9357,6 @@ pub const FuncGen = struct { | ... | @@ -9489,8 +9357,6 @@ pub const FuncGen = struct { |
| 9489 | break :t self.context.structType(&fields, fields_len, .False); | 9357 | break :t self.context.structType(&fields, fields_len, .False); |
| 9490 | }; | 9358 | }; |
| 9491 | | 9359 | |
| 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 | 9360 | // Now we follow the layout as expressed above with GEP instructions to set the |
| 9495 | // tag and the payload. | 9361 | // tag and the payload. |
| 9496 | const index_type = self.context.intType(32); | 9362 | const index_type = self.context.intType(32); |
| ... | @@ -9510,7 +9376,7 @@ pub const FuncGen = struct { | ... | @@ -9510,7 +9376,7 @@ pub const FuncGen = struct { |
| 9510 | index_type.constNull(), | 9376 | index_type.constNull(), |
| 9511 | }; | 9377 | }; |
| 9512 | const len: c_uint = if (field_size == layout.payload_size) 2 else 3; | 9378 | 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, ""); | 9379 | 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); | 9380 | try self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic); |
| 9515 | return result_ptr; | 9381 | return result_ptr; |
| 9516 | } | 9382 | } |
| ... | @@ -9522,7 +9388,7 @@ pub const FuncGen = struct { | ... | @@ -9522,7 +9388,7 @@ pub const FuncGen = struct { |
| 9522 | index_type.constNull(), | 9388 | index_type.constNull(), |
| 9523 | }; | 9389 | }; |
| 9524 | const len: c_uint = if (field_size == layout.payload_size) 2 else 3; | 9390 | 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, ""); | 9391 | 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); | 9392 | try self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic); |
| 9527 | } | 9393 | } |
| 9528 | { | 9394 | { |
| ... | @@ -9530,7 +9396,7 @@ pub const FuncGen = struct { | ... | @@ -9530,7 +9396,7 @@ pub const FuncGen = struct { |
| 9530 | index_type.constNull(), | 9396 | index_type.constNull(), |
| 9531 | index_type.constInt(@boolToInt(layout.tag_align < layout.payload_align), .False), | 9397 | index_type.constInt(@boolToInt(layout.tag_align < layout.payload_align), .False), |
| 9532 | }; | 9398 | }; |
| 9533 | const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, casted_ptr, &indices, indices.len, ""); | 9399 | 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); | 9400 | const tag_llvm_ty = try self.dg.lowerType(union_obj.tag_ty); |
| 9535 | const llvm_tag = tag_llvm_ty.constInt(tag_int, .False); | 9401 | const llvm_tag = tag_llvm_ty.constInt(tag_int, .False); |
| 9536 | const store_inst = self.builder.buildStore(llvm_tag, field_ptr); | 9402 | const store_inst = self.builder.buildStore(llvm_tag, field_ptr); |
| ... | @@ -9579,8 +9445,7 @@ pub const FuncGen = struct { | ... | @@ -9579,8 +9445,7 @@ pub const FuncGen = struct { |
| 9579 | .data => {}, | 9445 | .data => {}, |
| 9580 | } | 9446 | } |
| 9581 | | 9447 | |
| 9582 | const llvm_u8 = self.context.intType(8); | 9448 | 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); | 9449 | const llvm_u32 = self.context.intType(32); |
| 9585 | | 9450 | |
| 9586 | const llvm_fn_name = "llvm.prefetch.p0"; | 9451 | const llvm_fn_name = "llvm.prefetch.p0"; |
| ... | @@ -9595,10 +9460,9 @@ pub const FuncGen = struct { | ... | @@ -9595,10 +9460,9 @@ pub const FuncGen = struct { |
| 9595 | }; | 9460 | }; |
| 9596 | | 9461 | |
| 9597 | const ptr = try self.resolveInst(prefetch.ptr); | 9462 | const ptr = try self.resolveInst(prefetch.ptr); |
| 9598 | const ptr_u8 = self.builder.buildBitCast(ptr, llvm_ptr_u8, ""); | | |
| 9599 | | 9463 | |
| 9600 | const params = [_]*llvm.Value{ | 9464 | const params = [_]*llvm.Value{ |
| 9601 | ptr_u8, | 9465 | ptr, |
| 9602 | llvm_u32.constInt(@enumToInt(prefetch.rw), .False), | 9466 | llvm_u32.constInt(@enumToInt(prefetch.rw), .False), |
| 9603 | llvm_u32.constInt(prefetch.locality, .False), | 9467 | llvm_u32.constInt(prefetch.locality, .False), |
| 9604 | llvm_u32.constInt(@enumToInt(prefetch.cache), .False), | 9468 | llvm_u32.constInt(@enumToInt(prefetch.cache), .False), |
| ... | @@ -9625,8 +9489,7 @@ pub const FuncGen = struct { | ... | @@ -9625,8 +9489,7 @@ pub const FuncGen = struct { |
| 9625 | | 9489 | |
| 9626 | const slice_ty = Type.initTag(.const_slice_u8_sentinel_0); | 9490 | const slice_ty = Type.initTag(.const_slice_u8_sentinel_0); |
| 9627 | const slice_alignment = slice_ty.abiAlignment(self.dg.module.getTarget()); | 9491 | const slice_alignment = slice_ty.abiAlignment(self.dg.module.getTarget()); |
| 9628 | const llvm_slice_ty = try self.dg.lowerType(slice_ty); | 9492 | 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 | | 9493 | |
| 9631 | const error_name_table_global = self.dg.object.llvm_module.addGlobal(llvm_slice_ptr_ty, "__zig_err_name_table"); | 9494 | 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()); | 9495 | error_name_table_global.setInitializer(llvm_slice_ptr_ty.getUndef()); |
| ... | @@ -9699,7 +9562,7 @@ pub const FuncGen = struct { | ... | @@ -9699,7 +9562,7 @@ pub const FuncGen = struct { |
| 9699 | non_null_bit: *llvm.Value, | 9562 | non_null_bit: *llvm.Value, |
| 9700 | ) !?*llvm.Value { | 9563 | ) !?*llvm.Value { |
| 9701 | const optional_llvm_ty = try self.dg.lowerType(optional_ty); | 9564 | 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), ""); | 9565 | const non_null_field = self.builder.buildZExt(non_null_bit, self.context.intType(8), ""); |
| 9703 | | 9566 | |
| 9704 | if (isByRef(optional_ty)) { | 9567 | if (isByRef(optional_ty)) { |
| 9705 | const target = self.dg.module.getTarget(); | 9568 | const target = self.dg.module.getTarget(); |
| ... | @@ -9740,31 +9603,24 @@ pub const FuncGen = struct { | ... | @@ -9740,31 +9603,24 @@ pub const FuncGen = struct { |
| 9740 | .Packed => { | 9603 | .Packed => { |
| 9741 | const result_ty = self.air.typeOfIndex(inst); | 9604 | const result_ty = self.air.typeOfIndex(inst); |
| 9742 | const result_ty_info = result_ty.ptrInfo().data; | 9605 | const result_ty_info = result_ty.ptrInfo().data; |
| 9743 | const result_llvm_ty = try self.dg.lowerType(result_ty); | | |
| 9744 | | 9606 | |
| 9745 | if (result_ty_info.host_size != 0) { | 9607 | if (result_ty_info.host_size != 0) { |
| 9746 | // From LLVM's perspective, a pointer to a packed struct and a pointer | 9608 | // 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 | 9609 | // 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 | 9610 | // Zig pointer type which provides information for how to mask and shift |
| 9749 | // out the relevant bits when accessing the pointee. | 9611 | // out the relevant bits when accessing the pointee. |
| 9750 | // Here we perform a bitcast because we want to use the host_size | 9612 | return struct_ptr; |
| 9751 | // as the llvm pointer element type. | | |
| 9752 | return self.builder.buildBitCast(struct_ptr, result_llvm_ty, ""); | | |
| 9753 | } | 9613 | } |
| 9754 | | 9614 | |
| 9755 | // We have a pointer to a packed struct field that happens to be byte-aligned. | 9615 | // 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. | 9616 | // Offset our operand pointer by the correct number of bytes. |
| 9757 | const byte_offset = struct_ty.packedStructFieldByteOffset(field_index, target); | 9617 | const byte_offset = struct_ty.packedStructFieldByteOffset(field_index, target); |
| 9758 | if (byte_offset == 0) { | 9618 | 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); | 9619 | 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); | 9620 | const llvm_usize = try self.dg.lowerType(Type.usize); |
| 9764 | const llvm_index = llvm_usize.constInt(byte_offset, .False); | 9621 | const llvm_index = llvm_usize.constInt(byte_offset, .False); |
| 9765 | const indices: [1]*llvm.Value = .{llvm_index}; | 9622 | const indices: [1]*llvm.Value = .{llvm_index}; |
| 9766 | const new_ptr = self.builder.buildInBoundsGEP(byte_llvm_ty, ptr_as_bytes, &indices, indices.len, ""); | 9623 | return self.builder.buildInBoundsGEP(byte_llvm_ty, struct_ptr, &indices, indices.len, ""); |
| 9767 | return self.builder.buildBitCast(new_ptr, result_llvm_ty, ""); | | |
| 9768 | }, | 9624 | }, |
| 9769 | else => { | 9625 | else => { |
| 9770 | const struct_llvm_ty = try self.dg.lowerPtrElemTy(struct_ty); | 9626 | const struct_llvm_ty = try self.dg.lowerPtrElemTy(struct_ty); |
| ... | @@ -9777,39 +9633,25 @@ pub const FuncGen = struct { | ... | @@ -9777,39 +9633,25 @@ pub const FuncGen = struct { |
| 9777 | // end of the struct. Treat our struct pointer as an array of two and get | 9633 | // 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 | 9634 | // the index to the element at index `1` to get a pointer to the end of |
| 9779 | // the struct. | 9635 | // the struct. |
| 9780 | const llvm_u32 = self.dg.context.intType(32); | 9636 | const llvm_u32 = self.context.intType(32); |
| 9781 | const llvm_index = llvm_u32.constInt(@boolToInt(struct_ty.hasRuntimeBitsIgnoreComptime()), .False); | 9637 | const llvm_index = llvm_u32.constInt(@boolToInt(struct_ty.hasRuntimeBitsIgnoreComptime()), .False); |
| 9782 | const indices: [1]*llvm.Value = .{llvm_index}; | 9638 | const indices: [1]*llvm.Value = .{llvm_index}; |
| 9783 | return self.builder.buildInBoundsGEP(struct_llvm_ty, struct_ptr, &indices, indices.len, ""); | 9639 | return self.builder.buildInBoundsGEP(struct_llvm_ty, struct_ptr, &indices, indices.len, ""); |
| 9784 | } | 9640 | } |
| 9785 | }, | 9641 | }, |
| 9786 | }, | 9642 | }, |
| 9787 | .Union => return self.unionFieldPtr(inst, struct_ptr, struct_ty), | 9643 | .Union => { |
| | 9644 | const layout = struct_ty.unionGetLayout(target); |
| | 9645 | if (layout.payload_size == 0 or struct_ty.containerLayout() == .Packed) return struct_ptr; |
| | 9646 | const payload_index = @boolToInt(layout.tag_align >= layout.payload_align); |
| | 9647 | const union_llvm_ty = try self.dg.lowerType(struct_ty); |
| | 9648 | const union_field_ptr = self.builder.buildStructGEP(union_llvm_ty, struct_ptr, payload_index, ""); |
| | 9649 | return union_field_ptr; |
| | 9650 | }, |
| 9788 | else => unreachable, | 9651 | else => unreachable, |
| 9789 | } | 9652 | } |
| 9790 | } | 9653 | } |
| 9791 | | 9654 | |
| 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 { | 9655 | fn getIntrinsic(self: *FuncGen, name: []const u8, types: []const *llvm.Type) *llvm.Value { |
| 9814 | const id = llvm.lookupIntrinsicID(name.ptr, name.len); | 9656 | const id = llvm.lookupIntrinsicID(name.ptr, name.len); |
| 9815 | assert(id != 0); | 9657 | assert(id != 0); |
| ... | @@ -9828,13 +9670,12 @@ pub const FuncGen = struct { | ... | @@ -9828,13 +9670,12 @@ pub const FuncGen = struct { |
| 9828 | const target = fg.dg.module.getTarget(); | 9670 | const target = fg.dg.module.getTarget(); |
| 9829 | const result_align = @max(ptr_alignment, pointee_type.abiAlignment(target)); | 9671 | const result_align = @max(ptr_alignment, pointee_type.abiAlignment(target)); |
| 9830 | const result_ptr = fg.buildAlloca(pointee_llvm_ty, result_align); | 9672 | 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); | 9673 | const llvm_usize = fg.context.intType(Type.usize.intInfo(target).bits); |
| 9833 | const size_bytes = pointee_type.abiSize(target); | 9674 | const size_bytes = pointee_type.abiSize(target); |
| 9834 | _ = fg.builder.buildMemCpy( | 9675 | _ = fg.builder.buildMemCpy( |
| 9835 | fg.builder.buildBitCast(result_ptr, llvm_ptr_u8, ""), | 9676 | result_ptr, |
| 9836 | result_align, | 9677 | result_align, |
| 9837 | fg.builder.buildBitCast(ptr, llvm_ptr_u8, ""), | 9678 | ptr, |
| 9838 | ptr_alignment, | 9679 | ptr_alignment, |
| 9839 | llvm_usize.constInt(size_bytes, .False), | 9680 | llvm_usize.constInt(size_bytes, .False), |
| 9840 | is_volatile, | 9681 | is_volatile, |
| ... | @@ -9855,7 +9696,7 @@ pub const FuncGen = struct { | ... | @@ -9855,7 +9696,7 @@ pub const FuncGen = struct { |
| 9855 | | 9696 | |
| 9856 | assert(info.vector_index != .runtime); | 9697 | assert(info.vector_index != .runtime); |
| 9857 | if (info.vector_index != .none) { | 9698 | if (info.vector_index != .none) { |
| 9858 | const index_u32 = self.dg.context.intType(32).constInt(@enumToInt(info.vector_index), .False); | 9699 | 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); | 9700 | const vec_elem_ty = try self.dg.lowerType(info.pointee_type); |
| 9860 | const vec_ty = vec_elem_ty.vectorType(info.host_size); | 9701 | const vec_ty = vec_elem_ty.vectorType(info.host_size); |
| 9861 | | 9702 | |
| ... | @@ -9878,8 +9719,7 @@ pub const FuncGen = struct { | ... | @@ -9878,8 +9719,7 @@ pub const FuncGen = struct { |
| 9878 | } | 9719 | } |
| 9879 | | 9720 | |
| 9880 | const int_elem_ty = self.context.intType(info.host_size * 8); | 9721 | const int_elem_ty = self.context.intType(info.host_size * 8); |
| 9881 | const int_ptr = self.builder.buildBitCast(ptr, int_elem_ty.pointerType(0), ""); | 9722 | 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); | 9723 | containing_int.setAlignment(ptr_alignment); |
| 9884 | containing_int.setVolatile(ptr_volatile); | 9724 | containing_int.setVolatile(ptr_volatile); |
| 9885 | | 9725 | |
| ... | @@ -9894,8 +9734,7 @@ pub const FuncGen = struct { | ... | @@ -9894,8 +9734,7 @@ pub const FuncGen = struct { |
| 9894 | | 9734 | |
| 9895 | const same_size_int = self.context.intType(elem_bits); | 9735 | const same_size_int = self.context.intType(elem_bits); |
| 9896 | const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, ""); | 9736 | 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), ""); | 9737 | 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); | 9738 | store_inst.setAlignment(result_align); |
| 9900 | return result_ptr; | 9739 | return result_ptr; |
| 9901 | } | 9740 | } |
| ... | @@ -9933,7 +9772,7 @@ pub const FuncGen = struct { | ... | @@ -9933,7 +9772,7 @@ pub const FuncGen = struct { |
| 9933 | | 9772 | |
| 9934 | assert(info.vector_index != .runtime); | 9773 | assert(info.vector_index != .runtime); |
| 9935 | if (info.vector_index != .none) { | 9774 | if (info.vector_index != .none) { |
| 9936 | const index_u32 = self.dg.context.intType(32).constInt(@enumToInt(info.vector_index), .False); | 9775 | const index_u32 = self.context.intType(32).constInt(@enumToInt(info.vector_index), .False); |
| 9937 | const vec_elem_ty = try self.dg.lowerType(elem_ty); | 9776 | const vec_elem_ty = try self.dg.lowerType(elem_ty); |
| 9938 | const vec_ty = vec_elem_ty.vectorType(info.host_size); | 9777 | const vec_ty = vec_elem_ty.vectorType(info.host_size); |
| 9939 | | 9778 | |
| ... | @@ -9952,8 +9791,7 @@ pub const FuncGen = struct { | ... | @@ -9952,8 +9791,7 @@ pub const FuncGen = struct { |
| 9952 | | 9791 | |
| 9953 | if (info.host_size != 0) { | 9792 | if (info.host_size != 0) { |
| 9954 | const int_elem_ty = self.context.intType(info.host_size * 8); | 9793 | const int_elem_ty = self.context.intType(info.host_size * 8); |
| 9955 | const int_ptr = self.builder.buildBitCast(ptr, int_elem_ty.pointerType(0), ""); | 9794 | 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); | 9795 | assert(ordering == .NotAtomic); |
| 9958 | containing_int.setAlignment(ptr_alignment); | 9796 | containing_int.setAlignment(ptr_alignment); |
| 9959 | containing_int.setVolatile(ptr_volatile); | 9797 | containing_int.setVolatile(ptr_volatile); |
| ... | @@ -9978,7 +9816,7 @@ pub const FuncGen = struct { | ... | @@ -9978,7 +9816,7 @@ pub const FuncGen = struct { |
| 9978 | const shifted_value = self.builder.buildShl(extended_value, shift_amt, ""); | 9816 | const shifted_value = self.builder.buildShl(extended_value, shift_amt, ""); |
| 9979 | const ored_value = self.builder.buildOr(shifted_value, anded_containing_int, ""); | 9817 | const ored_value = self.builder.buildOr(shifted_value, anded_containing_int, ""); |
| 9980 | | 9818 | |
| 9981 | const store_inst = self.builder.buildStore(ored_value, int_ptr); | 9819 | const store_inst = self.builder.buildStore(ored_value, ptr); |
| 9982 | assert(ordering == .NotAtomic); | 9820 | assert(ordering == .NotAtomic); |
| 9983 | store_inst.setAlignment(ptr_alignment); | 9821 | store_inst.setAlignment(ptr_alignment); |
| 9984 | store_inst.setVolatile(ptr_volatile); | 9822 | store_inst.setVolatile(ptr_volatile); |
| ... | @@ -9992,12 +9830,11 @@ pub const FuncGen = struct { | ... | @@ -9992,12 +9830,11 @@ pub const FuncGen = struct { |
| 9992 | return; | 9830 | return; |
| 9993 | } | 9831 | } |
| 9994 | assert(ordering == .NotAtomic); | 9832 | assert(ordering == .NotAtomic); |
| 9995 | const llvm_ptr_u8 = self.context.intType(8).pointerType(0); | | |
| 9996 | const size_bytes = elem_ty.abiSize(target); | 9833 | const size_bytes = elem_ty.abiSize(target); |
| 9997 | _ = self.builder.buildMemCpy( | 9834 | _ = self.builder.buildMemCpy( |
| 9998 | self.builder.buildBitCast(ptr, llvm_ptr_u8, ""), | 9835 | ptr, |
| 9999 | ptr_alignment, | 9836 | ptr_alignment, |
| 10000 | self.builder.buildBitCast(elem, llvm_ptr_u8, ""), | 9837 | elem, |
| 10001 | elem_ty.abiAlignment(target), | 9838 | elem_ty.abiAlignment(target), |
| 10002 | self.context.intType(Type.usize.intInfo(target).bits).constInt(size_bytes, .False), | 9839 | self.context.intType(Type.usize.intInfo(target).bits).constInt(size_bytes, .False), |
| 10003 | info.@"volatile", | 9840 | info.@"volatile", |
| ... | @@ -11187,6 +11024,7 @@ fn compilerRtIntBits(bits: u16) u16 { | ... | @@ -11187,6 +11024,7 @@ fn compilerRtIntBits(bits: u16) u16 { |
| 11187 | } | 11024 | } |
| 11188 | | 11025 | |
| 11189 | fn buildAllocaInner( | 11026 | fn buildAllocaInner( |
| | 11027 | context: *llvm.Context, |
| 11190 | builder: *llvm.Builder, | 11028 | builder: *llvm.Builder, |
| 11191 | llvm_func: *llvm.Value, | 11029 | llvm_func: *llvm.Value, |
| 11192 | di_scope_non_null: bool, | 11030 | di_scope_non_null: bool, |
| ... | @@ -11224,7 +11062,7 @@ fn buildAllocaInner( | ... | @@ -11224,7 +11062,7 @@ fn buildAllocaInner( |
| 11224 | // The pointer returned from this function should have the generic address space, | 11062 | // 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. | 11063 | // if this isn't the case then cast it to the generic address space. |
| 11226 | if (address_space != llvm.address_space.default) { | 11064 | if (address_space != llvm.address_space.default) { |
| 11227 | return builder.buildAddrSpaceCast(alloca, llvm_ty.pointerType(llvm.address_space.default), ""); | 11065 | return builder.buildAddrSpaceCast(alloca, context.pointerType(llvm.address_space.default), ""); |
| 11228 | } | 11066 | } |
| 11229 | | 11067 | |
| 11230 | return alloca; | 11068 | return alloca; |