OSDN Git Service

* gcc.dg/debug/dwarf2/aranges-fnsec-1.c: Add -w to dg-options.
[pf3gnuchains/gcc-fork.git] / gcc / sched-vis.c
index b7544d2..8f45972 100644 (file)
@@ -1,6 +1,6 @@
 /* Instruction scheduling pass.
-   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+   2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
    and currently maintained by, Jim Wilson (wilson@cygnus.com)
 
@@ -8,7 +8,7 @@ This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -17,152 +17,25 @@ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 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.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 \f
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
-#include "toplev.h"
 #include "rtl.h"
-#include "tm_p.h"
-#include "regs.h"
+#include "obstack.h"
 #include "hard-reg-set.h"
 #include "basic-block.h"
-#include "insn-attr.h"
 #include "real.h"
 #include "sched-int.h"
-#include "target.h"
-
-#ifdef INSN_SCHEDULING
-/* target_units bitmask has 1 for each unit in the cpu.  It should be
-   possible to compute this variable from the machine description.
-   But currently it is computed by examining the insn list.  Since
-   this is only needed for visualization, it seems an acceptable
-   solution.  (For understanding the mapping of bits to units, see
-   definition of function_units[] in "insn-attrtab.c".)  The scheduler
-   using only DFA description should never use the following variable.  */
-
-static int target_units = 0;
+#include "tree-pass.h"
 
 static char *safe_concat (char *, char *, const char *);
-static int get_visual_tbl_length (void);
-static void print_exp (char *, rtx, int);
-static void print_value (char *, rtx, int);
-static void print_pattern (char *, rtx, int);
-
-/* Print names of units on which insn can/should execute, for debugging.  */
-
-void
-insn_print_units (rtx insn)
-{
-  int i;
-  int unit = insn_unit (insn);
-
-  if (unit == -1)
-    fprintf (sched_dump, "none");
-  else if (unit >= 0)
-    fprintf (sched_dump, "%s", function_units[unit].name);
-  else
-    {
-      fprintf (sched_dump, "[");
-      for (i = 0, unit = ~unit; unit; i++, unit >>= 1)
-       if (unit & 1)
-         {
-           fprintf (sched_dump, "%s", function_units[i].name);
-           if (unit != 1)
-             fprintf (sched_dump, " ");
-         }
-      fprintf (sched_dump, "]");
-    }
-}
-
-/* MAX_VISUAL_LINES is the maximum number of lines in visualization table
-   of a basic block.  If more lines are needed, table is split to two.
-   n_visual_lines is the number of lines printed so far for a block.
-   visual_tbl contains the block visualization info.
-   vis_no_unit holds insns in a cycle that are not mapped to any unit.  */
-#define MAX_VISUAL_LINES 100
-#define INSN_LEN 30
-int n_visual_lines;
-static unsigned visual_tbl_line_length;
-char *visual_tbl;
-int n_vis_no_unit;
-#define MAX_VISUAL_NO_UNIT 20
-rtx vis_no_unit[MAX_VISUAL_NO_UNIT];
-
-/* Finds units that are in use in this function.  Required only
-   for visualization.  */
-
-void
-init_target_units (void)
-{
-  rtx insn;
-  int unit;
-
-  for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
-    {
-      if (! INSN_P (insn))
-       continue;
-
-      unit = insn_unit (insn);
-
-      if (unit < 0)
-       target_units |= ~unit;
-      else
-       target_units |= (1 << unit);
-    }
-}
-
-/* Return the length of the visualization table.  */
-
-static int
-get_visual_tbl_length (void)
-{
-  int unit, i;
-  int n, n1;
-  char *s;
-
-  if (targetm.sched.use_dfa_pipeline_interface
-      && targetm.sched.use_dfa_pipeline_interface ())
-    {
-      visual_tbl_line_length = 1;
-      return 1; /* Can't return 0 because that will cause problems
-                   with alloca.  */
-    }
-
-  /* Compute length of one field in line.  */
-  s = alloca (INSN_LEN + 6);
-  sprintf (s, "  %33s", "uname");
-  n1 = strlen (s);
-
-  /* Compute length of one line.  */
-  n = strlen (";; ");
-  n += n1;
-  for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
-    if (function_units[unit].bitmask & target_units)
-      for (i = 0; i < function_units[unit].multiplicity; i++)
-       n += n1;
-  n += n1;
-  n += strlen ("\n") + 2;
-
-  visual_tbl_line_length = n;
-
-  /* Compute length of visualization string.  */
-  return (MAX_VISUAL_LINES * n);
-}
-
-/* Init block visualization debugging info.  */
-
-void
-init_block_visualization (void)
-{
-  strcpy (visual_tbl, "");
-  n_visual_lines = 0;
-  n_vis_no_unit = 0;
-}
+static void print_exp (char *, const_rtx, int);
+static void print_value (char *, const_rtx, int);
+static void print_pattern (char *, const_rtx, int);
 
 #define BUF_LEN 2048
 
