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]

Re: CFG fixup after early inlining


> > Yes, it is not supposed to happen so early.  fixup_cfg does two things -
> > it clears EH after setting after_inlining to tru and it adds edtges for
> > non-local gotos.  It looks like proper way is to break out this code and
> > move it to inliner (I must admit I am not sure at all why I placed it in
> > fixup cfg at first place, perhaps I just didn't wanted to introduce
> > another pass over GIMPLE and early inlining didn't exist at that time).
> 
> I wrote this non-local gotos fixup code. :-)
:)
> 
> > I can prepare patch this evening and send you it for testing (and try to
> > reproduce problem on my setup too)
> 
> Fine with me.  Thanks for stepping in, I'm not familiar enough with the new 
> machinery yet to write something well thought out here.
> 
> > Sorry for the problem,
> 
> No problem, the mainline FSF Ada compiler is in good shape, we only detected 
> the bug because we use slightly different settings locally.

Hi,
sorry for taking more time than expected for the patch.  This is what I
am testing now.

	* tree-optimize.c (has_abnormal_outgoing_edge_p): Move to tree-inline.
	(execute_fixup_cfg): Break out the abnormal goto code.
	* tree-inline.c (has_abnormal_outgoing_edge_p): Move here from
	tree-inline.c
	(make_nonlocal_label_edges): Move here from execute_fixup_cfg.
	(optimize_inline_calls): Call make_nonlocal_label_edges.
Index: tree-optimize.c
===================================================================
--- tree-optimize.c	(revision 121142)
+++ tree-optimize.c	(working copy)
@@ -267,25 +267,9 @@ struct tree_opt_pass pass_free_cfg_annot
   0					/* letter */
 };
 
-/* Return true if BB has at least one abnormal outgoing edge.  */
-
-static inline bool
-has_abnormal_outgoing_edge_p (basic_block bb)
-{
-  edge e;
-  edge_iterator ei;
-
-  FOR_EACH_EDGE (e, ei, bb->succs)
-    if (e->flags & EDGE_ABNORMAL)
-      return true;
-
-  return false;
-}
-
 /* Pass: fixup_cfg.  IPA passes, compilation of earlier functions or inlining
-   might have changed some properties, such as marked functions nothrow or
-   added calls that can potentially go to non-local labels.  Remove redundant
-   edges and basic blocks, and create new ones if necessary.
+   might have changed some properties, such as marked functions nothrow.
+   Remove redundant edges and basic blocks, and create new ones if necessary.
 
    This pass can't be executed as stand alone pass from pass manager, because
    in between inlining and this fixup the verify_flow_info would fail.  */
@@ -327,58 +317,11 @@ execute_fixup_cfg (void)
           todo |= TODO_cleanup_cfg;
       }
 
-  if (current_function_has_nonlocal_label)
-    {
-      FOR_EACH_BB (bb)
-	{
-	  for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
-	    {
-	      tree stmt = bsi_stmt (bsi);
-	      if (tree_can_make_abnormal_goto (stmt))
-		{
-		  if (stmt == bsi_stmt (bsi_last (bb)))
-		    {
-		      if (!has_abnormal_outgoing_edge_p (bb))
-			make_abnormal_goto_edges (bb, true);
-		    }
-		  else
-		    {
-		      edge e = split_block (bb, stmt);
-		      bb = e->src;
-		      make_abnormal_goto_edges (bb, true);
-		    }
-		  break;
-		}
-
-	      /* Update PHIs on nonlocal goto receivers we (possibly)
-		 just created new edges into.  */
-	      if (TREE_CODE (stmt) == LABEL_EXPR
-		  && gimple_in_ssa_p (cfun))
-		{
-		  tree target = LABEL_EXPR_LABEL (stmt);
-		  if (DECL_NONLOCAL (target))
-		    {
-		      tree phi;
-
-		      for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
-			{
-		          todo |= TODO_update_ssa | TODO_cleanup_cfg;
-			  gcc_assert (SSA_NAME_OCCURS_IN_ABNORMAL_PHI
-				      (PHI_RESULT (phi)));
-			  mark_sym_for_renaming
-			    (SSA_NAME_VAR (PHI_RESULT (phi)));
-			}
-		    }
-		}
-	    }
-	}
-    }
-
   /* Dump a textual representation of the flowgraph.  */
   if (dump_file)
     dump_tree_cfg (dump_file, dump_flags);
 
   return todo;
 }
 
 /* Do the actions required to initialize internal data structures used
Index: tree-inline.c
===================================================================
--- tree-inline.c	(revision 121142)
+++ tree-inline.c	(working copy)
@@ -2611,6 +2622,75 @@ fold_marked_statements (int first, struc
       }
 }
 
+/* Return true if BB has at least one abnormal outgoing edge.  */
+
+static inline bool
+has_abnormal_outgoing_edge_p (basic_block bb)
+{
+  edge e;
+  edge_iterator ei;
+
+  FOR_EACH_EDGE (e, ei, bb->succs)
+    if (e->flags & EDGE_ABNORMAL)
+      return true;
+
+  return false;
+}
+
+/* When the function has nonlocal labels we need to produce edges to each
+   of them.  Since new labels possibly appeared during inlining, we need to
+   scan entire function body.  */
+
+static void
+make_nonlocal_label_edges (void)
+{
+  block_stmt_iterator bsi;
+  basic_block bb;
+
+  FOR_EACH_BB (bb)
+    {
+      for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+	{
+	  tree stmt = bsi_stmt (bsi);
+	  if (tree_can_make_abnormal_goto (stmt))
+	    {
+	      if (stmt == bsi_stmt (bsi_last (bb)))
+		{
+		  if (!has_abnormal_outgoing_edge_p (bb))
+		    make_abnormal_goto_edges (bb, true);
+		}
+	      else
+		{
+		  edge e = split_block (bb, stmt);
+		  bb = e->src;
+		  make_abnormal_goto_edges (bb, true);
+		}
+	      break;
+	    }
+
+	  /* Update PHIs on nonlocal goto receivers we (possibly)
+	     just created new edges into.  */
+	  if (TREE_CODE (stmt) == LABEL_EXPR
+	      && gimple_in_ssa_p (cfun))
+	    {
+	      tree target = LABEL_EXPR_LABEL (stmt);
+	      if (DECL_NONLOCAL (target))
+		{
+		  tree phi;
+
+		  for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+		    {
+		      gcc_assert (SSA_NAME_OCCURS_IN_ABNORMAL_PHI
+				  (PHI_RESULT (phi)));
+		      mark_sym_for_renaming
+			(SSA_NAME_VAR (PHI_RESULT (phi)));
+		    }
+		}
+	    }
+	}
+    }
+}
+
 /* Expand calls to inline functions in the body of FN.  */
 
 unsigned int
@@ -2686,6 +2766,8 @@ optimize_inline_calls (tree fn)
   fold_marked_statements (last, id.statements_to_fold);
   pointer_set_destroy (id.statements_to_fold);
   fold_cond_expr_cond ();
+  if (current_function_has_nonlocal_label)
+    make_nonlocal_label_edges ();
   /* We make no attempts to keep dominance info up-to-date.  */
   free_dominance_info (CDI_DOMINATORS);
   free_dominance_info (CDI_POST_DOMINATORS);


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