OSDN Git Service

* bb-reorder.c, c-pch.c, c-pragma.c, c.opt, cfghooks.c, cfgloop.c,
[pf3gnuchains/gcc-fork.git] / gcc / toplev.c
index 7c8723c..f88b761 100644 (file)
@@ -16,8 +16,8 @@ for more details.
 
 You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
 
 /* This is the top level of cc1/c++.
    It parses command args, opens files, invokes the various passes
@@ -289,6 +289,14 @@ const char *aux_info_file_name;
 
 int flag_shlib;
 
+/* Generate code for GNU or NeXT Objective-C runtime environment.  */
+
+#ifdef NEXT_OBJC_RUNTIME
+int flag_next_runtime = 1;
+#else
+int flag_next_runtime = 0;
+#endif
+
 /* Set to the default thread-local storage (tls) model to use.  */
 
 enum tls_model flag_tls_default = TLS_MODEL_GLOBAL_DYNAMIC;
@@ -374,40 +382,6 @@ static const param_info lang_independent_params[] = {
   { NULL, 0, 0, 0, NULL }
 };
 
-#ifdef TARGET_SWITCHES
-/* Here is a table, controlled by the tm.h file, listing each -m switch
-   and which bits in `target_switches' it should set or clear.
-   If VALUE is positive, it is bits to set.
-   If VALUE is negative, -VALUE is bits to clear.
-   (The sign bit is not used so there is no confusion.)  */
-
-static const struct
-{
-  const char *const name;
-  const int value;
-  const char *const description;
-}
-target_switches[] = TARGET_SWITCHES;
-#endif
-
-/* This table is similar, but allows the switch to have a value.  */
-
-#ifdef TARGET_OPTIONS
-static const struct
-{
-  const char *const prefix;
-  const char **const variable;
-  const char *const description;
-  const char *const value;
-}
-target_options[] = TARGET_OPTIONS;
-#endif
-
-/* Nonzero means warn about function definitions that default the return type
-   or that use a null return and have a return-type other than void.  */
-
-int warn_return_type;
-
 /* Output files for assembler code (real compiler output)
    and debugging dumps.  */
 
