Index: gcc/rtl.h
===================================================================
--- gcc/rtl.h	2012-11-03 19:12:42.026369032 +0000
+++ gcc/rtl.h	2012-11-03 19:13:13.019368954 +0000
@@ -2573,6 +2573,41 @@ extern rtx make_compound_operation (rtx,
 extern void delete_dead_jumptables (void);
 
 /* In sched-vis.c.  */
+extern int printed_rtl_count;
+
+/* Represents an obstack-allocated rtl debugging string.  The global
+   printed_rtl_count variable counts the number of strings still in use.  */
+class printed_rtl {
+public:
+  printed_rtl (char *string)
+  : string_ (string)
+  {
+    printed_rtl_count++;
+  }
+
+  printed_rtl (const printed_rtl &other)
+  : string_ ((&other)->string_)
+  {
+    printed_rtl_count++;
+  }
+
+  ~printed_rtl ()
+  {
+    printed_rtl_count--;
+  }
+
+  const char *str () const
+  {
+    return string_;
+  }
+
+  const char *str (size_t limit);
+
+private:
+  char *string_;
+};
+
+extern printed_rtl slim_rtx_string (const_rtx, int);
 extern void debug_bb_n_slim (int);
 extern void debug_bb_slim (struct basic_block_def *);
 extern void print_value_slim (FILE *, const_rtx, int);
@@ -2580,6 +2615,13 @@ extern void debug_rtl_slim (FILE *, cons
 extern void dump_insn_slim (FILE *f, const_rtx x);
 extern void debug_insn_slim (const_rtx x);
 
+/* A "slim" string represention of X, for debugging purposes.
+   V selects between verbose and terse output.  */
+#define SLIM_RTX_STRING(X, V) (slim_rtx_string (X, V).str ())
+
+/* Like SLIM_RTX_STRING, but limit the string to LIMIT characters.  */
+#define SLIM_RTX_STRINGN(X, V, LIMIT) (slim_rtx_string (X, V).str (LIMIT))
+
 /* In sched-rgn.c.  */
 extern void schedule_insns (void);
 
Index: gcc/sched-int.h
===================================================================
--- gcc/sched-int.h	2012-11-03 19:12:42.026369032 +0000
+++ gcc/sched-int.h	2012-11-03 19:13:13.111368956 +0000
@@ -1587,11 +1587,5 @@ extern void sd_debug_lists (rtx, sd_list
 
 #endif /* INSN_SCHEDULING */
 
-/* Functions in sched-vis.c.  These must be outside INSN_SCHEDULING as
-   sched-vis.c is compiled always.  */
-extern void print_insn (char *, const_rtx, int);
-extern void print_pattern (char *, const_rtx, int);
-extern void print_value (char *, const_rtx, int);
-
 #endif /* GCC_SCHED_INT_H */
 
Index: gcc/sched-vis.c
===================================================================
--- gcc/sched-vis.c	2012-11-03 19:12:42.026369032 +0000
+++ gcc/sched-vis.c	2012-11-03 19:46:49.300364022 +0000
@@ -34,27 +34,133 @@ Software Foundation; either version 3, o
 #include "sched-int.h"
 #include "dumpfile.h"	/* for the TDF_* flags */
 
-static char *safe_concat (char *, char *, const char *);
+/* An obstack used for allocating debug strings.  */
+static obstack vis_obstack;
 
-#define BUF_LEN 2048
+/* The number of debug strings still in use.  */
+int printed_rtl_count;
 
-static char *
-safe_concat (char *buf, char *cur, const char *str)
+/* Trim the string to LIMIT characters and return it.  */
+
+const char *
+printed_rtl::str (size_t limit)
 {
-  char *end = buf + BUF_LEN - 2;	/* Leave room for null.  */
-  int c;
+  if (limit < strlen (string_))
+    string_[limit] = 0;
+  return string_;
+}
 
-  if (cur > end)
-    {
-      *end = '\0';
-      return end;
-    }
+/* Start a new debugging string.  */
+
+static void
+start_print (void)
+{
+  static bool initialized = false;
+  if (!initialized)
+    gcc_obstack_init (&vis_obstack);
+  else if (printed_rtl_count == 0)
+    obstack_free (&vis_obstack, NULL);
+}
+
+/* Finish the current debugging string.  */
+
+static printed_rtl
+finish_print (void)
+{
+  obstack_1grow (&vis_obstack, 0);
+  return printed_rtl ((char *) obstack_finish (&vis_obstack));
+}
+
+static void add_value (const_rtx, int);
+static void add_pattern (const_rtx, int);
+
+/* Add CH to the current debugging string.  */
+
+static inline void
+add_char (char ch)
+{
+  obstack_1grow (&vis_obstack, ch);
+}
+
+/* Add STRING to the current debugging string.  */
+
+static inline void
+add_string (const char *string)
+{
+  obstack_grow (&vis_obstack, string, strlen (string));
+}
+
+/* Add VALUE to the current debugging string, printing it as a signed
+   decimal number.  */
+
+static void
+add_signed (HOST_WIDE_INT value)
+{
+  char tmp[HOST_BITS_PER_WIDE_INT + sizeof (HOST_WIDE_INT_PRINT_DEC)];
+  sprintf (tmp, HOST_WIDE_INT_PRINT_DEC, value);
+  add_string (tmp);
+}
+
+/* Add VALUE to the current debugging string, printing it as an unsigned
+   decimal number.  */
+
+static void
+add_unsigned (unsigned HOST_WIDE_INT value)
+{
+  char tmp[HOST_BITS_PER_WIDE_INT + sizeof (HOST_WIDE_INT_PRINT_UNSIGNED)];
+  sprintf (tmp, HOST_WIDE_INT_PRINT_UNSIGNED, value);
+  add_string (tmp);
+}
+
+/* Add VALUE to the current debugging string, printing it in hex.  */
+
+static void
+add_hex (unsigned HOST_WIDE_INT value)
+{
+  char tmp[HOST_BITS_PER_WIDE_INT + sizeof (HOST_WIDE_INT_PRINT_HEX)];
+  sprintf (tmp, HOST_WIDE_INT_PRINT_HEX, value);
+  add_string (tmp);
+}
+
+/* Add VALUE to the current debugging string.  */
+
+static void
+add_real (const REAL_VALUE_TYPE *value)
+{
+  char buf[100];
+  real_to_decimal (buf, value, sizeof (buf), 0, 1);
+  add_string (buf);
+}
+
+/* Add VALUE to the current debugging string.  */
+
+static void
+add_fixed (const FIXED_VALUE_TYPE *value)
+{
+  char buf[100];
+  fixed_to_decimal (buf, value, sizeof (buf));
+  add_string (buf);
+}
 
-  while (cur < end && (c = *str++) != '\0')
-    *cur++ = c;
+/* Add a prefix for instruction INSN to the current debugging string.
+   VERBOSE says whether we want extra information to be printed.  */
 
-  *cur = '\0';
-  return cur;
+static void
+add_insn_uid_prefix (const_rtx insn, int verbose)
+{
+#ifdef INSN_SCHEDULING
+  if (verbose && current_sched_info && NONDEBUG_INSN_P (insn))
+    {
+      add_string ((*current_sched_info->print_insn) (insn, 1));
+      add_string (": ");
+    }
+  else
+#endif
+    {
+      char buf[HOST_BITS_PER_INT + sizeof (" : ")];
+      sprintf (buf, " %4d: ", INSN_UID (insn));
+      add_string (buf);
+    }
 }
 
 /* This recognizes rtx, I classified as expressions.  These are always
@@ -62,11 +168,9 @@ safe_concat (char *buf, char *cur, const
    may be stored in objects representing values.  */
 
 static void
-print_exp (char *buf, const_rtx x, int verbose)
+add_exp (const_rtx x, int verbose)
 {
-  char tmp[BUF_LEN];
   const char *st[4];
-  char *cur = buf;
   const char *fun = (char *) 0;
   const char *sep;
   rtx op[4];
@@ -349,21 +453,19 @@ print_exp (char *buf, const_rtx x, int v
     case UNSPEC:
     case UNSPEC_VOLATILE:
       {
-	cur = safe_concat (buf, cur, "unspec");
+	add_string ("unspec");
 	if (GET_CODE (x) == UNSPEC_VOLATILE)
-	  cur = safe_concat (buf, cur, "/v");
-	cur = safe_concat (buf, cur, "[");
+	  add_string ("/v");
+	add_char ('[');
 	sep = "";
 	for (i = 0; i < XVECLEN (x, 0); i++)
 	  {
-	    print_pattern (tmp, XVECEXP (x, 0, i), verbose);
-	    cur = safe_concat (buf, cur, sep);
-	    cur = safe_concat (buf, cur, tmp);
+	    add_string (sep);
+	    add_pattern (XVECEXP (x, 0, i), verbose);
 	    sep = ",";
 	  }
-	cur = safe_concat (buf, cur, "] ");
-	sprintf (tmp, "%d", XINT (x, 1));
-	cur = safe_concat (buf, cur, tmp);
+	add_string ("] ");
+	add_signed (XINT (x, 1));
       }
       break;
     default:
@@ -400,103 +502,92 @@ print_exp (char *buf, const_rtx x, int v
   /* Print this as a function?  */
   if (fun)
     {
-      cur = safe_concat (buf, cur, fun);
-      cur = safe_concat (buf, cur, "(");
+      add_string (fun);
+      add_char ('(');
     }
 
   for (i = 0; i < 4; i++)
     {
       if (st[i])
-	cur = safe_concat (buf, cur, st[i]);
+	add_string (st[i]);
 
       if (op[i])
 	{
 	  if (fun && i != 0)
-	    cur = safe_concat (buf, cur, ",");
-
-	  print_value (tmp, op[i], verbose);
-	  cur = safe_concat (buf, cur, tmp);
+	    add_char (',');
+	  add_value (op[i], verbose);
 	}
     }
 
   if (fun)
-    cur = safe_concat (buf, cur, ")");
-}		/* print_exp */
+    add_char (')');
+}
 
 /* Prints rtxes, I customarily classified as values.  They're constants,
    registers, labels, symbols and memory accesses.  */
 
-void
-print_value (char *buf, const_rtx x, int verbose)
+static void
+add_value (const_rtx x, int verbose)
 {
-  char t[BUF_LEN];
-  char *cur = buf;
-
   if (!x)
     {
-      safe_concat (buf, buf, "(nil)");
+      add_string ("(nil)");
       return;
     }
   switch (GET_CODE (x))
     {
     case CONST_INT:
-      sprintf (t, HOST_WIDE_INT_PRINT_HEX,
-	       (unsigned HOST_WIDE_INT) INTVAL (x));
-      cur = safe_concat (buf, cur, t);
+      add_hex (INTVAL (x));
       break;
     case CONST_DOUBLE:
       if (FLOAT_MODE_P (GET_MODE (x)))
-	real_to_decimal (t, CONST_DOUBLE_REAL_VALUE (x), sizeof (t), 0, 1);
+	add_real (CONST_DOUBLE_REAL_VALUE (x));
       else
-	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);
+	{
+	  add_char ('<');
+	  add_hex (CONST_DOUBLE_LOW (x));
+	  add_char (',');
+	  add_hex (CONST_DOUBLE_HIGH (x));
+	  add_char ('>');
+	}
       break;
     case CONST_FIXED:
-      fixed_to_decimal (t, CONST_FIXED_VALUE (x), sizeof (t));
-      cur = safe_concat (buf, cur, t);
+      add_fixed (CONST_FIXED_VALUE (x));
       break;
     case CONST_STRING:
-      cur = safe_concat (buf, cur, "\"");
-      cur = safe_concat (buf, cur, XSTR (x, 0));
-      cur = safe_concat (buf, cur, "\"");
+      add_char ('"');
+      add_string (XSTR (x, 0));
+      add_char ('"');
       break;
     case SYMBOL_REF:
-      cur = safe_concat (buf, cur, "`");
-      cur = safe_concat (buf, cur, XSTR (x, 0));
-      cur = safe_concat (buf, cur, "'");
+      add_char ('`');
+      add_string (XSTR (x, 0));
+      add_char ('\'');
       break;
     case LABEL_REF:
-      sprintf (t, "L%d", INSN_UID (XEXP (x, 0)));
-      cur = safe_concat (buf, cur, t);
+      add_char ('L');
+      add_unsigned (INSN_UID (XEXP (x, 0)));
       break;
     case CONST:
-      print_value (t, XEXP (x, 0), verbose);
-      cur = safe_concat (buf, cur, "const(");
-      cur = safe_concat (buf, cur, t);
-      cur = safe_concat (buf, cur, ")");
-      break;
     case HIGH:
-      print_value (t, XEXP (x, 0), verbose);
-      cur = safe_concat (buf, cur, "high(");
-      cur = safe_concat (buf, cur, t);
-      cur = safe_concat (buf, cur, ")");
+    case STRICT_LOW_PART:
+      add_string (GET_RTX_NAME (GET_CODE (x)));
+      add_char ('(');
+      add_value (XEXP (x, 0), verbose);
+      add_char (')');
       break;
     case REG:
       if (REGNO (x) < FIRST_PSEUDO_REGISTER)
 	{
 	  int c = reg_names[REGNO (x)][0];
 	  if (ISDIGIT (c))
-	    cur = safe_concat (buf, cur, "%");
-
-	  cur = safe_concat (buf, cur, reg_names[REGNO (x)]);
+	    add_char ('%');
+	  add_string (reg_names[REGNO (x)]);
 	}
       else
 	{
-	  sprintf (t, "r%d", REGNO (x));
-	  cur = safe_concat (buf, cur, t);
+	  add_char ('r');
+	  add_unsigned (REGNO (x));
 	}
       if (verbose
 #ifdef INSN_SCHEDULING
@@ -504,184 +595,117 @@ print_value (char *buf, const_rtx x, int
 #endif
 	 )
 	{
-	  sprintf (t, ":%s", GET_MODE_NAME (GET_MODE (x)));
-	  cur = safe_concat (buf, cur, t);
+	  add_char (':');
+	  add_string (GET_MODE_NAME (GET_MODE (x)));
 	}
       break;
     case SUBREG:
-      print_value (t, SUBREG_REG (x), verbose);
-      cur = safe_concat (buf, cur, t);
-      sprintf (t, "#%d", SUBREG_BYTE (x));
-      cur = safe_concat (buf, cur, t);
-      break;
-    case STRICT_LOW_PART:
-      print_value (t, XEXP (x, 0), verbose);
-      cur = safe_concat (buf, cur, "strict_low_part(");
-      cur = safe_concat (buf, cur, t);
-      cur = safe_concat (buf, cur, ")");
+      add_value (SUBREG_REG (x), verbose);
+      add_char ('#');
+      add_signed (SUBREG_BYTE (x));
       break;
     case SCRATCH:
-      cur = safe_concat (buf, cur, "scratch");
-      break;
     case CC0:
-      cur = safe_concat (buf, cur, "cc0");
-      break;
     case PC:
-      cur = safe_concat (buf, cur, "pc");
+      add_string (GET_RTX_NAME (GET_CODE (x)));
       break;
     case MEM:
-      print_value (t, XEXP (x, 0), verbose);
-      cur = safe_concat (buf, cur, "[");
-      cur = safe_concat (buf, cur, t);
-      cur = safe_concat (buf, cur, "]");
+      add_char ('[');
+      add_value (XEXP (x, 0), verbose);
+      add_char (']');
       break;
     case DEBUG_EXPR:
-      sprintf (t, "D#%i", DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x)));
-      cur = safe_concat (buf, cur, t);
+      add_string ("D#");
+      add_unsigned (DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x)));
       break;
     default:
-      print_exp (t, x, verbose);
-      cur = safe_concat (buf, cur, t);
+      add_exp (x, verbose);
       break;
     }
-}				/* print_value */
-
-/* Print X, an RTL value node, to file F in slim format.  Include
-   additional information if VERBOSE is nonzero.
-
-   Value nodes are constants, registers, labels, symbols and
-   memory.  */
-
-void
-print_value_slim (FILE *f, const_rtx x, int verbose)
-{
-  char buf[BUF_LEN];
-
-  print_value (buf, x, verbose);
-  fprintf (f, "%s", buf);
 }
 
 /* The next step in insn detalization, its pattern recognition.  */
 
