mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
std.Target: Make Cpu.Arch.supportsAddressSpace() take an optional context.
Allows deduplicating the code in Sema.
This commit is contained in:
parent
aa4ac2f85f
commit
0048166867
@ -1576,15 +1576,23 @@ pub const Cpu = struct {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns whether this architecture supports the address space
|
/// Returns whether this architecture supports `address_space`. If `context` is `null`, this
|
||||||
pub fn supportsAddressSpace(arch: Arch, address_space: std.builtin.AddressSpace) bool {
|
/// function simply answers the general question of whether the architecture has any concept
|
||||||
|
/// of `address_space`; if non-`null`, the function additionally checks whether
|
||||||
|
/// `address_space` is valid in that context.
|
||||||
|
pub fn supportsAddressSpace(
|
||||||
|
arch: Arch,
|
||||||
|
address_space: std.builtin.AddressSpace,
|
||||||
|
context: ?std.builtin.AddressSpace.Context,
|
||||||
|
) bool {
|
||||||
const is_nvptx = arch.isNvptx();
|
const is_nvptx = arch.isNvptx();
|
||||||
const is_spirv = arch.isSpirV();
|
const is_spirv = arch.isSpirV();
|
||||||
const is_gpu = is_nvptx or is_spirv or arch == .amdgcn;
|
const is_gpu = is_nvptx or is_spirv or arch == .amdgcn;
|
||||||
return switch (address_space) {
|
return switch (address_space) {
|
||||||
.generic => true,
|
.generic => true,
|
||||||
.fs, .gs, .ss => arch == .x86_64 or arch == .x86,
|
.fs, .gs, .ss => (arch == .x86_64 or arch == .x86) and (context == null or context == .pointer),
|
||||||
.global, .constant, .local, .shared => is_gpu,
|
.global, .local, .shared => is_gpu,
|
||||||
|
.constant => is_gpu and (context == null or context == .constant),
|
||||||
.param => is_nvptx,
|
.param => is_nvptx,
|
||||||
.input, .output, .uniform, .push_constant, .storage_buffer => is_spirv,
|
.input, .output, .uniform, .push_constant, .storage_buffer => is_spirv,
|
||||||
// TODO this should also check how many flash banks the cpu has
|
// TODO this should also check how many flash banks the cpu has
|
||||||
|
|||||||
@ -491,6 +491,21 @@ pub const CallingConvention = union(enum(u8)) {
|
|||||||
/// This data structure is used by the Zig language code generation and
|
/// This data structure is used by the Zig language code generation and
|
||||||
/// therefore must be kept in sync with the compiler implementation.
|
/// therefore must be kept in sync with the compiler implementation.
|
||||||
pub const AddressSpace = enum(u5) {
|
pub const AddressSpace = enum(u5) {
|
||||||
|
/// The places where a user can specify an address space attribute
|
||||||
|
pub const Context = enum {
|
||||||
|
/// A function is specified to be placed in a certain address space.
|
||||||
|
function,
|
||||||
|
/// A (global) variable is specified to be placed in a certain address space.
|
||||||
|
/// In contrast to .constant, these values (and thus the address space they will be
|
||||||
|
/// placed in) are required to be mutable.
|
||||||
|
variable,
|
||||||
|
/// A (global) constant value is specified to be placed in a certain address space.
|
||||||
|
/// In contrast to .variable, values placed in this address space are not required to be mutable.
|
||||||
|
constant,
|
||||||
|
/// A pointer is ascripted to point into a certain address space.
|
||||||
|
pointer,
|
||||||
|
};
|
||||||
|
|
||||||
// CPU address spaces.
|
// CPU address spaces.
|
||||||
generic,
|
generic,
|
||||||
gs,
|
gs,
|
||||||
|
|||||||
48
src/Sema.zig
48
src/Sema.zig
@ -37220,30 +37220,12 @@ fn analyzeComptimeAlloc(
|
|||||||
} })));
|
} })));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The places where a user can specify an address space attribute
|
|
||||||
pub const AddressSpaceContext = enum {
|
|
||||||
/// A function is specified to be placed in a certain address space.
|
|
||||||
function,
|
|
||||||
|
|
||||||
/// A (global) variable is specified to be placed in a certain address space.
|
|
||||||
/// In contrast to .constant, these values (and thus the address space they will be
|
|
||||||
/// placed in) are required to be mutable.
|
|
||||||
variable,
|
|
||||||
|
|
||||||
/// A (global) constant value is specified to be placed in a certain address space.
|
|
||||||
/// In contrast to .variable, values placed in this address space are not required to be mutable.
|
|
||||||
constant,
|
|
||||||
|
|
||||||
/// A pointer is ascripted to point into a certain address space.
|
|
||||||
pointer,
|
|
||||||
};
|
|
||||||
|
|
||||||
fn resolveAddressSpace(
|
fn resolveAddressSpace(
|
||||||
sema: *Sema,
|
sema: *Sema,
|
||||||
block: *Block,
|
block: *Block,
|
||||||
src: LazySrcLoc,
|
src: LazySrcLoc,
|
||||||
zir_ref: Zir.Inst.Ref,
|
zir_ref: Zir.Inst.Ref,
|
||||||
ctx: AddressSpaceContext,
|
ctx: std.builtin.AddressSpace.Context,
|
||||||
) !std.builtin.AddressSpace {
|
) !std.builtin.AddressSpace {
|
||||||
const air_ref = try sema.resolveInst(zir_ref);
|
const air_ref = try sema.resolveInst(zir_ref);
|
||||||
return sema.analyzeAsAddressSpace(block, src, air_ref, ctx);
|
return sema.analyzeAsAddressSpace(block, src, air_ref, ctx);
|
||||||
@ -37254,7 +37236,7 @@ pub fn analyzeAsAddressSpace(
|
|||||||
block: *Block,
|
block: *Block,
|
||||||
src: LazySrcLoc,
|
src: LazySrcLoc,
|
||||||
air_ref: Air.Inst.Ref,
|
air_ref: Air.Inst.Ref,
|
||||||
ctx: AddressSpaceContext,
|
ctx: std.builtin.AddressSpace.Context,
|
||||||
) !std.builtin.AddressSpace {
|
) !std.builtin.AddressSpace {
|
||||||
const pt = sema.pt;
|
const pt = sema.pt;
|
||||||
const addrspace_ty = try sema.getBuiltinType(src, .AddressSpace);
|
const addrspace_ty = try sema.getBuiltinType(src, .AddressSpace);
|
||||||
@ -37264,29 +37246,7 @@ pub fn analyzeAsAddressSpace(
|
|||||||
const target = pt.zcu.getTarget();
|
const target = pt.zcu.getTarget();
|
||||||
const arch = target.cpu.arch;
|
const arch = target.cpu.arch;
|
||||||
|
|
||||||
const is_nv = arch.isNvptx();
|
if (!arch.supportsAddressSpace(address_space, ctx)) {
|
||||||
const is_amd = arch == .amdgcn;
|
|
||||||
const is_spirv = arch.isSpirV();
|
|
||||||
const is_gpu = is_nv or is_amd or is_spirv;
|
|
||||||
|
|
||||||
// TODO: Deduplicate with `std.Target.Cpu.Arch.supportsAddressSpace`.
|
|
||||||
const supported = switch (address_space) {
|
|
||||||
// TODO: on spir-v only when os is opencl.
|
|
||||||
.generic => true,
|
|
||||||
.gs, .fs, .ss => (arch == .x86 or arch == .x86_64) and ctx == .pointer,
|
|
||||||
// TODO: check that .shared and .local are left uninitialized
|
|
||||||
.param => is_nv,
|
|
||||||
.input, .output, .uniform, .push_constant, .storage_buffer => is_spirv,
|
|
||||||
.global, .shared, .local => is_gpu,
|
|
||||||
.constant => is_gpu and (ctx == .constant),
|
|
||||||
// TODO this should also check how many flash banks the cpu has
|
|
||||||
.flash, .flash1, .flash2, .flash3, .flash4, .flash5 => arch == .avr,
|
|
||||||
|
|
||||||
.cog, .hub => arch == .propeller,
|
|
||||||
.lut => arch == .propeller and std.Target.propeller.featureSetHas(target.cpu.features, .p2),
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!supported) {
|
|
||||||
// TODO error messages could be made more elaborate here
|
// TODO error messages could be made more elaborate here
|
||||||
const entity = switch (ctx) {
|
const entity = switch (ctx) {
|
||||||
.function => "functions",
|
.function => "functions",
|
||||||
@ -38728,7 +38688,7 @@ pub fn resolveNavPtrModifiers(
|
|||||||
};
|
};
|
||||||
|
|
||||||
const @"addrspace": std.builtin.AddressSpace = as: {
|
const @"addrspace": std.builtin.AddressSpace = as: {
|
||||||
const addrspace_ctx: Sema.AddressSpaceContext = switch (zir_decl.kind) {
|
const addrspace_ctx: std.builtin.AddressSpace.Context = switch (zir_decl.kind) {
|
||||||
.@"var" => .variable,
|
.@"var" => .variable,
|
||||||
else => switch (nav_ty.zigTypeTag(zcu)) {
|
else => switch (nav_ty.zigTypeTag(zcu)) {
|
||||||
.@"fn" => .function,
|
.@"fn" => .function,
|
||||||
|
|||||||
@ -444,10 +444,10 @@ pub fn addrSpaceCastIsValid(
|
|||||||
) bool {
|
) bool {
|
||||||
const arch = target.cpu.arch;
|
const arch = target.cpu.arch;
|
||||||
switch (arch) {
|
switch (arch) {
|
||||||
.x86_64, .x86 => return arch.supportsAddressSpace(from) and arch.supportsAddressSpace(to),
|
.x86_64, .x86 => return arch.supportsAddressSpace(from, null) and arch.supportsAddressSpace(to, null),
|
||||||
.nvptx64, .nvptx, .amdgcn => {
|
.nvptx64, .nvptx, .amdgcn => {
|
||||||
const to_generic = arch.supportsAddressSpace(from) and to == .generic;
|
const to_generic = arch.supportsAddressSpace(from, null) and to == .generic;
|
||||||
const from_generic = arch.supportsAddressSpace(to) and from == .generic;
|
const from_generic = arch.supportsAddressSpace(to, null) and from == .generic;
|
||||||
return to_generic or from_generic;
|
return to_generic or from_generic;
|
||||||
},
|
},
|
||||||
else => return from == .generic and to == .generic,
|
else => return from == .generic and to == .generic,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user