In my last patch, it became clear during code review that the postfix
operation was actually a read THEN update, not update/read like other
single line versions. It wasn't clear at the time how much additional
work this would be to make postfix work correctly (and they are a bit of
a 'special' thing in codegen anyway), so this patch adds some
functionality to sense this and special-cases it when generating the
statement info for capture.
The 'atomic capture' variant of the `atomic` construct accepts either a
single statement, or a compound statement containing two statements.
Each of the statements it accepts meet a form of the previous
read/write/update forms, or is a combination of two.
The IR node for atomic capture takes two separate other acc.atomics,
plus a terminator.
This patch implements all of the lowering for these.
Note: This gets the postfix-increment/decrement wrong, but the effort
to do so is enough that I believe we can do that in a followup patch, so
I'll be doing so in the next patch.
This is the 3rd of 4 forms of the 'atomic' construct. This one allows
increment/decrement, compound-assign, and assign-to-bin-op(referencing
the original variable).
All of the above is enforced during Sema, but for our purposes, we ONLY
need to know the variable on the LHS and the expression, so this does
that.
The ACC dialect for acc.atomic.update uses a 'recipe' as well, which
takes the VALUE, and yields the value of the updated value.
To simplify the implementation, our lowering very simply creates an
alloca inside the recipe, stores the passed-in value, then loads/yields
it at the end.
This is a slightly more complicated variant of this, which supports 'x =
expr', so the right hand side is an r-value. This patch implements that,
adds some tests, and does some minor refactoring to the infrastructure
added for the 'atomic read' to make it more flexible for 'write'.
This is the second of four 'atomic' kinds.
The OpenACC spec allows only `v = x` form for atomic-read, and only when
both are L-values. The result is this ends up being a pretty trivial
patch, however it adds a decent amount of infrastructure for the other
forms of atomic.
Additionally, the 3.4 spec starts allowing the 'if' clause on atomic,
which has recently been added to the ACC dialect. This patch also
ensures that can be lowered as well. Extensive testing of this feature
was done on other clauses, so there isn't much further work/testing to
be done for it.
Adopt non-templated and array-ref returning forms of
`getTrailingObjects` in DeclOpenACC and StmtOpenACC. Also use
std::uninitialized_contruct_n to make the code a little concise.
This was added in OpenACC PR #511 in the 3.4 branch. From an AST/Sema
perspective this is pretty trivial as the infrastructure for 'if'
already exists, however the atomic construct needed to be taught to take
clauses. This patch does that and adds some testing to do so.
This statement level construct takes no clauses and has no associated
statement, and simply labels a number of array elements as valid for
caching. The implementation here is pretty simple, but it is a touch of
a special case for parsing, so the parsing code reflects that.
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 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.
The arguments to this are the same as for the 'wait' clause, so this
reuses all of that infrastructure. So all this has to do is support a
pair of clauses that are already implemented (if and async), plus create
an AST node. This patch does so, and adds proper testing.
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.
After implementing 'loop', we determined that the link to its parent
only ever uses the type, not the construct itself. This patch removes
it, as it is both a waste and causes problems with serialization.
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).
I discovered while working on something else that we were using the
location of the directive name as the 'beginloc' which caused some
problems in a few places. This patch makes it so our beginloc is the
'#' as we originally designed, and then adds a DirectiveLoc concept to a
construct for use diagnosing the name.
As a first step in adding clause support for OpenACC to Semantic
Analysis, this patch adds the 'base' AST nodes required for clauses.
This patch has no functional effect at the moment, but followup patches
will add the semantic analysis of clauses (plus individual clauses).
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.
'serial', 'parallel', and 'kernel' constructs are all considered
'Compute' constructs. This patch creates the AST type, plus the required
infrastructure for such a type, plus some base types that will be useful
in the future for breaking this up.
The only difference between the three is the 'kind'( plus some minor
clause legalization rules, but those can be differentiated easily
enough), so rather than representing them as separate AST nodes, it
seems
to make sense to make them the same.
Additionally, no clause AST functionality is being implemented yet, as
that fits better in a separate patch, and this is enough to get the
'naked' constructs implemented.
This is otherwise an 'NFC' patch, as it doesn't alter execution at all,
so there aren't any tests. I did this to break up the review workload
and to get feedback on the layout.