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 thread_prologue_and_epilogue_insns (PR middle-end/79499)


Hi!

In this function we insert 0-2 prologue sequences (which can sometimes
contain jumps and other insns that need to end basic blocks) on edges,
then commit edge insertions and then finally attempts to find out
into which basic blocks the sequences were inserted and calls
find_many_sub_basic_blocks on those blocks.

As the testcase shows, the guess is sometimes wrong,
commit_one_edge_insertion doesn't always insert on edge->dest, sometimes
it inserts on edge->src and in other cases splits edge and inserts into a
new basic block.

What is certain though is that all the real insns in the sequences are added
somewhere together.  So, what this patch does is finds the first
NONDEBUG_INSN_P, (if there are none, then we shouldn't need
find_many_sub_basic_blocks), and checks in which block it is using
BLOCK_FOR_INSN.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/7.2?

2017-08-01  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/79499
	* function.c (thread_prologue_and_epilogue_insns): Determine blocks
	for find_many_sub_basic_blocks bitmap by looking up BLOCK_FOR_INSN
	of first NONDEBUG_INSN_P in each of the split_prologue_seq and
	prologue_seq sequences - if any.

--- gcc/function.c.jj	2017-07-26 13:37:45.000000000 +0200
+++ gcc/function.c	2017-08-01 14:10:26.909836163 +0200
@@ -6048,20 +6048,42 @@ thread_prologue_and_epilogue_insns (void
 
   if (split_prologue_seq || prologue_seq)
     {
+      rtx_insn *split_prologue_insn = split_prologue_seq;
       if (split_prologue_seq)
-	insert_insn_on_edge (split_prologue_seq, orig_entry_edge);
+	{
+	  while (split_prologue_insn && !NONDEBUG_INSN_P (split_prologue_insn))
+	    split_prologue_insn = NEXT_INSN (split_prologue_insn);
+	  insert_insn_on_edge (split_prologue_seq, orig_entry_edge);
+	}
 
+      rtx_insn *prologue_insn = prologue_seq;
       if (prologue_seq)
-	insert_insn_on_edge (prologue_seq, entry_edge);
+	{
+	  while (prologue_insn && !NONDEBUG_INSN_P (prologue_insn))
+	    prologue_insn = NEXT_INSN (prologue_insn);
+	  insert_insn_on_edge (prologue_seq, entry_edge);
+	}
 
       commit_edge_insertions ();
 
       /* Look for basic blocks within the prologue insns.  */
-      auto_sbitmap blocks (last_basic_block_for_fn (cfun));
-      bitmap_clear (blocks);
-      bitmap_set_bit (blocks, entry_edge->dest->index);
-      bitmap_set_bit (blocks, orig_entry_edge->dest->index);
-      find_many_sub_basic_blocks (blocks);
+      if (split_prologue_insn
+	  && BLOCK_FOR_INSN (split_prologue_insn) == NULL)
+	split_prologue_insn = NULL;
+      if (prologue_insn
+	  && BLOCK_FOR_INSN (prologue_insn) == NULL)
+	prologue_insn = NULL;
+      if (split_prologue_insn || prologue_insn)
+	{
+	  auto_sbitmap blocks (last_basic_block_for_fn (cfun));
+	  bitmap_clear (blocks);
+	  if (split_prologue_insn)
+	    bitmap_set_bit (blocks,
+			    BLOCK_FOR_INSN (split_prologue_insn)->index);
+	  if (prologue_insn)
+	    bitmap_set_bit (blocks, BLOCK_FOR_INSN (prologue_insn)->index);
+	  find_many_sub_basic_blocks (blocks);
+	}
     }
 
   default_rtl_profile ();
--- gcc/testsuite/gcc.dg/pr79499.c.jj	2017-08-01 13:57:36.120485689 +0200
+++ gcc/testsuite/gcc.dg/pr79499.c	2017-08-01 13:57:26.000000000 +0200
@@ -0,0 +1,13 @@
+/* PR middle-end/79499 */
+/* { dg-do compile { target split_stack } } */
+/* { dg-options "-O2 -fsplit-stack -fno-omit-frame-pointer" } */
+
+struct S { struct S *a, *b; };
+
+void
+foo (struct S *x)
+{
+  do
+    x->b = x->a;
+  while (x = x->a);
+}

	Jakub


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