@@ -468,9 +442,9 @@ announce_function (tree decl)
   if (!quiet_flag)
     {
       if (rtl_dump_and_exit)
-       verbatim ("%s ", IDENTIFIER_POINTER (DECL_NAME (decl)));
+       fprintf (stderr, "%s ", IDENTIFIER_POINTER (DECL_NAME (decl)));
       else
-       verbatim (" %s", lang_hooks.decl_printable_name (decl, 2));
+       fprintf (stderr, " %s", lang_hooks.decl_printable_name (decl, 2));
       fflush (stderr);
       pp_needs_newline (global_dc->printer) = true;
       diagnostic_set_last_function (global_dc);
@@ -781,9 +755,11 @@ wrapup_global_declarations (tree *vec, int len)
              bool needed = 1;
              node = cgraph_varpool_node (decl);
 
-             if (flag_unit_at_a_time && node->finalized)
+             if (node->finalized)
                needed = 0;
-             else if ((flag_unit_at_a_time && !cgraph_global_info_ready)
+             else if (node->alias)
+               needed = 0;
+             else if (!cgraph_global_info_ready
                       && (TREE_USED (decl)
                           || TREE_USED (DECL_ASSEMBLER_NAME (decl))))
                /* needed */;
@@ -847,10 +823,10 @@ check_global_declarations (tree *vec, int len)
              || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
        {
          if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
-           pedwarn ("%J%qF used but never defined", decl, decl);
+           pedwarn ("%q+F used but never defined", decl);
          else
-           warning ("%J%qF declared %<static%> but never defined",
-                    decl, decl);
+           warning (0, "%q+F declared %<static%> but never defined",
+                    decl);
          /* This symbol is effectively an "extern" declaration now.  */
          TREE_PUBLIC (decl) = 1;
          assemble_external (decl);
@@ -875,7 +851,7 @@ check_global_declarations (tree *vec, int len)
          && ! (TREE_CODE (decl) == VAR_DECL && DECL_REGISTER (decl))
          /* Otherwise, ask the language.  */
          && lang_hooks.decls.warn_unused_global (decl))
-       warning ("%J%qD defined but not used", decl, decl);
+       warning (0, "%q+D defined but not used", decl);
 
       /* Avoid confusing the debug information machinery when there are
         errors.  */
@@ -898,7 +874,7 @@ warn_deprecated_use (tree node)
   if (DECL_P (node))
     {
       expanded_location xloc = expand_location (DECL_SOURCE_LOCATION (node));
-      warning ("%qs is deprecated (declared at %s:%d)",
+      warning (0, "%qs is deprecated (declared at %s:%d)",
               IDENTIFIER_POINTER (DECL_NAME (node)),
               xloc.file, xloc.line);
     }
@@ -921,18 +897,18 @@ warn_deprecated_use (tree node)
          expanded_location xloc
            = expand_location (DECL_SOURCE_LOCATION (decl));
          if (what)
-           warning ("%qs is deprecated (declared at %s:%d)", what,
+           warning (0, "%qs is deprecated (declared at %s:%d)", what,
                       xloc.file, xloc.line);
          else
-           warning ("type is deprecated (declared at %s:%d)",
+           warning (0, "type is deprecated (declared at %s:%d)",
                     xloc.file, xloc.line);
        }
       else
        {
          if (what)
-           warning ("%qs is deprecated", what);
+           warning (0, "%qs is deprecated", what);
          else
-           warning ("type is deprecated");
+           warning (0, "type is deprecated");
        }
     }
 }
@@ -1060,92 +1036,6 @@ compile_file (void)
   targetm.asm_out.file_end ();
 }
 
-/* Display help for target options.  */
-void
-display_target_options (void)
-{
-  int undoc;
-#if defined (TARGET_SWITCHES) || defined (TARGET_OPTIONS)
-  int i;
-#endif
-  unsigned int cli;
-  static bool displayed = false;
-
-  /* Avoid double printing for --help --target-help.  */
-  if (displayed)
-    return;
-
-  displayed = true;
-
-  for (cli = 0; cli < cl_options_count; cli++)
-    if ((cl_options[cli].flags & (CL_TARGET | CL_UNDOCUMENTED)) == CL_TARGET)
-      break;
-
-  if (cli < cl_options_count
-#ifdef TARGET_SWITCHES
-      || ARRAY_SIZE (target_switches) > 1
-#endif
-#ifdef TARGET_OPTIONS
-      || ARRAY_SIZE (target_options) > 1
-#endif
-      )
-    {
-      int doc = cli < cl_options_count;
-
-      undoc = 0;
-
-      printf (_("\nTarget specific options:\n"));
-
-#ifdef TARGET_SWITCHES
-      for (i = ARRAY_SIZE (target_switches); i--;)
-       {
-         const char *option      = target_switches[i].name;
-         const char *description = target_switches[i].description;
-
-         if (option == NULL || *option == 0)
-           continue;
-         else if (description == NULL)
-           {
-             undoc = 1;
-
-             if (extra_warnings)
-               printf (_("  -m%-23s [undocumented]\n"), option);
-           }
-         else if (*description != 0)
-           doc += printf ("  -m%-23s %s\n", option, _(description));
-       }
-#endif
-
-#ifdef TARGET_OPTIONS
-      for (i = ARRAY_SIZE (target_options); i--;)
-       {
-         const char *option      = target_options[i].prefix;
-         const char *description = target_options[i].description;
-
-         if (option == NULL || *option == 0)
-           continue;
-         else if (description == NULL)
-           {
-             undoc = 1;
-
-             if (extra_warnings)
-               printf (_("  -m%-23s [undocumented]\n"), option);
-           }
-         else if (*description != 0)
-           doc += printf ("  -m%-23s %s\n", option, _(description));
-       }
-#endif
-      print_filtered_help (CL_TARGET);
-      if (undoc)
-       {
-         if (doc)
-           printf (_("\nThere are undocumented target specific options as well.\n"));
-         else
-           printf (_("  They exist, but they are not documented.\n"));
-       }
-    }
-}
-
 /* Parse a -d... command line switch.  */
 
 void
@@ -1185,7 +1075,7 @@ decode_d_option (const char *arg)
       case 'a':
       default:
        if (!enable_rtl_dump_file (c))
-         warning ("unrecognized gcc debugging option: %c", c);
+         warning (0, "unrecognized gcc debugging option: %c", c);
        break;
       }
 }
