The atomic construct is a particularly complicated one. The directive
itself is pretty simple, it has 5 options for the 'atomic-clause'.
However, the associated statement is fairly complicated.
'read' accepts:
v = x;
'write' accepts:
x = expr;
'update' (or no clause) accepts:
x++;
x--;
++x;
--x;
x binop= expr;
x = x binop expr;
x = expr binop x;
'capture' accepts either a compound statement, or:
v = x++;
v = x--;
v = ++x;
v = --x;
v = x binop= expr;
v = x = x binop expr;
v = x = expr binop x;
IF 'capture' has a compound statement, it accepts:
{v = x; x binop= expr; }
{x binop= expr; v = x; }
{v = x; x = x binop expr; }
{v = x; x = expr binop x; }
{x = x binop expr ;v = x; }
{x = expr binop x; v = x; }
{v = x; x = expr; }
{v = x; x++; }
{v = x; ++x; }
{x++; v = x; }
{++x; v = x; }
{v = x; x--; }
{v = x; --x; }
{x--; v = x; }
{--x; v = x; }
While these are all quite complicated, there is a significant amount
of similarity between the 'capture' and 'update' lists, so this patch
reuses a lot of the same functions.
This patch implements the entirety of 'atomic', creating a new Sema file
for the sema for it, as it is fairly sizable.
34 lines
731 B
C++
34 lines
731 B
C++
// RUN: %clang_cc1 -fopenacc -ast-print %s -o - | FileCheck %s
|
|
|
|
void foo(int v, int x) {
|
|
// CHECK: #pragma acc atomic read
|
|
// CHECK-NEXT: v = x;
|
|
#pragma acc atomic read
|
|
v = x;
|
|
// CHECK-NEXT: pragma acc atomic write
|
|
// CHECK-NEXT: v = x + 1;
|
|
#pragma acc atomic write
|
|
v = x + 1;
|
|
// CHECK-NEXT: pragma acc atomic update
|
|
// CHECK-NEXT: x++;
|
|
#pragma acc atomic update
|
|
x++;
|
|
// CHECK-NEXT: pragma acc atomic
|
|
// CHECK-NEXT: x--;
|
|
#pragma acc atomic
|
|
x--;
|
|
// CHECK-NEXT: pragma acc atomic capture
|
|
// CHECK-NEXT: v = x++;
|
|
#pragma acc atomic capture
|
|
v = x++;
|
|
|
|
// CHECK-NEXT: #pragma acc atomic capture
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: x--;
|
|
// CHECK-NEXT: v = x;
|
|
// CHECK-NEXT: }
|
|
#pragma acc atomic capture
|
|
{ x--; v = x; }
|
|
|
|
}
|