diff -Naur ./gcc/Makefile.in ../gcc-4.1.0.patched/gcc/Makefile.in
--- ./gcc/Makefile.in	2006-02-16 16:23:24.000000000 +0100
+++ ../gcc-4.1.0.patched/gcc/Makefile.in	2006-03-01 19:08:45.000000000 +0100
@@ -770,6 +770,7 @@
 SYMTAB_H = $(srcdir)/../libcpp/include/symtab.h
 CPP_ID_DATA_H = $(CPPLIB_H) $(srcdir)/../libcpp/include/cpp-id-data.h
 TREE_DUMP_H = tree-dump.h $(SPLAY_TREE_H)
+XML_DUMP_H = xml-dump.h
 TREE_GIMPLE_H = tree-gimple.h tree-iterator.h
 TREE_FLOW_H = tree-flow.h tree-flow-inline.h tree-ssa-operands.h \
 		bitmap.h $(BASIC_BLOCK_H) hard-reg-set.h $(TREE_GIMPLE_H) \
@@ -984,7 +985,7 @@
  tree-profile.o rtlhooks.o cfgexpand.o lambda-mat.o    			   \
  lambda-trans.o	lambda-code.o tree-loop-linear.o tree-ssa-sink.o 	   \
  tree-vrp.o tree-stdarg.o tree-cfgcleanup.o tree-ssa-reassoc.o		   \
- tree-ssa-structalias.o tree-object-size.o
+ tree-ssa-structalias.o tree-object-size.o xml-dump.o
 
 
 OBJS-md = $(out_object_file)
@@ -1728,7 +1729,11 @@
    $(OBSTACK_H) pointer-set.h
 tree-dump.o: tree-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(TREE_H) langhooks.h toplev.h $(SPLAY_TREE_H) $(TREE_DUMP_H) \
-   tree-iterator.h tree-pass.h $(DIAGNOSTIC_H)
+   tree-iterator.h tree-pass.h $(DIAGNOSTIC_H) $(XML_DUMP_H)
+xml-dump.o: xml-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+   $(TREE_H) langhooks.h toplev.h $(SPLAY_TREE_H) $(XML_DUMP_H) $(TREE_DUMP_H)\
+   tree-iterator.h tree-pass.h $(DIAGNOSTIC_H) real.h basic-block.h tree-flow.h\
+   $(GGC_H)
 tree-inline.o : tree-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(TREE_H) $(RTL_H) $(EXPR_H) $(FLAGS_H) $(PARAMS_H) input.h insn-config.h \
    $(VARRAY_H) $(HASHTAB_H) $(SPLAY_TREE_H) toplev.h \
@@ -1944,7 +1949,7 @@
    $(C_TREE_H) $(C_COMMON_H) $(DIAGNOSTIC_H) $(TREE_GIMPLE_H) $(VARRAY_H) \
    $(FLAGS_H) langhooks.h toplev.h $(RTL_H) $(TREE_FLOW_H) $(LANGHOOKS_DEF_H) \
    $(TM_H) coretypes.h $(C_PRETTY_PRINT_H) $(CGRAPH_H) $(BASIC_BLOCK_H) \
-   hard-reg-set.h $(TREE_DUMP_H) tree-inline.h
+   hard-reg-set.h $(TREE_DUMP_H) tree-inline.h $(XML_DUMP_H)
 gimplify.o : gimplify.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
    $(DIAGNOSTIC_H) $(TREE_GIMPLE_H) tree-inline.h $(VARRAY_H) langhooks.h \
    $(LANGHOOKS_DEF_H) $(TREE_FLOW_H) $(CGRAPH_H) $(TIMEVAR_H) $(TM_H) \
@@ -2045,7 +2050,8 @@
    $(PARAMS_H) $(TM_P_H) reload.h dwarf2asm.h $(TARGET_H) \
    langhooks.h insn-flags.h $(CFGLAYOUT_H) real.h $(CFGLOOP_H) \
    hosthooks.h $(CGRAPH_H) $(COVERAGE_H) tree-pass.h $(TREE_DUMP_H) \
-   $(GGC_H) $(INTEGRATE_H) $(CPPLIB_H) opts.h tree-flow.h tree-inline.h
+   $(GGC_H) $(INTEGRATE_H) $(CPPLIB_H) opts.h tree-flow.h tree-inline.h \
+   $(XML_DUMP_H)
 
 main.o : main.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) toplev.h
 
@@ -2759,7 +2765,7 @@
   $(srcdir)/tree-ssa-operands.h $(srcdir)/tree-ssa-operands.c \
   $(srcdir)/tree-profile.c $(srcdir)/tree-nested.c \
   $(srcdir)/ipa-reference.c $(srcdir)/tree-ssa-structalias.h \
-  $(srcdir)/tree-ssa-structalias.c \
+  $(srcdir)/tree-ssa-structalias.c $(srcdir)/xml-dump.c \
   $(srcdir)/targhooks.c $(out_file) \
   @all_gtfiles@
 
diff -Naur ./gcc/c-gimplify.c ../gcc-4.1.0.patched/gcc/c-gimplify.c
--- ./gcc/c-gimplify.c	2005-06-25 04:02:01.000000000 +0200
+++ ../gcc-4.1.0.patched/gcc/c-gimplify.c	2006-03-01 19:08:45.000000000 +0100
@@ -46,6 +46,7 @@
 #include "tree-dump.h"
 #include "c-pretty-print.h"
 #include "cgraph.h"
+#include "xml-dump.h"
 
 
 /*  The gimplification pass converts the language-dependent trees
@@ -100,6 +101,10 @@
       fprintf (dump_file, "\n");
 
       dump_end (TDI_original, dump_file);
+
+      if(local_dump_flags & TDF_XML)
+	xml_dump_function(fndecl, TDI_original);
+
     }
 
   /* Go ahead and gimplify for now.  */
diff -Naur ./gcc/common.opt ../gcc-4.1.0.patched/gcc/common.opt
--- ./gcc/common.opt	2005-11-11 18:59:54.000000000 +0100
+++ ../gcc-4.1.0.patched/gcc/common.opt	2006-07-07 15:18:51.000000000 +0200
@@ -23,6 +23,10 @@
 
 ; Please try to keep this file in ASCII collating order.
 
+fxml
+Common
+Enable XML output.
+
 -help
 Common
 Display this information
diff -Naur ./gcc/flags.h ../gcc-4.1.0.patched/gcc/flags.h
--- ./gcc/flags.h	2005-06-29 05:01:27.000000000 +0200
+++ ../gcc-4.1.0.patched/gcc/flags.h	2006-07-07 15:18:51.000000000 +0200
@@ -82,6 +82,10 @@
 /* Global visibility options.  */
 extern struct visibility_flags visibility_options;
 
+/* enable or disable XML dump output */
+
+extern bool xml_dump;
+
 /* Nonzero means do optimizations.  -opt.  */
 
 extern int optimize;
diff -Naur ./gcc/opts.c ../gcc-4.1.0.patched/gcc/opts.c
--- ./gcc/opts.c	2005-12-06 12:28:18.000000000 +0100
+++ ../gcc-4.1.0.patched/gcc/opts.c	2006-07-07 15:18:51.000000000 +0200
@@ -40,6 +40,8 @@
 #include "target.h"
 #include "tree-pass.h"
 
+bool xml_dump = false;
+
 /* Value of the -G xx switch, and whether it was passed or not.  */
 unsigned HOST_WIDE_INT g_switch_value;
 bool g_switch_set;
@@ -749,6 +751,10 @@
       g_switch_set = true;
       break;
 
+    case OPT_fxml:
+      xml_dump = true;
+      break;
+
     case OPT_O:
     case OPT_Os:
       /* Currently handled in a prescan.  */
diff -Naur ./gcc/passes.c ../gcc-4.1.0.patched/gcc/passes.c
--- ./gcc/passes.c	2006-01-11 15:29:29.000000000 +0100
+++ ../gcc-4.1.0.patched/gcc/passes.c	2006-05-29 13:34:44.000000000 +0200
@@ -82,6 +82,7 @@
 #include "tree-flow.h"
 #include "tree-pass.h"
 #include "tree-dump.h"
+#include "xml-dump.h"
 
 #if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO)
 #include "dwarf2out.h"
@@ -100,6 +101,9 @@
 				   declarations for e.g. AIX 4.x.  */
 #endif
 
+/* dump intermediate representation and abort rest of compilation */
+#define IRDUMP_ENABLED
+
 /* Global variables used to communicate with passes.  */
 int dump_flags;
 bool in_gimple_form;
@@ -186,7 +190,10 @@
 
   /* Let cgraph know about the existence of variables.  */
   if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
-    cgraph_varpool_node (decl);
+    {
+      xml_dump_add_variable (decl);
+      cgraph_varpool_node (decl);
+    }
 }
 
 /* Called after finishing a record, union or enumeral type.  */
@@ -243,6 +250,10 @@
 	  free (name);
 	}
 
+  /* dump outstanding nodes of all phases and cleanup temporary data 
+     structures for XML dumps */
+  xml_dump_cleanup();
+
   timevar_pop (TV_DUMP);
 }
 
@@ -464,6 +475,9 @@
   NEXT_PASS (pass_fixup_cfg);
   NEXT_PASS (pass_init_datastructures);
   NEXT_PASS (pass_all_optimizations);
+#ifdef IRDUMP_ENABLED
+  NEXT_PASS (pass_irdump);
+#endif /* IRDUMP_ENABLED */
   NEXT_PASS (pass_warn_function_noreturn);
   NEXT_PASS (pass_mudflap_2);
   NEXT_PASS (pass_free_datastructures);
@@ -473,6 +487,10 @@
   NEXT_PASS (pass_clean_state);
   *p = NULL;
 
+  p = &pass_irdump.sub;
+  NEXT_PASS (pass_dump_xml);
+  p = NULL;
+  
   p = &pass_all_optimizations.sub;
   NEXT_PASS (pass_referenced_vars);
   NEXT_PASS (pass_create_structure_vars);
