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]

[PATCH] Fix verify_flow_info for cfglayout mode


Hi,

This patch fixes rtl_verify_flow_info{,_1} to work with a function
in cfglayout mode.  rtl_verify_flow_info_1 was expecting get_last_insn
to return the last insn in the insns stream -- but there is *no* insns
stream when we are in cfglayout mode, at least, not one in serial.  So
this is a genuine bug in rtl_verify_flow_info_1 :-/

Fixed by moving the check to rtl_verify_flow_info.

I also added a check that BLOCK_FOR_INSN is valid for all insns, and
I moved a check from rtl_verify_flow_info to rtl_verify_flow_info_1
so that the check is also performed if we are in cfglayout mode.

(I just noticed I moved some over-length lines from one place to
another.  I'll fix that when I commit this if approved...)

Bootstrapped&tested on ia64-unknown-linux-gnu.  OK for trunk?

Gr.
Steven

	* cfgrtl.c (rtl_verify_flow_info_1): Don't verify that BB_END
	and BB_HEAD are in the insn stream here.  Instead make sure
	that BB_INSN is valid on all insns.  Also, do check here that
	there are no pending branch predictions...
	(rtl_verify_flow_info): ...instead of doing it here.  Checks
	for BB_END and BB_HEAD moved from rtl_verify_flow_info_1 to
	here.

Index: gcc/cfgrtl.c
===================================================================
--- gcc/cfgrtl.c	(revision 121061)
+++ gcc/cfgrtl.c	(working copy)
@@ -1676,13 +1676,14 @@
 
    Currently it does following checks:
 
-   - test head/end pointers
    - overlapping of basic blocks
+   - insns with wrong BLOCK_FOR_INSN pointers
    - headers of basic blocks (the NOTE_INSN_BASIC_BLOCK note)
    - tails of basic blocks (ensure that boundary is necessary)
    - scans body of the basic block for JUMP_INSN, CODE_LABEL
      and NOTE_INSN_BASIC_BLOCK
    - verify that no fall_thru edge crosses hot/cold partition boundaries
+   - verify that there are no pending RTL branch predictions
 
    In future it can be extended check a lot of other stuff as well
    (reachability of basic blocks, life information, etc. etc.).  */
@@ -1690,65 +1691,36 @@
 static int
 rtl_verify_flow_info_1 (void)
 {
-  const int max_uid = get_max_uid ();
-  rtx last_head = get_last_insn ();
-  basic_block *bb_info;
   rtx x;
   int err = 0;
   basic_block bb;
 
-  bb_info = XCNEWVEC (basic_block, max_uid);
-
+  /* Check the general integrity of the basic blocks.  */
   FOR_EACH_BB_REVERSE (bb)
     {
-      rtx head = BB_HEAD (bb);
-      rtx end = BB_END (bb);
+      rtx insn;
 
-      /* Verify the end of the basic block is in the INSN chain.  */
-      for (x = last_head; x != NULL_RTX; x = PREV_INSN (x))
-	if (x == end)
-	  break;
-
       if (!(bb->flags & BB_RTL))
 	{
 	  error ("BB_RTL flag not set for block %d", bb->index);
 	  err = 1;
 	}
 
-      if (!x)
-	{
-	  error ("end insn %d for block %d not found in the insn stream",
-		 INSN_UID (end), bb->index);
-	  err = 1;
-	}
+      FOR_BB_INSNS (bb, insn)
+	if (BLOCK_FOR_INSN (insn) != bb)
+	  {
+	    error ("insn %d basic block pointer is %d, should be %d",
+		   INSN_UID (insn),
+		   BLOCK_FOR_INSN (insn) ? BLOCK_FOR_INSN (insn)->index : 0,
+		   bb->index);
+	    err = 1;
+	  }
 
-      /* Work backwards from the end to the head of the basic block
-	 to verify the head is in the RTL chain.  */
-      for (; x != NULL_RTX; x = PREV_INSN (x))
+      if (bb->predictions)
 	{
-	  /* While walking over the insn chain, verify insns appear
-	     in only one basic block and initialize the BB_INFO array
-	     used by other passes.  */
-	  if (bb_info[INSN_UID (x)] != NULL)
-	    {
-	      error ("insn %d is in multiple basic blocks (%d and %d)",
-		     INSN_UID (x), bb->index, bb_info[INSN_UID (x)]->index);
-	      err = 1;
-	    }
-
-	  bb_info[INSN_UID (x)] = bb;
-
-	  if (x == head)
-	    break;
-	}
-      if (!x)
-	{
-	  error ("head insn %d for block %d not found in the insn stream",
-		 INSN_UID (head), bb->index);
+	  error ("bb prediction set for block %d, but it is not used in RTL land", bb->index);
 	  err = 1;
 	}
-
-      last_head = x;
     }
 
   /* Now check the basic blocks (boundaries etc.) */
@@ -1916,7 +1888,6 @@
     }
 
   /* Clean up.  */
-  free (bb_info);
   return err;
 }
 
