| ... | @@ -2399,8 +2399,7 @@ pub const DeclGen = struct { | ... | @@ -2399,8 +2399,7 @@ pub const DeclGen = struct { |
| 2399 | // mismatch, because we don't have the LLVM type until the *value* is created, | 2399 | // mismatch, because we don't have the LLVM type until the *value* is created, |
| 2400 | // whereas the global needs to be created based on the type alone, because | 2400 | // whereas the global needs to be created based on the type alone, because |
| 2401 | // lowering the value may reference the global as a pointer. | 2401 | // lowering the value may reference the global as a pointer. |
| 2402 | const llvm_addrspace = toLlvmAddressSpace(decl.@"addrspace", target); | 2402 | const llvm_global_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target); |
| 2403 | const llvm_global_addrspace = toLlvmGlobalAddressSpace(llvm_addrspace, target); | | |
| 2404 | const new_global = dg.object.llvm_module.addGlobalInAddressSpace( | 2403 | const new_global = dg.object.llvm_module.addGlobalInAddressSpace( |
| 2405 | llvm_init.typeOf(), | 2404 | llvm_init.typeOf(), |
| 2406 | "", | 2405 | "", |
| ... | @@ -2414,12 +2413,9 @@ pub const DeclGen = struct { | ... | @@ -2414,12 +2413,9 @@ pub const DeclGen = struct { |
| 2414 | // replaceAllUsesWith requires the type to be unchanged. So we convert | 2413 | // replaceAllUsesWith requires the type to be unchanged. So we convert |
| 2415 | // the new global to the old type and use that as the thing to replace | 2414 | // the new global to the old type and use that as the thing to replace |
| 2416 | // old uses. | 2415 | // old uses. |
| 2417 | const new_global_ptr = if (llvm_addrspace != llvm_global_addrspace) | 2416 | // TODO: How should this work then the address space of a global changed? |
| 2418 | new_global.constAddrSpaceCast(llvm_init.typeOf().pointerType(llvm_addrspace)) | 2417 | const new_global_ptr = new_global.constBitCast(global.typeOf()); |
| 2419 | else | 2418 | global.replaceAllUsesWith(new_global_ptr); |
| 2420 | new_global; | | |
| 2421 | const new_global_casted_ptr = new_global_ptr.constBitCast(global.typeOf()); | | |
| 2422 | global.replaceAllUsesWith(new_global_casted_ptr); | | |
| 2423 | dg.object.decl_map.putAssumeCapacity(decl_index, new_global); | 2419 | dg.object.decl_map.putAssumeCapacity(decl_index, new_global); |
| 2424 | new_global.takeName(global); | 2420 | new_global.takeName(global); |
| 2425 | global.deleteGlobal(); | 2421 | global.deleteGlobal(); |
| ... | @@ -2617,11 +2613,12 @@ pub const DeclGen = struct { | ... | @@ -2617,11 +2613,12 @@ pub const DeclGen = struct { |
| 2617 | const target = dg.module.getTarget(); | 2613 | const target = dg.module.getTarget(); |
| 2618 | | 2614 | |
| 2619 | const llvm_type = try dg.lowerType(decl.ty); | 2615 | const llvm_type = try dg.lowerType(decl.ty); |
| 2620 | const llvm_addrspace = toLlvmAddressSpace(decl.@"addrspace", target); | 2616 | const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target); |
| | 2617 | |
| 2621 | const llvm_global = dg.object.llvm_module.addGlobalInAddressSpace( | 2618 | const llvm_global = dg.object.llvm_module.addGlobalInAddressSpace( |
| 2622 | llvm_type, | 2619 | llvm_type, |
| 2623 | fqn, | 2620 | fqn, |
| 2624 | toLlvmGlobalAddressSpace(llvm_addrspace, target), | 2621 | llvm_actual_addrspace, |
| 2625 | ); | 2622 | ); |
| 2626 | gop.value_ptr.* = llvm_global; | 2623 | gop.value_ptr.* = llvm_global; |
| 2627 | | 2624 | |
| ... | @@ -3241,16 +3238,18 @@ pub const DeclGen = struct { | ... | @@ -3241,16 +3238,18 @@ pub const DeclGen = struct { |
| 3241 | const decl_index = tv.val.castTag(.variable).?.data.owner_decl; | 3238 | const decl_index = tv.val.castTag(.variable).?.data.owner_decl; |
| 3242 | const decl = dg.module.declPtr(decl_index); | 3239 | const decl = dg.module.declPtr(decl_index); |
| 3243 | dg.module.markDeclAlive(decl); | 3240 | dg.module.markDeclAlive(decl); |
| | 3241 | |
| | 3242 | const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target); |
| | 3243 | const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target); |
| | 3244 | |
| 3244 | const llvm_var_type = try dg.lowerType(tv.ty); | 3245 | const llvm_var_type = try dg.lowerType(tv.ty); |
| 3245 | const llvm_var_addrspace = toLlvmAddressSpace(decl.@"addrspace", target); | 3246 | const llvm_actual_ptr_type = llvm_var_type.pointerType(llvm_actual_addrspace); |
| 3246 | const llvm_global_addrspace = toLlvmGlobalAddressSpace(llvm_var_addrspace, target); | | |
| 3247 | const llvm_var_ptr_type = llvm_var_type.pointerType(llvm_global_addrspace); | | |
| 3248 | | 3247 | |
| 3249 | const val = try dg.resolveGlobalDecl(decl_index); | 3248 | const val = try dg.resolveGlobalDecl(decl_index); |
| 3250 | const val_ptr = val.constBitCast(llvm_var_ptr_type); | 3249 | const val_ptr = val.constBitCast(llvm_actual_ptr_type); |
| 3251 | if (llvm_global_addrspace != llvm_var_addrspace) { | 3250 | if (llvm_actual_addrspace != llvm_wanted_addrspace) { |
| 3252 | const llvm_ptr_type = llvm_var_type.pointerType(llvm_var_addrspace); | 3251 | const llvm_wanted_ptr_type = llvm_var_type.pointerType(llvm_wanted_addrspace); |
| 3253 | return val_ptr.constAddrSpaceCast(llvm_ptr_type); | 3252 | return val_ptr.constAddrSpaceCast(llvm_wanted_ptr_type); |
| 3254 | } | 3253 | } |
| 3255 | return val_ptr; | 3254 | return val_ptr; |
| 3256 | }, | 3255 | }, |
| ... | @@ -4055,12 +4054,12 @@ pub const DeclGen = struct { | ... | @@ -4055,12 +4054,12 @@ pub const DeclGen = struct { |
| 4055 | try self.resolveGlobalDecl(decl_index); | 4054 | try self.resolveGlobalDecl(decl_index); |
| 4056 | | 4055 | |
| 4057 | const target = self.module.getTarget(); | 4056 | const target = self.module.getTarget(); |
| 4058 | const llvm_addrspace = toLlvmAddressSpace(decl.@"addrspace", target); | 4057 | const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target); |
| 4059 | const llvm_global_addrspace = toLlvmGlobalAddressSpace(llvm_addrspace, target); | 4058 | const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target); |
| 4060 | const llvm_val = if (llvm_addrspace != llvm_global_addrspace) blk: { | 4059 | const llvm_val = if (llvm_wanted_addrspace != llvm_actual_addrspace) blk: { |
| 4061 | const llvm_decl_ty = try self.lowerType(decl.ty); | 4060 | const llvm_decl_ty = try self.lowerType(decl.ty); |
| 4062 | const llvm_decl_ptr_ty = llvm_decl_ty.pointerType(llvm_addrspace); | 4061 | const llvm_decl_wanted_ptr_ty = llvm_decl_ty.pointerType(llvm_wanted_addrspace); |
| 4063 | break :blk llvm_decl_val.constAddrSpaceCast(llvm_decl_ptr_ty); | 4062 | break :blk llvm_decl_val.constAddrSpaceCast(llvm_decl_wanted_ptr_ty); |
| 4064 | } else llvm_decl_val; | 4063 | } else llvm_decl_val; |
| 4065 | | 4064 | |
| 4066 | const llvm_type = try self.lowerType(tv.ty); | 4065 | const llvm_type = try self.lowerType(tv.ty); |
| ... | @@ -4328,9 +4327,9 @@ pub const FuncGen = struct { | ... | @@ -4328,9 +4327,9 @@ pub const FuncGen = struct { |
| 4328 | // We have an LLVM value but we need to create a global constant and | 4327 | // We have an LLVM value but we need to create a global constant and |
| 4329 | // set the value as its initializer, and then return a pointer to the global. | 4328 | // set the value as its initializer, and then return a pointer to the global. |
| 4330 | const target = self.dg.module.getTarget(); | 4329 | const target = self.dg.module.getTarget(); |
| 4331 | const llvm_addrspace = toLlvmAddressSpace(.generic, target); | 4330 | const llvm_wanted_addrspace = toLlvmAddressSpace(.generic, target); |
| 4332 | const llvm_global_addrspace = toLlvmGlobalAddressSpace(llvm_addrspace, target); | 4331 | const llvm_actual_addrspace = toLlvmGlobalAddressSpace(.generic, target); |
| 4333 | const global = self.dg.object.llvm_module.addGlobalInAddressSpace(llvm_val.typeOf(), "", llvm_global_addrspace); | 4332 | const global = self.dg.object.llvm_module.addGlobalInAddressSpace(llvm_val.typeOf(), "", llvm_actual_addrspace); |
| 4334 | global.setInitializer(llvm_val); | 4333 | global.setInitializer(llvm_val); |
| 4335 | global.setLinkage(.Private); | 4334 | global.setLinkage(.Private); |
| 4336 | global.setGlobalConstant(.True); | 4335 | global.setGlobalConstant(.True); |
| ... | @@ -4340,10 +4339,13 @@ pub const FuncGen = struct { | ... | @@ -4340,10 +4339,13 @@ pub const FuncGen = struct { |
| 4340 | // the type of global constants might not match the type it is supposed to | 4339 | // the type of global constants might not match the type it is supposed to |
| 4341 | // be, and so we must bitcast the pointer at the usage sites. | 4340 | // be, and so we must bitcast the pointer at the usage sites. |
| 4342 | const wanted_llvm_ty = try self.dg.lowerType(ty); | 4341 | const wanted_llvm_ty = try self.dg.lowerType(ty); |
| 4343 | const wanted_bitcasted_llvm_ptr_ty = wanted_llvm_ty.pointerType(llvm_global_addrspace); | 4342 | const wanted_bitcasted_llvm_ptr_ty = wanted_llvm_ty.pointerType(llvm_actual_addrspace); |
| 4344 | const bitcasted_ptr = global.constBitCast(wanted_bitcasted_llvm_ptr_ty); | 4343 | const bitcasted_ptr = global.constBitCast(wanted_bitcasted_llvm_ptr_ty); |
| 4345 | const wanted_llvm_ptr_ty = wanted_llvm_ty.pointerType(llvm_addrspace); | 4344 | const wanted_llvm_ptr_ty = wanted_llvm_ty.pointerType(llvm_wanted_addrspace); |
| 4346 | const casted_ptr = bitcasted_ptr.constAddrSpaceCast(wanted_llvm_ptr_ty); | 4345 | const casted_ptr = if (llvm_wanted_addrspace != llvm_actual_addrspace) |
| | 4346 | bitcasted_ptr.constAddrSpaceCast(wanted_llvm_ptr_ty) |
| | 4347 | else |
| | 4348 | bitcasted_ptr; |
| 4347 | gop.value_ptr.* = casted_ptr; | 4349 | gop.value_ptr.* = casted_ptr; |
| 4348 | return casted_ptr; | 4350 | return casted_ptr; |
| 4349 | } | 4351 | } |
| ... | @@ -9948,13 +9950,13 @@ fn llvmDefaultGlobalAddressSpace(target: std.Target) c_uint { | ... | @@ -9948,13 +9950,13 @@ fn llvmDefaultGlobalAddressSpace(target: std.Target) c_uint { |
| 9948 | }; | 9950 | }; |
| 9949 | } | 9951 | } |
| 9950 | | 9952 | |
| 9951 | /// If `llvm_addrspace` is generic, convert it to the actual address space that globals | 9953 | /// Return the actual address space that a value should be stored in if its a global address space. |
| 9952 | /// should be stored in by default. | 9954 | /// When a value is placed in the resulting address space, it needs to be cast back into wanted_address_space. |
| 9953 | fn toLlvmGlobalAddressSpace(llvm_addrspace: c_uint, target: std.Target) c_uint { | 9955 | fn toLlvmGlobalAddressSpace(wanted_address_space: std.builtin.AddressSpace, target: std.Target) c_uint { |
| 9954 | return if (llvm_addrspace == llvm.address_space.default) | 9956 | return switch (wanted_address_space) { |
| 9955 | llvmDefaultGlobalAddressSpace(target) | 9957 | .generic => llvmDefaultGlobalAddressSpace(target), |
| 9956 | else | 9958 | else => |as| toLlvmAddressSpace(as, target), |
| 9957 | llvm_addrspace; | 9959 | }; |
| 9958 | } | 9960 | } |
| 9959 | | 9961 | |
| 9960 | /// Take into account 0 bit fields and padding. Returns null if an llvm | 9962 | /// Take into account 0 bit fields and padding. Returns null if an llvm |