Hi,

Here's a different approach that doesn't introduce indirection for privatized
variables at all, and keeps dependencies obvious in the IR, but, on the flip
side, requires mentioning all subfields of privatized structures in a few
places.

For each privatized variable, add it to the list of outputs of an asm at
function entry, and to the lists of inputs+outputs at SIMT region entry.  That
is, if original code has

  void foo()
  {
    int var1, var2;
    ...
  #pragma omp private(var1, var2)
    for (...) { ... }
  }

lower it to

void foo()
{
  int priv_var1, priv_var2;
  asm ("// non-transparent initialization" : "=r"(priv_var1), "=r"(priv_var2));

  ...

  void *simtrec;
  asm ("// simt entry" : "=r"(simtrec), "+r"(priv_var1), "+r"(priv_var2));

  for (...) { ... }

  asm ("// simt exit" : : "r"(simtrec) : "r"(priv_var1), "r"(priv_var2));
}

Note that technically adding privatized vars just to the clobbers list at region
exit is not enough since the compiler is free to move a write past that
downwards (with any subsequent reads).  But I'm not sure if that should be a
real concern.  Apart from that, I think this introduces the required data
depdendencies, and nothing more.

For composite privatized objects (arrays, structures), we'd had to recursively
walk them and emit individual fields/array entries in asm arguments.

At some point in the pass pipeline we'd have to remove the first asm and replace
the other two with IFN_GOMP_SIMT_ENTER/EXIT like in earlier approach (Jakub
suggested ompdevlow, as I remember).

Does this look ok?

Thanks.
Alexander

Reply via email to