public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [RFC] Remove kludge in commit_edge_insertions
@ 2011-04-04 21:09 Eric Botcazou
  2011-04-06 16:59 ` Jeff Law
  2011-04-07 21:14 ` Eric Botcazou
  0 siblings, 2 replies; 10+ messages in thread
From: Eric Botcazou @ 2011-04-04 21:09 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1889 bytes --]

commit_edge_insertions contains this kludge:

  /* In the old rtl CFG API, it was OK to insert control flow on an
     edge, apparently?  In cfglayout mode, this will *not* work, and
     the caller is responsible for making sure that control flow is
     valid at all times.  */
  if (current_ir_type () == IR_RTL_CFGLAYOUT)
    return;

  blocks = sbitmap_alloc (last_basic_block);
  sbitmap_zero (blocks);
  FOR_EACH_BB (bb)
    if (bb->aux)
      {
	SET_BIT (blocks, bb->index);
	/* Check for forgotten bb->aux values before commit_edge_insertions
	   call.  */
	gcc_assert (bb->aux == &bb->aux);
	bb->aux = NULL;
      }
  find_many_sub_basic_blocks (blocks);
  sbitmap_free (blocks);


At least on x86/x86-64, there is apparently only one case where control flow 
insns are inserted on edges: when the prologue is inserted on the entry edge.
Once this is accounted for, the above kludge can be removed, provided that the 
force_nonfallthru RTL routine is enhanced to preserve the loop nest structure.
The result is the attached patch, bootstrapped/regtested on x86 and x86-64.

I'll be testing it on IA-64 and SPARC over the next few days if there is an 
agreement that this is a progress.


	* basic-block.h (force_nonfallthru): Move to...
	* cfghooks.h (struct cfg_hooks): Add force_nonfallthru hook.
	(force_nonfallthru): ...here.
	* cfghooks.c (force_nonfallthru): New function.
	* cfgrtl.c (force_nonfallthru): Rename into...
	(rtl_force_nonfallthru): ...this.
	(commit_one_edge_insertion): Do not set AUX field.
	(commit_edge_insertions): Do not discover new basic blocks.
	(rtl_cfg_hooks): Add rtl_force_nonfallthru.
	(cfg_layout_rtl_cfg_hooks): Likewise.
	* function.c (thread_prologue_and_epilogue_insns): Remove bogus
	ATTRIBUTE_UNUSED.  Discover new basic blocks in the prologue insns.
	* tree-cfg.c (gimple_cfg_hooks): Add NULL for force_nonfallthru.


-- 
Eric Botcazou