@@ -836,6 +854,10 @@
   if (todo)
     execute_todo (pass, todo, false);
 
+  /* Create (or append to) an additional dump in XML format */
+  if(dump_file && dump_flags & TDF_XML)
+    xml_dump_function(current_function_decl, pass->static_pass_number);
+
   /* Flush and close dump file.  */
   if (dump_file_name)
     {
diff -Naur ./gcc/tree-dump.c ../gcc-4.1.0.patched/gcc/tree-dump.c
--- ./gcc/tree-dump.c	2005-08-20 18:03:58.000000000 +0200
+++ ../gcc-4.1.0.patched/gcc/tree-dump.c	2006-03-01 19:08:45.000000000 +0100
@@ -32,6 +32,7 @@
 #include "tree-pass.h"
 #include "langhooks.h"
 #include "tree-iterator.h"
+#include "xml-dump.h"
 
 static unsigned int queue (dump_info_p, tree, int);
 static void dump_index (dump_info_p, unsigned int);
@@ -751,6 +752,7 @@
   {"lineno", TDF_LINENO},
   {"uid", TDF_UID},
   {"stmtaddr", TDF_STMTADDR},
+  {"xml", TDF_XML},
   {"all", ~(TDF_RAW | TDF_SLIM | TDF_LINENO | TDF_TREE | TDF_RTL | TDF_IPA 
 	    | TDF_STMTADDR | TDF_GRAPH)},
   {NULL, 0}
@@ -1039,6 +1041,9 @@
     {
       dump_function_to_file (fn, stream, flags);
       dump_end (phase, stream);
+
+      if(flags & TDF_XML)
+	xml_dump_function(fn, phase);
     }
 }
 
diff -Naur ./gcc/tree-pass.h ../gcc-4.1.0.patched/gcc/tree-pass.h
--- ./gcc/tree-pass.h	2005-10-11 21:18:24.000000000 +0200
+++ ../gcc-4.1.0.patched/gcc/tree-pass.h	2006-04-05 10:48:27.000000000 +0200
@@ -68,6 +68,7 @@
 #define TDF_STMTADDR	(1 << 12)	/* Address of stmt.  */
 
 #define TDF_GRAPH	(1 << 13)	/* a graph dump is being emitted */
+#define TDF_XML         (1 << 14)       /* emit a tree dump in XML format */
 
 extern char *get_dump_file_name (enum tree_dump_index);
 extern int dump_enabled_p (enum tree_dump_index);
@@ -376,6 +377,10 @@
 extern struct tree_opt_pass pass_set_nothrow_function_flags;
 extern struct tree_opt_pass pass_final;
 
+extern struct tree_opt_pass pass_irdump;
+extern struct tree_opt_pass pass_dump_xml;
+
+
 /* The root of the compilation pass tree, once constructed.  */
 extern struct tree_opt_pass *all_passes, *all_ipa_passes, *all_lowering_passes;
 
