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