[cfe-dev] OpenCL and Type Poisoning

Peter Collingbourne peter at pcc.me.uk
Wed Jan 26 11:07:00 PST 2011


On Wed, Jan 26, 2011 at 09:02:45AM +0100, Speziale Ettore wrote:
> I have tried to implement an "openlcl_kernel_poison" pragma, but I've
> seen that the pragma construct is too far from what I want to do. Thus,
> I've tried to implement the same think with an attribute:
> 
> typedef long size_t __attribute__((opencl_kernel_poison));
> 
> kernel void foo(size_t err); // The diagnostic is issued here
> 
> While handling "opencl_kernel_function" attribute (code from Anton's
> patch), I recursively walk the typedef chain looking for declaration
> marked with the "opencl_kernel_poision" attribute. This seems working,
> however I don't think this to be the right solution.
> 
> >From my point of view, the "opencl_kernel_poison" attribute can be
> generalized to a "type_poison" attribute. It can be applied to any type
> declararation, marking the defined type poisoned. It should be handled
> like a type attribute, (e.g. "address_space"), and stored inside the
> clang::Qualifiers class as an extended qualifiers (There should be a
> free bit in clang::Qualifiers::Mask).
>
> Using this approach, detecting whether a type is poisoned is
> straighforward.

The concept of a poisoned type is distinct from a kernel poisoned
type.  Kernel poisoned types are in fact allowed anywhere in an
OpenCL program except in one specific place, namely parameter types
of __kernel functions.  So a general concept of type poisoning does
not seem useful for an OpenCL implementation.

Also, I don't know if it's a good idea to store this attribute as
a qualifier bit.  The attribute doesn't affect the semantics of
the program beyond the semantic analysis stage, so it's not really
necessary to allocate a bit for it.

Instead, we can store the attribute on the typedef and use
a generic convenience function for non-canonical types which
walks the chain testing for the presence of a specific attribute.
Maybe something like this (Type member function):

template <typename T> T *getTypedefAttr() {
  Type *T = this;
  while (TypedefType *TT = T->getAs<TypedefType>()) {
    TypedefDecl *TD = TT->getDecl();
    if (T *A = TD->getAttr<T>())
      return A;
    T = TD->getUnderlyingType();
  }
  return 0;
}

Then in the trivial case, we can use
T->getTypedefAttr<OpenCLKernelPoisonAttr>()
to test for the attribute.

> I don't known if that attribute can be usefull also for aggregated
> types:
> 
> typedef long size_t __attribute__((type_poison))__;
> 
> struct err_1 {
>   size_t err_2;
> };
> 
> The struct err_1 should also be poisoned.

Perhaps.  The OpenCL spec doesn't seem to say anything either way
about this, but it seems reasonable to disallow it for the reasons
given in the spec (and perhaps propose this restriction for a later
version of the spec).  Likewise pointers to poisoned types, I think.

Thanks,
-- 
Peter



More information about the cfe-dev mailing list