Commit 7a296495 by Christian Bruel Committed by Christian Bruel

add accumulate-outgoing-args and omit-frame-pointer for SH

From-SVN: r158399
parent 169afcb9
2010-04-16 Christian Bruel <christian.bruel@st.com>
* config/sh/sh.h (sh_frame_pointer_required): New function.
* config/sh/sh.h (TARGET_FRAME_POINTER_REQUIRED): New macro.
(flag_omit_frame_pointer) Set.
(MASK_ACCUMULATE_OUTGOING_ARGS) Define and Set.
(rounded_frame_size): Adjust size with outgoing_args_size.
(sh_set_return_address): Must return from stack pointer.
* gcc/config/sh/sh.h (CAN_DEBUG_WITHOUT_FP): Define.
(SUBTARGET_FRAME_POINTER_REQUIRED): Define.
(ACCUMULATE_OUTGOING_ARGS): Define.
* doc/invoke.texi (maccumulate-outgoing-args): Document for SH.
* gcc/config/sh/sh.opt: (maccumulate-outgoing-args): New option.
2010-04-15 Kaz Kojima <kkojima@gcc.gnu.org> 2010-04-15 Kaz Kojima <kkojima@gcc.gnu.org>
PR target/43471 PR target/43471
......
...@@ -189,6 +189,7 @@ static void pop (int); ...@@ -189,6 +189,7 @@ static void pop (int);
static void push_regs (HARD_REG_SET *, int); static void push_regs (HARD_REG_SET *, int);
static int calc_live_regs (HARD_REG_SET *); static int calc_live_regs (HARD_REG_SET *);
static HOST_WIDE_INT rounded_frame_size (int); static HOST_WIDE_INT rounded_frame_size (int);
static bool sh_frame_pointer_required (void);
static rtx mark_constant_pool_use (rtx); static rtx mark_constant_pool_use (rtx);
static tree sh_handle_interrupt_handler_attribute (tree *, tree, tree, int, bool *); static tree sh_handle_interrupt_handler_attribute (tree *, tree, tree, int, bool *);
static tree sh_handle_resbank_handler_attribute (tree *, tree, static tree sh_handle_resbank_handler_attribute (tree *, tree,
...@@ -503,6 +504,9 @@ static const struct attribute_spec sh_attribute_table[] = ...@@ -503,6 +504,9 @@ static const struct attribute_spec sh_attribute_table[] =
#undef TARGET_DWARF_CALLING_CONVENTION #undef TARGET_DWARF_CALLING_CONVENTION
#define TARGET_DWARF_CALLING_CONVENTION sh_dwarf_calling_convention #define TARGET_DWARF_CALLING_CONVENTION sh_dwarf_calling_convention
#undef TARGET_FRAME_POINTER_REQUIRED
#define TARGET_FRAME_POINTER_REQUIRED sh_frame_pointer_required
/* Return regmode weight for insn. */ /* Return regmode weight for insn. */
#define INSN_REGMODE_WEIGHT(INSN, MODE) regmode_weight[((MODE) == SImode) ? 0 : 1][INSN_UID (INSN)] #define INSN_REGMODE_WEIGHT(INSN, MODE) regmode_weight[((MODE) == SImode) ? 0 : 1][INSN_UID (INSN)]
...@@ -666,7 +670,6 @@ sh_optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED) ...@@ -666,7 +670,6 @@ sh_optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
{ {
if (level) if (level)
{ {
flag_omit_frame_pointer = 2;
if (!size) if (!size)
sh_div_str = "inv:minlat"; sh_div_str = "inv:minlat";
} }
...@@ -856,16 +859,7 @@ sh_override_options (void) ...@@ -856,16 +859,7 @@ sh_override_options (void)
if (! VALID_REGISTER_P (ADDREGNAMES_REGNO (regno))) if (! VALID_REGISTER_P (ADDREGNAMES_REGNO (regno)))
sh_additional_register_names[regno][0] = '\0'; sh_additional_register_names[regno][0] = '\0';
if (flag_omit_frame_pointer == 2) flag_omit_frame_pointer = (PREFERRED_DEBUGGING_TYPE == DWARF2_DEBUG);
{
/* The debugging information is sufficient,
but gdb doesn't implement this yet */
if (0)
flag_omit_frame_pointer
= (PREFERRED_DEBUGGING_TYPE == DWARF2_DEBUG);
else
flag_omit_frame_pointer = 0;
}
if ((flag_pic && ! TARGET_PREFERGOT) if ((flag_pic && ! TARGET_PREFERGOT)
|| (TARGET_SHMEDIA && !TARGET_PT_FIXED)) || (TARGET_SHMEDIA && !TARGET_PT_FIXED))
...@@ -897,6 +891,24 @@ sh_override_options (void) ...@@ -897,6 +891,24 @@ sh_override_options (void)
flag_schedule_insns = 0; flag_schedule_insns = 0;
} }
if ((target_flags_explicit & MASK_ACCUMULATE_OUTGOING_ARGS) == 0)
target_flags |= MASK_ACCUMULATE_OUTGOING_ARGS;
/* Unwind info is not correct around the CFG unless either a frame
pointer is present or M_A_O_A is set. Fixing this requires rewriting
unwind info generation to be aware of the CFG and propagating states
around edges. */
if ((flag_unwind_tables || flag_asynchronous_unwind_tables
|| flag_exceptions || flag_non_call_exceptions)
&& flag_omit_frame_pointer
&& !(target_flags & MASK_ACCUMULATE_OUTGOING_ARGS))
{
if (target_flags_explicit & MASK_ACCUMULATE_OUTGOING_ARGS)
warning (0, "unwind tables currently require either a frame pointer "
"or -maccumulate-outgoing-args for correctness");
target_flags |= MASK_ACCUMULATE_OUTGOING_ARGS;
}
/* Unwinding with -freorder-blocks-and-partition does not work on this /* Unwinding with -freorder-blocks-and-partition does not work on this
architecture, because it requires far jumps to label crossing between architecture, because it requires far jumps to label crossing between
hot/cold sections which are rejected on this architecture. */ hot/cold sections which are rejected on this architecture. */
...@@ -6583,6 +6595,9 @@ rounded_frame_size (int pushed) ...@@ -6583,6 +6595,9 @@ rounded_frame_size (int pushed)
HOST_WIDE_INT size = get_frame_size (); HOST_WIDE_INT size = get_frame_size ();
HOST_WIDE_INT align = STACK_BOUNDARY / BITS_PER_UNIT; HOST_WIDE_INT align = STACK_BOUNDARY / BITS_PER_UNIT;
if (ACCUMULATE_OUTGOING_ARGS)
size += crtl->outgoing_args_size;
return ((size + pushed + align - 1) & -align) - pushed; return ((size + pushed + align - 1) & -align) - pushed;
} }
...@@ -7431,7 +7446,11 @@ sh_set_return_address (rtx ra, rtx tmp) ...@@ -7431,7 +7446,11 @@ sh_set_return_address (rtx ra, rtx tmp)
pr_offset = rounded_frame_size (d); pr_offset = rounded_frame_size (d);
emit_insn (GEN_MOV (tmp, GEN_INT (pr_offset))); emit_insn (GEN_MOV (tmp, GEN_INT (pr_offset)));
emit_insn (GEN_ADD3 (tmp, tmp, hard_frame_pointer_rtx));
if (frame_pointer_needed)
emit_insn (GEN_ADD3 (tmp, tmp, hard_frame_pointer_rtx));
else
emit_insn (GEN_ADD3 (tmp, tmp, stack_pointer_rtx));
tmp = gen_frame_mem (Pmode, tmp); tmp = gen_frame_mem (Pmode, tmp);
emit_insn (GEN_MOV (tmp, ra)); emit_insn (GEN_MOV (tmp, ra));
...@@ -10936,6 +10955,20 @@ sh_vector_mode_supported_p (enum machine_mode mode) ...@@ -10936,6 +10955,20 @@ sh_vector_mode_supported_p (enum machine_mode mode)
return false; return false;
} }
bool
sh_frame_pointer_required (void)
{
/* If needed override this in other tm.h files to cope with various OS
lossage requiring a frame pointer. */
if (SUBTARGET_FRAME_POINTER_REQUIRED)
return true;
if (crtl->profile)
return true;
return false;
}
/* Implements target hook dwarf_calling_convention. Return an enum /* Implements target hook dwarf_calling_convention. Return an enum
of dwarf_calling_convention. */ of dwarf_calling_convention. */
int int
......
...@@ -98,8 +98,15 @@ do { \ ...@@ -98,8 +98,15 @@ do { \
? "__LITTLE_ENDIAN__" : "__BIG_ENDIAN__"); \ ? "__LITTLE_ENDIAN__" : "__BIG_ENDIAN__"); \
} while (0) } while (0)
/* We can not debug without a frame pointer. */ #define CAN_DEBUG_WITHOUT_FP
/* #define CAN_DEBUG_WITHOUT_FP */
/* Value should be nonzero if functions must have frame pointers.
Zero means the frame pointer need not be set up (and parms may be accessed
via the stack pointer) in functions that seem suitable. */
#ifndef SUBTARGET_FRAME_POINTER_REQUIRED
#define SUBTARGET_FRAME_POINTER_REQUIRED 0
#endif
#define CONDITIONAL_REGISTER_USAGE do \ #define CONDITIONAL_REGISTER_USAGE do \
{ \ { \
...@@ -2633,11 +2640,9 @@ extern int current_function_interrupt; ...@@ -2633,11 +2640,9 @@ extern int current_function_interrupt;
#define SIDI_OFF (TARGET_LITTLE_ENDIAN ? 0 : 4) #define SIDI_OFF (TARGET_LITTLE_ENDIAN ? 0 : 4)
/* ??? Define ACCUMULATE_OUTGOING_ARGS? This is more efficient than pushing /* Better to allocate once the maximum space for outgoing args in the
and popping arguments. However, we do have push/pop instructions, and prologue rather than duplicate around each call. */
rather limited offsets (4 bits) in load/store instructions, so it isn't #define ACCUMULATE_OUTGOING_ARGS TARGET_ACCUMULATE_OUTGOING_ARGS
clear if this would give better code. If implemented, should check for
compatibility problems. */
#define SH_DYNAMIC_SHIFT_COST \ #define SH_DYNAMIC_SHIFT_COST \
(TARGET_HARD_SH4 ? 1 : TARGET_SH3 ? (TARGET_SMALLCODE ? 1 : 2) : 20) (TARGET_HARD_SH4 ? 1 : TARGET_SH3 ? (TARGET_SMALLCODE ? 1 : 2) : 20)
......
...@@ -200,6 +200,10 @@ m5-compact-nofpu ...@@ -200,6 +200,10 @@ m5-compact-nofpu
Target RejectNegative Condition(SUPPORT_SH5_32MEDIA_NOFPU) Target RejectNegative Condition(SUPPORT_SH5_32MEDIA_NOFPU)
Generate FPU-less SHcompact code Generate FPU-less SHcompact code
maccumulate-outgoing-args
Target Report Mask(ACCUMULATE_OUTGOING_ARGS)
Reserve space for outgoing arguments in the function prologue
madjust-unroll madjust-unroll
Target Report Mask(ADJUST_UNROLL) Condition(SUPPORT_ANY_SH5) Target Report Mask(ADJUST_UNROLL) Condition(SUPPORT_ANY_SH5)
Throttle unrolling to avoid thrashing target registers unless the unroll benefit outweighs this Throttle unrolling to avoid thrashing target registers unless the unroll benefit outweighs this
......
...@@ -826,7 +826,7 @@ See RS/6000 and PowerPC Options. ...@@ -826,7 +826,7 @@ See RS/6000 and PowerPC Options.
-mprefergot -musermode -multcost=@var{number} -mdiv=@var{strategy} @gol -mprefergot -musermode -multcost=@var{number} -mdiv=@var{strategy} @gol
-mdivsi3_libfunc=@var{name} -mfixed-range=@var{register-range} @gol -mdivsi3_libfunc=@var{name} -mfixed-range=@var{register-range} @gol
-madjust-unroll -mindexed-addressing -mgettrcost=@var{number} -mpt-fixed @gol -madjust-unroll -mindexed-addressing -mgettrcost=@var{number} -mpt-fixed @gol
-minvalid-symbols} -maccumulate-outgoing-args -minvalid-symbols}
@emph{SPARC Options} @emph{SPARC Options}
@gccoptlist{-mcpu=@var{cpu-type} @gol @gccoptlist{-mcpu=@var{cpu-type} @gol
...@@ -16137,6 +16137,12 @@ by inserting a test to skip a number of operations in this case; this test ...@@ -16137,6 +16137,12 @@ by inserting a test to skip a number of operations in this case; this test
slows down the case of larger dividends. inv20u assumes the case of a such slows down the case of larger dividends. inv20u assumes the case of a such
a small dividend to be unlikely, and inv20l assumes it to be likely. a small dividend to be unlikely, and inv20l assumes it to be likely.
@item -maccumulate-outgoing-args
@opindex maccumulate-outgoing-args
Reserve space once for outgoing arguments in the function prologue rather
than around each call. Generally beneficial for performance and size. Also
needed for unwinding to avoid changing the stack frame around conditional code.
@item -mdivsi3_libfunc=@var{name} @item -mdivsi3_libfunc=@var{name}
@opindex mdivsi3_libfunc=@var{name} @opindex mdivsi3_libfunc=@var{name}
Set the name of the library function used for 32 bit signed division to Set the name of the library function used for 32 bit signed division to
......
2010-04-16 Christian Bruel <christian.bruel@st.com>
* g++.dg/torture/pr36191.C: Enable for SH.
2010-04-16 Eric Botcazou <ebotcazou@adacore.com> 2010-04-16 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/wide_boolean.adb: New test. * gnat.dg/wide_boolean.adb: New test.
......
// PR c++/36191 // PR c++/36191
// { dg-do compile } // { dg-do compile }
// { dg-options "-fnon-call-exceptions" } // { dg-options "-fnon-call-exceptions" }
// { dg-skip-if "Frame pointer required for unwind tables" { sh*-*-* m68k*-*-* fido*-*-* } "-fomit-frame-pointer" "" } // { dg-skip-if "Frame pointer required for unwind tables" { m68k*-*-* fido*-*-* } "-fomit-frame-pointer" "" }
__complex__ double __complex__ double
foo (__complex__ double x, double y) foo (__complex__ double x, double y)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment