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


Ian Lance Taylor wrote:

...

These patches are OK if you give the macros better names and add
comments before the macro definitions.

I suggest using IS_SPECULATION_... for all three new macros.  SPEC is
not an obvious abbreviation for SPECULATION.  Be sure to explain in
the comment what you mean by BRANCHY.

Approved with those changes.

These are updated patches. Will check them in when regtesting on {i386, ia64}-linux-gnu is over.



Thanks,


Maxim

2006-10-06  Maxim Kuvyrkov  <mkuvyrkov@ispras.ru>

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

2006-10-06  Maxim Kuvyrkov  <mkuvyrkov@ispras.ru>

	PR rtl-optimization/29128
	* gcc.c-torture/compile/pr29128.c: New test.
2006-10-06  Maxim Kuvyrkov  <mkuvyrkov@ispras.ru>

	* sched-int.h (IS_SPECULATION_CHECK_P, IS_SPECULATION_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/trunk/gcc)	(revision 435)
+++ sched-ebb.c	(/local/fix-pr29128/gcc)	(revision 435)
@@ -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_SPECULATION_BRANCHY_CHECK_P (insn)
+	  && !IS_SPECULATION_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 435)
+++ testsuite/gcc.c-torture/compile/pr29128.c	(/local/fix-pr29128/gcc)	(revision 435)
@@ -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 435)
+++ sched-int.h	(/local/fix-pr29128/gcc)	(revision 435)
@@ -359,6 +359,13 @@ 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)
 
+/* INSN is a speculation check that will branch to RECOVERY_BLOCK if the
+   speculation fail.  Insns in that block will reexecute the speculatively
+   scheduled code and then will return immediatelly after INSN thus preserving
+   semantics of the program.  */
+#define IS_SPECULATION_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.
--- sched-ebb.c	(/local/fix-pr29128/gcc)	(revision 435)
+++ sched-ebb.c	(/local/fix-pr29128-1/gcc)	(revision 435)
@@ -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_SPECULATION_CHECK_P (insn)
 		  && BB_HEAD (last_bb) != insn
 		  && BB_END (last_bb) == insn);
 
--- haifa-sched.c	(/local/fix-pr29128/gcc)	(revision 435)
+++ haifa-sched.c	(/local/fix-pr29128-1/gcc)	(revision 435)
@@ -1190,8 +1190,7 @@ schedule_insn (rtx insn)
 
       resolve_dep (next, insn);
 
-      if (!RECOVERY_BLOCK (insn)
-	  || RECOVERY_BLOCK (insn) == EXIT_BLOCK_PTR)
+      if (!IS_SPECULATION_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_SPECULATION_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_SPECULATION_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_SPECULATION_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_SPECULATION_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_SPECULATION_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_SPECULATION_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_SPECULATION_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_SPECULATION_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_SPECULATION_CHECK_P (jump)
+	      || IS_SPECULATION_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 435)
+++ sched-int.h	(/local/fix-pr29128-1/gcc)	(revision 435)
@@ -359,6 +359,14 @@ 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)
 
+/* INSN is either a simple or a branchy speculation check.  */
+#define IS_SPECULATION_CHECK_P(INSN) (RECOVERY_BLOCK (INSN) != NULL)
+
+/* INSN is a speculation check that will simply reexecute the speculatively
+   scheduled instruction if the speculation fail.  */
+#define IS_SPECULATION_SIMPLE_CHECK_P(INSN) \
+  (RECOVERY_BLOCK (INSN) == EXIT_BLOCK_PTR)
+
 /* INSN is a speculation check that will branch to RECOVERY_BLOCK if the
    speculation fail.  Insns in that block will reexecute the speculatively
    scheduled code and then will return immediatelly after INSN thus preserving
--- sched-rgn.c	(/local/fix-pr29128/gcc)	(revision 435)
+++ sched-rgn.c	(/local/fix-pr29128-1/gcc)	(revision 435)
@@ -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_SPECULATION_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]