Hello everybody, I am modifying GCC for inserting a new OpenMP pragma. This pragma has a clause that accepts a MYVAR (integer), and modifies its value. It behaves more or less as a PARALLEL pragma, except that the return value of the inserted function call is assigned to MYVAR. However, I never manage this to happen. I investigated a bit and found that: 1) If the MYVAR is declared inside the scope of pragma, it works 2) If the MYVAR is declare outside, then the value it's never assigned. or better, it's overwritten right after the annotated code, hence before the following usage. Please see pseudo-code below, where I decleare MYVAR outside the parallel region, and then annotate it as PRIVATE.
int main () { int myvar; #pragma omp parallel private(myvar) { #pragma omp mypragma myclause(myvar) { // this code here does NOT use myvar } printf ("%d", myvar); } } Is transformed by the compiler into (the following pseudo-code reflects what I see in the dump of the expansion pass) int main () { int myvar; GOMP_parallel_start(...) main.omp.fn.0 (...) GOMP_parallel_end(...) } // the "normal" parallel function void main.omp.fn.0(..) { int myvar; int myvar; // ...nope, this is *not* a typo!! myvar = main.omp.fn.1 (...); // this prints a wrong (always '0') value printf ("%d", myvar); } // my OpenMP extension void main.omp.fn.1(..) { // this code here does NOT use myvar return SOMETHING; } All of the generation of main.omp.fn.1 (...) and insertion of the calls is done by my modifications, the rest is a "normal" OpenMP expansion pass. My problem is that the following printf always prints '0' value, which is not the one I returned from the main.omp.fn.1(..) function. I investigated a bit, and found that MYVAR is replicated during the expansion pass of the outer parreg (The "real" one). Thus, the variable MYVAR that I write is *different* than the MYVAR I pass to the prinrf: the latter is uninitialized. GCC replaces it inside move_stmt_op function, in tree-cfg.c file, at ... /* Replace T with its duplicate. T should no longer appear in the parent function, so this looks wasteful; however, it may appear in referenced_vars, and more importantly, as virtual operands of statements, and in alias lists of other variables. It would be quite difficult to expunge it from all those places. ??? It might suffice to do this for addressable variables. */ if ((TREE_CODE (t) == VAR_DECL && !is_global_var (t)) || TREE_CODE (t) == CONST_DECL) replace_by_duplicate_decl (tp, p->vars_map, p->to_context); ... I tried to "mark" MYVAR as "NON REPLICABLE" as soon as I scan it (and modified the IF stmt up here), but then I have a segfault somewhere else in the compiler (probably because the tree of that function is not consistent anymore). Anyone can help? maybe I have to set another property of the VAR_DECL for MYVAR during the scan/lowering pass..? Thanks, cheers Paolo -- View this message in context: http://old.nabble.com/OpenMP-pragma-expansion-problem-tp34758091p34758091.html Sent from the gcc - Dev mailing list archive at Nabble.com.