OSDN Git Service

* expr.c (move_block_from_reg): Try using an integral mov operation first.
[pf3gnuchains/gcc-fork.git] / gcc / toplev.c
index 62e66d9..bb8e48c 100644 (file)
@@ -1,5 +1,5 @@
 /* Top level of GNU C compiler
-   Copyright (C) 1987, 88, 89, 92-5, 1996 Free Software Foundation, Inc.
+   Copyright (C) 1987, 88, 89, 92-6, 1997 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -240,6 +240,7 @@ int jump_opt_dump = 0;
 int cse_dump = 0;
 int loop_dump = 0;
 int cse2_dump = 0;
+int branch_prob_dump = 0;
 int flow_dump = 0;
 int combine_dump = 0;
 int sched_dump = 0;
@@ -292,9 +293,15 @@ int sorrycount = 0;
 /* Flag to output bytecode instead of native assembler */
 int output_bytecode = 0;
 
-/* Pointer to function to compute the name to use to print a declaration.  */
+/* Pointer to function to compute the name to use to print a declaration.
+   DECL is the declaration in question.
+   VERBOSITY determines what information will be printed:
+     0: DECL_NAME, demangled as necessary.
+     1: and scope information.
+     2: and any other information that might be interesting, such as function
+        parameter types in C++.  */
 
-char *(*decl_printable_name) ();
+char *(*decl_printable_name) (/* tree decl, int verbosity */);
 
 /* Pointer to function to compute rtl for a language-specific tree code.  */
 
@@ -317,6 +324,18 @@ int profile_flag = 0;
 
 int profile_block_flag;
 
+/* Nonzero if generating code to profile program flow graph arcs.  */
+
+int profile_arc_flag = 0;
+
+/* Nonzero if generating info for gcov to calculate line test coverage.  */
+
+int flag_test_coverage = 0;
+
+/* Nonzero indicates that branch taken probabilities should be calculated.  */
+
+int flag_branch_probabilities = 0;
+
 /* Nonzero for -pedantic switch: warn about anything
    that standard spec forbids.  */
 
@@ -627,6 +646,9 @@ struct { char *string; int *variable; int on_value;} f_options[] =
   {"pic", &flag_pic, 1},
   {"PIC", &flag_pic, 2},
   {"exceptions", &flag_exceptions, 1},
+  {"profile-arcs", &profile_arc_flag, 1},
+  {"test-coverage", &flag_test_coverage, 1},
+  {"branch-probabilities", &flag_branch_probabilities, 1},
   {"fast-math", &flag_fast_math, 1},
   {"common", &flag_no_common, 0},
   {"inhibit-size-directive", &flag_inhibit_size_directive, 1},
@@ -662,6 +684,10 @@ char *lang_options[] =
   "-fno-asm",
   "-fbuiltin",
   "-fno-builtin",
+  "-fhosted",
+  "-fno-hosted",
+  "-ffreestanding",
+  "-fno-freestanding",
   "-fcond-mismatch",
   "-fno-cond-mismatch",
   "-fdollars-in-identifiers",
@@ -692,6 +718,8 @@ char *lang_options[] =
   "-Wno-import",
   "-Wimplicit",
   "-Wno-implicit",
+  "-Wmain",
+  "-Wno-main",
   "-Wmissing-braces",
   "-Wno-missing-braces",
   "-Wmissing-declarations",
@@ -714,6 +742,8 @@ char *lang_options[] =
   "-Wno-traditional",
   "-Wtrigraphs",
   "-Wno-trigraphs",
+  "-Wundef",
+  "-Wno-undef",
   "-Wwrite-strings",
   "-Wno-write-strings",
 
@@ -820,6 +850,7 @@ FILE *jump_opt_dump_file;
 FILE *cse_dump_file;
 FILE *loop_dump_file;
 FILE *cse2_dump_file;
+FILE *branch_prob_dump_file;
 FILE *flow_dump_file;
 FILE *combine_dump_file;
 FILE *sched_dump_file;
@@ -839,6 +870,7 @@ int jump_time;
 int cse_time;
 int loop_time;
 int cse2_time;
+int branch_prob_time;
 int flow_time;
 int combine_time;
 int sched_time;
