Question about stripping address-space qualifier with C++

Hi all,

I am looking for some ways to strip address-space qualifiers with C++ from clang. I think we can use the 'addrspacecast' instruction to do it in IR level. Before doing it in an IR pass, I would like to try to do it with clang. But I can not find some ways to strip it with C++ source code from clang or generate 'addrspacecast' instructions with C++ from clang. Is there some C++ syntax to do it such as reinterpret_cast? If you have some ideas, please let me know.

Thanks,
JinGu Kang

What is the overall problem you are trying to solve? In general,
adress space casts either generate no code (no problem) or will modify
the behaviour of the code (necessary for correct operation). I don't
see much point in fixing the former, and breaking things by "fixing"
the latter doesn't seem like a brilliant idea either...

Can you give an example of C++ code that uses address space casts, and
that you want to remove them in?

(Caveat, I work on OpenCL, and we do use address space casts quite a bit)

Hi Mats,

We are also working on OpenCL. We have implemented some of OpenCL functions using clang's builtin functions. For example,

int atomic_or(volatile int local * p, int val) { return atomic_or(p, val); }
...
int atomic_max(volatile int global * p, int val) { return atomic_max(p, val); }
int atomic_max(volatile uint global * p, uint val) { return atomic_max(p, val); }
...

template <typename P, typename T>
T atomic_or(P p, const T t) {
   return __sync_fetch_and_or(p, t);
}

template <typename P, typename T>
int atomic_max(volatile int global *p, const int t) {
   if (__is_signedof(T))
     return __sync_fetch_and_max(reinterpret_cast<volatile T *>(p), t);
   else
     return __sync_fetch_and_umax(reinterpret_cast<volatile T *>(p), t);
}

'__sync_fetch_and_or' and '__sync_fetch_and_[u]max' function's prototypes are as follows:
BUILTIN(__sync_fetch_and_or, "v.", "t")
...
BUILTIN(__sync_fetch_and_min, "iiD*i", "n")
BUILTIN(__sync_fetch_and_max, "iiD*i", "n")
BUILTIN(__sync_fetch_and_umin, "UiUiD*Ui", "n")
BUILTIN(__sync_fetch_and_umax, "UiUiD*Ui", "n")

If builtin functions use custom type checking like '__sync_fetch_and_or', it is not problem. But we should match the function prototype in other cases like '__sync_fetch_and_max'. So we need to strip address space qualifier In order to call '__sync_fetch_and_max' function.

I think it depends on just only our implementation so I wanted to check some ways to strip address space qualifier.

Thanks,
JinGu Kang

So, at least in our world, just removing the address-space qualifier
wouldn't work, you would need to also convert the pointer to an
"absolute" (non-address-space) pointer before you can do that.

If you have a model where addresses are always linear and address
spaces don't matter, then perhaps "removing them" would work (and no,
I don't know immediately how to do that - I'd probably write a small
function that takes a generic type with qualifier, and "rebuild" the
type without address spaces, and then call that on encountering a
valid place where it's needed).

This sounds like you are working around builtins not working correctly with address spaces (which is probably most of them). Stripping the address space qualifier is not really what you want

This is a problem that I've had as well. Clang's builtin infrastructure lets you specify an address space for a builtin, but doesn't have a way of expressing builtins that are polymorphic in their address spaces. This is probably something that we need to fix. I'd be very happy to review patches to do this and may even have some time next week to have a pass at implementing it...

David

This is on my wish list as well. I'll be happy to help review, but am not going to get time to work on this myself any time soon.

Philip