@@ -190,7 +63,7 @@ safe_concat (char *buf, char *cur, const char *str)
    may be stored in objects representing values.  */
 
 static void
-print_exp (char *buf, rtx x, int verbose)
+print_exp (char *buf, const_rtx x, int verbose)
 {
   char tmp[BUF_LEN];
   const char *st[4];
@@ -457,6 +330,18 @@ print_exp (char *buf, rtx x, int verbose)
       op[0] = XEXP (x, 0);
       st[1] = "++";
       break;
+    case PRE_MODIFY:
+      st[0] = "pre ";
+      op[0] = XEXP (XEXP (x, 1), 0);
+      st[1] = "+=";
+      op[1] = XEXP (XEXP (x, 1), 1);
+      break;
+    case POST_MODIFY:
+      st[0] = "post ";
+      op[0] = XEXP (XEXP (x, 1), 0);
+      st[1] = "+=";
+      op[1] = XEXP (XEXP (x, 1), 1);
+      break;
     case CALL:
       st[0] = "call ";
       op[0] = XEXP (x, 0);
@@ -541,7 +426,7 @@ print_exp (char *buf, rtx x, int verbose)
    registers, labels, symbols and memory accesses.  */
 
 static void
-print_value (char *buf, rtx x, int verbose)
+print_value (char *buf, const_rtx x, int verbose)
 {
   char t[BUF_LEN];
   char *cur = buf;
@@ -556,7 +441,14 @@ print_value (char *buf, rtx x, int verbose)
       if (FLOAT_MODE_P (GET_MODE (x)))
        real_to_decimal (t, CONST_DOUBLE_REAL_VALUE (x), sizeof (t), 0, 1);
       else
-       sprintf (t, "<0x%lx,0x%lx>", (long) XWINT (x, 2), (long) XWINT (x, 3));
+       sprintf (t,
+                "<" HOST_WIDE_INT_PRINT_HEX "," HOST_WIDE_INT_PRINT_HEX ">",
+                (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x),
+                (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (x));
+      cur = safe_concat (buf, cur, t);
+      break;
+    case CONST_FIXED:
+      fixed_to_decimal (t, CONST_FIXED_VALUE (x), sizeof (t));
       cur = safe_concat (buf, cur, t);
       break;
     case CONST_STRING:
@@ -599,6 +491,15 @@ print_value (char *buf, rtx x, int verbose)
          sprintf (t, "r%d", REGNO (x));
          cur = safe_concat (buf, cur, t);
        }
+      if (verbose
+#ifdef INSN_SCHEDULING
+         && !current_sched_info
+#endif
+        )
+       {
+         sprintf (t, ":%s", GET_MODE_NAME (GET_MODE (x)));
+         cur = safe_concat (buf, cur, t);
+       }
       break;
     case SUBREG:
       print_value (t, SUBREG_REG (x), verbose);
@@ -631,7 +532,7 @@ print_value (char *buf, rtx x, int verbose)
 /* The next step in insn detalization, its pattern recognition.  */
 
 static void
-print_pattern (char *buf, rtx x, int verbose)
+print_pattern (char *buf, const_rtx x, int verbose)
 {
   char t1[BUF_LEN], t2[BUF_LEN], t3[BUF_LEN];
 
@@ -687,8 +588,7 @@ print_pattern (char *buf, rtx x, int verbose)
       break;
     case SEQUENCE:
       /* Should never see SEQUENCE codes until after reorg.  */
-      abort ();
-      break;
+      gcc_unreachable ();
     case ASM_INPUT:
       sprintf (buf, "asm {%s}", XSTR (x, 0));
       break;
@@ -751,19 +651,23 @@ print_insn (char *buf, rtx x, int verbose)
     {
     case INSN:
       print_pattern (t, PATTERN (x), verbose);
-      if (verbose)
+#ifdef INSN_SCHEDULING
+      if (verbose && current_sched_info)
        sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1),
                 t);
       else
-       sprintf (buf, "%-4d %s", INSN_UID (x), t);
+#endif
+       sprintf (buf, " %4d %s", INSN_UID (x), t);
       break;
     case JUMP_INSN:
       print_pattern (t, PATTERN (x), verbose);
-      if (verbose)
+#ifdef INSN_SCHEDULING
+      if (verbose && current_sched_info)
        sprintf (buf, "%s: jump %s", (*current_sched_info->print_insn) (x, 1),
                 t);
       else
-       sprintf (buf, "%-4d %s", INSN_UID (x), t);
+#endif
+       sprintf (buf, " %4d %s", INSN_UID (x), t);
       break;
     case CALL_INSN:
       x = PATTERN (insn);
@@ -774,172 +678,86 @@ print_insn (char *buf, rtx x, int verbose)
        }
       else
        strcpy (t, "call <...>");
-      if (verbose)
+#ifdef INSN_SCHEDULING
+      if (verbose && current_sched_info)
        sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1), t);
       else