-void
-print_pattern (char *buf, const_rtx x, int verbose)
+static void
+add_pattern (const_rtx x, int verbose)
 {
-  char t1[BUF_LEN], t2[BUF_LEN], t3[BUF_LEN];
-
   switch (GET_CODE (x))
     {
     case SET:
-      print_value (t1, SET_DEST (x), verbose);
-      print_value (t2, SET_SRC (x), verbose);
-      sprintf (buf, "%s=%s", t1, t2);
+      add_value (SET_DEST (x), verbose);
+      add_char ('=');
+      add_value (SET_SRC (x), verbose);
       break;
     case RETURN:
     case SIMPLE_RETURN:
     case EH_RETURN:
-      sprintf (buf, GET_RTX_NAME (GET_CODE (x)));
+      add_string (GET_RTX_NAME (GET_CODE (x)));
       break;
     case CALL:
-      print_exp (buf, x, verbose);
+      add_exp (x, verbose);
       break;
     case CLOBBER:
-      print_value (t1, XEXP (x, 0), verbose);
-      sprintf (buf, "clobber %s", t1);
-      break;
     case USE:
-      print_value (t1, XEXP (x, 0), verbose);
-      sprintf (buf, "use %s", t1);
+      add_string (GET_RTX_NAME (GET_CODE (x)));
+      add_char (' ');
+      add_value (XEXP (x, 0), verbose);
       break;
     case VAR_LOCATION:
-      print_value (t1, PAT_VAR_LOCATION_LOC (x), verbose);
-      sprintf (buf, "loc %s", t1);
+      add_string ("loc ");
+      add_value (PAT_VAR_LOCATION_LOC (x), verbose);
       break;
     case COND_EXEC:
+      add_char ('(');
       if (GET_CODE (COND_EXEC_TEST (x)) == NE
 	  && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
-	print_value (t1, XEXP (COND_EXEC_TEST (x), 0), verbose);
+	add_value (XEXP (COND_EXEC_TEST (x), 0), verbose);
       else if (GET_CODE (COND_EXEC_TEST (x)) == EQ
 	       && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
 	{
-	  t1[0] = '!';
-	  print_value (t1 + 1, XEXP (COND_EXEC_TEST (x), 0), verbose);
+	  add_char ('!');
+	  add_value (XEXP (COND_EXEC_TEST (x), 0), verbose);
 	}
       else
-	print_value (t1, COND_EXEC_TEST (x), verbose);
-      print_pattern (t2, COND_EXEC_CODE (x), verbose);
-      sprintf (buf, "(%s) %s", t1, t2);
+	add_value (COND_EXEC_TEST (x), verbose);
+      add_string (") ");
+      add_pattern (COND_EXEC_CODE (x), verbose);
       break;
     case PARALLEL:
-      {
-	int i;
-
-	sprintf (t1, "{");
-	for (i = 0; i < XVECLEN (x, 0); i++)
-	  {
-	    print_pattern (t2, XVECEXP (x, 0, i), verbose);
-	    sprintf (t3, "%s%s;", t1, t2);
-	    strcpy (t1, t3);
-	  }
-	sprintf (buf, "%s}", t1);
-      }
+      add_char ('{');
+      for (int i = 0; i < XVECLEN (x, 0); i++)
+	{
+	  add_pattern (XVECEXP (x, 0, i), verbose);
+	  add_char (';');
+	}
+      add_char ('}');
       break;
     case SEQUENCE:
-      {
-	int i;
-
-	sprintf (t1, "sequence{");
-	for (i = 0; i < XVECLEN (x, 0); i++)
-	  {
-	    print_pattern (t2, XVECEXP (x, 0, i), verbose);
-	    sprintf (t3, "%s%s;", t1, t2);
-	    strcpy (t1, t3);
-	  }
-	sprintf (buf, "%s}", t1);
-      }
+      add_string ("sequence{");
+      for (int i = 0; i < XVECLEN (x, 0); i++)
+	{
+	  add_pattern (XVECEXP (x, 0, i), verbose);
+	  add_char (';');
+	}
+      add_char ('}');
       break;
     case ASM_INPUT:
-      sprintf (buf, "asm {%s}", XSTR (x, 0));
+      add_string ("asm {");
+      add_string (XSTR (x, 0));
+      add_char ('}');
       break;
     case ADDR_VEC:
-      /* Fall through.  */
     case ADDR_DIFF_VEC:
-      print_value (buf, XEXP (x, 0), verbose);
+      add_value (XEXP (x, 0), verbose);
       break;
     case TRAP_IF:
-      print_value (t1, TRAP_CONDITION (x), verbose);
-      sprintf (buf, "trap_if %s", t1);
-      break;
-    case UNSPEC:
-      {
-	int i;
-
-	sprintf (t1, "unspec{");
-	for (i = 0; i < XVECLEN (x, 0); i++)
-	  {
-	    print_pattern (t2, XVECEXP (x, 0, i), verbose);
-	    sprintf (t3, "%s%s;", t1, t2);
-	    strcpy (t1, t3);
-	  }
-	sprintf (buf, "%s}", t1);
-      }
-      break;
-    case UNSPEC_VOLATILE:
-      {
-	int i;
-
-	sprintf (t1, "unspec/v{");
-	for (i = 0; i < XVECLEN (x, 0); i++)
-	  {
-	    print_pattern (t2, XVECEXP (x, 0, i), verbose);
-	    sprintf (t3, "%s%s;", t1, t2);
-	    strcpy (t1, t3);
-	  }
-	sprintf (buf, "%s}", t1);
-      }
+      add_string ("trap_if ");
+      add_value (TRAP_CONDITION (x), verbose);
       break;
     default:
-      print_value (buf, x, verbose);
+      add_value (x, verbose);
+      break;
     }
-}				/* print_pattern */
+}
 
 /* This is the main function in rtl visualization mechanism. It
    accepts an rtx and tries to recognize it as an insn, then prints it
@@ -690,120 +714,108 @@ print_pattern (char *buf, const_rtx x, i
    (Probably the last "option" should be extended somehow, since it
    depends now on sched.c inner variables ...)  */
 
-void
-print_insn (char *buf, const_rtx x, int verbose)
+static void
+add_insn (const_rtx x, int verbose)
 {
-  char t[BUF_LEN];
-  const_rtx insn = x;
-
   switch (GET_CODE (x))
     {
     case INSN:
-      print_pattern (t, PATTERN (x), verbose);
-#ifdef INSN_SCHEDULING
-      if (verbose && current_sched_info)
-	sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1),
-		 t);
-      else
-#endif
-	sprintf (buf, " %4d %s", INSN_UID (x), t);
-      break;
-
-    case DEBUG_INSN:
-      {
-	const char *name = "?";
-
-	if (DECL_P (INSN_VAR_LOCATION_DECL (insn)))
-	  {
-	    tree id = DECL_NAME (INSN_VAR_LOCATION_DECL (insn));
-	    char idbuf[32];
-	    if (id)
-	      name = IDENTIFIER_POINTER (id);
-	    else if (TREE_CODE (INSN_VAR_LOCATION_DECL (insn))
-		     == DEBUG_EXPR_DECL)
-	      {
-		sprintf (idbuf, "D#%i",
-			 DEBUG_TEMP_UID (INSN_VAR_LOCATION_DECL (insn)));
-		name = idbuf;
-	      }
-	    else
-	      {
-		sprintf (idbuf, "D.%i",
-			 DECL_UID (INSN_VAR_LOCATION_DECL (insn)));
-		name = idbuf;
-	      }
-	  }
-	if (VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (insn)))
-	  sprintf (buf, " %4d: debug %s optimized away", INSN_UID (insn), name);
-	else
-	  {
-	    print_pattern (t, INSN_VAR_LOCATION_LOC (insn), verbose);
-	    sprintf (buf, " %4d: debug %s => %s", INSN_UID (insn), name, t);
-	  }
-      }
-      break;
-
     case JUMP_INSN:
