[OE-core] [PATCH] gcc-4.5: Bring latest from linaro 4.5 and bump svn SRCREV for upstream

Khem Raj raj.khem at gmail.com
Thu Feb 17 21:51:09 UTC 2011


On Thu, Feb 17, 2011 at 1:10 PM, Koen Kooi <koen at dominion.thruhere.net> wrote:
> This looks to be against meta-oe instead of oe-core, but I guess you're
> testing patchwork?

This is a dummy patch, Yes I am testing the mailing list and patchwork
correct :)

>
> 2011/2/17 Khem Raj <raj.khem at gmail.com>
>>
>> Signed-off-by: Khem Raj <raj.khem at gmail.com>
>> ---
>>  recipes/gcc/gcc-4.5.inc                            |   13 +-
>>  recipes/gcc/gcc-4.5/arm-bswapsi2.patch             |   13 -
>>  .../gcc-4.5/gcc-arm-volatile-bitfield-fix.patch    |    6 +-
>>  .../gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99448.patch |  147 -
>>  .../gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99456.patch | 3163 ---------------
>>  .../gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99457.patch | 4236
>> --------------------
>>  .../gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99464.patch |  157 +
>>  .../gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99465.patch |   94 +
>>  .../gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99466.patch |   38 +
>>  .../gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99468.patch |  811 ++++
>>  .../gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99473.patch |  409 ++
>>  .../gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99474.patch | 3346
>> ++++++++++++++++
>>  .../gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99475.patch | 4217
>> +++++++++++++++++++
>>  13 files changed, 9083 insertions(+), 7567 deletions(-)
>>  delete mode 100644 recipes/gcc/gcc-4.5/arm-bswapsi2.patch
>>  delete mode 100644 recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99448.patch
>>  delete mode 100644 recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99456.patch
>>  delete mode 100644 recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99457.patch
>>  create mode 100644 recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99464.patch
>>  create mode 100644 recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99465.patch
>>  create mode 100644 recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99466.patch
>>  create mode 100644 recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99468.patch
>>  create mode 100644 recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99473.patch
>>  create mode 100644 recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99474.patch
>>  create mode 100644 recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99475.patch
>>
>> diff --git a/recipes/gcc/gcc-4.5.inc b/recipes/gcc/gcc-4.5.inc
>> index b630528..1f089f6 100644
>> --- a/recipes/gcc/gcc-4.5.inc
>> +++ b/recipes/gcc/gcc-4.5.inc
>> @@ -10,7 +10,7 @@ NATIVEDEPS = "mpfr-native gmp-native libmpc-native"
>>
>>  INC_PR = "r31"
>>
>> -SRCREV = "168622"
>> +SRCREV = "170123"
>>  PV = "4.5"
>>  # BINV should be incremented after updating to a revision
>>  # after a minor gcc release (e.g. 4.5.1 or 4.5.2) has been made
>> @@ -29,7 +29,6 @@ SRC_URI =
>> "svn://gcc.gnu.org/svn/gcc/branches;module=${BRANCH} \
>>           file://cache-amnesia.patch \
>>           file://gcc-flags-for-build.patch \
>>           file://libstdc++-emit-__cxa_end_cleanup-in-text.patch \
>> -          file://arm-bswapsi2.patch \
>>           file://Makefile.in.patch \
>>           file://gcc-armv4-pass-fix-v4bx-to-ld.patch \
>>           file://sh4-multilib.patch \
>> @@ -154,7 +153,6 @@ SRC_URI =
>> "svn://gcc.gnu.org/svn/gcc/branches;module=${BRANCH} \
>>           file://linaro/gcc-4.5-linaro-r99442.patch \
>>           file://linaro/gcc-4.5-linaro-r99443.patch \
>>           file://linaro/gcc-4.5-linaro-r99444.patch \
>> -          file://linaro/gcc-4.5-linaro-r99448.patch \
>>           file://linaro/gcc-4.5-linaro-r99449.patch \
>>           file://linaro/gcc-4.5-linaro-r99450.patch \
>>           file://linaro/gcc-4.5-linaro-r99451.patch \
>> @@ -162,8 +160,13 @@ SRC_URI =
>> "svn://gcc.gnu.org/svn/gcc/branches;module=${BRANCH} \
>>           file://linaro/gcc-4.5-linaro-r99453.patch \
>>           file://linaro/gcc-4.5-linaro-r99454.patch \
>>           file://linaro/gcc-4.5-linaro-r99455.patch \
>> -#         file://linaro/gcc-4.5-linaro-r99456.patch \
>> -#         file://linaro/gcc-4.5-linaro-r99457.patch \
>> +          file://linaro/gcc-4.5-linaro-r99464.patch \
>> +          file://linaro/gcc-4.5-linaro-r99465.patch \
>> +          file://linaro/gcc-4.5-linaro-r99466.patch \
>> +          file://linaro/gcc-4.5-linaro-r99468.patch \
>> +          file://linaro/gcc-4.5-linaro-r99473.patch \
>> +          file://linaro/gcc-4.5-linaro-r99474.patch \
>> +          file://linaro/gcc-4.5-linaro-r99475.patch \
>>           file://gcc-scalar-widening-pr45847.patch \
>>           file://gcc-arm-volatile-bitfield-fix.patch \
>>          "
>> diff --git a/recipes/gcc/gcc-4.5/arm-bswapsi2.patch
>> b/recipes/gcc/gcc-4.5/arm-bswapsi2.patch
>> deleted file mode 100644
>> index 7ac61a6..0000000
>> --- a/recipes/gcc/gcc-4.5/arm-bswapsi2.patch
>> +++ /dev/null
>> @@ -1,13 +0,0 @@
>> -Index: gcc-4.5/gcc/config/arm/arm.md
>> -===================================================================
>> ---- gcc-4.5.orig/gcc/config/arm/arm.md 2010-06-17 09:13:07.000000000
>> -0700
>> -+++ gcc-4.5/gcc/config/arm/arm.md      2010-06-22 08:08:45.397212002
>> -0700
>> -@@ -11267,7 +11267,7 @@
>> - (define_expand "bswapsi2"
>> -   [(set (match_operand:SI 0 "s_register_operand" "=r")
>> -       (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
>> --"TARGET_EITHER"
>> -+"TARGET_EITHER && (arm_arch6 && !optimize_size)"
>> - "
>> -   if (!arm_arch6)
>> -     {
>> diff --git a/recipes/gcc/gcc-4.5/gcc-arm-volatile-bitfield-fix.patch
>> b/recipes/gcc/gcc-4.5/gcc-arm-volatile-bitfield-fix.patch
>> index d5a31d1..f833358 100644
>> --- a/recipes/gcc/gcc-4.5/gcc-arm-volatile-bitfield-fix.patch
>> +++ b/recipes/gcc/gcc-4.5/gcc-arm-volatile-bitfield-fix.patch
>> @@ -89,9 +89,9 @@ ChangeLog
>>
>>  Index: gcc-4_5-branch/gcc/expr.c
>>  ===================================================================
>> ---- gcc-4_5-branch.orig/gcc/expr.c     2010-12-23 00:42:11.690101002
>> -0800
>> -+++ gcc-4_5-branch/gcc/expr.c  2010-12-24 15:07:39.400101000 -0800
>> -@@ -9029,7 +9029,8 @@
>> +--- gcc-4_5-branch.orig/gcc/expr.c
>> ++++ gcc-4_5-branch/gcc/expr.c
>> +@@ -9033,7 +9033,8 @@ expand_expr_real_1 (tree exp, rtx target
>>                && modifier != EXPAND_INITIALIZER)
>>            /* If the field is volatile, we always want an aligned
>>               access.  */
>> diff --git a/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99448.patch
>> b/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99448.patch
>> deleted file mode 100644
>> index 9f3d47f..0000000
>> --- a/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99448.patch
>> +++ /dev/null
>> @@ -1,147 +0,0 @@
>> -2010-12-13  Chung-Lin Tang  <cltang at codesourcery.com>
>> -
>> -       Backport from mainline:
>> -
>> -       2010-12-10  Jakub Jelinek  <jakub at redhat.com>
>> -
>> -       PR rtl-optimization/46865
>> -
>> -       * rtl.c (rtx_equal_p_cb, rtx_equal_p): For last operand of
>> -       ASM_OPERANDS and ASM_INPUT if integers are different,
>> -       call locator_eq.
>> -       * jump.c (rtx_renumbered_equal_p): Likewise.
>> -
>> -       gcc/testsuite/
>> -       * gcc.target/i386/pr46865-1.c: New test.
>> -       * gcc.target/i386/pr46865-2.c: New test.
>> -
>> -=== modified file 'gcc/jump.c'
>> ---- old/gcc/jump.c     2009-11-25 10:55:54 +0000
>> -+++ new/gcc/jump.c     2010-12-13 10:05:52 +0000
>> -@@ -1728,7 +1728,13 @@
>> -
>> -       case 'i':
>> -         if (XINT (x, i) != XINT (y, i))
>> --          return 0;
>> -+          {
>> -+            if (((code == ASM_OPERANDS && i == 6)
>> -+                 || (code == ASM_INPUT && i == 1))
>> -+                && locator_eq (XINT (x, i), XINT (y, i)))
>> -+              break;
>> -+            return 0;
>> -+          }
>> -         break;
>> -
>> -       case 't':
>> -
>> -=== modified file 'gcc/rtl.c'
>> ---- old/gcc/rtl.c      2009-11-25 10:55:54 +0000
>> -+++ new/gcc/rtl.c      2010-12-13 10:05:52 +0000
>> -@@ -429,7 +429,15 @@
>> -       case 'n':
>> -       case 'i':
>> -         if (XINT (x, i) != XINT (y, i))
>> --          return 0;
>> -+          {
>> -+#ifndef GENERATOR_FILE
>> -+            if (((code == ASM_OPERANDS && i == 6)
>> -+                 || (code == ASM_INPUT && i == 1))
>> -+                && locator_eq (XINT (x, i), XINT (y, i)))
>> -+              break;
>> -+#endif
>> -+            return 0;
>> -+          }
>> -         break;
>> -
>> -       case 'V':
>> -@@ -549,7 +557,15 @@
>> -       case 'n':
>> -       case 'i':
>> -         if (XINT (x, i) != XINT (y, i))
>> --          return 0;
>> -+          {
>> -+#ifndef GENERATOR_FILE
>> -+            if (((code == ASM_OPERANDS && i == 6)
>> -+                 || (code == ASM_INPUT && i == 1))
>> -+                && locator_eq (XINT (x, i), XINT (y, i)))
>> -+              break;
>> -+#endif
>> -+            return 0;
>> -+          }
>> -         break;
>> -
>> -       case 'V':
>> -
>> -=== added file 'gcc/testsuite/gcc.target/i386/pr46865-1.c'
>> ---- old/gcc/testsuite/gcc.target/i386/pr46865-1.c      1970-01-01
>> 00:00:00 +0000
>> -+++ new/gcc/testsuite/gcc.target/i386/pr46865-1.c      2010-12-13
>> 10:05:52 +0000
>> -@@ -0,0 +1,31 @@
>> -+/* PR rtl-optimization/46865 */
>> -+/* { dg-do compile } */
>> -+/* { dg-options "-O2" } */
>> -+
>> -+extern unsigned long f;
>> -+
>> -+#define m1(f)                                                 \
>> -+  if (f & 1)                                                  \
>> -+    asm volatile ("nop /* asmnop */\n");                      \
>> -+  else                                                                \
>> -+    asm volatile ("nop /* asmnop */\n");
>> -+
>> -+#define m2(f)                                                 \
>> -+  if (f & 1)                                                  \
>> -+    asm volatile ("nop /* asmnop */\n" : : "i" (6) : "cx");   \
>> -+  else                                                                \
>> -+    asm volatile ("nop /* asmnop */\n" : : "i" (6) : "cx");
>> -+
>> -+void
>> -+foo (void)
>> -+{
>> -+  m1 (f);
>> -+}
>> -+
>> -+void
>> -+bar (void)
>> -+{
>> -+  m2 (f);
>> -+}
>> -+
>> -+/* { dg-final { scan-assembler-times "asmnop" 2 } } */
>> -
>> -=== added file 'gcc/testsuite/gcc.target/i386/pr46865-2.c'
>> ---- old/gcc/testsuite/gcc.target/i386/pr46865-2.c      1970-01-01
>> 00:00:00 +0000
>> -+++ new/gcc/testsuite/gcc.target/i386/pr46865-2.c      2010-12-13
>> 10:05:52 +0000
>> -@@ -0,0 +1,32 @@
>> -+/* PR rtl-optimization/46865 */
>> -+/* { dg-do compile } */
>> -+/* { dg-options "-O2 -save-temps" } */
>> -+
>> -+extern unsigned long f;
>> -+
>> -+#define m1(f)                                                 \
>> -+  if (f & 1)                                                  \
>> -+    asm volatile ("nop /* asmnop */\n");                      \
>> -+  else                                                                \
>> -+    asm volatile ("nop /* asmnop */\n");
>> -+
>> -+#define m2(f)                                                 \
>> -+  if (f & 1)                                                  \
>> -+    asm volatile ("nop /* asmnop */\n" : : "i" (6) : "cx");   \
>> -+  else                                                                \
>> -+    asm volatile ("nop /* asmnop */\n" : : "i" (6) : "cx");
>> -+
>> -+void
>> -+foo (void)
>> -+{
>> -+  m1 (f);
>> -+}
>> -+
>> -+void
>> -+bar (void)
>> -+{
>> -+  m2 (f);
>> -+}
>> -+
>> -+/* { dg-final { scan-assembler-times "asmnop" 2 } } */
>> -+/* { dg-final { cleanup-saved-temps } } */
>> -
>> diff --git a/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99456.patch
>> b/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99456.patch
>> deleted file mode 100644
>> index 35f98d2..0000000
>> --- a/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99456.patch
>> +++ /dev/null
>> @@ -1,3163 +0,0 @@
>> -2011-01-03  Bernd Schmidt  <bernds at codesourcery.com>
>> -
>> -       gcc/
>> -       * doc/tm.texi (RETURN_ADDR_REGNUM): Document.
>> -       * doc/md.texi (simple_return): Document pattern.
>> -       (return): Add a sentence to clarify.
>> -       * doc/rtl.texi (simple_return): Document.
>> -       * doc/invoke.texi (Optimize Options): Document -fshrink-wrap.
>> -       * common.opt (fshrink-wrap): New.
>> -       * opts.c (decode_options): Set it for -O2 and above.
>> -       * gengenrtl.c (special_rtx): PC, CC0, RETURN and SIMPLE_RETURN
>> -       are special.
>> -       * rtl.h (ANY_RETURN_P): New macro.
>> -       (global_rtl_index): Add GR_RETURN and GR_SIMPLE_RETURN.
>> -       (ret_rtx, simple_return_rtx): New macros.
>> -       * genemit.c (gen_exp): RETURN and SIMPLE_RETURN have unique rtxs.
>> -       (gen_expand, gen_split): Use ANY_RETURN_P.
>> -       * rtl.c (copy_rtx): RETURN and SIMPLE_RETURN are shared.
>> -       * emit-rtl.c (verify_rtx_sharing): Likewise.
>> -       (skip_consecutive_labels): Return the argument if it is a return
>> rtx.
>> -       (classify_insn): Handle both kinds of return.
>> -       (init_emit_regs): Create global rtl for ret_rtx and
>> simple_return_rtx.
>> -       * df-scan.c (df_uses_record): Handle SIMPLE_RETURN.
>> -       * rtl.def (SIMPLE_RETURN): New.
>> -       * rtlanal.c (tablejump_p): Check JUMP_LABEL for returns.
>> -       * final.c (final_scan_insn): Recognize both kinds of return.
>> -       * reorg.c (function_return_label, function_simple_return_label):
>> New
>> -       static variables.
>> -       (end_of_function_label): Remove.
>> -       (simplejump_or_return_p): New static function.
>> -       (find_end_label): Add a new arg, KIND.  All callers changed.
>> -       Depending on KIND, look for a label suitable for return or
>> -       simple_return.
>> -       (make_return_insns): Make corresponding changes.
>> -       (get_jump_flags): Check JUMP_LABELs for returns.
>> -       (follow_jumps): Likewise.
>> -       (get_branch_condition): Check target for return patterns rather
>> -       than NULL.
>> -       (own_thread_p): Likewise for thread.
>> -       (steal_delay_list_from_target): Check JUMP_LABELs for returns.
>> -       Use simplejump_or_return_p.
>> -       (fill_simple_delay_slots): Likewise.
>> -       (optimize_skip): Likewise.
>> -       (fill_slots_from_thread): Likewise.
>> -       (relax_delay_slots): Likewise.
>> -       (dbr_schedule): Adjust handling of end_of_function_label for the
>> -       two new variables.
>> -       * ifcvt.c (find_if_case_1): Take care when redirecting jumps to
>> the
>> -       exit block.
>> -       (dead_or_predicable): Change NEW_DEST arg to DEST_EDGE.  All
>> callers
>> -       changed.  Ensure that the right label is passed to redirect_jump.
>> -       * jump.c (condjump_p, condjump_in_parallel_p, any_condjump_p,
>> -       returnjump_p): Handle SIMPLE_RETURNs.
>> -       (delete_related_insns): Check JUMP_LABEL for returns.
>> -       (redirect_target): New static function.
>> -       (redirect_exp_1): Use it.  Handle any kind of return rtx as a
>> label
>> -       rather than interpreting NULL as a return.
>> -       (redirect_jump_1): Assert that nlabel is not NULL.
>> -       (redirect_jump): Likewise.
>> -       (redirect_jump_2): Handle any kind of return rtx as a label rather
>> -       than interpreting NULL as a return.
>> -       * dwarf2out.c (compute_barrier_args_size_1): Check JUMP_LABEL for
>> -       returns.
>> -       * function.c (emit_return_into_block): Remove useless declaration.
>> -       (record_hard_reg_sets, frame_required_for_rtx, gen_return_pattern,
>> -       requires_stack_frame_p): New static functions.
>> -       (emit_return_into_block): New arg SIMPLE_P.  All callers changed.
>> -       Generate either kind of return pattern and update the JUMP_LABEL.
>> -       (thread_prologue_and_epilogue_insns): Implement a form of
>> -       shrink-wrapping.  Ensure JUMP_LABELs for return insns are set.
>> -       * print-rtl.c (print_rtx): Handle returns in JUMP_LABELs.
>> -       * cfglayout.c (fixup_reorder_chain): Ensure JUMP_LABELs for
>> returns
>> -       remain correct.
>> -       * resource.c (find_dead_or_set_registers): Check JUMP_LABELs for
>> -       returns.
>> -       (mark_target_live_regs): Don't pass a return rtx to
>> next_active_insn.
>> -       * basic-block.h (force_nonfallthru_and_redirect): Declare.
>> -       * sched-vis.c (print_pattern): Add case for SIMPLE_RETURN.
>> -       * cfgrtl.c (force_nonfallthru_and_redirect): No longer static.
>>  New arg
>> -       JUMP_LABEL.  All callers changed.  Use the label when generating
>> -       return insns.
>> -
>> -       * config/i386/i386.md (returns, return_str, return_cond): New
>> -       code_iterator and corresponding code_attrs.
>> -       (<return_str>return): Renamed from return and adapted.
>> -       (<return_str>return_internal): Likewise for return_internal.
>> -       (<return_str>return_internal_long): Likewise for
>> return_internal_long.
>> -       (<return_str>return_pop_internal): Likewise for
>> return_pop_internal.
>> -       (<return_str>return_indirect_internal): Likewise for
>> -       return_indirect_internal.
>> -       * config/i386/i386.c (ix86_expand_epilogue): Expand a
>> simple_return as
>> -       the last insn.
>> -       (ix86_pad_returns): Handle both kinds of return rtx.
>> -       * config/arm/arm.c (use_simple_return_p): new function.
>> -       (is_jump_table): Handle returns in JUMP_LABELs.
>> -       (output_return_instruction): New arg SIMPLE.  All callers changed.
>> -       Use it to determine which kind of return to generate.
>> -       (arm_final_prescan_insn): Handle both kinds of return.
>> -       * config/arm/arm.md (returns, return_str, return_simple_p,
>> -       return_cond): New code_iterator and corresponding code_attrs.
>> -       (<return_str>return): Renamed from return and adapted.
>> -       (arm_<return_str>return): Renamed from arm_return and adapted.
>> -       (cond_<return_str>return): Renamed from cond_return and adapted.
>> -       (cond_<return_str>return_inverted): Renamed from
>> cond_return_inverted
>> -       and adapted.
>> -       (epilogue): Use ret_rtx instead of gen_rtx_RETURN.
>> -       * config/arm/thumb2.md (thumb2_<return_str>return): Renamed from
>> -       thumb2_return and adapted.
>> -       * config/arm/arm.h (RETURN_ADDR_REGNUM): Define.
>> -       * config/arm/arm-protos.h (use_simple_return_p): Declare.
>> -       (output_return_instruction): Adjust declaration.
>> -       * config/mips/mips.c (mips_expand_epilogue): Generate a
>> simple_return
>> -       as final insn.
>> -       * config/mips/mips.md (simple_return): New expander.
>> -       (*simple_return, simple_return_internal): New patterns.
>> -       * config/sh/sh.c (barrier_align): Handle return in a JUMP_LABEL.
>> -       (split_branches): Don't pass a null label to redirect_jump.
>> -
>> -       From mainline:
>> -       * vec.h (FOR_EACH_VEC_ELT, FOR_EACH_VEC_ELT_REVERSE): New macros.
>> -       * haifa-sched.c (find_fallthru_edge_from): Rename from
>> -       find_fallthru_edge.  All callers changed.
>> -       * sched-int.h (find_fallthru_edge_from): Rename declaration as
>> well.
>> -       * basic-block.h (find_fallthru_edge): New inline function.
>> -
>> -=== modified file 'gcc/basic-block.h'
>> ---- old/gcc/basic-block.h      2010-09-01 13:29:58 +0000
>> -+++ new/gcc/basic-block.h      2011-01-05 12:12:18 +0000
>> -@@ -884,6 +884,7 @@
>> -
>> - /* In cfgrtl.c  */
>> - extern basic_block force_nonfallthru (edge);
>> -+extern basic_block force_nonfallthru_and_redirect (edge, basic_block,
>> rtx);
>> - extern rtx block_label (basic_block);
>> - extern bool purge_all_dead_edges (void);
>> - extern bool purge_dead_edges (basic_block);
>> -@@ -1004,6 +1005,20 @@
>> -   return false;
>> - }
>> -
>> -+/* Return the fallthru edge in EDGES if it exists, NULL otherwise.  */
>> -+static inline edge
>> -+find_fallthru_edge (VEC(edge,gc) *edges)
>> -+{
>> -+  edge e;
>> -+  edge_iterator ei;
>> -+
>> -+  FOR_EACH_EDGE (e, ei, edges)
>> -+    if (e->flags & EDGE_FALLTHRU)
>> -+      break;
>> -+
>> -+  return e;
>> -+}
>> -+
>> - /* In cfgloopmanip.c.  */
>> - extern edge mfb_kj_edge;
>> - extern bool mfb_keep_just (edge);
>> -
>> -=== modified file 'gcc/cfganal.c'
>> ---- old/gcc/cfganal.c  2009-11-25 10:55:54 +0000
>> -+++ new/gcc/cfganal.c  2011-01-05 12:12:18 +0000
>> -@@ -271,6 +271,37 @@
>> -       EDGE_SUCC (bb, 0)->flags |= EDGE_CAN_FALLTHRU;
>> -       EDGE_SUCC (bb, 1)->flags |= EDGE_CAN_FALLTHRU;
>> -     }
>> -+  /* dwarf2out expects that a NOTE_INSN_EPILOGUE_BEGIN is always paired
>> -+     with a return or a sibcall.  Ensure that this remains the case if
>> -+     they are in different basic blocks.  */
>> -+  FOR_EACH_BB (bb)
>> -+    {
>> -+      edge e;
>> -+      edge_iterator ei;
>> -+      rtx insn, end;
>> -+
>> -+      end = BB_END (bb);
>> -+      FOR_BB_INSNS (bb, insn)
>> -+      if (GET_CODE (insn) == NOTE
>> -+          && NOTE_KIND (insn) == NOTE_INSN_EPILOGUE_BEG
>> -+          && !(CALL_P (end) && SIBLING_CALL_P (end))
>> -+          && !returnjump_p (end))
>> -+        {
>> -+          basic_block other_bb = NULL;
>> -+          FOR_EACH_EDGE (e, ei, bb->succs)
>> -+            {
>> -+              if (e->flags & EDGE_FALLTHRU)
>> -+                other_bb = e->dest;
>> -+              else
>> -+                e->flags &= ~EDGE_CAN_FALLTHRU;
>> -+            }
>> -+          FOR_EACH_EDGE (e, ei, other_bb->preds)
>> -+            {
>> -+              if (!(e->flags & EDGE_FALLTHRU))
>> -+                e->flags &= ~EDGE_CAN_FALLTHRU;
>> -+            }
>> -+        }
>> -+    }
>> - }
>> -
>> - /* Find unreachable blocks.  An unreachable block will have 0 in
>> -
>> -=== modified file 'gcc/cfglayout.c'
>> ---- old/gcc/cfglayout.c        2010-05-17 16:30:54 +0000
>> -+++ new/gcc/cfglayout.c        2011-01-05 12:12:18 +0000
>> -@@ -766,6 +766,7 @@
>> -     {
>> -       edge e_fall, e_taken, e;
>> -       rtx bb_end_insn;
>> -+      rtx ret_label = NULL_RTX;
>> -       basic_block nb;
>> -       edge_iterator ei;
>> -
>> -@@ -785,6 +786,7 @@
>> -       bb_end_insn = BB_END (bb);
>> -       if (JUMP_P (bb_end_insn))
>> -       {
>> -+        ret_label = JUMP_LABEL (bb_end_insn);
>> -         if (any_condjump_p (bb_end_insn))
>> -           {
>> -             /* This might happen if the conditional jump has side
>> -@@ -899,7 +901,7 @@
>> -       }
>> -
>> -       /* We got here if we need to add a new jump insn.  */
>> --      nb = force_nonfallthru (e_fall);
>> -+      nb = force_nonfallthru_and_redirect (e_fall, e_fall->dest,
>> ret_label);
>> -       if (nb)
>> -       {
>> -         nb->il.rtl->visited = 1;
>> -@@ -1118,24 +1120,30 @@
>> - bool
>> - cfg_layout_can_duplicate_bb_p (const_basic_block bb)
>> - {
>> -+  rtx insn;
>> -+
>> -   /* Do not attempt to duplicate tablejumps, as we need to unshare
>> -      the dispatch table.  This is difficult to do, as the instructions
>> -      computing jump destination may be hoisted outside the basic block.
>>  */
>> -   if (tablejump_p (BB_END (bb), NULL, NULL))
>> -     return false;
>> -
>> --  /* Do not duplicate blocks containing insns that can't be copied.  */
>> --  if (targetm.cannot_copy_insn_p)
>> -+  insn = BB_HEAD (bb);
>> -+  while (1)
>> -     {
>> --      rtx insn = BB_HEAD (bb);
>> --      while (1)
>> --      {
>> --        if (INSN_P (insn) && targetm.cannot_copy_insn_p (insn))
>> --          return false;
>> --        if (insn == BB_END (bb))
>> --          break;
>> --        insn = NEXT_INSN (insn);
>> --      }
>> -+      /* Do not duplicate blocks containing insns that can't be copied.
>>  */
>> -+      if (INSN_P (insn) && targetm.cannot_copy_insn_p
>> -+        && targetm.cannot_copy_insn_p (insn))
>> -+      return false;
>> -+      /* dwarf2out expects that these notes are always paired with a
>> -+       returnjump or sibling call.  */
>> -+      if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_EPILOGUE_BEG
>> -+        && !returnjump_p (BB_END (bb))
>> -+        && (!CALL_P (BB_END (bb)) || !SIBLING_CALL_P (BB_END (bb))))
>> -+      return false;
>> -+      if (insn == BB_END (bb))
>> -+      break;
>> -+      insn = NEXT_INSN (insn);
>> -     }
>> -
>> -   return true;
>> -@@ -1167,6 +1175,9 @@
>> -             || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
>> -           break;
>> -         copy = emit_copy_of_insn_after (insn, get_last_insn ());
>> -+        if (JUMP_P (insn) && JUMP_LABEL (insn) != NULL_RTX
>> -+            && ANY_RETURN_P (JUMP_LABEL (insn)))
>> -+          JUMP_LABEL (copy) = JUMP_LABEL (insn);
>> -           maybe_copy_epilogue_insn (insn, copy);
>> -         break;
>> -
>> -
>> -=== modified file 'gcc/cfgrtl.c'
>> ---- old/gcc/cfgrtl.c   2010-09-20 21:30:35 +0000
>> -+++ new/gcc/cfgrtl.c   2011-01-05 12:12:18 +0000
>> -@@ -1107,10 +1107,13 @@
>> - }
>> -
>> - /* Like force_nonfallthru below, but additionally performs redirection
>> --   Used by redirect_edge_and_branch_force.  */
>> -+   Used by redirect_edge_and_branch_force.  JUMP_LABEL is used only
>> -+   when redirecting to the EXIT_BLOCK, it is either a return or a
>> -+   simple_return rtx indicating which kind of returnjump to create.
>> -+   It should be NULL otherwise.  */
>> -
>> --static basic_block
>> --force_nonfallthru_and_redirect (edge e, basic_block target)
>> -+basic_block
>> -+force_nonfallthru_and_redirect (edge e, basic_block target, rtx
>> jump_label)
>> - {
>> -   basic_block jump_block, new_bb = NULL, src = e->src;
>> -   rtx note;
>> -@@ -1242,11 +1245,25 @@
>> -   e->flags &= ~EDGE_FALLTHRU;
>> -   if (target == EXIT_BLOCK_PTR)
>> -     {
>> -+      if (jump_label == ret_rtx)
>> -+      {
>> - #ifdef HAVE_return
>> --      emit_jump_insn_after_setloc (gen_return (), BB_END (jump_block),
>> loc);
>> --#else
>> --      gcc_unreachable ();
>> --#endif
>> -+        emit_jump_insn_after_setloc (gen_return (), BB_END (jump_block),
>> -+                                     loc);
>> -+#else
>> -+        gcc_unreachable ();
>> -+#endif
>> -+      }
>> -+      else
>> -+      {
>> -+        gcc_assert (jump_label == simple_return_rtx);
>> -+#ifdef HAVE_simple_return
>> -+        emit_jump_insn_after_setloc (gen_simple_return (),
>> -+                                     BB_END (jump_block), loc);
>> -+#else
>> -+        gcc_unreachable ();
>> -+#endif
>> -+      }
>> -     }
>> -   else
>> -     {
>> -@@ -1273,7 +1290,7 @@
>> - basic_block
>> - force_nonfallthru (edge e)
>> - {
>> --  return force_nonfallthru_and_redirect (e, e->dest);
>> -+  return force_nonfallthru_and_redirect (e, e->dest, NULL_RTX);
>> - }
>> -
>> - /* Redirect edge even at the expense of creating new jump insn or
>> -@@ -1290,7 +1307,7 @@
>> -   /* In case the edge redirection failed, try to force it to be
>> non-fallthru
>> -      and redirect newly created simplejump.  */
>> -   df_set_bb_dirty (e->src);
>> --  return force_nonfallthru_and_redirect (e, target);
>> -+  return force_nonfallthru_and_redirect (e, target, NULL_RTX);
>> - }
>> -
>> - /* The given edge should potentially be a fallthru edge.  If that is in
>> -
>> -=== modified file 'gcc/common.opt'
>> ---- old/gcc/common.opt 2010-12-10 15:33:37 +0000
>> -+++ new/gcc/common.opt 2011-01-05 12:12:18 +0000
>> -@@ -1147,6 +1147,11 @@
>> - Common C ObjC C++ ObjC++ Report Var(flag_show_column) Init(1)
>> - Show column numbers in diagnostics, when available.  Default on
>> -
>> -+fshrink-wrap
>> -+Common Report Var(flag_shrink_wrap) Optimization
>> -+Emit function prologues only before parts of the function that need it,
>> -+rather than at the top of the function.
>> -+
>> - fsignaling-nans
>> - Common Report Var(flag_signaling_nans) Optimization
>> - Disable optimizations observable by IEEE signaling NaNs
>> -
>> -=== modified file 'gcc/config/arm/arm-protos.h'
>> ---- old/gcc/config/arm/arm-protos.h    2010-11-04 10:45:05 +0000
>> -+++ new/gcc/config/arm/arm-protos.h    2011-01-05 12:12:18 +0000
>> -@@ -26,6 +26,7 @@
>> - extern void arm_override_options (void);
>> - extern void arm_optimization_options (int, int);
>> - extern int use_return_insn (int, rtx);
>> -+extern bool use_simple_return_p (void);
>> - extern enum reg_class arm_regno_class (int);
>> - extern void arm_load_pic_register (unsigned long);
>> - extern int arm_volatile_func (void);
>> -@@ -137,7 +138,7 @@
>> - extern const char *output_add_immediate (rtx *);
>> - extern const char *arithmetic_instr (rtx, int);
>> - extern void output_ascii_pseudo_op (FILE *, const unsigned char *, int);
>> --extern const char *output_return_instruction (rtx, int, int);
>> -+extern const char *output_return_instruction (rtx, bool, bool, bool);
>> - extern void arm_poke_function_name (FILE *, const char *);
>> - extern void arm_print_operand (FILE *, rtx, int);
>> - extern void arm_print_operand_address (FILE *, rtx);
>> -
>> -=== modified file 'gcc/config/arm/arm.c'
>> ---- old/gcc/config/arm/arm.c   2011-01-05 11:32:50 +0000
>> -+++ new/gcc/config/arm/arm.c   2011-01-05 12:12:18 +0000
>> -@@ -2163,6 +2163,18 @@
>> -   return addr;
>> - }
>> -
>> -+/* Return true if we should try to use a simple_return insn, i.e.
>> perform
>> -+   shrink-wrapping if possible.  This is the case if we need to emit a
>> -+   prologue, which we can test by looking at the offsets.  */
>> -+bool
>> -+use_simple_return_p (void)
>> -+{
>> -+  arm_stack_offsets *offsets;
>> -+
>> -+  offsets = arm_get_frame_offsets ();
>> -+  return offsets->outgoing_args != 0;
>> -+}
>> -+
>> - /* Return 1 if it is possible to return using a single instruction.
>> -    If SIBLING is non-null, this is a test for a return before a sibling
>> -    call.  SIBLING is the call insn, so we can examine its register
>> usage.  */
>> -@@ -11284,6 +11296,7 @@
>> -
>> -   if (GET_CODE (insn) == JUMP_INSN
>> -       && JUMP_LABEL (insn) != NULL
>> -+      && !ANY_RETURN_P (JUMP_LABEL (insn))
>> -       && ((table = next_real_insn (JUMP_LABEL (insn)))
>> -         == next_real_insn (insn))
>> -       && table != NULL
>> -@@ -14168,7 +14181,7 @@
>> - /* Generate a function exit sequence.  If REALLY_RETURN is false, then
>> do
>> -    everything bar the final return instruction.  */
>> - const char *
>> --output_return_instruction (rtx operand, int really_return, int reverse)
>> -+output_return_instruction (rtx operand, bool really_return, bool
>> reverse, bool simple)
>> - {
>> -   char conditional[10];
>> -   char instr[100];
>> -@@ -14206,10 +14219,15 @@
>> -
>> -   sprintf (conditional, "%%?%%%c0", reverse ? 'D' : 'd');
>> -
>> --  cfun->machine->return_used_this_function = 1;
>> -+  if (simple)
>> -+    live_regs_mask = 0;
>> -+  else
>> -+    {
>> -+      cfun->machine->return_used_this_function = 1;
>> -
>> --  offsets = arm_get_frame_offsets ();
>> --  live_regs_mask = offsets->saved_regs_mask;
>> -+      offsets = arm_get_frame_offsets ();
>> -+      live_regs_mask = offsets->saved_regs_mask;
>> -+    }
>> -
>> -   if (live_regs_mask)
>> -     {
>> -@@ -17108,6 +17126,7 @@
>> -
>> -   /* If we start with a return insn, we only succeed if we find another
>> one.  */
>> -   int seeking_return = 0;
>> -+  enum rtx_code return_code = UNKNOWN;
>> -
>> -   /* START_INSN will hold the insn from where we start looking.  This is
>> the
>> -      first insn after the following code_label if REVERSE is true.  */
>> -@@ -17146,7 +17165,7 @@
>> -         else
>> -           return;
>> -       }
>> --      else if (GET_CODE (body) == RETURN)
>> -+      else if (ANY_RETURN_P (body))
>> -         {
>> -         start_insn = next_nonnote_insn (start_insn);
>> -         if (GET_CODE (start_insn) == BARRIER)
>> -@@ -17157,6 +17176,7 @@
>> -           {
>> -             reverse = TRUE;
>> -             seeking_return = 1;
>> -+            return_code = GET_CODE (body);
>> -           }
>> -         else
>> -           return;
>> -@@ -17197,11 +17217,15 @@
>> -         label = XEXP (XEXP (SET_SRC (body), 2), 0);
>> -         then_not_else = FALSE;
>> -       }
>> --      else if (GET_CODE (XEXP (SET_SRC (body), 1)) == RETURN)
>> --      seeking_return = 1;
>> --      else if (GET_CODE (XEXP (SET_SRC (body), 2)) == RETURN)
>> -+      else if (ANY_RETURN_P (XEXP (SET_SRC (body), 1)))
>> -+      {
>> -+        seeking_return = 1;
>> -+        return_code = GET_CODE (XEXP (SET_SRC (body), 1));
>> -+      }
>> -+      else if (ANY_RETURN_P (XEXP (SET_SRC (body), 2)))
>> -         {
>> -         seeking_return = 1;
>> -+        return_code = GET_CODE (XEXP (SET_SRC (body), 2));
>> -         then_not_else = FALSE;
>> -         }
>> -       else
>> -@@ -17302,8 +17326,7 @@
>> -                      && !use_return_insn (TRUE, NULL)
>> -                      && !optimize_size)
>> -               fail = TRUE;
>> --            else if (GET_CODE (scanbody) == RETURN
>> --                     && seeking_return)
>> -+            else if (GET_CODE (scanbody) == return_code)
>> -               {
>> -                 arm_ccfsm_state = 2;
>> -                 succeed = TRUE;
>> -
>> -=== modified file 'gcc/config/arm/arm.h'
>> ---- old/gcc/config/arm/arm.h   2010-11-11 11:12:14 +0000
>> -+++ new/gcc/config/arm/arm.h   2011-01-05 12:12:18 +0000
>> -@@ -2622,6 +2622,8 @@
>> - #define RETURN_ADDR_RTX(COUNT, FRAME) \
>> -   arm_return_addr (COUNT, FRAME)
>> -
>> -+#define RETURN_ADDR_REGNUM LR_REGNUM
>> -+
>> - /* Mask of the bits in the PC that contain the real return address
>> -    when running in 26-bit mode.  */
>> - #define RETURN_ADDR_MASK26 (0x03fffffc)
>> -
>> -=== modified file 'gcc/config/arm/arm.md'
>> ---- old/gcc/config/arm/arm.md  2011-01-05 11:52:16 +0000
>> -+++ new/gcc/config/arm/arm.md  2011-01-05 12:12:18 +0000
>> -@@ -8882,66 +8882,72 @@
>> -   [(set_attr "type" "call")]
>> - )
>> -
>> --(define_expand "return"
>> --  [(return)]
>> --  "TARGET_32BIT && USE_RETURN_INSN (FALSE)"
>> -+;; Both kinds of return insn.
>> -+(define_code_iterator returns [return simple_return])
>> -+(define_code_attr return_str [(return "") (simple_return "simple_")])
>> -+(define_code_attr return_simple_p [(return "false") (simple_return
>> "true")])
>> -+(define_code_attr return_cond [(return " && USE_RETURN_INSN (FALSE)")
>> -+                             (simple_return " && use_simple_return_p
>> ()")])
>> -+
>> -+(define_expand "<return_str>return"
>> -+  [(returns)]
>> -+  "TARGET_32BIT<return_cond>"
>> -   "")
>> -
>> --;; Often the return insn will be the same as loading from memory, so set
>> attr
>> --(define_insn "*arm_return"
>> --  [(return)]
>> --  "TARGET_ARM && USE_RETURN_INSN (FALSE)"
>> --  "*
>> --  {
>> --    if (arm_ccfsm_state == 2)
>> --      {
>> --        arm_ccfsm_state += 2;
>> --        return \"\";
>> --      }
>> --    return output_return_instruction (const_true_rtx, TRUE, FALSE);
>> --  }"
>> -+(define_insn "*arm_<return_str>return"
>> -+  [(returns)]
>> -+  "TARGET_ARM<return_cond>"
>> -+{
>> -+  if (arm_ccfsm_state == 2)
>> -+    {
>> -+      arm_ccfsm_state += 2;
>> -+      return "";
>> -+    }
>> -+  return output_return_instruction (const_true_rtx, true, false,
>> -+                                  <return_simple_p>);
>> -+}
>> -   [(set_attr "type" "load1")
>> -    (set_attr "length" "12")
>> -    (set_attr "predicable" "yes")]
>> - )
>> -
>> --(define_insn "*cond_return"
>> -+(define_insn "*cond_<return_str>return"
>> -   [(set (pc)
>> -         (if_then_else (match_operator 0 "arm_comparison_operator"
>> -                      [(match_operand 1 "cc_register" "") (const_int 0)])
>> --                      (return)
>> -+                      (returns)
>> -                       (pc)))]
>> --  "TARGET_ARM && USE_RETURN_INSN (TRUE)"
>> --  "*
>> --  {
>> --    if (arm_ccfsm_state == 2)
>> --      {
>> --        arm_ccfsm_state += 2;
>> --        return \"\";
>> --      }
>> --    return output_return_instruction (operands[0], TRUE, FALSE);
>> --  }"
>> -+  "TARGET_ARM<return_cond>"
>> -+{
>> -+  if (arm_ccfsm_state == 2)
>> -+    {
>> -+      arm_ccfsm_state += 2;
>> -+      return "";
>> -+    }
>> -+  return output_return_instruction (operands[0], true, false,
>> -+                                  <return_simple_p>);
>> -+}
>> -   [(set_attr "conds" "use")
>> -    (set_attr "length" "12")
>> -    (set_attr "type" "load1")]
>> - )
>> -
>> --(define_insn "*cond_return_inverted"
>> -+(define_insn "*cond_<return_str>return_inverted"
>> -   [(set (pc)
>> -         (if_then_else (match_operator 0 "arm_comparison_operator"
>> -                      [(match_operand 1 "cc_register" "") (const_int 0)])
>> -                       (pc)
>> --                    (return)))]
>> --  "TARGET_ARM && USE_RETURN_INSN (TRUE)"
>> --  "*
>> --  {
>> --    if (arm_ccfsm_state == 2)
>> --      {
>> --        arm_ccfsm_state += 2;
>> --        return \"\";
>> --      }
>> --    return output_return_instruction (operands[0], TRUE, TRUE);
>> --  }"
>> -+                    (returns)))]
>> -+  "TARGET_ARM<return_cond>"
>> -+{
>> -+  if (arm_ccfsm_state == 2)
>> -+    {
>> -+      arm_ccfsm_state += 2;
>> -+      return "";
>> -+    }
>> -+  return output_return_instruction (operands[0], true, true,
>> -+                                  <return_simple_p>);
>> -+}
>> -   [(set_attr "conds" "use")
>> -    (set_attr "length" "12")
>> -    (set_attr "type" "load1")]
>> -@@ -10809,8 +10815,7 @@
>> -       DONE;
>> -     }
>> -   emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
>> --      gen_rtvec (1,
>> --              gen_rtx_RETURN (VOIDmode)),
>> -+      gen_rtvec (1, ret_rtx),
>> -       VUNSPEC_EPILOGUE));
>> -   DONE;
>> -   "
>> -@@ -10827,7 +10832,7 @@
>> -   "TARGET_32BIT"
>> -   "*
>> -   if (use_return_insn (FALSE, next_nonnote_insn (insn)))
>> --    return output_return_instruction (const_true_rtx, FALSE, FALSE);
>> -+    return output_return_instruction (const_true_rtx, false, false,
>> false);
>> -   return arm_output_epilogue (next_nonnote_insn (insn));
>> -   "
>> - ;; Length is absolute worst case
>> -
>> -=== modified file 'gcc/config/arm/thumb2.md'
>> ---- old/gcc/config/arm/thumb2.md       2010-09-22 05:54:42 +0000
>> -+++ new/gcc/config/arm/thumb2.md       2011-01-05 12:12:18 +0000
>> -@@ -1020,16 +1020,15 @@
>> -
>> - ;; Note: this is not predicable, to avoid issues with linker-generated
>> - ;; interworking stubs.
>> --(define_insn "*thumb2_return"
>> --  [(return)]
>> --  "TARGET_THUMB2 && USE_RETURN_INSN (FALSE)"
>> --  "*
>> --  {
>> --    return output_return_instruction (const_true_rtx, TRUE, FALSE);
>> --  }"
>> -+(define_insn "*thumb2_<return_str>return"
>> -+  [(returns)]
>> -+  "TARGET_THUMB2<return_cond>"
>> -+{
>> -+  return output_return_instruction (const_true_rtx, true, false,
>> -+                                  <return_simple_p>);
>> -+}
>> -   [(set_attr "type" "load1")
>> --   (set_attr "length" "12")]
>> --)
>> -+   (set_attr "length" "12")])
>> -
>> - (define_insn_and_split "thumb2_eh_return"
>> -   [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
>> -
>> -=== modified file 'gcc/config/i386/i386.c'
>> ---- old/gcc/config/i386/i386.c 2010-11-16 18:05:53 +0000
>> -+++ new/gcc/config/i386/i386.c 2011-01-05 12:12:18 +0000
>> -@@ -9308,13 +9308,13 @@
>> -
>> -         pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
>> -                                    popc, -1, true);
>> --        emit_jump_insn (gen_return_indirect_internal (ecx));
>> -+        emit_jump_insn (gen_simple_return_indirect_internal (ecx));
>> -       }
>> -       else
>> --      emit_jump_insn (gen_return_pop_internal (popc));
>> -+      emit_jump_insn (gen_simple_return_pop_internal (popc));
>> -     }
>> -   else
>> --    emit_jump_insn (gen_return_internal ());
>> -+    emit_jump_insn (gen_simple_return_internal ());
>> -
>> -   /* Restore the state back to the state from the prologue,
>> -      so that it's correct for the next epilogue.  */
>> -@@ -26596,7 +26596,7 @@
>> -       rtx prev;
>> -       bool replace = false;
>> -
>> --      if (!JUMP_P (ret) || GET_CODE (PATTERN (ret)) != RETURN
>> -+      if (!JUMP_P (ret) || !ANY_RETURN_P (PATTERN (ret))
>> -         || optimize_bb_for_size_p (bb))
>> -       continue;
>> -       for (prev = PREV_INSN (ret); prev; prev = PREV_INSN (prev))
>> -@@ -26626,7 +26626,10 @@
>> -       }
>> -       if (replace)
>> -       {
>> --        emit_jump_insn_before (gen_return_internal_long (), ret);
>> -+        if (PATTERN (ret) == ret_rtx)
>> -+          emit_jump_insn_before (gen_return_internal_long (), ret);
>> -+        else
>> -+          emit_jump_insn_before (gen_simple_return_internal_long (),
>> ret);
>> -         delete_insn (ret);
>> -       }
>> -     }
>> -
>> -=== modified file 'gcc/config/i386/i386.md'
>> ---- old/gcc/config/i386/i386.md        2010-11-27 15:24:12 +0000
>> -+++ new/gcc/config/i386/i386.md        2011-01-05 12:12:18 +0000
>> -@@ -13797,24 +13797,29 @@
>> -   ""
>> -   [(set_attr "length" "0")])
>> -
>> -+(define_code_iterator returns [return simple_return])
>> -+(define_code_attr return_str [(return "") (simple_return "simple_")])
>> -+(define_code_attr return_cond [(return "ix86_can_use_return_insn_p ()")
>> -+                             (simple_return "")])
>> -+
>> - ;; Insn emitted into the body of a function to return from a function.
>> - ;; This is only done if the function's epilogue is known to be simple.
>> - ;; See comments for ix86_can_use_return_insn_p in i386.c.
>> -
>> --(define_expand "return"
>> --  [(return)]
>> --  "ix86_can_use_return_insn_p ()"
>> -+(define_expand "<return_str>return"
>> -+  [(returns)]
>> -+  "<return_cond>"
>> - {
>> -   if (crtl->args.pops_args)
>> -     {
>> -       rtx popc = GEN_INT (crtl->args.pops_args);
>> --      emit_jump_insn (gen_return_pop_internal (popc));
>> -+      emit_jump_insn (gen_<return_str>return_pop_internal (popc));
>> -       DONE;
>> -     }
>> - })
>> -
>> --(define_insn "return_internal"
>> --  [(return)]
>> -+(define_insn "<return_str>return_internal"
>> -+  [(returns)]
>> -   "reload_completed"
>> -   "ret"
>> -   [(set_attr "length" "1")
>> -@@ -13825,8 +13830,8 @@
>> - ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte
>> RET
>> - ;; instruction Athlon and K8 have.
>> -
>> --(define_insn "return_internal_long"
>> --  [(return)
>> -+(define_insn "<return_str>return_internal_long"
>> -+  [(returns)
>> -    (unspec [(const_int 0)] UNSPEC_REP)]
>> -   "reload_completed"
>> -   "rep\;ret"
>> -@@ -13836,8 +13841,8 @@
>> -    (set_attr "prefix_rep" "1")
>> -    (set_attr "modrm" "0")])
>> -
>> --(define_insn "return_pop_internal"
>> --  [(return)
>> -+(define_insn "<return_str>return_pop_internal"
>> -+  [(returns)
>> -    (use (match_operand:SI 0 "const_int_operand" ""))]
>> -   "reload_completed"
>> -   "ret\t%0"
>> -@@ -13846,8 +13851,8 @@
>> -    (set_attr "length_immediate" "2")
>> -    (set_attr "modrm" "0")])
>> -
>> --(define_insn "return_indirect_internal"
>> --  [(return)
>> -+(define_insn "<return_str>return_indirect_internal"
>> -+  [(returns)
>> -    (use (match_operand:SI 0 "register_operand" "r"))]
>> -   "reload_completed"
>> -   "jmp\t%A0"
>> -
>> -=== modified file 'gcc/config/mips/mips.c'
>> ---- old/gcc/config/mips/mips.c 2010-11-21 10:38:43 +0000
>> -+++ new/gcc/config/mips/mips.c 2011-01-05 12:12:18 +0000
>> -@@ -10497,7 +10497,8 @@
>> -           regno = GP_REG_FIRST + 7;
>> -         else
>> -           regno = RETURN_ADDR_REGNUM;
>> --        emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode,
>> regno)));
>> -+        emit_jump_insn (gen_simple_return_internal (gen_rtx_REG (Pmode,
>> -+
>> regno)));
>> -       }
>> -     }
>> -
>> -
>> -=== modified file 'gcc/config/mips/mips.md'
>> ---- old/gcc/config/mips/mips.md        2010-04-02 18:54:46 +0000
>> -+++ new/gcc/config/mips/mips.md        2011-01-05 12:12:18 +0000
>> -@@ -5815,6 +5815,18 @@
>> -   [(set_attr "type"   "jump")
>> -    (set_attr "mode"   "none")])
>> -
>> -+(define_expand "simple_return"
>> -+  [(simple_return)]
>> -+  "!mips_can_use_return_insn ()"
>> -+  { mips_expand_before_return (); })
>> -+
>> -+(define_insn "*simple_return"
>> -+  [(simple_return)]
>> -+  "!mips_can_use_return_insn ()"
>> -+  "%*j\t$31%/"
>> -+  [(set_attr "type"   "jump")
>> -+   (set_attr "mode"   "none")])
>> -+
>> - ;; Normal return.
>> -
>> - (define_insn "return_internal"
>> -@@ -5825,6 +5837,14 @@
>> -   [(set_attr "type"   "jump")
>> -    (set_attr "mode"   "none")])
>> -
>> -+(define_insn "simple_return_internal"
>> -+  [(simple_return)
>> -+   (use (match_operand 0 "pmode_register_operand" ""))]
>> -+  ""
>> -+  "%*j\t%0%/"
>> -+  [(set_attr "type"   "jump")
>> -+   (set_attr "mode"   "none")])
>> -+
>> - ;; Exception return.
>> - (define_insn "mips_eret"
>> -   [(return)
>> -
>> -=== modified file 'gcc/config/sh/sh.c'
>> ---- old/gcc/config/sh/sh.c     2010-12-10 15:34:19 +0000
>> -+++ new/gcc/config/sh/sh.c     2011-01-05 12:12:18 +0000
>> -@@ -5252,7 +5252,8 @@
>> -       }
>> -       if (prev
>> -         && JUMP_P (prev)
>> --        && JUMP_LABEL (prev))
>> -+        && JUMP_LABEL (prev)
>> -+        && !ANY_RETURN_P (JUMP_LABEL (prev)))
>> -       {
>> -         rtx x;
>> -         if (jump_to_next
>> -@@ -5951,7 +5952,7 @@
>> -                       JUMP_LABEL (insn) = far_label;
>> -                       LABEL_NUSES (far_label)++;
>> -                     }
>> --                  redirect_jump (insn, NULL_RTX, 1);
>> -+                  redirect_jump (insn, ret_rtx, 1);
>> -                   far_label = 0;
>> -                 }
>> -             }
>> -
>> -=== modified file 'gcc/df-scan.c'
>> ---- old/gcc/df-scan.c  2010-11-16 22:17:17 +0000
>> -+++ new/gcc/df-scan.c  2011-01-05 12:12:18 +0000
>> -@@ -3296,6 +3296,7 @@
>> -       }
>> -
>> -     case RETURN:
>> -+    case SIMPLE_RETURN:
>> -       break;
>> -
>> -     case ASM_OPERANDS:
>> -
>> -=== modified file 'gcc/doc/invoke.texi'
>> ---- old/gcc/doc/invoke.texi    2010-11-04 14:29:09 +0000
>> -+++ new/gcc/doc/invoke.texi    2011-01-05 12:12:18 +0000
>> -@@ -5750,6 +5750,7 @@
>> - -fipa-pure-const @gol
>> - -fipa-reference @gol
>> - -fmerge-constants
>> -+-fshrink-wrap @gol
>> - -fsplit-wide-types @gol
>> - -ftree-builtin-call-dce @gol
>> - -ftree-ccp @gol
>> -@@ -6504,6 +6505,12 @@
>> - When pipelining loops during selective scheduling, also pipeline outer
>> loops.
>> - This option has no effect until @option{-fsel-sched-pipelining} is
>> turned on.
>> -
>> -+ at item -fshrink-wrap
>> -+ at opindex fshrink-wrap
>> -+Emit function prologues only before parts of the function that need it,
>> -+rather than at the top of the function.  This flag is enabled by default
>> at
>> -+ at option{-O} and higher.
>> -+
>> - @item -fcaller-saves
>> - @opindex fcaller-saves
>> - Enable values to be allocated in registers that will be clobbered by
>> -
>> -=== modified file 'gcc/doc/md.texi'
>> ---- old/gcc/doc/md.texi        2009-12-15 18:36:44 +0000
>> -+++ new/gcc/doc/md.texi        2011-01-05 12:12:18 +0000
>> -@@ -4801,7 +4801,19 @@
>> - multiple instructions are usually needed to return from a function, but
>> - some class of functions only requires one instruction to implement a
>> - return.  Normally, the applicable functions are those which do not need
>> --to save any registers or allocate stack space.
>> -+to save any registers or allocate stack space, although some targets
>> -+have instructions that can perform both the epilogue and function return
>> -+in one instruction.
>> -+
>> -+ at cindex @code{simple_return} instruction pattern
>> -+ at item @samp{simple_return}
>> -+Subroutine return instruction.  This instruction pattern name should be
>> -+defined only if a single instruction can do all the work of returning
>> -+from a function on a path where no epilogue is required.  This pattern
>> -+is very similar to the @code{return} instruction pattern, but it is
>> emitted
>> -+only by the shrink-wrapping optimization on paths where the function
>> -+prologue has not been executed, and a function return should occur
>> without
>> -+any of the effects of the epilogue.
>> -
>> - @findex reload_completed
>> - @findex leaf_function_p
>> -
>> -=== modified file 'gcc/doc/rtl.texi'
>> ---- old/gcc/doc/rtl.texi       2010-07-06 19:23:53 +0000
>> -+++ new/gcc/doc/rtl.texi       2011-01-05 12:12:18 +0000
>> -@@ -2888,6 +2888,13 @@
>> - Note that an insn pattern of @code{(return)} is logically equivalent to
>> - @code{(set (pc) (return))}, but the latter form is never used.
>> -
>> -+ at findex simple_return
>> -+ at item (simple_return)
>> -+Like @code{(return)}, but truly represents only a function return, while
>> -+ at code{(return)} may represent an insn that also performs other functions
>> -+of the function epilogue.  Like @code{(return)}, this may also occur in
>> -+conditional jumps.
>> -+
>> - @findex call
>> - @item (call @var{function} @var{nargs})
>> - Represents a function call.  @var{function} is a @code{mem} expression
>> -@@ -3017,7 +3024,7 @@
>> - brackets stand for a vector; the operand of @code{parallel} is a
>> - vector of expressions.  @var{x0}, @var{x1} and so on are individual
>> - side effect expressions---expressions of code @code{set}, @code{call},
>> -- at code{return}, @code{clobber} or @code{use}.
>> -+ at code{return}, @code{simple_return}, @code{clobber} or @code{use}.
>> -
>> - ``In parallel'' means that first all the values used in the individual
>> - side-effects are computed, and second all the actual side-effects are
>> -@@ -3656,14 +3663,16 @@
>> - @table @code
>> - @findex PATTERN
>> - @item PATTERN (@var{i})
>> --An expression for the side effect performed by this insn.  This must be
>> --one of the following codes: @code{set}, @code{call}, @code{use},
>> -- at code{clobber}, @code{return}, @code{asm_input}, @code{asm_output},
>> -- at code{addr_vec}, @code{addr_diff_vec}, @code{trap_if}, @code{unspec},
>> -- at code{unspec_volatile}, @code{parallel}, @code{cond_exec}, or
>> @code{sequence}.  If it is a @code{parallel},
>> --each element of the @code{parallel} must be one these codes, except that
>> -- at code{parallel} expressions cannot be nested and @code{addr_vec} and
>> -- at code{addr_diff_vec} are not permitted inside a @code{parallel}
>> expression.
>> -+An expression for the side effect performed by this insn.  This must
>> -+be one of the following codes: @code{set}, @code{call}, @code{use},
>> -+ at code{clobber}, @code{return}, @code{simple_return}, @code{asm_input},
>> -+ at code{asm_output}, @code{addr_vec}, @code{addr_diff_vec},
>> -+ at code{trap_if}, @code{unspec}, @code{unspec_volatile},
>> -+ at code{parallel}, @code{cond_exec}, or @code{sequence}.  If it is a
>> -+ at code{parallel}, each element of the @code{parallel} must be one these
>> -+codes, except that @code{parallel} expressions cannot be nested and
>> -+ at code{addr_vec} and @code{addr_diff_vec} are not permitted inside a
>> -+ at code{parallel} expression.
>> -
>> - @findex INSN_CODE
>> - @item INSN_CODE (@var{i})
>> -
>> -=== modified file 'gcc/doc/tm.texi'
>> ---- old/gcc/doc/tm.texi        2010-09-01 13:29:58 +0000
>> -+++ new/gcc/doc/tm.texi        2011-01-05 12:12:18 +0000
>> -@@ -3287,6 +3287,12 @@
>> - from the frame pointer of the previous stack frame.
>> - @end defmac
>> -
>> -+ at defmac RETURN_ADDR_REGNUM
>> -+If defined, a C expression whose value is the register number of the
>> return
>> -+address for the current function.  Targets that pass the return address
>> on
>> -+the stack should not define this macro.
>> -+ at end defmac
>> -+
>> - @defmac INCOMING_RETURN_ADDR_RTX
>> - A C expression whose value is RTL representing the location of the
>> - incoming return address at the beginning of any function, before the
>> -
>> -=== modified file 'gcc/dwarf2out.c'
>> ---- old/gcc/dwarf2out.c        2010-12-21 18:46:10 +0000
>> -+++ new/gcc/dwarf2out.c        2011-01-05 12:12:18 +0000
>> -@@ -1396,7 +1396,7 @@
>> -     {
>> -       rtx dest = JUMP_LABEL (insn);
>> -
>> --      if (dest)
>> -+      if (dest && !ANY_RETURN_P (dest))
>> -       {
>> -         if (barrier_args_size [INSN_UID (dest)] < 0)
>> -           {
>> -
>> -=== modified file 'gcc/emit-rtl.c'
>> ---- old/gcc/emit-rtl.c 2010-10-04 00:50:43 +0000
>> -+++ new/gcc/emit-rtl.c 2011-01-05 12:12:18 +0000
>> -@@ -2432,6 +2432,8 @@
>> -     case CODE_LABEL:
>> -     case PC:
>> -     case CC0:
>> -+    case RETURN:
>> -+    case SIMPLE_RETURN:
>> -     case SCRATCH:
>> -       return;
>> -       /* SCRATCH must be shared because they represent distinct values.
>>  */
>> -@@ -3323,14 +3325,17 @@
>> -   return insn;
>> - }
>> -
>> --/* Return the last label to mark the same position as LABEL.  Return
>> null
>> --   if LABEL itself is null.  */
>> -+/* Return the last label to mark the same position as LABEL.  Return
>> LABEL
>> -+   itself if it is null or any return rtx.  */
>> -
>> - rtx
>> - skip_consecutive_labels (rtx label)
>> - {
>> -   rtx insn;
>> -
>> -+  if (label && ANY_RETURN_P (label))
>> -+    return label;
>> -+
>> -   for (insn = label; insn != 0 && !INSN_P (insn); insn = NEXT_INSN
>> (insn))
>> -     if (LABEL_P (insn))
>> -       label = insn;
>> -@@ -5209,7 +5214,7 @@
>> -     return CODE_LABEL;
>> -   if (GET_CODE (x) == CALL)
>> -     return CALL_INSN;
>> --  if (GET_CODE (x) == RETURN)
>> -+  if (GET_CODE (x) == RETURN || GET_CODE (x) == SIMPLE_RETURN)
>> -     return JUMP_INSN;
>> -   if (GET_CODE (x) == SET)
>> -     {
>> -@@ -5715,8 +5720,10 @@
>> -   init_reg_modes_target ();
>> -
>> -   /* Assign register numbers to the globally defined register rtx.  */
>> --  pc_rtx = gen_rtx_PC (VOIDmode);
>> --  cc0_rtx = gen_rtx_CC0 (VOIDmode);
>> -+  pc_rtx = gen_rtx_fmt_ (PC, VOIDmode);
>> -+  ret_rtx = gen_rtx_fmt_ (RETURN, VOIDmode);
>> -+  simple_return_rtx = gen_rtx_fmt_ (SIMPLE_RETURN, VOIDmode);
>> -+  cc0_rtx = gen_rtx_fmt_ (CC0, VOIDmode);
>> -   stack_pointer_rtx = gen_raw_REG (Pmode, STACK_POINTER_REGNUM);
>> -   frame_pointer_rtx = gen_raw_REG (Pmode, FRAME_POINTER_REGNUM);
>> -   hard_frame_pointer_rtx = gen_raw_REG (Pmode,
>> HARD_FRAME_POINTER_REGNUM);
>> -
>> -=== modified file 'gcc/final.c'
>> ---- old/gcc/final.c    2010-03-26 16:18:51 +0000
>> -+++ new/gcc/final.c    2011-01-05 12:12:18 +0000
>> -@@ -2428,7 +2428,7 @@
>> -               delete_insn (insn);
>> -               break;
>> -             }
>> --          else if (GET_CODE (SET_SRC (body)) == RETURN)
>> -+          else if (ANY_RETURN_P (SET_SRC (body)))
>> -             /* Replace (set (pc) (return)) with (return).  */
>> -             PATTERN (insn) = body = SET_SRC (body);
>> -
>> -
>> -=== modified file 'gcc/function.c'
>> ---- old/gcc/function.c 2010-08-16 19:18:08 +0000
>> -+++ new/gcc/function.c 2011-01-05 12:12:18 +0000
>> -@@ -147,9 +147,6 @@
>> -    can always export `prologue_epilogue_contains'.  */
>> - static void record_insns (rtx, rtx, htab_t *) ATTRIBUTE_UNUSED;
>> - static bool contains (const_rtx, htab_t);
>> --#ifdef HAVE_return
>> --static void emit_return_into_block (basic_block);
>> --#endif
>> - static void prepare_function_start (void);
>> - static void do_clobber_return_reg (rtx, void *);
>> - static void do_use_return_reg (rtx, void *);
>> -@@ -4987,35 +4984,189 @@
>> -   return 0;
>> - }
>> -
>> -+#ifdef HAVE_simple_return
>> -+/* This collects sets and clobbers of hard registers in a HARD_REG_SET,
>> -+   which is pointed to by DATA.  */
>> -+static void
>> -+record_hard_reg_sets (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data)
>> -+{
>> -+  HARD_REG_SET *pset = (HARD_REG_SET *)data;
>> -+  if (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER)
>> -+    {
>> -+      int nregs = hard_regno_nregs[REGNO (x)][GET_MODE (x)];
>> -+      while (nregs-- > 0)
>> -+      SET_HARD_REG_BIT (*pset, REGNO (x) + nregs);
>> -+    }
>> -+}
>> -+
>> -+/* A subroutine of requires_stack_frame_p, called via for_each_rtx.
>> -+   If any change is made, set CHANGED
>> -+   to true.  */
>> -+
>> -+static int
>> -+frame_required_for_rtx (rtx *loc, void *data ATTRIBUTE_UNUSED)
>> -+{
>> -+  rtx x = *loc;
>> -+  if (x == stack_pointer_rtx || x == hard_frame_pointer_rtx
>> -+      || x == arg_pointer_rtx || x == pic_offset_table_rtx
>> -+#ifdef RETURN_ADDR_REGNUM
>> -+      || (REG_P (x) && REGNO (x) == RETURN_ADDR_REGNUM)
>> -+#endif
>> -+      )
>> -+    return 1;
>> -+  return 0;
>> -+}
>> -+
>> -+static bool
>> -+requires_stack_frame_p (rtx insn)
>> -+{
>> -+  HARD_REG_SET hardregs;
>> -+  unsigned regno;
>> -+
>> -+  if (!INSN_P (insn) || DEBUG_INSN_P (insn))
>> -+    return false;
>> -+  if (CALL_P (insn))
>> -+    return !SIBLING_CALL_P (insn);
>> -+  if (for_each_rtx (&PATTERN (insn), frame_required_for_rtx, NULL))
>> -+    return true;
>> -+  CLEAR_HARD_REG_SET (hardregs);
>> -+  note_stores (PATTERN (insn), record_hard_reg_sets, &hardregs);
>> -+  AND_COMPL_HARD_REG_SET (hardregs, call_used_reg_set);
>> -+  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
>> -+    if (TEST_HARD_REG_BIT (hardregs, regno)
>> -+      && df_regs_ever_live_p (regno))
>> -+      return true;
>> -+  return false;
>> -+}
>> -+#endif
>> -+
>> - #ifdef HAVE_return
>> --/* Insert gen_return at the end of block BB.  This also means updating
>> --   block_for_insn appropriately.  */
>> -+
>> -+static rtx
>> -+gen_return_pattern (bool simple_p)
>> -+{
>> -+#ifdef HAVE_simple_return
>> -+  return simple_p ? gen_simple_return () : gen_return ();
>> -+#else
>> -+  gcc_assert (!simple_p);
>> -+  return gen_return ();
>> -+#endif
>> -+}
>> -+
>> -+/* Insert an appropriate return pattern at the end of block BB.  This
>> -+   also means updating block_for_insn appropriately.  */
>> -
>> - static void
>> --emit_return_into_block (basic_block bb)
>> -+emit_return_into_block (bool simple_p, basic_block bb)
>> - {
>> --  emit_jump_insn_after (gen_return (), BB_END (bb));
>> -+  rtx jump;
>> -+  jump = emit_jump_insn_after (gen_return_pattern (simple_p), BB_END
>> (bb));
>> -+  JUMP_LABEL (jump) = simple_p ? simple_return_rtx : ret_rtx;
>> - }
>> --#endif /* HAVE_return */
>> -+#endif
>> -
>> - /* Generate the prologue and epilogue RTL if the machine supports it.
>>  Thread
>> -    this into place with notes indicating where the prologue ends and
>> where
>> --   the epilogue begins.  Update the basic block information when
>> possible.  */
>> -+   the epilogue begins.  Update the basic block information when
>> possible.
>> -+
>> -+   Notes on epilogue placement:
>> -+   There are several kinds of edges to the exit block:
>> -+   * a single fallthru edge from LAST_BB
>> -+   * possibly, edges from blocks containing sibcalls
>> -+   * possibly, fake edges from infinite loops
>> -+
>> -+   The epilogue is always emitted on the fallthru edge from the last
>> basic
>> -+   block in the function, LAST_BB, into the exit block.
>> -+
>> -+   If LAST_BB is empty except for a label, it is the target of every
>> -+   other basic block in the function that ends in a return.  If a
>> -+   target has a return or simple_return pattern (possibly with
>> -+   conditional variants), these basic blocks can be changed so that a
>> -+   return insn is emitted into them, and their target is adjusted to
>> -+   the real exit block.
>> -+
>> -+   Notes on shrink wrapping: We implement a fairly conservative
>> -+   version of shrink-wrapping rather than the textbook one.  We only
>> -+   generate a single prologue and a single epilogue.  This is
>> -+   sufficient to catch a number of interesting cases involving early
>> -+   exits.
>> -+
>> -+   First, we identify the blocks that require the prologue to occur
>> before
>> -+   them.  These are the ones that modify a call-saved register, or
>> reference
>> -+   any of the stack or frame pointer registers.  To simplify things, we
>> then
>> -+   mark everything reachable from these blocks as also requiring a
>> prologue.
>> -+   This takes care of loops automatically, and avoids the need to
>> examine
>> -+   whether MEMs reference the frame, since it is sufficient to check for
>> -+   occurrences of the stack or frame pointer.
>> -+
>> -+   We then compute the set of blocks for which the need for a prologue
>> -+   is anticipatable (borrowing terminology from the shrink-wrapping
>> -+   description in Muchnick's book).  These are the blocks which either
>> -+   require a prologue themselves, or those that have only successors
>> -+   where the prologue is anticipatable.  The prologue needs to be
>> -+   inserted on all edges from BB1->BB2 where BB2 is in ANTIC and BB1
>> -+   is not.  For the moment, we ensure that only one such edge exists.
>> -+
>> -+   The epilogue is placed as described above, but we make a
>> -+   distinction between inserting return and simple_return patterns
>> -+   when modifying other blocks that end in a return.  Blocks that end
>> -+   in a sibcall omit the sibcall_epilogue if the block is not in
>> -+   ANTIC.  */
>> -
>> - static void
>> - thread_prologue_and_epilogue_insns (void)
>> - {
>> -   int inserted = 0;
>> -+  basic_block last_bb;
>> -+  bool last_bb_active;
>> -+#ifdef HAVE_simple_return
>> -+  bool unconverted_simple_returns = false;
>> -+  basic_block simple_return_block = NULL;
>> -+#endif
>> -+  rtx returnjump ATTRIBUTE_UNUSED;
>> -+  rtx seq ATTRIBUTE_UNUSED, epilogue_end ATTRIBUTE_UNUSED;
>> -+  rtx prologue_seq ATTRIBUTE_UNUSED, split_prologue_seq
>> ATTRIBUTE_UNUSED;
>> -+  edge entry_edge, orig_entry_edge, exit_fallthru_edge;
>> -   edge e;
>> --#if defined (HAVE_sibcall_epilogue) || defined (HAVE_epilogue) ||
>> defined (HAVE_return) || defined (HAVE_prologue)
>> --  rtx seq;
>> --#endif
>> --#if defined (HAVE_epilogue) || defined(HAVE_return)
>> --  rtx epilogue_end = NULL_RTX;
>> --#endif
>> -   edge_iterator ei;
>> -+  bitmap_head bb_flags;
>> -+
>> -+  df_analyze ();
>> -
>> -   rtl_profile_for_bb (ENTRY_BLOCK_PTR);
>> -+
>> -+  epilogue_end = NULL_RTX;
>> -+
>> -+  /* Can't deal with multiple successors of the entry block at the
>> -+     moment.  Function should always have at least one entry
>> -+     point.  */
>> -+  gcc_assert (single_succ_p (ENTRY_BLOCK_PTR));
>> -+  entry_edge = single_succ_edge (ENTRY_BLOCK_PTR);
>> -+  orig_entry_edge = entry_edge;
>> -+
>> -+  exit_fallthru_edge = find_fallthru_edge (EXIT_BLOCK_PTR->preds);
>> -+  if (exit_fallthru_edge != NULL)
>> -+    {
>> -+      rtx label;
>> -+
>> -+      last_bb = exit_fallthru_edge->src;
>> -+      /* Test whether there are active instructions in the last block.
>>  */
>> -+      label = BB_END (last_bb);
>> -+      while (label && !LABEL_P (label))
>> -+      {
>> -+        if (active_insn_p (label))
>> -+          break;
>> -+        label = PREV_INSN (label);
>> -+      }
>> -+
>> -+      last_bb_active = BB_HEAD (last_bb) != label || !LABEL_P (label);
>> -+    }
>> -+  else
>> -+    {
>> -+      last_bb = NULL;
>> -+      last_bb_active = false;
>> -+    }
>> -+
>> - #ifdef HAVE_prologue
>> -   if (HAVE_prologue)
>> -     {
>> -@@ -5040,19 +5191,168 @@
>> -         emit_insn (gen_blockage ());
>> - #endif
>> -
>> --      seq = get_insns ();
>> -+      prologue_seq = get_insns ();
>> -       end_sequence ();
>> -       set_insn_locators (seq, prologue_locator);
>> --
>> --      /* Can't deal with multiple successors of the entry block
>> --         at the moment.  Function should always have at least one
>> --         entry point.  */
>> --      gcc_assert (single_succ_p (ENTRY_BLOCK_PTR));
>> --
>> --      insert_insn_on_edge (seq, single_succ_edge (ENTRY_BLOCK_PTR));
>> --      inserted = 1;
>> --    }
>> --#endif
>> -+    }
>> -+#endif
>> -+
>> -+  bitmap_initialize (&bb_flags, &bitmap_default_obstack);
>> -+
>> -+#ifdef HAVE_simple_return
>> -+  /* Try to perform a kind of shrink-wrapping, making sure the
>> -+     prologue/epilogue is emitted only around those parts of the
>> -+     function that require it.  */
>> -+
>> -+  if (flag_shrink_wrap && HAVE_simple_return &&
>> !flag_non_call_exceptions
>> -+      && HAVE_prologue && !crtl->calls_eh_return)
>> -+    {
>> -+      HARD_REG_SET prologue_clobbered, live_on_edge;
>> -+      rtx p_insn;
>> -+      VEC(basic_block, heap) *vec;
>> -+      basic_block bb;
>> -+      bitmap_head bb_antic_flags;
>> -+      bitmap_head bb_on_list;
>> -+
>> -+      bitmap_initialize (&bb_antic_flags, &bitmap_default_obstack);
>> -+      bitmap_initialize (&bb_on_list, &bitmap_default_obstack);
>> -+
>> -+      vec = VEC_alloc (basic_block, heap, n_basic_blocks);
>> -+
>> -+      FOR_EACH_BB (bb)
>> -+      {
>> -+        rtx insn;
>> -+        FOR_BB_INSNS (bb, insn)
>> -+          {
>> -+            if (requires_stack_frame_p (insn))
>> -+              {
>> -+                bitmap_set_bit (&bb_flags, bb->index);
>> -+                VEC_quick_push (basic_block, vec, bb);
>> -+                break;
>> -+              }
>> -+          }
>> -+      }
>> -+
>> -+      /* For every basic block that needs a prologue, mark all blocks
>> -+       reachable from it, so as to ensure they are also seen as
>> -+       requiring a prologue.  */
>> -+      while (!VEC_empty (basic_block, vec))
>> -+      {
>> -+        basic_block tmp_bb = VEC_pop (basic_block, vec);
>> -+        edge e;
>> -+        edge_iterator ei;
>> -+        FOR_EACH_EDGE (e, ei, tmp_bb->succs)
>> -+          {
>> -+            if (e->dest == EXIT_BLOCK_PTR
>> -+                || bitmap_bit_p (&bb_flags, e->dest->index))
>> -+              continue;
>> -+            bitmap_set_bit (&bb_flags, e->dest->index);
>> -+            VEC_quick_push (basic_block, vec, e->dest);
>> -+          }
>> -+      }
>> -+      /* If the last basic block contains only a label, we'll be able
>> -+       to convert jumps to it to (potentially conditional) return
>> -+       insns later.  This means we don't necessarily need a prologue
>> -+       for paths reaching it.  */
>> -+      if (last_bb)
>> -+      {
>> -+        if (!last_bb_active)
>> -+          bitmap_clear_bit (&bb_flags, last_bb->index);
>> -+        else if (!bitmap_bit_p (&bb_flags, last_bb->index))
>> -+          goto fail_shrinkwrap;
>> -+      }
>> -+
>> -+      /* Now walk backwards from every block that is marked as needing
>> -+       a prologue to compute the bb_antic_flags bitmap.  */
>> -+      bitmap_copy (&bb_antic_flags, &bb_flags);
>> -+      FOR_EACH_BB (bb)
>> -+      {
>> -+        edge e;
>> -+        edge_iterator ei;
>> -+        if (!bitmap_bit_p (&bb_flags, bb->index))
>> -+          continue;
>> -+        FOR_EACH_EDGE (e, ei, bb->preds)
>> -+          if (!bitmap_bit_p (&bb_antic_flags, e->src->index))
>> -+            {
>> -+              VEC_quick_push (basic_block, vec, e->src);
>> -+              bitmap_set_bit (&bb_on_list, e->src->index);
>> -+            }
>> -+      }
>> -+      while (!VEC_empty (basic_block, vec))
>> -+      {
>> -+        basic_block tmp_bb = VEC_pop (basic_block, vec);
>> -+        edge e;
>> -+        edge_iterator ei;
>> -+        bool all_set = true;
>> -+
>> -+        bitmap_clear_bit (&bb_on_list, tmp_bb->index);
>> -+        FOR_EACH_EDGE (e, ei, tmp_bb->succs)
>> -+          {
>> -+            if (!bitmap_bit_p (&bb_antic_flags, e->dest->index))
>> -+              {
>> -+                all_set = false;
>> -+                break;
>> -+              }
>> -+          }
>> -+        if (all_set)
>> -+          {
>> -+            bitmap_set_bit (&bb_antic_flags, tmp_bb->index);
>> -+            FOR_EACH_EDGE (e, ei, tmp_bb->preds)
>> -+              if (!bitmap_bit_p (&bb_antic_flags, e->src->index))
>> -+                {
>> -+                  VEC_quick_push (basic_block, vec, e->src);
>> -+                  bitmap_set_bit (&bb_on_list, e->src->index);
>> -+                }
>> -+          }
>> -+      }
>> -+      /* Find exactly one edge that leads to a block in ANTIC from
>> -+       a block that isn't.  */
>> -+      if (!bitmap_bit_p (&bb_antic_flags, entry_edge->dest->index))
>> -+      FOR_EACH_BB (bb)
>> -+        {
>> -+          if (!bitmap_bit_p (&bb_antic_flags, bb->index))
>> -+            continue;
>> -+          FOR_EACH_EDGE (e, ei, bb->preds)
>> -+            if (!bitmap_bit_p (&bb_antic_flags, e->src->index))
>> -+              {
>> -+                if (entry_edge != orig_entry_edge)
>> -+                  {
>> -+                    entry_edge = orig_entry_edge;
>> -+                    goto fail_shrinkwrap;
>> -+                  }
>> -+                entry_edge = e;
>> -+              }
>> -+        }
>> -+
>> -+      /* Test whether the prologue is known to clobber any register
>> -+       (other than FP or SP) which are live on the edge.  */
>> -+      CLEAR_HARD_REG_SET (prologue_clobbered);
>> -+      for (p_insn = prologue_seq; p_insn; p_insn = NEXT_INSN (p_insn))
>> -+      if (NONDEBUG_INSN_P (p_insn))
>> -+        note_stores (PATTERN (p_insn), record_hard_reg_sets,
>> -+                     &prologue_clobbered);
>> -+      CLEAR_HARD_REG_BIT (prologue_clobbered, STACK_POINTER_REGNUM);
>> -+      if (frame_pointer_needed)
>> -+      CLEAR_HARD_REG_BIT (prologue_clobbered,
>> HARD_FRAME_POINTER_REGNUM);
>> -+
>> -+      CLEAR_HARD_REG_SET (live_on_edge);
>> -+      reg_set_to_hard_reg_set (&live_on_edge,
>> -+                             df_get_live_in (entry_edge->dest));
>> -+      if (hard_reg_set_intersect_p (live_on_edge, prologue_clobbered))
>> -+      entry_edge = orig_entry_edge;
>> -+
>> -+    fail_shrinkwrap:
>> -+      bitmap_clear (&bb_antic_flags);
>> -+      bitmap_clear (&bb_on_list);
>> -+      VEC_free (basic_block, heap, vec);
>> -+    }
>> -+#endif
>> -+
>> -+  if (prologue_seq != NULL_RTX)
>> -+    {
>> -+      insert_insn_on_edge (prologue_seq, entry_edge);
>> -+      inserted = true;
>> -+    }
>> -
>> -   /* If the exit block has no non-fake predecessors, we don't need
>> -      an epilogue.  */
>> -@@ -5063,100 +5363,130 @@
>> -     goto epilogue_done;
>> -
>> -   rtl_profile_for_bb (EXIT_BLOCK_PTR);
>> -+
>> - #ifdef HAVE_return
>> --  if (optimize && HAVE_return)
>> -+  /* If we're allowed to generate a simple return instruction, then by
>> -+     definition we don't need a full epilogue.  If the last basic
>> -+     block before the exit block does not contain active instructions,
>> -+     examine its predecessors and try to emit (conditional) return
>> -+     instructions.  */
>> -+  if (optimize && !last_bb_active
>> -+      && (HAVE_return || entry_edge != orig_entry_edge))
>> -     {
>> --      /* If we're allowed to generate a simple return instruction,
>> --       then by definition we don't need a full epilogue.  Examine
>> --       the block that falls through to EXIT.   If it does not
>> --       contain any code, examine its predecessors and try to
>> --       emit (conditional) return instructions.  */
>> --
>> --      basic_block last;
>> -+      edge_iterator ei2;
>> -+      int i;
>> -+      basic_block bb;
>> -       rtx label;
>> -+      VEC(basic_block,heap) *src_bbs;
>> -
>> --      FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
>> --      if (e->flags & EDGE_FALLTHRU)
>> --        break;
>> --      if (e == NULL)
>> -+      if (exit_fallthru_edge == NULL)
>> -       goto epilogue_done;
>> --      last = e->src;
>> --
>> --      /* Verify that there are no active instructions in the last block.
>>  */
>> --      label = BB_END (last);
>> --      while (label && !LABEL_P (label))
>> -+      label = BB_HEAD (last_bb);
>> -+
>> -+      src_bbs = VEC_alloc (basic_block, heap, EDGE_COUNT
>> (last_bb->preds));
>> -+      FOR_EACH_EDGE (e, ei2, last_bb->preds)
>> -+      if (e->src != ENTRY_BLOCK_PTR)
>> -+        VEC_quick_push (basic_block, src_bbs, e->src);
>> -+
>> -+      FOR_EACH_VEC_ELT (basic_block, src_bbs, i, bb)
>> -       {
>> --        if (active_insn_p (label))
>> --          break;
>> --        label = PREV_INSN (label);
>> -+        bool simple_p;
>> -+        rtx jump;
>> -+        e = find_edge (bb, last_bb);
>> -+
>> -+        jump = BB_END (bb);
>> -+
>> -+#ifdef HAVE_simple_return
>> -+        simple_p = (entry_edge != orig_entry_edge
>> -+                    ? !bitmap_bit_p (&bb_flags, bb->index) : false);
>> -+#else
>> -+        simple_p = false;
>> -+#endif
>> -+
>> -+        if (!simple_p
>> -+            && (!HAVE_return || !JUMP_P (jump)
>> -+                || JUMP_LABEL (jump) != label))
>> -+          continue;
>> -+
>> -+        /* If we have an unconditional jump, we can replace that
>> -+           with a simple return instruction.  */
>> -+        if (!JUMP_P (jump))
>> -+          {
>> -+            emit_barrier_after (BB_END (bb));
>> -+            emit_return_into_block (simple_p, bb);
>> -+          }
>> -+        else if (simplejump_p (jump))
>> -+          {
>> -+            emit_return_into_block (simple_p, bb);
>> -+            delete_insn (jump);
>> -+          }
>> -+        else if (condjump_p (jump) && JUMP_LABEL (jump) != label)
>> -+          {
>> -+            basic_block new_bb;
>> -+            edge new_e;
>> -+
>> -+            gcc_assert (simple_p);
>> -+            new_bb = split_edge (e);
>> -+            emit_barrier_after (BB_END (new_bb));
>> -+            emit_return_into_block (simple_p, new_bb);
>> -+#ifdef HAVE_simple_return
>> -+            simple_return_block = new_bb;
>> -+#endif
>> -+            new_e = single_succ_edge (new_bb);
>> -+            redirect_edge_succ (new_e, EXIT_BLOCK_PTR);
>> -+
>> -+            continue;
>> -+          }
>> -+        /* If we have a conditional jump branching to the last
>> -+           block, we can try to replace that with a conditional
>> -+           return instruction.  */
>> -+        else if (condjump_p (jump))
>> -+          {
>> -+            rtx dest;
>> -+            if (simple_p)
>> -+              dest = simple_return_rtx;
>> -+            else
>> -+              dest = ret_rtx;
>> -+            if (! redirect_jump (jump, dest, 0))
>> -+              {
>> -+#ifdef HAVE_simple_return
>> -+                if (simple_p)
>> -+                  unconverted_simple_returns = true;
>> -+#endif
>> -+                continue;
>> -+              }
>> -+
>> -+            /* If this block has only one successor, it both jumps
>> -+               and falls through to the fallthru block, so we can't
>> -+               delete the edge.  */
>> -+            if (single_succ_p (bb))
>> -+              continue;
>> -+          }
>> -+        else
>> -+          {
>> -+#ifdef HAVE_simple_return
>> -+            if (simple_p)
>> -+              unconverted_simple_returns = true;
>> -+#endif
>> -+            continue;
>> -+          }
>> -+
>> -+        /* Fix up the CFG for the successful change we just made.  */
>> -+        redirect_edge_succ (e, EXIT_BLOCK_PTR);
>> -       }
>> -+      VEC_free (basic_block, heap, src_bbs);
>> -
>> --      if (BB_HEAD (last) == label && LABEL_P (label))
>> -+      if (HAVE_return)
>> -       {
>> --        edge_iterator ei2;
>> --
>> --        for (ei2 = ei_start (last->preds); (e = ei_safe_edge (ei2)); )
>> --          {
>> --            basic_block bb = e->src;
>> --            rtx jump;
>> --
>> --            if (bb == ENTRY_BLOCK_PTR)
>> --              {
>> --                ei_next (&ei2);
>> --                continue;
>> --              }
>> --
>> --            jump = BB_END (bb);
>> --            if (!JUMP_P (jump) || JUMP_LABEL (jump) != label)
>> --              {
>> --                ei_next (&ei2);
>> --                continue;
>> --              }
>> --
>> --            /* If we have an unconditional jump, we can replace that
>> --               with a simple return instruction.  */
>> --            if (simplejump_p (jump))
>> --              {
>> --                emit_return_into_block (bb);
>> --                delete_insn (jump);
>> --              }
>> --
>> --            /* If we have a conditional jump, we can try to replace
>> --               that with a conditional return instruction.  */
>> --            else if (condjump_p (jump))
>> --              {
>> --                if (! redirect_jump (jump, 0, 0))
>> --                  {
>> --                    ei_next (&ei2);
>> --                    continue;
>> --                  }
>> --
>> --                /* If this block has only one successor, it both jumps
>> --                   and falls through to the fallthru block, so we can't
>> --                   delete the edge.  */
>> --                if (single_succ_p (bb))
>> --                  {
>> --                    ei_next (&ei2);
>> --                    continue;
>> --                  }
>> --              }
>> --            else
>> --              {
>> --                ei_next (&ei2);
>> --                continue;
>> --              }
>> --
>> --            /* Fix up the CFG for the successful change we just made.
>>  */
>> --            redirect_edge_succ (e, EXIT_BLOCK_PTR);
>> --          }
>> --
>> -         /* Emit a return insn for the exit fallthru block.  Whether
>> -            this is still reachable will be determined later.  */
>> -
>> --        emit_barrier_after (BB_END (last));
>> --        emit_return_into_block (last);
>> --        epilogue_end = BB_END (last);
>> --        single_succ_edge (last)->flags &= ~EDGE_FALLTHRU;
>> -+        emit_barrier_after (BB_END (last_bb));
>> -+        emit_return_into_block (false, last_bb);
>> -+        epilogue_end = BB_END (last_bb);
>> -+        if (JUMP_P (epilogue_end))
>> -+          JUMP_LABEL (epilogue_end) = ret_rtx;
>> -+        single_succ_edge (last_bb)->flags &= ~EDGE_FALLTHRU;
>> -         goto epilogue_done;
>> -       }
>> -     }
>> -@@ -5193,15 +5523,10 @@
>> -     }
>> - #endif
>> -
>> --  /* Find the edge that falls through to EXIT.  Other edges may exist
>> --     due to RETURN instructions, but those don't need epilogues.
>> --     There really shouldn't be a mixture -- either all should have
>> --     been converted or none, however...  */
>> -+  /* If nothing falls through into the exit block, we don't need an
>> -+     epilogue.  */
>> -
>> --  FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
>> --    if (e->flags & EDGE_FALLTHRU)
>> --      break;
>> --  if (e == NULL)
>> -+  if (exit_fallthru_edge == NULL)
>> -     goto epilogue_done;
>> -
>> - #ifdef HAVE_epilogue
>> -@@ -5217,25 +5542,38 @@
>> -       set_insn_locators (seq, epilogue_locator);
>> -
>> -       seq = get_insns ();
>> -+      returnjump = get_last_insn ();
>> -       end_sequence ();
>> -
>> --      insert_insn_on_edge (seq, e);
>> -+      insert_insn_on_edge (seq, exit_fallthru_edge);
>> -       inserted = 1;
>> -+      if (JUMP_P (returnjump))
>> -+      {
>> -+        rtx pat = PATTERN (returnjump);
>> -+        if (GET_CODE (pat) == PARALLEL)
>> -+          pat = XVECEXP (pat, 0, 0);
>> -+        if (ANY_RETURN_P (pat))
>> -+          JUMP_LABEL (returnjump) = pat;
>> -+        else
>> -+          JUMP_LABEL (returnjump) = ret_rtx;
>> -+      }
>> -+      else
>> -+      returnjump = NULL_RTX;
>> -     }
>> -   else
>> - #endif
>> -     {
>> -       basic_block cur_bb;
>> -
>> --      if (! next_active_insn (BB_END (e->src)))
>> -+      if (! next_active_insn (BB_END (exit_fallthru_edge->src)))
>> -       goto epilogue_done;
>> -       /* We have a fall-through edge to the exit block, the source is
>> not
>> --         at the end of the function, and there will be an assembler
>> epilogue
>> --         at the end of the function.
>> --         We can't use force_nonfallthru here, because that would try to
>> --         use return.  Inserting a jump 'by hand' is extremely messy, so
>> -+       at the end of the function, and there will be an assembler
>> epilogue
>> -+       at the end of the function.
>> -+       We can't use force_nonfallthru here, because that would try to
>> -+       use return.  Inserting a jump 'by hand' is extremely messy, so
>> -        we take advantage of cfg_layout_finalize using
>> --      fixup_fallthru_exit_predecessor.  */
>> -+       fixup_fallthru_exit_predecessor.  */
>> -       cfg_layout_initialize (0);
>> -       FOR_EACH_BB (cur_bb)
>> -       if (cur_bb->index >= NUM_FIXED_BLOCKS
>> -@@ -5244,6 +5582,7 @@
>> -       cfg_layout_finalize ();
>> -     }
>> - epilogue_done:
>> -+
>> -   default_rtl_profile ();
>> -
>> -   if (inserted)
>> -@@ -5260,33 +5599,93 @@
>> -       }
>> -     }
>> -
>> -+#ifdef HAVE_simple_return
>> -+  /* If there were branches to an empty LAST_BB which we tried to
>> -+     convert to conditional simple_returns, but couldn't for some
>> -+     reason, create a block to hold a simple_return insn and redirect
>> -+     those remaining edges.  */
>> -+  if (unconverted_simple_returns)
>> -+    {
>> -+      edge_iterator ei2;
>> -+      basic_block exit_pred = EXIT_BLOCK_PTR->prev_bb;
>> -+
>> -+      gcc_assert (entry_edge != orig_entry_edge);
>> -+
>> -+#ifdef HAVE_epilogue
>> -+      if (simple_return_block == NULL && returnjump != NULL_RTX
>> -+        && JUMP_LABEL (returnjump) == simple_return_rtx)
>> -+      {
>> -+        edge e = split_block (exit_fallthru_edge->src,
>> -+                              PREV_INSN (returnjump));
>> -+        simple_return_block = e->dest;
>> -+      }
>> -+#endif
>> -+      if (simple_return_block == NULL)
>> -+      {
>> -+        basic_block bb;
>> -+        rtx start;
>> -+
>> -+        bb = create_basic_block (NULL, NULL, exit_pred);
>> -+        start = emit_jump_insn_after (gen_simple_return (),
>> -+                                      BB_END (bb));
>> -+        JUMP_LABEL (start) = simple_return_rtx;
>> -+        emit_barrier_after (start);
>> -+
>> -+        simple_return_block = bb;
>> -+        make_edge (bb, EXIT_BLOCK_PTR, 0);
>> -+      }
>> -+
>> -+    restart_scan:
>> -+      for (ei2 = ei_start (last_bb->preds); (e = ei_safe_edge (ei2)); )
>> -+      {
>> -+        basic_block bb = e->src;
>> -+
>> -+        if (bb != ENTRY_BLOCK_PTR
>> -+            && !bitmap_bit_p (&bb_flags, bb->index))
>> -+          {
>> -+            redirect_edge_and_branch_force (e, simple_return_block);
>> -+            goto restart_scan;
>> -+          }
>> -+        ei_next (&ei2);
>> -+
>> -+      }
>> -+    }
>> -+#endif
>> -+
>> - #ifdef HAVE_sibcall_epilogue
>> -   /* Emit sibling epilogues before any sibling call sites.  */
>> -   for (ei = ei_start (EXIT_BLOCK_PTR->preds); (e = ei_safe_edge (ei)); )
>> -     {
>> -       basic_block bb = e->src;
>> -       rtx insn = BB_END (bb);
>> -+      rtx ep_seq;
>> -
>> -       if (!CALL_P (insn)
>> --        || ! SIBLING_CALL_P (insn))
>> -+        || ! SIBLING_CALL_P (insn)
>> -+        || (entry_edge != orig_entry_edge
>> -+            && !bitmap_bit_p (&bb_flags, bb->index)))
>> -       {
>> -         ei_next (&ei);
>> -         continue;
>> -       }
>> -
>> --      start_sequence ();
>> --      emit_note (NOTE_INSN_EPILOGUE_BEG);
>> --      emit_insn (gen_sibcall_epilogue ());
>> --      seq = get_insns ();
>> --      end_sequence ();
>> --
>> --      /* Retain a map of the epilogue insns.  Used in life analysis to
>> --       avoid getting rid of sibcall epilogue insns.  Do this before we
>> --       actually emit the sequence.  */
>> --      record_insns (seq, NULL, &epilogue_insn_hash);
>> --      set_insn_locators (seq, epilogue_locator);
>> --
>> --      emit_insn_before (seq, insn);
>> -+      ep_seq = gen_sibcall_epilogue ();
>> -+      if (ep_seq)
>> -+      {
>> -+        start_sequence ();
>> -+        emit_note (NOTE_INSN_EPILOGUE_BEG);
>> -+        emit_insn (ep_seq);
>> -+        seq = get_insns ();
>> -+        end_sequence ();
>> -+
>> -+        /* Retain a map of the epilogue insns.  Used in life analysis to
>> -+           avoid getting rid of sibcall epilogue insns.  Do this before
>> we
>> -+           actually emit the sequence.  */
>> -+        record_insns (seq, NULL, &epilogue_insn_hash);
>> -+        set_insn_locators (seq, epilogue_locator);
>> -+
>> -+        emit_insn_before (seq, insn);
>> -+      }
>> -       ei_next (&ei);
>> -     }
>> - #endif
>> -@@ -5311,6 +5710,8 @@
>> -     }
>> - #endif
>> -
>> -+  bitmap_clear (&bb_flags);
>> -+
>> -   /* Threading the prologue and epilogue changes the artificial refs
>> -      in the entry and exit blocks.  */
>> -   epilogue_completed = 1;
>> -
>> -=== modified file 'gcc/genemit.c'
>> ---- old/gcc/genemit.c  2009-11-27 11:37:06 +0000
>> -+++ new/gcc/genemit.c  2011-01-05 12:12:18 +0000
>> -@@ -222,6 +222,12 @@
>> -     case PC:
>> -       printf ("pc_rtx");
>> -       return;
>> -+    case RETURN:
>> -+      printf ("ret_rtx");
>> -+      return;
>> -+    case SIMPLE_RETURN:
>> -+      printf ("simple_return_rtx");
>> -+      return;
>> -     case CLOBBER:
>> -       if (REG_P (XEXP (x, 0)))
>> -       {
>> -@@ -544,8 +550,8 @@
>> -         || (GET_CODE (next) == PARALLEL
>> -             && ((GET_CODE (XVECEXP (next, 0, 0)) == SET
>> -                  && GET_CODE (SET_DEST (XVECEXP (next, 0, 0))) == PC)
>> --                || GET_CODE (XVECEXP (next, 0, 0)) == RETURN))
>> --        || GET_CODE (next) == RETURN)
>> -+                || ANY_RETURN_P (XVECEXP (next, 0, 0))))
>> -+        || ANY_RETURN_P (next))
>> -       printf ("  emit_jump_insn (");
>> -       else if ((GET_CODE (next) == SET && GET_CODE (SET_SRC (next)) ==
>> CALL)
>> -              || GET_CODE (next) == CALL
>> -@@ -660,7 +666,7 @@
>> -         || (GET_CODE (next) == PARALLEL
>> -             && GET_CODE (XVECEXP (next, 0, 0)) == SET
>> -             && GET_CODE (SET_DEST (XVECEXP (next, 0, 0))) == PC)
>> --        || GET_CODE (next) == RETURN)
>> -+        || ANY_RETURN_P (next))
>> -       printf ("  emit_jump_insn (");
>> -       else if ((GET_CODE (next) == SET && GET_CODE (SET_SRC (next)) ==
>> CALL)
>> -              || GET_CODE (next) == CALL
>> -
>> -=== modified file 'gcc/gengenrtl.c'
>> ---- old/gcc/gengenrtl.c        2007-08-22 23:30:39 +0000
>> -+++ new/gcc/gengenrtl.c        2011-01-05 12:12:18 +0000
>> -@@ -146,6 +146,10 @@
>> -         || strcmp (defs[idx].enumname, "REG") == 0
>> -         || strcmp (defs[idx].enumname, "SUBREG") == 0
>> -         || strcmp (defs[idx].enumname, "MEM") == 0
>> -+        || strcmp (defs[idx].enumname, "PC") == 0
>> -+        || strcmp (defs[idx].enumname, "CC0") == 0
>> -+        || strcmp (defs[idx].enumname, "RETURN") == 0
>> -+        || strcmp (defs[idx].enumname, "SIMPLE_RETURN") == 0
>> -         || strcmp (defs[idx].enumname, "CONST_VECTOR") == 0);
>> - }
>> -
>> -
>> -=== modified file 'gcc/haifa-sched.c'
>> ---- old/gcc/haifa-sched.c      2010-08-12 08:14:47 +0000
>> -+++ new/gcc/haifa-sched.c      2011-01-05 12:12:18 +0000
>> -@@ -4231,7 +4231,7 @@
>> - /* Helper function.
>> -    Find fallthru edge from PRED.  */
>> - edge
>> --find_fallthru_edge (basic_block pred)
>> -+find_fallthru_edge_from (basic_block pred)
>> - {
>> -   edge e;
>> -   edge_iterator ei;
>> -@@ -4298,7 +4298,7 @@
>> -   edge e;
>> -
>> -   last = EXIT_BLOCK_PTR->prev_bb;
>> --  e = find_fallthru_edge (last);
>> -+  e = find_fallthru_edge_from (last);
>> -
>> -   if (e)
>> -     {
>> -@@ -5234,6 +5234,11 @@
>> -                   gcc_assert (/* Usual case.  */
>> -                                 (EDGE_COUNT (bb->succs) > 1
>> -                                  && !BARRIER_P (NEXT_INSN (head)))
>> -+                              /* Special cases, see cfglayout.c:
>> -+                                 fixup_reorder_chain.  */
>> -+                              || (EDGE_COUNT (bb->succs) == 1
>> -+                                  && (!onlyjump_p (head)
>> -+                                      || returnjump_p (head)))
>> -                                 /* Or jump to the next instruction.  */
>> -                                 || (EDGE_COUNT (bb->succs) == 1
>> -                                     && (BB_HEAD (EDGE_I (bb->succs,
>> 0)->dest)
>> -
>> -=== modified file 'gcc/ifcvt.c'
>> ---- old/gcc/ifcvt.c    2010-11-26 12:03:32 +0000
>> -+++ new/gcc/ifcvt.c    2011-01-05 12:12:18 +0000
>> -@@ -105,7 +105,7 @@
>> - static int find_if_case_2 (basic_block, edge, edge);
>> - static int find_memory (rtx *, void *);
>> - static int dead_or_predicable (basic_block, basic_block, basic_block,
>> --                             basic_block, int);
>> -+                             edge, int);
>> - static void noce_emit_move_insn (rtx, rtx);
>> - static rtx block_has_only_trap (basic_block);
>> -
>> -@@ -3791,6 +3791,7 @@
>> -   basic_block then_bb = then_edge->dest;
>> -   basic_block else_bb = else_edge->dest;
>> -   basic_block new_bb;
>> -+  rtx else_target = NULL_RTX;
>> -   int then_bb_index;
>> -
>> -   /* If we are partitioning hot/cold basic blocks, we don't want to
>> -@@ -3840,9 +3841,16 @@
>> -                                   predictable_edge_p (then_edge)))))
>> -     return FALSE;
>> -
>> -+  if (else_bb == EXIT_BLOCK_PTR)
>> -+    {
>> -+      rtx jump = BB_END (else_edge->src);
>> -+      gcc_assert (JUMP_P (jump));
>> -+      else_target = JUMP_LABEL (jump);
>> -+    }
>> -+
>> -   /* Registers set are dead, or are predicable.  */
>> -   if (! dead_or_predicable (test_bb, then_bb, else_bb,
>> --                          single_succ (then_bb), 1))
>> -+                          single_succ_edge (then_bb), 1))
>> -     return FALSE;
>> -
>> -   /* Conversion went ok, including moving the insns and fixing up the
>> -@@ -3859,6 +3867,9 @@
>> -       redirect_edge_succ (FALLTHRU_EDGE (test_bb), else_bb);
>> -       new_bb = 0;
>> -     }
>> -+  else if (else_bb == EXIT_BLOCK_PTR)
>> -+    new_bb = force_nonfallthru_and_redirect (FALLTHRU_EDGE (test_bb),
>> -+                                           else_bb, else_target);
>> -   else
>> -     new_bb = redirect_edge_and_branch_force (FALLTHRU_EDGE (test_bb),
>> -                                            else_bb);
>> -@@ -3957,7 +3968,7 @@
>> -     return FALSE;
>> -
>> -   /* Registers set are dead, or are predicable.  */
>> --  if (! dead_or_predicable (test_bb, else_bb, then_bb, else_succ->dest,
>> 0))
>> -+  if (! dead_or_predicable (test_bb, else_bb, then_bb, else_succ, 0))
>> -     return FALSE;
>> -
>> -   /* Conversion went ok, including moving the insns and fixing up the
>> -@@ -3995,12 +4006,34 @@
>> -
>> - static int
>> - dead_or_predicable (basic_block test_bb, basic_block merge_bb,
>> --                  basic_block other_bb, basic_block new_dest, int
>> reversep)
>> -+                  basic_block other_bb, edge dest_edge, int reversep)
>> - {
>> --  rtx head, end, jump, earliest = NULL_RTX, old_dest, new_label =
>> NULL_RTX;
>> -+  basic_block new_dest = dest_edge->dest;
>> -+  rtx head, end, jump, earliest = NULL_RTX, old_dest;
>> -   bitmap merge_set = NULL;
>> -   /* Number of pending changes.  */
>> -   int n_validated_changes = 0;
>> -+  rtx new_dest_label;
>> -+
>> -+  jump = BB_END (dest_edge->src);
>> -+  if (JUMP_P (jump))
>> -+    {
>> -+      new_dest_label = JUMP_LABEL (jump);
>> -+      if (new_dest_label == NULL_RTX)
>> -+      {
>> -+        new_dest_label = PATTERN (jump);
>> -+        gcc_assert (ANY_RETURN_P (new_dest_label));
>> -+      }
>> -+    }
>> -+  else if (other_bb != new_dest)
>> -+    {
>> -+      if (new_dest == EXIT_BLOCK_PTR)
>> -+      new_dest_label = ret_rtx;
>> -+      else
>> -+      new_dest_label = block_label (new_dest);
>> -+    }
>> -+  else
>> -+    new_dest_label = NULL_RTX;
>> -
>> -   jump = BB_END (test_bb);
>> -
>> -@@ -4220,10 +4253,9 @@
>> -   old_dest = JUMP_LABEL (jump);
>> -   if (other_bb != new_dest)
>> -     {
>> --      new_label = block_label (new_dest);
>> -       if (reversep
>> --        ? ! invert_jump_1 (jump, new_label)
>> --        : ! redirect_jump_1 (jump, new_label))
>> -+        ? ! invert_jump_1 (jump, new_dest_label)
>> -+
>
> _______________________________________________
> Openembedded-core mailing list
> Openembedded-core at lists.linuxtogo.org
> http://lists.linuxtogo.org/cgi-bin/mailman/listinfo/openembedded-core
>
>




More information about the Openembedded-core mailing list