public inbox for jit@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: [PATCH 08/08] PR/64003 workaround (uninit memory in i386.md)
  2014-01-01  0:00 ` [PATCH 08/08] PR/64003 workaround (uninit memory in i386.md) David Malcolm
@ 2014-01-01  0:00   ` Jeff Law
  2014-01-01  0:00     ` David Malcolm
  0 siblings, 1 reply; 17+ messages in thread
From: Jeff Law @ 2014-01-01  0:00 UTC (permalink / raw)
  To: David Malcolm, gcc-patches, jit

On 11/25/14 18:39, David Malcolm wrote:
> I suspect this is papering over a real problem, but I've been
> applying this workaround locally to keep my valgrind output clean.
>
> gcc/ChangeLog:
> 	PR/64003
> 	* final.c (shorten_branches): Allocate insn_lengths with
> 	XCNEWVEC rather than XNEWVEC; remove subsequent per-element
> 	initialization.
I'd like more information on this one.

My first thought is that something must be creating a new insn after 
shorten_branches is complete or an existing insn that was not on the 
chain when we called shorten-branches, but got threaded onto the chain 
later.  Either would be considered bad in various ways, so we'd like to 
fix it.

Presumably you're not doing an out-of-range access into insn_lengths? 
Right?

Do you have a reasonable testcase for this?

jeff


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 06/08] Avoid overuse of name "buffer" in tree-pretty-print.c
  2014-01-01  0:00 [PATCH 00/08] More memory leak fixes David Malcolm
  2014-01-01  0:00 ` [PATCH 05/08] PR jit/63854: Fix double-initialization within tree-pretty-print.c David Malcolm
