]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
i386.c (ix86_expand_prologue): Optimize stack checking for leaf functions without...
authorEric Botcazou <ebotcazou@gcc.gnu.org>
Wed, 6 Nov 2013 10:55:13 +0000 (10:55 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Wed, 6 Nov 2013 10:55:13 +0000 (10:55 +0000)
* config/i386/i386.c (ix86_expand_prologue): Optimize stack checking for
leaf functions without dynamic stack allocation.
* config/ia64/ia64.c (ia64_emit_probe_stack_range): Adjust.
(ia64_expand_prologue): Likewise.
* config/mips/mips.c (mips_expand_prologue): Likewise.
* config/rs6000/rs6000.c (rs6000_emit_prologue): Likewise.
* config/sparc/sparc.c (sparc_expand_prologue): Likewise.
(sparc_flat_expand_prologue): Likewise.

From-SVN: r204450

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/config/ia64/ia64.c
gcc/config/mips/mips.c
gcc/config/rs6000/rs6000.c
gcc/config/sparc/sparc.c

index 069cb506f720cabec69d936800f91a8a086b57f4..677fba92c59b8b76106a9e2bd928aa0227d1f5e8 100644 (file)
@@ -1,3 +1,14 @@
+2013-11-06  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * config/i386/i386.c (ix86_expand_prologue): Optimize stack checking for
+       leaf functions without dynamic stack allocation.
+       * config/ia64/ia64.c (ia64_emit_probe_stack_range): Adjust.
+       (ia64_expand_prologue): Likewise.
+       * config/mips/mips.c (mips_expand_prologue): Likewise.
+       * config/rs6000/rs6000.c (rs6000_emit_prologue): Likewise.
+       * config/sparc/sparc.c (sparc_expand_prologue): Likewise.
+       (sparc_flat_expand_prologue): Likewise.
+
 2013-11-06  James Greenhalgh  <james.greenhalgh@arm.com>
 
        * config/aarch64/arm_neon.h
 
 2013-11-06  Christian Bruel  <christian.bruel@st.com>
 
-       * gcc/config/sh/sh-mem.cc (sh_expand_cmpnstr, sh_expand_cmpstr):
+       * config/sh/sh-mem.cc (sh_expand_cmpnstr, sh_expand_cmpstr):
        Factorize probabilities, Use adjust_address instead of
        adjust_automodify_address when possible. Enable for optimize.
        (sh_expand_strlen): New function.
-       * gcc/config/sh/sh-protos.h (sh_expand_strlen): Declare.
-       * gcc/config/sh/sh.md (strlensi): New pattern.
+       * config/sh/sh-protos.h (sh_expand_strlen): Declare.
+       * config/sh/sh.md (strlensi): New pattern.
        (UNSPEC_BUILTIN_STRLEN): Define.
 
 2013-11-06  Jakub Jelinek  <jakub@redhat.com>
 
 2013-11-04  Wei Mi  <wmi@google.com>
 
-       * gcc/config/i386/i386.c (memory_address_length): Extract a part
+       * config/i386/i386.c (memory_address_length): Extract a part
        of code to rip_relative_addr_p.
        (rip_relative_addr_p): New Function.
        (ix86_macro_fusion_p): Ditto.
        (ix86_macro_fusion_pair_p): Ditto.
-       * gcc/config/i386/i386.h: Add new tune features about macro-fusion.
-       * gcc/config/i386/x86-tune.def (DEF_TUNE): Ditto.
-       * gcc/doc/tm.texi: Generated.
-       * gcc/doc/tm.texi.in: Ditto.
-       * gcc/haifa-sched.c (try_group_insn): New Function.
+       * config/i386/i386.h: Add new tune features about macro-fusion.
+       * config/i386/x86-tune.def (DEF_TUNE): Ditto.
+       * doc/tm.texi: Generated.
+       * doc/tm.texi.in: Ditto.
+       * haifa-sched.c (try_group_insn): New Function.
        (group_insns_for_macro_fusion): Ditto.
        (sched_init): Call group_insns_for_macro_fusion.
-       * gcc/target.def: Add two hooks: macro_fusion_p and
+       * target.def: Add two hooks: macro_fusion_p and
        macro_fusion_pair_p.
 
 2013-11-04  Kostya Serebryany  <kcc@google.com>
 
 2013-11-04  Wei Mi  <wmi@google.com>
 
-       * gcc/config/i386/i386-c.c (ix86_target_macros_internal): Separate
+       * config/i386/i386-c.c (ix86_target_macros_internal): Separate
        PROCESSOR_COREI7_AVX out from PROCESSOR_COREI7.
-       * gcc/config/i386/i386.c (ix86_option_override_internal): Ditto.
+       * config/i386/i386.c (ix86_option_override_internal): Ditto.
        (ix86_issue_rate): Ditto.
        (ix86_adjust_cost): Ditto.
        (ia32_multipass_dfa_lookahead): Ditto.
        (ix86_sched_init_global): Ditto.
        (get_builtin_code_for_version): Ditto.
-       * gcc/config/i386/i386.h (enum target_cpu_default): Ditto.
+       * config/i386/i386.h (enum target_cpu_default): Ditto.
        (enum processor_type): Ditto.
-       * gcc/config/i386/x86-tune.def (DEF_TUNE): Ditto.
+       * config/i386/x86-tune.def (DEF_TUNE): Ditto.
 
 2013-11-04  Vladimir Makarov  <vmakarov@redhat.com>
 
 2013-10-30  Tobias Burnus  <burnus@net-b.de>
 
        PR other/33426
-       * gcc/tree-cfg.c (replace_loop_annotate): Replace warning by
+       * tree-cfg.c (replace_loop_annotate): Replace warning by
        warning_at.
 
 2013-10-30  Jason Merrill  <jason@redhat.com>
 
 2013-10-30  Christian Bruel  <christian.bruel@st.com>
 
-       * gcc/config/sh/sh-mem.cc (sh_expand_cmpnstr): New function.
+       * config/sh/sh-mem.cc (sh_expand_cmpnstr): New function.
        (sh_expand_cmpstr): Handle known align and schedule improvements.
-       * gcc/config/sh/sh-protos.h (sh_expand_cmpstrn): Declare.
-       * gcc/config/sh/sh.md (cmpstrnsi): New pattern.
+       * config/sh/sh-protos.h (sh_expand_cmpstrn): Declare.
+       * config/sh/sh.md (cmpstrnsi): New pattern.
 
 2013-10-30  Martin Jambor  <mjambor@suse.cz>
 
 
 2013-10-24  Joern Rennecke  <joern.rennecke@embecosm.com>
 
-       * gcc/config/arc/arc.c (arc_ccfsm_post_advance): Also handle
+       * config/arc/arc.c (arc_ccfsm_post_advance): Also handle
        TYPE_UNCOND_BRANCH.
        (arc_ifcvt) <case 1 and 2>: Check that arc_ccfsm_post_advance
        changes statep->state.
 2013-10-25  Christian Bruel  <christian.bruel@st.com>
 
        * config.gcc (sh-*): Add sh-mem.o to extra_obj.
-       * gcc/config/sh/t-sh (sh-mem.o): New rule.
-       * gcc/config/sh/sh-mem.cc (expand_block_move): Moved here.
+       * config/sh/t-sh (sh-mem.o): New rule.
+       * config/sh/sh-mem.cc (expand_block_move): Moved here.
        (sh_expand_cmpstr): New function.
-       * gcc/config/sh/sh.c (force_into, expand_block_move): Move to sh-mem.c.
-       * gcc/config/sh/sh-protos.h (sh_expand_cmpstr): Declare.
-       * gcc/config/sh/sh.md (cmpstrsi, cmpstr_t): New patterns.
+       * config/sh/sh.c (force_into, expand_block_move): Move to sh-mem.c.
+       * config/sh/sh-protos.h (sh_expand_cmpstr): Declare.
+       * config/sh/sh.md (cmpstrsi, cmpstr_t): New patterns.
        (rotlhi3_8): Rename.
 
 2013-10-24  Jan-Benedict Glaw  <jbglaw@lug-owl.de>
 
 2013-10-16  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
 
-       * gcc/config/rs6000/vector.md (vec_unpacks_hi_v4sf): Correct for
+       * config/rs6000/vector.md (vec_unpacks_hi_v4sf): Correct for
        endianness.
        (vec_unpacks_lo_v4sf): Likewise.
        (vec_unpacks_float_hi_v4si): Likewise.
        (anddi3_insn): Update type attribute.
        (xordi3_insn): Likewise.
        (one_cmpldi2): Likewise.
-       * gcc/config/arm/vfp.md (movhf_vfp_neon): Update type attribute.
-       * gcc/config/arm/neon.md (neon_mov): Update type attribute.
+       * config/arm/vfp.md (movhf_vfp_neon): Update type attribute.
+       * config/arm/neon.md (neon_mov): Update type attribute.
        (*movmisalign<mode>_neon_store): Likewise.
        (*movmisalign<mode>_neon_load): Likewise.
        (vec_set<mode>_internal): Likewise.
index 119233273231c6ae687eafc421a26d45991383da..0680dea7d62a7b34f459b44000a845bc1677b1c8 100644 (file)
@@ -10657,8 +10657,12 @@ ix86_expand_prologue (void)
 
       if (STACK_CHECK_MOVING_SP)
        {
-         ix86_adjust_stack_and_probe (allocate);
-         allocate = 0;
+         if (!(crtl->is_leaf && !cfun->calls_alloca
+               && allocate <= PROBE_INTERVAL))
+           {
+             ix86_adjust_stack_and_probe (allocate);
+             allocate = 0;
+           }
        }
       else
        {
@@ -10668,9 +10672,26 @@ ix86_expand_prologue (void)
            size = 0x80000000 - STACK_CHECK_PROTECT - 1;
 
          if (TARGET_STACK_PROBE)
-           ix86_emit_probe_stack_range (0, size + STACK_CHECK_PROTECT);
+           {
+             if (crtl->is_leaf && !cfun->calls_alloca)
+               {
+                 if (size > PROBE_INTERVAL)
+                   ix86_emit_probe_stack_range (0, size);
+               }
+             else
+               ix86_emit_probe_stack_range (0, size + STACK_CHECK_PROTECT);
+           }
          else
-           ix86_emit_probe_stack_range (STACK_CHECK_PROTECT, size);
+           {
+             if (crtl->is_leaf && !cfun->calls_alloca)
+               {
+                 if (size > PROBE_INTERVAL && size > STACK_CHECK_PROTECT)
+                   ix86_emit_probe_stack_range (STACK_CHECK_PROTECT,
+                                                size - STACK_CHECK_PROTECT);
+               }
+             else
+               ix86_emit_probe_stack_range (STACK_CHECK_PROTECT, size);
+           }
        }
     }
 