-       sprintf (buf, "%-4d %s", INSN_UID (insn), t);
+#endif
+       sprintf (buf, " %4d %s", INSN_UID (insn), t);
       break;
     case CODE_LABEL:
       sprintf (buf, "L%d:", INSN_UID (x));
       break;
     case BARRIER:
-      sprintf (buf, "i% 4d: barrier", INSN_UID (x));
+      sprintf (buf, "i%4d: barrier", INSN_UID (x));
       break;
     case NOTE:
-      if (NOTE_LINE_NUMBER (x) > 0)
-       sprintf (buf, "%4d note \"%s\" %d", INSN_UID (x),
-                NOTE_SOURCE_FILE (x), NOTE_LINE_NUMBER (x));
-      else
-       sprintf (buf, "%4d %s", INSN_UID (x),
-                GET_NOTE_INSN_NAME (NOTE_LINE_NUMBER (x)));
+      sprintf (buf, " %4d %s", INSN_UID (x),
+              GET_NOTE_INSN_NAME (NOTE_KIND (x)));
       break;
     default:
-      if (verbose)
-       {
-         sprintf (buf, "Not an INSN at all\n");
-         debug_rtx (x);
-       }
-      else
-       sprintf (buf, "i%-4d  <What?>", INSN_UID (x));
+      sprintf (buf, "i%4d  <What %s?>", INSN_UID (x),
+              GET_RTX_NAME (GET_CODE (x)));
     }
 }                              /* print_insn */
 
-/* Print visualization debugging info.  The scheduler using only DFA
-   description should never use the following function.  */
 
+/* Emit a slim dump of X (an insn) to the file F, including any register
+   note attached to the instruction.  */
 void
-print_block_visualization (const char *s)
+dump_insn_slim (FILE *f, rtx x)
 {
-  int unit, i;
-
-  /* Print header.  */
-  fprintf (sched_dump, "\n;;   ==================== scheduling visualization %s \n", s);
-
-  /* Print names of units.  */
-  fprintf (sched_dump, ";;   %-8s", "clock");
-  for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
-    if (function_units[unit].bitmask & target_units)
-      for (i = 0; i < function_units[unit].multiplicity; i++)
-       fprintf (sched_dump, "  %-33s", function_units[unit].name);
-  fprintf (sched_dump, "  %-8s\n", "no-unit");
-
-  fprintf (sched_dump, ";;   %-8s", "=====");
-  for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
-    if (function_units[unit].bitmask & target_units)
-      for (i = 0; i < function_units[unit].multiplicity; i++)
-       fprintf (sched_dump, "  %-33s", "==============================");
-  fprintf (sched_dump, "  %-8s\n", "=======");
-
-  /* Print insns in each cycle.  */
-  fprintf (sched_dump, "%s\n", visual_tbl);
+  char t[BUF_LEN + 32];
+  rtx note;
+
+  print_insn (t, x, 1);
+  fputs (t, f);
+  putc ('\n', f);
+  if (INSN_P (x) && REG_NOTES (x))
+    for (note = REG_NOTES (x); note; note = XEXP (note, 1))
+      {
+        print_value (t, XEXP (note, 0), 1);
+       fprintf (f, "      %s: %s\n",
+                GET_REG_NOTE_NAME (REG_NOTE_KIND (note)), t);
+      }
 }
 
-/* Print insns in the 'no_unit' column of visualization.  */
-
+/* Emit a slim dump of X (an insn) to stderr.  */
 void
