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_insn, at haifa-sched.c:1968


Hi!

This patch fixes PR rtl-optimization/28489.

The first problem is that we create new basic block for unreachable instructions in the wrong place (in the middle of current block) - sadly, that's my typo.

The second problem is that we should skip empty blocks during EBB scheduling so that there will be no need to move jumps between blocks when that is not needed.

::ADDPATCH scheduler:

Thanks,
Maxim

2006-08-14  Maxim Kuvyrkov  <mkuvyrkov@ispras.ru>

	PR rtl-optimization/28489
	* sched-ebb.c (begin_schedule_ready): Create basic block
	at the right place.
	(advance_target_bb): Skip empty blocks.
	* haifa-sched.c (bb_note): Make global.
	* sched-int.h (bb_note): Add prototype.

2006-08-14  Maxim Kuvyrkov  <mkuvyrkov@ispras.ru>

	PR rtl-optimization/28489
	* gcc.c-torture/compile/pr28489.c: New test.
--- sched-ebb.c	(/gcc-local/trunk/gcc)	(revision 21093)
+++ sched-ebb.c	(/gcc-local/fix-pr28489/gcc)	(revision 21093)
@@ -166,7 +166,8 @@ begin_schedule_ready (rtx insn, rtx last
 	  gcc_assert (NOTE_INSN_BASIC_BLOCK_P (BB_END (bb)));
 	}
       else
-	bb = create_basic_block (insn, 0, last_bb);
+	/* Create an empty unreachable block after the INSN.  */
+	bb = create_basic_block (NEXT_INSN (insn), NULL_RTX, last_bb);
       
       /* split_edge () creates BB before E->DEST.  Keep in mind, that
 	 this operation extends scheduling region till the end of BB.
@@ -728,10 +729,19 @@ advance_target_bb (basic_block bb, rtx i
       else
 	return 0;
     }
-  else if (bb != last_bb)
-    return bb->next_bb;
   else
-    gcc_unreachable ();
+    /* Return next non empty block.  */
+    {
+      do
+	{
+	  gcc_assert (bb != last_bb);
+
+	  bb = bb->next_bb;
+	}
+      while (bb_note (bb) == BB_END (bb));
+
+      return bb;
+    }
 }
 
 /* Fix internal data after interblock movement of jump instruction.
--- testsuite/gcc.c-torture/compile/pr28489.c	(/gcc-local/trunk/gcc)	(revision 21093)
+++ testsuite/gcc.c-torture/compile/pr28489.c	(/gcc-local/fix-pr28489/gcc)	(revision 21093)
@@ -0,0 +1,48 @@
+typedef int c_int;
+union c_insn
+{
+  void (*op) ();
+  c_int *mem;
+  c_int imm;
+};
+static union c_insn c_stack[((0x100 + 4) * 4)];
+static struct c_ident *c_funcs;
+static void (*c_op_bz) ();
+static void c_direct (union c_insn *addr);
+c_compile (int (*ext_getchar) (), void (*ext_rewind) (),
+	   struct c_ident *externs)
+{
+  c_direct (((void *) 0));
+}
+static void
+c_direct (union c_insn *addr)
+{
+  union c_insn *pc = addr;
+  union c_insn *sp = c_stack;
+  c_int imm = 0;
+  static void *ops[] = {
+    &&op_index, &&op_assign, &&op_add_a, &&op_sub_a, &&op_mul_a, &&op_div_a,
+      &&op_mod_a, &&op_or_a, &&op_xor_a, &&op_and_a, &&op_shl_a, &&op_shr_a,
+  };
+    {
+      c_op_bz = &&op_bz;
+    }
+  goto *(pc++)->op;
+op_bz:if (imm)
+    {
+    }
+op_push_imm_imm:(sp - 2)->imm = imm;
+  goto *(pc - 1)->op;
+op_index:imm = *((sp - 3)->mem += imm);
+op_assign:*(sp - 3)->mem = imm;
+op_add_a:imm = *(sp - 3)->mem += imm;
+op_sub_a:imm = *(sp - 3)->mem -= imm;
+op_mul_a:imm = *(sp - 3)->mem *= imm;
+op_div_a:imm = *(sp - 3)->mem /= imm;
+op_mod_a:imm = *(sp - 3)->mem %= imm;
+op_or_a:imm = *(sp - 3)->mem |= imm;
+op_xor_a:imm = *(sp - 3)->mem ^= imm;
+op_and_a:imm = *(sp - 3)->mem &= imm;
+op_shl_a:imm = *(sp - 3)->mem <<= imm;
+op_shr_a:imm = *(sp - 3)->mem >>= imm;
+}
--- haifa-sched.c	(/gcc-local/trunk/gcc)	(revision 21093)
+++ haifa-sched.c	(/gcc-local/fix-pr28489/gcc)	(revision 21093)
@@ -593,7 +593,6 @@ static void free_glat (void);
 static void sched_remove_insn (rtx);
 static void clear_priorities (rtx);
 static void add_jump_dependencies (rtx, rtx);
-static rtx bb_note (basic_block);
 static void calc_priorities (rtx);
 #ifdef ENABLE_CHECKING
 static int has_edge_p (VEC(edge,gc) *, int);
@@ -4549,7 +4548,7 @@ add_jump_dependencies (rtx insn, rtx jum
 }
 
 /* Return the NOTE_INSN_BASIC_BLOCK of BB.  */
-static rtx
+rtx
 bb_note (basic_block bb)
 {
   rtx note;
--- sched-int.h	(/gcc-local/trunk/gcc)	(revision 21093)
+++ sched-int.h	(/gcc-local/fix-pr28489/gcc)	(revision 21093)
@@ -637,6 +637,7 @@ extern void * xrecalloc (void *, size_t,
 extern void unlink_bb_notes (basic_block, basic_block);
 extern void add_block (basic_block, basic_block);
 extern void attach_life_info (void);
+extern rtx bb_note (basic_block);
 
 #ifdef ENABLE_CHECKING
 extern void check_reg_live (bool);

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