@ 2014-01-01  0:00 ` David Malcolm
  2014-01-01  0:00   ` Jeff Law
  2014-01-01  0:00 ` [PATCH 03/08] PR jit/63854: Fix leak in real.c for i386:init_ext_80387_constants David Malcolm
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 17+ messages in thread
From: David Malcolm @ 2014-01-01  0:00 UTC (permalink / raw)
  To: gcc-patches, jit; +Cc: David Malcolm

Various functions in tree-pretty-print.c take a param
  pretty_printer *buffer
and there's also a static pretty_printer *buffer;

Additionally, pretty_printer instances are not buffers; they
*contain* buffers (inasmuch as they have a field "buffer").

This patch renames such params from "buffer" to "pp", and the static
"buffer" to "tree_pp" to make it easier to tell what we're dealing
with (a param, a file-static, or a buffer).

gcc/ChangeLog:
	* tree-pretty-print.c (INDENT): Rename "buffer" to "pp".
	(NIY): Likewise.
	(buffer): Rename this variable to...
	(tree_pp): ...this.

	(do_niy): Rename param from "buffer" to "pp".
	(dump_decl_name): Likewise.
	(dump_function_name): Likewise.
	(dump_function_declaration): Likewise.
	(dump_array_domain): Likewise.
	(dump_omp_clause): Likewise.
	(dump_omp_clauses): Likewise.
	(dump_location): Likewise.
	(dump_block_node): Likewise.
	(dump_generic_node): Likewise.
	(print_declaration): Likewise.
	(print_struct_decl): Likewise.
	(print_call_name): Likewise.
	(pretty_print_string): Likewise.
	(newline_and_indent): Likewise.

	(print_generic_decl): Update for renaming of "buffer" to
	"tree_pp".
	(print_generic_stmt): Likewise.
	(print_generic_stmt_indented): Likewise.
	(print_generic_expr): Likewise.
	(maybe_init_pretty_print): Likewise.
---
 gcc/tree-pretty-print.c | 1946 +++++++++++++++++++++++------------------------
 1 file changed, 973 insertions(+), 973 deletions(-)

diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index ddd7521..a0468d1 100644
--- a/gcc/tree-pretty-print.c
+++ b/gcc/tree-pretty-print.c
@@ -57,33 +57,33 @@ static void print_struct_decl (pretty_printer *, const_tree, int, int);
 static void do_niy (pretty_printer *, const_tree);
 
 #define INDENT(SPACE) do { \
-  int i; for (i = 0; i<SPACE; i++) pp_space (buffer); } while (0)
+  int i; for (i = 0; i<SPACE; i++) pp_space (pp); } while (0)
 
-#define NIY do_niy (buffer, node)
+#define NIY do_niy (pp, node)
 
-static pretty_printer *buffer;
+static pretty_printer *tree_pp;
 
 /* Try to print something for an unknown tree code.  */
 
 static void
-do_niy (pretty_printer *buffer, const_tree node)
+do_niy (pretty_printer *pp, const_tree node)
 {
   int i, len;
 
-  pp_string (buffer, "<<< Unknown tree: ");
-  pp_string (buffer, get_tree_code_name (TREE_CODE (node)));
+  pp_string (pp, "<<< Unknown tree: ");
+  pp_string (pp, get_tree_code_name (TREE_CODE (node)));
 
   if (EXPR_P (node))
     {
       len = TREE_OPERAND_LENGTH (node);
       for (i = 0; i < len; ++i)
 	{
-	  newline_and_indent (buffer, 2);
-	  dump_generic_node (buffer, TREE_OPERAND (node, i), 2, 0, false);
+	  newline_and_indent (pp, 2);
+	  dump_generic_node (pp, TREE_OPERAND (node, i), 2, 0, false);
 	}
     }
 
-  pp_string (buffer, " >>>");
+  pp_string (pp, " >>>");
 }
 
 /* Debugging function to print out a generic expression.  */
@@ -132,8 +132,8 @@ void
 print_generic_decl (FILE *file, tree decl, int flags)
 {
   maybe_init_pretty_print (file);
-  print_declaration (buffer, decl, 2, flags);
-  pp_write_text_to_stream (buffer);
+  print_declaration (tree_pp, decl, 2, flags);
+  pp_write_text_to_stream (tree_pp);
 }
 
 /* Print tree T, and its successors, on file FILE.  FLAGS specifies details
@@ -143,8 +143,8 @@ void
 print_generic_stmt (FILE *file, tree t, int flags)
 {
   maybe_init_pretty_print (file);
-  dump_generic_node (buffer, t, 0, flags, true);
-  pp_newline_and_flush (buffer);
+  dump_generic_node (tree_pp, t, 0, flags, true);
+  pp_newline_and_flush (tree_pp);
 }
 
 /* Print tree T, and its successors, on file FILE.  FLAGS specifies details
@@ -159,9 +159,9 @@ print_generic_stmt_indented (FILE *file, tree t, int flags, int indent)
   maybe_init_pretty_print (file);
 
   for (i = 0; i < indent; i++)
-    pp_space (buffer);
-  dump_generic_node (buffer, t, indent, flags, true);
-  pp_newline_and_flush (buffer);
+    pp_space (tree_pp);
+  dump_generic_node (tree_pp, t, indent, flags, true);
+  pp_newline_and_flush (tree_pp);
 }
 
 /* Print a single expression T on file FILE.  FLAGS specifies details to show
@@ -171,77 +171,77 @@ void
 print_generic_expr (FILE *file, tree t, int flags)
 {
   maybe_init_pretty_print (file);
-  dump_generic_node (buffer, t, 0, flags, false);
-  pp_flush (buffer);
+  dump_generic_node (tree_pp, t, 0, flags, false);
+  pp_flush (tree_pp);
 }
 
 /* Dump the name of a _DECL node and its DECL_UID if TDF_UID is set
    in FLAGS.  */
 
 static void
-dump_decl_name (pretty_printer *buffer, tree node, int flags)
+dump_decl_name (pretty_printer *pp, tree node, int flags)
 {
   if (DECL_NAME (node))
     {
       if ((flags & TDF_ASMNAME) && DECL_ASSEMBLER_NAME_SET_P (node))
-	pp_tree_identifier (buffer, DECL_ASSEMBLER_NAME (node));
+	pp_tree_identifier (pp, DECL_ASSEMBLER_NAME (node));
       else
-	pp_tree_identifier (buffer, DECL_NAME (node));
+	pp_tree_identifier (pp, DECL_NAME (node));
     }
   if ((flags & TDF_UID) || DECL_NAME (node) == NULL_TREE)
     {
       if (TREE_CODE (node) == LABEL_DECL && LABEL_DECL_UID (node) != -1)
-	pp_printf (buffer, "L.%d", (int) LABEL_DECL_UID (node));
+	pp_printf (pp, "L.%d", (int) LABEL_DECL_UID (node));
       else if (TREE_CODE (node) == DEBUG_EXPR_DECL)
 	{
 	  if (flags & TDF_NOUID)
-	    pp_string (buffer, "D#xxxx");
+	    pp_string (pp, "D#xxxx");
 	  else
-	    pp_printf (buffer, "D#%i", DEBUG_TEMP_UID (node));
+	    pp_printf (pp, "D#%i", DEBUG_TEMP_UID (node));
 	}
       else
 	{
 	  char c = TREE_CODE (node) == CONST_DECL ? 'C' : 'D';
 	  if (flags & TDF_NOUID)
-	    pp_printf (buffer, "%c.xxxx", c);
+	    pp_printf (pp, "%c.xxxx", c);
 	  else
-	    pp_printf (buffer, "%c.%u", c, DECL_UID (node));
+	    pp_printf (pp, "%c.%u", c, DECL_UID (node));
 	}
     }
   if ((flags & TDF_ALIAS) && DECL_PT_UID (node) != DECL_UID (node))
     {
       if (flags & TDF_NOUID)
-	pp_printf (buffer, "ptD.xxxx");
+	pp_printf (pp, "ptD.xxxx");
       else
-	pp_printf (buffer, "ptD.%u", DECL_PT_UID (node));
+	pp_printf (pp, "ptD.%u", DECL_PT_UID (node));
     }
 }
 
 /* Like the above, but used for pretty printing function calls.  */
 
 static void
-dump_function_name (pretty_printer *buffer, tree node, int flags)
+dump_function_name (pretty_printer *pp, tree node, int flags)
 {
   if (CONVERT_EXPR_P (node))
     node = TREE_OPERAND (node, 0);
   if (DECL_NAME (node) && (flags & TDF_ASMNAME) == 0)
-    pp_string (buffer, lang_hooks.decl_printable_name (node, 1));
+    pp_string (pp, lang_hooks.decl_printable_name (node, 1));
   else
-    dump_decl_name (buffer, node, flags);
+    dump_decl_name (pp, node, flags);
 }
 
-/* Dump a function declaration.  NODE is the FUNCTION_TYPE.  BUFFER, SPC and
+/* Dump a function declaration.  NODE is the FUNCTION_TYPE.  PP, SPC and
    FLAGS are as in dump_generic_node.  */
 
 static void
-dump_function_declaration (pretty_printer *buffer, tree node,
+dump_function_declaration (pretty_printer *pp, tree node,
 			   int spc, int flags)
 {
   bool wrote_arg = false;
   tree arg;
 
-  pp_space (buffer);
-  pp_left_paren (buffer);
+  pp_space (pp);
+  pp_left_paren (pp);
 
   /* Print the argument types.  */
   arg = TYPE_ARG_TYPES (node);
@@ -249,31 +249,31 @@ dump_function_declaration (pretty_printer *buffer, tree node,
     {
       if (wrote_arg)
 	{
-	  pp_comma (buffer);
-	  pp_space (buffer);
+	  pp_comma (pp);
+	  pp_space (pp);
 	}
       wrote_arg = true;
-      dump_generic_node (buffer, TREE_VALUE (arg), spc, flags, false);
+      dump_generic_node (pp, TREE_VALUE (arg), spc, flags, false);
       arg = TREE_CHAIN (arg);
     }
 
   /* Drop the trailing void_type_node if we had any previous argument.  */
   if (arg == void_list_node && !wrote_arg)
-    pp_string (buffer, "void");
+    pp_string (pp, "void");
   /* Properly dump vararg function types.  */
   else if (!arg && wrote_arg)
-    pp_string (buffer, ", ...");
+    pp_string (pp, ", ...");
   /* Avoid printing any arg for unprototyped functions.  */
 
-  pp_right_paren (buffer);
+  pp_right_paren (pp);
 }
 
 /* Dump the domain associated with an array.  */
 
 static void
-dump_array_domain (pretty_printer *buffer, tree domain, int spc, int flags)
+dump_array_domain (pretty_printer *pp, tree domain, int spc, int flags)
 {
-  pp_left_bracket (buffer);
+  pp_left_bracket (pp);
   if (domain)
     {
       tree min = TYPE_MIN_VALUE (domain);
@@ -282,27 +282,27 @@ dump_array_domain (pretty_printer *buffer, tree domain, int spc, int flags)
       if (min && max
 	  && integer_zerop (min)
 	  && tree_fits_shwi_p (max))
-	pp_wide_integer (buffer, tree_to_shwi (max) + 1);
+	pp_wide_integer (pp, tree_to_shwi (max) + 1);
       else
 	{
 	  if (min)
-	    dump_generic_node (buffer, min, spc, flags, false);
-	  pp_colon (buffer);
+	    dump_generic_node (pp, min, spc, flags, false);
+	  pp_colon (pp);
 	  if (max)
-	    dump_generic_node (buffer, max, spc, flags, false);
+	    dump_generic_node (pp, max, spc, flags, false);
 	}
     }
   else
-    pp_string (buffer, "<unknown>");
-  pp_right_bracket (buffer);
+    pp_string (pp, "<unknown>");
+  pp_right_bracket (pp);
 }
 
 
-/* Dump OpenMP clause CLAUSE.  BUFFER, CLAUSE, SPC and FLAGS are as in
+/* Dump OpenMP clause CLAUSE.  PP, CLAUSE, SPC and FLAGS are as in
    dump_generic_node.  */
 
 static void
-dump_omp_clause (pretty_printer *buffer, tree clause, int spc, int flags)
+dump_omp_clause (pretty_printer *pp, tree clause, int spc, int flags)
 {
   const char *name;
 
@@ -333,440 +333,440 @@ dump_omp_clause (pretty_printer *buffer, tree clause, int spc, int flags)
       name = "_looptemp_";
       goto print_remap;
   print_remap:
-      pp_string (buffer, name);
-      pp_left_paren (buffer);
-      dump_generic_node (buffer, OMP_CLAUSE_DECL (clause),
+      pp_string (pp, name);
+      pp_left_paren (pp);
+      dump_generic_node (pp, OMP_CLAUSE_DECL (clause),
 			 spc, flags, false);
-      pp_right_paren (buffer);
+      pp_right_paren (pp);
       break;
 
     case OMP_CLAUSE_REDUCTION:
-      pp_string (buffer, "reduction(");
+      pp_string (pp, "reduction(");
       if (OMP_CLAUSE_REDUCTION_CODE (clause) != ERROR_MARK)
 	{
-	  pp_string (buffer,
+	  pp_string (pp,
 		     op_symbol_code (OMP_CLAUSE_REDUCTION_CODE (clause)));
-	  pp_colon (buffer);
+	  pp_colon (pp);
 	}
-      dump_generic_node (buffer, OMP_CLAUSE_DECL (clause),
+      dump_generic_node (pp, OMP_CLAUSE_DECL (clause),
 			 spc, flags, false);
-      pp_right_paren (buffer);
+      pp_right_paren (pp);
       break;
 
     case OMP_CLAUSE_IF:
-      pp_string (buffer, "if(");
-      dump_generic_node (buffer, OMP_CLAUSE_IF_EXPR (clause),
+      pp_string (pp, "if(");
+      dump_generic_node (pp, OMP_CLAUSE_IF_EXPR (clause),
 			 spc, flags, false);
-      pp_right_paren (buffer);
+      pp_right_paren (pp);
       break;
 
     case OMP_CLAUSE_NUM_THREADS:
-      pp_string (buffer, "num_threads(");
-      dump_generic_node (buffer, OMP_CLAUSE_NUM_THREADS_EXPR (clause),
+      pp_string (pp, "num_threads(");
+      dump_generic_node (pp, OMP_CLAUSE_NUM_THREADS_EXPR (clause),
 			 spc, flags, false);
-      pp_right_paren (buffer);
+      pp_right_paren (pp);
       break;
 
     case OMP_CLAUSE__CILK_FOR_COUNT_:
-      pp_string (buffer, "_Cilk_for_count_(");
-      dump_generic_node (buffer, OMP_CLAUSE_OPERAND (clause, 0),
+      pp_string (pp, "_Cilk_for_count_(");
+      dump_generic_node (pp, OMP_CLAUSE_OPERAND (clause, 0),
 			 spc, flags, false);
-      pp_right_paren (buffer);
+      pp_right_paren (pp);
       break;
 
     case OMP_CLAUSE_NOWAIT:
-      pp_string (buffer, "nowait");
+      pp_string (pp, "nowait");
       break;
     case OMP_CLAUSE_ORDERED:
-      pp_string (buffer, "ordered");
+      pp_string (pp, "ordered");
       break;
 
     case OMP_CLAUSE_DEFAULT:
-      pp_string (buffer, "default(");
+      pp_string (pp, "default(");
       switch (OMP_CLAUSE_DEFAULT_KIND (clause))
 	{
 	case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
 	  break;
 	case OMP_CLAUSE_DEFAULT_SHARED:
-	  pp_string (buffer, "shared");
+	  pp_string (pp, "shared");
 	  break;
 	case OMP_CLAUSE_DEFAULT_NONE:
-	  pp_string (buffer, "none");
+	  pp_string (pp, "none");
 	  break;
 	case OMP_CLAUSE_DEFAULT_PRIVATE:
-	  pp_string (buffer, "private");
+	  pp_string (pp, "private");
 	  break;
 	case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE:
-	  pp_string (buffer, "firstprivate");
+	  pp_string (pp, "firstprivate");
 	  break;
 	default:
 	  gcc_unreachable ();
 	}
-      pp_right_paren (buffer);
+      pp_right_paren (pp);
       break;
 
     case OMP_CLAUSE_SCHEDULE:
-      pp_string (buffer, "schedule(");
+      pp_string (pp, "schedule(");
       switch (OMP_CLAUSE_SCHEDULE_KIND (clause))
 	{
 	case OMP_CLAUSE_SCHEDULE_STATIC:
-	  pp_string (buffer, "static");
+	  pp_string (pp, "static");
 	  break;
 	case OMP_CLAUSE_SCHEDULE_DYNAMIC:
-	  pp_string (buffer, "dynamic");
+	  pp_string (pp, "dynamic");
 	  break;
 	case OMP_CLAUSE_SCHEDULE_GUIDED:
-	  pp_string (buffer, "guided");
+	  pp_string (pp, "guided");
 	  break;
 	case OMP_CLAUSE_SCHEDULE_RUNTIME:
-	  pp_string (buffer, "runtime");
+	  pp_string (pp, "runtime");
 	  break;
 	case OMP_CLAUSE_SCHEDULE_AUTO:
-	  pp_string (buffer, "auto");
+	  pp_string (pp, "auto");
 	  break;
 	case OMP_CLAUSE_SCHEDULE_CILKFOR:
-	  pp_string (buffer, "cilk-for grain");
+	  pp_string (pp, "cilk-for grain");
 	  break;
 	default:
 	  gcc_unreachable ();
 	}
       if (OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clause))
 	{
-	  pp_comma (buffer);
-	  dump_generic_node (buffer, OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clause),
+	  pp_comma (pp);
+	  dump_generic_node (pp, OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clause),
 			     spc, flags, false);
 	}
-      pp_right_paren (buffer);
+      pp_right_paren (pp);
       break;
 
     case OMP_CLAUSE_UNTIED:
-      pp_string (buffer, "untied");
+      pp_string (pp, "untied");
       break;
 
     case OMP_CLAUSE_COLLAPSE:
-      pp_string (buffer, "collapse(");
-      dump_generic_node (buffer, OMP_CLAUSE_COLLAPSE_EXPR (clause),
+      pp_string (pp, "collapse(");
+      dump_generic_node (pp, OMP_CLAUSE_COLLAPSE_EXPR (clause),
 			 spc, flags, false);
-      pp_right_paren (buffer);
+      pp_right_paren (pp);
       break;
 
     case OMP_CLAUSE_FINAL:
-      pp_string (buffer, "final(");
-      dump_generic_node (buffer, OMP_CLAUSE_FINAL_EXPR (clause),
+      pp_string (pp, "final(");
+      dump_generic_node (pp, OMP_CLAUSE_FINAL_EXPR (clause),
 			 spc, flags, false);
-      pp_right_paren (buffer);
+      pp_right_paren (pp);
       break;
 
     case OMP_CLAUSE_MERGEABLE:
-      pp_string (buffer, "mergeable");
+      pp_string (pp, "mergeable");
       break;
 
     case OMP_CLAUSE_LINEAR:
-      pp_string (buffer, "linear(");
-      dump_generic_node (buffer, OMP_CLAUSE_DECL (clause),
+      pp_string (pp, "linear(");
+      dump_generic_node (pp, OMP_CLAUSE_DECL (clause),
 			 spc, flags, false);
-      pp_colon (buffer);
-      dump_generic_node (buffer, OMP_CLAUSE_LINEAR_STEP (clause),
+      pp_colon (pp);
+      dump_generic_node (pp, OMP_CLAUSE_LINEAR_STEP (clause),
 			 spc, flags, false);
-      pp_right_paren (buffer);
+      pp_right_paren (pp);
       break;
 
     case OMP_CLAUSE_ALIGNED:
-      pp_string (buffer, "aligned(");
-      dump_generic_node (buffer, OMP_CLAUSE_DECL (clause),
+      pp_string (pp, "aligned(");
+      dump_generic_node (pp, OMP_CLAUSE_DECL (clause),
 			 spc, flags, false);
       if (OMP_CLAUSE_ALIGNED_ALIGNMENT (clause))
 	{
-	  pp_colon (buffer);
-	  dump_generic_node (buffer, OMP_CLAUSE_ALIGNED_ALIGNMENT (clause),
+	  pp_colon (pp);
+	  dump_generic_node (pp, OMP_CLAUSE_ALIGNED_ALIGNMENT (clause),
 			     spc, flags, false);
 	}
-      pp_right_paren (buffer);
+      pp_right_paren (pp);
       break;
 
     case OMP_CLAUSE_DEPEND:
-      pp_string (buffer, "depend(");
+      pp_string (pp, "depend(");
       switch (OMP_CLAUSE_DEPEND_KIND (clause))
 	{
 	case OMP_CLAUSE_DEPEND_IN:
-	  pp_string (buffer, "in");
+	  pp_string (pp, "in");
 	  break;
 	case OMP_CLAUSE_DEPEND_OUT:
-	  pp_string (buffer, "out");
+	  pp_string (pp, "out");
 	  break;
 	case OMP_CLAUSE_DEPEND_INOUT:
-	  pp_string (buffer, "inout");
+	  pp_string (pp, "inout");
 	  break;
 	default:
 	  gcc_unreachable ();
 	}
-      pp_colon (buffer);
-      dump_generic_node (buffer, OMP_CLAUSE_DECL (clause),
+      pp_colon (pp);
+      dump_generic_node (pp, OMP_CLAUSE_DECL (clause),
 			 spc, flags, false);
-      pp_right_paren (buffer);
+      pp_right_paren (pp);
       break;
 
     case OMP_CLAUSE_MAP:
-      pp_string (buffer, "map(");
+      pp_string (pp, "map(");
       switch (OMP_CLAUSE_MAP_KIND (clause))
 	{
 	case OMP_CLAUSE_MAP_ALLOC:
 	case OMP_CLAUSE_MAP_POINTER:
-	  pp_string (buffer, "alloc");
+	  pp_string (pp, "alloc");
 	  break;
 	case OMP_CLAUSE_MAP_TO:
 	case OMP_CLAUSE_MAP_TO_PSET:
-	  pp_string (buffer, "to");
+	  pp_string (pp, "to");
 	  break;
 	case OMP_CLAUSE_MAP_FROM:
-	  pp_string (buffer, "from");
+	  pp_string (pp, "from");
 	  break;
 	case OMP_CLAUSE_MAP_TOFROM:
-	  pp_string (buffer, "tofrom");
+	  pp_string (pp, "tofrom");
 	  break;
 	default:
 	  gcc_unreachable ();
 	}
-      pp_colon (buffer);
-      dump_generic_node (buffer, OMP_CLAUSE_DECL (clause),
+      pp_colon (pp);
+      dump_generic_node (pp, OMP_CLAUSE_DECL (clause),
 			 spc, flags, false);
      print_clause_size:
       if (OMP_CLAUSE_SIZE (clause))
 	{
 	  if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_MAP
 	      && OMP_CLAUSE_MAP_KIND (clause) == OMP_CLAUSE_MAP_POINTER)
-	    pp_string (buffer, " [pointer assign, bias: ");
+	    pp_string (pp, " [pointer assign, bias: ");
 	  else if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_MAP
 		   && OMP_CLAUSE_MAP_KIND (clause) == OMP_CLAUSE_MAP_TO_PSET)
-	    pp_string (buffer, " [pointer set, len: ");
+	    pp_string (pp, " [pointer set, len: ");
 	  else
-	    pp_string (buffer, " [len: ");
-	  dump_generic_node (buffer, OMP_CLAUSE_SIZE (clause),
+	    pp_string (pp, " [len: ");
+	  dump_generic_node (pp, OMP_CLAUSE_SIZE (clause),
 			     spc, flags, false);
-	  pp_right_bracket (buffer);
+	  pp_right_bracket (pp);
 	}
-      pp_right_paren (buffer);
+      pp_right_paren (pp);
       break;
 
     case OMP_CLAUSE_FROM:
-      pp_string (buffer, "from(");
-      dump_generic_node (buffer, OMP_CLAUSE_DECL (clause),
+      pp_string (pp, "from(");
+      dump_generic_node (pp, OMP_CLAUSE_DECL (clause),
 			 spc, flags, false);
       goto print_clause_size;
 
     case OMP_CLAUSE_TO:
-      pp_string (buffer, "to(");
-      dump_generic_node (buffer, OMP_CLAUSE_DECL (clause),
+      pp_string (pp, "to(");
+      dump_generic_node (pp, OMP_CLAUSE_DECL (clause),
 			 spc, flags, false);
       goto print_clause_size;
 
     case OMP_CLAUSE_NUM_TEAMS:
-      pp_string (buffer, "num_teams(");
-      dump_generic_node (buffer, OMP_CLAUSE_NUM_TEAMS_EXPR (clause),
+      pp_string (pp, "num_teams(");
+      dump_generic_node (pp, OMP_CLAUSE_NUM_TEAMS_EXPR (clause),
 			 spc, flags, false);
-      pp_right_paren (buffer);
+      pp_right_paren (pp);
       break;
 
     case OMP_CLAUSE_THREAD_LIMIT:
-      pp_string (buffer, "thread_limit(");
-      dump_generic_node (buffer, OMP_CLAUSE_THREAD_LIMIT_EXPR (clause),
+      pp_string (pp, "thread_limit(");
+      dump_generic_node (pp, OMP_CLAUSE_THREAD_LIMIT_EXPR (clause),
 			 spc, flags, false);
-      pp_right_paren (buffer);
+      pp_right_paren (pp);
       break;
 
     case OMP_CLAUSE_DEVICE:
-      pp_string (buffer, "device(");
-      dump_generic_node (buffer, OMP_CLAUSE_DEVICE_ID (clause),
+      pp_string (pp, "device(");
+      dump_generic_node (pp, OMP_CLAUSE_DEVICE_ID (clause),
 			 spc, flags, false);
-      pp_right_paren (buffer);
+      pp_right_paren (pp);
       break;
 
     case OMP_CLAUSE_DIST_SCHEDULE:
-      pp_string (buffer, "dist_schedule(static");
+      pp_string (pp, "dist_schedule(static");
       if (OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (clause))
 	{
-	  pp_comma (buffer);
-	  dump_generic_node (buffer,
+	  pp_comma (pp);
+	  dump_generic_node (pp,
 			     OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (clause),
 			     spc, flags, false);
 	}
-      pp_right_paren (buffer);
+      pp_right_paren (pp);
       break;
 
     case OMP_CLAUSE_PROC_BIND:
-      pp_string (buffer, "proc_bind(");
+      pp_string (pp, "proc_bind(");
       switch (OMP_CLAUSE_PROC_BIND_KIND (clause))
 	{
 	case OMP_CLAUSE_PROC_BIND_MASTER:
-	  pp_string (buffer, "master");
+	  pp_string (pp, "master");
 	  break;
 	case OMP_CLAUSE_PROC_BIND_CLOSE:
-	  pp_string (buffer, "close");
+	  pp_string (pp, "close");
 	  break;
 	case OMP_CLAUSE_PROC_BIND_SPREAD:
-	  pp_string (buffer, "spread");
+	  pp_string (pp, "spread");
 	  break;
 	default:
 	  gcc_unreachable ();
 	}
-      pp_right_paren (buffer);
+      pp_right_paren (pp);
       break;
 
     case OMP_CLAUSE_SAFELEN:
-      pp_string (buffer, "safelen(");
-      dump_generic_node (buffer, OMP_CLAUSE_SAFELEN_EXPR (clause),
+      pp_string (pp, "safelen(");
+      dump_generic_node (pp, OMP_CLAUSE_SAFELEN_EXPR (clause),
 			 spc, flags, false);
-      pp_right_paren (buffer);
+      pp_right_paren (pp);
       break;
 
     case OMP_CLAUSE_SIMDLEN:
-      pp_string (buffer, "simdlen(");
-      dump_generic_node (buffer, OMP_CLAUSE_SIMDLEN_EXPR (clause),
+      pp_string (pp, "simdlen(");
+      dump_generic_node (pp, OMP_CLAUSE_SIMDLEN_EXPR (clause),
 			 spc, flags, false);
-      pp_right_paren (buffer);
+      pp_right_paren (pp);
       break;
 
     case OMP_CLAUSE__SIMDUID_:
-      pp_string (buffer, "_simduid_(");
-      dump_generic_node (buffer, OMP_CLAUSE__SIMDUID__DECL (clause),
+      pp_string (pp, "_simduid_(");
+      dump_generic_node (pp, OMP_CLAUSE__SIMDUID__DECL (clause),
 			 spc, flags, false);
-      pp_right_paren (buffer);
+      pp_right_paren (pp);
       break;
 
     case OMP_CLAUSE_INBRANCH:
-      pp_string (buffer, "inbranch");
+      pp_string (pp, "inbranch");
       break;
     case OMP_CLAUSE_NOTINBRANCH:
-      pp_string (buffer, "notinbranch");
+      pp_string (pp, "notinbranch");
       break;
     case OMP_CLAUSE_FOR:
-      pp_string (buffer, "for");
+      pp_string (pp, "for");
       break;
     case OMP_CLAUSE_PARALLEL:
-      pp_string (buffer, "parallel");
+      pp_string (pp, "parallel");
       break;
     case OMP_CLAUSE_SECTIONS:
-      pp_string (buffer, "sections");
+      pp_string (pp, "sections");
       break;
     case OMP_CLAUSE_TASKGROUP:
-      pp_string (buffer, "taskgroup");
+      pp_string (pp, "taskgroup");
       break;
 
     default:
       /* Should never happen.  */
-      dump_generic_node (buffer, clause, spc, flags, false);
+      dump_generic_node (pp, clause, spc, flags, false);
       break;
     }
 }
 
 
-/* Dump the list of OpenMP clauses.  BUFFER, SPC and FLAGS are as in
+/* Dump the list of OpenMP clauses.  PP, SPC and FLAGS are as in
    dump_generic_node.  */
 
 void
-dump_omp_clauses (pretty_printer *buffer, tree clause, int spc, int flags)
+dump_omp_clauses (pretty_printer *pp, tree clause, int spc, int flags)
 {
   if (clause == NULL)
     return;
 
-  pp_space (buffer);
+  pp_space (pp);
   while (1)
     {
-      dump_omp_clause (buffer, clause, spc, flags);
+      dump_omp_clause (pp, clause, spc, flags);
       clause = OMP_CLAUSE_CHAIN (clause);
       if (clause == NULL)
 	return;
-      pp_space (buffer);
+      pp_space (pp);
     }
 }
 
 
-/* Dump location LOC to BUFFER.  */
+/* Dump location LOC to PP.  */
 
 void
-dump_location (pretty_printer *buffer, location_t loc)
+dump_location (pretty_printer *pp, location_t loc)
 {
   expanded_location xloc = expand_location (loc);
 
-  pp_left_bracket (buffer);
+  pp_left_bracket (pp);
   if (xloc.file)
     {
-      pp_string (buffer, xloc.file);
-      pp_string (buffer, ":");
+      pp_string (pp, xloc.file);
+      pp_string (pp, ":");
     }
-  pp_decimal_int (buffer, xloc.line);
-  pp_colon (buffer);
-  pp_decimal_int (buffer, xloc.column);
-  pp_string (buffer, "] ");
+  pp_decimal_int (pp, xloc.line);
+  pp_colon (pp);
+  pp_decimal_int (pp, xloc.column);
+  pp_string (pp, "] ");
 }
 
 
-/* Dump lexical block BLOCK.  BUFFER, SPC and FLAGS are as in
+/* Dump lexical block BLOCK.  PP, SPC and FLAGS are as in
    dump_generic_node.  */
 
 static void
-dump_block_node (pretty_printer *buffer, tree block, int spc, int flags)
+dump_block_node (pretty_printer *pp, tree block, int spc, int flags)
 {
   tree t;
 
-  pp_printf (buffer, "BLOCK #%d ", BLOCK_NUMBER (block));
+  pp_printf (pp, "BLOCK #%d ", BLOCK_NUMBER (block));
 
   if (flags & TDF_ADDRESS)
-    pp_printf (buffer, "[%p] ", (void *) block);
+    pp_printf (pp, "[%p] ", (void *) block);
 
   if (BLOCK_ABSTRACT (block))
-    pp_string (buffer, "[abstract] ");
+    pp_string (pp, "[abstract] ");
 
   if (TREE_ASM_WRITTEN (block))
-    pp_string (buffer, "[written] ");
+    pp_string (pp, "[written] ");
 
   if (flags & TDF_SLIM)
     return;
 
   if (BLOCK_SOURCE_LOCATION (block))
-    dump_location (buffer, BLOCK_SOURCE_LOCATION (block));
+    dump_location (pp, BLOCK_SOURCE_LOCATION (block));
 
-  newline_and_indent (buffer, spc + 2);
+  newline_and_indent (pp, spc + 2);
 
   if (BLOCK_SUPERCONTEXT (block))
     {
-      pp_string (buffer, "SUPERCONTEXT: ");
-      dump_generic_node (buffer, BLOCK_SUPERCONTEXT (block), 0,
+      pp_string (pp, "SUPERCONTEXT: ");
+      dump_generic_node (pp, BLOCK_SUPERCONTEXT (block), 0,
 			 flags | TDF_SLIM, false);
-      newline_and_indent (buffer, spc + 2);
+      newline_and_indent (pp, spc + 2);
     }
 
   if (BLOCK_SUBBLOCKS (block))
     {
-      pp_string (buffer, "SUBBLOCKS: ");
+      pp_string (pp, "SUBBLOCKS: ");
       for (t = BLOCK_SUBBLOCKS (block); t; t = BLOCK_CHAIN (t))
 	{
-	  dump_generic_node (buffer, t, 0, flags | TDF_SLIM, false);
-	  pp_space (buffer);
+	  dump_generic_node (pp, t, 0, flags | TDF_SLIM, false);
+	  pp_space (pp);
 	}
-      newline_and_indent (buffer, spc + 2);
+      newline_and_indent (pp, spc + 2);
     }
 
   if (BLOCK_CHAIN (block))
     {
-      pp_string (buffer, "SIBLINGS: ");
+      pp_string (pp, "SIBLINGS: ");
       for (t = BLOCK_CHAIN (block); t; t = BLOCK_CHAIN (t))
 	{
-	  dump_generic_node (buffer, t, 0, flags | TDF_SLIM, false);
-	  pp_space (buffer);
+	  dump_generic_node (pp, t, 0, flags | TDF_SLIM, false);
+	  pp_space (pp);
 	}
-      newline_and_indent (buffer, spc + 2);
+      newline_and_indent (pp, spc + 2);
     }
 
   if (BLOCK_VARS (block))
     {
-      pp_string (buffer, "VARS: ");
+      pp_string (pp, "VARS: ");
       for (t = BLOCK_VARS (block); t; t = TREE_CHAIN (t))
 	{
-	  dump_generic_node (buffer, t, 0, flags, false);
-	  pp_space (buffer);
+	  dump_generic_node (pp, t, 0, flags, false);
+	  pp_space (pp);
 	}
-      newline_and_indent (buffer, spc + 2);
+      newline_and_indent (pp, spc + 2);
     }
 
   if (vec_safe_length (BLOCK_NONLOCALIZED_VARS (block)) > 0)
@@ -774,51 +774,51 @@ dump_block_node (pretty_printer *buffer, tree block, int spc, int flags)
       unsigned i;
       vec<tree, va_gc> *nlv = BLOCK_NONLOCALIZED_VARS (block);
 
-      pp_string (buffer, "NONLOCALIZED_VARS: ");
+      pp_string (pp, "NONLOCALIZED_VARS: ");
       FOR_EACH_VEC_ELT (*nlv, i, t)
 	{
-	  dump_generic_node (buffer, t, 0, flags, false);
-	  pp_space (buffer);
+	  dump_generic_node (pp, t, 0, flags, false);
+	  pp_space (pp);
 	}
-      newline_and_indent (buffer, spc + 2);
+      newline_and_indent (pp, spc + 2);
     }
 
   if (BLOCK_ABSTRACT_ORIGIN (block))
     {
-      pp_string (buffer, "ABSTRACT_ORIGIN: ");
-      dump_generic_node (buffer, BLOCK_ABSTRACT_ORIGIN (block), 0,
+      pp_string (pp, "ABSTRACT_ORIGIN: ");
+      dump_generic_node (pp, BLOCK_ABSTRACT_ORIGIN (block), 0,
 			 flags | TDF_SLIM, false);
-      newline_and_indent (buffer, spc + 2);
+      newline_and_indent (pp, spc + 2);
     }
 
   if (BLOCK_FRAGMENT_ORIGIN (block))
     {
-      pp_string (buffer, "FRAGMENT_ORIGIN: ");
-      dump_generic_node (buffer, BLOCK_FRAGMENT_ORIGIN (block), 0,
+      pp_string (pp, "FRAGMENT_ORIGIN: ");
+      dump_generic_node (pp, BLOCK_FRAGMENT_ORIGIN (block), 0,
 			 flags | TDF_SLIM, false);
-      newline_and_indent (buffer, spc + 2);
+      newline_and_indent (pp, spc + 2);
     }
 
   if (BLOCK_FRAGMENT_CHAIN (block))
     {
-      pp_string (buffer, "FRAGMENT_CHAIN: ");
+      pp_string (pp, "FRAGMENT_CHAIN: ");
       for (t = BLOCK_FRAGMENT_CHAIN (block); t; t = BLOCK_FRAGMENT_CHAIN (t))
 	{
-	  dump_generic_node (buffer, t, 0, flags | TDF_SLIM, false);
-	  pp_space (buffer);
+	  dump_generic_node (pp, t, 0, flags | TDF_SLIM, false);
+	  pp_space (pp);
 	}
-      newline_and_indent (buffer, spc + 2);
+      newline_and_indent (pp, spc + 2);
     }
 }
 
 
-/* Dump the node NODE on the pretty_printer BUFFER, SPC spaces of
+/* Dump the node NODE on the pretty_printer PP, SPC spaces of
    indent.  FLAGS specifies details to show in the dump (see TDF_* in
    dumpfile.h).  If IS_STMT is true, the object printed is considered
    to be a statement and it is terminated by ';' if appropriate.  */
 
 int
-dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
+dump_generic_node (pretty_printer *pp, tree node, int spc, int flags,
 		   bool is_stmt)
 {
   tree type;
@@ -833,20 +833,20 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
   is_expr = EXPR_P (node);
 
   if (is_stmt && (flags & TDF_STMTADDR))
-    pp_printf (buffer, "<&%p> ", (void *)node);
+    pp_printf (pp, "<&%p> ", (void *)node);
 
   if ((flags & TDF_LINENO) && EXPR_HAS_LOCATION (node))
-    dump_location (buffer, EXPR_LOCATION (node));
+    dump_location (pp, EXPR_LOCATION (node));
 
   code = TREE_CODE (node);
   switch (code)
     {
     case ERROR_MARK:
-      pp_string (buffer, "<<< error >>>");
+      pp_string (pp, "<<< error >>>");
       break;
 
     case IDENTIFIER_NODE:
-      pp_tree_identifier (buffer, node);
+      pp_tree_identifier (pp, node);
       break;
 
     case TREE_LIST:
@@ -854,21 +854,21 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 	{
 	  if (TREE_PURPOSE (node))
 	    {
-	      dump_generic_node (buffer, TREE_PURPOSE (node), spc, flags, false);
-	      pp_space (buffer);
+	      dump_generic_node (pp, TREE_PURPOSE (node), spc, flags, false);
+	      pp_space (pp);
 	    }
-	  dump_generic_node (buffer, TREE_VALUE (node), spc, flags, false);
+	  dump_generic_node (pp, TREE_VALUE (node), spc, flags, false);
 	  node = TREE_CHAIN (node);
 	  if (node && TREE_CODE (node) == TREE_LIST)
 	    {
-	      pp_comma (buffer);
-	      pp_space (buffer);
+	      pp_comma (pp);
+	      pp_space (pp);
 	    }
 	}
       break;
 
     case TREE_BINFO:
-      dump_generic_node (buffer, BINFO_TYPE (node), spc, flags, false);
+      dump_generic_node (pp, BINFO_TYPE (node), spc, flags, false);
       break;
 
     case TREE_VEC:
@@ -879,12 +879,12 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 	    size_t len = TREE_VEC_LENGTH (node);
 	    for (i = 0; i < len - 1; i++)
 	      {
-		dump_generic_node (buffer, TREE_VEC_ELT (node, i), spc, flags,
+		dump_generic_node (pp, TREE_VEC_ELT (node, i), spc, flags,
 				   false);
-		pp_comma (buffer);
-		pp_space (buffer);
+		pp_comma (pp);
+		pp_space (pp);
 	      }
-	    dump_generic_node (buffer, TREE_VEC_ELT (node, len - 1), spc,
+	    dump_generic_node (pp, TREE_VEC_ELT (node, len - 1), spc,
 			       flags, false);
 	  }
       }
@@ -904,19 +904,19 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 	enum tree_code_class tclass;
 
 	if (quals & TYPE_QUAL_ATOMIC)
-	  pp_string (buffer, "atomic ");
+	  pp_string (pp, "atomic ");
 	if (quals & TYPE_QUAL_CONST)
-	  pp_string (buffer, "const ");
+	  pp_string (pp, "const ");
 	else if (quals & TYPE_QUAL_VOLATILE)
-	  pp_string (buffer, "volatile ");
+	  pp_string (pp, "volatile ");
 	else if (quals & TYPE_QUAL_RESTRICT)
-	  pp_string (buffer, "restrict ");
+	  pp_string (pp, "restrict ");
 
 	if (!ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (node)))
 	  {
-	    pp_string (buffer, "<address-space-");
-	    pp_decimal_int (buffer, TYPE_ADDR_SPACE (node));
-	    pp_string (buffer, "> ");
+	    pp_string (pp, "<address-space-");
+	    pp_decimal_int (pp, TYPE_ADDR_SPACE (node));
+	    pp_string (pp, "> ");
 	  }
 
 	tclass = TREE_CODE_CLASS (TREE_CODE (node));
@@ -924,90 +924,90 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 	if (tclass == tcc_declaration)
 	  {
 	    if (DECL_NAME (node))
-	      dump_decl_name (buffer, node, flags);
+	      dump_decl_name (pp, node, flags);
 	    else
-              pp_string (buffer, "<unnamed type decl>");
+              pp_string (pp, "<unnamed type decl>");
 	  }
 	else if (tclass == tcc_type)
 	  {
 	    if (TYPE_NAME (node))
 	      {
 		if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
-		  pp_tree_identifier (buffer, TYPE_NAME (node));
+		  pp_tree_identifier (pp, TYPE_NAME (node));
 		else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
 			 && DECL_NAME (TYPE_NAME (node)))
-		  dump_decl_name (buffer, TYPE_NAME (node), flags);
+		  dump_decl_name (pp, TYPE_NAME (node), flags);
 		else
-		  pp_string (buffer, "<unnamed type>");
+		  pp_string (pp, "<unnamed type>");
 	      }
 	    else if (TREE_CODE (node) == VECTOR_TYPE)
 	      {
-		pp_string (buffer, "vector");
-		pp_left_paren (buffer);
-		pp_wide_integer (buffer, TYPE_VECTOR_SUBPARTS (node));
-		pp_string (buffer, ") ");
-		dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
+		pp_string (pp, "vector");
+		pp_left_paren (pp);
+		pp_wide_integer (pp, TYPE_VECTOR_SUBPARTS (node));
+		pp_string (pp, ") ");
+		dump_generic_node (pp, TREE_TYPE (node), spc, flags, false);
 	      }
 	    else if (TREE_CODE (node) == INTEGER_TYPE)
 	      {
 		if (TYPE_PRECISION (node) == CHAR_TYPE_SIZE)
-		  pp_string (buffer, (TYPE_UNSIGNED (node)
+		  pp_string (pp, (TYPE_UNSIGNED (node)
 				      ? "unsigned char"
 				      : "signed char"));
 		else if (TYPE_PRECISION (node) == SHORT_TYPE_SIZE)
-		  pp_string (buffer, (TYPE_UNSIGNED (node)
+		  pp_string (pp, (TYPE_UNSIGNED (node)
 				      ? "unsigned short"
 				      : "signed short"));
 		else if (TYPE_PRECISION (node) == INT_TYPE_SIZE)
-		  pp_string (buffer, (TYPE_UNSIGNED (node)
+		  pp_string (pp, (TYPE_UNSIGNED (node)
 				      ? "unsigned int"
 				      : "signed int"));
 		else if (TYPE_PRECISION (node) == LONG_TYPE_SIZE)
-		  pp_string (buffer, (TYPE_UNSIGNED (node)
+		  pp_string (pp, (TYPE_UNSIGNED (node)
 				      ? "unsigned long"
 				      : "signed long"));
 		else if (TYPE_PRECISION (node) == LONG_LONG_TYPE_SIZE)
-		  pp_string (buffer, (TYPE_UNSIGNED (node)
+		  pp_string (pp, (TYPE_UNSIGNED (node)
 				      ? "unsigned long long"
 				      : "signed long long"));
 		else if (TYPE_PRECISION (node) >= CHAR_TYPE_SIZE
 			 && exact_log2 (TYPE_PRECISION (node)) != -1)
 		  {
-		    pp_string (buffer, (TYPE_UNSIGNED (node) ? "uint" : "int"));
-		    pp_decimal_int (buffer, TYPE_PRECISION (node));
-		    pp_string (buffer, "_t");
+		    pp_string (pp, (TYPE_UNSIGNED (node) ? "uint" : "int"));
+		    pp_decimal_int (pp, TYPE_PRECISION (node));
+		    pp_string (pp, "_t");
 		  }
 		else
 		  {
-		    pp_string (buffer, (TYPE_UNSIGNED (node)
+		    pp_string (pp, (TYPE_UNSIGNED (node)
 					? "<unnamed-unsigned:"
 					: "<unnamed-signed:"));
-		    pp_decimal_int (buffer, TYPE_PRECISION (node));
-		    pp_greater (buffer);
+		    pp_decimal_int (pp, TYPE_PRECISION (node));
+		    pp_greater (pp);
 		  }
 	      }
 	    else if (TREE_CODE (node) == COMPLEX_TYPE)
 	      {
-		pp_string (buffer, "__complex__ ");
-		dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
+		pp_string (pp, "__complex__ ");
+		dump_generic_node (pp, TREE_TYPE (node), spc, flags, false);
 	      }
 	    else if (TREE_CODE (node) == REAL_TYPE)
 	      {
-		pp_string (buffer, "<float:");
-		pp_decimal_int (buffer, TYPE_PRECISION (node));
-		pp_greater (buffer);
+		pp_string (pp, "<float:");
+		pp_decimal_int (pp, TYPE_PRECISION (node));
+		pp_greater (pp);
 	      }
 	    else if (TREE_CODE (node) == FIXED_POINT_TYPE)
 	      {
-		pp_string (buffer, "<fixed-point-");
-		pp_string (buffer, TYPE_SATURATING (node) ? "sat:" : "nonsat:");
-		pp_decimal_int (buffer, TYPE_PRECISION (node));
-		pp_greater (buffer);
+		pp_string (pp, "<fixed-point-");
+		pp_string (pp, TYPE_SATURATING (node) ? "sat:" : "nonsat:");
+		pp_decimal_int (pp, TYPE_PRECISION (node));
+		pp_greater (pp);
 	      }
 	    else if (TREE_CODE (node) == VOID_TYPE)
-	      pp_string (buffer, "void");
+	      pp_string (pp, "void");
 	    else
-              pp_string (buffer, "<unnamed type>");
+              pp_string (pp, "<unnamed type>");
 	  }
 	break;
       }
@@ -1018,51 +1018,51 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 
       if (TREE_TYPE (node) == NULL)
         {
-	  pp_string (buffer, str);
-          pp_string (buffer, "<null type>");
+	  pp_string (pp, str);
+          pp_string (pp, "<null type>");
         }
       else if (TREE_CODE (TREE_TYPE (node)) == FUNCTION_TYPE)
         {
 	  tree fnode = TREE_TYPE (node);
 
-	  dump_generic_node (buffer, TREE_TYPE (fnode), spc, flags, false);
-	  pp_space (buffer);
-	  pp_left_paren (buffer);
-	  pp_string (buffer, str);
+	  dump_generic_node (pp, TREE_TYPE (fnode), spc, flags, false);
+	  pp_space (pp);
+	  pp_left_paren (pp);
+	  pp_string (pp, str);
 	  if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node)))
-	    dump_decl_name (buffer, TYPE_NAME (node), flags);
+	    dump_decl_name (pp, TYPE_NAME (node), flags);
 	  else if (flags & TDF_NOUID)
-	    pp_printf (buffer, "<Txxxx>");
+	    pp_printf (pp, "<Txxxx>");
 	  else
-	    pp_printf (buffer, "<T%x>", TYPE_UID (node));
+	    pp_printf (pp, "<T%x>", TYPE_UID (node));
 
-	  pp_right_paren (buffer);
-	  dump_function_declaration (buffer, fnode, spc, flags);
+	  pp_right_paren (pp);
+	  dump_function_declaration (pp, fnode, spc, flags);
 	}
       else
         {
 	  unsigned int quals = TYPE_QUALS (node);
 
-          dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
-	  pp_space (buffer);
-	  pp_string (buffer, str);
+          dump_generic_node (pp, TREE_TYPE (node), spc, flags, false);
+	  pp_space (pp);
+	  pp_string (pp, str);
 
 	  if (quals & TYPE_QUAL_CONST)
-	    pp_string (buffer, " const");
+	    pp_string (pp, " const");
 	  if (quals & TYPE_QUAL_VOLATILE)
-	    pp_string (buffer, " volatile");
+	    pp_string (pp, " volatile");
 	  if (quals & TYPE_QUAL_RESTRICT)
-	    pp_string (buffer, " restrict");
+	    pp_string (pp, " restrict");
 
 	  if (!ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (node)))
 	    {
-	      pp_string (buffer, " <address-space-");
-	      pp_decimal_int (buffer, TYPE_ADDR_SPACE (node));
-	      pp_greater (buffer);
+	      pp_string (pp, " <address-space-");
+	      pp_decimal_int (pp, TYPE_ADDR_SPACE (node));
+	      pp_greater (pp);
 	    }
 
 	  if (TYPE_REF_CAN_ALIAS_ALL (node))
-	    pp_string (buffer, " {ref-all}");
+	    pp_string (pp, " {ref-all}");
 	}
       break;
 
@@ -1094,12 +1094,12 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 	  {
 	    if (TREE_CODE (TREE_OPERAND (node, 0)) != ADDR_EXPR)
 	      {
-		pp_star (buffer);
-		dump_generic_node (buffer, TREE_OPERAND (node, 0),
+		pp_star (pp);
+		dump_generic_node (pp, TREE_OPERAND (node, 0),
 				   spc, flags, false);
 	      }
 	    else
-	      dump_generic_node (buffer,
+	      dump_generic_node (pp,
 				 TREE_OPERAND (TREE_OPERAND (node, 0), 0),
 				 spc, flags, false);
 	  }
@@ -1107,21 +1107,21 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 	  {
 	    tree ptype;
 
-	    pp_string (buffer, "MEM[");
-	    pp_left_paren (buffer);
+	    pp_string (pp, "MEM[");
+	    pp_left_paren (pp);
 	    ptype = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (node, 1)));
-	    dump_generic_node (buffer, ptype,
+	    dump_generic_node (pp, ptype,
 			       spc, flags | TDF_SLIM, false);
-	    pp_right_paren (buffer);
-	    dump_generic_node (buffer, TREE_OPERAND (node, 0),
+	    pp_right_paren (pp);
+	    dump_generic_node (pp, TREE_OPERAND (node, 0),
 			       spc, flags, false);
 	    if (!integer_zerop (TREE_OPERAND (node, 1)))
 	      {
-		pp_string (buffer, " + ");
-		dump_generic_node (buffer, TREE_OPERAND (node, 1),
+		pp_string (pp, " + ");
+		dump_generic_node (pp, TREE_OPERAND (node, 1),
 				   spc, flags, false);
 	      }
-	    pp_right_bracket (buffer);
+	    pp_right_bracket (pp);
 	  }
 	break;
       }
@@ -1131,56 +1131,56 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 	const char *sep = "";
 	tree tmp;
 
-	pp_string (buffer, "MEM[");
+	pp_string (pp, "MEM[");
 
 	if (TREE_CODE (TMR_BASE (node)) == ADDR_EXPR)
 	  {
-	    pp_string (buffer, sep);
+	    pp_string (pp, sep);
 	    sep = ", ";
-	    pp_string (buffer, "symbol: ");
-	    dump_generic_node (buffer, TREE_OPERAND (TMR_BASE (node), 0),
+	    pp_string (pp, "symbol: ");
+	    dump_generic_node (pp, TREE_OPERAND (TMR_BASE (node), 0),
 			       spc, flags, false);
 	  }
 	else
 	  {
-	    pp_string (buffer, sep);
+	    pp_string (pp, sep);
 	    sep = ", ";
-	    pp_string (buffer, "base: ");
-	    dump_generic_node (buffer, TMR_BASE (node), spc, flags, false);
+	    pp_string (pp, "base: ");
+	    dump_generic_node (pp, TMR_BASE (node), spc, flags, false);
 	  }
 	tmp = TMR_INDEX2 (node);
 	if (tmp)
 	  {
-	    pp_string (buffer, sep);
+	    pp_string (pp, sep);
 	    sep = ", ";
-	    pp_string (buffer, "base: ");
-	    dump_generic_node (buffer, tmp, spc, flags, false);
+	    pp_string (pp, "base: ");
+	    dump_generic_node (pp, tmp, spc, flags, false);
 	  }
 	tmp = TMR_INDEX (node);
 	if (tmp)
 	  {
-	    pp_string (buffer, sep);
+	    pp_string (pp, sep);
 	    sep = ", ";
-	    pp_string (buffer, "index: ");
-	    dump_generic_node (buffer, tmp, spc, flags, false);
+	    pp_string (pp, "index: ");
+	    dump_generic_node (pp, tmp, spc, flags, false);
 	  }
 	tmp = TMR_STEP (node);
 	if (tmp)
 	  {
-	    pp_string (buffer, sep);
+	    pp_string (pp, sep);
 	    sep = ", ";
-	    pp_string (buffer, "step: ");
-	    dump_generic_node (buffer, tmp, spc, flags, false);
+	    pp_string (pp, "step: ");
+	    dump_generic_node (pp, tmp, spc, flags, false);
 	  }
 	tmp = TMR_OFFSET (node);
 	if (tmp)
 	  {
-	    pp_string (buffer, sep);
+	    pp_string (pp, sep);
 	    sep = ", ";
-	    pp_string (buffer, "offset: ");
-	    dump_generic_node (buffer, tmp, spc, flags, false);
+	    pp_string (pp, "offset: ");
+	    dump_generic_node (pp, tmp, spc, flags, false);
 	  }
-	pp_right_bracket (buffer);
+	pp_right_bracket (pp);
       }
       break;
 
@@ -1192,11 +1192,11 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 	for (tmp = TREE_TYPE (node); TREE_CODE (tmp) == ARRAY_TYPE;
 	     tmp = TREE_TYPE (tmp))
 	  ;
-	dump_generic_node (buffer, tmp, spc, flags, false);
+	dump_generic_node (pp, tmp, spc, flags, false);
 
 	/* Print the dimensions.  */
 	for (tmp = node; TREE_CODE (tmp) == ARRAY_TYPE; tmp = TREE_TYPE (tmp))
-	  dump_array_domain (buffer, TYPE_DOMAIN (tmp), spc, flags);
+	  dump_array_domain (pp, TYPE_DOMAIN (tmp), spc, flags);
 	break;
       }
 
@@ -1207,27 +1207,27 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 	unsigned int quals = TYPE_QUALS (node);
 
 	if (quals & TYPE_QUAL_ATOMIC)
-	  pp_string (buffer, "atomic ");
+	  pp_string (pp, "atomic ");
 	if (quals & TYPE_QUAL_CONST)
-	  pp_string (buffer, "const ");
+	  pp_string (pp, "const ");
 	if (quals & TYPE_QUAL_VOLATILE)
-	  pp_string (buffer, "volatile ");
+	  pp_string (pp, "volatile ");
 
         /* Print the name of the structure.  */
         if (TREE_CODE (node) == RECORD_TYPE)
-	  pp_string (buffer, "struct ");
+	  pp_string (pp, "struct ");
         else if (TREE_CODE (node) == UNION_TYPE)
-	  pp_string (buffer, "union ");
+	  pp_string (pp, "union ");
 
         if (TYPE_NAME (node))
-	  dump_generic_node (buffer, TYPE_NAME (node), spc, flags, false);
+	  dump_generic_node (pp, TYPE_NAME (node), spc, flags, false);
 	else if (!(flags & TDF_SLIM))
 	  /* FIXME: If we eliminate the 'else' above and attempt
 	     to show the fields for named types, we may get stuck
 	     following a cycle of pointers to structs.  The alleged
 	     self-reference check in print_struct_decl will not detect
 	     cycles involving more than one pointer or struct type.  */
-	  print_struct_decl (buffer, node, spc, flags);
+	  print_struct_decl (pp, node, spc, flags);
         break;
       }
 
@@ -1258,27 +1258,27 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 
              TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (node)))
 	     TYPE_PRECISION (TREE_TYPE (TREE_TYPE (node)))  */
-	  pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
-	  pp_string (buffer, "B"); /* pseudo-unit */
+	  pp_wide_integer (pp, TREE_INT_CST_LOW (node));
+	  pp_string (pp, "B"); /* pseudo-unit */
 	}
       else if (tree_fits_shwi_p (node))
-	pp_wide_integer (buffer, tree_to_shwi (node));
+	pp_wide_integer (pp, tree_to_shwi (node));
       else if (tree_fits_uhwi_p (node))
-	pp_unsigned_wide_integer (buffer, tree_to_uhwi (node));
+	pp_unsigned_wide_integer (pp, tree_to_uhwi (node));
       else
 	{
 	  wide_int val = node;
 
 	  if (wi::neg_p (val, TYPE_SIGN (TREE_TYPE (node))))
 	    {
-	      pp_minus (buffer);
+	      pp_minus (pp);
 	      val = -val;
 	    }
-	  print_hex (val, pp_buffer (buffer)->digit_buffer);
-	  pp_string (buffer, pp_buffer (buffer)->digit_buffer);
+	  print_hex (val, pp_buffer (pp)->digit_buffer);
+	  pp_string (pp, pp_buffer (pp)->digit_buffer);
 	}
       if (TREE_OVERFLOW (node))
-	pp_string (buffer, "(OVF)");
+	pp_string (pp, "(OVF)");
       break;
 
     case REAL_CST:
@@ -1286,27 +1286,27 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       {
 	REAL_VALUE_TYPE d;
 	if (TREE_OVERFLOW (node))
-	  pp_string (buffer, " overflow");
+	  pp_string (pp, " overflow");
 
 #if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
 	d = TREE_REAL_CST (node);
 	if (REAL_VALUE_ISINF (d))
-	  pp_string (buffer, REAL_VALUE_NEGATIVE (d) ? " -Inf" : " Inf");
+	  pp_string (pp, REAL_VALUE_NEGATIVE (d) ? " -Inf" : " Inf");
 	else if (REAL_VALUE_ISNAN (d))
-	  pp_string (buffer, " Nan");
+	  pp_string (pp, " Nan");
 	else
 	  {
 	    char string[100];
 	    real_to_decimal (string, &d, sizeof (string), 0, 1);
-	    pp_string (buffer, string);
+	    pp_string (pp, string);
 	  }
 #else
 	{
 	  HOST_WIDE_INT i;
 	  unsigned char *p = (unsigned char *) &TREE_REAL_CST (node);
-	  pp_string (buffer, "0x");
+	  pp_string (pp, "0x");
 	  for (i = 0; i < sizeof TREE_REAL_CST (node); i++)
-	    output_formatted_integer (buffer, "%02x", *p++);
+	    output_formatted_integer (pp, "%02x", *p++);
 	}
 #endif
 	break;
@@ -1316,77 +1316,77 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       {
 	char string[100];
 	fixed_to_decimal (string, TREE_FIXED_CST_PTR (node), sizeof (string));
-	pp_string (buffer, string);
+	pp_string (pp, string);
 	break;
       }
 
     case COMPLEX_CST:
-      pp_string (buffer, "__complex__ (");
-      dump_generic_node (buffer, TREE_REALPART (node), spc, flags, false);
-      pp_string (buffer, ", ");
-      dump_generic_node (buffer, TREE_IMAGPART (node), spc, flags, false);
-      pp_right_paren (buffer);
+      pp_string (pp, "__complex__ (");
+      dump_generic_node (pp, TREE_REALPART (node), spc, flags, false);
+      pp_string (pp, ", ");
+      dump_generic_node (pp, TREE_IMAGPART (node), spc, flags, false);
+      pp_right_paren (pp);
       break;
 
     case STRING_CST:
-      pp_string (buffer, "\"");
-      pretty_print_string (buffer, TREE_STRING_POINTER (node));
-      pp_string (buffer, "\"");
+      pp_string (pp, "\"");
+      pretty_print_string (pp, TREE_STRING_POINTER (node));
+      pp_string (pp, "\"");
       break;
 
     case VECTOR_CST:
       {
 	unsigned i;
-	pp_string (buffer, "{ ");
+	pp_string (pp, "{ ");
 	for (i = 0; i < VECTOR_CST_NELTS (node); ++i)
 	  {
 	    if (i != 0)
-	      pp_string (buffer, ", ");
-	    dump_generic_node (buffer, VECTOR_CST_ELT (node, i),
+	      pp_string (pp, ", ");
+	    dump_generic_node (pp, VECTOR_CST_ELT (node, i),
 			       spc, flags, false);
 	  }
-	pp_string (buffer, " }");
+	pp_string (pp, " }");
       }
       break;
 
     case FUNCTION_TYPE:
     case METHOD_TYPE:
-      dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
-      pp_space (buffer);
+      dump_generic_node (pp, TREE_TYPE (node), spc, flags, false);
+      pp_space (pp);
       if (TREE_CODE (node) == METHOD_TYPE)
 	{
 	  if (TYPE_METHOD_BASETYPE (node))
-	    dump_decl_name (buffer, TYPE_NAME (TYPE_METHOD_BASETYPE (node)),
+	    dump_decl_name (pp, TYPE_NAME (TYPE_METHOD_BASETYPE (node)),
 			    flags);
 	  else
-	    pp_string (buffer, "<null method basetype>");
-	  pp_colon_colon (buffer);
+	    pp_string (pp, "<null method basetype>");
+	  pp_colon_colon (pp);
 	}
       if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node)))
-	dump_decl_name (buffer, TYPE_NAME (node), flags);
+	dump_decl_name (pp, TYPE_NAME (node), flags);
       else if (flags & TDF_NOUID)
-	pp_printf (buffer, "<Txxxx>");
+	pp_printf (pp, "<Txxxx>");
       else
-	pp_printf (buffer, "<T%x>", TYPE_UID (node));
-      dump_function_declaration (buffer, node, spc, flags);
+	pp_printf (pp, "<T%x>", TYPE_UID (node));
+      dump_function_declaration (pp, node, spc, flags);
       break;
 
     case FUNCTION_DECL:
     case CONST_DECL:
-      dump_decl_name (buffer, node, flags);
+      dump_decl_name (pp, node, flags);
       break;
 
     case LABEL_DECL:
       if (DECL_NAME (node))
-	dump_decl_name (buffer, node, flags);
+	dump_decl_name (pp, node, flags);
       else if (LABEL_DECL_UID (node) != -1)
-	pp_printf (buffer, "<L%d>", (int) LABEL_DECL_UID (node));
+	pp_printf (pp, "<L%d>", (int) LABEL_DECL_UID (node));
       else
 	{
 	  if (flags & TDF_NOUID)
-	    pp_string (buffer, "<D.xxxx>");
+	    pp_string (pp, "<D.xxxx>");
 	  else
-	    pp_printf (buffer, "<D.%u>", DECL_UID (node));
+	    pp_printf (pp, "<D.%u>", DECL_UID (node));
 	}
       break;
 
@@ -1397,7 +1397,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 	  break;
 	}
       if (DECL_NAME (node))
-	dump_decl_name (buffer, node, flags);
+	dump_decl_name (pp, node, flags);
       else if (TYPE_NAME (TREE_TYPE (node)) != node)
 	{
 	  if ((TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
@@ -1406,19 +1406,19 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 	    {
 	      /* The type is a c++ class: all structures have at least
 		 4 methods.  */
-	      pp_string (buffer, "class ");
-	      dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
+	      pp_string (pp, "class ");
+	      dump_generic_node (pp, TREE_TYPE (node), spc, flags, false);
 	    }
 	  else
 	    {
-	      pp_string (buffer,
+	      pp_string (pp,
 			 (TREE_CODE (TREE_TYPE (node)) == UNION_TYPE
 			  ? "union" : "struct "));
-	      dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
+	      dump_generic_node (pp, TREE_TYPE (node), spc, flags, false);
 	    }
 	}
       else
-	pp_string (buffer, "<anon>");
+	pp_string (pp, "<anon>");
       break;
 
     case VAR_DECL:
@@ -1427,11 +1427,11 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
     case DEBUG_EXPR_DECL:
     case NAMESPACE_DECL:
     case NAMELIST_DECL:
-      dump_decl_name (buffer, node, flags);
+      dump_decl_name (pp, node, flags);
       break;
 
     case RESULT_DECL:
-      pp_string (buffer, "<retval>");
+      pp_string (pp, "<retval>");
       break;
 
     case COMPONENT_REF:
@@ -1465,44 +1465,44 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 	  str = "->";
 	}
       if (op_prio (op0) < op_prio (node))
-	pp_left_paren (buffer);
-      dump_generic_node (buffer, op0, spc, flags, false);
+	pp_left_paren (pp);
+      dump_generic_node (pp, op0, spc, flags, false);
       if (op_prio (op0) < op_prio (node))
-	pp_right_paren (buffer);
-      pp_string (buffer, str);
-      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
+	pp_right_paren (pp);
+      pp_string (pp, str);
+      dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
       op0 = component_ref_field_offset (node);
       if (op0 && TREE_CODE (op0) != INTEGER_CST)
 	{
-	  pp_string (buffer, "{off: ");
-	      dump_generic_node (buffer, op0, spc, flags, false);
-	      pp_right_brace (buffer);
+	  pp_string (pp, "{off: ");
+	      dump_generic_node (pp, op0, spc, flags, false);
+	      pp_right_brace (pp);
 	}
       break;
 
     case BIT_FIELD_REF:
-      pp_string (buffer, "BIT_FIELD_REF <");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, ", ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
-      pp_string (buffer, ", ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
-      pp_greater (buffer);
+      pp_string (pp, "BIT_FIELD_REF <");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (pp, ", ");
+      dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
+      pp_string (pp, ", ");
+      dump_generic_node (pp, TREE_OPERAND (node, 2), spc, flags, false);
+      pp_greater (pp);
       break;
 
     case ARRAY_REF:
     case ARRAY_RANGE_REF:
       op0 = TREE_OPERAND (node, 0);
       if (op_prio (op0) < op_prio (node))
-	pp_left_paren (buffer);
-      dump_generic_node (buffer, op0, spc, flags, false);
+	pp_left_paren (pp);
+      dump_generic_node (pp, op0, spc, flags, false);
       if (op_prio (op0) < op_prio (node))
-	pp_right_paren (buffer);
-      pp_left_bracket (buffer);
-      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
+	pp_right_paren (pp);
+      pp_left_bracket (pp);
+      dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
       if (TREE_CODE (node) == ARRAY_RANGE_REF)
-	pp_string (buffer, " ...");
-      pp_right_bracket (buffer);
+	pp_string (pp, " ...");
+      pp_right_bracket (pp);
 
       op0 = array_ref_low_bound (node);
       op1 = array_ref_element_size (node);
@@ -1511,11 +1511,11 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 	  || TREE_OPERAND (node, 2)
 	  || TREE_OPERAND (node, 3))
 	{
-	  pp_string (buffer, "{lb: ");
-	  dump_generic_node (buffer, op0, spc, flags, false);
-	  pp_string (buffer, " sz: ");
-	  dump_generic_node (buffer, op1, spc, flags, false);
-	  pp_right_brace (buffer);
+	  pp_string (pp, "{lb: ");
+	  dump_generic_node (pp, op0, spc, flags, false);
+	  pp_string (pp, " sz: ");
+	  dump_generic_node (pp, op1, spc, flags, false);
+	  pp_right_brace (pp);
 	}
       break;
 
@@ -1526,9 +1526,9 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 	bool is_struct_init = false;
 	bool is_array_init = false;
 	widest_int curidx;
-	pp_left_brace (buffer);
+	pp_left_brace (pp);
 	if (TREE_CLOBBER_P (node))
-	  pp_string (buffer, "CLOBBER");
+	  pp_string (pp, "CLOBBER");
 	else if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
 		 || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
 	  is_struct_init = true;
@@ -1548,30 +1548,30 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 	      {
 		if (is_struct_init)
 		  {
-		    pp_dot (buffer);
-		    dump_generic_node (buffer, field, spc, flags, false);
-		    pp_equal (buffer);
+		    pp_dot (pp);
+		    dump_generic_node (pp, field, spc, flags, false);
+		    pp_equal (pp);
 		  }
 		else if (is_array_init
 			 && (TREE_CODE (field) != INTEGER_CST
 			     || curidx != wi::to_widest (field)))
 		  {
-		    pp_left_bracket (buffer);
+		    pp_left_bracket (pp);
 		    if (TREE_CODE (field) == RANGE_EXPR)
 		      {
-			dump_generic_node (buffer, TREE_OPERAND (field, 0), spc,
+			dump_generic_node (pp, TREE_OPERAND (field, 0), spc,
 					   flags, false);
-			pp_string (buffer, " ... ");
-			dump_generic_node (buffer, TREE_OPERAND (field, 1), spc,
+			pp_string (pp, " ... ");
+			dump_generic_node (pp, TREE_OPERAND (field, 1), spc,
 					   flags, false);
 			if (TREE_CODE (TREE_OPERAND (field, 1)) == INTEGER_CST)
 			  curidx = wi::to_widest (TREE_OPERAND (field, 1));
 		      }
 		    else
-		      dump_generic_node (buffer, field, spc, flags, false);
+		      dump_generic_node (pp, field, spc, flags, false);
 		    if (TREE_CODE (field) == INTEGER_CST)
 		      curidx = wi::to_widest (field);
-		    pp_string (buffer, "]=");
+		    pp_string (pp, "]=");
 		  }
 	      }
             if (is_array_init)
@@ -1580,16 +1580,16 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 	      if (TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL)
 		val = TREE_OPERAND (val, 0);
 	    if (val && TREE_CODE (val) == FUNCTION_DECL)
-		dump_decl_name (buffer, val, flags);
+		dump_decl_name (pp, val, flags);
 	    else
-		dump_generic_node (buffer, val, spc, flags, false);
+		dump_generic_node (pp, val, spc, flags, false);
 	    if (ix != vec_safe_length (CONSTRUCTOR_ELTS (node)) - 1)
 	      {
-		pp_comma (buffer);
-		pp_space (buffer);
+		pp_comma (pp);
+		pp_space (pp);
 	      }
 	  }
-	pp_right_brace (buffer);
+	pp_right_brace (pp);
       }
       break;
 
@@ -1598,36 +1598,36 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 	tree *tp;
 	if (flags & TDF_SLIM)
 	  {
-	    pp_string (buffer, "<COMPOUND_EXPR>");
+	    pp_string (pp, "<COMPOUND_EXPR>");
 	    break;
 	  }
 
-	dump_generic_node (buffer, TREE_OPERAND (node, 0),
+	dump_generic_node (pp, TREE_OPERAND (node, 0),
 			   spc, flags, !(flags & TDF_SLIM));
 	if (flags & TDF_SLIM)
-	  newline_and_indent (buffer, spc);
+	  newline_and_indent (pp, spc);
 	else
 	  {
-	    pp_comma (buffer);
-	    pp_space (buffer);
+	    pp_comma (pp);
+	    pp_space (pp);
 	  }
 
 	for (tp = &TREE_OPERAND (node, 1);
 	     TREE_CODE (*tp) == COMPOUND_EXPR;
 	     tp = &TREE_OPERAND (*tp, 1))
 	  {
-	    dump_generic_node (buffer, TREE_OPERAND (*tp, 0),
+	    dump_generic_node (pp, TREE_OPERAND (*tp, 0),
 			       spc, flags, !(flags & TDF_SLIM));
 	    if (flags & TDF_SLIM)
-	      newline_and_indent (buffer, spc);
+	      newline_and_indent (pp, spc);
 	    else
 	      {
-	        pp_comma (buffer);
-	        pp_space (buffer);
+	        pp_comma (pp);
+	        pp_space (pp);
 	      }
 	  }
 
-	dump_generic_node (buffer, *tp, spc, flags, !(flags & TDF_SLIM));
+	dump_generic_node (pp, *tp, spc, flags, !(flags & TDF_SLIM));
       }
       break;
 
@@ -1638,52 +1638,52 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 
 	if (flags & TDF_SLIM)
 	  {
-	    pp_string (buffer, "<STATEMENT_LIST>");
+	    pp_string (pp, "<STATEMENT_LIST>");
 	    break;
 	  }
 
 	for (si = tsi_start (node); !tsi_end_p (si); tsi_next (&si))
 	  {
 	    if (!first)
-	      newline_and_indent (buffer, spc);
+	      newline_and_indent (pp, spc);
 	    else
 	      first = false;
-	    dump_generic_node (buffer, tsi_stmt (si), spc, flags, true);
+	    dump_generic_node (pp, tsi_stmt (si), spc, flags, true);
 	  }
       }
       break;
 
     case MODIFY_EXPR:
     case INIT_EXPR:
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags,
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags,
 	  		 false);
-      pp_space (buffer);
-      pp_equal (buffer);
-      pp_space (buffer);
-      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags,
+      pp_space (pp);
+      pp_equal (pp);
+      pp_space (pp);
+      dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags,
 	  		 false);
       break;
 
     case TARGET_EXPR:
-      pp_string (buffer, "TARGET_EXPR <");
-      dump_generic_node (buffer, TARGET_EXPR_SLOT (node), spc, flags, false);
-      pp_comma (buffer);
-      pp_space (buffer);
-      dump_generic_node (buffer, TARGET_EXPR_INITIAL (node), spc, flags, false);
-      pp_greater (buffer);
+      pp_string (pp, "TARGET_EXPR <");
+      dump_generic_node (pp, TARGET_EXPR_SLOT (node), spc, flags, false);
+      pp_comma (pp);
+      pp_space (pp);
+      dump_generic_node (pp, TARGET_EXPR_INITIAL (node), spc, flags, false);
+      pp_greater (pp);
       break;
 
     case DECL_EXPR:
-      print_declaration (buffer, DECL_EXPR_DECL (node), spc, flags);
+      print_declaration (pp, DECL_EXPR_DECL (node), spc, flags);
       is_stmt = false;
       break;
 
     case COND_EXPR:
       if (TREE_TYPE (node) == NULL || TREE_TYPE (node) == void_type_node)
 	{
-	  pp_string (buffer, "if (");
-	  dump_generic_node (buffer, COND_EXPR_COND (node), spc, flags, false);
-	  pp_right_paren (buffer);
+	  pp_string (pp, "if (");
+	  dump_generic_node (pp, COND_EXPR_COND (node), spc, flags, false);
+	  pp_right_paren (pp);
 	  /* The lowered cond_exprs should always be printed in full.  */
 	  if (COND_EXPR_THEN (node)
 	      && (IS_EMPTY_STMT (COND_EXPR_THEN (node))
@@ -1692,13 +1692,13 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 	      && (IS_EMPTY_STMT (COND_EXPR_ELSE (node))
 		  || TREE_CODE (COND_EXPR_ELSE (node)) == GOTO_EXPR))
 	    {
-	      pp_space (buffer);
-	      dump_generic_node (buffer, COND_EXPR_THEN (node),
+	      pp_space (pp);
+	      dump_generic_node (pp, COND_EXPR_THEN (node),
 				 0, flags, true);
 	      if (!IS_EMPTY_STMT (COND_EXPR_ELSE (node)))
 		{
-		  pp_string (buffer, " else ");
-		  dump_generic_node (buffer, COND_EXPR_ELSE (node),
+		  pp_string (pp, " else ");
+		  dump_generic_node (pp, COND_EXPR_ELSE (node),
 				     0, flags, true);
 		}
 	    }
@@ -1707,88 +1707,88 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 	      /* Output COND_EXPR_THEN.  */
 	      if (COND_EXPR_THEN (node))
 		{
-		  newline_and_indent (buffer, spc+2);
-		  pp_left_brace (buffer);
-		  newline_and_indent (buffer, spc+4);
-		  dump_generic_node (buffer, COND_EXPR_THEN (node), spc+4,
+		  newline_and_indent (pp, spc+2);
+		  pp_left_brace (pp);
+		  newline_and_indent (pp, spc+4);
+		  dump_generic_node (pp, COND_EXPR_THEN (node), spc+4,
 				     flags, true);
-		  newline_and_indent (buffer, spc+2);
-		  pp_right_brace (buffer);
+		  newline_and_indent (pp, spc+2);
+		  pp_right_brace (pp);
 		}
 
 	      /* Output COND_EXPR_ELSE.  */
 	      if (COND_EXPR_ELSE (node)
 		  && !IS_EMPTY_STMT (COND_EXPR_ELSE (node)))
 		{
-		  newline_and_indent (buffer, spc);
-		  pp_string (buffer, "else");
-		  newline_and_indent (buffer, spc+2);
-		  pp_left_brace (buffer);
-		  newline_and_indent (buffer, spc+4);
-		  dump_generic_node (buffer, COND_EXPR_ELSE (node), spc+4,
+		  newline_and_indent (pp, spc);
+		  pp_string (pp, "else");
+		  newline_and_indent (pp, spc+2);
+		  pp_left_brace (pp);
+		  newline_and_indent (pp, spc+4);
+		  dump_generic_node (pp, COND_EXPR_ELSE (node), spc+4,
 			             flags, true);
-		  newline_and_indent (buffer, spc+2);
-		  pp_right_brace (buffer);
+		  newline_and_indent (pp, spc+2);
+		  pp_right_brace (pp);
 		}
 	    }
 	  is_expr = false;
 	}
       else
 	{
-	  dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-	  pp_space (buffer);
-	  pp_question (buffer);
-	  pp_space (buffer);
-	  dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
-	  pp_space (buffer);
-	  pp_colon (buffer);
-	  pp_space (buffer);
-	  dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
+	  dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+	  pp_space (pp);
+	  pp_question (pp);
+	  pp_space (pp);
+	  dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
+	  pp_space (pp);
+	  pp_colon (pp);
+	  pp_space (pp);
+	  dump_generic_node (pp, TREE_OPERAND (node, 2), spc, flags, false);
 	}
       break;
 
     case BIND_EXPR:
-      pp_left_brace (buffer);
+      pp_left_brace (pp);
       if (!(flags & TDF_SLIM))
 	{
 	  if (BIND_EXPR_VARS (node))
 	    {
-	      pp_newline (buffer);
+	      pp_newline (pp);
 
 	      for (op0 = BIND_EXPR_VARS (node); op0; op0 = DECL_CHAIN (op0))
 		{
-		  print_declaration (buffer, op0, spc+2, flags);
-		  pp_newline (buffer);
+		  print_declaration (pp, op0, spc+2, flags);
+		  pp_newline (pp);
 		}
 	    }
 
-	  newline_and_indent (buffer, spc+2);
-	  dump_generic_node (buffer, BIND_EXPR_BODY (node), spc+2, flags, true);
-	  newline_and_indent (buffer, spc);
-	  pp_right_brace (buffer);
+	  newline_and_indent (pp, spc+2);
+	  dump_generic_node (pp, BIND_EXPR_BODY (node), spc+2, flags, true);
+	  newline_and_indent (pp, spc);
+	  pp_right_brace (pp);
 	}
       is_expr = false;
       break;
 
     case CALL_EXPR:
       if (CALL_EXPR_FN (node) != NULL_TREE)
-	print_call_name (buffer, CALL_EXPR_FN (node), flags);
+	print_call_name (pp, CALL_EXPR_FN (node), flags);
       else
-	pp_string (buffer, internal_fn_name (CALL_EXPR_IFN (node)));
+	pp_string (pp, internal_fn_name (CALL_EXPR_IFN (node)));
 
       /* Print parameters.  */
-      pp_space (buffer);
-      pp_left_paren (buffer);
+      pp_space (pp);
+      pp_left_paren (pp);
       {
 	tree arg;
 	call_expr_arg_iterator iter;
 	FOR_EACH_CALL_EXPR_ARG (arg, iter, node)
 	  {
-	    dump_generic_node (buffer, arg, spc, flags, false);
+	    dump_generic_node (pp, arg, spc, flags, false);
 	    if (more_call_expr_args_p (&iter))
 	      {
-		pp_comma (buffer);
-		pp_space (buffer);
+		pp_comma (pp);
+		pp_space (pp);
 	      }
 	  }
       }
@@ -1796,25 +1796,25 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 	{
 	  if (call_expr_nargs (node) > 0)
 	    {
-	      pp_comma (buffer);
-	      pp_space (buffer);
+	      pp_comma (pp);
+	      pp_space (pp);
 	    }
-	  pp_string (buffer, "__builtin_va_arg_pack ()");
+	  pp_string (pp, "__builtin_va_arg_pack ()");
 	}
-      pp_right_paren (buffer);
+      pp_right_paren (pp);
 
       op1 = CALL_EXPR_STATIC_CHAIN (node);
       if (op1)
 	{
-	  pp_string (buffer, " [static-chain: ");
-	  dump_generic_node (buffer, op1, spc, flags, false);
-	  pp_right_bracket (buffer);
+	  pp_string (pp, " [static-chain: ");
+	  dump_generic_node (pp, op1, spc, flags, false);
+	  pp_right_bracket (pp);
 	}
 
       if (CALL_EXPR_RETURN_SLOT_OPT (node))
-	pp_string (buffer, " [return slot optimization]");
+	pp_string (pp, " [return slot optimization]");
       if (CALL_EXPR_TAILCALL (node))
-	pp_string (buffer, " [tail call]");
+	pp_string (pp, " [tail call]");
       break;
 
     case WITH_CLEANUP_EXPR:
@@ -1822,15 +1822,15 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       break;
 
     case CLEANUP_POINT_EXPR:
-      pp_string (buffer, "<<cleanup_point ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, ">>");
+      pp_string (pp, "<<cleanup_point ");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (pp, ">>");
       break;
 
     case PLACEHOLDER_EXPR:
-      pp_string (buffer, "<PLACEHOLDER_EXPR ");
-      dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
-      pp_greater (buffer);
+      pp_string (pp, "<PLACEHOLDER_EXPR ");
+      dump_generic_node (pp, TREE_TYPE (node), spc, flags, false);
+      pp_greater (pp);
       break;
 
       /* Binary arithmetic and logic expressions.  */
@@ -1887,27 +1887,27 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 	   keep semantics of the tree representation.  */
 	if (op_prio (op0) <= op_prio (node))
 	  {
-	    pp_left_paren (buffer);
-	    dump_generic_node (buffer, op0, spc, flags, false);
-	    pp_right_paren (buffer);
+	    pp_left_paren (pp);
+	    dump_generic_node (pp, op0, spc, flags, false);
+	    pp_right_paren (pp);
 	  }
 	else
-	  dump_generic_node (buffer, op0, spc, flags, false);
+	  dump_generic_node (pp, op0, spc, flags, false);
 
-	pp_space (buffer);
-	pp_string (buffer, op);
-	pp_space (buffer);
+	pp_space (pp);
+	pp_string (pp, op);
+	pp_space (pp);
 
 	/* When the operands are expressions with less priority,
 	   keep semantics of the tree representation.  */
 	if (op_prio (op1) <= op_prio (node))
 	  {
-	    pp_left_paren (buffer);
-	    dump_generic_node (buffer, op1, spc, flags, false);
-	    pp_right_paren (buffer);
+	    pp_left_paren (pp);
+	    dump_generic_node (pp, op1, spc, flags, false);
+	    pp_right_paren (pp);
 	  }
 	else
-	  dump_generic_node (buffer, op1, spc, flags, false);
+	  dump_generic_node (pp, op1, spc, flags, false);
       }
       break;
 
@@ -1924,51 +1924,51 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 	      || TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL))
 	;	/* Do not output '&' for strings and function pointers.  */
       else
-	pp_string (buffer, op_symbol (node));
+	pp_string (pp, op_symbol (node));
 
       if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
 	{
-	  pp_left_paren (buffer);
-	  dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-	  pp_right_paren (buffer);
+	  pp_left_paren (pp);
+	  dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+	  pp_right_paren (pp);
 	}
       else
-	dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+	dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
       break;
 
     case POSTDECREMENT_EXPR:
     case POSTINCREMENT_EXPR:
       if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
 	{
-	  pp_left_paren (buffer);
-	  dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-	  pp_right_paren (buffer);
+	  pp_left_paren (pp);
+	  dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+	  pp_right_paren (pp);
 	}
       else
-	dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, op_symbol (node));
+	dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (pp, op_symbol (node));
       break;
 
     case MIN_EXPR:
-      pp_string (buffer, "MIN_EXPR <");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, ", ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
-      pp_greater (buffer);
+      pp_string (pp, "MIN_EXPR <");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (pp, ", ");
+      dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
+      pp_greater (pp);
       break;
 
     case MAX_EXPR:
-      pp_string (buffer, "MAX_EXPR <");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, ", ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
-      pp_greater (buffer);
+      pp_string (pp, "MAX_EXPR <");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (pp, ", ");
+      dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
+      pp_greater (pp);
       break;
 
     case ABS_EXPR:
-      pp_string (buffer, "ABS_EXPR <");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_greater (buffer);
+      pp_string (pp, "ABS_EXPR <");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_greater (pp);
       break;
 
     case RANGE_EXPR:
@@ -1984,119 +1984,119 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       op0 = TREE_OPERAND (node, 0);
       if (type != TREE_TYPE (op0))
 	{
-	  pp_left_paren (buffer);
-	  dump_generic_node (buffer, type, spc, flags, false);
-	  pp_string (buffer, ") ");
+	  pp_left_paren (pp);
+	  dump_generic_node (pp, type, spc, flags, false);
+	  pp_string (pp, ") ");
 	}
       if (op_prio (op0) < op_prio (node))
-	pp_left_paren (buffer);
-      dump_generic_node (buffer, op0, spc, flags, false);
+	pp_left_paren (pp);
+      dump_generic_node (pp, op0, spc, flags, false);
       if (op_prio (op0) < op_prio (node))
-	pp_right_paren (buffer);
+	pp_right_paren (pp);
       break;
 
     case VIEW_CONVERT_EXPR:
-      pp_string (buffer, "VIEW_CONVERT_EXPR<");
-      dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
-      pp_string (buffer, ">(");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_right_paren (buffer);
+      pp_string (pp, "VIEW_CONVERT_EXPR<");
+      dump_generic_node (pp, TREE_TYPE (node), spc, flags, false);
+      pp_string (pp, ">(");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_right_paren (pp);
       break;
 
     case PAREN_EXPR:
-      pp_string (buffer, "((");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, "))");
+      pp_string (pp, "((");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (pp, "))");
       break;
 
     case NON_LVALUE_EXPR:
-      pp_string (buffer, "NON_LVALUE_EXPR <");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_greater (buffer);
+      pp_string (pp, "NON_LVALUE_EXPR <");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_greater (pp);
       break;
 
     case SAVE_EXPR:
-      pp_string (buffer, "SAVE_EXPR <");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_greater (buffer);
+      pp_string (pp, "SAVE_EXPR <");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_greater (pp);
       break;
 
     case COMPLEX_EXPR:
-      pp_string (buffer, "COMPLEX_EXPR <");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, ", ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
-      pp_greater (buffer);
+      pp_string (pp, "COMPLEX_EXPR <");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (pp, ", ");
+      dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
+      pp_greater (pp);
       break;
 
     case CONJ_EXPR:
-      pp_string (buffer, "CONJ_EXPR <");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_greater (buffer);
+      pp_string (pp, "CONJ_EXPR <");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_greater (pp);
       break;
 
     case REALPART_EXPR:
-      pp_string (buffer, "REALPART_EXPR <");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_greater (buffer);
+      pp_string (pp, "REALPART_EXPR <");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_greater (pp);
       break;
 
     case IMAGPART_EXPR:
-      pp_string (buffer, "IMAGPART_EXPR <");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_greater (buffer);
+      pp_string (pp, "IMAGPART_EXPR <");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_greater (pp);
       break;
 
     case VA_ARG_EXPR:
-      pp_string (buffer, "VA_ARG_EXPR <");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_greater (buffer);
+      pp_string (pp, "VA_ARG_EXPR <");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_greater (pp);
       break;
 
     case TRY_FINALLY_EXPR:
     case TRY_CATCH_EXPR:
-      pp_string (buffer, "try");
-      newline_and_indent (buffer, spc+2);
-      pp_left_brace (buffer);
-      newline_and_indent (buffer, spc+4);
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc+4, flags, true);
-      newline_and_indent (buffer, spc+2);
-      pp_right_brace (buffer);
-      newline_and_indent (buffer, spc);
-      pp_string (buffer,
+      pp_string (pp, "try");
+      newline_and_indent (pp, spc+2);
+      pp_left_brace (pp);
+      newline_and_indent (pp, spc+4);
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc+4, flags, true);
+      newline_and_indent (pp, spc+2);
+      pp_right_brace (pp);
+      newline_and_indent (pp, spc);
+      pp_string (pp,
 			 (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
-      newline_and_indent (buffer, spc+2);
-      pp_left_brace (buffer);
-      newline_and_indent (buffer, spc+4);
-      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc+4, flags, true);
-      newline_and_indent (buffer, spc+2);
-      pp_right_brace (buffer);
+      newline_and_indent (pp, spc+2);
+      pp_left_brace (pp);
+      newline_and_indent (pp, spc+4);
+      dump_generic_node (pp, TREE_OPERAND (node, 1), spc+4, flags, true);
+      newline_and_indent (pp, spc+2);
+      pp_right_brace (pp);
       is_expr = false;
       break;
 
     case CATCH_EXPR:
-      pp_string (buffer, "catch (");
-      dump_generic_node (buffer, CATCH_TYPES (node), spc+2, flags, false);
-      pp_right_paren (buffer);
-      newline_and_indent (buffer, spc+2);
-      pp_left_brace (buffer);
-      newline_and_indent (buffer, spc+4);
-      dump_generic_node (buffer, CATCH_BODY (node), spc+4, flags, true);
-      newline_and_indent (buffer, spc+2);
-      pp_right_brace (buffer);
+      pp_string (pp, "catch (");
+      dump_generic_node (pp, CATCH_TYPES (node), spc+2, flags, false);
+      pp_right_paren (pp);
+      newline_and_indent (pp, spc+2);
+      pp_left_brace (pp);
+      newline_and_indent (pp, spc+4);
+      dump_generic_node (pp, CATCH_BODY (node), spc+4, flags, true);
+      newline_and_indent (pp, spc+2);
+      pp_right_brace (pp);
       is_expr = false;
       break;
 
     case EH_FILTER_EXPR:
-      pp_string (buffer, "<<<eh_filter (");
-      dump_generic_node (buffer, EH_FILTER_TYPES (node), spc+2, flags, false);
-      pp_string (buffer, ")>>>");
-      newline_and_indent (buffer, spc+2);
-      pp_left_brace (buffer);
-      newline_and_indent (buffer, spc+4);
-      dump_generic_node (buffer, EH_FILTER_FAILURE (node), spc+4, flags, true);
-      newline_and_indent (buffer, spc+2);
-      pp_right_brace (buffer);
+      pp_string (pp, "<<<eh_filter (");
+      dump_generic_node (pp, EH_FILTER_TYPES (node), spc+2, flags, false);
+      pp_string (pp, ")>>>");
+      newline_and_indent (pp, spc+2);
+      pp_left_brace (pp);
+      newline_and_indent (pp, spc+4);
+      dump_generic_node (pp, EH_FILTER_FAILURE (node), spc+4, flags, true);
+      newline_and_indent (pp, spc+2);
+      pp_right_brace (pp);
       is_expr = false;
       break;
 
@@ -2110,88 +2110,88 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 	      || strcmp (name, "continue") == 0)
 	    break;
 	}
-      dump_generic_node (buffer, op0, spc, flags, false);
-      pp_colon (buffer);
+      dump_generic_node (pp, op0, spc, flags, false);
+      pp_colon (pp);
       if (DECL_NONLOCAL (op0))
-	pp_string (buffer, " [non-local]");
+	pp_string (pp, " [non-local]");
       break;
 
     case LOOP_EXPR:
-      pp_string (buffer, "while (1)");
+      pp_string (pp, "while (1)");
       if (!(flags & TDF_SLIM))
 	{
-	  newline_and_indent (buffer, spc+2);
-	  pp_left_brace (buffer);
-	  newline_and_indent (buffer, spc+4);
-	  dump_generic_node (buffer, LOOP_EXPR_BODY (node), spc+4, flags, true);
-	  newline_and_indent (buffer, spc+2);
-	  pp_right_brace (buffer);
+	  newline_and_indent (pp, spc+2);
+	  pp_left_brace (pp);
+	  newline_and_indent (pp, spc+4);
+	  dump_generic_node (pp, LOOP_EXPR_BODY (node), spc+4, flags, true);
+	  newline_and_indent (pp, spc+2);
+	  pp_right_brace (pp);
 	}
       is_expr = false;
       break;
 
     case PREDICT_EXPR:
-      pp_string (buffer, "// predicted ");
+      pp_string (pp, "// predicted ");
       if (PREDICT_EXPR_OUTCOME (node))
-        pp_string (buffer, "likely by ");
+        pp_string (pp, "likely by ");
       else
-        pp_string (buffer, "unlikely by ");
-      pp_string (buffer, predictor_name (PREDICT_EXPR_PREDICTOR (node)));
-      pp_string (buffer, " predictor.");
+        pp_string (pp, "unlikely by ");
+      pp_string (pp, predictor_name (PREDICT_EXPR_PREDICTOR (node)));
+      pp_string (pp, " predictor.");
       break;
 
     case ANNOTATE_EXPR:
-      pp_string (buffer, "ANNOTATE_EXPR <");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (pp, "ANNOTATE_EXPR <");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
       switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (node, 1)))
 	{
 	case annot_expr_ivdep_kind:
-	  pp_string (buffer, ", ivdep");
+	  pp_string (pp, ", ivdep");
 	  break;
 	case annot_expr_no_vector_kind:
-	  pp_string (buffer, ", no-vector");
+	  pp_string (pp, ", no-vector");
 	  break;
 	case annot_expr_vector_kind:
-	  pp_string (buffer, ", vector");
+	  pp_string (pp, ", vector");
 	  break;
 	default:
 	  gcc_unreachable ();
 	}
-      pp_greater (buffer);
+      pp_greater (pp);
       break;
 
     case RETURN_EXPR:
-      pp_string (buffer, "return");
+      pp_string (pp, "return");
       op0 = TREE_OPERAND (node, 0);
       if (op0)
 	{
-	  pp_space (buffer);
+	  pp_space (pp);
 	  if (TREE_CODE (op0) == MODIFY_EXPR)
-	    dump_generic_node (buffer, TREE_OPERAND (op0, 1),
+	    dump_generic_node (pp, TREE_OPERAND (op0, 1),
 			       spc, flags, false);
 	  else
-	    dump_generic_node (buffer, op0, spc, flags, false);
+	    dump_generic_node (pp, op0, spc, flags, false);
 	}
       break;
 
     case EXIT_EXPR:
-      pp_string (buffer, "if (");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, ") break");
+      pp_string (pp, "if (");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (pp, ") break");
       break;
 
     case SWITCH_EXPR:
-      pp_string (buffer, "switch (");
-      dump_generic_node (buffer, SWITCH_COND (node), spc, flags, false);
-      pp_right_paren (buffer);
+      pp_string (pp, "switch (");
+      dump_generic_node (pp, SWITCH_COND (node), spc, flags, false);
+      pp_right_paren (pp);
       if (!(flags & TDF_SLIM))
 	{
-	  newline_and_indent (buffer, spc+2);
-	  pp_left_brace (buffer);
+	  newline_and_indent (pp, spc+2);
+	  pp_left_brace (pp);
 	  if (SWITCH_BODY (node))
 	    {
-	      newline_and_indent (buffer, spc+4);
-	      dump_generic_node (buffer, SWITCH_BODY (node), spc+4, flags,
+	      newline_and_indent (pp, spc+4);
+	      dump_generic_node (pp, SWITCH_BODY (node), spc+4, flags,
 		                 true);
 	    }
 	  else
@@ -2201,21 +2201,21 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 	      for (i = 0; i < n; ++i)
 		{
 		  tree elt = TREE_VEC_ELT (vec, i);
-		  newline_and_indent (buffer, spc+4);
+		  newline_and_indent (pp, spc+4);
 		  if (elt)
 		    {
-		      dump_generic_node (buffer, elt, spc+4, flags, false);
-		      pp_string (buffer, " goto ");
-		      dump_generic_node (buffer, CASE_LABEL (elt), spc+4,
+		      dump_generic_node (pp, elt, spc+4, flags, false);
+		      pp_string (pp, " goto ");
+		      dump_generic_node (pp, CASE_LABEL (elt), spc+4,
 					 flags, true);
-		      pp_semicolon (buffer);
+		      pp_semicolon (pp);
 		    }
 		  else
-		    pp_string (buffer, "case ???: goto ???;");
+		    pp_string (pp, "case ???: goto ???;");
 		}
 	    }
-	  newline_and_indent (buffer, spc+2);
-	  pp_right_brace (buffer);
+	  newline_and_indent (pp, spc+2);
+	  pp_right_brace (pp);
 	}
       is_expr = false;
       break;
@@ -2228,214 +2228,214 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 	  if (strcmp (name, "break") == 0
 	      || strcmp (name, "continue") == 0)
 	    {
-	      pp_string (buffer, name);
+	      pp_string (pp, name);
 	      break;
 	    }
 	}
-      pp_string (buffer, "goto ");
-      dump_generic_node (buffer, op0, spc, flags, false);
+      pp_string (pp, "goto ");
+      dump_generic_node (pp, op0, spc, flags, false);
       break;
 
     case ASM_EXPR:
-      pp_string (buffer, "__asm__");
+      pp_string (pp, "__asm__");
       if (ASM_VOLATILE_P (node))
-	pp_string (buffer, " __volatile__");
-      pp_left_paren (buffer);
-      dump_generic_node (buffer, ASM_STRING (node), spc, flags, false);
-      pp_colon (buffer);
-      dump_generic_node (buffer, ASM_OUTPUTS (node), spc, flags, false);
-      pp_colon (buffer);
-      dump_generic_node (buffer, ASM_INPUTS (node), spc, flags, false);
+	pp_string (pp, " __volatile__");
+      pp_left_paren (pp);
+      dump_generic_node (pp, ASM_STRING (node), spc, flags, false);
+      pp_colon (pp);
+      dump_generic_node (pp, ASM_OUTPUTS (node), spc, flags, false);
+      pp_colon (pp);
+      dump_generic_node (pp, ASM_INPUTS (node), spc, flags, false);
       if (ASM_CLOBBERS (node))
 	{
-	  pp_colon (buffer);
-	  dump_generic_node (buffer, ASM_CLOBBERS (node), spc, flags, false);
+	  pp_colon (pp);
+	  dump_generic_node (pp, ASM_CLOBBERS (node), spc, flags, false);
 	}
-      pp_right_paren (buffer);
+      pp_right_paren (pp);
       break;
 
     case CASE_LABEL_EXPR:
       if (CASE_LOW (node) && CASE_HIGH (node))
 	{
-	  pp_string (buffer, "case ");
-	  dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
-	  pp_string (buffer, " ... ");
-	  dump_generic_node (buffer, CASE_HIGH (node), spc, flags, false);
+	  pp_string (pp, "case ");
+	  dump_generic_node (pp, CASE_LOW (node), spc, flags, false);
+	  pp_string (pp, " ... ");
+	  dump_generic_node (pp, CASE_HIGH (node), spc, flags, false);
 	}
       else if (CASE_LOW (node))
 	{
-	  pp_string (buffer, "case ");
-	  dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
+	  pp_string (pp, "case ");
+	  dump_generic_node (pp, CASE_LOW (node), spc, flags, false);
 	}
       else
-	pp_string (buffer, "default");
-      pp_colon (buffer);
+	pp_string (pp, "default");
+      pp_colon (pp);
       break;
 
     case OBJ_TYPE_REF:
-      pp_string (buffer, "OBJ_TYPE_REF(");
-      dump_generic_node (buffer, OBJ_TYPE_REF_EXPR (node), spc, flags, false);
-      pp_semicolon (buffer);
+      pp_string (pp, "OBJ_TYPE_REF(");
+      dump_generic_node (pp, OBJ_TYPE_REF_EXPR (node), spc, flags, false);
+      pp_semicolon (pp);
       if (!(flags & TDF_SLIM) && virtual_method_call_p (node))
 	{
-	  pp_string (buffer, "(");
-	  dump_generic_node (buffer, obj_type_ref_class (node), spc, flags, false);
-	  pp_string (buffer, ")");
+	  pp_string (pp, "(");
+	  dump_generic_node (pp, obj_type_ref_class (node), spc, flags, false);
+	  pp_string (pp, ")");
 	}
-      dump_generic_node (buffer, OBJ_TYPE_REF_OBJECT (node), spc, flags, false);
-      pp_arrow (buffer);
-      dump_generic_node (buffer, OBJ_TYPE_REF_TOKEN (node), spc, flags, false);
-      pp_right_paren (buffer);
+      dump_generic_node (pp, OBJ_TYPE_REF_OBJECT (node), spc, flags, false);
+      pp_arrow (pp);
+      dump_generic_node (pp, OBJ_TYPE_REF_TOKEN (node), spc, flags, false);
+      pp_right_paren (pp);
       break;
 
     case SSA_NAME:
       if (SSA_NAME_IDENTIFIER (node))
-	dump_generic_node (buffer, SSA_NAME_IDENTIFIER (node),
+	dump_generic_node (pp, SSA_NAME_IDENTIFIER (node),
 			   spc, flags, false);
-      pp_underscore (buffer);
-      pp_decimal_int (buffer, SSA_NAME_VERSION (node));
+      pp_underscore (pp);
+      pp_decimal_int (pp, SSA_NAME_VERSION (node));
       if (SSA_NAME_IS_DEFAULT_DEF (node))
-	pp_string (buffer, "(D)");
+	pp_string (pp, "(D)");
       if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (node))
-	pp_string (buffer, "(ab)");
+	pp_string (pp, "(ab)");
       break;
 
     case WITH_SIZE_EXPR:
-      pp_string (buffer, "WITH_SIZE_EXPR <");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, ", ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
-      pp_greater (buffer);
+      pp_string (pp, "WITH_SIZE_EXPR <");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (pp, ", ");
+      dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
+      pp_greater (pp);
       break;
 
     case ASSERT_EXPR:
-      pp_string (buffer, "ASSERT_EXPR <");
-      dump_generic_node (buffer, ASSERT_EXPR_VAR (node), spc, flags, false);
-      pp_string (buffer, ", ");
-      dump_generic_node (buffer, ASSERT_EXPR_COND (node), spc, flags, false);
-      pp_greater (buffer);
+      pp_string (pp, "ASSERT_EXPR <");
+      dump_generic_node (pp, ASSERT_EXPR_VAR (node), spc, flags, false);
+      pp_string (pp, ", ");
+      dump_generic_node (pp, ASSERT_EXPR_COND (node), spc, flags, false);
+      pp_greater (pp);
       break;
 
     case SCEV_KNOWN:
-      pp_string (buffer, "scev_known");
+      pp_string (pp, "scev_known");
       break;
 
     case SCEV_NOT_KNOWN:
-      pp_string (buffer, "scev_not_known");
+      pp_string (pp, "scev_not_known");
       break;
 
     case POLYNOMIAL_CHREC:
-      pp_left_brace (buffer);
-      dump_generic_node (buffer, CHREC_LEFT (node), spc, flags, false);
-      pp_string (buffer, ", +, ");
-      dump_generic_node (buffer, CHREC_RIGHT (node), spc, flags, false);
-      pp_string (buffer, "}_");
-      dump_generic_node (buffer, CHREC_VAR (node), spc, flags, false);
+      pp_left_brace (pp);
+      dump_generic_node (pp, CHREC_LEFT (node), spc, flags, false);
+      pp_string (pp, ", +, ");
+      dump_generic_node (pp, CHREC_RIGHT (node), spc, flags, false);
+      pp_string (pp, "}_");
+      dump_generic_node (pp, CHREC_VAR (node), spc, flags, false);
       is_stmt = false;
       break;
 
     case REALIGN_LOAD_EXPR:
-      pp_string (buffer, "REALIGN_LOAD <");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, ", ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
-      pp_string (buffer, ", ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
-      pp_greater (buffer);
+      pp_string (pp, "REALIGN_LOAD <");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (pp, ", ");
+      dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
+      pp_string (pp, ", ");
+      dump_generic_node (pp, TREE_OPERAND (node, 2), spc, flags, false);
+      pp_greater (pp);
       break;
 
     case VEC_COND_EXPR:
-      pp_string (buffer, " VEC_COND_EXPR < ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, " , ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
-      pp_string (buffer, " , ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
-      pp_string (buffer, " > ");
+      pp_string (pp, " VEC_COND_EXPR < ");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (pp, " , ");
+      dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
+      pp_string (pp, " , ");
+      dump_generic_node (pp, TREE_OPERAND (node, 2), spc, flags, false);
+      pp_string (pp, " > ");
       break;
     
     case VEC_PERM_EXPR:
-      pp_string (buffer, " VEC_PERM_EXPR < ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, " , ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
-      pp_string (buffer, " , ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
-      pp_string (buffer, " > ");
+      pp_string (pp, " VEC_PERM_EXPR < ");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (pp, " , ");
+      dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
+      pp_string (pp, " , ");
+      dump_generic_node (pp, TREE_OPERAND (node, 2), spc, flags, false);
+      pp_string (pp, " > ");
       break;
 
     case DOT_PROD_EXPR:
-      pp_string (buffer, " DOT_PROD_EXPR < ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, ", ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
-      pp_string (buffer, ", ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
-      pp_string (buffer, " > ");
+      pp_string (pp, " DOT_PROD_EXPR < ");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (pp, ", ");
+      dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
+      pp_string (pp, ", ");
+      dump_generic_node (pp, TREE_OPERAND (node, 2), spc, flags, false);
+      pp_string (pp, " > ");
       break;
 
     case WIDEN_MULT_PLUS_EXPR:
-      pp_string (buffer, " WIDEN_MULT_PLUS_EXPR < ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, ", ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
-      pp_string (buffer, ", ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
-      pp_string (buffer, " > ");
+      pp_string (pp, " WIDEN_MULT_PLUS_EXPR < ");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (pp, ", ");
+      dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
+      pp_string (pp, ", ");
+      dump_generic_node (pp, TREE_OPERAND (node, 2), spc, flags, false);
+      pp_string (pp, " > ");
       break;
 
     case WIDEN_MULT_MINUS_EXPR:
-      pp_string (buffer, " WIDEN_MULT_MINUS_EXPR < ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, ", ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
-      pp_string (buffer, ", ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
-      pp_string (buffer, " > ");
+      pp_string (pp, " WIDEN_MULT_MINUS_EXPR < ");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (pp, ", ");
+      dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
+      pp_string (pp, ", ");
+      dump_generic_node (pp, TREE_OPERAND (node, 2), spc, flags, false);
+      pp_string (pp, " > ");
       break;
 
     case FMA_EXPR:
-      pp_string (buffer, " FMA_EXPR < ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, ", ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
-      pp_string (buffer, ", ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
-      pp_string (buffer, " > ");
+      pp_string (pp, " FMA_EXPR < ");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (pp, ", ");
+      dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
+      pp_string (pp, ", ");
+      dump_generic_node (pp, TREE_OPERAND (node, 2), spc, flags, false);
+      pp_string (pp, " > ");
       break;
 
     case OMP_PARALLEL:
-      pp_string (buffer, "#pragma omp parallel");
-      dump_omp_clauses (buffer, OMP_PARALLEL_CLAUSES (node), spc, flags);
+      pp_string (pp, "#pragma omp parallel");
+      dump_omp_clauses (pp, OMP_PARALLEL_CLAUSES (node), spc, flags);
 
     dump_omp_body:
       if (!(flags & TDF_SLIM) && OMP_BODY (node))
 	{
-	  newline_and_indent (buffer, spc + 2);
-	  pp_left_brace (buffer);
-	  newline_and_indent (buffer, spc + 4);
-	  dump_generic_node (buffer, OMP_BODY (node), spc + 4, flags, false);
-	  newline_and_indent (buffer, spc + 2);
-	  pp_right_brace (buffer);
+	  newline_and_indent (pp, spc + 2);
+	  pp_left_brace (pp);
+	  newline_and_indent (pp, spc + 4);
+	  dump_generic_node (pp, OMP_BODY (node), spc + 4, flags, false);
+	  newline_and_indent (pp, spc + 2);
+	  pp_right_brace (pp);
 	}
       is_expr = false;
       break;
 
     case OMP_TASK:
-      pp_string (buffer, "#pragma omp task");
-      dump_omp_clauses (buffer, OMP_TASK_CLAUSES (node), spc, flags);
+      pp_string (pp, "#pragma omp task");
+      dump_omp_clauses (pp, OMP_TASK_CLAUSES (node), spc, flags);
       goto dump_omp_body;
 
     case OMP_FOR:
-      pp_string (buffer, "#pragma omp for");
+      pp_string (pp, "#pragma omp for");
       goto dump_omp_loop;
 
     case OMP_SIMD:
-      pp_string (buffer, "#pragma omp simd");
+      pp_string (pp, "#pragma omp simd");
       goto dump_omp_loop;
 
     case CILK_SIMD:
-      pp_string (buffer, "#pragma simd");
+      pp_string (pp, "#pragma simd");
       goto dump_omp_loop;
 
     case CILK_FOR:
@@ -2445,32 +2445,32 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       goto dump_omp_loop_cilk_for;
 
     case OMP_DISTRIBUTE:
-      pp_string (buffer, "#pragma omp distribute");
+      pp_string (pp, "#pragma omp distribute");
       goto dump_omp_loop;
 
     case OMP_TEAMS:
-      pp_string (buffer, "#pragma omp teams");
-      dump_omp_clauses (buffer, OMP_TEAMS_CLAUSES (node), spc, flags);
+      pp_string (pp, "#pragma omp teams");
+      dump_omp_clauses (pp, OMP_TEAMS_CLAUSES (node), spc, flags);
       goto dump_omp_body;
 
     case OMP_TARGET_DATA:
-      pp_string (buffer, "#pragma omp target data");
-      dump_omp_clauses (buffer, OMP_TARGET_DATA_CLAUSES (node), spc, flags);
+      pp_string (pp, "#pragma omp target data");
+      dump_omp_clauses (pp, OMP_TARGET_DATA_CLAUSES (node), spc, flags);
       goto dump_omp_body;
 
     case OMP_TARGET:
-      pp_string (buffer, "#pragma omp target");
-      dump_omp_clauses (buffer, OMP_TARGET_CLAUSES (node), spc, flags);
+      pp_string (pp, "#pragma omp target");
+      dump_omp_clauses (pp, OMP_TARGET_CLAUSES (node), spc, flags);
       goto dump_omp_body;
 
     case OMP_TARGET_UPDATE:
-      pp_string (buffer, "#pragma omp target update");
-      dump_omp_clauses (buffer, OMP_TARGET_UPDATE_CLAUSES (node), spc, flags);
+      pp_string (pp, "#pragma omp target update");
+      dump_omp_clauses (pp, OMP_TARGET_UPDATE_CLAUSES (node), spc, flags);
       is_expr = false;
       break;
 
     dump_omp_loop:
-      dump_omp_clauses (buffer, OMP_FOR_CLAUSES (node), spc, flags);
+      dump_omp_clauses (pp, OMP_FOR_CLAUSES (node), spc, flags);
 
     dump_omp_loop_cilk_for:
       if (!(flags & TDF_SLIM))
@@ -2480,13 +2480,13 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 	  if (OMP_FOR_PRE_BODY (node))
 	    {
 	      if (TREE_CODE (node) == CILK_FOR)
-		pp_string (buffer, "  ");
+		pp_string (pp, "  ");
 	      else
-		newline_and_indent (buffer, spc + 2);
-	      pp_left_brace (buffer);
+		newline_and_indent (pp, spc + 2);
+	      pp_left_brace (pp);
 	      spc += 4;
-	      newline_and_indent (buffer, spc);
-	      dump_generic_node (buffer, OMP_FOR_PRE_BODY (node),
+	      newline_and_indent (pp, spc);
+	      dump_generic_node (pp, OMP_FOR_PRE_BODY (node),
 				 spc, flags, false);
 	    }
 	  if (OMP_FOR_INIT (node))
@@ -2496,162 +2496,162 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 		{
 		  spc += 2;
 		  if (TREE_CODE (node) != CILK_FOR || OMP_FOR_PRE_BODY (node))
-		    newline_and_indent (buffer, spc);
+		    newline_and_indent (pp, spc);
 		  if (TREE_CODE (node) == CILK_FOR)
-		    pp_string (buffer, "_Cilk_for (");
+		    pp_string (pp, "_Cilk_for (");
 		  else
-		    pp_string (buffer, "for (");
-		  dump_generic_node (buffer,
+		    pp_string (pp, "for (");
+		  dump_generic_node (pp,
 				     TREE_VEC_ELT (OMP_FOR_INIT (node), i),
 				     spc, flags, false);
-		  pp_string (buffer, "; ");
-		  dump_generic_node (buffer,
+		  pp_string (pp, "; ");
+		  dump_generic_node (pp,
 				     TREE_VEC_ELT (OMP_FOR_COND (node), i),
 				     spc, flags, false);
-		  pp_string (buffer, "; ");
-		  dump_generic_node (buffer,
+		  pp_string (pp, "; ");
+		  dump_generic_node (pp,
 				     TREE_VEC_ELT (OMP_FOR_INCR (node), i),
 				     spc, flags, false);
-		  pp_right_paren (buffer);
+		  pp_right_paren (pp);
 		}
 	      if (TREE_CODE (node) == CILK_FOR)
-		dump_omp_clauses (buffer, OMP_FOR_CLAUSES (node), spc, flags);
+		dump_omp_clauses (pp, OMP_FOR_CLAUSES (node), spc, flags);
 	    }
 	  if (OMP_FOR_BODY (node))
 	    {
-	      newline_and_indent (buffer, spc + 2);
-	      pp_left_brace (buffer);
-	      newline_and_indent (buffer, spc + 4);
-	      dump_generic_node (buffer, OMP_FOR_BODY (node), spc + 4, flags,
+	      newline_and_indent (pp, spc + 2);
+	      pp_left_brace (pp);
+	      newline_and_indent (pp, spc + 4);
+	      dump_generic_node (pp, OMP_FOR_BODY (node), spc + 4, flags,
 		  false);
-	      newline_and_indent (buffer, spc + 2);
-	      pp_right_brace (buffer);
+	      newline_and_indent (pp, spc + 2);
+	      pp_right_brace (pp);
 	    }
 	  if (OMP_FOR_INIT (node))
 	    spc -= 2 * TREE_VEC_LENGTH (OMP_FOR_INIT (node)) - 2;
 	  if (OMP_FOR_PRE_BODY (node))
 	    {
 	      spc -= 4;
-	      newline_and_indent (buffer, spc + 2);
-	      pp_right_brace (buffer);
+	      newline_and_indent (pp, spc + 2);
+	      pp_right_brace (pp);
 	    }
 	}
       is_expr = false;
       break;
 
     case OMP_SECTIONS:
-      pp_string (buffer, "#pragma omp sections");
-      dump_omp_clauses (buffer, OMP_SECTIONS_CLAUSES (node), spc, flags);
+      pp_string (pp, "#pragma omp sections");
+      dump_omp_clauses (pp, OMP_SECTIONS_CLAUSES (node), spc, flags);
       goto dump_omp_body;
 
     case OMP_SECTION:
-      pp_string (buffer, "#pragma omp section");
+      pp_string (pp, "#pragma omp section");
       goto dump_omp_body;
 
     case OMP_MASTER:
-      pp_string (buffer, "#pragma omp master");
+      pp_string (pp, "#pragma omp master");
       goto dump_omp_body;
 
     case OMP_TASKGROUP:
-      pp_string (buffer, "#pragma omp taskgroup");
+      pp_string (pp, "#pragma omp taskgroup");
       goto dump_omp_body;
 
     case OMP_ORDERED:
-      pp_string (buffer, "#pragma omp ordered");
+      pp_string (pp, "#pragma omp ordered");
       goto dump_omp_body;
 
     case OMP_CRITICAL:
-      pp_string (buffer, "#pragma omp critical");
+      pp_string (pp, "#pragma omp critical");
       if (OMP_CRITICAL_NAME (node))
 	{
-	  pp_space (buffer);
-	  pp_left_paren (buffer);
-          dump_generic_node (buffer, OMP_CRITICAL_NAME (node), spc,
+	  pp_space (pp);
+	  pp_left_paren (pp);
+          dump_generic_node (pp, OMP_CRITICAL_NAME (node), spc,
 			     flags, false);
-	  pp_right_paren (buffer);
+	  pp_right_paren (pp);
 	}
       goto dump_omp_body;
 
     case OMP_ATOMIC:
-      pp_string (buffer, "#pragma omp atomic");
+      pp_string (pp, "#pragma omp atomic");
       if (OMP_ATOMIC_SEQ_CST (node))
-	pp_string (buffer, " seq_cst");
-      newline_and_indent (buffer, spc + 2);
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_space (buffer);
-      pp_equal (buffer);
-      pp_space (buffer);
-      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
+	pp_string (pp, " seq_cst");
+      newline_and_indent (pp, spc + 2);
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_space (pp);
+      pp_equal (pp);
+      pp_space (pp);
+      dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
       break;
 
     case OMP_ATOMIC_READ:
-      pp_string (buffer, "#pragma omp atomic read");
+      pp_string (pp, "#pragma omp atomic read");
       if (OMP_ATOMIC_SEQ_CST (node))
-	pp_string (buffer, " seq_cst");
-      newline_and_indent (buffer, spc + 2);
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_space (buffer);
+	pp_string (pp, " seq_cst");
+      newline_and_indent (pp, spc + 2);
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_space (pp);
       break;
 
     case OMP_ATOMIC_CAPTURE_OLD:
     case OMP_ATOMIC_CAPTURE_NEW:
-      pp_string (buffer, "#pragma omp atomic capture");
+      pp_string (pp, "#pragma omp atomic capture");
       if (OMP_ATOMIC_SEQ_CST (node))
-	pp_string (buffer, " seq_cst");
-      newline_and_indent (buffer, spc + 2);
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_space (buffer);
-      pp_equal (buffer);
-      pp_space (buffer);
-      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
+	pp_string (pp, " seq_cst");
+      newline_and_indent (pp, spc + 2);
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_space (pp);
+      pp_equal (pp);
+      pp_space (pp);
+      dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
       break;
 
     case OMP_SINGLE:
-      pp_string (buffer, "#pragma omp single");
-      dump_omp_clauses (buffer, OMP_SINGLE_CLAUSES (node), spc, flags);
+      pp_string (pp, "#pragma omp single");
+      dump_omp_clauses (pp, OMP_SINGLE_CLAUSES (node), spc, flags);
       goto dump_omp_body;
 
     case OMP_CLAUSE:
-      dump_omp_clause (buffer, node, spc, flags);
+      dump_omp_clause (pp, node, spc, flags);
       is_expr = false;
       break;
 
     case TRANSACTION_EXPR:
       if (TRANSACTION_EXPR_OUTER (node))
-	pp_string (buffer, "__transaction_atomic [[outer]]");
+	pp_string (pp, "__transaction_atomic [[outer]]");
       else if (TRANSACTION_EXPR_RELAXED (node))
-	pp_string (buffer, "__transaction_relaxed");
+	pp_string (pp, "__transaction_relaxed");
       else
-	pp_string (buffer, "__transaction_atomic");
+	pp_string (pp, "__transaction_atomic");
       if (!(flags & TDF_SLIM) && TRANSACTION_EXPR_BODY (node))
 	{
-	  newline_and_indent (buffer, spc);
-	  pp_left_brace (buffer);
-	  newline_and_indent (buffer, spc + 2);
-	  dump_generic_node (buffer, TRANSACTION_EXPR_BODY (node),
+	  newline_and_indent (pp, spc);
+	  pp_left_brace (pp);
+	  newline_and_indent (pp, spc + 2);
+	  dump_generic_node (pp, TRANSACTION_EXPR_BODY (node),
 			     spc + 2, flags, false);
-	  newline_and_indent (buffer, spc);
-	  pp_right_brace (buffer);
+	  newline_and_indent (pp, spc);
+	  pp_right_brace (pp);
 	}
       is_expr = false;
       break;
 
     case REDUC_MAX_EXPR:
-      pp_string (buffer, " REDUC_MAX_EXPR < ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, " > ");
+      pp_string (pp, " REDUC_MAX_EXPR < ");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (pp, " > ");
       break;
 
     case REDUC_MIN_EXPR:
-      pp_string (buffer, " REDUC_MIN_EXPR < ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, " > ");
+      pp_string (pp, " REDUC_MIN_EXPR < ");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (pp, " > ");
       break;
 
     case REDUC_PLUS_EXPR:
-      pp_string (buffer, " REDUC_PLUS_EXPR < ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, " > ");
+      pp_string (pp, " REDUC_PLUS_EXPR < ");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (pp, " > ");
       break;
 
     case VEC_WIDEN_MULT_HI_EXPR:
@@ -2660,75 +2660,75 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
     case VEC_WIDEN_MULT_ODD_EXPR:
     case VEC_WIDEN_LSHIFT_HI_EXPR:
     case VEC_WIDEN_LSHIFT_LO_EXPR:
-      pp_space (buffer);
+      pp_space (pp);
       for (str = get_tree_code_name (code); *str; str++)
-	pp_character (buffer, TOUPPER (*str));
-      pp_string (buffer, " < ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, ", ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
-      pp_string (buffer, " > ");
+	pp_character (pp, TOUPPER (*str));
+      pp_string (pp, " < ");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (pp, ", ");
+      dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
+      pp_string (pp, " > ");
       break;
 
     case VEC_UNPACK_HI_EXPR:
-      pp_string (buffer, " VEC_UNPACK_HI_EXPR < ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, " > ");
+      pp_string (pp, " VEC_UNPACK_HI_EXPR < ");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (pp, " > ");
       break;
 
     case VEC_UNPACK_LO_EXPR:
-      pp_string (buffer, " VEC_UNPACK_LO_EXPR < ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, " > ");
+      pp_string (pp, " VEC_UNPACK_LO_EXPR < ");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (pp, " > ");
       break;
 
     case VEC_UNPACK_FLOAT_HI_EXPR:
-      pp_string (buffer, " VEC_UNPACK_FLOAT_HI_EXPR < ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, " > ");
+      pp_string (pp, " VEC_UNPACK_FLOAT_HI_EXPR < ");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (pp, " > ");
       break;
 
     case VEC_UNPACK_FLOAT_LO_EXPR:
-      pp_string (buffer, " VEC_UNPACK_FLOAT_LO_EXPR < ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, " > ");
+      pp_string (pp, " VEC_UNPACK_FLOAT_LO_EXPR < ");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (pp, " > ");
       break;
 
     case VEC_PACK_TRUNC_EXPR:
-      pp_string (buffer, " VEC_PACK_TRUNC_EXPR < ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, ", ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
-      pp_string (buffer, " > ");
+      pp_string (pp, " VEC_PACK_TRUNC_EXPR < ");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (pp, ", ");
+      dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
+      pp_string (pp, " > ");
       break;
 
     case VEC_PACK_SAT_EXPR:
-      pp_string (buffer, " VEC_PACK_SAT_EXPR < ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, ", ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
-      pp_string (buffer, " > ");
+      pp_string (pp, " VEC_PACK_SAT_EXPR < ");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (pp, ", ");
+      dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
+      pp_string (pp, " > ");
       break;
 
     case VEC_PACK_FIX_TRUNC_EXPR:
-      pp_string (buffer, " VEC_PACK_FIX_TRUNC_EXPR < ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, ", ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
-      pp_string (buffer, " > ");
+      pp_string (pp, " VEC_PACK_FIX_TRUNC_EXPR < ");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (pp, ", ");
+      dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
+      pp_string (pp, " > ");
       break;
 
     case BLOCK:
-      dump_block_node (buffer, node, spc, flags);
+      dump_block_node (pp, node, spc, flags);
       break;
 
     case CILK_SPAWN_STMT:
-      pp_string (buffer, "_Cilk_spawn ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (pp, "_Cilk_spawn ");
+      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
       break;
 
     case CILK_SYNC_STMT:
-      pp_string (buffer, "_Cilk_sync");
+      pp_string (pp, "_Cilk_sync");
       break;
 
     default:
@@ -2736,7 +2736,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
     }
 
   if (is_stmt && is_expr)
-    pp_semicolon (buffer);
+    pp_semicolon (pp);
 
   return spc;
 }
@@ -2744,28 +2744,28 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 /* Print the declaration of a variable.  */
 
 void
-print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
+print_declaration (pretty_printer *pp, tree t, int spc, int flags)
 {
   INDENT (spc);
 
   if (TREE_CODE(t) == NAMELIST_DECL)
     {
-      pp_string(buffer, "namelist ");
-      dump_decl_name (buffer, t, flags);
-      pp_semicolon (buffer);
+      pp_string(pp, "namelist ");
+      dump_decl_name (pp, t, flags);
+      pp_semicolon (pp);
       return;
     }
 
   if (TREE_CODE (t) == TYPE_DECL)
-    pp_string (buffer, "typedef ");
+    pp_string (pp, "typedef ");
 
   if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL) && DECL_REGISTER (t))
-    pp_string (buffer, "register ");
+    pp_string (pp, "register ");
 
   if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
-    pp_string (buffer, "extern ");
+    pp_string (pp, "extern ");
   else if (TREE_STATIC (t))
-    pp_string (buffer, "static ");
+    pp_string (pp, "static ");
 
   /* Print the type and name.  */
   if (TREE_TYPE (t) && TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
@@ -2776,43 +2776,43 @@ print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
       tmp = TREE_TYPE (t);
       while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
 	tmp = TREE_TYPE (tmp);
-      dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
+      dump_generic_node (pp, TREE_TYPE (tmp), spc, flags, false);
 
       /* Print variable's name.  */
-      pp_space (buffer);
-      dump_generic_node (buffer, t, spc, flags, false);
+      pp_space (pp);
+      dump_generic_node (pp, t, spc, flags, false);
 
       /* Print the dimensions.  */
       tmp = TREE_TYPE (t);
       while (TREE_CODE (tmp) == ARRAY_TYPE)
 	{
-	  dump_array_domain (buffer, TYPE_DOMAIN (tmp), spc, flags);
+	  dump_array_domain (pp, TYPE_DOMAIN (tmp), spc, flags);
 	  tmp = TREE_TYPE (tmp);
 	}
     }
   else if (TREE_CODE (t) == FUNCTION_DECL)
     {
-      dump_generic_node (buffer, TREE_TYPE (TREE_TYPE (t)), spc, flags, false);
-      pp_space (buffer);
-      dump_decl_name (buffer, t, flags);
-      dump_function_declaration (buffer, TREE_TYPE (t), spc, flags);
+      dump_generic_node (pp, TREE_TYPE (TREE_TYPE (t)), spc, flags, false);
+      pp_space (pp);
+      dump_decl_name (pp, t, flags);
+      dump_function_declaration (pp, TREE_TYPE (t), spc, flags);
     }
   else
     {
       /* Print type declaration.  */
-      dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
+      dump_generic_node (pp, TREE_TYPE (t), spc, flags, false);
 
       /* Print variable's name.  */
-      pp_space (buffer);
-      dump_generic_node (buffer, t, spc, flags, false);
+      pp_space (pp);
+      dump_generic_node (pp, t, spc, flags, false);
     }
 
   if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
     {
-      pp_string (buffer, " __asm__ ");
-      pp_left_paren (buffer);
-      dump_generic_node (buffer, DECL_ASSEMBLER_NAME (t), spc, flags, false);
-      pp_right_paren (buffer);
+      pp_string (pp, " __asm__ ");
+      pp_left_paren (pp);
+      dump_generic_node (pp, DECL_ASSEMBLER_NAME (t), spc, flags, false);
+      pp_right_paren (pp);
     }
 
   /* The initial value of a function serves to determine whether the function
@@ -2823,21 +2823,21 @@ print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
       /* Print the initial value.  */
       if (DECL_INITIAL (t))
 	{
-	  pp_space (buffer);
-	  pp_equal (buffer);
-	  pp_space (buffer);
-	  dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
+	  pp_space (pp);
+	  pp_equal (pp);
+	  pp_space (pp);
+	  dump_generic_node (pp, DECL_INITIAL (t), spc, flags, false);
 	}
     }
 
   if (TREE_CODE (t) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (t))
     {
-      pp_string (buffer, " [value-expr: ");
-      dump_generic_node (buffer, DECL_VALUE_EXPR (t), spc, flags, false);
-      pp_right_bracket (buffer);
+      pp_string (pp, " [value-expr: ");
+      dump_generic_node (pp, DECL_VALUE_EXPR (t), spc, flags, false);
+      pp_right_bracket (pp);
     }
 
-  pp_semicolon (buffer);
+  pp_semicolon (pp);
 }
 
 
@@ -2845,26 +2845,26 @@ print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
    FIXME: Still incomplete.  */
 
 static void
-print_struct_decl (pretty_printer *buffer, const_tree node, int spc, int flags)
+print_struct_decl (pretty_printer *pp, const_tree node, int spc, int flags)
 {
   /* Print the name of the structure.  */
   if (TYPE_NAME (node))
     {
       INDENT (spc);
       if (TREE_CODE (node) == RECORD_TYPE)
-	pp_string (buffer, "struct ");
+	pp_string (pp, "struct ");
       else if ((TREE_CODE (node) == UNION_TYPE
 		|| TREE_CODE (node) == QUAL_UNION_TYPE))
-	pp_string (buffer, "union ");
+	pp_string (pp, "union ");
 
-      dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
+      dump_generic_node (pp, TYPE_NAME (node), spc, 0, false);
     }
 
   /* Print the contents of the structure.  */
-  pp_newline (buffer);
+  pp_newline (pp);
   INDENT (spc);
-  pp_left_brace (buffer);
-  pp_newline (buffer);
+  pp_left_brace (pp);
+  pp_newline (pp);
 
   /* Print the fields of the structure.  */
   {
@@ -2881,14 +2881,14 @@ print_struct_decl (pretty_printer *buffer, const_tree node, int spc, int flags)
 	    && (TREE_CODE (TREE_TYPE (tmp)) != POINTER_TYPE
 		|| TREE_TYPE (TREE_TYPE (tmp)) != node))
 	  {
-	    print_declaration (buffer, tmp, spc+2, flags);
-	    pp_newline (buffer);
+	    print_declaration (pp, tmp, spc+2, flags);
+	    pp_newline (pp);
 	  }
 	tmp = DECL_CHAIN (tmp);
       }
   }
   INDENT (spc);
-  pp_right_brace (buffer);
+  pp_right_brace (pp);
 }
 
 /* Return the priority of the operator CODE.
@@ -3241,7 +3241,7 @@ op_symbol (const_tree op)
    the gimple_call_fn of a GIMPLE_CALL.  */
 
 void
-print_call_name (pretty_printer *buffer, tree node, int flags)
+print_call_name (pretty_printer *pp, tree node, int flags)
 {
   tree op0 = node;
 
@@ -3254,7 +3254,7 @@ print_call_name (pretty_printer *buffer, tree node, int flags)
     case VAR_DECL:
     case PARM_DECL:
     case FUNCTION_DECL:
-      dump_function_name (buffer, op0, flags);
+      dump_function_name (pp, op0, flags);
       break;
 
     case ADDR_EXPR:
@@ -3264,19 +3264,19 @@ print_call_name (pretty_printer *buffer, tree node, int flags)
       goto again;
 
     case COND_EXPR:
-      pp_left_paren (buffer);
-      dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, flags, false);
-      pp_string (buffer, ") ? ");
-      dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, flags, false);
-      pp_string (buffer, " : ");
-      dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, flags, false);
+      pp_left_paren (pp);
+      dump_generic_node (pp, TREE_OPERAND (op0, 0), 0, flags, false);
+      pp_string (pp, ") ? ");
+      dump_generic_node (pp, TREE_OPERAND (op0, 1), 0, flags, false);
+      pp_string (pp, " : ");
+      dump_generic_node (pp, TREE_OPERAND (op0, 2), 0, flags, false);
       break;
 
     case ARRAY_REF:
       if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
-	dump_function_name (buffer, TREE_OPERAND (op0, 0), flags);
+	dump_function_name (pp, TREE_OPERAND (op0, 0), flags);
       else
-	dump_generic_node (buffer, op0, 0, flags, false);
+	dump_generic_node (pp, op0, 0, flags, false);
       break;
 
     case MEM_REF:
@@ -3289,7 +3289,7 @@ print_call_name (pretty_printer *buffer, tree node, int flags)
     case COMPONENT_REF:
     case SSA_NAME:
     case OBJ_TYPE_REF:
-      dump_generic_node (buffer, op0, 0, flags, false);
+      dump_generic_node (pp, op0, 0, flags, false);
       break;
 
     default:
@@ -3300,7 +3300,7 @@ print_call_name (pretty_printer *buffer, tree node, int flags)
 /* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ...  */
 
 static void
-pretty_print_string (pretty_printer *buffer, const char *str)
+pretty_print_string (pretty_printer *pp, const char *str)
 {
   if (str == NULL)
     return;
@@ -3310,73 +3310,73 @@ pretty_print_string (pretty_printer *buffer, const char *str)
       switch (str[0])
 	{
 	case '\b':
-	  pp_string (buffer, "\\b");
+	  pp_string (pp, "\\b");
 	  break;
 
 	case '\f':
-	  pp_string (buffer, "\\f");
+	  pp_string (pp, "\\f");
 	  break;
 
 	case '\n':
-	  pp_string (buffer, "\\n");
+	  pp_string (pp, "\\n");
 	  break;
 
 	case '\r':
-	  pp_string (buffer, "\\r");
+	  pp_string (pp, "\\r");
 	  break;
 
 	case '\t':
-	  pp_string (buffer, "\\t");
+	  pp_string (pp, "\\t");
 	  break;
 
 	case '\v':
-	  pp_string (buffer, "\\v");
+	  pp_string (pp, "\\v");
 	  break;
 
 	case '\\':
-	  pp_string (buffer, "\\\\");
+	  pp_string (pp, "\\\\");
 	  break;
 
 	case '\"':
-	  pp_string (buffer, "\\\"");
+	  pp_string (pp, "\\\"");
 	  break;
 
 	case '\'':
-	  pp_string (buffer, "\\'");
+	  pp_string (pp, "\\'");
 	  break;
 
 	  /* No need to handle \0; the loop terminates on \0.  */
 
 	case '\1':
-	  pp_string (buffer, "\\1");
+	  pp_string (pp, "\\1");
 	  break;
 
 	case '\2':
-	  pp_string (buffer, "\\2");
+	  pp_string (pp, "\\2");
 	  break;
 
 	case '\3':
-	  pp_string (buffer, "\\3");
+	  pp_string (pp, "\\3");
 	  break;
 
 	case '\4':
-	  pp_string (buffer, "\\4");
+	  pp_string (pp, "\\4");
 	  break;
 
 	case '\5':
-	  pp_string (buffer, "\\5");
+	  pp_string (pp, "\\5");
 	  break;
 
 	case '\6':
-	  pp_string (buffer, "\\6");
+	  pp_string (pp, "\\6");
 	  break;
 
 	case '\7':
-	  pp_string (buffer, "\\7");
+	  pp_string (pp, "\\7");
 	  break;
 
 	default:
-	  pp_character (buffer, str[0]);
+	  pp_character (pp, str[0]);
 	  break;
 	}
       str++;
@@ -3386,20 +3386,20 @@ pretty_print_string (pretty_printer *buffer, const char *str)
 static void
 maybe_init_pretty_print (FILE *file)
 {
-  if (!buffer)
+  if (!tree_pp)
     {
-      buffer = new pretty_printer ();
-      pp_needs_newline (buffer) = true;
-      pp_translate_identifiers (buffer) = false;
+      tree_pp = new pretty_printer ();
+      pp_needs_newline (tree_pp) = true;
+      pp_translate_identifiers (tree_pp) = false;
     }
 
-  buffer->buffer->stream = file;
+  tree_pp->buffer->stream = file;
 }
 
 static void
-newline_and_indent (pretty_printer *buffer, int spc)
+newline_and_indent (pretty_printer *pp, int spc)
 {
-  pp_newline (buffer);
+  pp_newline (pp);
   INDENT (spc);
 }
 
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 03/08] PR jit/63854: Fix leak in real.c for i386:init_ext_80387_constants
  2014-01-01  0:00 ` [PATCH 03/08] PR jit/63854: Fix leak in real.c for i386:init_ext_80387_constants David Malcolm
