xref: /llvm-project/openmp/docs/remarks/OMP113.rst (revision 0c660256eb41fb0ba44277a32f39d2a028f797f2)
1.. _omp113:
2
3Could not move globalized variable to the stack. Variable is potentially captured in call. Mark parameter as `__attribute__((noescape))` to override. [OMP113]
4==============================================================================================================================================================
5
6This missed remark indicates that a globalized value could not be moved to the
7stack because it is potentially captured by a call to a function we cannot
8analyze. In order for a globalized variable to be moved to the stack, copies to
9its pointer cannot be stored. Otherwise it is considered captured and could
10potentially be shared between the threads. This can be overridden using a
11parameter level attribute as suggested in the remark text.
12
13Globalization will occur when a pointer to a thread-local variable escapes the
14current scope. In most cases it can be determined that the variable cannot be
15shared if a copy of its pointer is never made. However, this remark indicates a
16copy of the pointer is present or that sharing is possible because it is used
17outside the current translation unit.
18
19Examples
20--------
21
22If a pointer to a thread-local variable is passed to a function not visible in
23the current translation unit we need to assume a copy is made of it that can be
24shared between the threads. This prevents :ref:`OMP110 <omp110>` from
25triggering, which will result in a performance penalty when executing on the
26target device.
27
28.. code-block:: c++
29
30  extern void use(int *x);
31
32  void foo() {
33    int x;
34    use(&x);
35  }
36
37  int main() {
38  #pragma omp target parallel
39    foo();
40  }
41
42.. code-block:: console
43
44   $ clang++ -fopenmp -fopenmp-targets=nvptx64 -O2 -Rpass-missed=openmp-opt omp113.cpp
45   missed.cpp:4:7: remark: Could not move globalized variable to the stack. Variable is
46   potentially captured in call. Mark parameter as `__attribute__((noescape))` to
47   override. [OMP113]
48     int x;
49         ^
50
51As the remark suggests, this behaviour can be overridden using the ``noescape``
52attribute. This tells the compiler that no reference to the object the pointer
53points to that is derived from the parameter value will survive after the
54function returns. The user is responsible for verifying that this assertion is
55correct.
56
57.. code-block:: c++
58
59  extern void use(__attribute__((noescape)) int *x);
60
61  void foo() {
62    int x;
63    use(&x);
64  }
65
66  int main() {
67  #pragma omp target parallel
68    foo();
69  }
70
71.. code-block:: console
72
73   $ clang++ -fopenmp -fopenmp-targets=nvptx64 -O2 -Rpass=openmp-opt omp113.cpp
74   missed.cpp:4:7: remark: Moving globalized variable to the stack. [OMP110]
75   int x;
76       ^
77
78Diagnostic Scope
79----------------
80
81OpenMP target offloading missed remark.
82