[cfe-dev] Ideas for enabling builtin fucntions to accept non-zero address spaces
Philip Reames
listmail at philipreames.com
Tue Mar 3 10:24:06 PST 2015
On 03/03/2015 08:55 AM, Tom Stellard wrote:
> Hi,
>
> I'm looking for suggestions for how to get builtin functions to accept pointers
> with non-zero address spaces. The reason I would like to do this is
> so I can use __builtin_nanf() from OpenCL C.
>
> This currently does not work, because in OpenCL all string literals are
> stored in the constant address space. For example:
>
> kernel void test(global float* out) {
> out[0] = __builtin_nanf("");
> }
>
> test.cl:3:27: error: passing '__constant char *' to parameter of type
> 'const char *' changes address space of pointer
>
>
> So far I have had two ideas. The first was this:
>
> --- a/include/clang/AST/Type.h
> +++ b/include/clang/AST/Type.h
> @@ -422,7 +422,7 @@ public:
> /// Generally this answers the question of whether an object with the
> //other
> /// qualifiers can be safely used as an object with these qualifiers.
> bool compatiblyIncludes(Qualifiers other) const {
> - return isAddressSpaceSupersetOf(other) &&
> + return (!hasAddressSpace() || isAddressSpaceSupersetOf(other)) &&
> // ObjC GC qualifiers can match, be added, or be removed,
> // but can't
> // be changed.
> (getObjCGCAttr() == other.getObjCGCAttr() || !hasObjCGCAttr() ||
>
>
>
> This intention of this change was to make it so that pointer types with no
> address space qualifier are considered compatible to pointers with
> address space qualifiers. This fixed my example, but broke
> several existing address space tests.
>
>
> The second idea I had was to create a FunctionDecl for the builtin which
> matched the arguments used in the CallExpr. This would have the effect
> of creating an overloaded version of the builtin with the correct
> address space on the fly. I thought I could do this in
> Sema::LazilyCreateBuiltin(), but I couldn't figure out how to get
> a reference to the CallExpr that triggered the FunctionDecl to be
> created.
>
>
> Do either of these approaches make sense? Does anyone have a better
> idea for implementing this?
The idea of having a marker for a function which is generic w.r.t. the
address space of a particular pointer has come up before. It would be
generally useful, but isn't the simplest thing in the world to create.
We already have a bit of hacked generics mechanism used when defining
intrinsics. (It's implemented by mangling the types into a suffix for
the intrinsic name.) You could extend the "llvm_anyptr_ty" to handle
address spaces, or introduce a new "llvm_asany_ty" with semantics that
allow a single specified type, but any address space. (see
IR/Intriniscs.td and Function.cpp for implementation)
I could be argued around to the idea that we need to support a generic
address space mechanism in the IR. This can't be done by overloading an
existing address space; that would break existing users. We could add a
new keyword to the language. Something like "type
addrspace(generic)*". We'd then have to implement a templating engine
to specialize these based on call types. This is effectively just a
slight generalization of the intrinsics only approach mentioned above.
p.s. I can't help with the clang code structure issues. I don't know
that code at all. :)
Philip
More information about the cfe-dev
mailing list