[-- Attachment #2: p.diff --]
[-- Type: text/x-diff, Size: 7962 bytes --]

Index: cfghooks.c
===================================================================
--- cfghooks.c	(revision 171942)
+++ cfghooks.c	(working copy)
@@ -398,8 +398,7 @@ redirect_edge_and_branch_force (edge e,
     rescan_loop_exit (e, false, true);
 
   ret = cfg_hooks->redirect_edge_and_branch_force (e, dest);
-  if (ret != NULL
-      && dom_info_available_p (CDI_DOMINATORS))
+  if (ret != NULL && dom_info_available_p (CDI_DOMINATORS))
     set_immediate_dominator (CDI_DOMINATORS, ret, src);
 
   if (current_loops != NULL)
@@ -820,6 +819,8 @@ make_forwarder_block (basic_block bb, bo
   return fallthru;
 }
 
+/* Try to make the edge fallthru.  */
+
 void
 tidy_fallthru_edge (edge e)
 {
@@ -874,6 +875,42 @@ tidy_fallthru_edges (void)
     }
 }
 
+/* Edge E is assumed to be fallthru edge.  Emit needed jump instruction
+   (and possibly create new basic block) to make edge non-fallthru.
+   Return newly created BB or NULL if none.  */
+
+basic_block
+force_nonfallthru (edge e)
+{
+  basic_block ret, src = e->src, dest = e->dest;
+  struct loop *loop;
+
+  if (!cfg_hooks->force_nonfallthru)
+    internal_error ("%s does not support force_nonfallthru",
+		    cfg_hooks->name);
+
+  if (current_loops != NULL)
+    rescan_loop_exit (e, false, true);
+
+  ret = cfg_hooks->force_nonfallthru (e);
+  if (ret != NULL && dom_info_available_p (CDI_DOMINATORS))
+    set_immediate_dominator (CDI_DOMINATORS, ret, src);
+
+  if (current_loops != NULL)
+    {
+      if (ret != NULL)
+	{
+	  loop = find_common_loop (single_pred (ret)->loop_father,
+				   single_succ (ret)->loop_father);
+	  add_bb_to_loop (ret, loop);
+	}
+      else if (find_edge (src, dest) == e)
+	rescan_loop_exit (e, true, false);
+    }
+
+  return ret;
+}
+
 /* Returns true if we can duplicate basic block BB.  */
 
 bool
Index: cfghooks.h
===================================================================
--- cfghooks.h	(revision 171942)
+++ cfghooks.h	(working copy)
@@ -85,9 +85,12 @@ struct cfg_hooks
   basic_block (*split_edge) (edge);
   void (*make_forwarder_block) (edge);
 
-  /* Tries to make the edge fallthru.  */
+  /* Try to make the edge fallthru.  */
   void (*tidy_fallthru_edge) (edge);
 
+  /* Make the edge non-fallthru.  */
+  basic_block (*force_nonfallthru) (edge);
+
   /* Say whether a block ends with a call, possibly followed by some
      other code that must stay with the call.  */
   bool (*block_ends_with_call_p) (basic_block);
@@ -156,6 +159,7 @@ extern bool can_merge_blocks_p (basic_bl
 extern void merge_blocks (basic_block, basic_block);
 extern edge make_forwarder_block (basic_block, bool (*)(edge),
 				  void (*) (basic_block));
+extern basic_block force_nonfallthru (edge);
 extern void tidy_fallthru_edge (edge);
 extern void tidy_fallthru_edges (void);
 extern void predict_edge (edge e, enum br_predictor predictor, int probability);
Index: function.c
===================================================================
--- function.c	(revision 171942)
+++ function.c	(working copy)
@@ -5282,8 +5282,7 @@ thread_prologue_and_epilogue_insns (void
 {
   bool inserted;
   rtx seq ATTRIBUTE_UNUSED, epilogue_end ATTRIBUTE_UNUSED;
-  edge entry_edge ATTRIBUTE_UNUSED;
-  edge e;
+  edge entry_edge, e;
   edge_iterator ei;
 
   rtl_profile_for_bb (ENTRY_BLOCK_PTR);
@@ -5315,10 +5314,6 @@ thread_prologue_and_epilogue_insns (void
       record_insns (seq, NULL, &prologue_insn_hash);
       set_insn_locators (seq, prologue_locator);
 
-      /* This relies on the fact that committing the edge insertion
-	 will look for basic blocks within the inserted instructions,
-	 which in turn relies on the fact that we are not in CFG
-	 layout mode here.  */
       insert_insn_on_edge (seq, entry_edge);
       inserted = true;
 #endif
@@ -5541,13 +5536,23 @@ thread_prologue_and_epilogue_insns (void
 	  cur_bb->aux = cur_bb->next_bb;
       cfg_layout_finalize ();
     }
+
 epilogue_done:
   default_rtl_profile ();
 
   if (inserted)
     {
+      sbitmap blocks;
+
       commit_edge_insertions ();
 
+      /* Look for basic blocks within the prologue insns.  */
+      blocks = sbitmap_alloc (last_basic_block);
+      sbitmap_zero (blocks);
+      SET_BIT (blocks, entry_edge->dest->index);
+      find_many_sub_basic_blocks (blocks);
+      sbitmap_free (blocks);
+
       /* The epilogue insns we inserted may cause the exit edge to no longer
 	 be fallthru.  */
       FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
Index: basic-block.h
===================================================================
--- basic-block.h	(revision 171942)
+++ basic-block.h	(working copy)
@@ -794,7 +794,6 @@ extern void flow_nodes_print (const char
 extern void flow_edge_list_print (const char *, const edge *, int, FILE *);
 
 /* In cfgrtl.c  */
-extern basic_block force_nonfallthru (edge);
 extern rtx block_label (basic_block);
 extern bool purge_all_dead_edges (void);
 extern bool purge_dead_edges (basic_block);
Index: tree-cfg.c
===================================================================
--- tree-cfg.c	(revision 171942)
+++ tree-cfg.c	(working copy)
@@ -7135,6 +7135,7 @@ struct cfg_hooks gimple_cfg_hooks = {
   gimple_split_edge,		/* split_edge  */
   gimple_make_forwarder_block,	/* make_forward_block  */
   NULL,				/* tidy_fallthru_edge  */
+  NULL,				/* force_nonfallthru */
   gimple_block_ends_with_call_p,/* block_ends_with_call_p */
   gimple_block_ends_with_condjump_p, /* block_ends_with_condjump_p */
   gimple_flow_call_edges_add,   /* flow_call_edges_add */
Index: cfgrtl.c
===================================================================
--- cfgrtl.c	(revision 171942)
+++ cfgrtl.c	(working copy)
@@ -1279,8 +1279,8 @@ force_nonfallthru_and_redirect (edge e,
    (and possibly create new basic block) to make edge non-fallthru.
    Return newly created BB or NULL if none.  */
 
-basic_block
-force_nonfallthru (edge e)
+static basic_block
+rtl_force_nonfallthru (edge e)
 {
   return force_nonfallthru_and_redirect (e, e->dest);
 }
@@ -1566,10 +1566,6 @@ commit_one_edge_insertion (edge e)
     }
   else
     gcc_assert (!JUMP_P (last));
-
-  /* Mark the basic block for find_many_sub_basic_blocks.  */
-  if (current_ir_type () != IR_RTL_CFGLAYOUT)
-    bb->aux = &bb->aux;
 }
 
 /* Update the CFG for all queued instructions.  */
@@ -1578,8 +1574,6 @@ void
 commit_edge_insertions (void)
 {
   basic_block bb;
-  sbitmap blocks;
-  bool changed = false;
 
 #ifdef ENABLE_CHECKING
   verify_flow_info ();
@@ -1592,35 +1586,8 @@ commit_edge_insertions (void)
 
       FOR_EACH_EDGE (e, ei, bb->succs)
 	if (e->insns.r)
-	  {
-	    changed = true;
-	    commit_one_edge_insertion (e);
-	  }
+	  commit_one_edge_insertion (e);
     }
-
-  if (!changed)
-    return;
-
-  /* In the old rtl CFG API, it was OK to insert control flow on an
-     edge, apparently?  In cfglayout mode, this will *not* work, and
-     the caller is responsible for making sure that control flow is
-     valid at all times.  */
-  if (current_ir_type () == IR_RTL_CFGLAYOUT)
-    return;
-
-  blocks = sbitmap_alloc (last_basic_block);
-  sbitmap_zero (blocks);
-  FOR_EACH_BB (bb)
-    if (bb->aux)
-      {
-	SET_BIT (blocks, bb->index);
-	/* Check for forgotten bb->aux values before commit_edge_insertions
-	   call.  */
-	gcc_assert (bb->aux == &bb->aux);
-	bb->aux = NULL;
-      }
-  find_many_sub_basic_blocks (blocks);
-  sbitmap_free (blocks);
 }
 \f
 
@@ -3233,6 +3200,7 @@ struct cfg_hooks rtl_cfg_hooks = {
   rtl_split_edge,
   rtl_make_forwarder_block,
   rtl_tidy_fallthru_edge,
+  rtl_force_nonfallthru,
   rtl_block_ends_with_call_p,
   rtl_block_ends_with_condjump_p,
   rtl_flow_call_edges_add,
@@ -3276,7 +3244,8 @@ struct cfg_hooks cfg_layout_rtl_cfg_hook
   cfg_layout_duplicate_bb,
   cfg_layout_split_edge,
   rtl_make_forwarder_block,
-  NULL,
+  NULL, /* tidy_fallthru_edge */
+  rtl_force_nonfallthru,
   rtl_block_ends_with_call_p,
   rtl_block_ends_with_condjump_p,
   rtl_flow_call_edges_add,

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2011-04-07 21:14 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-04-04 21:09 [RFC] Remove kludge in commit_edge_insertions Eric Botcazou
2011-04-06 16:59 ` Jeff Law
2011-04-06 18:01   ` Steven Bosscher
2011-04-06 18:16     ` Jeff Law
2011-04-06 18:37       ` Steven Bosscher
2011-04-06 18:39         ` Steven Bosscher
2011-04-06 19:33           ` Jeff Law
2011-04-06 18:58         ` Jeff Law
2011-04-06 18:44   ` Eric Botcazou
2011-04-07 21:14 ` Eric Botcazou

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).