@ 2014-01-01  0:00   ` Richard Biener
  0 siblings, 0 replies; 17+ messages in thread
From: Richard Biener @ 2014-01-01  0:00 UTC (permalink / raw)
  To: David Malcolm; +Cc: GCC Patches, jit

On Wed, Nov 26, 2014 at 2:39 AM, David Malcolm <dmalcolm@redhat.com> wrote:
> Valgrind of testsuite/jit.dg/test-types.c showed this leak in real.c
> when converting the strings in init_ext_80387_constants to real.
>
> 160 bytes in 5 blocks are definitely lost in loss record 89 of 144
>    at 0x4A0645D: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
>    by 0x30AF40C368: __gmp_default_allocate (memory.c:44)
>    by 0x309842EA20: mpfr_init2 (init2.c:55)
>    by 0x527C033: real_from_string(real_value*, char const*) (real.c:2045)
>    by 0x56F0CEF: init_ext_80387_constants() (i386.c:9200)
>    by 0x56F0E4A: standard_80387_constant_p(rtx_def*) (i386.c:9237)
>    by 0x5740115: ix86_rtx_costs(rtx_def*, int, int, int, int*, bool) (i386.c:41735)
>    by 0x52E4417: rtx_cost(rtx_def*, rtx_code, int, bool) (rtlanal.c:3855)
>    by 0x4F28E9C: set_src_cost(rtx_def*, bool) (rtl.h:2111)
>    by 0x4F33AFB: compress_float_constant(rtx_def*, rtx_def*) (expr.c:3667)
>    by 0x4F3380E: emit_move_insn(rtx_def*, rtx_def*) (expr.c:3590)
>    by 0x4F3A1B6: store_expr_with_bounds(tree_node*, rtx_def*, int, bool, tree_node*) (expr.c:5540)
>
> Fix it.

Ok.

Thanks,
Richard.

> gcc/ChangeLog:
>         PR jit/63854
>         * real.c (real_from_string): Add missing mpfr_clear.
> ---
>  gcc/real.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/gcc/real.c b/gcc/real.c
> index cebbe8d..5e8050d 100644
> --- a/gcc/real.c
> +++ b/gcc/real.c
> @@ -2067,6 +2067,7 @@ real_from_string (REAL_VALUE_TYPE *r, const char *str)
>           gcc_assert (r->cl = rvc_normal);
>           /* Set a sticky bit if mpfr_strtofr was inexact.  */
>           r->sig[0] |= inexact;
> +         mpfr_clear (m);
>         }
>      }
>
> --
> 1.8.5.3
>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 05/08] PR jit/63854: Fix double-initialization within tree-pretty-print.c
  2014-01-01  0:00 ` [PATCH 05/08] PR jit/63854: Fix double-initialization within tree-pretty-print.c David Malcolm