@@ -1196,64 +1086,6 @@ const char *const debug_type_names[] =
   "none", "stabs", "coff", "dwarf-2", "xcoff", "vms"
 };
 
-/* Decode -m switches.  */
-/* Decode the switch -mNAME.  */
-
-void
-set_target_switch (const char *name)
-{
-#if defined (TARGET_SWITCHES) || defined (TARGET_OPTIONS)
-  size_t j;
-#endif
-  int valid_target_option = 0;
-
-#ifdef TARGET_SWITCHES
-  for (j = 0; j < ARRAY_SIZE (target_switches); j++)
-    if (!strcmp (target_switches[j].name, name))
-      {
-       if (target_switches[j].value < 0)
-         target_flags &= ~-target_switches[j].value;
-       else
-         target_flags |= target_switches[j].value;
-       if (name[0] != 0)
-         {
-           if (target_switches[j].value < 0)
-             target_flags_explicit |= -target_switches[j].value;
-           else
-             target_flags_explicit |= target_switches[j].value;
-         }
-       valid_target_option = 1;
-      }
-#endif
-
-#ifdef TARGET_OPTIONS
-  if (!valid_target_option)
-    for (j = 0; j < ARRAY_SIZE (target_options); j++)
-      {
-       int len = strlen (target_options[j].prefix);
-       if (target_options[j].value)
-         {
-           if (!strcmp (target_options[j].prefix, name))
-             {
-               *target_options[j].variable = target_options[j].value;
-               valid_target_option = 1;
-             }
-         }
-       else
-         {
-           if (!strncmp (target_options[j].prefix, name, len))
-             {
-               *target_options[j].variable = name + len;
-               valid_target_option = 1;
-             }
-         }
-      }
-#endif
-
-  if (name[0] != 0 && !valid_target_option)
-    error ("invalid option %qs", name);
-}
-
 /* Print version information to FILE.
    Each line begins with INDENT (for the case where FILE is the
    assembler output file).  */
@@ -1261,19 +1093,25 @@ set_target_switch (const char *name)
 void
 print_version (FILE *file, const char *indent)
 {
-#ifndef __VERSION__
-#define __VERSION__ "[?]"
-#endif
-  fnotice (file,
+  static const char fmt1[] =
 #ifdef __GNUC__
-          "%s%s%s version %s (%s)\n%s\tcompiled by GNU C version %s.\n"
+    N_("%s%s%s version %s (%s)\n%s\tcompiled by GNU C version %s.\n")
 #else
-          "%s%s%s version %s (%s) compiled by CC.\n"
+    N_("%s%s%s version %s (%s) compiled by CC.\n")
 #endif
-          , indent, *indent != 0 ? " " : "",
+    ;
+  static const char fmt2[] =
+    N_("%s%sGGC heuristics: --param ggc-min-expand=%d --param ggc-min-heapsize=%d\n");
+#ifndef __VERSION__
+#define __VERSION__ "[?]"
+#endif
+  fprintf (file,
+          file == stderr ? _(fmt1) : fmt1,
+          indent, *indent != 0 ? " " : "",
           lang_hooks.name, version_string, TARGET_NAME,
           indent, __VERSION__);
-  fnotice (file, "%s%sGGC heuristics: --param ggc-min-expand=%d --param ggc-min-heapsize=%d\n",
+  fprintf (file,
+          file == stderr ? _(fmt2) : fmt2,
           indent, *indent != 0 ? " " : "",
           PARAM_VALUE (GGC_MIN_EXPAND), PARAM_VALUE (GGC_MIN_HEAPSIZE));
 }
@@ -1358,35 +1196,10 @@ print_switch_values (FILE *file, int pos, int max,
 
   for (j = 0; j < cl_options_count; j++)
     if ((cl_options[j].flags & CL_REPORT)
-       && option_enabled (&cl_options[j]) > 0)
+       && option_enabled (j) > 0)
       pos = print_single_switch (file, pos, max, indent, sep, term,
                                 "", cl_options[j].opt_text);
 
-  /* Print target specific options.  */
-
-#ifdef TARGET_SWITCHES
-  for (j = 0; j < ARRAY_SIZE (target_switches); j++)
-    if (target_switches[j].name[0] != '\0'
-       && target_switches[j].value > 0
-       && ((target_switches[j].value & target_flags)
-           == target_switches[j].value))
-      {
-       pos = print_single_switch (file, pos, max, indent, sep, term,
-                                  "-m", target_switches[j].name);
-      }
-#endif
-
-#ifdef TARGET_OPTIONS
-  for (j = 0; j < ARRAY_SIZE (target_options); j++)
-    if (*target_options[j].variable != NULL)
-      {
-       char prefix[256];
-       sprintf (prefix, "-m%s", target_options[j].prefix);
-       pos = print_single_switch (file, pos, max, indent, sep, term,
-                                  prefix, *target_options[j].variable);
-      }
-#endif
-
   fprintf (file, "%s", term);
 }
 
@@ -1437,6 +1250,21 @@ init_asm_output (const char *name)
     }
 }
 
