This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gomp] Debug info support for OpenMP (PR debug/36617)


Hi!

Debug info was in theory supposed to work for OpenMP, we were keeping
VAR_DECLs with DECL_VALUE_EXPR e.g. for shared variables around, etc.
But in reality nothing was actually emitted.  One of the problems
was that the DECL_INITIAL BLOCK of the destination ompfn didn't
have TREE_USED set, and setting it to 1 showed a lot of issues,
like all the variables were put into that one BLOCK, no subblocks
of the #pragma omp parallel/#pragma omp task were moved over to
the new function, worksharing constructs didn't care to preserve
BLOCKs, etc.  Also, locus on many statements was incorrect.
The following patch fixes this, with -g -O0 -fopenmp on the attached
testcase I get useful debugging session (especially with OMP_NUM_THREADS=1
to avoid things in parallel), seeing the privatized and shared variables
that should be seen.  For #pragma omp parallel (and task too) one steps
into the artificial *ompfn* function and isn't able to see there
the local variables of the original function that aren't ever mentioned
in the construct, except by doing up and looking at them in the parent
frame.  If you have suggestions how to further improve this, please let
me know.

Diego, does this look ok?

2008-06-26  Jakub Jelinek  <jakub@redhat.com>

	PR debug/36617
	* tree-cfg.c (struct move_stmt_d): Replace block field with
	orig_block and new_block fields.
	(move_stmt_r): Only set TREE_BLOCK to p->new_block if
	if it used to be NULL, p->orig_block or if p->orig_block is NULL.
	(move_block_to_fn): Replace vars_map and new_label_map arguments
	with struct move_stmt_d pointer.
	(replace_block_vars_by_duplicates): New function.
	(move_sese_region_to_fn): Add ORIG_BLOCK argument.  Adjust
	move_block_to_fn caller.  If ORIG_BLOCK is non-NULL, move over
	all subblocks of ORIG_BLOCK to the new function.  Call
	replace_block_vars_by_duplicates.
	* tree-flow.h (move_sese_region_to_fn): Adjust prototype.
	* omp-low.c (expand_omp_taskreg): Set TREE_USED on DECL_INITIAL
	BLOCK of the new function.  Adjust move_sese_region_to_fn caller.
	Prune vars with original DECL_CONTEXT from child_cfun->local_decls.
	(expand_omp): Temporarily set input_location to the location of
	region's controlling stmt.
	(lower_omp_sections, lower_omp_for): Add a BLOCK into outermost
	BIND_EXPR, push ctx->block_vars and gimplification vars into
	the BIND_EXPR and its block's BLOCK_VARS instead of directly
	into dest function.
	(lower_omp_single): Set TREE_USED on the BIND_EXPR's BLOCK if
	there are any BLOCK_VARS.
	(lower_omp_taskreg): Set BLOCK on a BIND_EXPR containing the
	OMP_PARALLEL or OMP_TASK stmt.
	(lower_omp): Save and restore input_location around the lower_omp_1
	call.

	* testsuite/libgomp.c/debug-1.c: New test.

