On Tue, Aug 29, 2023 at 06:12:58PM +0200, Tobias Burnus wrote: > This adds support for > #pragma omp allocate(var-list) [allocator(..) align(..)] > > While the spec permits stack and static variables, this patch only > adds support for stack variables - keeping the 'sorry' for static > variables. > It is also only C as I wanted to get this out before updating C++ > parsing. However, if disable the 'sorry' + add the attribute, it > will also work for C++. > > For Fortran, there is no expression associated with the declaration > such that it will not work with the gimplify.cc patch (it cannot > find the place to add it); however, I have a mostly working version > for FE generated support for stack _and_ static variables. > > The main RFC question for this patch is whether to generate the > GOMP_alloc/free calls also for !TREE_USED() or not. This patch avoids > this to aid removal of such stack variables, but one could also argue > otherwise. > > Thoughts, comments, remarks?
Don't have time to look through it in detail right now, so just 2 quick comments. One thing is that for C++ one needs to be careful about vars optimized by NRV by the FE. Dunno if we can simply disregard vars mentioned in allocate directive from FE NRV, or whether we instead should ignore the allocate directive, or sorry, etc. Because NRV optimized vars are turned into RESULT_DECL and live usually in the caller's stack frame rather than current function, so they can't be heap allocated... And, just from the gimplify_bind_expr function name, I'm guessing you are adding the allocations at the start of surrounding BIND_EXPR, is that where we generally want to allocate them? Other option is on DECL_EXPR, e.g. for C++ right before they are constructed, or for C initialized if they have initializer. Though, that can have a drawback, one can e.g. in C (and I think in C++ too as long as the vars don't need any kind of construction) jump across that initialization and one would then bypass this allocation. Though, what happens with say void foo (int i) { switch (i) { int j; #pragma omp allocate (j) ... case 42: j = 5; use (&j); break; default: j = 24; use (&j); break; } } Where will j be allocated and where will j be deallocated with your patch? If it is try/finally, then perhaps break; as jump out of the BIND_EXPR will destruct it fine, but I have no idea how it would work when jumping into the switch (or goto into middle of some compound statement etc.). Jakub