@@ -1025,9 +1057,9 @@ fatal_insn_not_found (insn)
 /* This is the default decl_printable_name function.  */
 
 static char *
-decl_name (decl, kind)
+decl_name (decl, verbosity)
      tree decl;
-     char **kind;
+     int verbosity;
 {
   return IDENTIFIER_POINTER (DECL_NAME (decl));
 }
@@ -1051,11 +1083,10 @@ announce_function (decl)
 {
   if (! quiet_flag)
     {
-      char *junk;
       if (rtl_dump_and_exit)
        fprintf (stderr, "%s ", IDENTIFIER_POINTER (DECL_NAME (decl)));
       else
-       fprintf (stderr, " %s", (*decl_printable_name) (decl, &junk));
+       fprintf (stderr, " %s", (*decl_printable_name) (decl, 2));
       fflush (stderr);
       need_error_newline = 1;
       last_error_function = current_function_decl;
@@ -1083,7 +1114,7 @@ default_print_error_function (file)
        fprintf (stderr, "At top level:\n");
       else
        {
-         char *name = (*decl_printable_name) (current_function_decl, &kind);
+         char *name = (*decl_printable_name) (current_function_decl, 2);
          fprintf (stderr, "In %s `%s':\n", kind, name);
        }
 
@@ -1181,7 +1212,7 @@ v_message_with_decl (decl, prefix, s, ap)
      char *s;
      va_list ap;
 {
-  char *n, *p, *junk;
+  char *n, *p;
 
   fprintf (stderr, "%s:%d: ",
           DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
@@ -1217,7 +1248,7 @@ v_message_with_decl (decl, prefix, s, ap)
   if (*p == '%')               /* Print the name.  */
     {
       char *n = (DECL_NAME (decl)
-                ? (*decl_printable_name) (decl, &junk)
+                ? (*decl_printable_name) (decl, 2)
                 : "((anonymous))");
       fputs (n, stderr);
       while (*p)
@@ -1864,9 +1895,27 @@ floor_log2_wide (x)
   return log;
 }
 
+static int float_handler_set;
 int float_handled;
 jmp_buf float_handler;
 
+/* Signals actually come here.  */
+
+static void
+float_signal (signo)
+     /* If this is missing, some compilers complain.  */
+     int signo;
+{
+  if (float_handled == 0)
+    abort ();
+#if defined (USG) || defined (hpux)
+  signal (SIGFPE, float_signal);  /* re-enable the signal catcher */
+#endif
+  float_handled = 0;
+  signal (SIGFPE, float_signal);
+  longjmp (float_handler, 1);
+}
+
 /* Specify where to longjmp to when a floating arithmetic error happens.
    If HANDLER is 0, it means don't handle the errors any more.  */
 
@@ -1877,6 +1926,12 @@ set_float_handler (handler)
   float_handled = (handler != 0);
   if (handler)
     bcopy ((char *) handler, (char *) float_handler, sizeof (float_handler));
+
+  if (float_handled && ! float_handler_set)
+    {
+      signal (SIGFPE, float_signal);
+      float_handler_set = 1;
+    }
 }
 
 /* Specify, in HANDLER, where to longjmp to when a floating arithmetic
@@ -1911,23 +1966,6 @@ pop_float_handler (handled, handler)
     bcopy ((char *) handler, (char *) float_handler, sizeof (float_handler));
 }
 
-/* Signals actually come here.  */
-
-static void
-float_signal (signo)
-     /* If this is missing, some compilers complain.  */
-     int signo;
-{
-  if (float_handled == 0)
-    abort ();
-#if defined (USG) || defined (hpux)
-  signal (SIGFPE, float_signal);  /* re-enable the signal catcher */
-#endif
-  float_handled = 0;
-  signal (SIGFPE, float_signal);
-  longjmp (float_handler, 1);
-}
-
 /* Handler for SIGPIPE.  */
 
 static void
@@ -2058,6 +2096,7 @@ compile_file (name)
   cse_time = 0;
   loop_time = 0;
   cse2_time = 0;
+  branch_prob_time = 0;
   flow_time = 0;
   combine_time = 0;
   sched_time = 0;
@@ -2096,7 +2135,8 @@ compile_file (name)
      but the options would have to be parsed first to know that. -bson */
   init_rtl ();
   init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL
-                 || debug_info_level == DINFO_LEVEL_VERBOSE);
+                 || debug_info_level == DINFO_LEVEL_VERBOSE
+                 || flag_test_coverage);
   init_regs ();
   init_decl_processing ();
   init_optabs ();
@@ -2139,6 +2179,10 @@ compile_file (name)
   if (cse2_dump)
     cse2_dump_file = open_dump_file (dump_base_name, ".cse2");
 
+  /* If branch_prob dump desired, open the output file.  */
+  if (branch_prob_dump)
+    branch_prob_dump_file = open_dump_file (dump_base_name, ".bp");
+
   /* If flow dump desired, open the output file.  */
   if (flow_dump)
     flow_dump_file = open_dump_file (dump_base_name, ".flow");
@@ -2327,6 +2371,7 @@ compile_file (name)
 
   if (!output_bytecode)
     init_final (main_input_filename);
+  init_branch_prob (dump_base_name);
 
   start_time = get_run_time ();
 
@@ -2344,6 +2389,8 @@ compile_file (name)
        poplevel (0, 0, 0);
     }
 