-visualize_no_unit (rtx insn)
+debug_insn_slim (rtx x)
 {
-  if (n_vis_no_unit < MAX_VISUAL_NO_UNIT)
-    {
-      vis_no_unit[n_vis_no_unit] = insn;
-      n_vis_no_unit++;
-    }
+  dump_insn_slim (stderr, x);
 }
 
-/* Print insns scheduled in clock, for visualization.  */
-
+/* Provide a slim dump the instruction chain starting at FIRST to F, honoring
+   the dump flags given in FLAGS.  Currently, TDF_BLOCKS and TDF_DETAILS
+   include more information on the basic blocks.  */
 void
-visualize_scheduled_insns (int clock)
+print_rtl_slim_with_bb (FILE *f, rtx first, int flags)
 {
-  int i, unit;
+  basic_block current_bb = NULL;
+  rtx insn;
 
-  /* If no more room, split table into two.  */
-  if (n_visual_lines >= MAX_VISUAL_LINES)
+  for (insn = first; NULL != insn; insn = NEXT_INSN (insn))
     {
-      print_block_visualization ("(incomplete)");
-      init_block_visualization ();
-    }
-
-  n_visual_lines++;
-
-  sprintf (visual_tbl + strlen (visual_tbl), ";;   %-8d", clock);
-  for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
-    if (function_units[unit].bitmask & target_units)
-      for (i = 0; i < function_units[unit].multiplicity; i++)
+      if ((flags & TDF_BLOCKS)
+         && (INSN_P (insn) || GET_CODE (insn) == NOTE)
+         && BLOCK_FOR_INSN (insn)
+         && !current_bb)
        {
-         int instance = unit + i * FUNCTION_UNITS_SIZE;
-         rtx insn = get_unit_last_insn (instance);
-
-         /* Print insns that still keep the unit busy.  */
-         if (insn
-             && actual_hazard_this_instance (unit, instance, insn, clock, 0))
-           {
-             char str[BUF_LEN];
-             print_insn (str, insn, 0);
-             str[INSN_LEN] = '\0';
-             sprintf (visual_tbl + strlen (visual_tbl), "  %-33s", str);
-           }
-         else
-           sprintf (visual_tbl + strlen (visual_tbl), "  %-33s", "------------------------------");
+         current_bb = BLOCK_FOR_INSN (insn);
+         dump_bb_info (current_bb, true, false, flags, ";; ", f);
        }
 
-  /* Print insns that are not assigned to any unit.  */
-  for (i = 0; i < n_vis_no_unit; i++)
-    sprintf (visual_tbl + strlen (visual_tbl), "  %-8d",
-            INSN_UID (vis_no_unit[i]));
-  n_vis_no_unit = 0;
-
-  sprintf (visual_tbl + strlen (visual_tbl), "\n");
-}
+      dump_insn_slim (f, insn);
 
-/* Print stalled cycles.  */
-
-void
-visualize_stall_cycles (int stalls)
-{
-  static const char *const prefix = ";;       ";
-  const char *suffix = "\n";
-  char *p;
-
-  /* If no more room, split table into two.  */
-  if (n_visual_lines >= MAX_VISUAL_LINES)
-    {
-      print_block_visualization ("(incomplete)");
-      init_block_visualization ();
-    }
-
-  n_visual_lines++;
-
-  p = visual_tbl + strlen (visual_tbl);
-  strcpy (p, prefix);
-  p += strlen (prefix);
-
-  if ((unsigned) stalls >
-      visual_tbl_line_length - strlen (prefix) - strlen (suffix))
-    {
-      suffix = "[...]\n";
-      stalls = visual_tbl_line_length - strlen (prefix) - strlen (suffix);
+      if ((flags & TDF_BLOCKS)
+         && current_bb
+         && insn == BB_END (current_bb))
+       {
+         dump_bb_info (current_bb, false, true, flags, ";; ", f);
+         current_bb = NULL;
+       }
     }
-
-  memset (p, '.', stalls);
-  p += stalls;
-
-  strcpy (p, suffix);
-}
-
-/* Allocate data used for visualization during scheduling.  */
-
-void
-visualize_alloc (void)
-{
-  visual_tbl = xmalloc (get_visual_tbl_length ());
 }
 
-/* Free data used for visualization.  */
-
-void
-visualize_free (void)
-{
-  free (visual_tbl);
-}
-#endif