Description
Since SYCL is focusing on heterogeneous computing and bare-metal efficiency in modern C++, it will require a lot of extensions in Clang/LLVM under the hood, such as vendor-specific built-ins, decorations, attributes...
A good example is fbffaab and obviously we need FPGA extensions. :-)
This is a very good example of the kinds of information we need to carry.
But these extensions are difficult to maintain in a fork with all the merge conflicts or even to be accepted upstream just because of their narrow use-case. So we should think about a way to express in a generic way in Clang/LLVM some attributes, intrinsics, etc.
It would be nice to be able to declare some C++ constructions that abstracts in a nice way the extensions, for example with new types, decorator functions, properties... These constructions at the C++ level would be defined in an extension-specific header, using intrinsic functions or some kind of decoration.
If the back-end is using some "pseudo-intrinsics" (user-defined functions that behaves like intrinsics from the back-end point-of-view), it seems rather easy. You can see an implementation example under https://github.com/triSYCL/triSYCL/tree/master/include/CL/sycl/vendor/Xilinx
But this does not work to decorate other things like types...
Some languages like D have the concept of user-defined attributes https://dlang.org/spec/attribute.html#uda with some introspection mechanism which could serve as a source of inspiration. But it does not provide some way to synthesize some kinds of internal IR decorations.
C++ it-self has the concept of attributes since C++11 https://en.cppreference.com/w/cpp/language/attributes but there is no generic way to implement them into Clang/LLVM as far as I know.
Now we have contracts in C++20, there are 3 new attributes https://en.cppreference.com/w/cpp/language/attributes/contract which do use a C++ expression, so we have at least a source of inspiration about how to implement some part of the mechanic to access to expressions, and indirectly to types through the typeid()
operator.
A first approach could be to introduce a new Clang über-attribute able to implement everything with a small DSL. For example
[[ using clang::attribute::generic :
llvm::function::attribute::inaccessiblememonly,
llvm::function::attribute::builtin,
llvm::function::attribute::convergent,
llvm::function::attribute::noduplicate,
llvm::function::attribute::alignstack(4),
llvm::metadata::callees(f, g),
llvm::metadata::loop::distribute::enable ]]
Would allow to synthesize some specific metadata https://llvm.org/docs/LangRef.html#metadata,
There is already such a DSL in C/C++ compilers for decades to deal with extensions like inline assembler expressions, see https://llvm.org/docs/LangRef.html#inline-assembler-expressions for example.
This could be a RFC for the Clang mailing list.
What do you think?