OSDN Git Service

add accumulate-outgoing-args and omit-frame-pointer for SH
authorchrbr <chrbr@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 16 Apr 2010 08:04:05 +0000 (08:04 +0000)
committerchrbr <chrbr@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 16 Apr 2010 08:04:05 +0000 (08:04 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158399 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/sh/sh.c
gcc/config/sh/sh.h
gcc/config/sh/sh.opt
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr36191.C

index 5d3da7c..032af2b 100644 (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
index 5dd9b6e..04b98c1 100644 (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
index 8b4f6c0..f870ba6 100644 (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)
index dbe077c..95e2ca4 100644 (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
index ad8eff8..8dcba6e 100644 (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
index a0ee05e..a029d98 100644 (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.
index 125d8a1..175707d 100644 (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)