The following fixes FDO on setjmp using functions.  We may not
blindly split blocks before setjmp receivers as that disconnects
the PHIs and will end up creating a bogus CFG when IPA inlining
then creates new abnormal edges to the new setjmp block - we're
going to have a hard time coalescing SSA names that way.

Fixed by following what the SJLJ machinery does - not split blocks
before ECF_RETURNS_TWICE.

Bootstrap / regtest running on x86_64-unknown-linux-gnu
(253.perlbmk with FDO passed with this patch).

Richard.

2013-05-22  Richard Biener  <rguent...@suse.de>

        PR middle-end/57349
        * profile.c (branch_prob): Do not split blocks that are
        abnormally receiving from ECF_RETURNS_TWICE functions.

Index: gcc/profile.c
===================================================================
*** gcc/profile.c       (revision 199138)
--- gcc/profile.c       (working copy)
*************** branch_prob (void)
*** 1085,1102 ****
                 or __builtin_setjmp_dispatcher calls.  These are very
                 special and don't expect anything to be inserted before
                 them.  */
!             if (!is_gimple_call (first)
!                 || (fndecl = gimple_call_fndecl (first)) == NULL
!                 || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL
!                 || (DECL_FUNCTION_CODE (fndecl) != BUILT_IN_SETJMP_RECEIVER
!                     && (DECL_FUNCTION_CODE (fndecl)
!                         != BUILT_IN_SETJMP_DISPATCHER)))
!               {
!                 if (dump_file)
!                   fprintf (dump_file, "Splitting bb %i after labels\n",
!                            bb->index);
!                 split_block_after_labels (bb);
!               }
            }
        }
      }
--- 1085,1104 ----
                 or __builtin_setjmp_dispatcher calls.  These are very
                 special and don't expect anything to be inserted before
                 them.  */
!             if (is_gimple_call (first)
!                 && (((fndecl = gimple_call_fndecl (first)) != NULL
!                      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
!                      && (DECL_FUNCTION_CODE (fndecl)
!                          == BUILT_IN_SETJMP_RECEIVER
!                          || (DECL_FUNCTION_CODE (fndecl)
!                              == BUILT_IN_SETJMP_DISPATCHER)))
!                     || gimple_call_flags (first) & ECF_RETURNS_TWICE))
!               continue;
! 
!             if (dump_file)
!               fprintf (dump_file, "Splitting bb %i after labels\n",
!                        bb->index);
!             split_block_after_labels (bb);
            }
        }
      }

Reply via email to