[cfe-dev] Implementing OpenMP function variants

Finkel, Hal J. via cfe-dev cfe-dev at lists.llvm.org
Fri Dec 13 07:08:16 PST 2019

Richard, John, et al.,

Let me top-post here quickly to add that this question comes directly 
from a disagreement about the application of Clang's design principle of 
keeping the AST faithful to the source code (and I suspect that such a 
question may be of wider interest to the community).

Johannes has summarized the OpenMP language semantics below (thanks, 

The relevant review thread is here: https://reviews.llvm.org/D71241

Alexey's position is that, because the source code contains what appears 
to be a call to the base() function, the AST should always reflect that 
fact by having getCallee() return a reference to base(), and we should 
lower the call to the selected variant using logic in CodeGen. Some 
other member function should be used by AST-level tools to retrieve the 
actually-called variant. This has the benefit that the primary AST 
representation is independent of the compilation target and other 
relevant OpenMP context.

My position is that, like other cases where we perform overload 
resolution and specializaton selection (including host/device overloads 
in CUDA), we should resolve the variant selected in Sema, and 
getCallee() should return a reference to the function that will actually 
be called (even if that function has a different name from the name used 
syntactically to form the call expression). This will ensure that 
static-analysis tools see the correct call-site <-> callee relationship. 
We should, I think, also keep a reference to the original OpenMP base 
function in the AST, but some other member function should be used to 
retrieve it.

We say that we keep Clang's AST faithful to the source code, but how to 
best apply that philosophy in this case is now under debate.

Thanks again,


On 12/12/19 11:28 PM, Doerfert, Johannes wrote:
> Background:
> The prototype for OpenMPs 5.1 feature `begin/end declare variant` caused
> a discussion that seems to be stuck. I'll briefly outline the semantics
> of the OpenMP 5.0 `declare variant` and the `begin/end declare variant`
> here before I present the two competing designs on a very high level. If
> there is a need for more information, a summary of what was said, or
> anything else, please feel free to ask for it.
> ---
> OpenMP 5.0 `declare variant` allows you to define a variant of a base
> function that is called instead of the base function if the context
> specified with the variant matches at a call site.
> As an example, the call to base below is replaced by a call to special
> if the code is compiled with a compiler that identifies as "llvm".
> ```
> void special();
> #pragma omp declare variant(special) match(implementation={vendor(llvm)})
> void base();
> void test() {
>    base();
> }
> ```
> Context selectors for the match clause can be specific to the target,
> the implementation, or the context in which the call is executed, e.g.,
> syntactic inside a #omp parallel.
> ---
> OpenMP 5.1 `begin/end declare variant` is an extension of the 5.0
> version that (1) makes the user specific mangling obsolete, and (2)
> guards the code in between the begin/end if the context selector does
> not match at compile time. The use case can be simplified to the code
> below in which we want the `sin` call to resolve to the NVIDIA specific
> version if we are compiling for nvptx and to the one in math.h
> otherwise. Note that the variant in the begin/end range has the same
> name as the base it overloads.
> ```
> #include "math.h"
> #pragma omp begin declare variant match(device={arch(nvptx)})
> double sin(double s) { return __nv_sin(s); }
> #pragma omp end declare variant
> double calc(double s) {
>    return sin(sin(sin(s)));
> }
> ```
> ---
> Now that we are all OpenMP experts, we need to decide how/where to
> implement this. Oversimplified, these are the options being discussed:
> Proposal 1, CodeGen:
>    Introduce aliases that redirect from one function to the other or
>    replace the callee in the CodeGen.
> Proposal 2), SemaOverload:
>    Use the multi-version overloading for the 5.1 feature and introduce
>    another level of overload resolution for the 5.0 feature.
> ---
> Thanks in advance for your time and input,
>    Johannes

Hal Finkel
Lead, Compiler Technology and Programming Languages
Leadership Computing Facility
Argonne National Laboratory

More information about the cfe-dev mailing list