--- gcc/tree-cfg.c.jj	2008-06-26 16:35:40.000000000 +0200
+++ gcc/tree-cfg.c	2008-06-26 19:49:17.000000000 +0200
@@ -5665,7 +5665,8 @@ replace_ssa_name (tree name, struct poin
 
 struct move_stmt_d
 {
-  tree block;
+  tree orig_block;
+  tree new_block;
   tree from_context;
   tree to_context;
   struct pointer_map_t *vars_map;
@@ -5674,8 +5675,8 @@ struct move_stmt_d
 };
 
 /* Helper for move_block_to_fn.  Set TREE_BLOCK in every expression
-   contained in *TP and change the DECL_CONTEXT of every local
-   variable referenced in *TP.  */
+   contained in *TP if it has been ORIG_BLOCK previously and change the
+   DECL_CONTEXT of every local variable referenced in *TP.  */
 
 static tree
 move_stmt_r (tree *tp, int *walk_subtrees, void *data)
@@ -5683,9 +5684,22 @@ move_stmt_r (tree *tp, int *walk_subtree
   struct move_stmt_d *p = (struct move_stmt_d *) data;
   tree t = *tp;
 
-  if (p->block
-      && (EXPR_P (t) || GIMPLE_STMT_P (t)))
-    TREE_BLOCK (t) = p->block;
+  if (EXPR_P (t) || GIMPLE_STMT_P (t))
+    {
+      tree block = TREE_BLOCK (t);
+      if (p->orig_block == NULL_TREE
+	  || block == p->orig_block
+	  || block == NULL_TREE)
+	TREE_BLOCK (t) = p->new_block;
+#ifdef ENABLE_CHECKING
+      else if (block != p->new_block)
+	{
+	  while (block && block != p->orig_block)
+	    block = BLOCK_SUPERCONTEXT (block);
+	  gcc_assert (block);
+	}
+#endif
+    }
 
   if (OMP_DIRECTIVE_P (t)
       && TREE_CODE (t) != OMP_RETURN
@@ -5792,14 +5806,12 @@ mark_virtual_ops_in_region (VEC (basic_b
 static void
 move_block_to_fn (struct function *dest_cfun, basic_block bb,
 		  basic_block after, bool update_edge_count_p,
-		  struct pointer_map_t *vars_map, htab_t new_label_map,
-		  int eh_offset)
+		  struct move_stmt_d *d, int eh_offset)
 {
   struct control_flow_graph *cfg;
   edge_iterator ei;
   edge e;
   block_stmt_iterator si;
-  struct move_stmt_d d;
   unsigned old_len, new_len;
   tree phi, next_phi;
 
@@ -5856,33 +5868,22 @@ move_block_to_fn (struct function *dest_
 	  continue;
 	}
 
-      SET_PHI_RESULT (phi, replace_ssa_name (op, vars_map, dest_cfun->decl));
+      SET_PHI_RESULT (phi,
+		      replace_ssa_name (op, d->vars_map, dest_cfun->decl));
       FOR_EACH_PHI_ARG (use, phi, oi, SSA_OP_USE)
 	{
 	  op = USE_FROM_PTR (use);
 	  if (TREE_CODE (op) == SSA_NAME)
-	    SET_USE (use, replace_ssa_name (op, vars_map, dest_cfun->decl));
+	    SET_USE (use, replace_ssa_name (op, d->vars_map, dest_cfun->decl));
 	}
     }
 
-  /* The statements in BB need to be associated with a new TREE_BLOCK.
-     Labels need to be associated with a new label-to-block map.  */
-  memset (&d, 0, sizeof (d));
-  d.vars_map = vars_map;
-  d.from_context = cfun->decl;
-  d.to_context = dest_cfun->decl;
-  d.new_label_map = new_label_map;
-
   for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
     {
       tree stmt = bsi_stmt (si);
       int region;
 
-      d.remap_decls_p = true;
-      if (TREE_BLOCK (stmt))
-	d.block = DECL_INITIAL (dest_cfun->decl);
-
-      walk_tree (&stmt, move_stmt_r, &d, NULL);
+      walk_tree (&stmt, move_stmt_r, d, NULL);
 
       if (TREE_CODE (stmt) == LABEL_EXPR)
 	{
@@ -5989,6 +5990,35 @@ new_label_mapper (tree decl, void *data)
   return m->to;
 }
 
+/* Change DECL_CONTEXT of all BLOCK_VARS in block, including
+   subblocks.  */
+
+static void
+replace_block_vars_by_duplicates (tree block, struct pointer_map_t *vars_map,
+				  tree to_context)
+{
+  tree *tp, t;
+
+  for (tp = &BLOCK_VARS (block); *tp; tp = &TREE_CHAIN (*tp))
+    {
+      t = *tp;
+      replace_by_duplicate_decl (&t, vars_map, to_context);
+      if (t != *tp)
+	{
+	  if (TREE_CODE (*tp) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (*tp))
+	    {
+	      SET_DECL_VALUE_EXPR (t, DECL_VALUE_EXPR (*tp));
+	      DECL_HAS_VALUE_EXPR_P (t) = 1;
+	    }
+	  TREE_CHAIN (t) = TREE_CHAIN (*tp);
+	  *tp = t;
+	}
+    }
+
+  for (block = BLOCK_SUBBLOCKS (block); block; block = BLOCK_CHAIN (block))
+    replace_block_vars_by_duplicates (block, vars_map, to_context);
+}
+
 /* Move a single-entry, single-exit region delimited by ENTRY_BB and
    EXIT_BB to function DEST_CFUN.  The whole region is replaced by a
    single basic block in the original CFG and the new basic block is
@@ -5999,13 +6029,17 @@ new_label_mapper (tree decl, void *data)
    is that ENTRY_BB should be the only entry point and it must
    dominate EXIT_BB.
 
+   Change TREE_BLOCK of all statements in ORIG_BLOCK to the new
+   functions outermost BLOCK, move all subblocks of ORIG_BLOCK
+   to the new function.
+
    All local variables referenced in the region are assumed to be in
    the corresponding BLOCK_VARS and unexpanded variable lists
    associated with DEST_CFUN.  */
 
 basic_block
 move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
-		        basic_block exit_bb)
+		        basic_block exit_bb, tree orig_block)
 {
   VEC(basic_block,heap) *bbs, *dom_bbs;
   basic_block dom_entry = get_immediate_dominator (CDI_DOMINATORS, entry_bb);
@@ -6019,6 +6053,7 @@ move_sese_region_to_fn (struct function 
   htab_t new_label_map;
   struct pointer_map_t *vars_map;
   struct loop *loop = entry_bb->loop_father;
+  struct move_stmt_d d;
 
   /* If ENTRY does not strictly dominate EXIT, this cannot be an SESE
      region.  */
@@ -6115,16 +6150,42 @@ move_sese_region_to_fn (struct function 
   gcc_assert (VEC_length (basic_block, bbs) >= 2);
   after = dest_cfun->cfg->x_entry_block_ptr;
   vars_map = pointer_map_create ();
+
+  memset (&d, 0, sizeof (d));
+  d.vars_map = vars_map;
+  d.from_context = cfun->decl;
+  d.to_context = dest_cfun->decl;
+  d.new_label_map = new_label_map;
+  d.remap_decls_p = true;
+  d.orig_block = orig_block;
+  d.new_block = DECL_INITIAL (dest_cfun->decl);
+
   for (i = 0; VEC_iterate (basic_block, bbs, i, bb); i++)
     {
       /* No need to update edge counts on the last block.  It has
 	 already been updated earlier when we detached the region from
 	 the original CFG.  */
-      move_block_to_fn (dest_cfun, bb, after, bb != exit_bb, vars_map,
-	                new_label_map, eh_offset);
+      move_block_to_fn (dest_cfun, bb, after, bb != exit_bb, &d, eh_offset);
       after = bb;
     }
 
+  /* Rewire BLOCK_SUBBLOCKS of orig_block.  */
+  if (orig_block)
+    {
+      tree block;
+      gcc_assert (BLOCK_SUBBLOCKS (DECL_INITIAL (dest_cfun->decl))
+		  == NULL_TREE);
+      BLOCK_SUBBLOCKS (DECL_INITIAL (dest_cfun->decl))
+	= BLOCK_SUBBLOCKS (orig_block);
+      for (block = BLOCK_SUBBLOCKS (orig_block);
+	   block; block = BLOCK_CHAIN (block))
+	BLOCK_SUPERCONTEXT (block) = DECL_INITIAL (dest_cfun->decl);
+      BLOCK_SUBBLOCKS (orig_block) = NULL_TREE;
+    }
+
+  replace_block_vars_by_duplicates (DECL_INITIAL (dest_cfun->decl),
+				    vars_map, dest_cfun->decl);
+
   if (new_label_map)
     htab_delete (new_label_map);
   pointer_map_destroy (vars_map);
--- gcc/tree-flow.h.jj	2008-06-26 16:35:40.000000000 +0200
+++ gcc/tree-flow.h	2008-06-26 16:45:36.000000000 +0200
@@ -1,5 +1,5 @@
 /* Data and Control Flow Analysis for Trees.
-   Copyright (C) 2001, 2003, 2004, 2005, 2006, 2007
+   Copyright (C) 2001, 2003, 2004, 2005, 2006, 2007, 2008
    Free Software Foundation, Inc.
    Contributed by Diego Novillo <dnovillo@redhat.com>
 
@@ -788,7 +788,7 @@ extern void replace_uses_by (tree, tree)
 extern void start_recording_case_labels (void);
 extern void end_recording_case_labels (void);
 extern basic_block move_sese_region_to_fn (struct function *, basic_block,
-				           basic_block);
+				           basic_block, tree);
 void remove_edge_and_dominated_blocks (edge);
 void mark_virtual_ops_in_bb (basic_block);
 
--- gcc/omp-low.c.jj	2008-06-26 16:35:56.000000000 +0200
+++ gcc/omp-low.c	2008-06-27 12:42:28.000000000 +0200
@@ -3140,7 +3140,7 @@ expand_omp_taskreg (struct omp_region *r
 {
   basic_block entry_bb, exit_bb, new_bb;
   struct function *child_cfun;
-  tree child_fn, block, t, ws_args;
+  tree child_fn, block, t, ws_args, *tp;
   block_stmt_iterator si;
   tree entry_stmt;
   edge e;
@@ -3251,6 +3251,7 @@ expand_omp_taskreg (struct omp_region *r
       block = DECL_INITIAL (child_fn);
       BLOCK_VARS (block) = list2chain (child_cfun->local_decls);
       DECL_SAVED_TREE (child_fn) = bb_stmt_list (single_succ (entry_bb));
+      TREE_USED (block) = 1;
 
       /* Reset DECL_CONTEXT on function arguments.  */
       for (t = DECL_ARGUMENTS (child_fn); t; t = TREE_CHAIN (t))
@@ -3287,11 +3288,22 @@ expand_omp_taskreg (struct omp_region *r
 	  init_ssa_operands ();
 	  cfun->gimple_df->in_ssa_p = true;
 	  pop_cfun ();
+	  block = NULL_TREE;
 	}
-      new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb);
+      else
+	block = TREE_BLOCK (entry_stmt);
+
+      new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb, block);
       if (exit_bb)
 	single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
 
+      /* Remove non-local VAR_DECLs from child_cfun->local_decls list.  */
+      for (tp = &child_cfun->local_decls; *tp; )
+	if (DECL_CONTEXT (TREE_VALUE (*tp)) != cfun->decl)
+	  tp = &TREE_CHAIN (*tp);
+	else
+	  *tp = TREE_CHAIN (*tp);
+
       /* Inform the callgraph about the new function.  */
       DECL_STRUCT_FUNCTION (child_fn)->curr_properties
 	= cfun->curr_properties;
@@ -5030,6 +5042,8 @@ expand_omp (struct omp_region *region)
 {
   while (region)
     {
+      location_t saved_location;
+
       /* First, determine whether this is a combined parallel+workshare
        	 region.  */
       if (region->type == OMP_PARALLEL)
@@ -5038,6 +5052,10 @@ expand_omp (struct omp_region *region)
       if (region->inner)
 	expand_omp (region->inner);
 
+      saved_location = input_location;
+      if (EXPR_HAS_LOCATION (last_stmt (region->entry)))
+	input_location = EXPR_LOCATION (last_stmt (region->entry));
+
       switch (region->type)
 	{
 	case OMP_PARALLEL:
@@ -5075,11 +5093,11 @@ expand_omp (struct omp_region *region)
 	  expand_omp_atomic (region);
 	  break;
 
-
 	default:
 	  gcc_unreachable ();
 	}
 
+      input_location = saved_location;
       region = region->next;
     }
 }
@@ -5312,12 +5330,18 @@ lower_omp_sections (tree *stmt_p, omp_co
   olist = NULL_TREE;
   lower_reduction_clauses (OMP_SECTIONS_CLAUSES (stmt), &olist, ctx);
 
-  pop_gimplify_context (NULL_TREE);
-  record_vars_into (ctx->block_vars, ctx->cb.dst_fn);
-
-  new_stmt = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
+  block = make_node (BLOCK);
+  new_stmt = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
   TREE_SIDE_EFFECTS (new_stmt) = 1;
 
+  pop_gimplify_context (new_stmt);
+
+  BIND_EXPR_VARS (new_stmt)
+    = chainon (BIND_EXPR_VARS (new_stmt), ctx->block_vars);
+  BLOCK_VARS (block) = BIND_EXPR_VARS (new_stmt);
+  if (BLOCK_VARS (block))
+    TREE_USED (block) = 1;
+
   new_body = alloc_stmt_list ();
   append_to_statement_list (ilist, &new_body);
   append_to_statement_list (stmt, &new_body);
@@ -5491,6 +5515,8 @@ lower_omp_single (tree *stmt_p, omp_cont
 
   BIND_EXPR_VARS (bind) = chainon (BIND_EXPR_VARS (bind), ctx->block_vars);
   BLOCK_VARS (block) = BIND_EXPR_VARS (bind);
+  if (BLOCK_VARS (block))
+    TREE_USED (block) = 1;
 }
 
 
@@ -5714,7 +5740,7 @@ lower_omp_for_lastprivate (struct omp_fo
 static void
 lower_omp_for (tree *stmt_p, omp_context *ctx)
 {
-  tree t, stmt, ilist, dlist, new_stmt, *body_p, *rhs_p;
+  tree t, stmt, ilist, dlist, new_stmt, block, *body_p, *rhs_p;
   struct omp_for_data fd;
   int i;
 
@@ -5725,14 +5751,17 @@ lower_omp_for (tree *stmt_p, omp_context
   lower_omp (&OMP_FOR_PRE_BODY (stmt), ctx);
   lower_omp (&OMP_FOR_BODY (stmt), ctx);
 
+  block = make_node (BLOCK);
+  new_stmt = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
+  TREE_SIDE_EFFECTS (new_stmt) = 1;
+  body_p = &BIND_EXPR_BODY (new_stmt);
+
   /* Move declaration of temporaries in the loop body before we make
      it go away.  */
   if (TREE_CODE (OMP_FOR_BODY (stmt)) == BIND_EXPR)
-    record_vars_into (BIND_EXPR_VARS (OMP_FOR_BODY (stmt)), ctx->cb.dst_fn);
-
-  new_stmt = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
-  TREE_SIDE_EFFECTS (new_stmt) = 1;
-  body_p = &BIND_EXPR_BODY (new_stmt);
+    BIND_EXPR_VARS (new_stmt)
+      = chainon (BIND_EXPR_VARS (new_stmt),
+		 BIND_EXPR_VARS (OMP_FOR_BODY (stmt)));
 
   /* The pre-body and input clauses go before the lowered OMP_FOR.  */
   ilist = NULL;
@@ -5786,8 +5815,12 @@ lower_omp_for (tree *stmt_p, omp_context
   OMP_RETURN_NOWAIT (t) = fd.have_nowait;
   append_to_statement_list (t, body_p);
 
-  pop_gimplify_context (NULL_TREE);
-  record_vars_into (ctx->block_vars, ctx->cb.dst_fn);
+  pop_gimplify_context (new_stmt);
+  BIND_EXPR_VARS (new_stmt)
+    = chainon (BIND_EXPR_VARS (new_stmt), ctx->block_vars);
+  BLOCK_VARS (block) = BIND_EXPR_VARS (new_stmt);
+  if (BLOCK_VARS (block))
+    TREE_USED (block) = 1;
 
   OMP_FOR_BODY (stmt) = NULL_TREE;
   OMP_FOR_PRE_BODY (stmt) = NULL_TREE;
@@ -6157,8 +6190,9 @@ lower_omp_taskreg (tree *stmt_p, omp_con
 
   /* Once all the expansions are done, sequence all the different
      fragments inside OMP_TASKREG_BODY.  */
-  bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
-  append_to_statement_list (ilist, &BIND_EXPR_BODY (bind));
+  bind = build3 (BIND_EXPR, void_type_node, NULL, NULL,
+		 BIND_EXPR_BLOCK (par_bind));
+  TREE_SIDE_EFFECTS (bind) = 1;
 
   new_body = alloc_stmt_list ();
 
@@ -6180,7 +6214,14 @@ lower_omp_taskreg (tree *stmt_p, omp_con
   OMP_TASKREG_BODY (stmt) = new_body;
 
   append_to_statement_list (stmt, &BIND_EXPR_BODY (bind));
-  append_to_statement_list (olist, &BIND_EXPR_BODY (bind));
+  if (ilist || olist)
+    {
+      append_to_statement_list (bind, &ilist);
+      append_to_statement_list (olist, &ilist);
+      bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
+      TREE_SIDE_EFFECTS (bind) = 1;
+      append_to_statement_list (ilist, &BIND_EXPR_BODY (bind));
+    }
 
   *stmt_p = bind;
 
@@ -6363,7 +6404,9 @@ lower_omp_1 (tree *tp, omp_context *ctx,
 static void
 lower_omp (tree *stmt_p, omp_context *ctx)
 {
+  location_t saved_location = input_location;
   lower_omp_1 (stmt_p, ctx, NULL);
+  input_location = saved_location;
 }
 
 /* Main entry point.  */
--- libgomp/testsuite/libgomp.c/debug-1.c.jj	2008-06-27 15:26:04.000000000 +0200
+++ libgomp/testsuite/libgomp.c/debug-1.c	2008-06-27 15:25:41.000000000 +0200
@@ -0,0 +1,162 @@
+/* PR debug/36617 */
+/* { dg-do run } */
+/* { dg-options "-g -fopenmp -O0" } */
+
+int
+f1 (void)
+{
+  int v1i, v1j, v1k, v1l = 0;
+  v1i = 6;
+  v1j = 8;
+  #pragma omp parallel private (v1k) firstprivate (v1j) shared (v1i) reduction (+:v1l)
+  {
+    v1k = v1i + v1j;
+    {
+      int v1m = 1;
+      v1l = v1m;
+    }
+  }
+  return v1l;
+}
+
+int v2k = 9;
+
+int
+f2 (void)
+{
+  int v2i = 6, v2j = 7;
+  #pragma omp single private (v2i) firstprivate (v2k)
+  {
+    int v2l = v2j + v2k;
+    v2i = 8;
+    v2k = 10;
+    v2j = v2l + v2i;
+  }
+  return v2i + v2j;
+}
+
+int
+f3 (void)
+{
+  int v3i = 6, v3j = 7, v3k = 9;
+  #pragma omp parallel
+  {
+    #pragma omp master
+      v3i++;
+    #pragma omp single private (v3i) firstprivate (v3k)
+    {
+      int v3l = v3j + v3k;
+      v3i = 8;
+      v3k = 10;
+      v3j = v3l + v3i;
+    }
+    #pragma omp atomic
+      v3k++;
+  }
+  return v3i + v3j;
+}
+
+int v4k = 9, v4l = 0;
+
+int
+f4 (void)
+{
+  int v4i = 6, v4j = 7, v4n = 0;
+  #pragma omp sections private (v4i) firstprivate (v4k) reduction (+:v4l)
+  {
+    #pragma omp section
+    {
+      int v4m = v4j + v4k;
+      v4i = 8;
+      v4k = 10;
+      v4l++;
+      v4n = v4m + v4i;
+    }
+    #pragma omp section
+    {
+      int v4o = v4j + v4k;
+      v4i = 10;
+      v4k = 11;
+      v4l++;
+    }
+  }
+  return v4i + v4j + v4l + v4n;
+}
+
+int
+f5 (void)
+{
+  int v5i = 6, v5j = 7, v5k = 9, v5l = 0, v5n = 0, v5p = 0;
+  #pragma omp parallel
+  {
+    #pragma omp master
+      v5p++;
+    #pragma omp sections private (v5i) firstprivate (v5k) reduction (+:v5l)
+    {
+      #pragma omp section
+      {
+	int v5m = v5j + v5k;
+	v5i = 8;
+	v5k = 10;
+	v5l++;
+	v5n = v5m + v5i;
+      }
+      #pragma omp section
+      {
+	int v5o = v5j + v5k;
+	v5i = 10;
+	v5k = 11;
+	v5l++;
+      }
+    }
+  }
+  return v5i + v5j + v5l + v5n + v5p;
+}
+
+int v6k = 9, v6l = 0;
+
+int
+f6 (void)
+{
+  int v6i = 6, v6j = 7, v6n = 0;
+  #pragma omp for private (v6i) firstprivate (v6k) reduction (+:v6l)
+  for (v6n = 0; v6n < 3; v6n++)
+    {
+      int v6m = v6j + v6k;
+      v6i = 8;
+      v6l++;
+    }
+  return v6i + v6j + v6k + v6l + v6n;
+}
+
+int
+f7 (void)
+{
+  int v7i = 6, v7j = 7, v7k = 9, v7l = 0, v7n = 0, v7o = 1;
+  #pragma omp parallel
+  {
+    #pragma omp master
+      v7o++;
+    #pragma omp for private (v7i) firstprivate (v7k) reduction (+:v7l)
+    for (v7n = 0; v7n < 3; v7n++)
+      {
+	int v7m = v7j + v7k;
+	v7i = 8;
+	v7l++;
+      }
+  }
+  return v7i + v7j + v7k + v7l + v7n;
+}
+
+int
+main (void)
+{
+  f1 ();
+  f2 ();
+  f3 ();
+  f4 ();
+  f5 ();
+  f6 ();
+  f7 ();
+  return 0;
+}

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]