+/* Return true if the state of option OPTION should be stored in PCH files
+   and checked by default_pch_valid_p.  Store the option's current state
+   in STATE if so.  */
+
+static inline bool
+option_affects_pch_p (int option, struct cl_option_state *state)
+{
+  if ((cl_options[option].flags & CL_TARGET) == 0)
+    return false;
+  if (cl_options[option].flag_var == &target_flags)
+    if (targetm.check_pch_target_flags)
+      return false;
+  return get_option_state (option, state);
+}
+
 /* Default version of get_pch_validity.
    By default, every flag difference is fatal; that will be mostly right for
    most targets, but completely right for very few.  */
@@ -1444,51 +1272,58 @@ init_asm_output (const char *name)
 void *
 default_get_pch_validity (size_t *len)
 {
-#ifdef TARGET_OPTIONS
+  struct cl_option_state state;
   size_t i;
-#endif
   char *result, *r;
 
-  *len = sizeof (target_flags) + 2;
-#ifdef TARGET_OPTIONS
-  for (i = 0; i < ARRAY_SIZE (target_options); i++)
-    {
-      *len += 1;
-      if (*target_options[i].variable)
-       *len += strlen (*target_options[i].variable);
-    }
-#endif
+  *len = 2;
+  if (targetm.check_pch_target_flags)
+    *len += sizeof (target_flags);
+  for (i = 0; i < cl_options_count; i++)
+    if (option_affects_pch_p (i, &state))
+      *len += state.size;
 
   result = r = xmalloc (*len);
   r[0] = flag_pic;
   r[1] = flag_pie;
   r += 2;
-  memcpy (r, &target_flags, sizeof (target_flags));
-  r += sizeof (target_flags);
-
-#ifdef TARGET_OPTIONS
-  for (i = 0; i < ARRAY_SIZE (target_options); i++)
+  if (targetm.check_pch_target_flags)
     {
-      const char *str = *target_options[i].variable;
-      size_t l;
-      if (! str)
-       str = "";
-      l = strlen (str) + 1;
-      memcpy (r, str, l);
-      r += l;
+      memcpy (r, &target_flags, sizeof (target_flags));
+      r += sizeof (target_flags);
     }
-#endif
+
+  for (i = 0; i < cl_options_count; i++)
+    if (option_affects_pch_p (i, &state))
+      {
+       memcpy (r, state.data, state.size);
+       r += state.size;
+      }
 
   return result;
 }
 
