Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[libclc] Support the generic address space #137183

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

frasercrmck
Copy link
Contributor

This commit provides definitions of builtins with the generic address space.

It is assumed that all current libclc targets can support the generic address space.

One concept to consider is the difference between supporting the generic address space from the user's perspective and the requirement for libclc as a compiler implementation detail to define separate generic address space builtins. In practice a target (like NVPTX) might notionally support the generic address space, but it's mapped to the same LLVM target address space as another address space (often the private one).

In such cases libclc must be careful not to define both private and generic overloads of the same builtin. We track these two concepts separately, and make the assumption that if the generic address space does clash with another, it's with the private one. We track the concepts separately because there are some builtins such as atomics that are defined for the generic address space but not the private address space.

@frasercrmck frasercrmck added the libclc libclc OpenCL library label Apr 24, 2025
@frasercrmck frasercrmck requested a review from arsenm April 24, 2025 14:26
@frasercrmck
Copy link
Contributor Author

CC @wenju-he

Copy link
Contributor

@arsenm arsenm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even as a compiler implementation detail, libclc should not need to consider the address space mapping (unless maybe you're directly using IR)

There is a clang bug if there is different mangling. The itanium mangling should be coming from the source type / original address space, not whatever IR address space value that happens to map to

@frasercrmck
Copy link
Contributor Author

There is a clang bug if there is different mangling. The itanium mangling should be coming from the source type / original address space, not whatever IR address space value that happens to map to

Yeah, that would be nice but this is what's happening, I'm afraid.

It is actually supported in the Itanium mangler:

    if (Context.getASTContext().addressSpaceMapManglingFor(AS)) {
      //  <target-addrspace> ::= "AS" <address-space-number>
      unsigned TargetAS = Context.getASTContext().getTargetAddressSpace(AS);
      if (TargetAS != 0 ||
          Context.getASTContext().getTargetAddressSpace(LangAS::Default) != 0)
        ASString = "AS" + llvm::utostr(TargetAS);
    } else {
      switch (AS) {
      default: llvm_unreachable("Not a language specific address space");
      //  <OpenCL-addrspace> ::= "CL" [ "global" | "local" | "constant" |
      //                                "private"| "generic" | "device" |
      //                                "host" ]
      case LangAS::opencl_global:
        ASString = "CLglobal";
        break;

It's just that targets we care about in libclc unconditionally enable that address space map mangling for all address spaces, such as AMDGPU and NVPTX.

I'm not sure I would want to change this behaviour at this point. At least not for the purposes of enabling generic address space support in libclc. There will be a bunch of downstream toolchains that rely on the current mangling scheme.

@arsenm
Copy link
Contributor

arsenm commented Apr 24, 2025

It is actually supported in the Itanium mangler:

I don't remember this part of the hack. There was a recent fix to always use the correct mapping values for AMDGPU when generic address space is enabled (which should be the only mapping, still need to do something about the setAddressSpaceMap hack).

Comment on lines +441 to +442
# FIXME: Shouldn't clang automatically enable this extension based on the
# target?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the extension should be reported as available or not by the target macros

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should enable __opencl_c_generic_address_space for amdgpu and nvptx in setSupportedOpenCLOpts API rather than in this CMakeLists file, right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes (although for amdgpu it needs to skip the ancient targets without flat addressing)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the first PR for AMDGPU support: #137636.

I'll do a separate one for NVPTX. It looks like SPIRV (and X86) enable all by default. That should cover all libclc targets.

Comment on lines +32 to +37
#ifdef __CLC_DISTINCT_GENERIC_ADDRSPACE__
#define _CLC_DISTINCT_GENERIC_AS_SUPPORTED 1
#else
#define _CLC_DISTINCT_GENERIC_AS_SUPPORTED 0
#endif
#else
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These macro names are too general for the implementation. I don't think this works for anything other than the 0-is-private-and-generic case.

What if you defined a qualifier macro with the value, and check if they are equal

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These macro names are too general for the implementation. I don't think this works for anything other than the 0-is-private-and-generic case.

Yes the assumption is very much currently that it's either fully distinct or 0-is-both. I didn't know how much effort to put into making it fully flexible given our list of targets is fairly static.

I'd be open to making it more flexible. I don't think there's anything technically stopping a target having two or more of constant, local and global mangle to the same target address space, for example. Do we want something in libclc that can take care of all possibilities, or just the generic space with another?

What if you defined a qualifier macro with the value, and check if they are equal

Could you expand on this, sorry?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean something like

#define __libclc_generic_addrspace_val 0
#define __libclc_private_addrspace_val 5

#if __libclc_private_addrspace_val == __libclc_generic_addrspace_val
// ...
#endif

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even if not this, the current name is misleading. It's not about generic being supported, if anything it's more like private isn't real

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, something like that. Thanks for clarifying, I was half wondering if you meant adding some new macro definition to clang itself.

I am a bit hesitant to encode actual address space values in libclc as it's ultimately up to clang (and may differ depending on the subtarget/CPU), but either way unless clang gives us more information we have to encode some kind of assumption in libclc. Having some kind of introspection available about the address space mappings would be nice but overkill.

It looks like every target uses private = 0 except for AMDGPU which has private = 5. For generic we have mostly 0 too, except for DirectX and SPIR (which I think influences SPIRV?) which use 4. It's doable using some preprocessorr logic, or some defs passed in from CMake as build options, but I'd worry a bit about it getting out of sync with the actual compiler.

I think the macro could definitely be better worded to include the assumption of "private". Something along the lines of GENERIC_IS_(NOT_)PRIVATE or whatever. Ultimately this only applies to NVPTX so there's also the possibility of using the NVPTX target rather than trying to come up with something general. At least if anything goes wrong it would fail at build time.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is ultimately a clang bug. The two functions are different symbols. addressSpaceMapManglingFor shouldn't be reporting true in the colliding cases

This commit provides definitions of builtins with the generic address
space.

It is assumed that all current libclc targets can support the generic
address space.

One concept to consider is the difference between supporting the generic
address space from the user's perspective, and the requirement for
libclc as a compiler implementation detail to define separate generic
address space builtins. In practice a target (like NVPTX) might
notionally support the generic address space, but it's mapped to the
same LLVM target address space as the private address space. Therefore
libclc may not define both private and generic overloads of the same
builtin. We track these two concepts separately, and make the assumption
that if the generic address space does clash with another, it's with the
private one.
@frasercrmck frasercrmck force-pushed the libclc-generic-addrspace branch from b437f11 to 694166d Compare April 29, 2025 16:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libclc libclc OpenCL library
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants