This is an archive of the discontinued LLVM Phabricator instance.

[OpenCL] Add support of language builtins for OpenCL C 3.0
ClosedPublic

Authored by azabaznov on Jan 31 2022, 7:12 AM.

Details

Summary

OpenCL C 3.0 introduces optionality to some builtins, in particularly
to those which are conditionally supported with pipe, device enqueue
and generic address space features.

The idea is to conditionally support such builtins depending on the language options
being set for a certain feature. This allows users to define functions with names
of those optional builtins in OpenCL (as such names are not reserved).

Diff Detail

Event Timeline

azabaznov created this revision.Jan 31 2022, 7:12 AM
azabaznov requested review of this revision.Jan 31 2022, 7:12 AM
Herald added a project: Restricted Project. · View Herald Transcript
azabaznov updated this revision to Diff 404511.Jan 31 2022, 7:14 AM

Remove no longer required comment in the test.

Anastasia added inline comments.Jan 31 2022, 9:04 AM
clang/include/clang/Basic/Builtins.def
88

It might be better to avoid adding such limited language-specific functionality into generic representation of Builtins. Do you think could we could just introduce specific language modes, say:

OCLC_PIPES
OCLC_DSE
OCLC_GAS

and then check against those in builtinIsSupported?

Anastasia added inline comments.Feb 1 2022, 4:55 AM
clang/include/clang/Basic/Builtins.def
88

Btw another approach could be to do something similar to TARGET_BUILTIN i.e. list features in the last parameter as strings. We could add a separate macro for such builtins and just reuse target Builtins flow. This might be a bit more scalable in case we would need to add more of such builtins later on?

azabaznov added inline comments.Feb 1 2022, 5:52 AM
clang/include/clang/Basic/Builtins.def
88

It might be better to avoid adding such limited language-specific functionality into generic representation of Builtins.

Nice idea! Though I think LanguageID is not designed to be used this way, it's used only to check against specific language version. So it seems pretty invasive. Also, function attributes seem more natural to me to specify the type of the function. I don't know for sure which way is better...

Btw another approach could be to do something similar to TARGET_BUILTIN i.e. list features in the last parameter as strings.

I'd prefer to not use TARGET_BUILTIN as it operates on target feature, but OpenCL feature is some other concept in clang...

Anastasia added inline comments.Feb 1 2022, 8:15 AM
clang/include/clang/Basic/Builtins.def
88

Buitlins handling is pretty vital for clang so if we extend common functionality for just a few built-in functions it might not justify the overhead in terms of complexity, parsing time or space... so we would need to dive in those aspects more before finalizing the design... if we can avoid it we should try... and I feel in this case there might be some good ways to avoid it.

Nice idea! Though I think LanguageID is not designed to be used this way, it's used only to check against specific language version. So it seems pretty invasive. Also, function attributes seem more natural to me to specify the type of the function. I don't know for sure which way is better...

I think this LanguageID is only used for the purposes of Builtins, so there should be no issue in evolving it differently. With the documentation and adequate naming we can resolve the confusions in any.

The whole idea of language options in clang is that it is not dependent on the target. But we have violated this design already. The whole concept of OpenCL 3.0 language features that are target-specific is misaligned with the original design in clang.

Btw another approach could be to do something similar to TARGET_BUILTIN i.e. list features in the last parameter as strings.

I'd prefer to not use TARGET_BUILTIN as it operates on target feature, but OpenCL feature is some other concept in clang...

But we also have target features mirroring these, right? So I see no reason not to reuse what we already have... instead of adding another way to do the same or very similar thing...

We could also consider extending the functionality slightly to use language features instead however I can't see the immediate benefit at this point... other than it might be useful in the future... but we can't know for sure.

azabaznov added inline comments.Feb 2 2022, 1:53 AM
clang/include/clang/Basic/Builtins.def
88

