This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][varmap] Add dumps for the variable mappings
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 13 Nov 2007 12:17:42 +0100 (CET)
- Subject: [PATCH][varmap] Add dumps for the variable mappings
This patch adds a new dump flag (-vars) which annotates statements
with the variables referenced.
Applied to var-mappings-branch.
Richard.
2007-11-07 Richard Guenther <rguenther@suse.de>
* tree.h (print_ssa_varmap): Declare.
* tree-ssanames.c (print_ssa_varmap): New function.
* Makefile.in (tree-ssanames.o): Add $(DIAGNOSTIC_H) dependency.
* tree-dump.c (struct dump_option_value_in): Add vars modifier.
* tree-pass.h (TDF_VARS): Define.
* tree-pretty-print.c (print_varmap): New helper function.
(print_expr_varmap): Likewise.
(dump_generic_node): Call it on defs and return expressions.
* passes.c (execute_function_todo): Print variable mapping
info if requested.
* print-rtl.c (print_rtx): Print variable bitmap for SETs if
available.
* gcc.dg/tree-ssa/vars-1.c: New testcase.
Index: var-mappings-branch/gcc/tree-ssanames.c
===================================================================
*** var-mappings-branch.orig/gcc/tree-ssanames.c 2007-11-12 18:33:12.000000000 +0100
--- var-mappings-branch/gcc/tree-ssanames.c 2007-11-12 18:33:46.000000000 +0100
*************** along with GCC; see the file COPYING3.
*** 26,31 ****
--- 26,32 ----
#include "ggc.h"
#include "tree-flow.h"
#include "tree-pass.h"
+ #include "diagnostic.h"
/* Rewriting a function into SSA form can create a huge number of SSA_NAMEs,
many of which may be thrown away shortly after their creation if jumps
*************** ssa_varmap_process_copy_1 (tree lhs, tre
*** 405,410 ****
--- 406,420 ----
{
bitmap lhs_vars, rhs_vars;
+ if (dump_file && dump_flags & TDF_VARS)
+ {
+ fprintf (dump_file, "Processing copy relation ");
+ print_generic_expr (dump_file, lhs, 0);
+ fprintf (dump_file, " = ");
+ print_generic_expr (dump_file, rhs, 0);
+ fprintf (dump_file, "\n");
+ }
+
/* We cannot blindly exchange an artificial vars ssa_name variable
with another as this may create overlapping life-ranges. So we
also cannot assume that artificial vars do not have a variable map. */
*************** ssa_varmap_add_var (tree name, tree var)
*** 469,474 ****
--- 479,493 ----
{
bitmap lhs_vars;
+ if (dump_file && dump_flags & TDF_VARS)
+ {
+ fprintf (dump_file, "Adding variable ");
+ print_generic_expr (dump_file, var, 0);
+ fprintf (dump_file, " to SSA_NAME ");
+ print_generic_expr (dump_file, name, 0);
+ fprintf (dump_file, " map\n");
+ }
+
if (DECL_ARTIFICIAL (var))
return;
*************** ssa_varmap_process_phi (tree stmt)
*** 505,510 ****
--- 524,536 ----
if (MTAG_P (SSA_NAME_VAR (PHI_RESULT (stmt))))
return;
+ if (dump_file && dump_flags & TDF_VARS)
+ {
+ fprintf (dump_file, "Processing merge relation ");
+ print_generic_expr (dump_file, stmt, 0);
+ fprintf (dump_file, "\n");
+ }
+
/* A PHI nodes result represents the intersection of all decls of
the PHI arguments. */
tmp = BITMAP_GGC_ALLOC ();
*************** ssa_varmap_build_exprmap (tree *values)
*** 629,634 ****
--- 655,706 ----
}
}
+ /* Print variable maps to FILE. */
+
+ void
+ print_ssa_varmap (FILE *file)
+ {
+ int live_ssa_names = 0, with_map = 0, max_vars = 0, total_vars = 0;
+ unsigned int i;
+
+ fprintf (file, "\nSSA variable maps:\n");
+ for (i = 0; i < num_ssa_names; ++i)
+ {
+ tree name = ssa_name (i);
+ int n = 0;
+ bitmap_iterator bi;
+ unsigned int i;
+ bitmap vars;
+ if (!name)
+ continue;
+ live_ssa_names++;
+ vars = ssa_varmap_lookup (name);
+ if (!vars)
+ continue;
+ with_map++;
+ fprintf (file, " ");
+ print_generic_expr (file, name, 0);
+ fprintf (file, ": ");
+ EXECUTE_IF_SET_IN_BITMAP (vars, 0, i, bi)
+ {
+ tree var = ssa_varmap_get_ref (i);
+ n++;
+ if (var)
+ print_generic_expr (file, var, 0);
+ else
+ fprintf (file, "%u", i);
+ fprintf (file, " ");
+ }
+ total_vars += n;
+ if (n > max_vars)
+ max_vars = n;
+ fprintf (file, "\n");
+ }
+ fprintf (file, "%d SSA_NAMEs, %d with variable map\n"
+ "with average %.3f variables (%d max)\n\n", live_ssa_names,
+ with_map, with_map > 0 ? total_vars / (float)with_map : 0, max_vars);
+ }
+
/* Return SSA names that are unused to GGC memory. This is used to keep
footprint of compiler during interprocedural optimization.
As a side effect the SSA_NAME_VERSION number reuse is reduced
Index: var-mappings-branch/gcc/tree-dump.c
===================================================================
*** var-mappings-branch.orig/gcc/tree-dump.c 2007-11-12 18:31:56.000000000 +0100
--- var-mappings-branch/gcc/tree-dump.c 2007-11-12 18:33:46.000000000 +0100
*************** static const struct dump_option_value_in
*** 825,830 ****
--- 825,831 ----
{"uid", TDF_UID},
{"stmtaddr", TDF_STMTADDR},
{"memsyms", TDF_MEMSYMS},
+ {"vars", TDF_VARS},
{"all", ~(TDF_RAW | TDF_SLIM | TDF_LINENO | TDF_TREE | TDF_RTL | TDF_IPA
| TDF_STMTADDR | TDF_GRAPH | TDF_DIAGNOSTIC)},
{NULL, 0}
Index: var-mappings-branch/gcc/tree-pass.h
===================================================================
*** var-mappings-branch.orig/gcc/tree-pass.h 2007-11-12 18:31:56.000000000 +0100
--- var-mappings-branch/gcc/tree-pass.h 2007-11-12 18:33:46.000000000 +0100
*************** enum tree_dump_index
*** 73,78 ****
--- 73,80 ----
#define TDF_DIAGNOSTIC (1 << 15) /* A dump to be put in a diagnostic
message. */
+ #define TDF_VARS (1 << 16) /* Dump variable mappings. */
+
extern char *get_dump_file_name (enum tree_dump_index);
extern int dump_enabled_p (enum tree_dump_index);
extern int dump_initialized_p (enum tree_dump_index);
Index: var-mappings-branch/gcc/tree-pretty-print.c
===================================================================
*** var-mappings-branch.orig/gcc/tree-pretty-print.c 2007-11-12 18:31:56.000000000 +0100
--- var-mappings-branch/gcc/tree-pretty-print.c 2007-11-12 18:33:46.000000000 +0100
*************** dump_symbols (pretty_printer *buffer, bi
*** 435,440 ****
--- 435,509 ----
}
+ static void
+ print_varmap (pretty_printer *buffer, tree name, int spc, int flags)
+ {
+ bitmap vars;
+ bitmap_iterator bi;
+ unsigned int i;
+
+ if (DECL_ARTIFICIAL (SSA_NAME_VAR (name)))
+ return;
+
+ vars = ssa_varmap_lookup (name);
+ if (!vars)
+ return;
+
+ pp_string (buffer, "\t{ ");
+ EXECUTE_IF_SET_IN_BITMAP (vars, 0, i, bi)
+ {
+ tree var = ssa_varmap_get_ref (i);
+ if (var)
+ dump_generic_node (buffer, var, spc, flags, false);
+ else
+ pp_string (buffer, "[optimized out]");
+ pp_space (buffer);
+ }
+ pp_character (buffer, '}');
+ }
+
+ static void
+ print_expr_varmap (pretty_printer *buffer, tree expr, int spc, int flags)
+ {
+ bitmap vars;
+ bitmap_iterator bi;
+ unsigned int i;
+ bool rhs = false;
+
+ if (TREE_CODE (expr) != GIMPLE_MODIFY_STMT
+ && !EXPR_P (expr))
+ return;
+
+ vars = ssa_varmap_exprmap_lookup (expr);
+ if (!vars)
+ {
+ if (TREE_CODE (expr) == GIMPLE_MODIFY_STMT)
+ {
+ vars = ssa_varmap_exprmap_lookup (GIMPLE_STMT_OPERAND (expr, 1));
+ if (!vars)
+ return;
+ rhs = true;
+ }
+ else
+ return;
+ }
+
+ if (!rhs)
+ pp_string (buffer, " E{ ");
+ else
+ pp_string (buffer, " R{ ");
+ EXECUTE_IF_SET_IN_BITMAP (vars, 0, i, bi)
+ {
+ tree var = ssa_varmap_get_ref (i);
+ if (var)
+ dump_generic_node (buffer, var, spc, flags, false);
+ else
+ pp_string (buffer, "[optimized out]");
+ pp_space (buffer);
+ }
+ pp_character (buffer, '}');
+ }
+
/* Dump the node NODE on the pretty_printer BUFFER, SPC spaces of indent.
FLAGS specifies details to show in the dump (see TDF_* in tree-pass.h).
If IS_STMT is true, the object printed is considered to be a statement
*************** dump_generic_node (pretty_printer *buffe
*** 1099,1104 ****
--- 1168,1177 ----
pp_space (buffer);
dump_generic_node (buffer, GENERIC_TREE_OPERAND (node, 1), spc, flags,
false);
+ if (flags & TDF_VARS
+ && TREE_CODE (node) == GIMPLE_MODIFY_STMT
+ && TREE_CODE (GIMPLE_STMT_OPERAND (node, 0)) == SSA_NAME)
+ print_varmap (buffer, GIMPLE_STMT_OPERAND (node, 0), spc, flags);
break;
case TARGET_EXPR:
*************** dump_generic_node (pretty_printer *buffe
*** 1594,1603 ****
pp_space (buffer);
if (TREE_CODE (op0) == MODIFY_EXPR
|| TREE_CODE (op0) == GIMPLE_MODIFY_STMT)
! dump_generic_node (buffer, GENERIC_TREE_OPERAND (op0, 1),
! spc, flags, false);
! else
! dump_generic_node (buffer, op0, spc, flags, false);
}
break;
--- 1667,1677 ----
pp_space (buffer);
if (TREE_CODE (op0) == MODIFY_EXPR
|| TREE_CODE (op0) == GIMPLE_MODIFY_STMT)
! op0 = GENERIC_TREE_OPERAND (op0, 1);
! dump_generic_node (buffer, op0, spc, flags, false);
! if (flags & TDF_VARS
! && TREE_CODE (op0) == SSA_NAME)
! print_varmap (buffer, op0, spc, flags);
}
break;
*************** dump_generic_node (pretty_printer *buffe
*** 2160,2165 ****
--- 2234,2242 ----
NIY;
}
+ if (flags & TDF_VARS && is_expr)
+ print_expr_varmap (buffer, node, spc, flags);
+
if (is_stmt && is_expr)
pp_semicolon (buffer);
Index: var-mappings-branch/gcc/tree.h
===================================================================
*** var-mappings-branch.orig/gcc/tree.h 2007-11-12 18:33:12.000000000 +0100
--- var-mappings-branch/gcc/tree.h 2007-11-12 18:33:46.000000000 +0100
*************** void ssa_varmap_add_ref (tree);
*** 3914,3919 ****
--- 3914,3922 ----
extern bitmap ssa_varmap_exprmap_lookup (tree);
extern void ssa_varmap_exprmap_insert (tree, bitmap);
extern void ssa_varmap_build_exprmap (tree *);
+ #ifdef BUFSIZ
+ extern void print_ssa_varmap (FILE *);
+ #endif
#ifdef GATHER_STATISTICS
extern void ssanames_print_statistics (void);
Index: var-mappings-branch/gcc/passes.c
===================================================================
*** var-mappings-branch.orig/gcc/passes.c 2007-11-12 18:31:56.000000000 +0100
--- var-mappings-branch/gcc/passes.c 2007-11-12 18:33:46.000000000 +0100
*************** execute_function_todo (void *data)
*** 902,907 ****
--- 902,911 ----
unsigned update_flags = flags & TODO_update_ssa_any;
update_ssa (update_flags);
cfun->last_verified &= ~TODO_verify_ssa;
+
+ if (dump_flags & TDF_VARS
+ && dump_file)
+ print_ssa_varmap (dump_file);
}
if (flags & TODO_rebuild_alias)
Index: var-mappings-branch/gcc/Makefile.in
===================================================================
*** var-mappings-branch.orig/gcc/Makefile.in 2007-11-12 18:31:56.000000000 +0100
--- var-mappings-branch/gcc/Makefile.in 2007-11-12 18:33:46.000000000 +0100
*************** tree-ssa-threadupdate.o : tree-ssa-threa
*** 2051,2057 ****
$(DIAGNOSTIC_H) $(FUNCTION_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
$(BASIC_BLOCK_H) $(FLAGS_H) tree-pass.h $(CFGLOOP_H)
tree-ssanames.o : tree-ssanames.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
! $(TM_H) $(TREE_H) $(VARRAY_H) $(GGC_H) $(TREE_FLOW_H)
tree-phinodes.o : tree-phinodes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(TREE_H) $(VARRAY_H) $(GGC_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) \
gt-tree-phinodes.h $(RTL_H) toplev.h
--- 2051,2058 ----
$(DIAGNOSTIC_H) $(FUNCTION_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
$(BASIC_BLOCK_H) $(FLAGS_H) tree-pass.h $(CFGLOOP_H)
tree-ssanames.o : tree-ssanames.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
! $(TM_H) $(TREE_H) $(VARRAY_H) $(GGC_H) $(TREE_FLOW_H) \
! $(DIAGNOSTIC_H)
tree-phinodes.o : tree-phinodes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(TREE_H) $(VARRAY_H) $(GGC_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) \
gt-tree-phinodes.h $(RTL_H) toplev.h
Index: var-mappings-branch/gcc/tree-outof-ssa.c
===================================================================
*** var-mappings-branch.orig/gcc/tree-outof-ssa.c 2007-11-12 18:33:24.000000000 +0100
--- var-mappings-branch/gcc/tree-outof-ssa.c 2007-11-12 18:34:14.000000000 +0100
*************** insert_backedge_copies (void)
*** 1306,1311 ****
--- 1306,1314 ----
static unsigned int
rewrite_out_of_ssa (void)
{
+ if (dump_file && dump_flags & TDF_VARS)
+ print_ssa_varmap (dump_file);
+
/* And allocate the temporary expression to debug variables mapping. */
cfun->varmap_exprmap = htab_create_ggc (7, tree_bitmap_map_hash,
tree_bitmap_map_eq, NULL);
Index: var-mappings-branch/gcc/print-rtl.c
===================================================================
*** var-mappings-branch.orig/gcc/print-rtl.c 2007-11-12 18:31:56.000000000 +0100
--- var-mappings-branch/gcc/print-rtl.c 2007-11-12 18:33:46.000000000 +0100
*************** along with GCC; see the file COPYING3.
*** 40,45 ****
--- 40,47 ----
#include "flags.h"
#include "hard-reg-set.h"
#include "basic-block.h"
+ #include "tree-flow.h"
+ #include "diagnostic.h"
#endif
static FILE *outfile;
*************** print_rtx (const_rtx in_rtx)
*** 505,511 ****
case 'b':
#ifndef GENERATOR_FILE
! if (XBITMAP (in_rtx, i) == NULL)
fputs (" {null}", outfile);
else
bitmap_print (outfile, XBITMAP (in_rtx, i), " {", "}");
--- 507,539 ----
case 'b':
#ifndef GENERATOR_FILE
! if (GET_CODE (in_rtx) == SET
! && XBITMAP (in_rtx, 2) != NULL)
! {
! bitmap_iterator bi;
! unsigned int i;
! bool first = true;
!
! fputs (" { ", outfile);
! EXECUTE_IF_SET_IN_BITMAP (XBITMAP (in_rtx, 2), 0, i, bi)
! {
! /* ??? We don't keep referenced vars after RTL expansion,
! so we might want to add all to our internal map. */
! tree var = ssa_varmap_get_ref (i);
! if (!first)
! fputs (", ", outfile);
! first = false;
! if (var)
! print_generic_expr (outfile, var, 0);
! else
! /* Optimized out. */
! fprintf (outfile, "D.%u", i);
! }
! fputs (" }", outfile);
! }
! else if (GET_CODE (in_rtx) == SET)
! /* Do not print {null} for non-existant SET var bitmaps. */ ;
! else if (XBITMAP (in_rtx, i) == NULL)
fputs (" {null}", outfile);
else
bitmap_print (outfile, XBITMAP (in_rtx, i), " {", "}");
Index: gcc/testsuite/gcc.dg/tree-ssa/vars-1.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/vars-1.c (revision 0)
+++ gcc/testsuite/gcc.dg/tree-ssa/vars-1.c (revision 0)
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-final_cleanup-vars" } */
+
+/* In this test we want to keep the name "j" associated with
+ the expression "i * k" passed to the inlined function "bar". */
+
+static int bar(int j)
+{
+ return j;
+}
+int l;
+int foo(int i, int k)
+{
+ l = bar(i*k);
+ return l;
+}
+
+/* { dg-final { scan-tree-dump "k \\\* i E{ j }" "final_cleanup" } } */
+/* { dg-final { cleanup-tree-dump "final_cleanup" } } */