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.
This completes the implementation of 'update' by implementing its last
restriction. This restriction requires at least 1 of the 'self', 'host',
or 'device' clauses.
This executable construct has a larger list of clauses than some of the
others, plus has some additional restrictions. This patch implements
the AST node, plus the 'cannot be the body of a if, while, do, switch,
or label' statement restriction. Future patches will handle the
rest of the restrictions, which are based on clauses.
The 'set' construct is another fairly simple one, it doesn't have an
associated statement and only a handful of allowed clauses. This patch
implements it and all the rules for it, allowing 3 of its for clauses.
The only exception is default_async, which will be implemented in a
future patch, because it isn't just being enabled, it needs a complete
new implementation.
These two constructs are very simple and similar, and only support 3
different clauses, two of which are already implemented. This patch
adds AST nodes for both constructs, and leaves the device_num clause
unimplemented, but enables the other two.
All 4 of the 'data' constructs have a requirement that at least 1 of a
small list of clauses must appear on the construct. This patch
implements that restriction, and updates all of the tests it takes to
do so.
These constructs are all very similar and closely related, so this patch
creates the AST nodes for them, serialization, printing/etc.
Additionally the restrictions are all added as tests/todos in the tests,
as those will have to be implemented once we get those clauses implemented.
Combined constructs (OpenACC 3.3 section 2.11) are a short-cut for
writing a `loop` construct immediately inside of a `compute` construct.
However, this interaction requires we do additional work to ensure that
we get the semantics between the two correct, as well as diagnostics.
This patch adds the semantic analysis for the constructs (but no
clauses), as well as the AST nodes.
OpenACC restricts the contents of a 'for' loop affected by a 'loop'
construct without a 'seq'. The loop variable must be integer, pointer,
or random-access-iterator, it must monotonically increase/decrease, and
the trip count must be computable at runtime before the function.
This patch tries to implement some of these limitations to the best of
our ability, though it causes us to be perhaps overly restrictive at the
moment. I expect we'll revisit some of these rules/add additional
supported forms of loop-variable and 'monotonically increasing' here,
but the currently enforced rules are heavily inspired by the OMP
implementation here.
This patch implements the 'loop' construct AST, as well as the basic
appertainment rule. Additionally, it sets up the 'parent' compute
construct, which is necessary for codegen/other diagnostics.
A 'loop' can apply to a for or range-for loop, otherwise it has no other
restrictions (though some of its clauses do).
So far, all the work we've done for compute constructs has only used
'parallel'. This patch does the work to enable the same logic for
'serial' and 'kernels' constructs as well, since they are the same
semantic behavior.
This patch Implements AST node creation and appertainment enforcement
for 'parallel', as well as changes the 'not implemented' messages to be
more specific. It does not deal with clauses/clause legality, nor a few
of the other rules from the standard, but this gets us most of the way
for a framework for future construct implementation.
Currently we just emit a generic 'not implemented' diagnostic for all
OpenACC pragmas. This patch moves the diagnostic to 'Sema' and diagnoses
for a specific clause or construct, in preperation of implementing Sema
for constructs.
As we've now finished parsing the constructs, we're moving onto
implementing 'clause' parsing. While some are complicated and require
their own patch, the handful added here are simple to parse (that is,
they are a single identifier).
This patch adds the infrastructure to parse these and a clause-list in
its entirety. This adds some complication to how we are diagnosing
parsing errors elsewhere, so a few changes were made to better recover
from errors.
It was brought up during the cache review that we shouldn't be using
'getSpelling', and instead should use the IdentifierInfo itself. This
patch replaces all uses of it.
The 'routine' construct applies either to a function directly, or, when
provided a name, applies to the function named (and is visible in the
current scope). This patch implements the parsing for this. The
identifier provided (or Id Expression) is required to be a valid,
declared identifier, though the semantic analysis portion of the Routine
directive will need to enforce it being a function/overload set.
`atomic` is required to be followed by a special `atomic clause`, so
this patch manages the parsing of that. We are representing each of the
variants of the atomic construct as separate kinds, because they have
distinct rules/application/etc, and this should make it easier to check
rules in the future.
These two constructs, 'enter data' and 'exit data', are novel compared
to what is currently in the parser, as this is the first set implemented
where the first token is itself not a valid construct. Because of this,
it requires some additional work to do the first keyword parsing.
Now that the `parallel` support has landed, add the other 'trivial' to
implement ones that don't require any additional work other than adding
them to the StringSwitch.
As the first real parsing effort for the OpenACC implementation effort,
this implements the parsing for first construct/directive name. This
does not do any semantic analysis, nor any of the clauses. Those will
come in a future patch.
For the time being, we warn when we hit a point that we don't implement
the parsing for either of these situations.