[Commited] Fix libgomp mid-air collision on tree-cfg.c

Roger Sayle roger@eyesopen.com
Sat Apr 15 03:27:00 GMT 2006


The following patch resolves the bootstrap failure introduced by
Jakub Jelinek's commit of a patch for PR middle-end/26823.  The
problem is that this check-in accidentally reverted the tree-cfg.c
parts of Richard Henderson's patch for PR libgomp/26651 which was
checked in shortly before.

Compare the tree-cfg.c changes made by revision 112959
http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=112959
with the single small change that was intended from the post
http://gcc.gnu.org/ml/gcc-patches/2006-04/msg00492.html

Whilst I was at it I also corrected RTH's ChangeLog entry to
refer to "PR libgomp/26651" instead of just "PR 26651".


The following patch was commited to mainline as revision 112966,
after confirming that bootstrap on i686-pc-linux-gnu made it past
the point of the current bootstrap failure.



2006-04-14  Roger Sayle  <roger@eyesopen.com>

	* tree-cfg.c (make_edges, make_omp_sections_edges, move_stmt_r,
	is_ctrl_altering_stmt): Reinstate RTH's changes from r112935 that
	were accidentally reverted by r112959.


Index: tree-cfg.c
===================================================================
*** tree-cfg.c	(revision 112965)
--- tree-cfg.c	(working copy)
*************** static void make_edges (void);
*** 103,109 ****
  static void make_cond_expr_edges (basic_block);
  static void make_switch_expr_edges (basic_block);
  static void make_goto_expr_edges (basic_block);
- static void make_omp_sections_edges (basic_block);
  static edge tree_redirect_edge_and_branch (edge, basic_block);
  static edge tree_try_redirect_by_replacing_jump (edge, basic_block);
  static unsigned int split_critical_edges (void);
