From b357f682db35f4431e3011e7486a0ac865686e3e Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@redhat.com>
Date: Fri, 27 Jun 2008 21:42:32 +0200
Subject: [PATCH] re PR debug/36617 (Debug info for OpenMP code is almost
 non-existent)

	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.

From-SVN: r137198
---
 gcc/ChangeLog                         |  31 +++++
 gcc/omp-low.c                         |  79 ++++++++++---
 gcc/tree-cfg.c                        | 115 +++++++++++++-----
 gcc/tree-flow.h                       |   4 +-
 libgomp/ChangeLog                     |   5 +
 libgomp/testsuite/libgomp.c/debug-1.c | 162 ++++++++++++++++++++++++++
 6 files changed, 349 insertions(+), 47 deletions(-)
 create mode 100644 libgomp/testsuite/libgomp.c/debug-1.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f1279f8b7af0..38ce1cff5945 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,34 @@
+2008-06-27  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.
+
 2008-06-27  Richard Guenther  <rguenther@suse.de>
 
 	PR tree-optimization/36400
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index e26ebbcb9d70..e5680077bd0a 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -3140,7 +3140,7 @@ expand_omp_taskreg (struct omp_region *region)
 {
   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 *region)
       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 *region)
 	  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_context *ctx)
   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_context *ctx)
 
   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_for_data *fd, tree *body_p,
 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 *ctx)
   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 *ctx)
   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_context *ctx)
 
   /* 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_context *ctx)
   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, tree_stmt_iterator *tsi)
 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.  */
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 50f53a080e83..341a1de749d9 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -5665,7 +5665,8 @@ replace_ssa_name (tree name, struct pointer_map_t *vars_map,
 
 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_subtrees, void *data)
   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_block,heap) *bbs)
 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_cfun, basic_block bb,
 	  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 *dest_cfun, basic_block entry_bb,
   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 *dest_cfun, basic_block entry_bb,
   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);
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index 15329ac002ec..ded7687b75eb 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -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);
 
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index ed27454354ea..18e1bf7c43a0 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,8 @@
+2008-06-27  Jakub Jelinek  <jakub@redhat.com>
+
+	PR debug/36617
+	* testsuite/libgomp.c/debug-1.c: New test.
+
 2008-06-19  Jakub Jelinek  <jakub@redhat.com>
 
 	* testsuite/libgomp.c/nqueens-1.c: New test.
diff --git a/libgomp/testsuite/libgomp.c/debug-1.c b/libgomp/testsuite/libgomp.c/debug-1.c
new file mode 100644
index 000000000000..09bcf7f3cc1b
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/debug-1.c
@@ -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;
+}
-- 
GitLab