OpenCL Address Spaces and Runtimes

Hi,

I wrote this mail to ask about how OpenCL specific address spaces should
be mapped to the llvm intermediate bitcode.

Currently, in clang it is possible to attach to variables OpenCL
specific address spaces. While parsing, a language specific address
space is attached to the variable base type:

global int *a;

inside clang becomes

__attribute__((address_space(16776960))) int *a;

When the AST is translated to llvm representation, the language specific
address space is translated to the corresponding address space in the
target machine. We loss any information about language specific address
spaces.

I am currently implementing a small OpenCL runtime. I have adopted llvm
as intermediate representation, because I expect to manage multiple
devices.

The OpenCL program can be built using two OpenCL runtime api:

clBuildProgramWithSources
clBuildProgramWithBinaries

I have implemented the first such that an LLVM module is generated. I
expect to implement the second by simply de-serializing an LLVM BC
stream.

OpenCL kernels are located exploiting the "opencl.kernels" module
metadata. In order to properly analyze kernels, I also need to know
which kernel parameters points to global/local/constant address spaces.

Collecting this info is not possible, with current implementation,
because we lose language specific address spaces. These info are
mandatory for implementing some OpenCL devices. As an example, the X86
architecture does not define OpenCL specific address spaces, thus
analyzing kernel signature is not possible to derive which kernel
pointer arguments should reference global or local OpenCL address space,
and thus properly be set.

For this reason, I would like to add other OpenCL specific metadata in
order to detect the referenced OpenCL address space. Such kind of
metadata would also be useful to define some OpenCL specific
optimization passes.

I propose the following metadata extension:

1) add 4 metadata to keep in the llvm bit code the OpenCL logical
   address space number; this allows to be independent on clang target
   mapping definitions

!opencl.global_address_space = !{!1}
!opencl.local_address_space = !{!2}
!opencl.constant_address_space = !{!3}
!opencl.invalid_address_space = !{!4}

!1 = metadata !{i32 16776960}
!2 = metadata !{i32 16776961}
!3 = metadata !{i32 16776962}
!4 = metadata !{i32 -1}

2) given a kernel k, add to k metadata the address space pointed by
   each argument. If an argument is not a pointer, use the invalid
   address space number

!opencl.kernels = !{!0}

!0 = !{void (i32 addrspace(1)*, i32)* @foo,
       metadata !{!1}, ; Indirected (A)
       metadata !{i32 -1} ; Directed (B)
      }

The languages specific address space associated with the i-th kernel k
argument is the i + 1 metadata of k. I do not know which metadata
representation ((A) or (B)) inside k metadata is the best.

What do you think?

Thank you for your attention,
speziale.ettore@gmail.com

PS: I explicitly do not mention OpenCL local variables, because they are
currently not handled by clang.

I asked about whether OpenCL backends would possibly need this
information and was informed that they wouldn't. If that's not true, then
we should move to a different representation, like a normal decl
attribute instead of a type attribute.

John.

Hi,

I asked about whether OpenCL backends would possibly need this
information and was informed that they wouldn't. If that's not true, then
we should move to a different representation, like a normal decl
attribute instead of a type attribute.

I think the most important thing should be consistency. Since it has
been chosen to exploit metadata to keep kernel information inside llvm
bitcode, a similar approach must be used to keep information about
address spaces.

Path attached, with minor edits with respect to the proposed approach.
Comments are welcome.

Best regards,
speziale.ettore@gmail.com

address-spaces-metadata.patch (3.87 KB)

test.cl (99 Bytes)

test.ll (929 Bytes)