-      print_pattern (t, PATTERN (x), verbose);
-#ifdef INSN_SCHEDULING
-      if (verbose && current_sched_info)
-	sprintf (buf, "%s: jump %s", (*current_sched_info->print_insn) (x, 1),
-		 t);
-      else
-#endif
-	sprintf (buf, " %4d %s", INSN_UID (x), t);
+      add_insn_uid_prefix (x, verbose);
+      add_pattern (PATTERN (x), verbose);
       break;
-    case CALL_INSN:
-      x = PATTERN (insn);
-      if (GET_CODE (x) == PARALLEL)
+    case DEBUG_INSN:
+      add_insn_uid_prefix (x, verbose);
+      add_string ("debug ");
+      if (DECL_P (INSN_VAR_LOCATION_DECL (x)))
 	{
-	  x = XVECEXP (x, 0, 0);
-	  print_pattern (t, x, verbose);
+	  tree id = DECL_NAME (INSN_VAR_LOCATION_DECL (x));
+	  if (id)
+	    add_string (IDENTIFIER_POINTER (id));
+	  else if (TREE_CODE (INSN_VAR_LOCATION_DECL (x)) == DEBUG_EXPR_DECL)
+	    {
+	      add_string ("D#");
+	      add_unsigned (DEBUG_TEMP_UID (INSN_VAR_LOCATION_DECL (x)));
+	    }
+	  else
+	    {
+	      add_string ("D.");
+	      add_unsigned (DECL_UID (INSN_VAR_LOCATION_DECL (x)));
+	    }
 	}
       else