index 273cd39065f249656498ab33193c660d4bcbbc20..971fe2f818917b42be8b9e4dbd8965f7d4bbff6f 100644 (file)
@@ -3206,61 +3206,54 @@ gen_fr_restore_x (rtx dest, rtx src, rtx offset ATTRIBUTE_UNUSED)
 #define BACKING_STORE_SIZE(N) ((N) > 0 ? ((N) + (N)/63 + 1) * 8 : 0)
 
 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
-   inclusive.  These are offsets from the current stack pointer.  SOL is the
-   size of local registers.  ??? This clobbers r2 and r3.  */
+   inclusive.  These are offsets from the current stack pointer.  BS_SIZE
+   is the size of the backing store.  ??? This clobbers r2 and r3.  */
 
 static void
-ia64_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size, int sol)
+ia64_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size,
+                            int bs_size)
 {
- /* On the IA-64 there is a second stack in memory, namely the Backing Store
-    of the Register Stack Engine.  We also need to probe it after checking
-    that the 2 stacks don't overlap.  */
-  const int bs_size = BACKING_STORE_SIZE (sol);
   rtx r2 = gen_rtx_REG (Pmode, GR_REG (2));
   rtx r3 = gen_rtx_REG (Pmode, GR_REG (3));
-
-  /* Detect collision of the 2 stacks if necessary.  */
-  if (bs_size > 0 || size > 0)
-    {
-      rtx p6 = gen_rtx_REG (BImode, PR_REG (6));
-
-      emit_insn (gen_bsp_value (r3));
-      emit_move_insn (r2, GEN_INT (-(first + size)));
-
-      /* Compare current value of BSP and SP registers.  */
-      emit_insn (gen_rtx_SET (VOIDmode, p6,
-                             gen_rtx_fmt_ee (LTU, BImode,
-                                             r3, stack_pointer_rtx)));
-
-      /* Compute the address of the probe for the Backing Store (which grows
-        towards higher addresses).  We probe only at the first offset of
-        the next page because some OS (eg Linux/ia64) only extend the
-        backing store when this specific address is hit (but generate a SEGV
-        on other address).  Page size is the worst case (4KB).  The reserve
-        size is at least 4096 - (96 + 2) * 8 = 3312 bytes, which is enough.
-        Also compute the address of the last probe for the memory stack
-        (which grows towards lower addresses).  */
-      emit_insn (gen_rtx_SET (VOIDmode, r3, plus_constant (Pmode, r3, 4095)));
-      emit_insn (gen_rtx_SET (VOIDmode, r2,
-                             gen_rtx_PLUS (Pmode, stack_pointer_rtx, r2)));
-
-      /* Compare them and raise SEGV if the former has topped the latter.  */
-      emit_insn (gen_rtx_COND_EXEC (VOIDmode,
-                                   gen_rtx_fmt_ee (NE, VOIDmode, p6,
-                                                   const0_rtx),
-                                   gen_rtx_SET (VOIDmode, p6,
-                                                gen_rtx_fmt_ee (GEU, BImode,
-                                                                r3, r2))));
-      emit_insn (gen_rtx_SET (VOIDmode,
-                             gen_rtx_ZERO_EXTRACT (DImode, r3, GEN_INT (12),
-                                                   const0_rtx),
-                             const0_rtx));
-      emit_insn (gen_rtx_COND_EXEC (VOIDmode,
-                                   gen_rtx_fmt_ee (NE, VOIDmode, p6,
-                                                   const0_rtx),
-                                   gen_rtx_TRAP_IF (VOIDmode, const1_rtx,
-                                                    GEN_INT (11))));
-    }
+  rtx p6 = gen_rtx_REG (BImode, PR_REG (6));
+
+  /* On the IA-64 there is a second stack in memory, namely the Backing Store
+     of the Register Stack Engine.  We also need to probe it after checking
+     that the 2 stacks don't overlap.  */
+  emit_insn (gen_bsp_value (r3));
+  emit_move_insn (r2, GEN_INT (-(first + size)));
+
+  /* Compare current value of BSP and SP registers.  */
+  emit_insn (gen_rtx_SET (VOIDmode, p6,
+                         gen_rtx_fmt_ee (LTU, BImode,
+                                         r3, stack_pointer_rtx)));
+
+  /* Compute the address of the probe for the Backing Store (which grows
+     towards higher addresses).  We probe only at the first offset of
+     the next page because some OS (eg Linux/ia64) only extend the
+     backing store when this specific address is hit (but generate a SEGV
+     on other address).  Page size is the worst case (4KB).  The reserve
+     size is at least 4096 - (96 + 2) * 8 = 3312 bytes, which is enough.
+     Also compute the address of the last probe for the memory stack
+     (which grows towards lower addresses).  */
+  emit_insn (gen_rtx_SET (VOIDmode, r3, plus_constant (Pmode, r3, 4095)));
+  emit_insn (gen_rtx_SET (VOIDmode, r2,
+                         gen_rtx_PLUS (Pmode, stack_pointer_rtx, r2)));
+
+  /* Compare them and raise SEGV if the former has topped the latter.  */
+  emit_insn (gen_rtx_COND_EXEC (VOIDmode,
+                               gen_rtx_fmt_ee (NE, VOIDmode, p6, const0_rtx),
+                               gen_rtx_SET (VOIDmode, p6,
+                                            gen_rtx_fmt_ee (GEU, BImode,
+                                                            r3, r2))));
+  emit_insn (gen_rtx_SET (VOIDmode,
+                         gen_rtx_ZERO_EXTRACT (DImode, r3, GEN_INT (12),
+                                               const0_rtx),
+                         const0_rtx));
+  emit_insn (gen_rtx_COND_EXEC (VOIDmode,
+                               gen_rtx_fmt_ee (NE, VOIDmode, p6, const0_rtx),
+                               gen_rtx_TRAP_IF (VOIDmode, const1_rtx,
+                                                GEN_INT (11))));
 
   /* Probe the Backing Store if necessary.  */
   if (bs_size > 0)
@@ -3444,10 +3437,23 @@ ia64_expand_prologue (void)
     current_function_static_stack_size = current_frame_info.total_size;
 
   if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK)
-    ia64_emit_probe_stack_range (STACK_CHECK_PROTECT,
-                                current_frame_info.total_size,
-                                current_frame_info.n_input_regs
-                                  + current_frame_info.n_local_regs);
+    {
+      HOST_WIDE_INT size = current_frame_info.total_size;
+      int bs_size = BACKING_STORE_SIZE (current_frame_info.n_input_regs
+                                         + current_frame_info.n_local_regs);
+
+      if (crtl->is_leaf && !cfun->calls_alloca)
+       {
+         if (size > PROBE_INTERVAL && size > STACK_CHECK_PROTECT)
+           ia64_emit_probe_stack_range (STACK_CHECK_PROTECT,
+                                        size - STACK_CHECK_PROTECT,
+                                        bs_size);
+         else if (size + bs_size > STACK_CHECK_PROTECT)
+           ia64_emit_probe_stack_range (STACK_CHECK_PROTECT, 0, bs_size);
+       }
+      else if (size + bs_size > 0)
+       ia64_emit_probe_stack_range (STACK_CHECK_PROTECT, size, bs_size);
+    }
 
   if (dump_file) 
     {
index 60e5e788f902fef2d9aa1e3e762d1f34441a3963..c1d8f3a0ade7aee6f98e16fa56ab996748860aaa 100644 (file)
@@ -10994,8 +10994,17 @@ mips_expand_prologue (void)
   if (flag_stack_usage_info)
     current_function_static_stack_size = size;
 
-  if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && size)
-    mips_emit_probe_stack_range (STACK_CHECK_PROTECT, size);
+  if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK)
+    {
+      if (crtl->is_leaf && !cfun->calls_alloca)
+       {
+         if (size > PROBE_INTERVAL && size > STACK_CHECK_PROTECT)
+           mips_emit_probe_stack_range (STACK_CHECK_PROTECT,
+                                        size - STACK_CHECK_PROTECT);
+       }
+      else if (size > 0)
+       mips_emit_probe_stack_range (STACK_CHECK_PROTECT, size);
+    }
 
   /* Save the registers.  Allocate up to MIPS_MAX_FIRST_STACK_STEP
      bytes beforehand; this is enough to cover the register save area
index a6b66816aee22b04c7eaa1687e021ef434f204b6..fce8f317c6a6868d0ad19afee860a0d117adc693 100644 (file)
@@ -21538,8 +21538,19 @@ rs6000_emit_prologue (void)
   if (flag_stack_usage_info)
     current_function_static_stack_size = info->total_size;
 
-  if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && info->total_size)
-    rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT, info->total_size);
+  if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK)
+    {
+      HOST_WIDE_INT size = info->total_size;
+
+      if (crtl->is_leaf && !cfun->calls_alloca)
+       {
+         if (size > PROBE_INTERVAL && size > STACK_CHECK_PROTECT)
+           rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT,
+                                          size - STACK_CHECK_PROTECT);
+       }
+      else if (size > 0)
+       rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT, size);
+    }
 
   if (TARGET_FIX_AND_CONTINUE)
     {
index 8ef634133c546d02b5c8d1900c65ca2d5c830e2f..0eabd5b2b726f469ee084ea9e011dc556271b576 100644 (file)
@@ -5362,8 +5362,17 @@ sparc_expand_prologue (void)
   if (flag_stack_usage_info)
     current_function_static_stack_size = size;
 
-  if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && size)
-    sparc_emit_probe_stack_range (STACK_CHECK_PROTECT, size);
+  if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK)
+    {
+      if (crtl->is_leaf && !cfun->calls_alloca)
+       {
+         if (size > PROBE_INTERVAL && size > STACK_CHECK_PROTECT)
+           sparc_emit_probe_stack_range (STACK_CHECK_PROTECT,
+                                         size - STACK_CHECK_PROTECT);
+       }
+      else if (size > 0)
+       sparc_emit_probe_stack_range (STACK_CHECK_PROTECT, size);
+    }
 
   if (size == 0)
     ; /* do nothing.  */
@@ -5464,8 +5473,17 @@ sparc_flat_expand_prologue (void)
   if (flag_stack_usage_info)
     current_function_static_stack_size = size;
 
-  if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && size)
-    sparc_emit_probe_stack_range (STACK_CHECK_PROTECT, size);
+  if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK)
+    {
+      if (crtl->is_leaf && !cfun->calls_alloca)
+       {
+         if (size > PROBE_INTERVAL && size > STACK_CHECK_PROTECT)
+           sparc_emit_probe_stack_range (STACK_CHECK_PROTECT,
+                                         size - STACK_CHECK_PROTECT);
+       }
+      else if (size > 0)
+       sparc_emit_probe_stack_range (STACK_CHECK_PROTECT, size);
+    }
 
   if (sparc_save_local_in_regs_p)
     emit_save_or_restore_local_in_regs (stack_pointer_rtx, SPARC_STACK_BIAS,