OSDN Git Service

Fix mips64vr4100-elf build failure.
[pf3gnuchains/gcc-fork.git] / gcc / profile.c
index 80f4549..060ecfc 100644 (file)
@@ -1,5 +1,5 @@
 /* Calculate branch probabilities, and basic block execution counts. 
-   Copyright (C) 1990, 91, 92, 93, 94, 96, 1997 Free Software Foundation, Inc.
+   Copyright (C) 1990, 91-94, 96, 97, 1998 Free Software Foundation, Inc.
    Contributed by James E. Wilson, UC Berkeley/Cygnus Support;
    based on some ideas from Dain Samples of UC Berkeley.
    Further mangling by Bob Manson, Cygnus Support.
@@ -41,7 +41,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
    achieve this, see Dain Sample's UC Berkeley thesis.  */
 
 #include "config.h"
-#include <stdio.h>
+#include "system.h"
 #include "rtl.h"
 #include "flags.h"
 #include "insn-flags.h"
@@ -51,9 +51,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "tree.h"
 #include "output.h"
 #include "gcov-io.h"
+#include "toplev.h"
 
 extern char * xmalloc ();
-extern void free ();
 
 /* One of these is dynamically created whenever we identify an arc in the
    function.  */
@@ -184,11 +184,6 @@ instrument_arcs (f, num_blocks, dump_file)
   int num_instr_arcs = 0;
   rtx insn;
 
-  int neg_one = -1;
-  int zero = 0;
-  int inverted;
-  rtx note;
-
   /* Instrument the program start.  */
   /* Handle block 0 specially, since it will always be instrumented,
      but it doesn't have a valid first_insn or branch_insn.  We must
@@ -419,6 +414,25 @@ output_gcov_string (string, delimiter)
   __write_long (delimiter, bb_file, 4);
 }
 \f
+/* Return TRUE if this insn must be a tablejump entry insn.  This works for
+   the MIPS port, but may give false negatives for some targets.  */
+
+int
+tablejump_entry_p (insn, label)
+     rtx insn, label;
+{
+  rtx next = next_active_insn (insn);
+  enum rtx_code code = GET_CODE (PATTERN (next));
+
+  if (code != ADDR_DIFF_VEC && code != ADDR_VEC)
+    return 0;
+
+  if (PREV_INSN (next) == XEXP (label, 0))
+    return 1;
+
+  return 0;
+}
+
 /* Instrument and/or analyze program behavior based on program flow graph.
    In either case, this function builds a flow graph for the function being
    compiled.  The flow graph is stored in BB_GRAPH.
@@ -441,8 +455,6 @@ branch_prob (f, dump_file)
      FILE *dump_file;
 {
   int i, num_blocks;
-  int dest;
-  rtx insn;
   struct adj_list *arcptr;
   int num_arcs, changes, passes;
   int total, prob;
@@ -626,7 +638,7 @@ branch_prob (f, dump_file)
     register int i;
     int fall_through = 0;
     struct adj_list *arcptr;
-    int dest;
+    int dest = 0;
 
     /* Block 0 always falls through to block 1.  */
     num_arcs = 0;
@@ -679,7 +691,7 @@ branch_prob (f, dump_file)
            bb_graph[i].first_insn = insn;
          }
        else if (code == NOTE)
-         ;
+         {;}
 
        if (code == CALL_INSN)
          {
@@ -719,10 +731,22 @@ branch_prob (f, dump_file)
               We have to handle tablejumps and returns specially anyways, so
               we don't check the JUMP_LABEL at all here.  */
 
+           /* ??? This code should be rewritten.  We need a more elegant way
+              to find the LABEL_REF.  We need a more elegant way to
+              differentiate tablejump entries from computed gotos.
+              We should perhaps reuse code from flow to compute the CFG
+              instead of trying to compute it here.
+
+              We can't use current_function_has_computed_jump, because that
+              is calculated later by flow.  We can't use computed_jump_p,
+              because that returns true for tablejump entry insns for some
+              targets, e.g. HPPA and MIPS.  */
+
            if (GET_CODE (pattern) == PARALLEL)
              {
-               /* This assumes that PARALLEL jumps are tablejump entry
-                  jumps.  */
+               /* This assumes that PARALLEL jumps with a USE are
+                  tablejump entry jumps.  The same assumption can be found
+                  in computed_jump_p.  */
                /* Make an arc from this jump to the label of the
                   jump table.  This will instrument the number of
                   times the switch statement is executed.  */
@@ -752,16 +776,34 @@ branch_prob (f, dump_file)
              tablejump = pattern;
            else if (GET_CODE (pattern) == RETURN)
              dest = num_blocks - 1;
+           else if (GET_CODE (pattern) != SET)
+             abort ();
            else if ((tem = SET_SRC (pattern))
                     && GET_CODE (tem) == LABEL_REF)
              dest = label_to_bb[CODE_LABEL_NUMBER (XEXP (tem, 0))];
+           /* Recognize HPPA table jump entry.  This code is similar to
+              the code above in the PARALLEL case.  */
+           else if (GET_CODE (tem) == PLUS
+                    && GET_CODE (XEXP (tem, 0)) == MEM
+                    && GET_CODE (XEXP (XEXP (tem, 0), 0)) == PLUS
+                    && GET_CODE (XEXP (XEXP (XEXP (tem, 0), 0), 0)) == PC
+                    && GET_CODE (XEXP (tem, 1)) == LABEL_REF
+                    && tablejump_entry_p (insn, XEXP (tem, 1)))
+             dest = label_to_bb[CODE_LABEL_NUMBER (XEXP (XEXP (tem, 1), 0))];
+           /* Recognize the MIPS table jump entry.  */
+           else if (GET_CODE (tem) == PLUS
+                    && GET_CODE (XEXP (tem, 0)) == REG
+                    && GET_CODE (XEXP (tem, 1)) == LABEL_REF
+                    && tablejump_entry_p (insn, XEXP (tem, 1)))
+             dest = label_to_bb[CODE_LABEL_NUMBER (XEXP (XEXP (tem, 1), 0))];
            else
              {
                rtx label_ref;
 
-               /* Must be an IF_THEN_ELSE branch.  */
+               /* Must be an IF_THEN_ELSE branch.  If it isn't, assume it
+                  is a computed goto, which aren't supported yet.  */
                if (GET_CODE (tem) != IF_THEN_ELSE)
-                 abort ();
+                 fatal ("-fprofile-arcs does not support computed gotos");
                if (XEXP (tem, 1) != pc_rtx)
                  label_ref = XEXP (tem, 1);
                else
@@ -1649,7 +1691,8 @@ output_func_start_profiler ()
   /* Reset flag_inline_functions to its original value.  */
   flag_inline_functions = save_flag_inline_functions;
 
-  fflush (asm_out_file);
+  if (! quiet_flag)
+    fflush (asm_out_file);
   current_function_decl = NULL_TREE;
 
   assemble_constructor (IDENTIFIER_POINTER (DECL_NAME (fndecl)));