@@ -1925,31 +1896,74 @@
 
    Currently it does following checks:
    - all checks of rtl_verify_flow_info_1
+   - test head/end pointers
    - check that all insns are in the basic blocks
      (except the switch handling code, barriers and notes)
    - check that all returns are followed by barriers
    - check that all fallthru edge points to the adjacent blocks.  */
+
 static int
 rtl_verify_flow_info (void)
 {
   basic_block bb;
   int err = rtl_verify_flow_info_1 ();
   rtx x;
+  rtx last_head = get_last_insn ();
+  basic_block *bb_info;
   int num_bb_notes;
   const rtx rtx_first = get_insns ();
   basic_block last_bb_seen = ENTRY_BLOCK_PTR, curr_bb = NULL;
+  const int max_uid = get_max_uid ();
 
+  bb_info = XCNEWVEC (basic_block, max_uid);
+
   FOR_EACH_BB_REVERSE (bb)
     {
       edge e;
       edge_iterator ei;
+      rtx head = BB_HEAD (bb);
+      rtx end = BB_END (bb);
 
-      if (bb->predictions)
+      /* Verify the end of the basic block is in the INSN chain.  */
+      for (x = last_head; x != NULL_RTX; x = PREV_INSN (x))
+	if (x == end)
+	  break;
+
+      if (!x)
 	{
-	  error ("bb prediction set for block %i, but it is not used in RTL land", bb->index);
+	  error ("end insn %d for block %d not found in the insn stream",
+		 INSN_UID (end), bb->index);
 	  err = 1;
 	}
 
+      /* Work backwards from the end to the head of the basic block
+	 to verify the head is in the RTL chain.  */
+      for (; x != NULL_RTX; x = PREV_INSN (x))
+	{
+	  /* While walking over the insn chain, verify insns appear
+	     in only one basic block and initialize the BB_INFO array
+	     used by other passes.  */
+	  if (bb_info[INSN_UID (x)] != NULL)
+	    {
+	      error ("insn %d is in multiple basic blocks (%d and %d)",
+		     INSN_UID (x), bb->index, bb_info[INSN_UID (x)]->index);
+	      err = 1;
+	    }
+
+	  bb_info[INSN_UID (x)] = bb;
+
+	  if (x == head)
+	    break;
+	}
+      if (!x)
+	{
+	  error ("head insn %d for block %d not found in the insn stream",
+		 INSN_UID (head), bb->index);
+	  err = 1;
+	}
+
+      last_head = x;
+
       FOR_EACH_EDGE (e, ei, bb->succs)
 	if (e->flags & EDGE_FALLTHRU)
 	  break;
@@ -1994,6 +2008,8 @@
 	}
     }
 
+  free (bb_info);
+
   num_bb_notes = 0;
   last_bb_seen = ENTRY_BLOCK_PTR;
 


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