+/* Return a message which says that a PCH file was created with a different
+   setting of OPTION.  */
+
+static const char *
+pch_option_mismatch (const char *option)
+{
+  char *r;
+
+  asprintf (&r, _("created and used with differing settings of '%s'"), option);
+  if (r == NULL)
+    return _("out of memory");
+  return r;
+}
+
 /* Default version of pch_valid_p.  */
 
 const char *
 default_pch_valid_p (const void *data_p, size_t len)
 {
+  struct cl_option_state state;
   const char *data = (const char *)data_p;
-  const char *flag_that_differs = NULL;
   size_t i;
 
   /* -fpic and -fpie also usually make a PCH invalid.  */
@@ -1499,81 +1334,47 @@ default_pch_valid_p (const void *data_p, size_t len)
   data += 2;
 
   /* Check target_flags.  */
-  if (memcmp (data, &target_flags, sizeof (target_flags)) != 0)
+  if (targetm.check_pch_target_flags)
     {
       int tf;
+      const char *r;
 
       memcpy (&tf, data, sizeof (target_flags));
-#ifdef TARGET_SWITCHES
-      for (i = 0; i < ARRAY_SIZE (target_switches); i++)
-       {
-         int bits;
-
-         bits = target_switches[i].value;
-         if (bits < 0)
-           bits = -bits;
-         if ((target_flags & bits) != (tf & bits))
-           {
-             flag_that_differs = target_switches[i].name;
-             goto make_message;
-           }
-       }
-#endif
-      for (i = 0; i < cl_options_count; i++)
-       if (cl_options[i].flag_var == &target_flags
-           && (cl_options[i].var_value & (target_flags ^ tf)) != 0)
-         {
-           flag_that_differs = cl_options[i].opt_text + 2;
-           goto make_message;
-         }
-      gcc_unreachable ();
+      data += sizeof (target_flags);
+      len -= sizeof (target_flags);
+      r = targetm.check_pch_target_flags (tf);
+      if (r != NULL)
+       return r;
     }
-  data += sizeof (target_flags);
-  len -= sizeof (target_flags);
 
-  /* Check string options.  */
-#ifdef TARGET_OPTIONS
-  for (i = 0; i < ARRAY_SIZE (target_options); i++)
-    {
-      const char *str = *target_options[i].variable;
-      size_t l;
-      if (! str)
-       str = "";
-      l = strlen (str) + 1;
-      if (len < l || memcmp (data, str, l) != 0)
-       {
-         flag_that_differs = target_options[i].prefix;
-         goto make_message;
-       }
-      data += l;
-      len -= l;
-    }
-#endif
+  for (i = 0; i < cl_options_count; i++)
+    if (option_affects_pch_p (i, &state))
+      {
+       if (memcmp (data, state.data, state.size) != 0)
+         return pch_option_mismatch (cl_options[i].opt_text);
+       data += state.size;
+       len -= state.size;
+      }
 
   return NULL;
-
- make_message:
-  {
-    char *r;
-    asprintf (&r, _("created and used with differing settings of '-m%s'"),
-                 flag_that_differs);
-    if (r == NULL)
-      return _("out of memory");
-    return r;
-  }
 }
 
 /* Default tree printer.   Handles declarations only.  */
 static bool