-	strcpy (t, "call <...>");
-#ifdef INSN_SCHEDULING
-      if (verbose && current_sched_info)
-	sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (insn, 1), t);
+	add_char ('?');
+      if (VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (x)))
+	add_string (" optimized away");
       else
-#endif
-	sprintf (buf, " %4d %s", INSN_UID (insn), t);
+	{
+	  add_string (" => ");
+	  add_pattern (INSN_VAR_LOCATION_LOC (x), verbose);
+	}
+      break;
+    case CALL_INSN:
+      add_insn_uid_prefix (x, verbose);
+      x = PATTERN (x);
+      if (GET_CODE (x) == PARALLEL)
+	x = XVECEXP (x, 0, 0);
+      add_pattern (x, verbose);
       break;
     case CODE_LABEL:
-      sprintf (buf, "L%d:", INSN_UID (x));
+      add_char ('L');
+      add_unsigned (INSN_UID (x));
+      add_char (':');
       break;
     case BARRIER:
-      sprintf (buf, "i%4d: barrier", INSN_UID (x));
+      add_insn_uid_prefix (x, verbose);
+      add_string ("barrier");
       break;
     case NOTE:
-      sprintf (buf, " %4d %s", INSN_UID (x),
-	       GET_NOTE_INSN_NAME (NOTE_KIND (x)));
+      add_insn_uid_prefix (x, verbose);
+      add_string (GET_NOTE_INSN_NAME (NOTE_KIND (x)));
       break;
     default:
