Commit e9bd9cf3 by Daniel Berlin Committed by Daniel Berlin

re PR middle-end/23488 (GCSE load PRE does not work with non sets (or missing…

re PR middle-end/23488 (GCSE load PRE does not work with non sets (or missing load PRE with plain decls))

2007-07-06  Daniel Berlin  <dberlin@dberlin.org>

	Fix PR tree-optimization/23488

	* tree-ssa-sccvn.c (expr_has_constants): Handle tcc_declaration.
	(try_to_simplify): Ditto.
	(visit_use): Ditto.
	* tree-vn.c (set_value_handle): Use decl_vh_map for decl value
	handles.
	* tree-flow-inline.h (get_value_handle): Ditto.
	* tree-ssa-pre.c (decl_vh_map): New.
	(decl_node_pool): New.
	(can_value_number_operation): Support DECL_P.
	(can_PRE_operation): Ditto.
	(create_expression_by_pieces): Ditto.
	(find_existing_value_expr): Modify to differnetiate between
	addressing and top level.
	(create_value_handle_for_expr): Handle DECL's.
	(poolify_tree): Ditto.
	(make_values_for_phi): Don't insert into PHI_GEN during FRE.
	(make_values_for_stmt): Handle DECL's properly.
	(init_pre): Reorg to not init useless things during FRE.
	(fini_pre): Ditto.
	* tree-flow.h: Include pointer-set.h.
	(decl_vh_map): Declare.
	* Makefile.in (TREE_FLOW_H): Add pointer-set.h

From-SVN: r126434
parent 3673b8ca
2007-07-06 Daniel Berlin <dberlin@dberlin.org>
Fix PR tree-optimization/23488
* tree-ssa-sccvn.c (expr_has_constants): Handle tcc_declaration.
(try_to_simplify): Ditto.
(visit_use): Ditto.
* tree-vn.c (set_value_handle): Use decl_vh_map for decl value
handles.
* tree-flow-inline.h (get_value_handle): Ditto.
* tree-ssa-pre.c (decl_vh_map): New.
(decl_node_pool): New.
(can_value_number_operation): Support DECL_P.
(can_PRE_operation): Ditto.
(create_expression_by_pieces): Ditto.
(find_existing_value_expr): Modify to differnetiate between
addressing and top level.
(create_value_handle_for_expr): Handle DECL's.
(poolify_tree): Ditto.
(make_values_for_phi): Don't insert into PHI_GEN during FRE.
(make_values_for_stmt): Handle DECL's properly.
(init_pre): Reorg to not init useless things during FRE.
(fini_pre): Ditto.
* tree-flow.h: Include pointer-set.h.
(decl_vh_map): Declare.
* Makefile.in (TREE_FLOW_H): Add pointer-set.h
2007-07-06 Sandra Loosemore <sandra@codesourcery.com> 2007-07-06 Sandra Loosemore <sandra@codesourcery.com>
* c-opts.c (c_common_handle_option): Make DOLLARS_IN_IDENTIFIERS * c-opts.c (c_common_handle_option): Make DOLLARS_IN_IDENTIFIERS
......
...@@ -805,7 +805,7 @@ TREE_DUMP_H = tree-dump.h $(SPLAY_TREE_H) ...@@ -805,7 +805,7 @@ TREE_DUMP_H = tree-dump.h $(SPLAY_TREE_H)
TREE_GIMPLE_H = tree-gimple.h tree-iterator.h TREE_GIMPLE_H = tree-gimple.h tree-iterator.h
TREE_FLOW_H = tree-flow.h tree-flow-inline.h tree-ssa-operands.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) \ bitmap.h $(BASIC_BLOCK_H) hard-reg-set.h $(TREE_GIMPLE_H) \
$(HASHTAB_H) $(CGRAPH_H) $(IPA_REFERENCE_H) $(HASHTAB_H) $(CGRAPH_H) $(IPA_REFERENCE_H) pointer-set.h
TREE_SSA_LIVE_H = tree-ssa-live.h $(PARTITION_H) vecprim.h TREE_SSA_LIVE_H = tree-ssa-live.h $(PARTITION_H) vecprim.h
PRETTY_PRINT_H = pretty-print.h input.h $(OBSTACK_H) PRETTY_PRINT_H = pretty-print.h input.h $(OBSTACK_H)
DIAGNOSTIC_H = diagnostic.h diagnostic.def $(PRETTY_PRINT_H) options.h DIAGNOSTIC_H = diagnostic.h diagnostic.def $(PRETTY_PRINT_H) options.h
......
2007-07-06 Daniel Berlin <dberlin@dberlin.org>
* gcc.dg/tree-ssa/ssa-pre-17.c: New test.
* gcc.dg/tree-ssa/ssa-fre-7.c: New test.
2007-07-06 Nathan Froyd <froydnj@codesourcery.com> 2007-07-06 Nathan Froyd <froydnj@codesourcery.com>
* gcc.dg/20001012-1.c: Run on all fpic-capable targets. * gcc.dg/20001012-1.c: Run on all fpic-capable targets.
/* { dg-do compile } */
/* { dg-options "-O -fdump-tree-fre-details" } */
int i; int foo(void) { i = 2; int j = i * 2; int k = i + 2; return j == k; }
/* { dg-final { scan-tree-dump-times "Replaced " 5 "fre" } } */
/* { dg-final { cleanup-tree-dump "fre" } } */
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-pre-details" } */
int i;
int foo(int q) {
int j;
int p;
for (j = 0; j < 9; j++)
{
p = i + q;
}
return p;
}
/* We should replace p = a load from i that will pop into the loop, with a hoisted version.
We should also replace i + q with a hoisted version. */
/* { dg-final { scan-tree-dump-times "Replaced " 2 "pre" } } */
/* { dg-final { cleanup-tree-dump "pre" } } */
...@@ -1792,12 +1792,20 @@ get_value_handle (tree expr) ...@@ -1792,12 +1792,20 @@ get_value_handle (tree expr)
{ {
if (TREE_CODE (expr) == SSA_NAME) if (TREE_CODE (expr) == SSA_NAME)
return SSA_NAME_VALUE (expr); return SSA_NAME_VALUE (expr);
else if (DECL_P (expr) || TREE_CODE (expr) == TREE_LIST else if (TREE_CODE (expr) == TREE_LIST
|| TREE_CODE (expr) == CONSTRUCTOR) || TREE_CODE (expr) == CONSTRUCTOR)
{ {
tree_ann_common_t ann = tree_common_ann (expr); tree_ann_common_t ann = tree_common_ann (expr);
return ((ann) ? ann->value_handle : NULL_TREE); return ((ann) ? ann->value_handle : NULL_TREE);
} }
else if (DECL_P (expr))
{
tree *result = (tree *)pointer_map_contains (decl_vh_map,
expr);
if (result)
return *result;
return NULL_TREE;
}
else if (is_gimple_min_invariant (expr)) else if (is_gimple_min_invariant (expr))
return expr; return expr;
else if (EXPR_P (expr)) else if (EXPR_P (expr))
......
...@@ -31,6 +31,7 @@ Boston, MA 02110-1301, USA. */ ...@@ -31,6 +31,7 @@ Boston, MA 02110-1301, USA. */
#include "tree-ssa-operands.h" #include "tree-ssa-operands.h"
#include "cgraph.h" #include "cgraph.h"
#include "ipa-reference.h" #include "ipa-reference.h"
#include "pointer-set.h"
/* Forward declare structures for the garbage collector GTY markers. */ /* Forward declare structures for the garbage collector GTY markers. */
#ifndef GCC_BASIC_BLOCK_H #ifndef GCC_BASIC_BLOCK_H
...@@ -1081,7 +1082,7 @@ extern bool maybe_clean_or_replace_eh_stmt (tree, tree); ...@@ -1081,7 +1082,7 @@ extern bool maybe_clean_or_replace_eh_stmt (tree, tree);
void add_to_value (tree, tree); void add_to_value (tree, tree);
void debug_value_expressions (tree); void debug_value_expressions (tree);
void print_value_expressions (FILE *, tree); void print_value_expressions (FILE *, tree);
extern struct pointer_map_t *decl_vh_map;
/* In tree-vn.c */ /* In tree-vn.c */
tree make_value_handle (tree); tree make_value_handle (tree);
......
...@@ -46,6 +46,7 @@ Boston, MA 02110-1301, USA. */ ...@@ -46,6 +46,7 @@ Boston, MA 02110-1301, USA. */
#include "langhooks.h" #include "langhooks.h"
#include "cfgloop.h" #include "cfgloop.h"
#include "tree-ssa-sccvn.h" #include "tree-ssa-sccvn.h"
#include "pointer-set.h"
/* TODO: /* TODO:
...@@ -182,6 +183,14 @@ Boston, MA 02110-1301, USA. */ ...@@ -182,6 +183,14 @@ Boston, MA 02110-1301, USA. */
useful only for debugging, since we don't do identity lookups. */ useful only for debugging, since we don't do identity lookups. */
/* Mapping from decl's to value handles, by pointer equality. We
"unshare" decls so we can give the same decl in different places
different value handles. */
struct pointer_map_t *decl_vh_map;
/* Mapping from expressions to ids. */
struct pointer_map_t *expression_id_map;
/* Next global expression id number. */ /* Next global expression id number. */
static unsigned int next_expression_id; static unsigned int next_expression_id;
...@@ -193,15 +202,14 @@ static VEC(tree, heap) *expressions; ...@@ -193,15 +202,14 @@ static VEC(tree, heap) *expressions;
static inline unsigned int static inline unsigned int
alloc_expression_id (tree expr) alloc_expression_id (tree expr)
{ {
tree_ann_common_t ann; unsigned int *slot;
ann = get_tree_common_ann (expr);
slot = (unsigned int *) pointer_map_insert (expression_id_map,
expr);
/* Make sure we won't overflow. */ /* Make sure we won't overflow. */
gcc_assert (next_expression_id + 1 > next_expression_id); gcc_assert (next_expression_id + 1 > next_expression_id);
ann->aux = XNEW (unsigned int); *slot = next_expression_id++;
* ((unsigned int *)ann->aux) = next_expression_id++;
VEC_safe_push (tree, heap, expressions, expr); VEC_safe_push (tree, heap, expressions, expr);
return next_expression_id - 1; return next_expression_id - 1;
} }
...@@ -211,11 +219,10 @@ alloc_expression_id (tree expr) ...@@ -211,11 +219,10 @@ alloc_expression_id (tree expr)
static inline unsigned int static inline unsigned int
get_expression_id (tree expr) get_expression_id (tree expr)
{ {
tree_ann_common_t ann = tree_common_ann (expr); unsigned int *slot;
gcc_assert (ann); slot = (unsigned int *) pointer_map_contains (expression_id_map,
gcc_assert (ann->aux); expr);
return *slot;
return *((unsigned int *)ann->aux);
} }
/* Return the existing expression id for EXPR, or create one if one /* Return the existing expression id for EXPR, or create one if one
...@@ -224,12 +231,13 @@ get_expression_id (tree expr) ...@@ -224,12 +231,13 @@ get_expression_id (tree expr)
static inline unsigned int static inline unsigned int
get_or_alloc_expression_id (tree expr) get_or_alloc_expression_id (tree expr)
{ {
tree_ann_common_t ann = tree_common_ann (expr); unsigned int *slot;
slot = (unsigned int *) pointer_map_contains (expression_id_map,
if (ann == NULL || !ann->aux) expr);
if (slot)
return *slot;
else
return alloc_expression_id (expr); return alloc_expression_id (expr);
return get_expression_id (expr);
} }
/* Return the expression that has expression id ID */ /* Return the expression that has expression id ID */
...@@ -240,23 +248,6 @@ expression_for_id (unsigned int id) ...@@ -240,23 +248,6 @@ expression_for_id (unsigned int id)
return VEC_index (tree, expressions, id); return VEC_index (tree, expressions, id);
} }
/* Free the expression id field in all of our expressions,
and then destroy the expressions array. */
static void
clear_expression_ids (void)
{
int i;
tree expr;
for (i = 0; VEC_iterate (tree, expressions, i, expr); i++)
{
free (tree_common_ann (expr)->aux);
tree_common_ann (expr)->aux = NULL;
}
VEC_free (tree, heap, expressions);
}
static bool in_fre = false; static bool in_fre = false;
/* An unordered bitmap set. One bitmap tracks values, the other, /* An unordered bitmap set. One bitmap tracks values, the other,
...@@ -369,6 +360,7 @@ static alloc_pool unary_node_pool; ...@@ -369,6 +360,7 @@ static alloc_pool unary_node_pool;
static alloc_pool reference_node_pool; static alloc_pool reference_node_pool;
static alloc_pool comparison_node_pool; static alloc_pool comparison_node_pool;
static alloc_pool modify_expr_node_pool; static alloc_pool modify_expr_node_pool;
static alloc_pool decl_node_pool;
static bitmap_obstack grand_bitmap_obstack; static bitmap_obstack grand_bitmap_obstack;
/* We can't use allocation pools to hold temporary CALL_EXPR objects, since /* We can't use allocation pools to hold temporary CALL_EXPR objects, since
...@@ -954,7 +946,8 @@ phi_translate_1 (tree expr, bitmap_set_t set1, bitmap_set_t set2, ...@@ -954,7 +946,8 @@ phi_translate_1 (tree expr, bitmap_set_t set1, bitmap_set_t set2,
return expr; return expr;
/* Phi translations of a given expression don't change. */ /* Phi translations of a given expression don't change. */
if (EXPR_P (expr) || GIMPLE_STMT_P (expr)) if (EXPR_P (expr) || GIMPLE_STMT_P (expr) || REFERENCE_CLASS_P (expr)
|| DECL_P (expr))
{ {
tree vh; tree vh;
...@@ -1101,7 +1094,13 @@ phi_translate_1 (tree expr, bitmap_set_t set1, bitmap_set_t set2, ...@@ -1101,7 +1094,13 @@ phi_translate_1 (tree expr, bitmap_set_t set1, bitmap_set_t set2,
pred); pred);
if (oldvuses != newvuses) if (oldvuses != newvuses)
vn_lookup_or_add_with_vuses (expr, newvuses); {
tree newexpr = (tree) pool_alloc (decl_node_pool);
memcpy (newexpr, expr, tree_size (expr));
vn_lookup_or_add_with_vuses (newexpr, newvuses);
expr = newexpr;
phi_trans_add (expr, expr, pred, newvuses);
}
phi_trans_add (oldexpr, expr, pred, newvuses); phi_trans_add (oldexpr, expr, pred, newvuses);
} }
...@@ -2065,6 +2064,7 @@ can_value_number_operation (tree op) ...@@ -2065,6 +2064,7 @@ can_value_number_operation (tree op)
|| BINARY_CLASS_P (op) || BINARY_CLASS_P (op)
|| COMPARISON_CLASS_P (op) || COMPARISON_CLASS_P (op)
|| REFERENCE_CLASS_P (op) || REFERENCE_CLASS_P (op)
|| DECL_P (op)
|| (TREE_CODE (op) == CALL_EXPR || (TREE_CODE (op) == CALL_EXPR
&& can_value_number_call (op)); && can_value_number_call (op));
} }
...@@ -2080,6 +2080,7 @@ can_PRE_operation (tree op) ...@@ -2080,6 +2080,7 @@ can_PRE_operation (tree op)
return UNARY_CLASS_P (op) return UNARY_CLASS_P (op)
|| BINARY_CLASS_P (op) || BINARY_CLASS_P (op)
|| COMPARISON_CLASS_P (op) || COMPARISON_CLASS_P (op)
|| DECL_P (op)
|| TREE_CODE (op) == INDIRECT_REF || TREE_CODE (op) == INDIRECT_REF
|| TREE_CODE (op) == COMPONENT_REF || TREE_CODE (op) == COMPONENT_REF
|| TREE_CODE (op) == CALL_EXPR || TREE_CODE (op) == CALL_EXPR
...@@ -2316,7 +2317,14 @@ create_expression_by_pieces (basic_block block, tree expr, tree stmts) ...@@ -2316,7 +2317,14 @@ create_expression_by_pieces (basic_block block, tree expr, tree stmts)
genop1, genop2); genop1, genop2);
break; break;
} }
case tcc_declaration:
{
/* Get the "shared" version of the DECL, that we didn't create
using a pool. */
folded = referenced_var_lookup (DECL_UID (expr));
}
break;
case tcc_unary: case tcc_unary:
{ {
tree op1 = TREE_OPERAND (expr, 0); tree op1 = TREE_OPERAND (expr, 0);
...@@ -2957,10 +2965,15 @@ find_existing_value_expr (tree t, tree stmt) ...@@ -2957,10 +2965,15 @@ find_existing_value_expr (tree t, tree stmt)
replaced with the value handles of each of the operands of EXPR. replaced with the value handles of each of the operands of EXPR.
VUSES represent the virtual use operands associated with EXPR (if VUSES represent the virtual use operands associated with EXPR (if
any). Insert EXPR's operands into the EXP_GEN set for BLOCK. */ any). Insert EXPR's operands into the EXP_GEN set for BLOCK.
TOP_LEVEL is true if we are at the top of the original
expression. This is used to differentiate between addressing and
actual loads of globals. IE a = t vs a = t[0]. */
static inline tree static inline tree
create_value_expr_from (tree expr, basic_block block, tree stmt) create_value_expr_from (tree expr, basic_block block, tree stmt,
bool top_level)
{ {
int i; int i;
enum tree_code code = TREE_CODE (expr); enum tree_code code = TREE_CODE (expr);
...@@ -2985,6 +2998,8 @@ create_value_expr_from (tree expr, basic_block block, tree stmt) ...@@ -2985,6 +2998,8 @@ create_value_expr_from (tree expr, basic_block block, tree stmt)
pool = binary_node_pool; pool = binary_node_pool;
else if (TREE_CODE_CLASS (code) == tcc_comparison) else if (TREE_CODE_CLASS (code) == tcc_comparison)
pool = comparison_node_pool; pool = comparison_node_pool;
else if (TREE_CODE_CLASS (code) == tcc_declaration)
pool = decl_node_pool;
else else
gcc_assert (code == CALL_EXPR); gcc_assert (code == CALL_EXPR);
...@@ -2995,12 +3010,15 @@ create_value_expr_from (tree expr, basic_block block, tree stmt) ...@@ -2995,12 +3010,15 @@ create_value_expr_from (tree expr, basic_block block, tree stmt)
vexpr = (tree) pool_alloc (pool); vexpr = (tree) pool_alloc (pool);
memcpy (vexpr, expr, tree_size (expr)); memcpy (vexpr, expr, tree_size (expr));
} }
for (i = 0; i < TREE_OPERAND_LENGTH (expr); i++) for (i = 0; i < TREE_OPERAND_LENGTH (expr); i++)
{ {
tree val = NULL_TREE; tree val = NULL_TREE;
tree op; tree op;
if (i != 0)
top_level = false;
op = TREE_OPERAND (expr, i); op = TREE_OPERAND (expr, i);
if (op == NULL_TREE) if (op == NULL_TREE)
continue; continue;
...@@ -3008,7 +3026,7 @@ create_value_expr_from (tree expr, basic_block block, tree stmt) ...@@ -3008,7 +3026,7 @@ create_value_expr_from (tree expr, basic_block block, tree stmt)
/* Recursively value-numberize reference ops and tree lists. */ /* Recursively value-numberize reference ops and tree lists. */
if (REFERENCE_CLASS_P (op)) if (REFERENCE_CLASS_P (op))
{ {
tree tempop = create_value_expr_from (op, block, stmt); tree tempop = create_value_expr_from (op, block, stmt, false);
op = tempop ? tempop : op; op = tempop ? tempop : op;
val = vn_lookup_or_add_with_stmt (op, stmt); val = vn_lookup_or_add_with_stmt (op, stmt);
} }
...@@ -3059,13 +3077,15 @@ poolify_tree (tree node) ...@@ -3059,13 +3077,15 @@ poolify_tree (tree node)
return temp; return temp;
} }
break; break;
case PARM_DECL:
case RESULT_DECL:
case VAR_DECL:
case CONST_DECL:
case FUNCTION_DECL:
case SSA_NAME: case SSA_NAME:
case INTEGER_CST: case INTEGER_CST:
case STRING_CST: case STRING_CST:
case REAL_CST: case REAL_CST:
case PARM_DECL:
case VAR_DECL:
case RESULT_DECL:
return node; return node;
default: default:
gcc_unreachable (); gcc_unreachable ();
...@@ -3280,7 +3300,8 @@ make_values_for_phi (tree phi, basic_block block) ...@@ -3280,7 +3300,8 @@ make_values_for_phi (tree phi, basic_block block)
if (sccvnval) if (sccvnval)
{ {
vn_add (result, sccvnval); vn_add (result, sccvnval);
bitmap_insert_into_set (PHI_GEN (block), result); if (!in_fre)
bitmap_insert_into_set (PHI_GEN (block), result);
bitmap_value_insert_into_set (AVAIL_OUT (block), result); bitmap_value_insert_into_set (AVAIL_OUT (block), result);
} }
else else
...@@ -3348,7 +3369,7 @@ make_values_for_stmt (tree stmt, basic_block block) ...@@ -3348,7 +3369,7 @@ make_values_for_stmt (tree stmt, basic_block block)
/* For value numberable operation, create a /* For value numberable operation, create a
duplicate expression with the operands replaced duplicate expression with the operands replaced
with the value handles of the original RHS. */ with the value handles of the original RHS. */
tree newt = create_value_expr_from (rhs, block, stmt); tree newt = create_value_expr_from (rhs, block, stmt, true);
if (newt) if (newt)
{ {
/* If we already have a value number for the LHS, reuse /* If we already have a value number for the LHS, reuse
...@@ -3376,8 +3397,7 @@ make_values_for_stmt (tree stmt, basic_block block) ...@@ -3376,8 +3397,7 @@ make_values_for_stmt (tree stmt, basic_block block)
&& !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs)) && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs))
|| is_gimple_min_invariant (rhs) || is_gimple_min_invariant (rhs)
|| TREE_CODE (rhs) == ADDR_EXPR || TREE_CODE (rhs) == ADDR_EXPR
|| TREE_INVARIANT (rhs) || TREE_INVARIANT (rhs))
|| DECL_P (rhs))
{ {
if (lhsval) if (lhsval)
...@@ -3785,7 +3805,8 @@ static void ...@@ -3785,7 +3805,8 @@ static void
init_pre (bool do_fre) init_pre (bool do_fre)
{ {
basic_block bb; basic_block bb;
unsigned int max_decl_size;
next_expression_id = 0; next_expression_id = 0;
expressions = NULL; expressions = NULL;
in_fre = do_fre; in_fre = do_fre;
...@@ -3796,52 +3817,63 @@ init_pre (bool do_fre) ...@@ -3796,52 +3817,63 @@ init_pre (bool do_fre)
storetemp = NULL_TREE; storetemp = NULL_TREE;
prephitemp = NULL_TREE; prephitemp = NULL_TREE;
if (!do_fre)
loop_optimizer_init (LOOPS_NORMAL);
connect_infinite_loops_to_exit ();
memset (&pre_stats, 0, sizeof (pre_stats)); memset (&pre_stats, 0, sizeof (pre_stats));
bitmap_obstack_initialize (&grand_bitmap_obstack);
postorder = XNEWVEC (int, n_basic_blocks - NUM_FIXED_BLOCKS); if (!do_fre)
post_order_compute (postorder, false, false); {
loop_optimizer_init (LOOPS_NORMAL);
connect_infinite_loops_to_exit ();
postorder = XNEWVEC (int, n_basic_blocks - NUM_FIXED_BLOCKS);
post_order_compute (postorder, false, false);
calculate_dominance_info (CDI_POST_DOMINATORS);
phi_translate_table = htab_create (5110, expr_pred_trans_hash,
expr_pred_trans_eq, free);
seen_during_translate = BITMAP_ALLOC (&grand_bitmap_obstack);
binary_node_pool = create_alloc_pool ("Binary tree nodes",
tree_code_size (PLUS_EXPR), 30);
unary_node_pool = create_alloc_pool ("Unary tree nodes",
tree_code_size (NEGATE_EXPR), 30);
reference_node_pool = create_alloc_pool ("Reference tree nodes",
tree_code_size (ARRAY_REF), 30);
comparison_node_pool = create_alloc_pool ("Comparison tree nodes",
tree_code_size (EQ_EXPR), 30);
modify_expr_node_pool = create_alloc_pool ("GIMPLE_MODIFY_STMT nodes",
tree_code_size (GIMPLE_MODIFY_STMT),
30);
max_decl_size = MAX (tree_code_size (VAR_DECL), tree_code_size (PARM_DECL));
max_decl_size = MAX (max_decl_size, tree_code_size (RESULT_DECL));
max_decl_size = MAX (max_decl_size, tree_code_size (CONST_DECL));
max_decl_size = MAX (max_decl_size, tree_code_size (FUNCTION_DECL));
decl_node_pool = create_alloc_pool ("_DECL nodes", max_decl_size, 30);
obstack_init (&temp_call_expr_obstack);
modify_expr_template = NULL;
}
FOR_ALL_BB (bb) FOR_ALL_BB (bb)
bb->aux = xcalloc (1, sizeof (struct bb_bitmap_sets)); bb->aux = xcalloc (1, sizeof (struct bb_bitmap_sets));
calculate_dominance_info (CDI_POST_DOMINATORS);
calculate_dominance_info (CDI_DOMINATORS); calculate_dominance_info (CDI_DOMINATORS);
bitmap_obstack_initialize (&grand_bitmap_obstack);
phi_translate_table = htab_create (5110, expr_pred_trans_hash,
expr_pred_trans_eq, free);
seen_during_translate = BITMAP_ALLOC (&grand_bitmap_obstack);
bitmap_set_pool = create_alloc_pool ("Bitmap sets", bitmap_set_pool = create_alloc_pool ("Bitmap sets",
sizeof (struct bitmap_set), 30); sizeof (struct bitmap_set), 30);
binary_node_pool = create_alloc_pool ("Binary tree nodes",
tree_code_size (PLUS_EXPR), 30);
unary_node_pool = create_alloc_pool ("Unary tree nodes",
tree_code_size (NEGATE_EXPR), 30);
reference_node_pool = create_alloc_pool ("Reference tree nodes",
tree_code_size (ARRAY_REF), 30);
comparison_node_pool = create_alloc_pool ("Comparison tree nodes",
tree_code_size (EQ_EXPR), 30);
modify_expr_node_pool = create_alloc_pool ("GIMPLE_MODIFY_STMT nodes",
tree_code_size (GIMPLE_MODIFY_STMT),
30);
obstack_init (&temp_call_expr_obstack);
modify_expr_template = NULL;
FOR_ALL_BB (bb) FOR_ALL_BB (bb)
{ {
EXP_GEN (bb) = bitmap_set_new (); if (!do_fre)
PHI_GEN (bb) = bitmap_set_new (); {
TMP_GEN (bb) = bitmap_set_new (); EXP_GEN (bb) = bitmap_set_new ();
PHI_GEN (bb) = bitmap_set_new ();
TMP_GEN (bb) = bitmap_set_new ();
}
AVAIL_OUT (bb) = bitmap_set_new (); AVAIL_OUT (bb) = bitmap_set_new ();
} }
maximal_set = in_fre ? NULL : bitmap_set_new (); maximal_set = do_fre ? NULL : bitmap_set_new ();
need_eh_cleanup = BITMAP_ALLOC (NULL); need_eh_cleanup = BITMAP_ALLOC (NULL);
decl_vh_map = pointer_map_create ();
expression_id_map = pointer_map_create ();
} }
...@@ -3852,19 +3884,24 @@ fini_pre (void) ...@@ -3852,19 +3884,24 @@ fini_pre (void)
{ {
basic_block bb; basic_block bb;
unsigned int i; unsigned int i;
free (postorder); if (!in_fre)
VEC_free (tree, heap, inserted_exprs); {
VEC_free (tree, heap, need_creation); free (postorder);
VEC_free (tree, heap, inserted_exprs);
VEC_free (tree, heap, need_creation);
free_alloc_pool (binary_node_pool);
free_alloc_pool (reference_node_pool);
free_alloc_pool (unary_node_pool);
free_alloc_pool (comparison_node_pool);
free_alloc_pool (modify_expr_node_pool);
free_alloc_pool (decl_node_pool);
htab_delete (phi_translate_table);
remove_fake_exit_edges ();
free_dominance_info (CDI_POST_DOMINATORS);
}
bitmap_obstack_release (&grand_bitmap_obstack); bitmap_obstack_release (&grand_bitmap_obstack);
free_alloc_pool (bitmap_set_pool); free_alloc_pool (bitmap_set_pool);
free_alloc_pool (binary_node_pool);
free_alloc_pool (reference_node_pool);
free_alloc_pool (unary_node_pool);
free_alloc_pool (comparison_node_pool);
free_alloc_pool (modify_expr_node_pool);
htab_delete (phi_translate_table);
remove_fake_exit_edges ();
FOR_ALL_BB (bb) FOR_ALL_BB (bb)
{ {
...@@ -3872,8 +3909,6 @@ fini_pre (void) ...@@ -3872,8 +3909,6 @@ fini_pre (void)
bb->aux = NULL; bb->aux = NULL;
} }
free_dominance_info (CDI_POST_DOMINATORS);
if (!bitmap_empty_p (need_eh_cleanup)) if (!bitmap_empty_p (need_eh_cleanup))
{ {
tree_purge_all_dead_eh_edges (need_eh_cleanup); tree_purge_all_dead_eh_edges (need_eh_cleanup);
...@@ -3881,7 +3916,9 @@ fini_pre (void) ...@@ -3881,7 +3916,9 @@ fini_pre (void)
} }
BITMAP_FREE (need_eh_cleanup); BITMAP_FREE (need_eh_cleanup);
pointer_map_destroy (decl_vh_map);
pointer_map_destroy (expression_id_map);
/* Wipe out pointers to VALUE_HANDLEs. In the not terribly distant /* Wipe out pointers to VALUE_HANDLEs. In the not terribly distant
future we will want them to be persistent though. */ future we will want them to be persistent though. */
for (i = 0; i < num_ssa_names; i++) for (i = 0; i < num_ssa_names; i++)
...@@ -3895,7 +3932,7 @@ fini_pre (void) ...@@ -3895,7 +3932,7 @@ fini_pre (void)
&& TREE_CODE (SSA_NAME_VALUE (name)) == VALUE_HANDLE) && TREE_CODE (SSA_NAME_VALUE (name)) == VALUE_HANDLE)
SSA_NAME_VALUE (name) = NULL; SSA_NAME_VALUE (name) = NULL;
} }
if (current_loops != NULL) if (current_loops != NULL && !in_fre)
loop_optimizer_finalize (); loop_optimizer_finalize ();
} }
...@@ -3956,7 +3993,6 @@ execute_pre (bool do_fre) ...@@ -3956,7 +3993,6 @@ execute_pre (bool do_fre)
bsi_commit_edge_inserts (); bsi_commit_edge_inserts ();
free_scc_vn (); free_scc_vn ();
clear_expression_ids ();
if (!do_fre) if (!do_fre)
{ {
remove_dead_inserted_code (); remove_dead_inserted_code ();
......
...@@ -1332,6 +1332,7 @@ expr_has_constants (tree expr) ...@@ -1332,6 +1332,7 @@ expr_has_constants (tree expr)
/* Constants inside reference ops are rarely interesting, but /* Constants inside reference ops are rarely interesting, but
it can take a lot of looking to find them. */ it can take a lot of looking to find them. */
case tcc_reference: case tcc_reference:
case tcc_declaration:
return false; return false;
default: default:
return is_gimple_min_invariant (expr); return is_gimple_min_invariant (expr);
...@@ -1453,7 +1454,7 @@ try_to_simplify (tree stmt, tree rhs) ...@@ -1453,7 +1454,7 @@ try_to_simplify (tree stmt, tree rhs)
{ {
/* For references, see if we find a result for the lookup, /* For references, see if we find a result for the lookup,
and use it if we do. */ and use it if we do. */
case tcc_declaration:
case tcc_reference: case tcc_reference:
{ {
tree result = vn_reference_lookup (rhs, tree result = vn_reference_lookup (rhs,
...@@ -1613,7 +1614,7 @@ visit_use (tree use) ...@@ -1613,7 +1614,7 @@ visit_use (tree use)
if (TREE_CODE (lhs) == SSA_NAME if (TREE_CODE (lhs) == SSA_NAME
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs)) && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
changed = defs_to_varying (stmt); changed = defs_to_varying (stmt);
else if (REFERENCE_CLASS_P (lhs)) else if (REFERENCE_CLASS_P (lhs) || DECL_P (lhs))
{ {
changed = visit_reference_op_store (lhs, rhs, stmt); changed = visit_reference_op_store (lhs, rhs, stmt);
} }
......
...@@ -83,6 +83,10 @@ expressions_equal_p (tree e1, tree e2) ...@@ -83,6 +83,10 @@ expressions_equal_p (tree e1, tree e2)
return true; return true;
} }
else if (TREE_CODE (e1) == TREE_CODE (e2)
&& DECL_P (e1)
&& te1 == te2)
return DECL_UID (e1) == DECL_UID (e2);
else if (TREE_CODE (e1) == TREE_CODE (e2) else if (TREE_CODE (e1) == TREE_CODE (e2)
&& (te1 == te2 && (te1 == te2
|| types_compatible_p (te1, te2)) || types_compatible_p (te1, te2))
...@@ -99,7 +103,12 @@ set_value_handle (tree e, tree v) ...@@ -99,7 +103,12 @@ set_value_handle (tree e, tree v)
{ {
if (TREE_CODE (e) == SSA_NAME) if (TREE_CODE (e) == SSA_NAME)
SSA_NAME_VALUE (e) = v; SSA_NAME_VALUE (e) = v;
else if (EXPR_P (e) || DECL_P (e) || TREE_CODE (e) == TREE_LIST else if (DECL_P (e))
{
tree *slot = (tree *)pointer_map_insert (decl_vh_map, e);
*slot = v;
}
else if (EXPR_P (e) || TREE_CODE (e) == TREE_LIST
|| GIMPLE_STMT_P (e) || GIMPLE_STMT_P (e)
|| TREE_CODE (e) == CONSTRUCTOR) || TREE_CODE (e) == CONSTRUCTOR)
get_tree_common_ann (e)->value_handle = v; get_tree_common_ann (e)->value_handle = v;
......
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