Buitlins handling is pretty vital for clang so if we extend common functionality for just a few built-in functions it might not justify the overhead in terms of complexity, parsing time or space... so we would need to dive in those aspects more before finalizing the design... if we can avoid it we should try... and I feel in this case there might be some good ways to avoid it.

Nice idea! Though I think LanguageID is not designed to be used this way, it's used only to check against specific >?language version. So it seems pretty invasive. Also, function attributes seem more natural to me to specify the type of the function. I don't know for sure which way is better...

I think this LanguageID is only used for the purposes of Builtins, so there should be no issue in evolving it differently. With the documentation and adequate naming we can resolve the confusions in any.

So yeah, I think reusing LanguageID is pretty doable and sounds like a good idea.

The whole idea of language options in clang is that it is not dependent on the target. But we have violated this design already. The whole concept of OpenCL 3.0 language features that are target-specific is misaligned with the original design in clang.

Btw another approach could be to do something similar to TARGET_BUILTIN i.e. list features in the last parameter as strings.

I'd prefer to not use TARGET_BUILTIN as it operates on target feature, but OpenCL feature is some other concept in clang...

But we also have target features mirroring these, right? So I see no reason not to reuse what we already have... instead of adding another way to do the same or very similar thing...

We could also consider extending the functionality slightly to use language features instead however I can't see the immediate benefit at this point... other than it might be useful in the future... but we can't know for sure.

The whole problem is that features used by TARGET_BUILTIN are defined by targets in llvm, for example avx512vl in X86. So making each target to define, for example, __opencl_c_device_enqueue is not possible. The other approach might be to outline the list of common subtarget features shared by all targets, which is also not a good solution (despite the fact that there are already some of those), but OpenCL features would fit into such concept.

We discussed this a lot, but IMO OpenCL features are more about the language, not about the target. For example, target might not support fp64, but __opencl_c_fp64 is supported so target can emulate fp64 (not a good example, but I imagine this is possible). With this fact given, I thing LANGBUILTIN fits better here then TARGET_BUILTIN.

azabaznov updated this revision to Diff 405921.Feb 4 2022, 4:25 AM

Reimplement with checking language options only.

azabaznov marked 3 inline comments as done.Feb 4 2022, 4:26 AM
Anastasia added inline comments.Feb 4 2022, 7:33 AM
clang/include/clang/Basic/Builtins.h
39

I am thinking that we probably don't need this combined mode now... I think it is enough to just have GAS, PIPES and BLOCKS separately. Then in Builtin::Context::builtinIsSupported we will have 3 separate checks against LangOpts.OpenCLGenericAddressSpace, LangOpts.OpenCLPipes and LangOpts.Blocks as they can be used for both OpenCL 2.0 and OpenCL 3.0. This could simplify this list.

Then we can also remove OCL2P_WITH_GAS, OCL2P_WITH_PIPES and OCL2P_WITH_BLOCKS.

40

Btw is this field needed? I can't see any builtins that are using this... If it's unused we should just remove this entry.

43

let's use OCL_BLOCKS since enqueue_kernel, etc are OpenCL-only builtins.

51

For consistency ALL_OCLC_LANGUAGES -> ALL_OCL_LANGUAGES

azabaznov updated this revision to Diff 406434.Feb 7 2022, 6:38 AM

Check only against specific language option, remove unused LanguageIDs

azabaznov marked 4 inline comments as done.Feb 7 2022, 6:40 AM
azabaznov added inline comments.
clang/lib/Basic/Builtins.cpp
79

This check is needed as -cl-std=CL1.2 can be used together with -fblocks. But in 3.0 block support requires __opencl_c_device_enqueue feature.

@Anastasia @svenvh ping. Just a kind reminder.

svenvh added inline comments.Feb 9 2022, 6:37 AM
clang/include/clang/Basic/Builtins.def
88

Nice idea! Though I think LanguageID is not designed to be used this way, it's used only to check against specific language version. So it seems pretty invasive. Also, function attributes seem more natural to me to specify the type of the function. I don't know for sure which way is better...