@ 2014-01-01  0:00   ` Jeff Law
  0 siblings, 0 replies; 17+ messages in thread
From: Jeff Law @ 2014-01-01  0:00 UTC (permalink / raw)
  To: David Malcolm, gcc-patches, jit

On 11/25/14 18:39, David Malcolm wrote:
> Running various JIT testcases under valgrid showed this one-time leak:
>
> 8,464 (336 direct, 8,128 indirect) bytes in 1 blocks are definitely lost in loss record 144 of 147
>     at 0x4A081D4: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
>     by 0x5DF4EA0: xcalloc (xmalloc.c:162)
>     by 0x5DB0D9C: pretty_printer::pretty_printer(char const*, int) (pretty-print.c:777)
>     by 0x54DA67D: __static_initialization_and_destruction_0(int, int) (tree-pretty-print.c:66)
>     by 0x54DA6AF: _GLOBAL__sub_I_tree_pretty_print.c (tree-pretty-print.c:3542)
>     by 0x309540F2D9: call_init.part.0 (dl-init.c:82)
>     by 0x309540F3C2: _dl_init (dl-init.c:34)
>     by 0x3095401229: ??? (in /usr/lib64/ld-2.18.so)
>     by 0x1: ???
>     by 0xFFEFFFFBE: ???
>     by 0xFFEFFFFDA: ???
>
> tree-pretty-print.c:66 is:
>    static pretty_printer buffer;
>
> pretty-print.c:777 is:
> pretty_printer::pretty_printer (const char *p, int l)
>    : buffer (new (XCNEW (output_buffer)) output_buffer ()),
>
> This is the ctor of "buffer" (the pretty_printer) running at startup
> by the dynamic linker, allocating its "buffer" output_buffer field
> and the pair of obstacks it contains.
>
> [Arguably "buffer" is a poor name for a pretty_printer, and these
> should be named "pp" or somesuch, though that seems like it should
> be a separate patch, which I'll do as a followup].
>
> However, this ctor gets rerun the first time that
> maybe_init_pretty_print is called, reallocating the output_buffer and
> its obstacks, leaking the old ones:
>
>   static void
>   maybe_init_pretty_print (FILE *file)
>   {
>     if (!initialized)
>       {
>         new (&buffer) pretty_printer ();
>         /* etc */
>       }
>     /* etc */
>   }
>
> This is a one-time leak, so it's worth fixing mostly for the sake of
> keeping the valgrind output clean.
>
> Having objects with non-empty ctors/dtors in a statically-allocated
> section feels like too much C++ to me: we can't rely on the order in
> which they run, and in the past I've been bitten by runtimes that
> didn't support them fully (where the compiler worked, but the
> linker/startup code didn't).
>
> Hence this patch fixes the leak by rewriting the global "buffer" to
> be a pointer, allocating the pp on the heap, eliminating the
> before-main static ctor/dtor pair.
>
> gcc/ChangeLog:
> 	PR jit/63854
> 	* tree-pretty-print.c: Eliminate include of <new>.
> 	(buffer): Convert this variable from a pretty_printer to a
> 	pretty_printer *.
> 	(initialized): Eliminate this variable in favor of the NULL-ness
> 	of "buffer".
> 	(print_generic_decl): Update for "buffer" becoming a pointer.
> 	(print_generic_stmt): Likewise.
> 	(print_generic_stmt_indented): Likewise.
> 	(print_generic_expr): Likewise.
> 	(maybe_init_pretty_print): Likewise, allocating "buffer" on the
> 	heap and using its non-NULL-ness to ensure idempotency.
OK.

Jeff

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 07/08] PR jit/63854: Fix leaks in toyvm.c
  2014-01-01  0:00 [PATCH 00/08] More memory leak fixes David Malcolm
                   ` (2 preceding siblings ...)
  2014-01-01  0:00 ` [PATCH 03/08] PR jit/63854: Fix leak in real.c for i386:init_ext_80387_constants David Malcolm
@ 2014-01-01  0:00 ` David Malcolm
  2014-01-01  0:00 ` [PATCH 02/08] PR jit/63854: Fix leak within jit-builtins.c David Malcolm
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 17+ messages in thread
From: David Malcolm @ 2014-01-01  0:00 UTC (permalink / raw)
  To: gcc-patches, jit; +Cc: David Malcolm

Introduce a struct toyvm_compiled_function so that we can clean things
up fully, avoiding warnings from valgrind.

gcc/jit/ChangeLog:
	PR jit/63854
	(toyvm_compiled_function): New typedef.
	(toyvm_compiled_func) Rename to...
	(toyvm_compiled_code) ...this.
	(struct toyvm_compiled_function): New struct.
	(toyvm_function_compile): Return a toyvm_compiled_function *
	rather than a toyvm_compiled_func, so that the caller can fully
	clean things up.  Free "funcname".
	(test_script): Update for change to toyvm_function_compile.
	Clean up the toyvm_compiled_function.
	(main): Likewise.
	(docs/intro/tutorial04.rst): Update to reflect the above changes,
	and to better spell out the lifetime of the compiled code.
---
 gcc/jit/docs/examples/tut04-toyvm/toyvm.c | 54 +++++++++++++++++++++++++------
 gcc/jit/docs/intro/tutorial04.rst         | 11 ++++++-
 2 files changed, 55 insertions(+), 10 deletions(-)

diff --git a/gcc/jit/docs/examples/tut04-toyvm/toyvm.c b/gcc/jit/docs/examples/tut04-toyvm/toyvm.c
index 666bf2e..07de507 100644
--- a/gcc/jit/docs/examples/tut04-toyvm/toyvm.c
+++ b/gcc/jit/docs/examples/tut04-toyvm/toyvm.c
@@ -33,9 +33,10 @@ typedef struct toyvm_op toyvm_op;
 typedef struct toyvm_function toyvm_function;
 typedef struct toyvm_frame toyvm_frame;
 typedef struct compilation_state compilation_state;
+typedef struct toyvm_compiled_function toyvm_compiled_function;
 
 /* Functions are compiled to this function ptr type.  */
-typedef int (*toyvm_compiled_func) (int);
+typedef int (*toyvm_compiled_code) (int);
 
 enum opcode {
   /* Ops taking no operand.  */
@@ -440,9 +441,17 @@ add_pop (compilation_state *state,
 	gcc_jit_lvalue_as_rvalue (state->stack_depth))));
 }
 
+/* A struct to hold the compilation results.  */
+
+struct toyvm_compiled_function
+{
+  gcc_jit_result *cf_jit_result;
+  toyvm_compiled_code cf_code;
+};
+
 /* The main compilation hook.  */
 
-static toyvm_compiled_func
+static toyvm_compiled_function *
 toyvm_function_compile (toyvm_function *fn)
 {
   compilation_state state;
@@ -724,12 +733,26 @@ toyvm_function_compile (toyvm_function *fn)
     } /* end of loop on PC locations.  */
 
   /* We've now finished populating the context.  Compile it.  */
-  gcc_jit_result *result = gcc_jit_context_compile (state.ctxt);
+  gcc_jit_result *jit_result = gcc_jit_context_compile (state.ctxt);
   gcc_jit_context_release (state.ctxt);
 
-  return (toyvm_compiled_func)gcc_jit_result_get_code (result,
-						       funcname);
-  /* (this leaks "result" and "funcname") */
+  toyvm_compiled_function *toyvm_result =
+    (toyvm_compiled_function *)calloc (1, sizeof (toyvm_compiled_function));
+  if (!toyvm_result)
+    {
+      fprintf (stderr, "out of memory allocating toyvm_compiled_function\n");
+      gcc_jit_result_release (jit_result);
+      return NULL;
+    }
+
+  toyvm_result->cf_jit_result = jit_result;
+  toyvm_result->cf_code =
+    (toyvm_compiled_code)gcc_jit_result_get_code (jit_result,
+						  funcname);
+
+  free (funcname);
+
+  return toyvm_result;
 }
 
 char test[1024];
@@ -768,7 +791,8 @@ test_script (const char *scripts_dir, const char *script_name, int input,
   char *script_path;
   toyvm_function *fn;
   int interpreted_result;
-  toyvm_compiled_func code;
+  toyvm_compiled_function *compiled_fn;
+  toyvm_compiled_code code;
   int compiled_result;
 
   snprintf (test, sizeof (test), "toyvm.c: %s", script_name);
@@ -784,12 +808,18 @@ test_script (const char *scripts_dir, const char *script_name, int input,
   interpreted_result = toyvm_function_interpret (fn, input, NULL);
   CHECK_VALUE (interpreted_result, expected_result);
 
-  code = toyvm_function_compile (fn);
+  compiled_fn = toyvm_function_compile (fn);
+  CHECK_NON_NULL (compiled_fn);
+
+  code = (toyvm_compiled_code)compiled_fn->cf_code;
   CHECK_NON_NULL (code);
 
   compiled_result = code (input);
   CHECK_VALUE (compiled_result, expected_result);
 
+  gcc_jit_result_release (compiled_fn->cf_jit_result);
+  free (compiled_fn);
+  free (fn);
   free (script_path);
 }
 
@@ -853,9 +883,15 @@ main (int argc, char **argv)
 	  toyvm_function_interpret (fn, atoi (argv[2]), NULL));
 
   /* JIT-compilation.  */
-  toyvm_compiled_func code = toyvm_function_compile (fn);
+  toyvm_compiled_function *compiled_fn
+    = toyvm_function_compile (fn);
+
+  toyvm_compiled_code code = compiled_fn->cf_code;
   printf ("compiler result: %d\n",
 	  code (atoi (argv[2])));
 
+  gcc_jit_result_release (compiled_fn->cf_jit_result);
+  free (compiled_fn);
+
  return 0;
 }
diff --git a/gcc/jit/docs/intro/tutorial04.rst b/gcc/jit/docs/intro/tutorial04.rst
index cafdddb..3aac670 100644
--- a/gcc/jit/docs/intro/tutorial04.rst
+++ b/gcc/jit/docs/intro/tutorial04.rst
@@ -101,6 +101,15 @@ then directly executed in-process:
     :end-before: enum opcode
     :language: c
 
+The lifetime of the code is tied to that of a :c:type:`gcc_jit_result *`.
+We'll handle this by bundling them up in a structure, so that we can
+clean them up together by calling :c:func:`gcc_jit_result_release`:
+
+   .. literalinclude:: ../examples/tut04-toyvm/toyvm.c
+    :start-after: /* A struct to hold the compilation results.  */
+    :end-before: /* The main compilation hook.  */
+    :language: c
+
 Our compiler isn't very sophisticated; it takes the implementation of
 each opcode above, and maps it directly to the operations supported by
 the libgccjit API.
@@ -155,7 +164,7 @@ a block, implementing pushing and popping values:
 
    .. literalinclude:: ../examples/tut04-toyvm/toyvm.c
     :start-after: /* Stack manipulation.  */
-    :end-before: /* The main compilation hook.  */
+    :end-before: /* A struct to hold the compilation results.  */
     :language: c
 
 We will support single-stepping through the generated code in the
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 01/08] PR jit/63854: Fix leak in tree-ssa-math-opts.c
  2014-01-01  0:00 ` [PATCH 01/08] PR jit/63854: Fix leak in tree-ssa-math-opts.c David Malcolm
