[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