authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2022-09-25 01:15:33+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2022-10-12 20:36:15+02:00
loge90a42a80844f49e8755ab92d1c082e9ac906dee
treec782a403b60256c557be524a9db0f4f2d7687fbf
parentad747739594805546e0d52d112dfd4a75978c8c7
signature Commit is signed but in an unrecognized format.

stage2: improve globals with address spaces a little


1 files changed, 37 insertions(+), 35 deletions(-)

src/codegen/llvm.zig+37-35
...@@ -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, because2400 // 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 convert2413 // 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 replace2414 // 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 else2418 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();
26182614
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;
26272624
...@@ -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);
32483247
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);
40564055
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;
40654064
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 and4327 // 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 to4339 // 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}
99509952
9951/// If `llvm_addrspace` is generic, convert it to the actual address space that globals9953/// 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.
9953fn toLlvmGlobalAddressSpace(llvm_addrspace: c_uint, target: std.Target) c_uint {9955fn 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 else9958 else => |as| toLlvmAddressSpace(as, target),
9957 llvm_addrspace;9959 };
9958}9960}
99599961
9960/// Take into account 0 bit fields and padding. Returns null if an llvm9962/// Take into account 0 bit fields and padding. Returns null if an llvm