@ 2014-01-01  0:00   ` Richard Biener
  0 siblings, 0 replies; 17+ messages in thread
From: Richard Biener @ 2014-01-01  0:00 UTC (permalink / raw)
  To: David Malcolm; +Cc: GCC Patches, jit

On Wed, Nov 26, 2014 at 2:39 AM, David Malcolm <dmalcolm@redhat.com> wrote:
> Running testsuite/jit.dg/test-functions.c under valgrind showed this
> leak (amongst others):
>
> 400 bytes in 10 blocks are definitely lost in loss record 142 of 181
>    at 0x4A0645D: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
>    by 0x5DCDF2F: xrealloc (xmalloc.c:177)
>    by 0x53726CE: void va_heap::reserve<gimple_statement_base*>(vec<gimple_statement_base*, va_heap, vl_embed>*&, unsigned int, bool) (vec.h:310)
>    by 0x5371BB1: vec<gimple_statement_base*, va_heap, vl_ptr>::reserve(unsigned int, bool) (vec.h:1428)
>    by 0x5370F5D: vec<gimple_statement_base*, va_heap, vl_ptr>::safe_push(gimple_statement_base* const&) (vec.h:1537)
>    by 0x5523E71: maybe_record_sincos(vec<gimple_statement_base*, va_heap, vl_ptr>*, basic_block_def**, gimple_statement_base*) (tree-ssa-math-opts.c:718)
>    by 0x552403E: execute_cse_sincos_1(tree_node*) (tree-ssa-math-opts.c:760)
>    by 0x5526224: (anonymous namespace)::pass_cse_sincos::execute(function*) (tree-ssa-math-opts.c:1497)
>    by 0x5250095: execute_one_pass(opt_pass*) (passes.c:2311)
>    by 0x525030C: execute_pass_list_1(opt_pass*) (passes.c:2363)
>    by 0x525033D: execute_pass_list_1(opt_pass*) (passes.c:2364)
>    by 0x525037A: execute_pass_list(function*, opt_pass*) (passes.c:2374)
>
> For some reason (which I've filed for myself as PR jit/64020), this
> code was bailing out:
>
>   fndecl = mathfn_built_in (type, BUILT_IN_CEXPI);
>   if (!fndecl)
>     return false;
>
> That exit path is missing a:
>   stmts.release ();
> and thus is leaking the buffer of stmts on the way out.
>
> Fix it by converting stmts from vec<> to auto_vec<>, to avoid the need to
> have handwritten release calls on every exit path.

Ok.

Thanks,
Richard.

> gcc/ChangeLog:
>         PR jit/63854
>         * tree-ssa-math-opts.c (execute_cse_sincos_1): Fix a missing
>         release of stmts by converting it to an auto_vec.
> ---
>  gcc/tree-ssa-math-opts.c | 9 ++-------
>  1 file changed, 2 insertions(+), 7 deletions(-)
>
> diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
> index f9c30bf..5e08c7ee 100644
> --- a/gcc/tree-ssa-math-opts.c
> +++ b/gcc/tree-ssa-math-opts.c
> @@ -740,7 +740,7 @@ execute_cse_sincos_1 (tree name)
>    tree fndecl, res, type;
>    gimple def_stmt, use_stmt, stmt;
>    int seen_cos = 0, seen_sin = 0, seen_cexpi = 0;
> -  vec<gimple> stmts = vNULL;
> +  auto_vec<gimple> stmts;
>    basic_block top_bb = NULL;
>    int i;
>    bool cfg_changed = false;
> @@ -773,10 +773,7 @@ execute_cse_sincos_1 (tree name)
>      }
>
>    if (seen_cos + seen_sin + seen_cexpi <= 1)
> -    {
> -      stmts.release ();
> -      return false;
> -    }
> +    return false;
>
>    /* Simply insert cexpi at the beginning of top_bb but not earlier than
>       the name def statement.  */
> @@ -835,8 +832,6 @@ execute_cse_sincos_1 (tree name)
>           cfg_changed = true;
>      }
>
> -  stmts.release ();
> -
>    return cfg_changed;
>  }
>
> --
> 1.8.5.3
>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 08/08] PR/64003 workaround (uninit memory in i386.md)
  2014-01-01  0:00   ` Jeff Law
