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.

Reply via email to