diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5d3da7cd5a0..032af2b8d8c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2010-04-16 Christian Bruel + + * 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 PR target/43471 diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index 5dd9b6ec992..04b98c1eb22 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -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 diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h index 8b4f6c0539c..f870ba69e98 100644 --- a/gcc/config/sh/sh.h +++ b/gcc/config/sh/sh.h @@ -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) diff --git a/gcc/config/sh/sh.opt b/gcc/config/sh/sh.opt index dbe077ca49b..95e2ca439d5 100644 --- a/gcc/config/sh/sh.opt +++ b/gcc/config/sh/sh.opt @@ -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 diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index ad8eff8a983..8dcba6ee0c8 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a0ee05e5b6f..a029d982b25 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2010-04-16 Christian Bruel + + * g++.dg/torture/pr36191.C: Enable for SH. + 2010-04-16 Eric Botcazou * gnat.dg/wide_boolean.adb: New test. diff --git a/gcc/testsuite/g++.dg/torture/pr36191.C b/gcc/testsuite/g++.dg/torture/pr36191.C index 125d8a12205..175707d1baf 100644 --- a/gcc/testsuite/g++.dg/torture/pr36191.C +++ b/gcc/testsuite/g++.dg/torture/pr36191.C @@ -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)