[PATCH] Make the world a bit safer for cfglayout mode

Steven Bosscher stevenb.gcc@gmail.com
Tue Nov 14 19:06:00 GMT 2006


Hi,

This patch changes a few things that would work in cfgrtl mode
but not in cfglayout mode. ChangeLog says all.

This is all pretty obvious, I'd say.

The only bit I'm not sure about is this one:
+               gcc_assert (JUMP_TABLE_DATA_P (insn));

I'm assuming we can only have tablejump data between basic blocks,
but I seem to recall you could also have constant pools and such
there. Right? Anything else that may show up between basic blocks?

Bootstrapped and tested on x86_64 and ia64 linux.
OK for trunk?

Gr.
Steven


	* jump.c (mark_all_labels): Work in cfglayout mode.
	* cfgcleanup.c (cleanup_cfg): Do not call delete_dead_jumptables
	when in cfglayout mode, because there are no dead jumptables
	visible.
	* cfgrtl.c (commit_edge_insertions): Do not allow insertion
	of instructions with control flow insns when in cfglayout mode.

Index: jump.c
===================================================================
--- jump.c	(revision 118822)
+++ jump.c	(working copy)
@@ -202,6 +202,31 @@ mark_all_labels (rtx f)
 	      }
 	  }
       }
+  
+  /* If we are in cfglayout mode, there may be non-insns between the
+     basic blocks.  If those non-insns represent tablejump data, they
+     contain label references that we must record.  */
+  if (current_ir_type () == IR_RTL_CFGLAYOUT)
+    {
+      basic_block bb;
+      rtx insn;
+      FOR_EACH_BB (bb)
+	{
+	  for (insn = bb->il.rtl->header; insn; insn = NEXT_INSN (insn))
+	    if (INSN_P (insn))
+	      {
+		gcc_assert (JUMP_TABLE_DATA_P (insn));
+		mark_jump_label (PATTERN (insn), insn, 0);
+	      }
+
+	  for (insn = bb->il.rtl->footer; insn; insn = NEXT_INSN (insn))
+	    if (INSN_P (insn))
+	      {
+		gcc_assert (JUMP_TABLE_DATA_P (insn));
+		mark_jump_label (PATTERN (insn), insn, 0);
+	      }
+	}
+    }
 }
 
 /* Move all block-beg, block-end and loop-beg notes between START and END out
Index: cfgcleanup.c
===================================================================
--- cfgcleanup.c	(revision 118822)
+++ cfgcleanup.c	(working copy)
@@ -763,8 +763,6 @@ merge_blocks_move (edge e, basic_block b
   if (BB_PARTITION (b) != BB_PARTITION (c))
     return NULL;
 
-
-
   /* If B has a fallthru edge to C, no need to move anything.  */
   if (e->flags & EDGE_FALLTHRU)
     {
@@ -2260,7 +2258,15 @@ cleanup_cfg (int mode)
 	}
       else
 	break;
-      delete_dead_jumptables ();
+
+      /* Don't call delete_dead_jumptables in cfglayout mode, because
+	 that function assumes that jump tables are in the insns stream.
+	 But we also don't _have_ to delete dead jumptables in cfglayout
+	 mode because we shouldn't even be looking at things that are
+	 not in a basic block.  Dead jumptables are cleaned up when
+	 going out of cfglayout mode.  */
+      if (!(mode & CLEANUP_CFGLAYOUT))
+	delete_dead_jumptables ();
     }
 
   timevar_pop (TV_CLEANUP_CFG);
Index: cfgrtl.c
===================================================================
--- cfgrtl.c	(revision 118822)
+++ cfgrtl.c	(working copy)
@@ -1520,6 +1520,13 @@ commit_edge_insertions (void)
   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)



More information about the Gcc-patches mailing list