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 PR28489 - [4.2 Regression] ICE: in move_block_after_check, at haifa-sched.c:4337


Hi!

The first patch fixes PR29128 and the second one provides cleanup for the related code.

The PR appears in the code that handles interblock movements of the jumps in sched-ebb.c . Actually, the only jumps we will possibly move during sched-ebb are 'branchy speculation checks'. So the problem is that all 'speculation checks' were considered as jumps in sched-ebb.c: advance_target_bb ().

For clarity, second patch introduces macros to identify speculation checks.

Both patches were bootstrapped and regtested on {ia64, i386}-linux-gnu. I also checked that the patched compiler produces exactly the same SPEC2000 binaries as the original one.

Thanks,
Maxim
2006-09-23  Maxim Kuvyrkov  <mkuvyrkov@ispras.ru>

	PR rtl-optimization/29128
	* sched-ebb.c (advance_target_bb): Use correct condition to
	allow interblock movement of speculation checks.
	* sched-int.h (IS_SPEC_BRANCY_CHECK_P): New macro.

2006-09-23  Maxim Kuvyrkov  <mkuvyrkov@ispras.ru>

	PR rtl-optimization/29128
	* gcc.c-torture/compile/pr29128.c: New test.
--- sched-ebb.c	(/local/trunk/gcc)	(revision 278)
+++ sched-ebb.c	(/local/fix-pr29128/gcc)	(revision 278)
@@ -719,9 +719,13 @@ advance_target_bb (basic_block bb, rtx i
     {
       if (BLOCK_FOR_INSN (insn) != bb
 	  && control_flow_insn_p (insn)
-	  && !RECOVERY_BLOCK (insn)
-	  && !RECOVERY_BLOCK (BB_END (bb)))
+	  /* We handle interblock movement of the speculation check
+	     or over a speculation check in
+	     haifa-sched.c: move_block_after_check ().  */
+	  && !IS_SPEC_BRANCHY_CHECK_P (insn)
+	  && !IS_SPEC_BRANCHY_CHECK_P (BB_END (bb)))
 	{
+	  /* Assert that we don't move jumps across blocks.  */
 	  gcc_assert (!control_flow_insn_p (BB_END (bb))
 		      && NOTE_INSN_BASIC_BLOCK_P (BB_HEAD (bb->next_bb)));
 	  return bb;
--- testsuite/gcc.c-torture/compile/pr29128.c	(/local/trunk/gcc)	(revision 278)
+++ testsuite/gcc.c-torture/compile/pr29128.c	(/local/fix-pr29128/gcc)	(revision 278)
@@ -0,0 +1,28 @@
+typedef unsigned long Eterm;
+process_main (void)
+{
+  register Eterm x0;
+  register Eterm *reg = ((void *) 0);
+  register Eterm *I = ((void *) 0);
+  static void *opcodes[] = {
+      &&lb_allocate_heap_zero_III,
+      &&lb_allocate_init_tIy, &&lb_allocate_zero_tt
+  };
+lb_allocate_heap_III:{
+    Eterm *next;
+    goto *(next);
+  }
+lb_allocate_heap_zero_III:{
+  }
+lb_allocate_init_tIy:{
+  }
+lb_allocate_zero_tt:{
+    Eterm *next;
+    {
+      Eterm *tmp_ptr = ((Eterm *) (((x0)) - 0x1));
+      (*(Eterm *) (((unsigned char *) reg) + (I[(0) + 1]))) = ((tmp_ptr)[0]);
+      x0 = ((tmp_ptr)[1]);
+    }
+    goto *(next);
+  }
+}
--- sched-int.h	(/local/trunk/gcc)	(revision 278)
+++ sched-int.h	(/local/fix-pr29128/gcc)	(revision 278)
@@ -359,6 +359,9 @@ extern regset *glat_start, *glat_end;
 #define RECOVERY_BLOCK(INSN)    (h_i_d[INSN_UID (INSN)].recovery_block)
 #define ORIG_PAT(INSN)          (h_i_d[INSN_UID (INSN)].orig_pat)
 
+#define IS_SPEC_BRANCHY_CHECK_P(INSN) \
+  (RECOVERY_BLOCK (INSN) != NULL && RECOVERY_BLOCK (INSN) != EXIT_BLOCK_PTR)
+
 /* DEP_STATUS of the link encapsulates information, that is needed for
    speculative scheduling.  Namely, it is 4 integers in the range
    [0, MAX_DEP_WEAK] and 3 bits.
2006-09-24  Maxim Kuvyrkov  <mkuvyrkov@ispras.ru>

	* sched-int.h (IS_SPEC_CHECK_P, IS_SPEC_SIMPLE_CHECK_P): New macros.
	* sched-ebb.c (begin_schedule_ready): Use them.
	* haifa-sched.c (schedule_insn, move_insn, try_ready,
	add_to_speculative_block, create_check_block_twin, speculate_insn,
	fix_jump_move, move_block_after_check): Ditto.
	* sched-rgn.c (new_ready): Ditto.
--- sched-ebb.c	(/local/fix-pr29128/gcc)	(revision 279)
+++ sched-ebb.c	(/local/fix-pr29128-1/gcc)	(revision 279)
@@ -145,7 +145,7 @@ begin_schedule_ready (rtx insn, rtx last
       gcc_assert (!e || !(e->flags & EDGE_COMPLEX));	    
 
       gcc_assert (BLOCK_FOR_INSN (insn) == last_bb
-		  && !RECOVERY_BLOCK (insn)
+		  && !IS_SPEC_CHECK_P (insn)
 		  && BB_HEAD (last_bb) != insn
 		  && BB_END (last_bb) == insn);
 
--- haifa-sched.c	(/local/fix-pr29128/gcc)	(revision 279)
+++ haifa-sched.c	(/local/fix-pr29128-1/gcc)	(revision 279)
@@ -1190,8 +1190,7 @@ schedule_insn (rtx insn)
 
       resolve_dep (next, insn);
 
-      if (!RECOVERY_BLOCK (insn)
-	  || RECOVERY_BLOCK (insn) == EXIT_BLOCK_PTR)
+      if (!IS_SPEC_BRANCHY_CHECK_P (insn))
 	{
 	  int effective_cost;      
 	  
@@ -1960,8 +1959,7 @@ move_insn (rtx insn)
 
 	  gcc_assert (!jump_p
 		      || ((current_sched_info->flags & SCHED_RGN)
-			  && RECOVERY_BLOCK (insn)
-			  && RECOVERY_BLOCK (insn) != EXIT_BLOCK_PTR)
+			  && IS_SPEC_BRANCHY_CHECK_P (insn))
 		      || (current_sched_info->flags & SCHED_EBB));
 	  
 	  gcc_assert (BLOCK_FOR_INSN (PREV_INSN (insn)) == bb);
@@ -3115,8 +3113,7 @@ try_ready (rtx next)
      or we simply don't care (*ts & HARD_DEP).  */
   
   gcc_assert (!ORIG_PAT (next)
-	      || !RECOVERY_BLOCK (next)
-	      || RECOVERY_BLOCK (next) == EXIT_BLOCK_PTR);
+	      || !IS_SPEC_BRANCHY_CHECK_P (next));
   
   if (*ts & HARD_DEP)
     {
@@ -3128,11 +3125,11 @@ try_ready (rtx next)
       change_queue_index (next, QUEUE_NOWHERE);
       return -1;
     }
-  else if (!(*ts & BEGIN_SPEC) && ORIG_PAT (next) && !RECOVERY_BLOCK (next))
+  else if (!(*ts & BEGIN_SPEC) && ORIG_PAT (next) && !IS_SPEC_CHECK_P (next))
     /* We should change pattern of every previously speculative 
        instruction - and we determine if NEXT was speculative by using
-       ORIG_PAT field.  Except one case - simple checks have ORIG_PAT
-       pat too, hence we also check for the RECOVERY_BLOCK.  */
+       ORIG_PAT field.  Except one case - speculation checks have ORIG_PAT
+       pat too, so skip them.  */
     {
       change_pattern (next, ORIG_PAT (next));
       ORIG_PAT (next) = 0;
@@ -3444,7 +3441,7 @@ add_to_speculative_block (rtx insn)
 
       check = XEXP (link, 0);
 
-      if (RECOVERY_BLOCK (check))
+      if (IS_SPEC_SIMPLE_CHECK_P (check))
 	{
 	  create_check_block_twin (check, true);
 	  link = LOG_LINKS (insn);
@@ -3466,7 +3463,8 @@ add_to_speculative_block (rtx insn)
 		  && (DEP_STATUS (link) & DEP_TYPES) == DEP_TRUE);
 
       check = XEXP (link, 0);
-      gcc_assert (!RECOVERY_BLOCK (check) && !ORIG_PAT (check)
+
+      gcc_assert (!IS_SPEC_CHECK_P (check) && !ORIG_PAT (check)
 		  && QUEUE_INDEX (check) == QUEUE_NOWHERE);
       
       rec = BLOCK_FOR_INSN (check);
@@ -3718,7 +3716,7 @@ create_check_block_twin (rtx insn, bool 
 
   gcc_assert (ORIG_PAT (insn)
 	      && (!mutate_p 
-		  || (RECOVERY_BLOCK (insn) == EXIT_BLOCK_PTR
+		  || (IS_SPEC_SIMPLE_CHECK_P (insn)
 		      && !(TODO_SPEC (insn) & SPECULATIVE))));
 
   /* Create recovery block.  */
@@ -4091,7 +4089,7 @@ speculate_insn (rtx insn, ds_t request, 
       || (request & spec_info->mask) != request)    
     return -1;
   
-  gcc_assert (!RECOVERY_BLOCK (insn));
+  gcc_assert (!IS_SPEC_CHECK_P (insn));
 
   if (request & BE_IN_SPEC)
     {            
@@ -4299,8 +4297,7 @@ fix_jump_move (rtx jump)
   jump_bb_next = jump_bb->next_bb;
 
   gcc_assert (current_sched_info->flags & SCHED_EBB
-	      || (RECOVERY_BLOCK (jump)
-		  && RECOVERY_BLOCK (jump) != EXIT_BLOCK_PTR));
+	      || IS_SPEC_BRANCHY_CHECK_P (jump));
   
   if (!NOTE_INSN_BASIC_BLOCK_P (BB_END (jump_bb_next)))
     /* if jump_bb_next is not empty.  */
@@ -4333,8 +4330,8 @@ move_block_after_check (rtx jump)
   
   update_bb_for_insn (jump_bb);
   
-  gcc_assert (RECOVERY_BLOCK (jump)
-	      || RECOVERY_BLOCK (BB_END (jump_bb_next)));
+  gcc_assert (IS_SPEC_CHECK_P (jump)
+	      || IS_SPEC_CHECK_P (BB_END (jump_bb_next)));
 
   unlink_block (jump_bb_next);
   link_block (jump_bb_next, bb);
--- sched-int.h	(/local/fix-pr29128/gcc)	(revision 279)
+++ sched-int.h	(/local/fix-pr29128-1/gcc)	(revision 279)
@@ -359,6 +359,8 @@ extern regset *glat_start, *glat_end;
 #define RECOVERY_BLOCK(INSN)    (h_i_d[INSN_UID (INSN)].recovery_block)
 #define ORIG_PAT(INSN)          (h_i_d[INSN_UID (INSN)].orig_pat)
 
+#define IS_SPEC_CHECK_P(INSN) (RECOVERY_BLOCK (INSN) != NULL)
+#define IS_SPEC_SIMPLE_CHECK_P(INSN) (RECOVERY_BLOCK (INSN) == EXIT_BLOCK_PTR)
 #define IS_SPEC_BRANCHY_CHECK_P(INSN) \
   (RECOVERY_BLOCK (INSN) != NULL && RECOVERY_BLOCK (INSN) != EXIT_BLOCK_PTR)
 
--- sched-rgn.c	(/local/fix-pr29128/gcc)	(revision 279)
+++ sched-rgn.c	(/local/fix-pr29128-1/gcc)	(revision 279)
@@ -2089,7 +2089,7 @@ new_ready (rtx next, ds_t ts)
 	      && ((recog_memoized (next) >= 0
 		   && min_insn_conflict_delay (curr_state, next, next) 
                    > PARAM_VALUE (PARAM_MAX_SCHED_INSN_CONFLICT_DELAY))
-                  || RECOVERY_BLOCK (next)
+                  || IS_SPEC_CHECK_P (next)
 		  || !check_live (next, INSN_BB (next))
 		  || (not_ex_free = !is_exception_free (next, INSN_BB (next),
 							target_bb)))))

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