Commit 33c94679 by Diego Novillo Committed by Diego Novillo

Makefile.in (tree-vn.o): New.


	* Makefile.in (tree-vn.o): New.
	(tree-ssa-pre.o): Don't depend on RTL_H.
	* tree-dfa.c (find_referenced_vars): Don't call init_tree_ssa.
	* tree-flow.h (struct var_ann_d): Remove field expr_set.
	(add_to_value, expressions_equal_p, get_value_handle, vn_compute,
	vn_lookup_or_add, vn_add, vn_lookup, vn_init, vn_delete): Declare.
	* tree-optimize.c (execute_init_datastructures): New local function.
	(pass_init_datastructures): New local variable.
	(init_tree_optimization_passes): Sequence pass_init_datastructures.
	* tree-pretty-print.c (MASK_POINTER): Remove.
	(dump_generic_node): Handle VALUE_HANDLE.
	* tree-ssa-pre.c: Move all value numbering routines to tree-vn.c.
	Update callers to use new function names.
	Use VALUE_HANDLE_ID and VALUE_HANDLE_EXPR_SET instead of
	variable annotations.
	* tree-ssa.c (init_tree_ssa): Call vn_init.
	(delete_tree_ssa): Call vn_delete.
	* tree-vn.c: New file.
	* tree.c (tree_size): Handle VALUE_HANDLE.
	(tree_node_structure): Likewise.
	(iterative_hash_expr): Likewise.
	* tree.def (VALUE_HANDLE): New code.
	* tree.h (struct tree_value_handle): New.
	(VALUE_HANDLE_ID): Define.
	(VALUE_HANDLE_EXPR_SET): Define.
	(enum tree_node_structure_enum): Add TS_VALUE_HANDLE.
	(union tree_node): Add struct tree_value_handle.

