[PATCH] D71989: [OpenMP][IRBuilder][WIP] Prototype `omp task` support

Johannes Doerfert via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 14 18:00:51 PST 2020


jdoerfert added a comment.

In D71989#1820289 <https://reviews.llvm.org/D71989#1820289>, @rogfer01 wrote:

> > and we then call the copy constructors like this:
> > 
> >   void *local_addr = ...;
> >   for (kmp_uint32 u = 0; u < sizeof_copy_infos; ++u)
> >     local_addr = copy_wrapper_list[u](copied_obj_list[u], local_addr);
>
> Just to confirm: that `local_addr` would be somehow linked to the task, I imagine it'd be initialized to something like `task->shareds + offset_to_firstprivates`, wouldn't it?


Yes. It is some location in which the task local variables live.

> Also, perhaps you already considered if it makes sense to just have a copy function generated by the front-end rather than one of for each "firstprivatized variable that can't just be memcpy'ed"?

Having a copy function per type allows us to reuse it, otherwise we have one copy function per static task location (at worst). Either works for me I think.

> Also I'm curious why are you moving away (perhaps I did get this wrong!) from the current model of
> 
> 1. `kmpc_omp_task_alloc`
> 2. capture environment
> 3. queue the task `kmpc_omp_task`or (if the task is `if(0)`) do an "immediate" execution but use the environment captured in 2
> 
>   to something that looks like
> 4. (partially?) capture the environment. I think I didn't understand what `void *shared_and_private_vars` will do here. Is this something that the front-end precaptured for us?

The idea is that we can allocate variables (for which we do not invoke a copy constructor) in a smart way so that we can easily copy them if we need to or not copy them at all if we don't. This interface is a first version though roughly designed like the `tregion` interface. Any suggestions are welcome!

> 2. copy the environment you obtained from `shared_and_private_vars` to a task-local storage and then queue the task or (if the task is `if(0)`) do an immediate execution using the environment you got from the argument to `kmpc_task`

Optimally, you would only copy if you need to.

> I guess there is a benefit in the new approach. So far I read this as improving the `if(0)` case (but I may be missing something here).

There are multiple reasons but the main one for me is for sure the ability to use `callback` metadata to link the values passed at the call site of `kmpc_task` with the values received at the outlined body function. This is really complicated in the old approach, because there is no direct link possible between the captured values and the local copies in the thread (the stores go to some really hard to describe location and the body function reference is only at some point later).
In the new approach you link `shared_and_private_vars` to the argument the task function receives. Now you encapsulate the call site in an additional, modifiable level of indirection (see D71505 <https://reviews.llvm.org/D71505>), and the Attributor will unpack the struct (see D68852 <https://reviews.llvm.org/D68852>), propagate constants, alias information, ... between the task invocation and the task function.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D71989/new/

https://reviews.llvm.org/D71989





More information about the llvm-commits mailing list