diff -Naur ./gcc/xml-dump.c ../gcc-4.1.0.patched/gcc/xml-dump.c
--- ./gcc/xml-dump.c	1970-01-01 01:00:00.000000000 +0100
+++ ../gcc-4.1.0.patched/gcc/xml-dump.c	2006-10-31 11:34:56.000000000 +0100
@@ -0,0 +1,2152 @@
+/* dumping functionality for trees in XML format.
+   Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
+   Written by Dietmar Ebner <ebner@complang.tuwien.ac.at>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "flags.h"
+#include "tree.h"
+#include "ggc.h"
+#include "splay-tree.h"
+#include "diagnostic.h"
+#include "toplev.h"
+#include "xml-dump.h"
+#include "tree-dump.h"
+#include "tree-pass.h"
+#include "langhooks.h"
+#include "tree-iterator.h"
+#include "real.h"
+#include "basic-block.h"
+#include "tree-flow.h"
+
+#define INDENT "  "
+
+#define XML_LT    "&lt;"
+#define XML_GT    "&gt;"
+#define XML_AMP   "&amp;"
+#define XML_APOS  "&apos;"
+#define XML_QUOTE "&quot;"
+#define XML_NUM_ESC "&#"
+
+#define HASH_SIZE (512)
+#define MAKEHASH(node) (((unsigned long) node >> 4) % HASH_SIZE)
+
+/* this must coincide with the number of elements in the enum tree_code_class */
+#define NUM_TREE_CLASSES 10
+
+typedef struct _xml_node_bucket GTY ((chain_next ("%h.next")))
+{
+  unsigned int id;
+  tree node;
+  bool complete;
+  struct _xml_node_bucket *next;
+} xml_node_bucket;
+
+typedef struct _xml_node_bucket* xml_node_bucket_p;
+
+struct xml_dump_info GTY (())
+{
+  /* phase */
+  enum tree_dump_index phase;
+  /* name of the dump file */
+  char *name;
+  /* the stream on which to dump to */
+  /* this should actually be of type FILE*, but then the ggc complains */
+  void *GTY ((skip(""))) stream;
+  /* indent level */
+  int indent;
+  /* id counter */
+  unsigned int next_ticket[NUM_TREE_CLASSES];
+  /* hashtable of dumped nodes */
+  xml_node_bucket_p hashtab[HASH_SIZE];
+};
+
+typedef struct xml_dump_info *xml_dump_info_p;
+
+/* current size of <phases> */
+static int phases_size = 0;
+/* a pointer array of dump info structures */
+static GTY ((length("phases_size"))) xml_dump_info_p *phases = NULL;
+/* number of registered dump phases so far */
+static int num_phases = 0;
+/* a pointer to the current dump info structure in use */
+static xml_dump_info_p cdi = NULL;
+/* a list of free hash table entries (will be recycled) */
+static GTY ((deletable (""))) xml_node_bucket_p free_list=NULL;
+
+static GTY(()) VEC(tree,gc) *xml_globals = NULL;
+
+/* prototypes */
+static xml_dump_info_p xml_dump_register (enum tree_dump_index phase);
+
+static int xprintf (const char *fmt, ...)
+  __attribute__ ((format (printf, 1, 2)));
+static int xiprintf (const char *fmt, ...)
+  __attribute__ ((format (printf, 1, 2)));
+static void indent (void);
+static bool is_empty_stmt (tree);
+static char *xml_escape (const char *s);
+
+static void xml_dump_header (void);
+static void xml_dump_footer (void);
+static void xml_dump_local_cleanup(void);
+
+static void dump_ref_attr(const char* attrname, tree t);
+static void dump_name_attr (tree);
+static void dump_type_attr (tree);
+static void dump_domain_attr (tree);
+static void dump_decl_attr (tree);
+static void xml_dump_node (tree t);
+static void dump_tcc_type (tree t);
+static void dump_tcc_declaration (tree t);
+static void dump_tcc_constant (tree t);
+static void dump_tcc_exceptional (tree t);
+static void dump_reference (tree t);
+
+static void dump_integer_cst_value (tree t);
+static void dump_real_cst_value (tree t);
+static void dump_string_cst_value (tree t);
+static void dump_cfg_edge (edge e);
+static void complete_dump_class (enum tree_code_class class, const char *tagname,
+			         void (*dump_fun) (tree));
+static void complete_dump_code (enum tree_code code, const char *tagname,
+			        void (*dump_fun) (tree));
+static void recursive_add_nodes(xml_node_bucket_p p);
+static void dump_basic_block (basic_block bb);
+
+static bool mark_bucket (tree, xml_node_bucket_p *);
+static xml_node_bucket_p get_bucket (tree);
+static xml_node_bucket_p add_bucket (tree, bool);
+static const char *tree_class_prfx (tree);
+
+#define SUBTAGS_INIT() \
+      if(!close_tag)       \
+	{                  \
+	  xprintf(">\n");  \
+	  cdi->indent ++;  \
+	  close_tag=true;  \
+	}
+
+static void
+indent (void)
+{
+  int i;
+  for (i = 0; i < cdi->indent; i++)
+    fprintf (cdi->stream, INDENT);
+}
+
+/* indents and prints to cdi->stream */
+static int
+xiprintf (const char *fmt, ...)
+{
+  int ret = 0;
+  va_list argptr;
+  va_start (argptr, fmt);
+
+  if (fmt && *fmt != '\0')
+    indent ();
+
+  ret = vfprintf (cdi->stream, fmt, argptr);
+  va_end (argptr);
+  return ret;
+}
+
+/* prints without prior indent */
+static int
+xprintf (const char *fmt, ...)
+{
+  int ret = 0;
+  va_list argptr;
+  va_start (argptr, fmt);
+  ret = vfprintf (cdi->stream, fmt, argptr);
+  va_end (argptr);
+  return ret;
+}
+
+/* returns true, if t is a stmt generated by build_empty_stmt */
+static bool
+is_empty_stmt (tree t)
+{
+  if (t && TREE_CODE (t) == NOP_EXPR && TREE_OPERAND (t, 0) == size_zero_node)
+      return true;
+  return false;
+}
+
+/* allocates a new string and replaces special characters */
+static char *
+xml_escape (const char *s)
+{
+  const char *p;
+  char *q, *new;
+  int len;
+
+  if (!s)
+    return NULL;
+  len = strlen (s);
+
+  p = s;
+  while (*p)
+    {
+      switch (*p)
+	{
+	case '<':
+	  len += strlen (XML_LT);
+	  break;
+	case '>':
+	  len += strlen (XML_GT);
+	  break;
+	case '&':
+	  len += strlen (XML_AMP);
+	  break;
+	case '\'':
+	  len += strlen (XML_APOS);
+	  break;
+	case '"':
+	  len += strlen (XML_QUOTE);
+	  break;
+	default:
+          if (*p < 32)
+            len += strlen (XML_NUM_ESC) + 3 + 1; /* &#<num>; */
+          break;
+	}
+      p++;
+    }
+
+  new = xmalloc (sizeof (char *) * (len + 1));
+  gcc_assert (new);
+
+  p = s;
+  q = new;
+  while (*p)
+    {
+      switch (*p)
+	{
+	case '<':
+	  strcpy (q, XML_LT);
+	  q += strlen (XML_LT);
+	  break;
+	case '>':
+	  strcpy (q, XML_GT);
+	  q += strlen (XML_GT);
+	  break;
+	case '&':
+	  strcpy (q, XML_AMP);
+	  q += strlen (XML_AMP);
+	  break;
+	case '\'':
+	  strcpy (q, XML_APOS);
+	  q += strlen (XML_APOS);
+	  break;
+	case '"':
+	  strcpy (q, XML_QUOTE);
+	  q += strlen (XML_QUOTE);
+	  break;
+	default:
+          if (*p < 32) {
+            sprintf (q, "%s%03d;", XML_NUM_ESC, *p);
+            q += strlen (XML_NUM_ESC) + 3 + 1; /* &#<num>; */
+          }
+          else {
+            *q = *p;
+            q++;
+          }
+          break;
+	}
+      p++;
+    }
+  *q = '\0';
+  return new;
+}
+
+/* creates a new hash table entry for the given node and sets the
+   <complete> flag to true
+   returns false if the node has already been dumped
+   the newly created or modified entry is returned in <hte>
+*/
+static bool
+mark_bucket (tree t, xml_node_bucket_p * hte)
+{
+  gcc_assert (t);
+
+  *hte = get_bucket (t);
+  if (*hte)
+    {
+      if ((*hte)->complete)	/* we already dumped this type */
+	return false;
+      else
+	(*hte)->complete = true;
+    }
+  else
+    (*hte) = add_bucket (t, true);
+  return true;
+}
+
+static xml_node_bucket_p
+get_bucket (tree t)
+{
+  unsigned int hash;
+  xml_node_bucket_p p;
+
+  gcc_assert (cdi->hashtab);
+  hash = MAKEHASH (t);
+  p = (cdi->hashtab)[hash];
+
+  while (p)
+    {
+      if (p->node == t)
+	return p;
+      p = p->next;
+    }
+
+  return NULL;
+}
+
+static xml_node_bucket_p
+add_bucket (tree t, bool complete)
+{
+  unsigned int hash;
+  xml_node_bucket_p p;
+  int class_id;
+
+  gcc_assert (cdi->hashtab && t);
+  hash = MAKEHASH (t);
+
+  /* use an entry in the free list if possible */
+  if(free_list)
+    {
+      p = free_list;
+      free_list = free_list->next;
+    }
+  else
+    {
+/*       p = xmalloc (sizeof (xml_node_bucket)); */
+      p = ggc_alloc (sizeof (xml_node_bucket));
+      gcc_assert (p);
+    }
+
+  p->node = t;
+  p->complete = complete;
+
+  /* get a new ticket for the given node */
+  class_id = (int) TREE_CODE_CLASS (TREE_CODE (t));
+  gcc_assert(class_id >=0 && class_id < NUM_TREE_CLASSES);
+  p->id = (cdi->next_ticket)[class_id]++;
+
+  p->next = (cdi->hashtab)[hash];
+  cdi->hashtab[hash] = p;
+
+  return p;
+}
+
+static const char *
+tree_class_prfx (tree t)
+{
+  enum tree_code_class class;
+
+  if (t != NULL_TREE)
+    {
+      class = TREE_CODE_CLASS (TREE_CODE (t));
+      switch (class)
+	{
+	case tcc_exceptional:
+	  return "EXC";
+	case tcc_constant:
+	  return "CST";
+	case tcc_type:
+	  return "TPE";
+	case tcc_declaration:
+	  return "DCL";
+	case tcc_reference:
+	  return "REF";
+	case tcc_comparison:
+	  return "CMP";
+	case tcc_unary:
+	  return "UNA";
+	case tcc_binary:
+	  return "BNA";
+	case tcc_statement:
+	  return "STM";
+	case tcc_expression:
+	  return "XPR";
+	}
+    }
+
+  gcc_unreachable ();
+  return NULL;
+}
+
+static void
+xml_dump_header (void)
+{
+  xiprintf ("<?xml version=\"1.0\" encoding=\"US-ASCII\" standalone=\"yes\"?>\n");
+  xiprintf ("\n");
+  xiprintf ("<translation_unit>\n");
+  cdi->indent++;
+}
+
+static void
+xml_dump_footer (void)
+{
+  cdi->indent--;
+  xiprintf ("</translation_unit>\n");
+}
+
+static xml_dump_info_p
+xml_dump_register (enum tree_dump_index phase)
+{
+  int i;
+  char *dname;
+  xml_dump_info_p p = NULL;
+
+  /* initialize dump info structure */
+  p = ggc_alloc (sizeof (struct xml_dump_info));
+  gcc_assert (p);
+
+  p->name = NULL;
+  dname = get_dump_file_name (phase);
+  if(dname)
+    {
+      p->name = concat (dname, ".xml", NULL);
+      gcc_assert (p->name);
+      free (dname);
+    }
+
+  p->indent = 0;
+  p->phase = phase;
+  p->stream = stdout;
+
+  if (p->name)
+    {
+    p->stream = fopen (p->name, "w");
+    if (!(p->stream))
+      {
+	error ("could not open dump file %qs: %s", p->name, strerror (errno));
+	return false;
+      }
+    }
+  
+  /* init hash table */
+  memset (p->hashtab, 0, sizeof (xml_node_bucket_p) * HASH_SIZE);
+
+  /* reset id tickets */
+  for (i = 0; i < NUM_TREE_CLASSES; i++)
+    (p->next_ticket)[i] = 0;
+
+  return p;
+}
+
+/* inspired/copied by from varasm.c::output_addressed_constants */
+static void
+recursive_add_all_nodes (tree exp)
+{
+  tree tem;
+
+  if (TREE_TYPE (exp) && !get_bucket (TREE_TYPE (exp))) {
+    recursive_add_nodes (add_bucket (TREE_TYPE (exp), false));
+  }
+
+  switch (TREE_CODE (exp))
+    {
+    case ADDR_EXPR:
+    case FDESC_EXPR:
+      /* Go inside any operations that get_inner_reference can handle and see
+	 if what's inside is a constant: no need to do anything here for
+	 addresses of variables or functions.  */
+      for (tem = TREE_OPERAND (exp, 0); handled_component_p (tem);
+	   tem = TREE_OPERAND (tem, 0))
+	;
+
+      /* If we have an initialized CONST_DECL, retrieve the initializer.  */
+      if (TREE_CODE (tem) == CONST_DECL && DECL_INITIAL (tem))
+	tem = DECL_INITIAL (tem);
+
+      if (CONSTANT_CLASS_P (tem) && !get_bucket (tem))
+        recursive_add_nodes (add_bucket (tem, false));
+      else if (TREE_CODE_CLASS (TREE_CODE (tem)) == tcc_declaration && !get_bucket (tem))
+        add_bucket (tem, false);
+      else if (TREE_CODE (tem) == CONSTRUCTOR)
+        recursive_add_all_nodes (tem);
+      else if (!get_bucket (tem))
+        gcc_unreachable ();
+      break;
+
+    case PLUS_EXPR:
+    case MINUS_EXPR:
+      recursive_add_all_nodes (TREE_OPERAND (exp, 1));
+      /* Fall through.  */
+
+    case NOP_EXPR:
+    case CONVERT_EXPR:
+    case NON_LVALUE_EXPR:
+    case VIEW_CONVERT_EXPR:
+      recursive_add_all_nodes (TREE_OPERAND (exp, 0));
+      break;
+
+    case CONSTRUCTOR:
+      {
+	unsigned HOST_WIDE_INT idx;
+	FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), idx, tem)
+	  if (tem != 0)
+	    recursive_add_all_nodes (tem);
+      }
+      break;
+
+    default:
+      break;
+    }
+}
+
+static void
+recursive_add_nodes(xml_node_bucket_p p)
+{
+  tree t;
+  enum tree_code code;
+  enum tree_code_class class;
+  
+  if (!p || p->complete)
+    return;
+  
+  code = TREE_CODE (p->node);
+  class = TREE_CODE_CLASS (code);
+
+  /* types or declarations might add types */
+  if ( (class == tcc_type || class == tcc_declaration) &&
+       TREE_TYPE (p->node) &&
+       ! get_bucket ( TREE_TYPE (p->node)))
+    {
+      recursive_add_nodes (add_bucket (TREE_TYPE (p->node), false));
+    }
+
+  /* initial expressions may add types, constants and declarations 
+   * the initial node may have expressions and constructors in it, thus
+   * the recursive_add_nodes function can not be used here.
+   */
+  if (code == VAR_DECL && DECL_INITIAL (p->node))
+    {
+      recursive_add_all_nodes (DECL_INITIAL (p->node));
+    }
+
+  /* typedefs might add their TYPE_DECL nodes */
+  if (class == tcc_type && 
+      TYPE_NAME (p->node) && 
+      TREE_CODE (TYPE_NAME (p->node)) == TYPE_DECL && 
+      !get_bucket(TYPE_NAME (p->node)))
+    {
+      recursive_add_nodes (add_bucket (TYPE_NAME (p->node), false));
+    }
+       
+  /* array types might add their domain */
+  if (code == ARRAY_TYPE && TYPE_DOMAIN (p->node) && !get_bucket (TYPE_DOMAIN (p->node)))
+    {
+      recursive_add_nodes (add_bucket (TYPE_DOMAIN(p->node), false));
+    }
+
+  /* some types have field declarations */
+  if((code == RECORD_TYPE || code == UNION_TYPE || code == QUAL_UNION_TYPE) && TYPE_FIELDS (p->node))
+    {
+      for (t = TYPE_FIELDS (p->node); t; t = TREE_CHAIN (t))
+	{
+	  if (!get_bucket (t))
+	    recursive_add_nodes (add_bucket (t, false));
+	}
+    }
+
+  /* function types have parameters */
+  if(code == FUNCTION_TYPE && TYPE_ARG_TYPES (p->node))
+   {
+     for (t = TYPE_ARG_TYPES (p->node); t; t = TREE_CHAIN (t))
+     {
+       if (!get_bucket (TREE_VALUE (t)))
+         recursive_add_nodes (add_bucket (TREE_VALUE (t), false));
+     }
+   }
+
+  /* complex constants are built of an imaginary and real part */
+  if (code == COMPLEX_CST)
+    {
+      if (!get_bucket (TREE_REALPART (p->node)))
+        recursive_add_nodes (add_bucket (TREE_REALPART (p->node), false));
+
+      if (!get_bucket (TREE_IMAGPART (p->node)))
+        recursive_add_nodes (add_bucket (TREE_IMAGPART (p->node), false));
+    }
+}
+
+void
+xml_dump_cleanup (void)
+{
+  int phase, j, i;
+  xml_node_bucket_p p, q;
+  tree decl;
+
+  for (phase = 0; phase < num_phases; phase++)
+    {
+      cdi = phases[phase];
+      if (cdi)
+        {
+          if (xml_globals) {
+            for (i = 0; VEC_iterate (tree, xml_globals, i, decl); i++) {
+              if (!get_bucket (decl))
+                add_bucket (decl, false);
+            }
+          }
+
+	  /* make sure, all nodes referenced by incomplete entries are added 
+	     to the hashtable */
+	  for (j = 0; j < HASH_SIZE; j++)
+	    {
+	      for (p = cdi->hashtab[j]; p; p = p->next)
+		recursive_add_nodes(p);
+	    }
+
+          /* functions */
+	  complete_dump_code (FUNCTION_DECL, NULL, &dump_tcc_declaration);
+
+	  /* global types */
+	  /* dump types before declarations to handle FIELD_DECLS along with their types */
+	  complete_dump_class (tcc_type, "types", &dump_tcc_type);
+
+	  /* global declarations */
+	  complete_dump_class (tcc_declaration, "declarations", &dump_tcc_declaration);
+	  
+	  /* constants */
+	  complete_dump_class (tcc_constant, "constants", &dump_tcc_constant);
+
+	  /* footer */
+	  xml_dump_footer ();
+
+	  /* begin cleanup */
+	  fclose (cdi->stream);
+	  cdi->stream = NULL;
+
+	  /* free the hashtable */
+	  for (j = 0; j < HASH_SIZE; j++)
+	    {
+	      p = (cdi->hashtab)[j];
+	      while (p)
+		{
+		  /* make sure the particular node has been dumped */
+ 		  gcc_assert (p->complete || TREE_CODE(p->node) == FUNCTION_DECL);
+		  q = p;
+		  p = p->next;
+		  ggc_free (q);
+		}
+	    }
+
+	  ggc_free (cdi);
+	  cdi = phases[phase] = NULL;
+	}
+    }
+
+  if (phases)
+    ggc_free (phases);
+
+  /* cleanup free list */
+  p = free_list;
+  while (p)
+    {
+      q = p;
+      p = p->next;
+      ggc_free (q);
+    }
+
+  phases = NULL;
+  phases_size = 0;
+  num_phases = 0;
+  free_list = NULL;
+}
+
+/* moves entries that should not be referenced from other function
+   trees any more from the hash table to the free list */
+static void
+xml_dump_local_cleanup (void)
+{
+  int i;
+  xml_node_bucket_p p;
+  xml_node_bucket_p *pp;
+  enum tree_code code;
+  enum tree_code_class class;
+  bool remove;
+
+  for (i = 0; i < HASH_SIZE; i++)
+    {
+      pp = &((cdi->hashtab)[i]);
+      while (*pp)
+	{
+	  p = *pp;
+
+	  code = TREE_CODE (p->node);
+	  class = TREE_CODE_CLASS (code);
+	  remove = true;
+
+	  if (class == tcc_constant)
+	    remove = false;
+	  if (class == tcc_type)
+	    remove = TYPE_CONTEXT (p->node) && TREE_CODE (TYPE_CONTEXT (p->node)) != TRANSLATION_UNIT_DECL;
+	  else if (class == tcc_declaration && CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
+	    remove = DECL_CONTEXT (p->node) && TREE_CODE (DECL_CONTEXT (p->node)) != TRANSLATION_UNIT_DECL;
+	  remove = remove && p->complete;
+
+	  if (remove)
+	    {
+	      /* unlink the node from the hash table */
+	      *pp = p->next;
+
+	      /* add the node to the free_list */
+	      memset (p, 0, sizeof (xml_node_bucket));
+	      p->next = free_list;
+	      free_list = p;
+	    }
+	  else
+	    {
+	      pp = &(p->next);
+	    }
+	}
+    }
+}
+
+static void 
+dump_ref_attr(const char* attrname, tree t)
+{
+  xml_node_bucket_p p;
+  
+  /* we only want to reference the given type, so check if it has 
+     already been dumped */
+  p = get_bucket (t);
+
+  if (!p)
+    {
+      /* create a preliminary id that must be used in the subsequent
+         dump of the node */
+      p = add_bucket (t, false);
+      gcc_assert (p);
+    }
+
+  xprintf (" %s=\"%s%u\"", attrname, tree_class_prfx (t), p->id);
+}
+
+static void
+dump_type_attr (tree type)
+{
+  gcc_assert (type && TREE_CODE_CLASS (TREE_CODE (type)) == tcc_type);
+  dump_ref_attr("type", type);
+}
+
+
+static void
+dump_domain_attr (tree t)
+{
+  gcc_assert (t);
+  dump_ref_attr("domain", t);
+}
+
+static void
+dump_decl_attr (tree t)
+{
+  gcc_assert (t && TREE_CODE(t) == TYPE_DECL);
+  dump_ref_attr("decl", t);
+}
+
+static void
+dump_name_attr (tree name)
+{
+  char *cp;
+  if (name != NULL_TREE)
+    {
+      cp = xml_escape (IDENTIFIER_POINTER (name));
+      xprintf (" name=\"%s\"", cp ? cp : "");
+      free (cp);
+    }
+}
+
+static void
+dump_cfg_edge (edge e)
+{
+  xiprintf ("<edge");
+
+  /* from & to */
+  xprintf (" from=\"%d\" to=\"%d\"", e->src->index, e->dest->index);
+
+  /* fallthru */
+  if (e->flags & EDGE_FALLTHRU)
+    xprintf (" fallthru=\"true\"");
+
+  /* abnormal */
+  if (e->flags & EDGE_ABNORMAL)
+    xprintf (" abnormal=\"true\"");
+
+  /* abnormal-call */
+  if (e->flags & EDGE_ABNORMAL_CALL)
+    xprintf (" abnormal-call=\"true\"");
+
+  /* exception-throw */
+  if (e->flags & EDGE_EH)
+    xprintf (" exception-throw=\"true\"");
+
+  /* faked */
+  if (e->flags & EDGE_FAKE)
+    xprintf (" faked=\"true\"");
+
+  /* backward */
+  if (e->flags & EDGE_DFS_BACK)
+    xprintf (" backward=\"true\"");
+
+  /* can-fallthru */
+  if (e->flags & EDGE_CAN_FALLTHRU)
+    xprintf (" can-fallthru=\"true\"");
+
+  /* irreducible-loop */
+  if (e->flags & EDGE_IRREDUCIBLE_LOOP)
+    xprintf (" irreducible-loop=\"true\"");
+
+  /* sibcall */
+  if (e->flags & EDGE_SIBCALL)
+    xprintf (" sibcall=\"true\"");
+
+  /* loop-exit */
+  if (e->flags & EDGE_LOOP_EXIT)
+    xprintf (" loop-exit=\"true\"");
+
+  /* taken-on-true */
+  if (e->flags & EDGE_TRUE_VALUE)
+    xprintf (" taken-on-true=\"true\"");
+
+  /* taken-on-false */
+  if (e->flags & EDGE_FALSE_VALUE)
+    xprintf (" taken-on-false=\"true\"");
+
+  xprintf (" />\n");
+}
+
+static void
+dump_integer_cst_value (tree t)
+{
+  if (t == NULL_TREE || TREE_CODE (t) != INTEGER_CST)
+    return;
+
+  if (TREE_INT_CST_HIGH (t) == 0)
+    xprintf (HOST_WIDE_INT_PRINT_UNSIGNED, TREE_INT_CST_LOW (t));
+  else if (TREE_INT_CST_HIGH (t) == -1 && TREE_INT_CST_LOW (t) != 0)
+    xprintf ("-" HOST_WIDE_INT_PRINT_UNSIGNED, -TREE_INT_CST_LOW (t));
+  else
+    xprintf (HOST_WIDE_INT_PRINT_DOUBLE_HEX, TREE_INT_CST_HIGH (t),
+	     TREE_INT_CST_LOW (t));
+}
+
+static void
+dump_real_cst_value (tree t)
+{
+  REAL_VALUE_TYPE d;
+
+  if (t == NULL_TREE || TREE_CODE (t) != REAL_CST)
+    return;
+
+  d = TREE_REAL_CST (t);
+
+  if (REAL_VALUE_ISINF (d))
+    xprintf ("INF");
+  else if (REAL_VALUE_ISNAN (d))
+    xprintf ("NAN");
+  else
+    {
+      char buffer[64];
+      real_to_decimal (buffer, &d, sizeof (buffer), 0, 1);
+      xprintf ("%s", buffer);
+    }
+}
+
+static void
+dump_string_cst_value (tree t)
+{
+  char *p;
+  int len;
+
+  if (t == NULL_TREE || TREE_CODE (t) != STRING_CST)
+    return;
+  
+  p = xml_escape(TREE_STRING_POINTER (t));
+  len = TREE_STRING_LENGTH (t);
+  xprintf("%s", p);
+  free(p);
+}
+
+static void
+dump_tcc_type (tree t)
+{
+  const char *code_name;
+  char *p;
+  enum machine_mode mode;
+  xml_node_bucket_p hte;
+  bool close_tag, is_typedef;
+  tree s;
+  int quals;
+
+  gcc_assert (t && TREE_CODE_CLASS (TREE_CODE (t)) == tcc_type);
+
+  /* hash table bookkeeping */
+  if (!mark_bucket (t, &hte))
+    gcc_unreachable ();
+
+  code_name = tree_code_name[(int) TREE_CODE (t)];
+
+  xiprintf ("<%s", code_name);
+
+  /* name */
+  is_typedef = false;
+  if (TYPE_NAME (t))
+    {
+      if (TREE_CODE (TYPE_NAME (t)) == IDENTIFIER_NODE)
+	dump_name_attr (TYPE_NAME (t));
+      else if (TREE_CODE (TYPE_NAME (t)) == TYPE_DECL
+	       && DECL_NAME (TYPE_NAME (t)))
+	{
+	  dump_name_attr (DECL_NAME (TYPE_NAME (t)));
+	  is_typedef = true;
+	}
+    }
+  
+  if(is_typedef)
+    dump_decl_attr (TYPE_NAME (t));
+
+  /* uid */
+  xprintf (" uid=\"%s%u\"", tree_class_prfx (t), hte->id);
+
+  /* type */
+  if (TREE_TYPE (t))
+    dump_type_attr (TREE_TYPE (t));
+
+  /* domain */
+  if (TREE_CODE (t) == ARRAY_TYPE && TYPE_DOMAIN (t))
+    dump_domain_attr (TYPE_DOMAIN (t));
+
+  /* unsigned */
+  if (TYPE_UNSIGNED (t))
+    xprintf (" unsigned=\"true\"");
+
+  /* qualifier */
+  quals = lang_hooks.tree_dump.type_quals (t);
+  if (quals != TYPE_UNQUALIFIED)
+    {
+      xprintf (" qualifiers=\"");
+      if (quals & TYPE_QUAL_CONST)
+	xprintf ("const");
+      if (quals & TYPE_QUAL_VOLATILE)
+	xprintf ("%svolatile", quals & TYPE_QUAL_CONST ? " " : "");
+      if (quals & TYPE_QUAL_RESTRICT)
+	xprintf ("%srestrict", quals & TYPE_QUAL_CONST
+		 || quals & TYPE_QUAL_VOLATILE ? " " : "");
+      xprintf ("\"");
+    }
+
+  /* mode */
+  if ((mode = TYPE_MODE (t)))
+    {
+      p = xml_escape (GET_MODE_NAME (mode));
+      xprintf (" mode=\"%s\"", p);
+      free (p);
+    }
+
+  /* size */
+  if (TYPE_SIZE (t))
+    {
+      xprintf (" size=\"");
+      dump_integer_cst_value (TYPE_SIZE (t));
+      xprintf ("\"");
+    }
+
+  /*unit-size */
+  if (TYPE_SIZE_UNIT (t))
+    {
+      xprintf (" unit-size=\"");
+      dump_integer_cst_value (TYPE_SIZE_UNIT (t));
+      xprintf ("\"");
+    }
+
+  /* align */
+  xprintf (" align=\"%d\"", TYPE_ALIGN (t));
+
+  if (INTEGRAL_TYPE_P (t) || TREE_CODE (t) == REAL_TYPE)
+    {
+      /* precision */
+      xprintf (" precision=\"%d\"", TYPE_PRECISION (t));
+
+      /* min value */
+      if (TYPE_MIN_VALUE (t))
+	{
+	  xprintf (" min=\"");
+	  dump_integer_cst_value (TYPE_MIN_VALUE (t));
+	  xprintf ("\"");
+	}
+
+      /* max value */
+      if (TYPE_MAX_VALUE (t))
+	{
+	  xprintf (" max=\"");
+	  dump_integer_cst_value (TYPE_MAX_VALUE (t));
+	  xprintf ("\"");
+	}
+    }
+
+  /* some types require some more care */
+  close_tag = false;
+  if (TREE_CODE (t) == VECTOR_TYPE)
+    {
+      /* nunits  */
+      xprintf (" nunits=\"%d\"", (int) TYPE_VECTOR_SUBPARTS (t));
+    }
+  else if (TREE_CODE (t) == ENUMERAL_TYPE)
+    {
+      /* values */
+      s = TYPE_VALUES (t);
+      while (s)
+	{
+	  SUBTAGS_INIT ();
+	  xiprintf("<item ");
+	  
+	  /* name */
+	  if (TREE_PURPOSE (s))
+	    dump_name_attr (TREE_PURPOSE (s));
+	  
+	  /* value */
+	  if (TREE_VALUE (s))
+	    dump_ref_attr ("value", TREE_VALUE (s));
+	  
+	  xprintf (" />\n");
+
+	  s = TREE_CHAIN (s);
+	}
+      
+    }
+  else if ((TREE_CODE (t) == RECORD_TYPE
+	    || TREE_CODE (t) == UNION_TYPE
+	    || TREE_CODE (t) == QUAL_UNION_TYPE) &&
+	   TYPE_FIELDS (t))
+    {
+      /* <fields> */
+      SUBTAGS_INIT ();
+      xiprintf("<fields>\n");
+      cdi->indent++;
+	
+      s = TYPE_FIELDS (t);
+      while (s)
+	{
+	  dump_tcc_declaration(s);
+	  s = TREE_CHAIN (s);
+	}
+      
+      cdi->indent--;
+      xiprintf("</fields>\n");
+    }
+  else if (TREE_CODE (t) == FUNCTION_TYPE && TYPE_ARG_TYPES(t))  
+    {
+      SUBTAGS_INIT ();
+      xiprintf("<params>\n");
+      cdi->indent++;
+
+      s = TYPE_ARG_TYPES (t);
+      while (s)
+	{
+          xiprintf("<param ");
+          dump_type_attr (TREE_VALUE (s));
+          xprintf("/>\n");
+	  s = TREE_CHAIN (s);
+	}
+
+      cdi->indent--;
+      xiprintf("</params>\n");
+    }
+
+  if (close_tag)
+    {
+      cdi->indent--;
+      xiprintf ("</%s>\n", code_name);
+    }
+  else
+    xprintf (" />\n");
+}
+
+static void
+dump_tcc_declaration (tree t)
+{
+  const char *code_name;
+  enum tree_code code;
+  const char *tagname;
+  char *p;
+  enum machine_mode mode;
+  expanded_location loc;
+  tree arg, vars;
+  basic_block bb;
+  xml_node_bucket_p hte;
+  bool close_tag = false, have_cfg = false, have_varlist = false;
+
+  gcc_assert (t && TREE_CODE_CLASS (TREE_CODE (t)) == tcc_declaration);
+
+  /* hash table bookkeeping */
+  if (!mark_bucket (t, &hte))
+    {
+      dump_reference(t);
+      return;
+    }
+
+  code = TREE_CODE (t);
+  code_name = tree_code_name[(int) code];
+  xiprintf ("<%s", code_name);
+
+  /* name */
+  if (DECL_NAME (t))
+    dump_name_attr (DECL_NAME (t));
+  else if (code == LABEL_DECL && LABEL_DECL_UID (t) != -1)
+    xprintf (" name=\"L_" HOST_WIDE_INT_PRINT_DEC "\"", LABEL_DECL_UID (t));
+  else if (code == CONST_DECL)
+    xprintf (" name=\"C_%u\"", DECL_UID (t));
+  else
+    xprintf (" name=\"D_%u\"", DECL_UID (t));
+
+  /* uid */
+  xprintf (" uid=\"%s%u\"", tree_class_prfx (t), hte->id);
+
+  /* id */
+  xprintf (" id=\"%u\"", DECL_UID (t));
+
+  /* type */
+  if (TREE_TYPE (t))
+    dump_type_attr (TREE_TYPE (t));
+
+  /* location */
+  loc = expand_location (DECL_SOURCE_LOCATION (t));
+  p = xml_escape (loc.file);
+  xprintf (" location=\"%s:%d\"", p, loc.line);
+  free (p);
+
+  if(is_gimple_variable (t))
+    {
+      if(is_global_var(t))
+	xprintf(" storage-class=\"global\"");
+      else if(is_gimple_reg(t))
+	xprintf(" storage-class=\"register\"");
+      else
+	xprintf(" storage-class=\"stack\"");
+    }
+  
+  if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
+    {
+      /* unsigned */
+      if (DECL_UNSIGNED (t))
+	xprintf (" unsigned=\"true\"");
+
+      /* ignored */
+      if (DECL_IGNORED_P (t))
+	xprintf (" ignored=\"true\"");
+      
+      /* abstract */
+      if (DECL_ABSTRACT (t))
+	xprintf (" abstract=\"true\"");
+
+      /* external */
+      if (DECL_EXTERNAL (t))
+	xprintf (" external=\"true\"");
+
+      /* nonlocal */
+      if (DECL_NONLOCAL (t))
+	xprintf (" nonlocal=\"true\"");
+
+      /* virtual */
+      if (DECL_VIRTUAL_P (t))
+	xprintf (" virtual=\"true\"");
+
+      /* preserve */
+      if (DECL_PRESERVE_P (t))
+	xprintf (" preserve=\"true\"");
+    }
+  
+  if (code == FUNCTION_DECL)
+    {
+      have_cfg = cfun && cfun->decl == t && cfun->cfg && basic_block_info;
+      have_varlist = cfun && cfun->decl == t && cfun->unexpanded_var_list;
+
+      /* static or global */
+      if (TREE_PUBLIC (t))
+	xprintf (" public=\"true\"");
+
+      /* cfg */
+      xprintf (" cfg=\"%s\"", have_cfg ? "true" : "false");
+
+      /* inline (true, false, auto) */
+      xprintf (" inline=\"%s\"", DECL_INLINE (t) ? (DECL_DECLARED_INLINE_P (t) ? "true" : "auto") : "false");
+
+      /* built-in */
+      if (DECL_BUILT_IN (t))
+	{
+	  xprintf (" built-in=\"true\"");
+	  xprintf (" built-in-class=\"%s:%s\"",
+		   built_in_class_names[(int) DECL_BUILT_IN_CLASS (t)],
+		   built_in_names[(int) DECL_FUNCTION_CODE (t)]);
+	}
+
+      /* no-static-chain */
+      if (DECL_NO_STATIC_CHAIN (t))
+	xprintf (" no-static-chain=\"true\"");
+    }
+  else if (code == FIELD_DECL)
+    {
+      /* packed */
+      if (DECL_PACKED (t))
+	xprintf (" packed=\"true\"");
+
+      /* bit-field */
+      if (DECL_BIT_FIELD (t))
+	xprintf (" bit-field=\"true\"");
+
+      /* nonadressable */
+      if (DECL_NONADDRESSABLE_P (t))
+	xprintf (" nonadressable=\"true\"");
+
+      /* offset */
+      xprintf (" offset=\"");
+      dump_integer_cst_value (DECL_FIELD_OFFSET (t));
+      xprintf ("\"");
+
+      /* offset-align */
+      xprintf (" offset-align=\"" HOST_WIDE_INT_PRINT_UNSIGNED "\"", DECL_OFFSET_ALIGN (t));
+
+      /* bit-offset */
+      xprintf (" bit-offset=\"");
+      dump_integer_cst_value (DECL_FIELD_BIT_OFFSET (t));
+      xprintf ("\"");
+    }
+  else if (code == LABEL_DECL)
+    {
+      /* error-issued */
+      if (DECL_ERROR_ISSUED (t))
+	xprintf (" error-issued=\"true\"");
+    }
+  else if (code == VAR_DECL)
+    {
+      /* in-text-section */
+      if (DECL_IN_TEXT_SECTION (t))
+	xprintf (" in-text-section=\"true\"");
+
+      /* static or global */
+      if (TREE_PUBLIC (t))
+	xprintf (" public=\"true\"");
+
+      /* common */
+      if (DECL_COMMON (t))
+	xprintf (" common=\"true\"");
+
+      /* tls-model (global-dynamic, local-dynamic, initial-exec, local-exec) */
+      if (DECL_THREAD_LOCAL_P (t))
+	{
+	  enum tls_model tlsmodel = DECL_TLS_MODEL (t);
+	  const char *modelattr;
+	  switch (tlsmodel)
+	    {
+	    case TLS_MODEL_GLOBAL_DYNAMIC:
+	      modelattr = "global-dynamic";
+	      break;
+	    case TLS_MODEL_LOCAL_DYNAMIC:
+	      modelattr = "local-dynamic";
+	      break;
+	    case TLS_MODEL_INITIAL_EXEC:
+	      modelattr = "initial-exec";
+	      break;
+	    case TLS_MODEL_LOCAL_EXEC:
+	      modelattr = "local-exec";
+	      break;
+	    default:
+	      gcc_unreachable ();
+	    }
+	  xprintf (" tls-model=\"%s\"", modelattr);
+	}
+    }
+
+  if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
+    {	  
+      /* mode */
+      if ((mode = DECL_MODE (t)))
+	{
+	  p = xml_escape (GET_MODE_NAME (mode));
+	  xprintf (" mode=\"%s\"", p);
+	  free (p);
+	}
+
+      /* size */
+      if (DECL_SIZE (t))
+	{
+	  xprintf (" size=\"");
+	  dump_integer_cst_value (DECL_SIZE (t));
+	  xprintf ("\"");
+	}
+      
+      /* unit-size */
+      if (DECL_SIZE_UNIT (t))
+	{
+	  xprintf (" unit-size=\"");
+	  dump_integer_cst_value (DECL_SIZE_UNIT (t));
+	  xprintf ("\"");
+	}
+
+      /* align */
+      if (code != FUNCTION_DECL)
+	xprintf (" align=\"%d\"", DECL_ALIGN (t));
+    }
+
+  close_tag = false;
+  if(code == FUNCTION_DECL)
+    {
+      /* <arguments> */
+      arg = DECL_ARGUMENTS (t);
+      if (arg)
+	{
+	  SUBTAGS_INIT ();
+	  xiprintf ("<arguments>\n");
+	  cdi->indent++;
+	  /* dump the whole chain */
+	  while (arg)
+	    {
+	      /* dump the actual declaration instead of a refernce */
+	      dump_tcc_declaration (arg);
+	      arg = TREE_CHAIN (arg);
+	    }
+	  cdi->indent--;
+	  xiprintf ("</arguments>\n");
+	}
+    }
+
+  if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON) && DECL_INITIAL (t))
+    {
+      switch (code)
+	{
+	case TRANSLATION_UNIT_DECL:
+	  tagname = "namespaces";
+	  break;
+	case VAR_DECL:
+	  tagname = "initial";
+	  break;
+	case FIELD_DECL:
+	  tagname = "values";
+	  break;
+	default:
+	  tagname = NULL;
+	}
+
+      if (tagname)
+	{
+	  SUBTAGS_INIT ();
+	  xiprintf ("<%s>\n", tagname);
+	  cdi->indent++;
+	  xml_dump_node (DECL_INITIAL (t));
+	  cdi->indent--;
+	  xiprintf ("</%s>\n", tagname);
+	}
+    }
+
+  if (code == FUNCTION_DECL && !DECL_EXTERNAL (t))
+    {
+      /*lowering GIMPLE removes declaration of variables in BIND_EXPR nodes
+         -> dump them here separately
+       */
+      if (have_varlist)
+	{
+	  SUBTAGS_INIT ();
+	  vars = cfun->unexpanded_var_list;
+	  xiprintf ("<declarations>\n");
+	  cdi->indent++;
+
+	  while (vars)
+	    {
+	      dump_tcc_declaration (TREE_VALUE (vars));
+	      vars = TREE_CHAIN (vars);
+	    }
+	  cdi->indent--;
+	  xiprintf ("</declarations>\n");
+	}
+
+      /* dump the result declaration, if available */
+      if (DECL_RESULT (t))
+	{
+	  SUBTAGS_INIT ();
+	  xiprintf ("<result>\n");
+	  cdi->indent++;
+	  dump_tcc_declaration (DECL_RESULT (t));
+	  cdi->indent--;
+	  xiprintf ("</result>\n");
+	}
+
+      /* <body> */
+      if (have_cfg)
+	{
+	  /* make a cfg based dump */
+	  FOR_EACH_BB (bb) dump_basic_block (bb);
+	}
+      else
+	{
+	  /* make a tree based dump */
+	  if (DECL_SAVED_TREE (t))
+	    {
+	      SUBTAGS_INIT ();
+	      xiprintf ("<body>\n");
+	      cdi->indent++;
+	      xml_dump_node (DECL_SAVED_TREE (t));
+	      cdi->indent--;
+	      xiprintf ("</body>\n");
+	    }
+	}
+    }
+
+  if (close_tag)
+    {
+      cdi->indent--;
+      xiprintf ("</%s>\n", code_name);
+    }
+  else
+    xprintf (" />\n");
+}
+
+static void
+dump_tcc_constant (tree t)
+{
+  const char *code_name;
+  xml_node_bucket_p hte;	/* hash table entry */
+  tree val;
+  int i;
+
+  gcc_assert (t && TREE_CODE_CLASS (TREE_CODE (t)) == tcc_constant);
+
+  /* hash table bookkeeping */
+  if (!mark_bucket (t, &hte))
+    gcc_unreachable ();
+
+  code_name = tree_code_name[(int) TREE_CODE (t)];
+  xiprintf ("<%s", code_name);
+
+  /* uid */
+  xprintf (" uid=\"%s%u\"", tree_class_prfx (t), hte->id);
+
+  if (TREE_CODE (t) == STRING_CST)
+    xprintf (" length=\"%d\"", TREE_STRING_LENGTH (t));
+  else if (TREE_CONSTANT_OVERFLOW (t))
+    xprintf (" overflow=\"true\"");
+    
+  xprintf (">");
+
+  switch (TREE_CODE (t))
+    {
+    case INTEGER_CST:
+      dump_integer_cst_value (t);
+      break;
+    case REAL_CST:
+      dump_real_cst_value (t);
+      break;
+    case COMPLEX_CST:
+      xprintf ("\n");
+      cdi->indent++;
+      xiprintf ("<real>\n");
+      cdi->indent++;
+      xml_dump_node (TREE_REALPART (t));
+      cdi->indent--;
+      xiprintf ("</real>\n");
+      xiprintf ("<imag>\n");
+      cdi->indent++;
+      xml_dump_node (TREE_IMAGPART (t));
+      cdi->indent--;
+      xiprintf ("</imag>\n");
+      indent ();
+      break;
+    case VECTOR_CST:
+      xprintf ("\n");
+      cdi->indent++;
+      val = TREE_VECTOR_CST_ELTS (t);
+      for (i = 0; val; val = TREE_CHAIN (val), i++)
+	{
+	  xiprintf ("<element index=\"%d\">\n", i);
+	  cdi->indent++;
+	  xml_dump_node (TREE_VALUE (val));
+	  cdi->indent--;
+	  xiprintf ("</element>\n");
+	}
+      cdi->indent--;
+      indent ();
+      break;
+    case STRING_CST:
+      dump_string_cst_value (t);
+      break;
+    default:
+      gcc_unreachable ();
+    }
+
+  xprintf ("</%s>\n", code_name);
+}
+
+static void
+dump_tcc_exceptional (tree t)
+{
+  const char *code_name;
+  char *cp;
+  tree_stmt_iterator iter;
+/*   struct ptr_info_def *pi; */
+  xml_node_bucket_p hte, p;
+  int len, i;
+  tree var, s;
+
+  
+  gcc_assert (t && TREE_CODE_CLASS (TREE_CODE (t)) == tcc_exceptional);
+  code_name = tree_code_name[(int) TREE_CODE (t)];
+  
+  if (t == error_mark_node)
+    {
+      xiprintf("<error_mark />\n");
+      return;
+    }
+  
+  /* only some types may be references anyway, e.g., via SSA_NAME_DEF_STMT */
+  if (TREE_CODE (t) == SSA_NAME || TREE_CODE (t) == PHI_NODE)
+    {
+      /* hash table bookkeeping */
+      if (!mark_bucket (t, &hte))
+	{
+	  dump_reference (t);
+	  return;
+	}
+
+      xiprintf ("<%s uid=\"%s%u\"", code_name, tree_class_prfx (t), hte->id);
+    }
+  else
+    xiprintf ("<%s", code_name);
+
+  switch (TREE_CODE (t))
+    {
+    case ERROR_MARK:
+      xprintf (" />\n");
+      break;
+    case IDENTIFIER_NODE:
+      cp = xml_escape (IDENTIFIER_POINTER (t));
+      xprintf (" length=\"%d\">%s</%s>\n",
+	       IDENTIFIER_LENGTH (t), cp, code_name);
+      free (cp);
+      break;
+    case TREE_VEC:
+      len = TREE_VEC_LENGTH (t);
+      xprintf (" length=\"%d\">\n", len);
+      cdi->indent++;
+      for (i = 0; i < len; i++)
+	{
+	  s = TREE_VEC_ELT (t, i);
+	  if (s)	    
+	    xml_dump_node (TREE_VEC_ELT (t, i));
+	  else
+	    xiprintf ("<null_expr />\n");
+	}
+      cdi->indent--;
+      xiprintf ("</%s>\n", code_name);
+      break;
+    case PLACEHOLDER_EXPR:
+      xprintf (" />\n");
+      break;
+    case SSA_NAME:
+      /* references */
+      if ((var = SSA_NAME_VAR (t)))
+	{
+	  if (!(p = get_bucket (var)))
+	    p = add_bucket (var, false);
+	  xprintf (" references=\"%s%u\"", tree_class_prfx (var), p->id);
+	}
+
+      /* def-stmt */
+      if ((s = SSA_NAME_DEF_STMT (t)))
+	{
+	  /*undefined variables, e.g. PARM_DECL, are linked to empty expressions 
+	    which will never been dumped -> omit the def-stmt attribute in those
+	    cases */
+	  if (!is_empty_stmt (s))
+	    {
+	      if (!(p = get_bucket (s)))
+		p = add_bucket (s, false);
+
+	      xprintf (" def-stmt=\"%s%u\"", tree_class_prfx (s), p->id);
+	    }
+	}
+      
+      /* version */
+      xprintf (" version=\"%u\"", SSA_NAME_VERSION (t));
+
+      /* in-abnormal-phi */
+      if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (t))
+	xprintf (" in-abnormal-phi=\"true\"");
+      
+      xprintf (" />\n");
+      break;
+    case STATEMENT_LIST:
+      gcc_assert (TREE_CODE (t) == STATEMENT_LIST);
+      xprintf (">\n");
+      cdi->indent++;
+      for (iter = tsi_start (t); !tsi_end_p (iter); tsi_next (&iter))
+	xml_dump_node (tsi_stmt (iter));
+      cdi->indent--;
+      xiprintf ("</%s>\n", code_name);
+      break;
+    case PHI_NODE:
+      xprintf (">\n");
+      cdi->indent++;
+
+      /* <result> */
+      xiprintf ("<phi-result>\n");
+      cdi->indent++;
+      xml_dump_node (PHI_RESULT (t));
+      cdi->indent--;
+      xiprintf ("</phi-result>\n");
+
+      /* <arguments> */
+      len = PHI_NUM_ARGS (t);
+      xiprintf ("<phi-args count=\"%d\">\n", len);
+      cdi->indent++;
+      for (i = 0; i < len; i++)
+	{
+	  xiprintf ("<phi-arg index=\"%d\" edge=\"%d\">\n", i,
+		    PHI_ARG_EDGE (t, i)->src->index);
+	  cdi->indent++;
+	  xml_dump_node (PHI_ARG_DEF (t, i));
+	  cdi->indent--;
+	  xiprintf ("</phi-arg>\n");
+	}
+      cdi->indent--;
+      xiprintf ("</phi-args>\n");
+
+      cdi->indent--;
+      xiprintf ("</%s>\n", code_name);
+      break;
+    case TREE_LIST:
+      xprintf (">\n");
+      cdi->indent++;
+      
+      s = t;
+      while (s)
+	{
+	  xml_dump_node (TREE_VALUE (s));
+	  s = TREE_CHAIN (s);
+	}
+
+      cdi->indent--;
+      xiprintf ("</%s>\n", code_name);
+      break;
+
+    case CONSTRUCTOR:
+      {
+        tree index, value;
+        unsigned int ix;
+        VEC(constructor_elt,gc) *v = CONSTRUCTOR_ELTS(t);
+
+        xprintf (">\n");
+        cdi->indent++;
+
+        FOR_EACH_CONSTRUCTOR_ELT (v, ix, index, value) {
+          if (TREE_CODE_CLASS (TREE_CODE (index)) == tcc_constant || 
+              TREE_CODE (index) == FIELD_DECL) {
+            xiprintf ("<index");
+            dump_ref_attr ("ref", index);
+            xprintf ("/>\n");
+          }
+          else {
+            gcc_assert (TREE_CODE (index) == RANGE_EXPR);
+            xiprintf ("<index>\n");
+            cdi->indent++;
+            xml_dump_node (index);
+            cdi->indent--;
+            xiprintf ("</index>\n");
+          }
+
+          if (TREE_CODE_CLASS (TREE_CODE (value)) == tcc_constant) {
+            xiprintf ("<value");
+            dump_ref_attr ("ref", value);
+            xprintf ("/>\n");
+          }
+          else {
+            xiprintf ("<value>\n");
+            cdi->indent++;
+            xml_dump_node (value);
+            cdi->indent--;
+            xiprintf ("</value>\n");
+          }
+        }
+
+        cdi->indent--;
+        xiprintf ("</%s>\n", code_name);
+        break;
+      }
+    case VALUE_HANDLE:
+    case TREE_BINFO:
+    case BLOCK:
+      xprintf (" todo=\"true\" />\n");
+      break;
+    default:
+      gcc_unreachable ();
+    }
+}
+
+static void
+dump_tcc_expression (tree t)
+{
+  const char *code_name;
+  expanded_location loc;
+  xml_node_bucket_p hte;
+  tree var;
+  char *p;
+  int i, len;
+
+  gcc_assert (t);
+
+  code_name = tree_code_name[(int) TREE_CODE (t)];
+
+  /* hash table bookkeeping */
+  if (!mark_bucket (t, &hte))
+    {
+      dump_reference(t);
+      return;
+    }
+
+  xiprintf ("<%s uid=\"%s%u\"", code_name, tree_class_prfx (t), hte->id);
+
+  /* unsigned */
+  if (TREE_CODE (t) == BIT_FIELD_REF && BIT_FIELD_REF_UNSIGNED (t))
+    xprintf (" unsigned=\"true\"");
+
+  if (EXPR_HAS_LOCATION (t))
+    {
+      /* location */
+      loc = expand_location (EXPR_LOCATION (t));
+      p = xml_escape (loc.file);
+      xprintf (" location=\"%s:%d\"", p, loc.line);
+      free (p);
+    }
+
+  if (TREE_CODE (t) == BIND_EXPR)
+    {
+      xprintf (">\n");
+      cdi->indent++;
+
+      /* <variables> */
+      xiprintf ("<declarations>\n");
+      cdi->indent++;
+      var = BIND_EXPR_VARS (t);
+      while (var)
+	{
+	  dump_tcc_declaration (var);
+	  var = TREE_CHAIN (var);
+	}
+      cdi->indent--;
+      xiprintf ("</declarations>\n");
+
+      /* <body> */
+      xiprintf ("<body>\n");
+      cdi->indent++;
+      xml_dump_node (BIND_EXPR_BODY (t));
+      cdi->indent--;
+      xiprintf ("</body>\n");
+    }
+  else
+    {
+      len = TREE_CODE_LENGTH (TREE_CODE (t));
+
+      /* #arguments */
+      xprintf (" arguments=\"%d\"", len);
+      
+      /* type */
+      if (TREE_TYPE (t) && TREE_TYPE (t) != void_type_node)
+	dump_type_attr (TREE_TYPE (t));
+
+      xprintf (">\n");
+      cdi->indent++;
+
+      for (i = 0; i < len; i++)
+	{
+	  if (!TREE_OPERAND (t, i))
+	    {
+	      xiprintf ("<null_expr />\n");
+	    }
+	  else
+	    {
+	      if (TREE_CODE (t) == LABEL_EXPR)
+		{
+		  gcc_assert (len == 1 && TREE_OPERAND (t, 0)
+			      && TREE_CODE (TREE_OPERAND (t, 0)) == LABEL_DECL);
+		  dump_tcc_declaration (TREE_OPERAND (t, 0));
+		}
+	      else if (TREE_CODE (t) == CASE_LABEL_EXPR && i == 2)
+		{
+		  gcc_assert (TREE_CODE (TREE_OPERAND (t, i)) == LABEL_DECL);
+		  dump_tcc_declaration (TREE_OPERAND (t, i));
+		}
+	      else if (TREE_CODE (t) == DECL_EXPR)
+		{
+		  gcc_assert (len == 1 && TREE_OPERAND (t, 0)
+			      && TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (t, 0))) == tcc_declaration);
+		  dump_tcc_declaration (TREE_OPERAND (t, 0));
+		}
+	      else
+		{
+		  xml_dump_node (TREE_OPERAND (t, i));
+		}
+	    }
+	}
+    }
+
+  cdi->indent--;
+  xiprintf ("</%s>\n", code_name);
+}
+
+static void
+dump_reference (tree t)
+{
+  xml_node_bucket_p p;
+  const char *code_name;
+
+  if (!t)
+    return;
+
+  if (t == error_mark_node)
+    {
+      xiprintf("<error_mark />\n");
+      return;
+    }
+
+  code_name = tree_code_name[(int) TREE_CODE (t)];
+  p = get_bucket (t);
+
+  if (!p)
+    {
+      /* create a preliminary id that must be used in the subsequent
+         dump of the node 
+       */
+      p = add_bucket (t, false);
+      gcc_assert (p);
+    }
+
+  xiprintf ("<%s ref=\"%s%u\" />\n", code_name, tree_class_prfx (t), p->id);
+}
+
+static void
+xml_dump_node (tree t)
+{
+  enum tree_code code;
+  enum tree_code_class class;
+
+  if (t != NULL_TREE)
+    {
+      code = TREE_CODE (t);
+      class = TREE_CODE_CLASS (code);
+
+      switch (class)
+	{
+	case tcc_type:
+	  dump_tcc_type (t);
+	  break;
+	case tcc_declaration:
+	  dump_reference (t);
+	  break;
+	case tcc_constant:
+	  dump_reference (t);
+	  break;
+	case tcc_exceptional:
+	  dump_tcc_exceptional (t);
+	  break;
+	case tcc_expression:
+	case tcc_unary:
+	case tcc_binary:
+	case tcc_reference:
+	case tcc_statement:
+	case tcc_comparison:
+	  dump_tcc_expression (t);
+	  break;
+	}
+    }
+}
+
+/* calls <dump_fun> for each node in the hash table of a particular class
+   which has not been dumped yet
+*/
+static void
+complete_dump_class (enum tree_code_class class, const char *tagname,
+	             void (*dump_fun) (tree))
+{
+  int i;
+  bool first, found;
+  xml_node_bucket_p p;
+
+  first = true;
+  found = false;
+  for (i = 0; i < HASH_SIZE; i++)
+    {
+      p = (cdi->hashtab)[i];
+      while (p)
+	{
+	  if (!p->complete && TREE_CODE_CLASS (TREE_CODE (p->node)) == class)
+	    {
+	      found = true;
+	      if (first)
+		{
+		  first = false;
+		  xiprintf ("<%s>\n", tagname);
+		  cdi->indent++;
+		}
+
+	      dump_fun (p->node);
+	      gcc_assert (p->complete);
+	    }
+	  p = p->next;
+	}
+    }
+
+  if (!first)
+    {
+      cdi->indent--;
+      xiprintf ("</%s>\n", tagname);
+    }
+}
+
+static void
+complete_dump_code (enum tree_code code, const char *tagname,
+	            void (*dump_fun) (tree))
+{
+  int i;
+  bool first, found;
+  xml_node_bucket_p p;
+
+  first = true;
+  found = false;
+  for (i = 0; i < HASH_SIZE; i++)
+    {
+      p = (cdi->hashtab)[i];
+      while (p)
+	{
+	  if (!p->complete && TREE_CODE (p->node) == code)
+	    {
+	      found = true;
+	      if (first && tagname)
+		{
+		  first = false;
+		  xiprintf ("<%s>\n", tagname);
+		  cdi->indent++;
+		}
+
+	      dump_fun (p->node);
+	      gcc_assert (p->complete);
+	    }
+	  p = p->next;
+	}
+    }
+
+  if (!first && tagname)
+    {
+      cdi->indent--;
+      xiprintf ("</%s>\n", tagname);
+    }
+}
+
+static void
+dump_basic_block (basic_block bb)
+{
+  block_stmt_iterator bsi;
+  edge_iterator ei;
+  tree stmt, phi;
+  edge e;
+
+  /* <basic_block> */
+  xiprintf ("<basic_block");
+
+  /* index */
+  xprintf (" index=\"%d\"", bb->index);
+
+  /* entry-block */
+  if (bb == ENTRY_BLOCK_PTR)
+    xprintf (" entry-block=\"true\"");
+
+  /* exit-block */
+  if (bb == EXIT_BLOCK_PTR)
+    xprintf (" e2xit-block=\"true\"");
+  
+  /* frequency */
+  if (bb->frequency)
+    xprintf (" frequency=\"%d\"", bb->frequency);
+
+  /* count */
+  if (bb->count)
+    xprintf (" count=\"" HOST_WIDEST_INT_PRINT_DEC "\"", bb->count);
+
+  /* loop-depth */
+  if (bb->loop_depth)
+    xprintf (" loop-depth=\"%d\"", bb->loop_depth);
+
+  xprintf (">\n");
+  cdi->indent++;
+
+  /* <predecessors> */
+  if (EDGE_COUNT (bb->preds))
+    {
+      xiprintf ("<edges>\n");
+      cdi->indent++;
+      FOR_EACH_EDGE (e, ei, bb->preds) dump_cfg_edge (e);
+      FOR_EACH_EDGE (e, ei, bb->succs) dump_cfg_edge (e);
+      cdi->indent--;
+      xiprintf ("</edges>\n");
+    }
+
+  /* <phi-nodes> */
+  phi = phi_nodes (bb);
+  if (phi)
+    {
+      xiprintf ("<phi-nodes>\n");
+      cdi->indent++;
+      for (; phi; phi = PHI_CHAIN (phi))
+	xml_dump_node (phi);
+      cdi->indent--;
+      xiprintf ("</phi-nodes>\n");
+    }
+
+  /* <body> */
+  xiprintf ("<body>\n");
+  cdi->indent++;
+  for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+    {
+      stmt = bsi_stmt (bsi);
+      xml_dump_node (stmt);
+    }
+  cdi->indent--;
+  xiprintf ("</body>\n");
+
+  cdi->indent--;
+  xiprintf ("</basic_block>\n");
+}
+
+/* registers the dump if not yet done and prints the 
+   given function declaration */
+void
+xml_dump_function (tree t, enum tree_dump_index phase)
+{
+  int i;
+
+  if (!t || TREE_CODE (t) != FUNCTION_DECL)
+    return;
+
+  /* check, if there is some space left and realloc otherwise */
+  if (!phases || num_phases >= phases_size)
+    {
+      if (phases_size == 0)
+	phases_size = 32;
+      else
+	phases_size *= 2;
+
+/*       phases = xrealloc (phases, phases_size * sizeof (xml_dump_info_p)); */
+      phases = ggc_realloc (phases, phases_size * sizeof (xml_dump_info_p));
+      gcc_assert (phases);
+
+      /* initialize newly created slots to NULL */
+      for (i = num_phases; i < phases_size; i++)
+	phases[i] = NULL;
+    }
+
+  /* check, if the dump is already registered */
+  cdi = NULL;
+  for (i = 0; !cdi && i < num_phases; i++)
+    if (phases[i] && (phases[i])->phase == phase)
+      cdi = phases[i];
+
+  /* register the phase, if not yet done */
+  if (!cdi)
+    {
+      cdi = xml_dump_register (phase);
+      gcc_assert (cdi);
+      phases[num_phases++] = cdi;
+      
+      /* dump the XML header */
+      xml_dump_header ();
+    }
+  
+  /* dump the function declaration */
+  dump_tcc_declaration (t);
+
+  /* do some early cleanup to reduce memory usage */
+  xml_dump_local_cleanup ();
+
+  cdi=NULL;
+}
+
+static bool
+xml_dump_gate (void)
+{
+  return xml_dump;
+}
+
+void xml_dump_add_variable (tree decl)
+{
+  /* dump only declarations of the translation unit */
+  if (xml_dump_gate () && DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == TRANSLATION_UNIT_DECL) 
+    {
+      if (!xml_globals)
+        xml_globals = VEC_alloc (tree, gc, 50);
+      VEC_safe_push (tree, gc, xml_globals, decl);
+    }
+}
+
+
+static void
+execute_dump_xml (void)
+{
+  xml_dump_function(current_function_decl, pass_dump_xml.static_pass_number);
+}
+
+struct tree_opt_pass pass_irdump =
+{
+  NULL,					/* name */
+  &xml_dump_gate,                       /* gate */
+  NULL,					/* execute */
+  NULL,					/* sub */
+  NULL,					/* next */
+  0,					/* static_pass_number */
+  0,					/* tv_id */
+  0,					/* properties_required */
+  0,					/* properties_provided */
+  0,					/* properties_destroyed */
+  0,					/* todo_flags_start */
+  0,					/* todo_flags_finish */
+  0					/* letter */
+};
+
+struct tree_opt_pass pass_dump_xml = 
+{
+  "dump_xml",				/* name */
+  NULL,          			/* gate */
+  execute_dump_xml,			/* execute */
+  NULL,					/* sub */
+  NULL,					/* next */
+  0,					/* static_pass_number */
+  0,	         			/* tv_id */
+  PROP_cfg,                       	/* properties_required */
+  0,					/* properties_provided */
+  0,					/* properties_destroyed */
+  TODO_verify_ssa,    			/* todo_flags_start */
+  0,	                                /* todo_flags_finish */
+  0					/* letter */
+};
+
+#include "gt-xml-dump.h"
+
+#undef SUBTAGS_INIT
diff -Naur ./gcc/xml-dump.h ../gcc-4.1.0.patched/gcc/xml-dump.h
--- ./gcc/xml-dump.h	1970-01-01 01:00:00.000000000 +0100
+++ ../gcc-4.1.0.patched/gcc/xml-dump.h	2006-05-29 13:34:44.000000000 +0200
@@ -0,0 +1,31 @@
+/* dumping functionality for trees in XML format.
+   Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
+   Written by Dietmar Ebner <ebner@complang.tuwien.ac.at>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
+
+#ifndef GCC_XML_DUMP_H
+#define GCC_XML_DUMP_H
+
+#include "tree-pass.h"
+
+void xml_dump_add_variable (tree decl);
+void xml_dump_cleanup(void);
+void xml_dump_function (tree, enum tree_dump_index);
+
+#endif /* ! GCC_XML_DUMP_H */
