profile.c (branch_prob): Call allocate_reg_info after outputting profile rtl in instr...
[platform/upstream/gcc.git] / gcc / profile.c
index 5d319f4..b06f91b 100644 (file)
@@ -1,5 +1,5 @@
 /* Calculate branch probabilities, and basic block execution counts. 
-   Copyright (C) 1990, 91-94, 97, 1998 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,14 +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>
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
+#include "system.h"
 #include "rtl.h"
 #include "flags.h"
 #include "insn-flags.h"
@@ -58,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.  */
@@ -421,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.
@@ -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;
@@ -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,9 +776,26 @@ 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;
@@ -916,7 +957,10 @@ branch_prob (f, dump_file)
   /* For each arc not on the spanning tree, add counting code as rtl.  */
 
   if (profile_arc_flag)
-    instrument_arcs (f, num_blocks, dump_file);
+    {
+      instrument_arcs (f, num_blocks, dump_file);
+      allocate_reg_info (max_reg_num (), FALSE, FALSE);
+    }
 
   /* Execute the rest only if doing branch probabilities.  */
   if (! flag_branch_probabilities)
@@ -1650,7 +1694,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)));