@ 2014-01-01  0:00     ` David Malcolm
  2014-01-01  0:00       ` Jeff Law
  2014-01-01  0:00       ` Jeff Law
  0 siblings, 2 replies; 17+ messages in thread
From: David Malcolm @ 2014-01-01  0:00 UTC (permalink / raw)
  To: Jeff Law; +Cc: gcc-patches, jit

On Wed, 2014-11-26 at 10:41 -0700, Jeff Law wrote:
> On 11/25/14 18:39, David Malcolm wrote:
> > I suspect this is papering over a real problem, but I've been
> > applying this workaround locally to keep my valgrind output clean.
> >
> > gcc/ChangeLog:
> > 	PR/64003
> > 	* final.c (shorten_branches): Allocate insn_lengths with
> > 	XCNEWVEC rather than XNEWVEC; remove subsequent per-element
> > 	initialization.
> I'd like more information on this one.

I've spent some time trying to track this down, and I've added detailed
notes to the bug.

In short, I believe the problem occurs with a "*jcc_1" insn that jumps
forwards, but the full details are in the bug.

> My first thought is that something must be creating a new insn after 
> shorten_branches is complete or an existing insn that was not on the 
> chain when we called shorten-branches, but got threaded onto the chain 
> later.  Either would be considered bad in various ways, so we'd like to 
> fix it.

I don't think either of these are the case.  I believe it's due to the
size of the jcc_1 insn being affected by the distance to the jump
target, which for a forward jump is a bit of a chicken-and-egg issue,
since that distance is affected by the size of the jcc_1 insn itself.  

It looks like align_fuzz exists in order to cope with this kind of
circular definition, but the issue seems to occur inside align_fuzz
itself.

> Presumably you're not doing an out-of-range access into insn_lengths? 
> Right?
> 
> Do you have a reasonable testcase for this?

I've added a more minimal reproducer to the bug (8 lines); see:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64003#c7

I see it with latest trunk (r218254) on x86_64.

See my notes in the bug.

Dave

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 08/08] PR/64003 workaround (uninit memory in i386.md)
  2014-01-01  0:00     ` David Malcolm