+  output_func_start_profiler ();
+
   /* Compilation is now finished except for writing
      what's left of the symbol table output.  */
 
@@ -2576,7 +2623,8 @@ compile_file (name)
 
   if (!output_bytecode)
     {
-      end_final (main_input_filename);
+      end_final (dump_base_name);
+      end_branch_prob (branch_prob_dump_file);
 
 #ifdef ASM_FILE_END
       ASM_FILE_END (asm_out_file);
@@ -2614,6 +2662,9 @@ compile_file (name)
   if (cse2_dump)
     fclose (cse2_dump_file);
 
+  if (branch_prob_dump)
+    fclose (branch_prob_dump_file);
+
   if (flow_dump)
     fclose (flow_dump_file);
 
@@ -2668,6 +2719,7 @@ compile_file (name)
          print_time ("cse", cse_time);
          print_time ("loop", loop_time);
          print_time ("cse2", cse2_time);
+         print_time ("branch-probabilities", branch_prob_time);
          print_time ("flow", flow_time);
          print_time ("combine", combine_time);
          print_time ("sched", sched_time);
@@ -2776,15 +2828,6 @@ rest_of_type_compilation (type, toplev)
   if (write_symbols == SDB_DEBUG)
     TIMEVAR (symout_time, sdbout_symbol (TYPE_STUB_DECL (type), !toplev));
 #endif
-#ifdef DWARF_DEBUGGING_INFO
-  /* Don't write out function-scope types here.  */
-  if (write_symbols == DWARF_DEBUG && toplev)
-    TIMEVAR (symout_time, dwarfout_file_scope_decl (TYPE_STUB_DECL (type), 0));
-#endif
-#ifdef DWARF2_DEBUGGING_INFO
-  if (write_symbols == DWARF2_DEBUG)
-    TIMEVAR (symout_time, dwarf2out_decl (TYPE_STUB_DECL (type)));
-#endif
 }
 
 /* This is called from finish_function (within yyparse)
@@ -2963,12 +3006,9 @@ rest_of_compilation (decl)
       goto exit_rest_of_compilation;
     }
 
-  /* From now on, allocate rtl in current_obstack, not in saveable_obstack.
-     Note that that may have been done above, in save_for_inline_copying.
-     The call to resume_temporary_allocation near the end of this function
-     goes back to the usual state of affairs.  */
-
-  rtl_in_current_obstack ();
+  /* Add an unwinder for exception handling, if needed.
+     This must be done before we finalize PIC code.  */
+  emit_unwinder ();
 
 #ifdef FINALIZE_PIC
   /* If we are doing position-independent code generation, now
@@ -2979,8 +3019,14 @@ rest_of_compilation (decl)
     FINALIZE_PIC;
 #endif
 
-  /* Add an unwinder for exception handling, if needed.  */
-  emit_unwinder ();
+  /* From now on, allocate rtl in current_obstack, not in saveable_obstack.
+     Note that that may have been done above, in save_for_inline_copying.
+     The call to resume_temporary_allocation near the end of this function
+     goes back to the usual state of affairs.  This must be done after
+     we've built up any unwinders for exception handling, and done
+     the FINALIZE_PIC work, if necessary.  */
+
+  rtl_in_current_obstack ();
 
   insns = get_insns ();
 
@@ -3109,10 +3155,12 @@ rest_of_compilation (decl)
     }
 
   if (optimize > 0 && flag_thread_jumps)
-    /* This pass of jump threading straightens out code
-       that was kinked by loop optimization.  */
-    TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 0));
-
+    {
+      /* This pass of jump threading straightens out code
+         that was kinked by loop optimization.  */
+      TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
+      TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 0));
+    }
   /* Dump rtl code after cse, if we are doing that.  */
 
   if (cse2_dump)
@@ -3122,6 +3170,25 @@ rest_of_compilation (decl)
               fflush (cse2_dump_file);
             });
 
+  if (branch_prob_dump)
+    TIMEVAR (dump_time,
+            {
+              fprintf (branch_prob_dump_file, "\n;; Function %s\n\n",
+                       IDENTIFIER_POINTER (DECL_NAME (decl)));
+            });
+
+  if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
+    TIMEVAR (branch_prob_time,
+            {
+              branch_prob (insns, branch_prob_dump_file);
+            });
+
+  if (branch_prob_dump)
+    TIMEVAR (dump_time,
+            {
+              print_rtl (branch_prob_dump_file, insns);
+              fflush (branch_prob_dump_file);
+            });
   /* We are no longer anticipating cse in this function, at least.  */
 
   cse_not_expected = 1;
@@ -3559,11 +3626,6 @@ main (argc, argv, envp)
     }
 
   obey_regdecls = (optimize == 0);
-  if (optimize == 0)
-    {
-      flag_no_inline = 1;
-      warn_inline = 0;
-    }
 
   if (optimize >= 1)
     {
@@ -3642,6 +3704,7 @@ main (argc, argv, envp)
                switch (*p++)
                  {
                  case 'a':
+                   branch_prob_dump = 1;
                    combine_dump = 1;
                    dbr_sched_dump = 1;
                    flow_dump = 1;
@@ -3656,6 +3719,9 @@ main (argc, argv, envp)
                    sched2_dump = 1;
                    stack_reg_dump = 1;
                    break;
+                 case 'b':
+                   branch_prob_dump = 1;
+                   break;
                  case 'k':
                    stack_reg_dump = 1;
                    break;
@@ -3902,19 +3968,11 @@ main (argc, argv, envp)
                { "gstabs+", DBX_DEBUG, 1 },
 #endif
 #ifdef DWARF_DEBUGGING_INFO
-               { "gdwarf-1", DWARF_DEBUG, 0 },
-               { "gdwarf-1+", DWARF_DEBUG, 1 },
-#endif
-#ifdef DWARF2_DEBUGGING_INFO
-               { "gdwarf-2", DWARF2_DEBUG, 0 },
-#endif
-#if defined (DWARF_DEBUGGING_INFO) || defined (DWARF2_DEBUGGING_INFO)
-#if PREFERRED_DEBUGGING_TYPE == DWARF_DEBUG || !defined (DWARF2_DEBUGGING_INFO)
                { "gdwarf", DWARF_DEBUG, 0 },
                { "gdwarf+", DWARF_DEBUG, 1 },
-#else
-               { "gdwarf", DWARF2_DEBUG, 0 },
 #endif
+#ifdef DWARF2_DEBUGGING_INFO
+               { "gdwarf-2", DWARF2_DEBUG, 0 },
 #endif
 #ifdef XCOFF_DEBUGGING_INFO
                { "gxcoff", XCOFF_DEBUG, 0 },
@@ -3963,6 +4021,10 @@ main (argc, argv, envp)
                      if (type == NO_DEBUG)
                        type = PREFERRED_DEBUGGING_TYPE;
 
+                     if (type == NO_DEBUG)
+                       warning ("`-%s' not supported by this configuration of GCC",
+                                str);
+
                      /* Does it conflict with an already selected type?  */
                      if (type_explicitly_set_p
                          /* -g/-ggdb don't conflict with anything */