From-SVN: r83564
parent 881f20cb
2004-06-23 Diego Novillo <dnovillo@redhat.com>
* Makefile.in (tree-vn.o): New.
(tree-ssa-pre.o): Don't depend on RTL_H.
* tree-dfa.c (find_referenced_vars): Don't call init_tree_ssa.
* tree-flow.h (struct var_ann_d): Remove field expr_set.
(add_to_value, expressions_equal_p, get_value_handle, vn_compute,
vn_lookup_or_add, vn_add, vn_lookup, vn_init, vn_delete): Declare.
* tree-optimize.c (execute_init_datastructures): New local function.
(pass_init_datastructures): New local variable.
(init_tree_optimization_passes): Sequence pass_init_datastructures.
* tree-pretty-print.c (MASK_POINTER): Remove.
(dump_generic_node): Handle VALUE_HANDLE.
* tree-ssa-pre.c: Move all value numbering routines to tree-vn.c.
Update callers to use new function names.
Use VALUE_HANDLE_ID and VALUE_HANDLE_EXPR_SET instead of
variable annotations.
* tree-ssa.c (init_tree_ssa): Call vn_init.
(delete_tree_ssa): Call vn_delete.
* tree-vn.c: New file.
* tree.c (tree_size): Handle VALUE_HANDLE.
(tree_node_structure): Likewise.
(iterative_hash_expr): Likewise.
* tree.def (VALUE_HANDLE): New code.
* tree.h (struct tree_value_handle): New.
(VALUE_HANDLE_ID): Define.
(VALUE_HANDLE_EXPR_SET): Define.
(enum tree_node_structure_enum): Add TS_VALUE_HANDLE.
(union tree_node): Add struct tree_value_handle.
2004-06-23 Andrew Pinski <apinski@apple.com>
* c-typeck.c (composite_type):
......
......@@ -887,7 +887,7 @@ C_OBJS = c-parse.o c-lang.o stub-objc.o $(C_AND_OBJC_OBJS)
OBJS-common = \
tree-cfg.o tree-dfa.o tree-eh.o tree-ssa.o tree-optimize.o tree-gimple.o \
tree-alias-type.o gimplify.o tree-pretty-print.o tree-into-ssa.o \
tree-outof-ssa.o tree-alias-common.o tree-ssa-ccp.o \
tree-outof-ssa.o tree-alias-common.o tree-ssa-ccp.o tree-vn.o \
@ANDER@ tree-ssa-dce.o tree-ssa-copy.o tree-nrv.o tree-ssa-copyrename.o \
tree-ssa-pre.o tree-ssa-live.o tree-ssa-operands.o tree-ssa-alias.o \
tree-ssa-phiopt.o tree-ssa-forwprop.o tree-nested.o tree-ssa-dse.o \
......@@ -1640,9 +1640,12 @@ tree-ssa-copyrename.o : tree-ssa-copyrename.c $(TREE_FLOW_H) $(CONFIG_H) \
diagnostic.h errors.h toplev.h function.h $(TIMEVAR_H) tree-pass.h \
tree-alias-common.h $(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_SSA_LIVE_H)
tree-ssa-pre.o : tree-ssa-pre.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) \
$(SYSTEM_H) $(TREE_H) $(TM_P_H) $(EXPR_H) \
$(GGC_H) output.h diagnostic.h errors.h toplev.h $(TIMEVAR_H) \
$(TM_H) coretypes.h $(TREE_DUMP_H) tree-pass.h $(FLAGS_H)
tree-vn.o : tree-vn.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(GGC_H) \
$(TREE_H) $(TREE_FLOW_H) $(HASHTAB_H) langhooks.h tree-pass.h \
$(TREE_DUMP_H) diagnostic.h
tree-cfg.o : tree-cfg.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) $(FLAGS_H) output.h \
diagnostic.h errors.h function.h $(TIMEVAR_H) $(TM_H) coretypes.h \
......@@ -3068,6 +3071,7 @@ distclean: clean lang.distclean
-rm -f fixinc/Makefile
# Delete po/*.gmo only if we are not building in the source directory.
-if [ ! -f po/exgettext ]; then rm -f po/*.gmo; fi
-rmdir ada cp f java objc fixinc intl po testsuite 2>/dev/null
# Get rid of every file that's generated from some other file, except for `configure'.
# Most of these files ARE PRESENT in the GCC distribution.
......
......@@ -111,10 +111,6 @@ find_referenced_vars (void)
struct walk_state walk_state;
tree block;
/* This is the very first pass in preparation for building the SSA
form of the function, so initialize internal data structures now. */
init_tree_ssa ();
/* Walk the lexical blocks in the function looking for variables that may
have been used to declare VLAs and for nested functions. Both
constructs create hidden uses of variables.
......
......@@ -167,11 +167,6 @@ struct var_ann_d GTY(())
live at the same time and this can happen for each call to the
dominator optimizer. */
tree current_def;
/* The set of expressions represented by this variable if it is a
value handle. This is used by GVN-PRE. */
PTR GTY ((skip)) expr_set;
};
......@@ -576,12 +571,23 @@ extern bool tree_can_throw_internal (tree);
extern bool tree_can_throw_external (tree);
extern void add_stmt_to_eh_region (tree, int);
/* In tree-ssa-pre.c */
tree get_value_handle (tree);
void set_value_handle (tree, tree);
/* In tree-ssa-pre.c */
void add_to_value (tree, tree);
void debug_value_expressions (tree);
void print_value_expressions (FILE *, tree);
/* In tree-vn.c */
bool expressions_equal_p (tree e1, tree e2);
tree get_value_handle (tree);
hashval_t vn_compute (tree, hashval_t);
tree vn_lookup_or_add (tree);
void vn_add (tree, tree);
tree vn_lookup (tree);
void vn_init (void);
void vn_delete (void);
/* In tree-sra.c */
void insert_edge_copies (tree stmt, basic_block bb);
......
......@@ -153,6 +153,33 @@ static struct tree_opt_pass pass_free_datastructures =
0 /* todo_flags_finish */
};
/* Do the actions required to initialize internal data structures used
in tree-ssa optimization passes. */
static void
execute_init_datastructures (void)
{
/* Allocate hash tables, arrays and other structures. */
init_tree_ssa ();
}
static struct tree_opt_pass pass_init_datastructures =
{
NULL, /* name */
NULL, /* gate */
execute_init_datastructures, /* execute */
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */
0, /* tv_id */
PROP_cfg, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
0 /* todo_flags_finish */
};
/* Iterate over the pass tree allocating dump file numbers. We want
to do this depth first, and independent of whether the pass is
enabled or not. */
......@@ -253,6 +280,7 @@ init_tree_optimization_passes (void)
NEXT_PASS (pass_lower_eh);
NEXT_PASS (pass_build_cfg);
NEXT_PASS (pass_tree_profile);
NEXT_PASS (pass_init_datastructures);
NEXT_PASS (pass_all_optimizations);
NEXT_PASS (pass_mudflap_2);
NEXT_PASS (pass_free_datastructures);
......
......@@ -55,8 +55,6 @@ static void dump_generic_bb_buff (pretty_printer *, basic_block, int, int);
lang_hooks.decl_printable_name (TREE_OPERAND (NODE, 0), 1) : \
lang_hooks.decl_printable_name (NODE, 1))
#define MASK_POINTER(P) ((unsigned)((unsigned long)(P) & 0xffff))
static pretty_printer buffer;
static int initialized = 0;
static bool dumping_stmts;
......@@ -1403,6 +1401,10 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
pp_decimal_int (buffer, SSA_NAME_VERSION (node));
break;
case VALUE_HANDLE:
pp_printf (buffer, "VH.%d", VALUE_HANDLE_ID (node));
break;
default:
NIY;
}
......
......@@ -497,6 +497,7 @@ init_tree_ssa (void)
init_ssa_operands ();
init_ssanames ();
init_phinodes ();
vn_init ();
global_var = NULL_TREE;
aliases_computed_p = false;
}
......@@ -527,6 +528,7 @@ delete_tree_ssa (void)
fini_ssanames ();
fini_phinodes ();
fini_ssa_operands ();
vn_delete ();
global_var = NULL_TREE;
BITMAP_XFREE (call_clobbered_vars);
......
/* Value Numbering routines for tree expressions.
Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Daniel Berlin <dan@dberlin.org>, Steven Bosscher
<stevenb@suse.de> and Diego Novillo <dnovillo@redhat.com>
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, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "ggc.h"
#include "tree.h"
#include "tree-flow.h"
#include "hashtab.h"
#include "langhooks.h"
#include "tree-pass.h"
#include "tree-dump.h"
#include "diagnostic.h"
/* The value table that maps expressions to values. */
static htab_t value_table;
/* Map expressions to values. These are simple pairs of expressions
and the values they represent. To find the value represented by
an expression, we use a hash table where the elements are {e,v}
pairs, and the expression is the key. */
typedef struct val_expr_pair_d
{
tree v, e;
hashval_t hashcode;
} *val_expr_pair_t;
static void set_value_handle (tree e, tree v);
/* Create and return a new value handle node of type TYPE. */
static tree
make_value_handle (tree type)
{
static unsigned int id = 0;
tree vh;
vh = build0 (VALUE_HANDLE, type);
VALUE_HANDLE_ID (vh) = id++;
return vh;
}
/* Given an expression or statement P, compute a hash value number using the
code of the expression and its real operands. */
hashval_t
vn_compute (tree expr, hashval_t val)
{
val = iterative_hash_expr (expr, val);
return val;
}
/* Compare two expressions E1 and E2 and return true if they are
equal. */
bool
expressions_equal_p (tree e1, tree e2)
{
tree te1, te2;
if (e1 == e2)
return true;
te1 = TREE_TYPE (e1);
te2 = TREE_TYPE (e2);
if (TREE_CODE (e1) == TREE_CODE (e2)
&& (te1 == te2 || lang_hooks.types_compatible_p (te1, te2))
&& operand_equal_p (e1, e2, 0))
return true;
return false;
}
/* Hash a {v,e} pair that is pointed to by P.
The hashcode is cached in the val_expr_pair, so we just return
that. */
static hashval_t
val_expr_pair_hash (const void *p)
{
const val_expr_pair_t ve = (val_expr_pair_t) p;
return ve->hashcode;
}
/* Given two val_expr_pair_t's, return true if they represent the same
expression, false otherwise.
P1 and P2 should point to the val_expr_pair_t's to be compared. */
static int
val_expr_pair_expr_eq (const void *p1, const void *p2)
{
const val_expr_pair_t ve1 = (val_expr_pair_t) p1;
const val_expr_pair_t ve2 = (val_expr_pair_t) p2;
if (expressions_equal_p (ve1->e, ve2->e))
return true;
return false;
}
/* Set the value handle for expression E to value V */
static void
set_value_handle (tree e, tree v)
{
if (TREE_CODE (e) == SSA_NAME)
SSA_NAME_VALUE (e) = v;
else if (EXPR_P (e) || DECL_P (e))
get_tree_ann (e)->common.value_handle = v;
else if (TREE_CODE_CLASS (TREE_CODE (e)) == 'c')
/* Do nothing. Constants are their own value handles. */
;
else
abort ();
}
/* Insert E into VALUE_TABLE with value V, and add expression E to the
value set for value V. */
void
vn_add (tree e, tree v)
{
void **slot;
val_expr_pair_t new_pair = xmalloc (sizeof (struct val_expr_pair_d));
new_pair->e = e;
new_pair->v = v;
new_pair->hashcode = vn_compute (e, 0);
slot = htab_find_slot_with_hash (value_table, new_pair, new_pair->hashcode,
INSERT);
if (*slot)
free (*slot);
*slot = (void *) new_pair;
set_value_handle (e, v);
add_to_value (v, e);
}
/* Search in VALUE_TABLE for an existing instance of expression E, and
return its value, or NULL if none has been set. */
tree
vn_lookup (tree e)
{
void **slot;
struct val_expr_pair_d vep = {NULL, NULL, 0};
if (TREE_CODE_CLASS (TREE_CODE (e)) == 'c')
return e;
vep.e = e;
vep.hashcode = vn_compute (e, 0);
slot = htab_find_slot_with_hash (value_table, &vep, vep.hashcode, NO_INSERT);
if (!slot)
return NULL_TREE;
else
return ((val_expr_pair_t) *slot)->v;
}
/* Like vn_lookup, but creates a new value for expression E if E doesn't
already have a value. Return the existing/created value for E. */
tree
vn_lookup_or_add (tree e)
{
tree x = vn_lookup (e);
if (x == NULL_TREE)
{
tree v = make_value_handle (TREE_TYPE (e));
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Created value ");
print_generic_expr (dump_file, v, dump_flags);
fprintf (dump_file, " for ");
print_generic_expr (dump_file, e, dump_flags);
fprintf (dump_file, "\n");
}
vn_add (e, v);
x = v;
}
set_value_handle (e, x);
return x;
}
/* Get the value handle of EXPR. This is the only correct way to get
the value handle for a "thing". If EXPR does not have a value
handle associated, it generates and returns a new one. */
tree
get_value_handle (tree expr)
{
if (TREE_CODE (expr) == SSA_NAME)
return SSA_NAME_VALUE (expr);
else if (TREE_CODE_CLASS (TREE_CODE (expr)) == 'c')
return expr;
else if (EXPR_P (expr) || DECL_P (expr))
{
tree_ann_t ann = tree_ann (expr);
return ((ann) ? ann->common.value_handle : NULL_TREE);
}
abort ();
}
/* Initialize data structures used in value numbering. */
void
vn_init (void)
{
value_table = htab_create (511, val_expr_pair_hash,
val_expr_pair_expr_eq, free);
}
/* Delete data used for value numbering. */
void
vn_delete (void)
{
htab_delete (value_table);
value_table = NULL;
}
......@@ -196,6 +196,7 @@ tree_size (tree node)
case STATEMENT_LIST: return sizeof (struct tree_statement_list);
case BLOCK: return sizeof (struct tree_block);
case VALUE_HANDLE: return sizeof (struct tree_value_handle);
default:
return lang_hooks.tree_size (code);
......@@ -1497,6 +1498,7 @@ tree_node_structure (tree t)
case PLACEHOLDER_EXPR: return TS_COMMON;
case STATEMENT_LIST: return TS_STATEMENT_LIST;
case BLOCK: return TS_BLOCK;
case VALUE_HANDLE: return TS_VALUE_HANDLE;
default:
abort ();
......@@ -3851,7 +3853,8 @@ iterative_hash_expr (tree t, hashval_t val)
code = TREE_CODE (t);
class = TREE_CODE_CLASS (code);
if (class == 'd')
if (class == 'd'
|| TREE_CODE (t) == VALUE_HANDLE)
{
/* Decls we can just compare by pointer. */
val = iterative_hash_object (t, val);
......
......@@ -899,6 +899,12 @@ DEFTREECODE (EH_FILTER_EXPR, "eh_filter_expr", 's', 2)
Use the interface in tree-iterator.h to access this node. */
DEFTREECODE (STATEMENT_LIST, "statement_list", 'x', 0)
/* Value handles. Artificial nodes to represent expressions in
partial redundancy elimination (tree-ssa-pre.c). These nodes are
used for expression canonicalization. If two expressions compute
the same value, they will be assigned the same value handle. */
DEFTREECODE (VALUE_HANDLE, "value_handle", 'x', 0)
/*
Local variables:
mode:c
......
......@@ -2234,6 +2234,28 @@ struct tree_statement_list
struct tree_statement_list_node *head;
struct tree_statement_list_node *tail;
};
#define VALUE_HANDLE_ID(NODE) \
(VALUE_HANDLE_CHECK (NODE)->value_handle.id)
#define VALUE_HANDLE_EXPR_SET(NODE) \
(VALUE_HANDLE_CHECK (NODE)->value_handle.expr_set)
/* Defined and used in tree-ssa-pre.c. */
struct value_set;
struct tree_value_handle GTY(())
{
struct tree_common common;
/* The set of expressions represented by this handle. */
struct value_set * GTY ((skip)) expr_set;
/* Unique ID for this value handle. IDs are handed out in a
conveniently dense form starting at 0, so that we can make
bitmaps of value handles. */
unsigned int id;
};
enum tree_node_structure_enum {
TS_COMMON,
......@@ -2252,6 +2274,7 @@ enum tree_node_structure_enum {
TS_PHI_NODE,
TS_BLOCK,
TS_STATEMENT_LIST,
TS_VALUE_HANDLE,
LAST_TS_ENUM
};
......@@ -2278,6 +2301,7 @@ union tree_node GTY ((ptr_alias (union lang_tree_node),
struct tree_phi_node GTY ((tag ("TS_PHI_NODE"))) phi;
struct tree_block GTY ((tag ("TS_BLOCK"))) block;
struct tree_statement_list GTY ((tag ("TS_STATEMENT_LIST"))) stmt_list;
struct tree_value_handle GTY ((tag ("TS_VALUE_HANDLE"))) value_handle;
};
/* Standard named or nameless data types of the C compiler. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment