for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
switch (OMP_CLAUSE_CODE (c))
{
- tree var;
+ tree var, new_var, *allocate_ptr;
default:
break;
case OMP_CLAUSE_MAP:
case OMP_CLAUSE_PRIVATE:
var = OMP_CLAUSE_DECL (c);
by_ref = omp_privatize_by_reference (var);
- if (is_variable_sized (var))
+ new_var = lookup_decl (var, ctx);
+ allocate_ptr = alloc_map.get (new_var);
+ if (is_variable_sized (var, by_ref)
+ || (!allocate_ptr && by_ref && !is_gimple_omp_oacc (ctx->stmt)))
{
- tree new_var = lookup_decl (var, ctx);
- tree *allocate_ptr = alloc_map.get (new_var);
if (allocate_ptr)
{
gimple_seq *allocate_seq = alloc_seq_map.get (new_var);
if (!allocate_ptr)
{
tree atmp = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
- tree al = size_int (DECL_ALIGN (var));
- x = TYPE_SIZE_UNIT (TREE_TYPE (new_var));
+ tree ty = TREE_TYPE (new_var);
+ if (by_ref)
+ ty = TREE_TYPE (ty);
+ x = TYPE_SIZE_UNIT (ty);
+ if (TREE_CONSTANT (x))
+ break;
+ tree al = size_int (TYPE_ALIGN (ty));
x = build_call_expr_loc (clause_loc, atmp, 2, x, al);
x = fold_convert_loc (clause_loc, TREE_TYPE (new_pvar), x);
}
gimple_seq_add_stmt (&new_body,
gimple_build_assign (new_pvar, x));
}
- else if (by_ref && !is_gimple_omp_oacc (ctx->stmt))
- {
- location_t clause_loc = OMP_CLAUSE_LOCATION (c);
- tree new_var = lookup_decl (var, ctx);
- tree x = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var)));
- if (TREE_CONSTANT (x))
- break;
- else
- {
- tree atmp
- = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
- tree rtype = TREE_TYPE (TREE_TYPE (new_var));
- tree al = size_int (TYPE_ALIGN (rtype));
- x = build_call_expr_loc (clause_loc, atmp, 2, x, al);
- }
-
- x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
- gimplify_expr (&x, &new_body, NULL, is_gimple_val, fb_rvalue);
- gimple_seq_add_stmt (&new_body,
- gimple_build_assign (new_var, x));
- }
break;
case OMP_CLAUSE_FIRSTPRIVATE:
var = OMP_CLAUSE_DECL (c);
// PR middle-end/113436
// { dg-do "compile" }
-// { dg-options "-std=gnu++20 -fopenmp -fdump-tree-omplower" }
+// { dg-options "-fopenmp -fdump-tree-omplower" }
// #include <omp.h>
typedef __UINTPTR_TYPE__ omp_uintptr_t;
void f()
{
int a[10];
- auto &aRef = a;
+ int (&aRef)[10] = a;
#pragma omp target firstprivate(aRef) \
allocate(align(128), allocator(omp_low_lat_mem_alloc): aRef)
// { dg-do "compile" }
// { dg-options "-fopenmp -fdump-tree-omplower" }
+// #include <omp.h>
+typedef __UINTPTR_TYPE__ omp_uintptr_t;
+
+#if __cplusplus >= 201103L
+# define __GOMP_UINTPTR_T_ENUM : omp_uintptr_t
+#else
+# define __GOMP_UINTPTR_T_ENUM
+#endif
+
+typedef enum omp_allocator_handle_t __GOMP_UINTPTR_T_ENUM
+{
+ omp_null_allocator = 0,
+ omp_default_mem_alloc = 1,
+ omp_large_cap_mem_alloc = 2,
+ omp_const_mem_alloc = 3,
+ omp_high_bw_mem_alloc = 4,
+ omp_low_lat_mem_alloc = 5,
+ omp_cgroup_mem_alloc = 6,
+ omp_pteam_mem_alloc = 7,
+ omp_thread_mem_alloc = 8,
+ ompx_gnu_pinned_mem_alloc = 200,
+ ompx_gnu_managed_mem_alloc = 201,
+ __omp_allocator_handle_t_max__ = __UINTPTR_MAX__
+} omp_allocator_handle_t;
+
+
void f(int x)
{
int a[x];
- int (&c)[x] = a;
+ int (&aRef)[x] = a;
- #pragma omp target private (c)
- {
- c[0] = 1;
- }
+ #pragma omp target private(aRef) \
+ allocate(align(128), allocator(omp_high_bw_mem_alloc): aRef)
+ aRef[0] = 1;
}
-// Ensure that the size of memory allocated for the VLA is from a variable rather than a constant.
-// { dg-final { scan-tree-dump "D\\\.\[0-9\]\+ = __builtin_alloca_with_align \\\(D\\\.\[0-9\]\+, \[0-9\]\+\\\);" "omplower" } }
+// { dg-final { scan-tree-dump "D\\\.\[0-9\]\+ = __builtin_GOMP_alloc \\\(128, D\\\.\[0-9\]\+, 4\\\);" "omplower" } }
+// { dg-final { scan-tree-dump "aRef = D\\\.\[0-9\]\+;" "omplower" } }
+// { dg-final { scan-tree-dump "\\\(\\\*aRef\\\)\\\[0\\\] = 1;" "omplower" } }
+// { dg-final { scan-tree-dump "__builtin_GOMP_free \\\(D\\\.\[0-9\]\+, 4\\\);" "omplower" } }
--- /dev/null
+// PR middle-end/113436
+// { dg-do "compile" }
+// { dg-options "-fopenmp -fdump-tree-omplower" }
+
+// #include <omp.h>
+typedef __UINTPTR_TYPE__ omp_uintptr_t;
+
+#if __cplusplus >= 201103L
+# define __GOMP_UINTPTR_T_ENUM : omp_uintptr_t
+#else
+# define __GOMP_UINTPTR_T_ENUM
+#endif
+
+typedef enum omp_allocator_handle_t __GOMP_UINTPTR_T_ENUM
+{
+ omp_null_allocator = 0,
+ omp_default_mem_alloc = 1,
+ omp_large_cap_mem_alloc = 2,
+ omp_const_mem_alloc = 3,
+ omp_high_bw_mem_alloc = 4,
+ omp_low_lat_mem_alloc = 5,
+ omp_cgroup_mem_alloc = 6,
+ omp_pteam_mem_alloc = 7,
+ omp_thread_mem_alloc = 8,
+ ompx_gnu_pinned_mem_alloc = 200,
+ ompx_gnu_managed_mem_alloc = 201,
+ __omp_allocator_handle_t_max__ = __UINTPTR_MAX__
+} omp_allocator_handle_t;
+
+void f(int x)
+{
+ int a[x], *b[x];
+ int (&aRef)[x] = a;
+ int *(&bRef)[x] = b;
+
+ #pragma omp target firstprivate (aRef, bRef) \
+ allocate (allocator (omp_low_lat_mem_alloc): aRef) \
+ allocate (allocator (omp_large_cap_mem_alloc): bRef)
+ {
+ aRef[0] = 0;
+ bRef[0] = 0;
+ }
+}
+
+// Ensure that the size of memory allocated for the VLA is from a variable
+// rather than a constant, and that the default alignments are as expected.
+
+// { dg-final { scan-tree-dump "a\\\.\[0-9\]\+ = __builtin_alloca_with_align \\\(D\\\.\[0-9\]\+, 32\\\);" "omplower" { target int32 } } }
+// { dg-final { scan-tree-dump "b\\\.\[0-9\]\+ = __builtin_alloca_with_align \\\(D\\\.\[0-9\]\+, 32\\\);" "omplower" { target ilp32 } } }
+// { dg-final { scan-tree-dump "b\\\.\[0-9\]\+ = __builtin_alloca_with_align \\\(D\\\.\[0-9\]\+, 64\\\);" "omplower" { target { lp64 || llp64 } } } }
+// { dg-final { scan-tree-dump "D\\\.\[0-9\]\+ = __builtin_GOMP_alloc \\\(4, D\\\.\[0-9\]\+, 5\\\);" "omplower" { target int32 } } }
+// { dg-final { scan-tree-dump "D\\\.\[0-9\]\+ = __builtin_GOMP_alloc \\\(4, D\\\.\[0-9\]\+, 2\\\);" "omplower" { target ilp32 } } }
+// { dg-final { scan-tree-dump "D\\\.\[0-9\]\+ = __builtin_GOMP_alloc \\\(8, D\\\.\[0-9\]\+, 2\\\);" "omplower" { target { lp64 || llp64 } } } }
+// { dg-final { scan-tree-dump "aRef = D\\\.\[0-9\]\+;" "omplower" } }
+// { dg-final { scan-tree-dump "bRef = D\\\.\[0-9\]\+;" "omplower" } }
--- /dev/null
+// PR middle-end/113436
+// { dg-do "compile" }
+// { dg-options "-fopenmp -fdump-tree-omplower" }
+
+// #include <omp.h>
+typedef __UINTPTR_TYPE__ omp_uintptr_t;
+
+#if __cplusplus >= 201103L
+# define __GOMP_UINTPTR_T_ENUM : omp_uintptr_t
+#else
+# define __GOMP_UINTPTR_T_ENUM
+#endif
+
+typedef enum omp_allocator_handle_t __GOMP_UINTPTR_T_ENUM
+{
+ omp_null_allocator = 0,
+ omp_default_mem_alloc = 1,
+ omp_large_cap_mem_alloc = 2,
+ omp_const_mem_alloc = 3,
+ omp_high_bw_mem_alloc = 4,
+ omp_low_lat_mem_alloc = 5,
+ omp_cgroup_mem_alloc = 6,
+ omp_pteam_mem_alloc = 7,
+ omp_thread_mem_alloc = 8,
+ ompx_gnu_pinned_mem_alloc = 200,
+ ompx_gnu_managed_mem_alloc = 201,
+ __omp_allocator_handle_t_max__ = __UINTPTR_MAX__
+} omp_allocator_handle_t;
+
+void f(int x)
+{
+ int a[x], *b[x];
+ int (&aRef)[x] = a;
+ int *(&bRef)[x] = b;
+
+ #pragma omp target private (aRef, bRef) \
+ allocate (allocator (omp_low_lat_mem_alloc): aRef) \
+ allocate (allocator (omp_large_cap_mem_alloc): bRef)
+ {
+ aRef[0] = 0;
+ bRef[0] = 0;
+ }
+}
+
+// Ensure that the size of memory allocated for the VLA is from a variable
+// rather than a constant, and that the default alignments are as expected.
+
+// { dg-final { scan-tree-dump "a\\\.\[0-9\]\+ = __builtin_alloca_with_align \\\(D\\\.\[0-9\]\+, 32\\\);" "omplower" { target int32 } } }
+// { dg-final { scan-tree-dump "b\\\.\[0-9\]\+ = __builtin_alloca_with_align \\\(D\\\.\[0-9\]\+, 32\\\);" "omplower" { target ilp32 } } }
+// { dg-final { scan-tree-dump "b\\\.\[0-9\]\+ = __builtin_alloca_with_align \\\(D\\\.\[0-9\]\+, 64\\\);" "omplower" { target { lp64 || llp64 } } } }
+// { dg-final { scan-tree-dump "D\\\.\[0-9\]\+ = __builtin_GOMP_alloc \\\(4, D\\\.\[0-9\]\+, 5\\\);" "omplower" { target int32 } } }
+// { dg-final { scan-tree-dump "D\\\.\[0-9\]\+ = __builtin_GOMP_alloc \\\(4, D\\\.\[0-9\]\+, 2\\\);" "omplower" { target ilp32 } } }
+// { dg-final { scan-tree-dump "D\\\.\[0-9\]\+ = __builtin_GOMP_alloc \\\(8, D\\\.\[0-9\]\+, 2\\\);" "omplower" { target { lp64 || llp64 } } } }
+// { dg-final { scan-tree-dump "aRef = D\\\.\[0-9\]\+;" "omplower" } }
+// { dg-final { scan-tree-dump "bRef = D\\\.\[0-9\]\+;" "omplower" } }
--- /dev/null
+// PR middle-end/113436
+// { dg-do "compile" }
+// { dg-options "-fopenmp -fdump-tree-omplower" }
+
+void f(int x)
+{
+ int a[x], *b[x];
+ int (&aRef)[x] = a;
+ int *(&bRef)[x] = b;
+
+ #pragma omp target private (aRef, bRef)
+ {
+ aRef[0] = 0;
+ bRef[0] = 0;
+ }
+}
+
+// Ensure that the size of memory allocated for the VLA is from a variable
+// rather than a constant, and that the default alignments are as expected.
+
+// { dg-final { scan-tree-dump "a\\\.\[0-9\]\+ = __builtin_alloca_with_align \\\(D\\\.\[0-9\]\+, 32\\\);" "omplower" { target int32 } } }
+// { dg-final { scan-tree-dump "b\\\.\[0-9\]\+ = __builtin_alloca_with_align \\\(D\\\.\[0-9\]\+, 32\\\);" "omplower" { target ilp32 } } }
+// { dg-final { scan-tree-dump "b\\\.\[0-9\]\+ = __builtin_alloca_with_align \\\(D\\\.\[0-9\]\+, 64\\\);" "omplower" { target { lp64 || llp64 } } } }
+// { dg-final { scan-tree-dump "D\\\.\[0-9\]\+ = __builtin_alloca_with_align \\\(D\\\.\[0-9\]\+, 32\\\);" "omplower" { target int32 } } }
+// { dg-final { scan-tree-dump "D\\\.\[0-9\]\+ = __builtin_alloca_with_align \\\(D\\\.\[0-9\]\+, 32\\\);" "omplower" { target ilp32 } } }
+// { dg-final { scan-tree-dump "D\\\.\[0-9\]\+ = __builtin_alloca_with_align \\\(D\\\.\[0-9\]\+, 64\\\);" "omplower" { target { lp64 || llp64 } } } }
+// { dg-final { scan-tree-dump "aRef = D\\\.\[0-9\]\+;" "omplower" } }
+// { dg-final { scan-tree-dump "bRef = D\\\.\[0-9\]\+;" "omplower" } }
}
}
+void
+test_vla_by_ref (int n)
+{
+ int x[n];
+ for (int i = 0; i < n; i++)
+ x[i] = i;
+ int (&y)[n] = x;
+
+ #pragma omp target firstprivate(y) \
+ allocate(allocator(omp_low_lat_mem_alloc), align(128): y)
+ {
+ if (((uintptr_t) &y) % 128 != 0)
+ __builtin_abort ();
+ for (int i = 0; i < n; i++)
+ y[i]++;
+ for (int i = 0; i < n; i++)
+ if (y[i] != i + 1)
+ __builtin_abort ();
+ }
+}
+
int main ()
{
test_int_by_ref ();
+ test_vla_by_ref (17);
}
}
}
+void
+test_vla_by_ref (int n)
+{
+ int x[n];
+ for (int i = 0; i < n; i++)
+ x[i] = i;
+ int (&y)[n] = x;
+
+ #pragma omp target private(y) \
+ allocate(allocator(omp_low_lat_mem_alloc), align(128): y)
+ {
+ if (((uintptr_t) &y) % 128 != 0)
+ __builtin_abort ();
+ for (int i = 0; i < n; i++)
+ y[i] = i + 1;
+ }
+}
+
int main ()
{
test_int_by_ref ();
+ test_vla_by_ref (17);
}