@ 2014-01-01  0:00       ` Jeff Law
  2014-01-01  0:00       ` Jeff Law
  1 sibling, 0 replies; 17+ messages in thread
From: Jeff Law @ 2014-01-01  0:00 UTC (permalink / raw)
  To: David Malcolm; +Cc: gcc-patches, jit

On 12/02/14 09:20, David Malcolm wrote:
> In short, I believe the problem occurs with a "*jcc_1" insn that jumps
> forwards, but the full details are in the bug.
>
>> My first thought is that something must be creating a new insn after
>> shorten_branches is complete or an existing insn that was not on the
>> chain when we called shorten-branches, but got threaded onto the chain
>> later.  Either would be considered bad in various ways, so we'd like to
>> fix it.
>
> I don't think either of these are the case.  I believe it's due to the
> size of the jcc_1 insn being affected by the distance to the jump
> target, which for a forward jump is a bit of a chicken-and-egg issue,
> since that distance is affected by the size of the jcc_1 insn itself.
>
> It looks like align_fuzz exists in order to cope with this kind of
> circular definition, but the issue seems to occur inside align_fuzz
> itself.
Sorry, I didn't look at the BZ, you had already put a fair amount of 
analysis in there.  My bad.

This feels sooooo familiar.

Jeff

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 04/08] PR jit/63854: Remove xstrdup from ipa/cgraph fprintf calls
  2014-01-01  0:00 [PATCH 00/08] More memory leak fixes David Malcolm
                   ` (4 preceding siblings ...)
  2014-01-01  0:00 ` [PATCH 02/08] PR jit/63854: Fix leak within jit-builtins.c David Malcolm
@ 2014-01-01  0:00 ` David Malcolm
  2014-01-01  0:00 ` [PATCH 01/08] PR jit/63854: Fix leak in tree-ssa-math-opts.c David Malcolm
  2014-01-01  0:00 ` [PATCH 08/08] PR/64003 workaround (uninit memory in i386.md) David Malcolm
  7 siblings, 0 replies; 17+ messages in thread
From: David Malcolm @ 2014-01-01  0:00 UTC (permalink / raw)
  To: gcc-patches, jit; +Cc: David Malcolm

cgraph*.c and ipa-*.c use xstrdup on strings when dumping them via
fprintf, leaking all of the duplicated buffers.

Is/was there a reason for doing this?

Taking them out fixes these leaks (seen when dumping is enabled):

12 bytes in 1 blocks are definitely lost in loss record 11 of 148
at 0x4A0645D: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x5DED3E7: xmalloc (xmalloc.c:147)
by 0x5DED4D9: xstrdup (xstrdup.c:34)
by 0x5126326: ipa_print_node_jump_functions(_IO_FILE*, cgraph_node*) (ipa-prop.c:397)
by 0x512657F: ipa_print_all_jump_functions(_IO_FILE*) (ipa-prop.c:443)
by 0x5CE4471: ipcp_driver() (ipa-cp.c:4216)
by 0x5CE46D8: (anonymous namespace)::pass_ipa_cp::execute(function*) (ipa-cp.c:4315)
by 0x525BF51: execute_one_pass(opt_pass*) (passes.c:2311)
by 0x525CE68: execute_ipa_pass_list(opt_pass*) (passes.c:2708)
by 0x4E5263C: ipa_passes() (cgraphunit.c:2099)
by 0x4E5298C: symbol_table::compile() (cgraphunit.c:2187)
by 0x4E52D22: symbol_table::finalize_compilation_unit() (cgraphunit.c:2340)

12 bytes in 1 blocks are definitely lost in loss record 12 of 148
at 0x4A0645D: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x5DED3E7: xmalloc (xmalloc.c:147)
by 0x5DED4D9: xstrdup (xstrdup.c:34)
by 0x5CF155A: report_inline_failed_reason(cgraph_edge*) (ipa-inline.c:253)
by 0x5CF1C35: can_inline_edge_p(cgraph_edge*, bool, bool) (ipa-inline.c:394)
by 0x5CF4DFC: inline_small_functions() (ipa-inline.c:1651)
by 0x5CF6785: ipa_inline() (ipa-inline.c:2188)
by 0x5CF7358: (anonymous namespace)::pass_ipa_inline::execute(function*) (ipa-inline.c:2557)
by 0x525BF51: execute_one_pass(opt_pass*) (passes.c:2311)
by 0x525CE68: execute_ipa_pass_list(opt_pass*) (passes.c:2708)
by 0x4E5263C: ipa_passes() (cgraphunit.c:2099)
by 0x4E5298C: symbol_table::compile() (cgraphunit.c:2187)

16 bytes in 1 blocks are definitely lost in loss record 16 of 148
at 0x4A0645D: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x5DED3E7: xmalloc (xmalloc.c:147)
by 0x5DED4D9: xstrdup (xstrdup.c:34)
by 0x5126308: ipa_print_node_jump_functions(_IO_FILE*, cgraph_node*) (ipa-prop.c:397)
by 0x512657F: ipa_print_all_jump_functions(_IO_FILE*) (ipa-prop.c:443)
by 0x5CE4471: ipcp_driver() (ipa-cp.c:4216)
by 0x5CE46D8: (anonymous namespace)::pass_ipa_cp::execute(function*) (ipa-cp.c:4315)
by 0x525BF51: execute_one_pass(opt_pass*) (passes.c:2311)
by 0x525CE68: execute_ipa_pass_list(opt_pass*) (passes.c:2708)
by 0x4E5263C: ipa_passes() (cgraphunit.c:2099)
by 0x4E5298C: symbol_table::compile() (cgraphunit.c:2187)
by 0x4E52D22: symbol_table::finalize_compilation_unit() (cgraphunit.c:2340)

16 bytes in 1 blocks are definitely lost in loss record 17 of 148
at 0x4A0645D: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x5DED3E7: xmalloc (xmalloc.c:147)
by 0x5DED4D9: xstrdup (xstrdup.c:34)
by 0x5CF1533: report_inline_failed_reason(cgraph_edge*) (ipa-inline.c:253)
by 0x5CF1C35: can_inline_edge_p(cgraph_edge*, bool, bool) (ipa-inline.c:394)
by 0x5CF4DFC: inline_small_functions() (ipa-inline.c:1651)
by 0x5CF6785: ipa_inline() (ipa-inline.c:2188)
by 0x5CF7358: (anonymous namespace)::pass_ipa_inline::execute(function*) (ipa-inline.c:2557)
by 0x525BF51: execute_one_pass(opt_pass*) (passes.c:2311)
by 0x525CE68: execute_ipa_pass_list(opt_pass*) (passes.c:2708)
by 0x4E5263C: ipa_passes() (cgraphunit.c:2099)
by 0x4E5298C: symbol_table::compile() (cgraphunit.c:2187)

gcc/ChangeLog:
	PR jit/63854
	* cgraph.c (cgraph_node::get_create): Remove xstrdup from within
	fprintf dumping call.
	(cgraph_edge::make_speculative): Likewise.
	(cgraph_edge::resolve_speculation): Likewise.
	(cgraph_edge::redirect_call_stmt_to_callee): Likewise.
	(cgraph_node::dump): Likewise.
	* cgraphclones.c (symbol_table::materialize_all_clones): Likewise.
	* ipa-cp.c (perhaps_add_new_callers): Likewise.
	* ipa-inline.c (report_inline_failed_reason): Likewise.
	(want_early_inline_function_p): Likewise.
	(edge_badness): Likewise.
	(update_edge_key): Likewise.
	(flatten_function): Likewise.
	(inline_always_inline_functions): Likewise.
	(early_inline_small_functions): Likewise.
	* ipa-profile.c (ipa_profile): Likewise.
	* ipa-prop.c (ipa_print_node_jump_functions): Likewise.
	(ipa_make_edge_direct_to_target): Likewise.
	(remove_described_reference): Likewise.
	(propagate_controlled_uses): Likewise.
	* ipa-utils.c (ipa_merge_profiles): Likewise.
---
 gcc/cgraph.c       | 32 ++++++++++++++++----------------
 gcc/cgraphclones.c |  4 ++--
 gcc/ipa-cp.c       |  4 ++--
 gcc/ipa-inline.c   | 44 ++++++++++++++++++++++----------------------
 gcc/ipa-profile.c  |  4 ++--
 gcc/ipa-prop.c     | 34 +++++++++++++++++-----------------
 gcc/ipa-utils.c    |  4 ++--
 7 files changed, 63 insertions(+), 63 deletions(-)

diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 5323468..b79a3aa 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -537,11 +537,11 @@ cgraph_node::get_create (tree decl)
       if (dump_file)
 	fprintf (dump_file, "Introduced new external node "
 		 "(%s/%i) and turned into root of the clone tree.\n",
-		 xstrdup (node->name ()), node->order);
+		 node->name (), node->order);
     }
   else if (dump_file)
     fprintf (dump_file, "Introduced new external node "
-	     "(%s/%i).\n", xstrdup (node->name ()),
+	     "(%s/%i).\n", node->name (),
 	     node->order);
   return node;
 }
@@ -1070,8 +1070,8 @@ cgraph_edge::make_speculative (cgraph_node *n2, gcov_type direct_count,
     {
       fprintf (dump_file, "Indirect call -> speculative call"
 	       " %s/%i => %s/%i\n",
-	       xstrdup (n->name ()), n->order,
-	       xstrdup (n2->name ()), n2->order);
+	       n->name (), n->order,
+	       n2->name (), n2->order);
     }
   speculative = true;
   e2 = n->create_edge (n2, call_stmt, direct_count, direct_frequency);
@@ -1190,16 +1190,16 @@ cgraph_edge::resolve_speculation (tree callee_decl)
 	    {
 	      fprintf (dump_file, "Speculative indirect call %s/%i => %s/%i has "
 		       "turned out to have contradicting known target ",
-		       xstrdup (edge->caller->name ()), edge->caller->order,
-		       xstrdup (e2->callee->name ()), e2->callee->order);
+		       edge->caller->name (), edge->caller->order,
+		       e2->callee->name (), e2->callee->order);
 	      print_generic_expr (dump_file, callee_decl, 0);
 	      fprintf (dump_file, "\n");
 	    }
 	  else
 	    {
 	      fprintf (dump_file, "Removing speculative call %s/%i => %s/%i\n",
-		       xstrdup (edge->caller->name ()), edge->caller->order,
-		       xstrdup (e2->callee->name ()), e2->callee->order);
+		       edge->caller->name (), edge->caller->order,
+		       e2->callee->name (), e2->callee->order);
 	    }
 	}
     }
@@ -1319,9 +1319,9 @@ cgraph_edge::redirect_call_stmt_to_callee (void)
 	  if (dump_file)
 	    fprintf (dump_file, "Not expanding speculative call of %s/%i -> %s/%i\n"
 		     "Type mismatch.\n",
-		     xstrdup (e->caller->name ()),
+		     e->caller->name (),
 		     e->caller->order,
-		     xstrdup (e->callee->name ()),
+		     e->callee->name (),
 		     e->callee->order);
 	  e = e->resolve_speculation ();
 	  /* We are producing the final function body and will throw away the
@@ -1338,9 +1338,9 @@ cgraph_edge::redirect_call_stmt_to_callee (void)
 	    fprintf (dump_file,
 		     "Expanding speculative call of %s/%i -> %s/%i count:"
 		     "%"PRId64"\n",
-		     xstrdup (e->caller->name ()),
+		     e->caller->name (),
 		     e->caller->order,
-		     xstrdup (e->callee->name ()),
+		     e->callee->name (),
 		     e->callee->order,
 		     (int64_t)e->count);
 	  gcc_assert (e2->speculative);
@@ -1415,8 +1415,8 @@ cgraph_edge::redirect_call_stmt_to_callee (void)
   if (symtab->dump_file)
     {
       fprintf (symtab->dump_file, "updating call of %s/%i -> %s/%i: ",
-	       xstrdup (e->caller->name ()), e->caller->order,
-	       xstrdup (e->callee->name ()), e->callee->order);
+	       e->caller->name (), e->caller->order,
+	       e->callee->name (), e->callee->order);
       print_gimple_stmt (symtab->dump_file, e->call_stmt, 0, dump_flags);
       if (e->callee->clone.combined_args_to_skip)
 	{
@@ -1965,9 +1965,9 @@ cgraph_node::dump (FILE *f)
 
   if (global.inlined_to)
     fprintf (f, "  Function %s/%i is inline copy in %s/%i\n",
-	     xstrdup (name ()),
+	     name (),
 	     order,
-	     xstrdup (global.inlined_to->name ()),
+	     global.inlined_to->name (),
 	     global.inlined_to->order);
   if (clone_of)
     fprintf (f, "  Clone of %s/%i\n",
diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c
index 086dd92..a40ed4b 100644
--- a/gcc/cgraphclones.c
+++ b/gcc/cgraphclones.c
@@ -1074,8 +1074,8 @@ symbol_table::materialize_all_clones (void)
 		  if (symtab->dump_file)
 		    {
 		      fprintf (symtab->dump_file, "cloning %s to %s\n",
-			       xstrdup (node->clone_of->name ()),
-			       xstrdup (node->name ()));
+			       node->clone_of->name (),
+			       node->name ());
 		      if (node->clone.tree_map)
 		        {
 			  unsigned int i;
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index f97912b..11b886b 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -3791,9 +3791,9 @@ perhaps_add_new_callers (cgraph_node *node, ipcp_value<valtype> *val)
 		  if (dump_file)
 		    fprintf (dump_file, " - adding an extra caller %s/%i"
 			     " of %s/%i\n",
-			     xstrdup (cs->caller->name ()),
+			     cs->caller->name (),
 			     cs->caller->order,
-			     xstrdup (val->spec_node->name ()),
+			     val->spec_node->name (),
 			     val->spec_node->order);
 
 		  cs->redirect_callee (val->spec_node);
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 72c0715..a0779a1 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -248,8 +248,8 @@ report_inline_failed_reason (struct cgraph_edge *e)
   if (dump_file)
     {
       fprintf (dump_file, "  not inlinable: %s/%i -> %s/%i, %s\n",
-	       xstrdup (e->caller->name ()), e->caller->order,
-	       xstrdup (e->callee->name ()), e->callee->order,
+	       e->caller->name (), e->caller->order,
+	       e->callee->name (), e->callee->order,
 	       cgraph_inline_failed_string (e->inline_failed));
     }
 }
@@ -480,9 +480,9 @@ want_early_inline_function_p (struct cgraph_edge *e)
 	  if (dump_file)
 	    fprintf (dump_file, "  will not early inline: %s/%i->%s/%i, "
 		     "call is cold and code would grow by %i\n",
-		     xstrdup (e->caller->name ()),
+		     e->caller->name (),
 		     e->caller->order,
-		     xstrdup (callee->name ()), callee->order,
+		     callee->name (), callee->order,
 		     growth);
 	  want_inline = false;
 	}
@@ -491,9 +491,9 @@ want_early_inline_function_p (struct cgraph_edge *e)
 	  if (dump_file)
 	    fprintf (dump_file, "  will not early inline: %s/%i->%s/%i, "
 		     "growth %i exceeds --param early-inlining-insns\n",
-		     xstrdup (e->caller->name ()),
+		     e->caller->name (),
 		     e->caller->order,
-		     xstrdup (callee->name ()), callee->order,
+		     callee->name (), callee->order,
 		     growth);
 	  want_inline = false;
 	}
@@ -504,9 +504,9 @@ want_early_inline_function_p (struct cgraph_edge *e)
 	    fprintf (dump_file, "  will not early inline: %s/%i->%s/%i, "
 		     "growth %i exceeds --param early-inlining-insns "
 		     "divided by number of calls\n",
-		     xstrdup (e->caller->name ()),
+		     e->caller->name (),
 		     e->caller->order,
-		     xstrdup (callee->name ()), callee->order,
+		     callee->name (), callee->order,
 		     growth);
 	  want_inline = false;
 	}
@@ -925,9 +925,9 @@ edge_badness (struct cgraph_edge *edge, bool dump)
   if (dump)
     {
       fprintf (dump_file, "    Badness calculation for %s/%i -> %s/%i\n",
-	       xstrdup (edge->caller->name ()),
+	       edge->caller->name (),
 	       edge->caller->order,
-	       xstrdup (callee->name ()),
+	       callee->name (),
 	       edge->callee->order);
       fprintf (dump_file, "      size growth %i, time %i ",
 	       growth,
@@ -1093,9 +1093,9 @@ update_edge_key (edge_heap_t *heap, struct cgraph_edge *edge)
 	    {
 	      fprintf (dump_file,
 		       "  decreasing badness %s/%i -> %s/%i, %i to %i\n",
-		       xstrdup (edge->caller->name ()),
+		       edge->caller->name (),
 		       edge->caller->order,
-		       xstrdup (edge->callee->name ()),
+		       edge->callee->name (),
 		       edge->callee->order,
 		       (int)n->get_key (),
 		       badness);
@@ -1110,9 +1110,9 @@ update_edge_key (edge_heap_t *heap, struct cgraph_edge *edge)
 	 {
 	   fprintf (dump_file,
 		    "  enqueuing call %s/%i -> %s/%i, badness %i\n",
-		    xstrdup (edge->caller->name ()),
+		    edge->caller->name (),
 		    edge->caller->order,
-		    xstrdup (edge->callee->name ()),
+		    edge->callee->name (),
 		    edge->callee->order,
 		    badness);
 	 }
@@ -1891,8 +1891,8 @@ flatten_function (struct cgraph_node *node, bool early)
 	  if (dump_file)
 	    fprintf (dump_file,
 		     "Not inlining %s into %s to avoid cycle.\n",
-		     xstrdup (callee->name ()),
-		     xstrdup (e->caller->name ()));
+		     callee->name (),
+		     e->caller->name ());
 	  e->inline_failed = CIF_RECURSIVE_INLINING;
 	  continue;
 	}
@@ -1932,8 +1932,8 @@ flatten_function (struct cgraph_node *node, bool early)
          recursing through the original node if the node was cloned.  */
       if (dump_file)
 	fprintf (dump_file, " Inlining %s into %s.\n",
-		 xstrdup (callee->name ()),
-		 xstrdup (e->caller->name ()));
+		 callee->name (),
+		 e->caller->name ());
       orig_callee = callee;
       inline_call (e, true, NULL, NULL, false);
       if (e->callee != orig_callee)
@@ -2310,8 +2310,8 @@ inline_always_inline_functions (struct cgraph_node *node)
 
       if (dump_file)
 	fprintf (dump_file, "  Inlining %s into %s (always_inline).\n",
-		 xstrdup (e->callee->name ()),
-		 xstrdup (e->caller->name ()));
+		 e->callee->name (),
+		 e->caller->name ());
       inline_call (e, true, NULL, NULL, false);
       inlined = true;
     }
@@ -2362,8 +2362,8 @@ early_inline_small_functions (struct cgraph_node *node)
 
       if (dump_file)
 	fprintf (dump_file, " Inlining %s into %s.\n",
-		 xstrdup (callee->name ()),
-		 xstrdup (e->caller->name ()));
+		 callee->name (),
+		 e->caller->name ());
       inline_call (e, true, NULL, NULL, true);
       inlined = true;
     }
diff --git a/gcc/ipa-profile.c b/gcc/ipa-profile.c
index 340d033..d8a4371 100644
--- a/gcc/ipa-profile.c
+++ b/gcc/ipa-profile.c
@@ -607,8 +607,8 @@ ipa_profile (void)
 		    {
 		      fprintf (dump_file, "Indirect call -> direct call from"
 			       " other module %s/%i => %s/%i, prob %3.2f\n",
-			       xstrdup (n->name ()), n->order,
-			       xstrdup (n2->name ()), n2->order,
+			       n->name (), n->order,
+			       n2->name (), n2->order,
 			       e->indirect_info->common_target_probability
 			       / (float)REG_BR_PROB_BASE);
 		    }
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index be1921a..68f6fa6 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -392,8 +392,8 @@ ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
 	continue;
 
       fprintf (f, "    callsite  %s/%i -> %s/%i : \n",
-	       xstrdup (node->name ()), node->order,
-	       xstrdup (cs->callee->name ()),
+	       node->name (), node->order,
+	       cs->callee->name (),
 	       cs->callee->order);
       ipa_print_node_jump_functions_for_edge (f, cs);
     }
@@ -2620,9 +2620,9 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
 	  if (dump_file)
 	    fprintf (dump_file, "ipa-prop: Discovered call to a known target "
 		     "(%s/%i -> %s/%i) but can not refer to it. Giving up.\n",
-		     xstrdup (ie->caller->name ()),
+		     ie->caller->name (),
 		     ie->caller->order,
-		     xstrdup (ie->callee->name ()),
+		     ie->callee->name (),
 		     ie->callee->order);
 	  return NULL;
 	}
@@ -2641,11 +2641,11 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
 	  if (dump_file)
 	    fprintf (dump_file, "ipa-prop: Discovered call to a speculative target "
 		     "(%s/%i -> %s/%i) but the call is already speculated to %s/%i. Giving up.\n",
-		     xstrdup (ie->caller->name ()),
+		     ie->caller->name (),
 		     ie->caller->order,
-		     xstrdup (callee->name ()),
+		     callee->name (),
 		     callee->order,
-		     xstrdup (e2->callee->name ()),
+		     e2->callee->name (),
 		     e2->callee->order);
 	}
       else
@@ -2653,9 +2653,9 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
 	  if (dump_file)
 	    fprintf (dump_file, "ipa-prop: Discovered call to a speculative target "
 		     "(%s/%i -> %s/%i) this agree with previous speculation.\n",
-		     xstrdup (ie->caller->name ()),
+		     ie->caller->name (),
 		     ie->caller->order,
-		     xstrdup (callee->name ()),
+		     callee->name (),
 		     callee->order);
 	}
       return NULL;
@@ -2676,9 +2676,9 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
 	       "(%s/%i -> %s/%i), for stmt ",
 	       ie->indirect_info->polymorphic ? "a virtual" : "an indirect",
 	       speculative ? "speculative" : "known",
-	       xstrdup (ie->caller->name ()),
+	       ie->caller->name (),
 	       ie->caller->order,
-	       xstrdup (callee->name ()),
+	       callee->name (),
 	       callee->order);
       if (ie->call_stmt)
 	print_gimple_stmt (dump_file, ie->call_stmt, 2, TDF_SLIM);
@@ -2762,8 +2762,8 @@ remove_described_reference (symtab_node *symbol, struct ipa_cst_ref_desc *rdesc)
   to_del->remove_reference ();
   if (dump_file)
     fprintf (dump_file, "ipa-prop: Removed a reference from %s/%i to %s.\n",
-	     xstrdup (origin->caller->name ()),
-	     origin->caller->order, xstrdup (symbol->name ()));
+	     origin->caller->name (),
+	     origin->caller->order, symbol->name ());
   return true;
 }
 
@@ -3177,9 +3177,9 @@ propagate_controlled_uses (struct cgraph_edge *cs)
 		  if (dump_file)
 		    fprintf (dump_file, "ipa-prop: Removing cloning-created "
 			     "reference from %s/%i to %s/%i.\n",
-			     xstrdup (new_root->name ()),
+			     new_root->name (),
 			     new_root->order,
-			     xstrdup (n->name ()), n->order);
+			     n->name (), n->order);
 		  ref->remove_reference ();
 		}
 	    }
@@ -3218,9 +3218,9 @@ propagate_controlled_uses (struct cgraph_edge *cs)
 			    fprintf (dump_file, "ipa-prop: Removing "
 				     "cloning-created reference "
 				     "from %s/%i to %s/%i.\n",
-				     xstrdup (clone->name ()),
+				     clone->name (),
 				     clone->order,
-				     xstrdup (n->name ()),
+				     n->name (),
 				     n->order);
 			  ref->remove_reference ();
 			}
diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c
index 7613205..c0b855a 100644
--- a/gcc/ipa-utils.c
+++ b/gcc/ipa-utils.c
@@ -427,8 +427,8 @@ ipa_merge_profiles (struct cgraph_node *dst,
   if (symtab->dump_file)
     {
       fprintf (symtab->dump_file, "Merging profiles of %s/%i to %s/%i\n",
-	       xstrdup (src->name ()), src->order,
-	       xstrdup (dst->name ()), dst->order);
+	       src->name (), src->order,
+	       dst->name (), dst->order);
     }
   dst->count += src->count;
 
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 08/08] PR/64003 workaround (uninit memory in i386.md)
  2014-01-01  0:00 [PATCH 00/08] More memory leak fixes David Malcolm
                   ` (6 preceding siblings ...)
  2014-01-01  0:00 ` [PATCH 01/08] PR jit/63854: Fix leak in tree-ssa-math-opts.c David Malcolm
@ 2014-01-01  0:00 ` David Malcolm
  2014-01-01  0:00   ` Jeff Law
  7 siblings, 1 reply; 17+ messages in thread
From: David Malcolm @ 2014-01-01  0:00 UTC (permalink / raw)
  To: gcc-patches, jit; +Cc: David Malcolm

I suspect this is papering over a real problem, but I've been
applying this workaround locally to keep my valgrind output clean.

gcc/ChangeLog:
	PR/64003
	* final.c (shorten_branches): Allocate insn_lengths with
	XCNEWVEC rather than XNEWVEC; remove subsequent per-element
	initialization.
---
 gcc/final.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/gcc/final.c b/gcc/final.c
index c3805c9..53b0e86 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -1019,7 +1019,7 @@ shorten_branches (rtx_insn *first)
     return;
 
   /* Allocate the rest of the arrays.  */
-  insn_lengths = XNEWVEC (int, max_uid);
+  insn_lengths = XCNEWVEC (int, max_uid);
   insn_lengths_max_uid = max_uid;
   /* Syntax errors can lead to labels being outside of the main insn stream.
      Initialize insn_addresses, so that we get reproducible results.  */
@@ -1127,8 +1127,6 @@ shorten_branches (rtx_insn *first)
     {
       uid = INSN_UID (insn);
 
-      insn_lengths[uid] = 0;
-
       if (LABEL_P (insn))
 	{
 	  int log = LABEL_TO_ALIGNMENT (insn);
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 05/08] PR jit/63854: Fix double-initialization within tree-pretty-print.c
  2014-01-01  0:00 [PATCH 00/08] More memory leak fixes David Malcolm
@ 2014-01-01  0:00 ` David Malcolm
  2014-01-01  0:00   ` Jeff Law
  2014-01-01  0:00 ` [PATCH 06/08] Avoid overuse of name "buffer" in tree-pretty-print.c David Malcolm
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 17+ messages in thread
From: David Malcolm @ 2014-01-01  0:00 UTC (permalink / raw)
  To: gcc-patches, jit; +Cc: David Malcolm