-      sprintf (buf, "i%4d  <What %s?>", INSN_UID (x),
-	       GET_RTX_NAME (GET_CODE (x)));
+      add_pattern (x, verbose);
+      break;
     }
-}				/* print_insn */
+}
+
+/* Return a string representation of X, for debugging purposes.
+   Include additional information if VERBOSE is nonzero.  */
+
+printed_rtl
+slim_rtx_string (const_rtx x, int verbose)
+{
+  start_print ();
+  add_insn (x, verbose);
+  return finish_print ();
+}
+
+/* Print X, an RTL value node, to file F in slim format.  Include
+   additional information if VERBOSE is nonzero.  */
+
+void
+print_value_slim (FILE *f, const_rtx x, int verbose)
+{
+  fprintf (f, "%s", SLIM_RTX_STRING (x, verbose));
+}
 
 /* Emit a slim dump of X (an insn) to the file F, including any register
    note attached to the instruction.  */
 void
 dump_insn_slim (FILE *f, const_rtx x)
 {
-  char t[BUF_LEN + 32];
   rtx note;
 
-  print_insn (t, x, 1);
   fputs (print_rtx_head, f);
-  fputs (t, f);
+  fputs (SLIM_RTX_STRING (x, 1), f);
   putc ('\n', f);
   if (INSN_P (x) && REG_NOTES (x))
     for (note = REG_NOTES (x); note; note = XEXP (note, 1))
       {
 	fputs (print_rtx_head, f);
-        print_pattern (t, XEXP (note, 0), 1);
 	fprintf (f, "      %s: %s\n",
-		 GET_REG_NOTE_NAME (REG_NOTE_KIND (note)), t);
+		 GET_REG_NOTE_NAME (REG_NOTE_KIND (note)),
+		 SLIM_RTX_STRING (XEXP (note, 0), 1));
       }
 }
 