I think this LanguageID is only used for the purposes of Builtins, so there should be no issue in evolving it differently. With the documentation and adequate naming we can resolve the confusions in any.

OCL_GAS could be considered as a different language mode, namely it's the "OpenCL + Generic Addrspace" language mode. But it might be worth asking someone outside of the OpenCL community whether it's desirable to use the LanguageID enum in this way.

clang/lib/Basic/Builtins.cpp
79

This check is needed as -cl-std=CL1.2 can be used together with -fblocks.

That surprised me, I cannot find anything in the OpenCL 1.2 spec about this. @Anastasia do you know if this is an (undocumented?) Clang extension?

There are tests checking for this (e.g. clang/test/Frontend/opencl.cl), so we need this check to preserve the existing behavior indeed.

Anastasia added inline comments.Feb 10 2022, 2:39 AM
clang/lib/Basic/Builtins.cpp
79

I think blocks is a clang language feature that can be enabled using -fblocks and activate extra functionality of blocks used as lambda only in C-based languages. But the enqueue_kernel is only supported from OpenCL 2.0 onwards since it requires functionality outside of frontend so I think this check is reasonable. I feel perhaps we should rename to something like:

OCL_BLOCKS -> OCL_KERNEL_ENQUEUE or OCL_DSE?

Since the builtins are not about blocks but about enqueueing kernels from device...

Also I would suggest a comment explaining that we check for Blocks because it is coupled with enqueue kernel functionality.

azabaznov updated this revision to Diff 407823.Feb 11 2022, 3:08 AM

Rename language mode for device side enqueue builtins; add the comment that device side enqueue builtins are not supported until OpenCL 2.0.

azabaznov marked an inline comment as done.Feb 11 2022, 3:08 AM

There are tests checking for this (e.g. clang/test/Frontend/opencl.cl), so we need this check to preserve the existing behavior indeed.

Thanks. The other test is SemaOpenCL/clang-builtin-version.cl.

But it might be worth asking someone outside of the OpenCL community whether it's desirable to use the LanguageID enum in this way.

I personally think this looks good now, for OpenCL in particularly, as it became version-agnostic (except for DSE). But we still are querying language options only, and we expect language options for generic AS, pipes and DSE to be immutable at this point.

There are tests checking for this (e.g. clang/test/Frontend/opencl.cl), so we need this check to preserve the existing behavior indeed.

Thanks. The other test is SemaOpenCL/clang-builtin-version.cl.

But it might be worth asking someone outside of the OpenCL community whether it's desirable to use the LanguageID enum in this way.

I personally think this looks good now, for OpenCL in particularly, as it became version-agnostic (except for DSE). But we still are querying language options only, and we expect language options for generic AS, pipes and DSE to be immutable at this point.

Note that this LanguageID is intended for Builtins use because there are other LanguageIDs used elsewhere.

Anastasia accepted this revision.Feb 11 2022, 4:49 AM

LGTM! Thanks

This revision is now accepted and ready to land.Feb 11 2022, 4:49 AM

There are tests checking for this (e.g. clang/test/Frontend/opencl.cl), so we need this check to preserve the existing behavior indeed.

Thanks. The other test is SemaOpenCL/clang-builtin-version.cl.

But it might be worth asking someone outside of the OpenCL community whether it's desirable to use the LanguageID enum in this way.

I personally think this looks good now, for OpenCL in particularly, as it became version-agnostic (except for DSE). But we still are querying language options only, and we expect language options for generic AS, pipes and DSE to be immutable at this point.

Note that this LanguageID is intended for Builtins use because there are other LanguageIDs used elsewhere.

Fair enough. Just in case someone disagrees, there's always the option of giving the builtins a reserved name and providing a macro in opencl-c-base.h that maps the real name to the builtin, conditionalized on feature macros. But macros have the drawback of less beautiful diagnostics, so if nobody objects we should keep what we have done currently I think.