-default_tree_printer (pretty_printer * pp, text_info *text)
+default_tree_printer (pretty_printer * pp, text_info *text, const char *spec,
+                     int precision, bool wide, bool set_locus, bool hash)
 {
   tree t;
 
-  switch (*text->format_spec)
+  /* FUTURE: %+x should set the locus.  */
+  if (precision != 0 || wide || hash)
+    return false;
+
+  switch (*spec)
     {
     case 'D':
       t = va_arg (*text->args_ptr, tree);
-      if (DECL_DEBUG_EXPR (t) && DECL_DEBUG_EXPR_IS_FROM (t))
+      if (DECL_DEBUG_EXPR_IS_FROM (t) && DECL_DEBUG_EXPR (t))
        t = DECL_DEBUG_EXPR (t);
       break;
 
@@ -1586,6 +1387,9 @@ default_tree_printer (pretty_printer * pp, text_info *text)
       return false;
     }
 
+  if (set_locus && text->locus)
+    *text->locus = DECL_SOURCE_LOCATION (t);
+
   if (DECL_P (t))
     {
       const char *n = DECL_NAME (t)
@@ -1616,6 +1420,9 @@ general_init (const char *argv0)
 
   hex_init ();
 
+  /* Unlock the stdio streams.  */
+  unlock_std_streams ();
+
   gcc_init_libintl ();
 
   /* Initialize the diagnostics reporting machinery, so option parsing
@@ -1766,11 +1573,11 @@ process_options (void)
   /* Warn about options that are not supported on this machine.  */
 #ifndef INSN_SCHEDULING
   if (flag_schedule_insns || flag_schedule_insns_after_reload)
-    warning ("instruction scheduling not supported on this target machine");
+    warning (0, "instruction scheduling not supported on this target machine");
 #endif
 #ifndef DELAY_SLOTS
   if (flag_delayed_branch)
-    warning ("this target machine does not have delayed branches");
+    warning (0, "this target machine does not have delayed branches");
 #endif
 
   user_label_prefix = USER_LABEL_PREFIX;
@@ -1784,7 +1591,7 @@ process_options (void)
          user_label_prefix = flag_leading_underscore ? "_" : "";
        }
       else
-       warning ("-f%sleading-underscore not supported on this target machine",
+       warning (0, "-f%sleading-underscore not supported on this target machine",
                 flag_leading_underscore ? "" : "no-");
     }
 
@@ -1870,10 +1677,10 @@ process_options (void)
       if (flag_var_tracking == 1)
         {
          if (debug_info_level < DINFO_LEVEL_NORMAL)
-           warning ("variable tracking requested, but useless unless "
+           warning (0, "variable tracking requested, but useless unless "
                     "producing debug info");
          else
-           warning ("variable tracking requested, but not supported "
+           warning (0, "variable tracking requested, but not supported "
                     "by this debug format");
        }
       flag_var_tracking = 0;
@@ -1900,44 +1707,44 @@ process_options (void)
     {
       if (flag_function_sections)
        {
-         warning ("-ffunction-sections not supported for this target");
+         warning (0, "-ffunction-sections not supported for this target");
          flag_function_sections = 0;
        }
       if (flag_data_sections)
        {
-         warning ("-fdata-sections not supported for this target");
+         warning (0, "-fdata-sections not supported for this target");
          flag_data_sections = 0;
        }
     }
 
   if (flag_function_sections && profile_flag)
     {
-      warning ("-ffunction-sections disabled; it makes profiling impossible");
+      warning (0, "-ffunction-sections disabled; it makes profiling impossible");
       flag_function_sections = 0;
     }
 
 #ifndef HAVE_prefetch
   if (flag_prefetch_loop_arrays)
     {
-      warning ("-fprefetch-loop-arrays not supported for this target");
+      warning (0, "-fprefetch-loop-arrays not supported for this target");
       flag_prefetch_loop_arrays = 0;
     }
   if (flag_speculative_prefetching)
     {
       if (flag_speculative_prefetching_set)
-       warning ("-fspeculative-prefetching not supported for this target");
+       warning (0, "-fspeculative-prefetching not supported for this target");
       flag_speculative_prefetching = 0;
     }
 #else
   if (flag_prefetch_loop_arrays && !HAVE_prefetch)
     {
-      warning ("-fprefetch-loop-arrays not supported for this target (try -march switches)");
+      warning (0, "-fprefetch-loop-arrays not supported for this target (try -march switches)");
       flag_prefetch_loop_arrays = 0;
     }
   if (flag_speculative_prefetching && !HAVE_prefetch)
     {
       if (flag_speculative_prefetching_set)
-       warning ("-fspeculative-prefetching not supported for this target (try -march switches)");
+       warning (0, "-fspeculative-prefetching not supported for this target (try -march switches)");
       flag_speculative_prefetching = 0;
     }
 #endif
@@ -1946,13 +1753,13 @@ process_options (void)
      make much sense anyway, so don't allow it.  */
   if (flag_prefetch_loop_arrays && optimize_size)
     {
-      warning ("-fprefetch-loop-arrays is not supported with -Os");
+      warning (0, "-fprefetch-loop-arrays is not supported with -Os");
       flag_prefetch_loop_arrays = 0;
     }
 
 #ifndef OBJECT_FORMAT_ELF
   if (flag_function_sections && write_symbols != NO_DEBUG)
-    warning ("-ffunction-sections may affect debugging on some targets");
+    warning (0, "-ffunction-sections may affect debugging on some targets");
 #endif
 
   /* The presence of IEEE signaling NaNs, implies all math can trap.  */
@@ -1962,6 +1769,16 @@ process_options (void)
   /* With -fcx-limited-range, we do cheap and quick complex arithmetic.  */
   if (flag_cx_limited_range)
     flag_complex_method = 0;
+
+  /* Targets must be able to place spill slots at lower addresses.  If the
+     target already uses a soft frame pointer, the transition is trivial.  */
+  if (!FRAME_GROWS_DOWNWARD && flag_stack_protect)
+    {
+      warning (0, "-fstack-protector not supported for this target");
+      flag_stack_protect = 0;
+    }
+  if (!flag_stack_protect)
+    warn_stack_protect = 0;
 }
 
 /* Initialize the compiler back end.  */
@@ -1982,7 +1799,6 @@ backend_init (void)
   init_alias_once ();
   init_loop ();
   init_reload ();
-  init_function_once ();
   init_varasm_once ();
 
   /* The following initialization functions need to generate rtl, so