------- Comment #3 from jakub at gcc dot gnu dot org  2006-09-11 14:22 -------
I believe OMP_PARALLEL handling in tree-nested.c isn't the only problem, see
e.g.:
extern void abort (void);

void
foo (int *j)
{
  int i = 5;
  int bar (void) { return i + 1; }
#pragma omp sections private (i)
  {
    #pragma omp section
    {
      i = 6;
      if (bar () != 7)
        #pragma omp atomic
          ++*j;
    }
    #pragma omp section
    {
      if (bar () != 6)
        #pragma omp atomic
          ++*j;
    }
  }
}

int
main (void)
{
  int j = 0;
#pragma omp parallel num_threads (2)
  foo (&j);
  if (j)
    abort ();
  return 0;
}

My understanding is that even the OMP_PRIVATE clause in the worksharing
construct
should result in a different FRAME.  Another testcase:
extern void abort (void);
extern int omp_get_thread_num ();
extern void omp_set_dynamic (int);

int
main (void)
{
  int j = 0, k = 6, l = 7, m = 8;
  void
  foo (void)
  {
    int i = 5;
    int bar (void) { return i + 1 + (j > 100 ? 10000 : 0); }
  #pragma omp sections private (i)
    {
      #pragma omp section
      {
        i = 6;
        if (bar () != 7)
          #pragma omp atomic
            ++j;
      }
      #pragma omp section
      {
        if (bar () != 6)
          #pragma omp atomic
            ++j;
      }
    }
    if (k != 6 + omp_get_thread_num () || l != 7 || m != 9)
      #pragma omp atomic
        ++j;
  }
  omp_set_dynamic (0);
#pragma omp parallel num_threads (2) firstprivate (k) shared (l) private (m)
  {
    if (omp_get_thread_num () != 0)
      k += omp_get_thread_num ();
    m = 9;
    foo ();
  }
  if (j)
    abort ();
  return 0;
}

I believe in many cases we will have to force use_pointer_in_frame when OpenMP
constructs are involved in the parent routines of nested functions.  We don't
need it if either all the variables in FRAME structure are shared (then we can
pass around a pointer to the parent's FRAME), or if all are private (then we
could create a completely new copy of the FRAME and make the private vars live
in there), but as soon as things start to get mixed, we need to use pointers.
But not sure how easy would be to figure it out.  As convert_nonlocal_reference
already needs to know if it should use pointer or a var directly, we'd need
another flag_openmp pass before walk_all_functions (convert_nonlocal_reference,
root); that would perhaps stick all vars mentioned in omp clauses in some hash
table in struct nesting_info and then use that as a guide to
use_pointer_in_frame.


-- 

jakub at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |rth at gcc dot gnu dot org,
                   |                            |dnovillo at gcc dot gnu dot
                   |                            |org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25261

Reply via email to