[RFC][OpenCL] Rename OpenCL opaque types in LLVM IR from opencl.* to __opencl_*

Currently OpenCL opaque types have name opencl.* in LLVM IR, which causes difficulty for library developers who need to implement the concrete types corresponding to the opaque types.

For example, read_only image2d_t type is translated to opencl.image2d_ro_t addrspace(1)* in LLVM IR. Ideally, a library developer would implement a concreate struct type with name opencl.image2d_ro_t and access its members. However, due to the '.', 'opencl.image2d_ro_t' is not a valid identifier in OpenCL C language, library developers cannot use it as the name of the concrete struct type for image2d_t. Bitcasts have to be introduced, which causes extra efforts in backends.

Due to this reason, we would like to propose renaming OpenCL opaque types in LLVM IR from opencl.* to __opencl_*.

This change will make the IR deviate from SPIR spec. However, considering there is simple rule to map this new name to SPIR defined name, and LLVM IR currently generated by Clang has already been deviated from SPIR spec, a SPIR consumer should be able to accommodate this change if it is able to accommodate existing deviations.

Your feedbacks are welcome. Thanks.

Sam

Sounds good to me!

Thanks,

Anastasia

Hi Sam,

I want to clarify the use case.

The intension is to allow library developer redefining OpenCL images types in a library written in OpenCL C and prefix starting with double underscore is supposed to protect the library image types definitions from redefinition by user.

The change you are proposing is to rename image opaque types in LLVM IR, without making them concrete.

Am I getting it right?

Wouldn’t types defined by library developer prefixed with ‘struct.’? Shouldn’t clang create opaque types with ‘struct._opencl’ prefix instead to match the type names defined by library developer?

You are right. It should be struct._opencl prefix.

Sam

In this case I am not sure it’s generic enough to assume that those types are always mapped to some struct.

Perhaps, we should stay with the conversion?

Anastasia

In LLVM, the OpenCL opaque types are already represented as an opaque struct type since only struct types can have name. This proposal does not change that, it only changes the name of the struct type to be accessible in the OpenCL source code.

Besides, Clang does not allow OpenCL opaque types such as sampler and image types to be explicitly casted to other types.

Sam

Right, what I mean is that OpenCL types are now generated by Clang as unknown opaque types identified by their name in LLVM. Unfortunately LLVM is missing proper type support for OpenCL, therefore we have this issue. But adding “struct.” prefix might imply that this has to be a struct. Clang uses “struct.” prefix as a naming convention for generated C struct types in LLVM.

Implementation should however have freedom to use OpenCL opaque types differently to struct (we don’t force it to be anything). I don’t think adding a struct prefix to the OpenCL opaque type names in LLVM is a good idea as it adds some confusion about their representation.

Cheers,

Anastasia

Clang does not allow casting OpenCL opaque types to any other types. For example,

$ cat test3.cl

void f(sampler_t s) {

void q = (void) s;

char p = (char) s;

}

$ bin/clang -cc1 test3.cl

test3.cl:2:21: error: operand of type ‘sampler_t’ where arithmetic or pointer type is required

void q = (void) s;

^

test3.cl:3:21: error: operand of type ‘sampler_t’ where arithmetic or pointer type is required

char p = (char) s;

^

2 errors generated.

That makes sense since allowing OpenCL opaque types to be casted to other types potentially can cause lots of issues and needs more checks.

Then I don’t know how representing OpenCL opaque type as a non-struct type would work.

On the other hand, any type can be easily packaged in a struct type. What we need is a struct name that can be used by a common OpenCL source code.

Sam

Hi Sam,

From the practical perspective I don’t disagree with your approach. Logically, however, OpenCL types aren’t intended to be struct or any existing LLVM type. The implementation of backend doesn’t work on OpenCL source level, and therefore can take different approach than the implementation that you are proposing here. One way is for example to transform those types to something that hardware architecture supports natively.

Cheers,

Anastasia

Hi Sam,

You can cast OpenCL image types to pointer type using __builtin_astype function.

void f(read_only image2d_t s) {

void q = __builtin_astype(s, void);

void p = __builtin_astype(s, char);

}

I think this approach will work for sampler type too.

Yes, I think casting is the most reasonable solution. Sam could you explain what issue do you have with it? I am guessing bitcast shouldn’t affect performance of the compiled code as it’s mainly a semantic node which is optimised out.

Anastasia

I did not realize that __builtin_astype can be used for this. Thanks Alexey.

For now I will drop this RFC unless I encounter further issues with this approach.

Thanks.

Sam

I noticed we use different naming scheme for OpenCL types while generating debug info in CGDebugInfo.cpp, which is “opencl_*”. I think we should make this consistent across CodeGen components.

Cheers,

Anastasia

You mean changing the name of OpenCL types in debug info from ‘opencl_’ to ‘opencl.’ to match the names used in LLVM IR?

Sam

Exactly, I think we should make it consistent.

The debug information is for user to view the type of a variable when executing the program, and the LLVM type name is only used during compilation. Do they really need to be the same? Also changing debug info may break debugger.

Sam

How will it break the debugger?

I don’t think having two different naming schemes for the same thing helps anyone.

Anastasia

Just guessing. If they have code relying on the opencl type names.

I do not have strong opinion on this.

Sam