diff mbox

[committed] Fix -fopenmp -fwhole-file (PR fortran/47331)

Message ID 20110117223028.GI2724@tyan-ft48-01.lab.bos.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Jan. 17, 2011, 10:30 p.m. UTC
Hi!

openmp.c has some private state (3 variables) that are used during
resolving.  When -fwhole-file calls gfc_resolve on some procedure while
resolving a different one the state was not cleared, which caused it to
behave as if the other procedure code was inside of one of the OpenMP
regions.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
committed to trunk.  Will commit to 4.5 after a while.

2011-01-17  Jakub Jelinek  <jakub@redhat.com>

	PR fortran/47331
	* gfortran.h (struct gfc_omp_saved_state): New type.
	(gfc_omp_save_and_clear_state, gfc_omp_restore_state): New prototypes.
	* resolve.c (resolve_global_procedure): Call it around gfc_resolve
	call.
	* openmp.c (gfc_omp_save_and_clear_state, gfc_omp_restore_state): New
	functions.

	* gfortran.dg/gomp/pr47331.f90: New test.


	Jakub
diff mbox

Patch

--- gcc/fortran/gfortran.h.jj	2011-01-15 11:26:40.000000000 +0100
+++ gcc/fortran/gfortran.h	2011-01-17 18:24:23.244651575 +0100
@@ -2651,11 +2651,14 @@  void gfc_free_case_list (gfc_case *);
 gfc_expr *gfc_get_parentheses (gfc_expr *);
 
 /* openmp.c */
+struct gfc_omp_saved_state { void *ptrs[2]; int ints[1]; };
 void gfc_free_omp_clauses (gfc_omp_clauses *);
 void gfc_resolve_omp_directive (gfc_code *, gfc_namespace *);
 void gfc_resolve_do_iterator (gfc_code *, gfc_symbol *);
 void gfc_resolve_omp_parallel_blocks (gfc_code *, gfc_namespace *);
 void gfc_resolve_omp_do_blocks (gfc_code *, gfc_namespace *);
+void gfc_omp_save_and_clear_state (struct gfc_omp_saved_state *);
+void gfc_omp_restore_state (struct gfc_omp_saved_state *);
 
 /* expr.c */
 void gfc_free_actual_arglist (gfc_actual_arglist *);
--- gcc/fortran/resolve.c.jj	2011-01-15 11:26:40.000000000 +0100
+++ gcc/fortran/resolve.c	2011-01-17 18:30:42.917420785 +0100
@@ -2011,11 +2011,14 @@  resolve_global_procedure (gfc_symbol *sy
       if (!gsym->ns->resolved)
 	{
 	  gfc_dt_list *old_dt_list;
+	  struct gfc_omp_saved_state old_omp_state;
 
 	  /* Stash away derived types so that the backend_decls do not
 	     get mixed up.  */
 	  old_dt_list = gfc_derived_types;
 	  gfc_derived_types = NULL;
+	  /* And stash away openmp state.  */
+	  gfc_omp_save_and_clear_state (&old_omp_state);
 
 	  gfc_resolve (gsym->ns);
 
@@ -2025,6 +2028,8 @@  resolve_global_procedure (gfc_symbol *sy
 
 	  /* Restore the derived types of this namespace.  */
 	  gfc_derived_types = old_dt_list;
+	  /* And openmp state.  */
+	  gfc_omp_restore_state (&old_omp_state);
 	}
 
       /* Make sure that translation for the gsymbol occurs before
--- gcc/fortran/openmp.c.jj	2010-09-08 18:45:50.000000000 +0200
+++ gcc/fortran/openmp.c	2011-01-17 18:28:47.853567674 +0100
@@ -1390,6 +1390,31 @@  gfc_resolve_omp_parallel_blocks (gfc_cod
 }
 
 
+/* Save and clear openmp.c private state.  */
+
+void
+gfc_omp_save_and_clear_state (struct gfc_omp_saved_state *state)
+{
+  state->ptrs[0] = omp_current_ctx;
+  state->ptrs[1] = omp_current_do_code;
+  state->ints[0] = omp_current_do_collapse;
+  omp_current_ctx = NULL;
+  omp_current_do_code = NULL;
+  omp_current_do_collapse = 0;
+}
+
+
+/* Restore openmp.c private state from the saved state.  */
+
+void
+gfc_omp_restore_state (struct gfc_omp_saved_state *state)
+{
+  omp_current_ctx = (struct omp_context *) state->ptrs[0];
+  omp_current_do_code = (gfc_code *) state->ptrs[1];
+  omp_current_do_collapse = state->ints[0];
+}
+
+
 /* Note a DO iterator variable.  This is special in !$omp parallel
    construct, where they are predetermined private.  */
 
--- gcc/testsuite/gfortran.dg/gomp/pr47331.f90.jj	2011-01-17 18:41:09.218638419 +0100
+++ gcc/testsuite/gfortran.dg/gomp/pr47331.f90	2011-01-17 18:40:02.000000000 +0100
@@ -0,0 +1,24 @@ 
+! PR fortran/47331
+! { dg-do compile }
+! { dg-options "-fopenmp -fwhole-file" }
+
+subroutine foo
+  !$omp parallel
+    call bar ()
+  !$omp end parallel
+end subroutine foo
+
+subroutine bar
+  integer :: k
+  do k=1,5
+    call baz (k)
+  end do
+end subroutine bar
+
+subroutine baz (k)
+  integer :: k
+end subroutine
+
+program pr47331
+  call foo
+end program pr47331