[OpenMPOpt] Look inside the callbacks the loop runtime functions are handed (#221449)
The `__kmpc_{distribute_,for_,distribute_for_}static_loop_*` functions
take the
loop body as a callback, so a parallel region written inside that body
is
reachable from the kernel only through the runtime call. `AAKernelInfo`
could not
see it: it recorded an unknown reaching region, and every kernel using
those
functions got a worker state machine whose only option was an indirect
call to
whatever it was handed.
Describe each function's callback argument in `OMPKinds.def`, attach
`!callback`
metadata, and fold the callback's `AAKernelInfo` state into the
caller's, so the
state machine can dispatch directly to the regions the body reaches. The
two
"more than one callee means give up" checks are relaxed for functions
carrying
`!callback`, since that edge is analyzable by construction; the
conservative
unknown-region record is kept for the case that motivated it, a callback
we only
see a declaration of.
These calls still block SPMD-ization, and the `TODO` saying they need
not is
replaced with the obstacles that actually remain. A plain `distribute`
spreads
iterations over teams, so the runtime runs it with TId 0 and a team size
of one;
SPMD-izing has every thread run its block's whole share. The
thread-indexed
families are stopped by the transform rather than the analysis: guarding
puts
single-threaded code behind a block-wide barrier, and a barrier inside a
body
only some threads run is divergent.
Ported from AMD's ROCm fork, `8176194f36b9`, which also used the
analysis to
SPMD-ize these kernels; that part is left out because it is disabled by
default
downstream after regressing applications.
Tested on gfx90a: `llvm/test/Transforms/{OpenMP,Attributor}` 260 passed,
1
unsupported. `offload/test/amdgpu-amd-amdhsa` 516 passed, including the
new
Fortran reproducer. No kernel in the AOMP smoke and smoke-fort suites
changes
execution mode.