Index: gcc/haifa-sched.c
===================================================================
--- gcc/haifa-sched.c	2012-11-03 19:12:42.026369032 +0000
+++ gcc/haifa-sched.c	2012-11-03 19:13:13.914368953 +0000
@@ -2171,8 +2171,6 @@ model_recompute (rtx insn)
 
 	    if (sched_verbose >= 5)
 	      {
-		char buf[2048];
-
 		if (!print_p)
 		  {
 		    fprintf (sched_dump, MODEL_BAR);
@@ -2182,9 +2180,9 @@ model_recompute (rtx insn)
 		    print_p = true;
 		  }
 
-		print_pattern (buf, PATTERN (insn), 0);
 		fprintf (sched_dump, ";;\t\t| %3d %4d %-30s ",
-			 point, INSN_UID (insn), buf);
+			 point, INSN_UID (insn),
+			 SLIM_RTX_STRING (PATTERN (insn), 0));
 		for (pci = 0; pci < ira_pressure_classes_num; pci++)
 		  {
 		    cl = ira_pressure_classes[pci];
@@ -3346,18 +3344,16 @@ model_record_pressures (struct model_ins
   point = model_index (insn->insn);
   if (sched_verbose >= 2)
     {
-      char buf[2048];
-
       if (point == 0)
 	{
 	  fprintf (sched_dump, "\n;;\tModel schedule:\n;;\n");
 	  fprintf (sched_dump, ";;\t| idx insn | mpri hght dpth prio |\n");
 	}
-      print_pattern (buf, PATTERN (insn->insn), 0);
       fprintf (sched_dump, ";;\t| %3d %4d | %4d %4d %4d %4d | %-30s ",
 	       point, INSN_UID (insn->insn), insn->model_priority,
 	       insn->depth + insn->alap, insn->depth,
-	       INSN_PRIORITY (insn->insn), buf);
+	       INSN_PRIORITY (insn->insn),
+	       SLIM_RTX_STRING (PATTERN (insn->insn), 0));
     }
   calculate_reg_deaths (insn->insn, death);
   reg_pressure = INSN_REG_PRESSURE (insn->insn);
@@ -3718,11 +3714,9 @@ schedule_insn (rtx insn)
   if (sched_verbose >= 1)
     {
       struct reg_pressure_data *pressure_info;
-      char buf[2048];
 
-      print_insn (buf, insn, 0);
-      buf[40] = 0;
-      fprintf (sched_dump, ";;\t%3i--> %-40s:", clock_var, buf);
+      fprintf (sched_dump, ";;\t%3i--> %-40s:", clock_var,
+	       SLIM_RTX_STRINGN (insn, 0, 40));
 
       if (recog_memoized (insn) < 0)
 	fprintf (sched_dump, "nothing");
Index: gcc/sel-sched-dump.c
===================================================================
--- gcc/sel-sched-dump.c	2012-11-03 19:12:42.025369032 +0000
+++ gcc/sel-sched-dump.c	2012-11-03 19:13:14.211368950 +0000
@@ -136,12 +136,7 @@ dump_insn_rtx_1 (rtx insn, int flags)
     sel_print ("%d;", INSN_UID (insn));
 
   if (flags & DUMP_INSN_RTX_PATTERN)
-    {
-      char buf[2048];
-
-      print_insn (buf, insn, 0);
-      sel_print ("%s;", buf);
-    }
+    sel_print ("%s;", SLIM_RTX_STRING (insn, 0));
 
   if (flags & DUMP_INSN_RTX_BBN)
     {