--- 103,108 ----
*************** static void
*** 447,452 ****
--- 446,452 ----
  make_edges (void)
  {
    basic_block bb;
+   struct omp_region *cur_region = NULL;

    /* Create an edge from entry to the first block with executable
       statements in it.  */
*************** make_edges (void)
*** 460,466 ****

        if (last)
  	{
! 	  switch (TREE_CODE (last))
  	    {
  	    case GOTO_EXPR:
  	      make_goto_expr_edges (bb);
--- 460,467 ----

        if (last)
  	{
! 	  enum tree_code code = TREE_CODE (last);
! 	  switch (code)
  	    {
  	    case GOTO_EXPR:
  	      make_goto_expr_edges (bb);
*************** make_edges (void)
*** 522,541 ****
  	    case OMP_ORDERED:
  	    case OMP_CRITICAL:
  	    case OMP_SECTION:
  	      fallthru = true;
  	      break;

- 	    case OMP_RETURN_EXPR:
- 	      /* In the case of an OMP_SECTION, we may have already made
- 		 an edge in make_omp_sections_edges.  */
- 	      fallthru = EDGE_COUNT (bb->succs) == 0;
- 	      break;
-
  	    case OMP_SECTIONS:
! 	      make_omp_sections_edges (bb);
  	      fallthru = false;
  	      break;

  	    default:
  	      gcc_assert (!stmt_ends_bb_p (last));
  	      fallthru = true;
--- 523,577 ----
  	    case OMP_ORDERED:
  	    case OMP_CRITICAL:
  	    case OMP_SECTION:
+ 	      cur_region = new_omp_region (bb, code, cur_region);
  	      fallthru = true;
  	      break;

  	    case OMP_SECTIONS:
! 	      cur_region = new_omp_region (bb, code, cur_region);
  	      fallthru = false;
  	      break;

+ 	    case OMP_RETURN:
+ 	      /* In the case of an OMP_SECTION, the edge will go somewhere
+ 		 other than the next block.  This will be created later.  */
+ 	      cur_region->exit = bb;
+ 	      fallthru = cur_region->type != OMP_SECTION;
+ 	      cur_region = cur_region->outer;
+ 	      break;
+
+ 	    case OMP_CONTINUE:
+ 	      cur_region->cont = bb;
+ 	      switch (cur_region->type)
+ 		{
+ 		case OMP_FOR:
+ 		  /* ??? Technically there should be a some sort of loopback
+ 		     edge here, but it goes to a block that doesn't exist yet,
+ 		     and without it, updating the ssa form would be a real
+ 		     bear.  Fortunately, we don't yet do ssa before expanding
+ 		     these nodes.  */
+ 		  break;
+
+ 		case OMP_SECTIONS:
+ 		  /* Wire up the edges into and out of the nested sections.  */
+ 		  /* ??? Similarly wrt loopback.  */
+ 		  {
+ 		    struct omp_region *i;
+ 		    for (i = cur_region->inner; i ; i = i->next)
+ 		      {
+ 			gcc_assert (i->type == OMP_SECTION);
+ 			make_edge (cur_region->entry, i->entry, 0);
+ 			make_edge (i->exit, bb, EDGE_FALLTHRU);
+ 		      }
+ 		  }
+ 		  break;
+
+ 		default:
+ 		  gcc_unreachable ();
+ 		}
+ 	      fallthru = true;
+ 	      break;
+
  	    default:
  	      gcc_assert (!stmt_ends_bb_p (last));
  	      fallthru = true;
*************** make_edges (void)
*** 548,553 ****
--- 584,592 ----
  	make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
      }

+   if (root_omp_region)
+     free_omp_regions ();
+
    /* Fold COND_EXPR_COND of each COND_EXPR.  */
    fold_cond_expr_cond ();

*************** make_edges (void)
*** 556,590 ****
  }


- /* Link an OMP_SECTIONS block to all the OMP_SECTION blocks in its body.  */
-
- static void
- make_omp_sections_edges (basic_block bb)
- {
-   basic_block exit_bb;
-   size_t i, n;
-   tree vec, stmt;
-
-   stmt = last_stmt (bb);
-   vec = OMP_SECTIONS_SECTIONS (stmt);
-   n = TREE_VEC_LENGTH (vec);
-   exit_bb = bb_for_stmt (TREE_VEC_ELT (vec, n - 1));
-
-   for (i = 0; i < n - 1; i += 2)
-     {
-       basic_block start_bb = bb_for_stmt (TREE_VEC_ELT (vec, i));
-       basic_block end_bb = bb_for_stmt (TREE_VEC_ELT (vec, i + 1));
-       make_edge (bb, start_bb, 0);
-       make_edge (end_bb, exit_bb, EDGE_FALLTHRU);
-     }
-
-   /* Once the CFG has been built, the vector of sections is no longer
-      useful.  The region can be easily obtained with build_omp_regions.
-      Furthermore, this sharing of tree expressions is not allowed by the
-      statement verifier.  */
-   OMP_SECTIONS_SECTIONS (stmt) = NULL_TREE;
- }
-
  /* Create the edges for a COND_EXPR starting at block BB.
     At this point, both clauses must contain only simple gotos.  */

--- 595,600 ----
*************** is_ctrl_altering_stmt (tree t)
*** 2498,2504 ****
      }

    /* OpenMP directives alter control flow.  */
!   if (flag_openmp && OMP_DIRECTIVE_P (t))
      return true;

    /* If a statement can throw, it alters control flow.  */
--- 2508,2514 ----
      }

    /* OpenMP directives alter control flow.  */
!   if (OMP_DIRECTIVE_P (t))
      return true;

    /* If a statement can throw, it alters control flow.  */
*************** move_stmt_r (tree *tp, int *walk_subtree
*** 4549,4555 ****
    if (p->block && IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (t))))
      TREE_BLOCK (t) = p->block;

!   if (OMP_DIRECTIVE_P (t) && TREE_CODE (t) != OMP_RETURN_EXPR)
      {
        /* Do not remap variables inside OMP directives.  Variables
  	 referenced in clauses and directive header belong to the
--- 4559,4567 ----
    if (p->block && IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (t))))
      TREE_BLOCK (t) = p->block;

!   if (OMP_DIRECTIVE_P (t)
!       && TREE_CODE (t) != OMP_RETURN
!       && TREE_CODE (t) != OMP_CONTINUE)
      {
        /* Do not remap variables inside OMP directives.  Variables
  	 referenced in clauses and directive header belong to the


Roger
-- 



More information about the Gcc-patches mailing list