On August 1, 2017 10:35:43 PM GMT+02:00, Jakub Jelinek <ja...@redhat.com> wrote:
>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?

OK.

Thanks,
Richard.

>2017-08-01  Jakub Jelinek  <ja...@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

Reply via email to