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

From-SVN: r158399
This commit is contained in:
Christian Bruel 2010-04-16 10:04:05 +02:00 committed by Christian Bruel
parent 169afcb99f
commit 7a296495eb
7 changed files with 87 additions and 21 deletions

View File

@ -1,3 +1,17 @@
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>
PR target/43471

View File

@ -189,6 +189,7 @@ static void pop (int);
static void push_regs (HARD_REG_SET *, int);
static int calc_live_regs (HARD_REG_SET *);
static HOST_WIDE_INT rounded_frame_size (int);
static bool sh_frame_pointer_required (void);
static rtx mark_constant_pool_use (rtx);
static tree sh_handle_interrupt_handler_attribute (tree *, tree, tree, int, bool *);
static tree sh_handle_resbank_handler_attribute (tree *, tree,
@ -503,6 +504,9 @@ static const struct attribute_spec sh_attribute_table[] =
#undef TARGET_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. */
#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)
{
if (level)
{
flag_omit_frame_pointer = 2;
if (!size)
sh_div_str = "inv:minlat";
}
@ -856,16 +859,7 @@ sh_override_options (void)
if (! VALID_REGISTER_P (ADDREGNAMES_REGNO (regno)))
sh_additional_register_names[regno][0] = '\0';
if (flag_omit_frame_pointer == 2)
{
/* 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;
}
flag_omit_frame_pointer = (PREFERRED_DEBUGGING_TYPE == DWARF2_DEBUG);
if ((flag_pic && ! TARGET_PREFERGOT)
|| (TARGET_SHMEDIA && !TARGET_PT_FIXED))
@ -897,6 +891,24 @@ sh_override_options (void)
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
architecture, because it requires far jumps to label crossing between
hot/cold sections which are rejected on this architecture. */
@ -6583,6 +6595,9 @@ rounded_frame_size (int pushed)
HOST_WIDE_INT size = get_frame_size ();
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;
}
@ -7431,7 +7446,11 @@ sh_set_return_address (rtx ra, rtx tmp)
pr_offset = rounded_frame_size (d);
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);
emit_insn (GEN_MOV (tmp, ra));
@ -10936,6 +10955,20 @@ sh_vector_mode_supported_p (enum machine_mode mode)
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
of dwarf_calling_convention. */
int

View File

@ -98,8 +98,15 @@ do { \
? "__LITTLE_ENDIAN__" : "__BIG_ENDIAN__"); \
} 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 \
{ \
@ -2633,11 +2640,9 @@ extern int current_function_interrupt;
#define SIDI_OFF (TARGET_LITTLE_ENDIAN ? 0 : 4)
/* ??? Define ACCUMULATE_OUTGOING_ARGS? This is more efficient than pushing
and popping arguments. However, we do have push/pop instructions, and
rather limited offsets (4 bits) in load/store instructions, so it isn't
clear if this would give better code. If implemented, should check for
compatibility problems. */
/* Better to allocate once the maximum space for outgoing args in the
prologue rather than duplicate around each call. */
#define ACCUMULATE_OUTGOING_ARGS TARGET_ACCUMULATE_OUTGOING_ARGS
#define SH_DYNAMIC_SHIFT_COST \
(TARGET_HARD_SH4 ? 1 : TARGET_SH3 ? (TARGET_SMALLCODE ? 1 : 2) : 20)

View File

@ -200,6 +200,10 @@ m5-compact-nofpu
Target RejectNegative Condition(SUPPORT_SH5_32MEDIA_NOFPU)
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
Target Report Mask(ADJUST_UNROLL) Condition(SUPPORT_ANY_SH5)
Throttle unrolling to avoid thrashing target registers unless the unroll benefit outweighs this

View File

@ -826,7 +826,7 @@ See RS/6000 and PowerPC Options.
-mprefergot -musermode -multcost=@var{number} -mdiv=@var{strategy} @gol
-mdivsi3_libfunc=@var{name} -mfixed-range=@var{register-range} @gol
-madjust-unroll -mindexed-addressing -mgettrcost=@var{number} -mpt-fixed @gol
-minvalid-symbols}
-maccumulate-outgoing-args -minvalid-symbols}
@emph{SPARC Options}
@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
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.
@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}
@opindex mdivsi3_libfunc=@var{name}
Set the name of the library function used for 32 bit signed division to

View File

@ -1,3 +1,7 @@
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>
* gnat.dg/wide_boolean.adb: New test.

View File

@ -1,7 +1,7 @@
// PR c++/36191
// { dg-do compile }
// { 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
foo (__complex__ double x, double y)