+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.
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
{
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);
+ }
}
}
#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)
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)
{
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
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)
{
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. */
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,