Running various JIT testcases under valgrid showed this one-time leak:

8,464 (336 direct, 8,128 indirect) bytes in 1 blocks are definitely lost in loss record 144 of 147
   at 0x4A081D4: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
   by 0x5DF4EA0: xcalloc (xmalloc.c:162)
   by 0x5DB0D9C: pretty_printer::pretty_printer(char const*, int) (pretty-print.c:777)
   by 0x54DA67D: __static_initialization_and_destruction_0(int, int) (tree-pretty-print.c:66)
   by 0x54DA6AF: _GLOBAL__sub_I_tree_pretty_print.c (tree-pretty-print.c:3542)
   by 0x309540F2D9: call_init.part.0 (dl-init.c:82)
   by 0x309540F3C2: _dl_init (dl-init.c:34)
   by 0x3095401229: ??? (in /usr/lib64/ld-2.18.so)
   by 0x1: ???
   by 0xFFEFFFFBE: ???
   by 0xFFEFFFFDA: ???

tree-pretty-print.c:66 is:
  static pretty_printer buffer;

pretty-print.c:777 is:
pretty_printer::pretty_printer (const char *p, int l)
  : buffer (new (XCNEW (output_buffer)) output_buffer ()),

This is the ctor of "buffer" (the pretty_printer) running at startup
by the dynamic linker, allocating its "buffer" output_buffer field
and the pair of obstacks it contains.

[Arguably "buffer" is a poor name for a pretty_printer, and these
should be named "pp" or somesuch, though that seems like it should
be a separate patch, which I'll do as a followup].

However, this ctor gets rerun the first time that
maybe_init_pretty_print is called, reallocating the output_buffer and
its obstacks, leaking the old ones:

 static void
 maybe_init_pretty_print (FILE *file)
 {
   if (!initialized)
     {
       new (&buffer) pretty_printer ();
       /* etc */
     }
   /* etc */
 }

This is a one-time leak, so it's worth fixing mostly for the sake of
keeping the valgrind output clean.

Having objects with non-empty ctors/dtors in a statically-allocated
section feels like too much C++ to me: we can't rely on the order in
which they run, and in the past I've been bitten by runtimes that
didn't support them fully (where the compiler worked, but the
linker/startup code didn't).

Hence this patch fixes the leak by rewriting the global "buffer" to
be a pointer, allocating the pp on the heap, eliminating the
before-main static ctor/dtor pair.

gcc/ChangeLog:
	PR jit/63854
	* tree-pretty-print.c: Eliminate include of <new>.
	(buffer): Convert this variable from a pretty_printer to a
	pretty_printer *.
	(initialized): Eliminate this variable in favor of the NULL-ness
	of "buffer".
	(print_generic_decl): Update for "buffer" becoming a pointer.
	(print_generic_stmt): Likewise.
	(print_generic_stmt_indented): Likewise.
	(print_generic_expr): Likewise.
	(maybe_init_pretty_print): Likewise, allocating "buffer" on the
	heap and using its non-NULL-ness to ensure idempotency.
---
 gcc/tree-pretty-print.c | 34 +++++++++++++++-------------------
 1 file changed, 15 insertions(+), 19 deletions(-)

diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index 53720de..ddd7521 100644
--- a/gcc/tree-pretty-print.c
+++ b/gcc/tree-pretty-print.c
@@ -48,8 +48,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "wide-int-print.h"
 #include "internal-fn.h"
 
-#include <new>                           // For placement-new.
-
 /* Local functions, macros and variables.  */
 static const char *op_symbol (const_tree);
 static void pretty_print_string (pretty_printer *, const char*);
@@ -63,8 +61,7 @@ static void do_niy (pretty_printer *, const_tree);
 
 #define NIY do_niy (buffer, node)
 
-static pretty_printer buffer;
-static int initialized = 0;
+static pretty_printer *buffer;
 
 /* Try to print something for an unknown tree code.  */
 
@@ -135,8 +132,8 @@ void
 print_generic_decl (FILE *file, tree decl, int flags)
 {
   maybe_init_pretty_print (file);
-  print_declaration (&buffer, decl, 2, flags);
-  pp_write_text_to_stream (&buffer);
+  print_declaration (buffer, decl, 2, flags);
+  pp_write_text_to_stream (buffer);
 }
 
 /* Print tree T, and its successors, on file FILE.  FLAGS specifies details
@@ -146,8 +143,8 @@ void
 print_generic_stmt (FILE *file, tree t, int flags)
 {
   maybe_init_pretty_print (file);
-  dump_generic_node (&buffer, t, 0, flags, true);
-  pp_newline_and_flush (&buffer);
+  dump_generic_node (buffer, t, 0, flags, true);
+  pp_newline_and_flush (buffer);
 }
 
 /* Print tree T, and its successors, on file FILE.  FLAGS specifies details
@@ -162,9 +159,9 @@ print_generic_stmt_indented (FILE *file, tree t, int flags, int indent)
   maybe_init_pretty_print (file);
 
   for (i = 0; i < indent; i++)
-    pp_space (&buffer);
-  dump_generic_node (&buffer, t, indent, flags, true);
-  pp_newline_and_flush (&buffer);
+    pp_space (buffer);
+  dump_generic_node (buffer, t, indent, flags, true);
+  pp_newline_and_flush (buffer);
 }
 
 /* Print a single expression T on file FILE.  FLAGS specifies details to show
@@ -174,8 +171,8 @@ void
 print_generic_expr (FILE *file, tree t, int flags)
 {
   maybe_init_pretty_print (file);
-  dump_generic_node (&buffer, t, 0, flags, false);
-  pp_flush (&buffer);
+  dump_generic_node (buffer, t, 0, flags, false);
+  pp_flush (buffer);
 }
 
 /* Dump the name of a _DECL node and its DECL_UID if TDF_UID is set
@@ -3389,15 +3386,14 @@ pretty_print_string (pretty_printer *buffer, const char *str)
 static void
 maybe_init_pretty_print (FILE *file)
 {
-  if (!initialized)
+  if (!buffer)
     {
-      new (&buffer) pretty_printer ();
-      pp_needs_newline (&buffer) = true;
-      pp_translate_identifiers (&buffer) = false;
-      initialized = 1;
+      buffer = new pretty_printer ();
+      pp_needs_newline (buffer) = true;
+      pp_translate_identifiers (buffer) = false;
     }
 
-  buffer.buffer->stream = file;
+  buffer->buffer->stream = file;
 }
 
 static void
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 00/08] More memory leak fixes
@ 2014-01-01  0:00 David Malcolm
  2014-01-01  0:00 ` [PATCH 05/08] PR jit/63854: Fix double-initialization within tree-pretty-print.c David Malcolm
                   ` (7 more replies)
  0 siblings, 8 replies; 17+ messages in thread
From: David Malcolm @ 2014-01-01  0:00 UTC (permalink / raw)
  To: gcc-patches, jit; +Cc: David Malcolm

Various fixes/improvements to jit.exp

Successfully bootstrapped & regrtested on x86_64-unknown-linux-gnu
(Fedora 20).

OK for trunk?

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 03/08] PR jit/63854: Fix leak in real.c for i386:init_ext_80387_constants
  2014-01-01  0:00 [PATCH 00/08] More memory leak fixes David Malcolm
  2014-01-01  0:00 ` [PATCH 05/08] PR jit/63854: Fix double-initialization within tree-pretty-print.c David Malcolm
  2014-01-01  0:00 ` [PATCH 06/08] Avoid overuse of name "buffer" in tree-pretty-print.c David Malcolm
@ 2014-01-01  0:00 ` David Malcolm
  2014-01-01  0:00   ` Richard Biener
  2014-01-01  0:00 ` [PATCH 07/08] PR jit/63854: Fix leaks in toyvm.c David Malcolm
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 17+ messages in thread
From: David Malcolm @ 2014-01-01  0:00 UTC (permalink / raw)
  To: gcc-patches, jit; +Cc: David Malcolm

Valgrind of testsuite/jit.dg/test-types.c showed this leak in real.c
when converting the strings in init_ext_80387_constants to real.

160 bytes in 5 blocks are definitely lost in loss record 89 of 144
   at 0x4A0645D: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
   by 0x30AF40C368: __gmp_default_allocate (memory.c:44)
   by 0x309842EA20: mpfr_init2 (init2.c:55)
   by 0x527C033: real_from_string(real_value*, char const*) (real.c:2045)
   by 0x56F0CEF: init_ext_80387_constants() (i386.c:9200)
   by 0x56F0E4A: standard_80387_constant_p(rtx_def*) (i386.c:9237)
   by 0x5740115: ix86_rtx_costs(rtx_def*, int, int, int, int*, bool) (i386.c:41735)
   by 0x52E4417: rtx_cost(rtx_def*, rtx_code, int, bool) (rtlanal.c:3855)
   by 0x4F28E9C: set_src_cost(rtx_def*, bool) (rtl.h:2111)
   by 0x4F33AFB: compress_float_constant(rtx_def*, rtx_def*) (expr.c:3667)
   by 0x4F3380E: emit_move_insn(rtx_def*, rtx_def*) (expr.c:3590)
   by 0x4F3A1B6: store_expr_with_bounds(tree_node*, rtx_def*, int, bool, tree_node*) (expr.c:5540)

Fix it.

gcc/ChangeLog:
	PR jit/63854
	* real.c (real_from_string): Add missing mpfr_clear.
---
 gcc/real.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/real.c b/gcc/real.c
index cebbe8d..5e8050d 100644
--- a/gcc/real.c
+++ b/gcc/real.c
@@ -2067,6 +2067,7 @@ real_from_string (REAL_VALUE_TYPE *r, const char *str)
 	  gcc_assert (r->cl = rvc_normal);
 	  /* Set a sticky bit if mpfr_strtofr was inexact.  */
 	  r->sig[0] |= inexact;
+	  mpfr_clear (m);
 	}
     }
 
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 02/08] PR jit/63854: Fix leak within jit-builtins.c
  2014-01-01  0:00 [PATCH 00/08] More memory leak fixes David Malcolm
                   ` (3 preceding siblings ...)
  2014-01-01  0:00 ` [PATCH 07/08] PR jit/63854: Fix leaks in toyvm.c David Malcolm
@ 2014-01-01  0:00 ` David Malcolm
  2014-01-01  0:00 ` [PATCH 04/08] PR jit/63854: Remove xstrdup from ipa/cgraph fprintf calls David Malcolm
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 17+ messages in thread
From: David Malcolm @ 2014-01-01  0:00 UTC (permalink / raw)
  To: gcc-patches, jit; +Cc: David Malcolm

Running testsuite/jit.dg/test-functions.c under valgrind showed this
leak (amongst others):

520 (320 direct, 200 indirect) bytes in 5 blocks are definitely lost in loss record 144 of 181
   at 0x4A06965: operator new(unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
   by 0x4DF2110: gcc::jit::recording::builtins_manager::make_fn_type(gcc::jit::recording::jit_builtin_type, gcc::jit::recording::jit_builtin_type, bool, int, ...) (jit-builtins.c:405)
   by 0x4DEEDD4: gcc::jit::recording::builtins_manager::make_type(gcc::jit::recording::jit_builtin_type) (builtin-types.def:242)
   by 0x4DED7B9: gcc::jit::recording::builtins_manager::get_type(gcc::jit::recording::jit_builtin_type) (jit-builtins.c:216)
   by 0x4DED5BB: gcc::jit::recording::builtins_manager::make_builtin_function(built_in_function) (jit-builtins.c:177)
   by 0x4DED503: gcc::jit::recording::builtins_manager::get_builtin_function(char const*) (jit-builtins.c:163)
   by 0x4DD7F57: gcc::jit::recording::context::get_builtin_function(char const*) (jit-recording.c:576)
   by 0x4DD33D5: gcc_jit_context_get_builtin_function (libgccjit.c:851)
   by 0x402820: create_test_of_builtin_strcmp (test-functions.c:134)
   by 0x402B2D: create_use_of_builtins (test-functions.c:231)
   by 0x4033E1: create_code (test-functions.c:345)
   by 0x40216D: test_jit (harness.h:217)

The recording::function_type instances created by the builtin_manager
were being leaked.  These are recording::memento instances, and thus
the context is responsible for freeing them - the bug was that they
weren't getting recorded into the context's list of mementos.

In general, only the recording::context should directly create mementos;
everything else goes through factory methods of recording::context, which
takes care of calling "record" on the new instances (putting them into
the list of "owned" objects).

Fix this by creating a new "new_function_type" factory method of the
context and using it from jit-builtins.c

gcc/jit/ChangeLog:
	PR jit/63854
	* jit-builtins.c
	(gcc::jit::recording::builtins_manager::make_fn_type): Call the
	context's new_function_type method, rather than directly creating
	a function_type instance.
	* jit-recording.c
	(gcc::jit::recording::context::new_function_type): New method,
	adapted from part of...
	(gcc::jit::recording::context::new_function_ptr_type): ...this.
	Update to call new_function_type.
	* jit-recording.h
	(gcc::jit::recording::context::new_function_type): New method.
---
 gcc/jit/jit-builtins.c  |  9 ++++-----
 gcc/jit/jit-recording.c | 33 ++++++++++++++++++++++++++-------
 gcc/jit/jit-recording.h |  6 ++++++
 3 files changed, 36 insertions(+), 12 deletions(-)

diff --git a/gcc/jit/jit-builtins.c b/gcc/jit/jit-builtins.c
index 07902e8..49d37d8 100644
--- a/gcc/jit/jit-builtins.c
+++ b/gcc/jit/jit-builtins.c
@@ -398,11 +398,10 @@ builtins_manager::make_fn_type (enum jit_builtin_type,
   if (!return_type)
     goto error;
 
-  result = new function_type (m_ctxt,
-			      return_type,
-			      num_args,
-			      param_types,
-			      is_variadic);
+  result = m_ctxt->new_function_type (return_type,
+				      num_args,
+				      param_types,
+				      is_variadic);
 
  error:
   delete[] param_types;
diff --git a/gcc/jit/jit-recording.c b/gcc/jit/jit-recording.c
index 8069afc..32bf034 100644
--- a/gcc/jit/jit-recording.c
+++ b/gcc/jit/jit-recording.c
@@ -492,6 +492,27 @@ recording::context::new_union_type (recording::location *loc,
   return result;
 }
 
+/* Create a recording::function_type instance and add it to this context's
+   list of mementos.
+
+   Used by new_function_ptr_type and by builtins_manager::make_fn_type.  */
+
+recording::function_type *
+recording::context::new_function_type (recording::type *return_type,
+				       int num_params,
+				       recording::type **param_types,
+				       int is_variadic)
+{
+  recording::function_type *fn_type
+    = new function_type (this,
+			 return_type,
+			 num_params,
+			 param_types,
+			 is_variadic);
+  record (fn_type);
+  return fn_type;
+}
+
 /* Create a recording::type instance and add it to this context's list
    of mementos.
 
@@ -505,13 +526,11 @@ recording::context::new_function_ptr_type (recording::location *, /* unused loc
 					   recording::type **param_types,
 					   int is_variadic)
 {
-  recording::function_type *fn_type =
-    new function_type (this,
-		       return_type,
-		       num_params,
-		       param_types,
-		       is_variadic);
-  record (fn_type);
+  recording::function_type *fn_type
+    = new_function_type (return_type,
+			 num_params,
+			 param_types,
+			 is_variadic);
 
   /* Return a pointer-type to the the function type.  */
   return fn_type->get_pointer ();
diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h
index 4ea8ef1..9b2cfc6 100644
--- a/gcc/jit/jit-recording.h
+++ b/gcc/jit/jit-recording.h
@@ -88,6 +88,12 @@ public:
   new_union_type (location *loc,
 		  const char *name);
 
+  function_type *
+  new_function_type (type *return_type,
+		     int num_params,
+		     type **param_types,
+		     int is_variadic);
+
   type *
   new_function_ptr_type (location *loc,
 			 type *return_type,
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 01/08] PR jit/63854: Fix leak in tree-ssa-math-opts.c
  2014-01-01  0:00 [PATCH 00/08] More memory leak fixes David Malcolm
                   ` (5 preceding siblings ...)
  2014-01-01  0:00 ` [PATCH 04/08] PR jit/63854: Remove xstrdup from ipa/cgraph fprintf calls David Malcolm
@ 2014-01-01  0:00 ` David Malcolm
  2014-01-01  0:00   ` Richard Biener
  2014-01-01  0:00 ` [PATCH 08/08] PR/64003 workaround (uninit memory in i386.md) David Malcolm
  7 siblings, 1 reply; 17+ messages in thread
From: David Malcolm @ 2014-01-01  0:00 UTC (permalink / raw)
  To: gcc-patches, jit; +Cc: David Malcolm

Running testsuite/jit.dg/test-functions.c under valgrind showed this
leak (amongst others):

400 bytes in 10 blocks are definitely lost in loss record 142 of 181
   at 0x4A0645D: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
   by 0x5DCDF2F: xrealloc (xmalloc.c:177)
   by 0x53726CE: void va_heap::reserve<gimple_statement_base*>(vec<gimple_statement_base*, va_heap, vl_embed>*&, unsigned int, bool) (vec.h:310)
   by 0x5371BB1: vec<gimple_statement_base*, va_heap, vl_ptr>::reserve(unsigned int, bool) (vec.h:1428)
   by 0x5370F5D: vec<gimple_statement_base*, va_heap, vl_ptr>::safe_push(gimple_statement_base* const&) (vec.h:1537)
   by 0x5523E71: maybe_record_sincos(vec<gimple_statement_base*, va_heap, vl_ptr>*, basic_block_def**, gimple_statement_base*) (tree-ssa-math-opts.c:718)
   by 0x552403E: execute_cse_sincos_1(tree_node*) (tree-ssa-math-opts.c:760)
   by 0x5526224: (anonymous namespace)::pass_cse_sincos::execute(function*) (tree-ssa-math-opts.c:1497)
   by 0x5250095: execute_one_pass(opt_pass*) (passes.c:2311)
   by 0x525030C: execute_pass_list_1(opt_pass*) (passes.c:2363)
   by 0x525033D: execute_pass_list_1(opt_pass*) (passes.c:2364)
   by 0x525037A: execute_pass_list(function*, opt_pass*) (passes.c:2374)

For some reason (which I've filed for myself as PR jit/64020), this
code was bailing out:

  fndecl = mathfn_built_in (type, BUILT_IN_CEXPI);
  if (!fndecl)
    return false;

That exit path is missing a:
  stmts.release ();
and thus is leaking the buffer of stmts on the way out.

Fix it by converting stmts from vec<> to auto_vec<>, to avoid the need to
have handwritten release calls on every exit path.

gcc/ChangeLog:
	PR jit/63854
	* tree-ssa-math-opts.c (execute_cse_sincos_1): Fix a missing
	release of stmts by converting it to an auto_vec.
---
 gcc/tree-ssa-math-opts.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
index f9c30bf..5e08c7ee 100644
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -740,7 +740,7 @@ execute_cse_sincos_1 (tree name)
   tree fndecl, res, type;
   gimple def_stmt, use_stmt, stmt;
   int seen_cos = 0, seen_sin = 0, seen_cexpi = 0;
-  vec<gimple> stmts = vNULL;
+  auto_vec<gimple> stmts;
   basic_block top_bb = NULL;
   int i;
   bool cfg_changed = false;
@@ -773,10 +773,7 @@ execute_cse_sincos_1 (tree name)
     }
 
   if (seen_cos + seen_sin + seen_cexpi <= 1)
-    {
-      stmts.release ();
-      return false;
-    }
+    return false;
 
   /* Simply insert cexpi at the beginning of top_bb but not earlier than
      the name def statement.  */
@@ -835,8 +832,6 @@ execute_cse_sincos_1 (tree name)
 	  cfg_changed = true;
     }
 
-  stmts.release ();
-
   return cfg_changed;
 }
 
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 08/08] PR/64003 workaround (uninit memory in i386.md)
  2014-01-01  0:00     ` David Malcolm
  2014-01-01  0:00       ` Jeff Law
@ 2014-01-01  0:00       ` Jeff Law
  1 sibling, 0 replies; 17+ messages in thread
From: Jeff Law @ 2014-01-01  0:00 UTC (permalink / raw)
  To: David Malcolm; +Cc: gcc-patches, jit

On 12/02/14 09:20, David Malcolm wrote:
>
> I've spent some time trying to track this down, and I've added detailed
> notes to the bug.
>
> In short, I believe the problem occurs with a "*jcc_1" insn that jumps
> forwards, but the full details are in the bug.
>
>> My first thought is that something must be creating a new insn after
>> shorten_branches is complete or an existing insn that was not on the
>> chain when we called shorten-branches, but got threaded onto the chain
>> later.  Either would be considered bad in various ways, so we'd like to
>> fix it.
>
> I don't think either of these are the case.  I believe it's due to the
> size of the jcc_1 insn being affected by the distance to the jump
> target, which for a forward jump is a bit of a chicken-and-egg issue,
> since that distance is affected by the size of the jcc_1 insn itself.
I thought we had code somewhere that made worst case assumptions about 
the lengths, to get those arrays initialized with reasonable value 
without looking forward.  But that may have also been in place prior to 
the addition of align_fuzz.

>
> It looks like align_fuzz exists in order to cope with this kind of
> circular definition, but the issue seems to occur inside align_fuzz
> itself.
align_fuzz is meant to estimate padding due to alignments.  Joern and I 
went round and round on that code and I never managed to wrap my head 
around it or its correctness.  Jim W. might have stepped in at some 
point to arbitrate.  I may have to pull out my archives and review that 
history (IIRC is predates egcs).

Interestingly there was a great discussion around the code in 2009 which 
mirrored some of my initial concerns with this code.  Ultimately Bernd 
recommended removing it, but nobody reviewed/approved the patch.

I think you should ping Joern to chime in here about the proper course 
of action to take if we're going to keep this code in GCC.  You could 
just assign in the BZ to him.  FWIW, I can't convince myself 
initializing the value to zero is actually safe or not.


jeff


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 06/08] Avoid overuse of name "buffer" in tree-pretty-print.c
  2014-01-01  0:00 ` [PATCH 06/08] Avoid overuse of name "buffer" in tree-pretty-print.c David Malcolm
@ 2014-01-01  0:00   ` Jeff Law
  0 siblings, 0 replies; 17+ messages in thread
From: Jeff Law @ 2014-01-01  0:00 UTC (permalink / raw)
  To: David Malcolm, gcc-patches, jit

On 11/25/14 18:39, David Malcolm wrote:
> Various functions in tree-pretty-print.c take a param
>    pretty_printer *buffer
> and there's also a static pretty_printer *buffer;
>
> Additionally, pretty_printer instances are not buffers; they
> *contain* buffers (inasmuch as they have a field "buffer").
>
> This patch renames such params from "buffer" to "pp", and the static
> "buffer" to "tree_pp" to make it easier to tell what we're dealing
> with (a param, a file-static, or a buffer).
>
> gcc/ChangeLog:
> 	* tree-pretty-print.c (INDENT): Rename "buffer" to "pp".
> 	(NIY): Likewise.
> 	(buffer): Rename this variable to...
> 	(tree_pp): ...this.
>
> 	(do_niy): Rename param from "buffer" to "pp".
> 	(dump_decl_name): Likewise.
> 	(dump_function_name): Likewise.
> 	(dump_function_declaration): Likewise.
> 	(dump_array_domain): Likewise.
> 	(dump_omp_clause): Likewise.
> 	(dump_omp_clauses): Likewise.
> 	(dump_location): Likewise.
> 	(dump_block_node): Likewise.
> 	(dump_generic_node): Likewise.
> 	(print_declaration): Likewise.
> 	(print_struct_decl): Likewise.
> 	(print_call_name): Likewise.
> 	(pretty_print_string): Likewise.
> 	(newline_and_indent): Likewise.
>
> 	(print_generic_decl): Update for renaming of "buffer" to
> 	"tree_pp".
> 	(print_generic_stmt): Likewise.
> 	(print_generic_stmt_indented): Likewise.
> 	(print_generic_expr): Likewise.
> 	(maybe_init_pretty_print): Likewise.
OK.
jeff

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2014-12-02 21:20 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-01-01  0:00 [PATCH 00/08] More memory leak fixes David Malcolm
2014-01-01  0:00 ` [PATCH 05/08] PR jit/63854: Fix double-initialization within tree-pretty-print.c David Malcolm
2014-01-01  0:00   ` Jeff Law
2014-01-01  0:00 ` [PATCH 06/08] Avoid overuse of name "buffer" in tree-pretty-print.c David Malcolm
2014-01-01  0:00   ` Jeff Law
2014-01-01  0:00 ` [PATCH 03/08] PR jit/63854: Fix leak in real.c for i386:init_ext_80387_constants David Malcolm
2014-01-01  0:00   ` Richard Biener
2014-01-01  0:00 ` [PATCH 07/08] PR jit/63854: Fix leaks in toyvm.c David Malcolm
2014-01-01  0:00 ` [PATCH 02/08] PR jit/63854: Fix leak within jit-builtins.c David Malcolm
2014-01-01  0:00 ` [PATCH 04/08] PR jit/63854: Remove xstrdup from ipa/cgraph fprintf calls David Malcolm
2014-01-01  0:00 ` [PATCH 01/08] PR jit/63854: Fix leak in tree-ssa-math-opts.c David Malcolm
2014-01-01  0:00   ` Richard Biener
2014-01-01  0:00 ` [PATCH 08/08] PR/64003 workaround (uninit memory in i386.md) David Malcolm
2014-01-01  0:00   ` Jeff Law
2014-01-01  0:00     ` David Malcolm
2014-01-01  0:00       ` Jeff Law
2014-01-01  0:00       ` Jeff Law

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).