summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDaniel Berlin <dberlin@dberlin.org>2007-07-07 03:25:29 +0000
committerDaniel Berlin <dberlin@gcc.gnu.org>2007-07-07 03:25:29 +0000
commite9bd9cf340129729a451df77baee39f5b2978226 (patch)
tree24aed28d0f9be6fc1f86cf8db9b21c0fc8d53291 /gcc
parent3673b8ca2b37955838b1c238ba9f70c2a30ac298 (diff)
downloadgcc-e9bd9cf340129729a451df77baee39f5b2978226.tar.gz
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog27
-rw-r--r--gcc/Makefile.in2
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-6.c6
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-17.c17
-rw-r--r--gcc/tree-flow-inline.h10
-rw-r--r--gcc/tree-flow.h3
-rw-r--r--gcc/tree-ssa-pre.c226
-rw-r--r--gcc/tree-ssa-sccvn.c5
-rw-r--r--gcc/tree-vn.c11
10 files changed, 211 insertions, 101 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b12440f8881..5f9ffcd87dc 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,30 @@
+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>
* c-opts.c (c_common_handle_option): Make DOLLARS_IN_IDENTIFIERS
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index c084f0a838b..045bfee732d 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -805,7 +805,7 @@ TREE_DUMP_H = tree-dump.h $(SPLAY_TREE_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) \
- $(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
PRETTY_PRINT_H = pretty-print.h input.h $(OBSTACK_H)
DIAGNOSTIC_H = diagnostic.h diagnostic.def $(PRETTY_PRINT_H) options.h
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 47233a9add0..20b4f95b06e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+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>
* gcc.dg/20001012-1.c: Run on all fpic-capable targets.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-6.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-6.c
new file mode 100644
index 00000000000..6963c1ce483
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-6.c
@@ -0,0 +1,6 @@
+/* { 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" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-17.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-17.c
new file mode 100644
index 00000000000..8fbfced3d5e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-17.c
@@ -0,0 +1,17 @@
+/* { 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" } } */
diff --git a/gcc/tree-flow-inline.h b/gcc/tree-flow-inline.h
index cb2f6558943..2ab4a5ec1c8 100644
--- a/gcc/tree-flow-inline.h
+++ b/gcc/tree-flow-inline.h
@@ -1792,12 +1792,20 @@ get_value_handle (tree expr)
{
if (TREE_CODE (expr) == SSA_NAME)
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_ann_common_t ann = tree_common_ann (expr);
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))
return expr;
else if (EXPR_P (expr))
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index 542f5f85f3d..d521a16b933 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -31,6 +31,7 @@ Boston, MA 02110-1301, USA. */
#include "tree-ssa-operands.h"
#include "cgraph.h"
#include "ipa-reference.h"
+#include "pointer-set.h"
/* Forward declare structures for the garbage collector GTY markers. */
#ifndef GCC_BASIC_BLOCK_H
@@ -1081,7 +1082,7 @@ extern bool maybe_clean_or_replace_eh_stmt (tree, tree);
void add_to_value (tree, tree);
void debug_value_expressions (tree);
void print_value_expressions (FILE *, tree);
-
+extern struct pointer_map_t *decl_vh_map;
/* In tree-vn.c */
tree make_value_handle (tree);
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index ce70a2609f5..9ea3057e9ef 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -46,6 +46,7 @@ Boston, MA 02110-1301, USA. */
#include "langhooks.h"
#include "cfgloop.h"
#include "tree-ssa-sccvn.h"
+#include "pointer-set.h"
/* TODO:
@@ -182,6 +183,14 @@ Boston, MA 02110-1301, USA. */
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. */
static unsigned int next_expression_id;
@@ -193,15 +202,14 @@ static VEC(tree, heap) *expressions;
static inline unsigned int
alloc_expression_id (tree expr)
{
- tree_ann_common_t ann;
-
- ann = get_tree_common_ann (expr);
+ unsigned int *slot;
+ slot = (unsigned int *) pointer_map_insert (expression_id_map,
+ expr);
/* Make sure we won't overflow. */
gcc_assert (next_expression_id + 1 > next_expression_id);
- ann->aux = XNEW (unsigned int);
- * ((unsigned int *)ann->aux) = next_expression_id++;
+ *slot = next_expression_id++;
VEC_safe_push (tree, heap, expressions, expr);
return next_expression_id - 1;
}
@@ -211,11 +219,10 @@ alloc_expression_id (tree expr)
static inline unsigned int
get_expression_id (tree expr)
{
- tree_ann_common_t ann = tree_common_ann (expr);
- gcc_assert (ann);
- gcc_assert (ann->aux);
-
- return *((unsigned int *)ann->aux);
+ unsigned int *slot;
+ slot = (unsigned int *) pointer_map_contains (expression_id_map,
+ expr);
+ return *slot;
}
/* Return the existing expression id for EXPR, or create one if one
@@ -224,12 +231,13 @@ get_expression_id (tree expr)
static inline unsigned int
get_or_alloc_expression_id (tree expr)
{
- tree_ann_common_t ann = tree_common_ann (expr);
-
- if (ann == NULL || !ann->aux)
+ unsigned int *slot;
+ slot = (unsigned int *) pointer_map_contains (expression_id_map,
+ expr);
+ if (slot)
+ return *slot;
+ else
return alloc_expression_id (expr);
-
- return get_expression_id (expr);
}
/* Return the expression that has expression id ID */
@@ -240,23 +248,6 @@ expression_for_id (unsigned int 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;
/* An unordered bitmap set. One bitmap tracks values, the other,
@@ -369,6 +360,7 @@ static alloc_pool unary_node_pool;
static alloc_pool reference_node_pool;
static alloc_pool comparison_node_pool;
static alloc_pool modify_expr_node_pool;
+static alloc_pool decl_node_pool;
static bitmap_obstack grand_bitmap_obstack;
/* 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,
return expr;
/* 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;
@@ -1101,7 +1094,13 @@ phi_translate_1 (tree expr, bitmap_set_t set1, bitmap_set_t set2,
pred);
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);
}
@@ -2065,6 +2064,7 @@ can_value_number_operation (tree op)
|| BINARY_CLASS_P (op)
|| COMPARISON_CLASS_P (op)
|| REFERENCE_CLASS_P (op)
+ || DECL_P (op)
|| (TREE_CODE (op) == CALL_EXPR
&& can_value_number_call (op));
}
@@ -2080,6 +2080,7 @@ can_PRE_operation (tree op)
return UNARY_CLASS_P (op)
|| BINARY_CLASS_P (op)
|| COMPARISON_CLASS_P (op)
+ || DECL_P (op)
|| TREE_CODE (op) == INDIRECT_REF
|| TREE_CODE (op) == COMPONENT_REF
|| TREE_CODE (op) == CALL_EXPR
@@ -2316,7 +2317,14 @@ create_expression_by_pieces (basic_block block, tree expr, tree stmts)
genop1, genop2);
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:
{
tree op1 = TREE_OPERAND (expr, 0);
@@ -2957,10 +2965,15 @@ find_existing_value_expr (tree t, tree stmt)
replaced with the value handles of each of the operands of EXPR.
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
-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;
enum tree_code code = TREE_CODE (expr);
@@ -2985,6 +2998,8 @@ create_value_expr_from (tree expr, basic_block block, tree stmt)
pool = binary_node_pool;
else if (TREE_CODE_CLASS (code) == tcc_comparison)
pool = comparison_node_pool;
+ else if (TREE_CODE_CLASS (code) == tcc_declaration)
+ pool = decl_node_pool;
else
gcc_assert (code == CALL_EXPR);
@@ -2995,12 +3010,15 @@ create_value_expr_from (tree expr, basic_block block, tree stmt)
vexpr = (tree) pool_alloc (pool);
memcpy (vexpr, expr, tree_size (expr));
}
-
+
for (i = 0; i < TREE_OPERAND_LENGTH (expr); i++)
{
tree val = NULL_TREE;
tree op;
-
+
+ if (i != 0)
+ top_level = false;
+
op = TREE_OPERAND (expr, i);
if (op == NULL_TREE)
continue;
@@ -3008,7 +3026,7 @@ create_value_expr_from (tree expr, basic_block block, tree stmt)
/* Recursively value-numberize reference ops and tree lists. */
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;
val = vn_lookup_or_add_with_stmt (op, stmt);
}
@@ -3059,13 +3077,15 @@ poolify_tree (tree node)
return temp;
}
break;
+ case PARM_DECL:
+ case RESULT_DECL:
+ case VAR_DECL:
+ case CONST_DECL:
+ case FUNCTION_DECL:
case SSA_NAME:
case INTEGER_CST:
case STRING_CST:
case REAL_CST:
- case PARM_DECL:
- case VAR_DECL:
- case RESULT_DECL:
return node;
default:
gcc_unreachable ();
@@ -3280,7 +3300,8 @@ make_values_for_phi (tree phi, basic_block block)
if (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);
}
else
@@ -3348,7 +3369,7 @@ make_values_for_stmt (tree stmt, basic_block block)
/* For value numberable operation, create a
duplicate expression with the operands replaced
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 we already have a value number for the LHS, reuse
@@ -3376,8 +3397,7 @@ make_values_for_stmt (tree stmt, basic_block block)
&& !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs))
|| is_gimple_min_invariant (rhs)
|| TREE_CODE (rhs) == ADDR_EXPR
- || TREE_INVARIANT (rhs)
- || DECL_P (rhs))
+ || TREE_INVARIANT (rhs))
{
if (lhsval)
@@ -3785,7 +3805,8 @@ static void
init_pre (bool do_fre)
{
basic_block bb;
-
+ unsigned int max_decl_size;
+
next_expression_id = 0;
expressions = NULL;
in_fre = do_fre;
@@ -3796,52 +3817,63 @@ init_pre (bool do_fre)
storetemp = 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));
-
-
- postorder = XNEWVEC (int, n_basic_blocks - NUM_FIXED_BLOCKS);
- post_order_compute (postorder, false, false);
-
+ bitmap_obstack_initialize (&grand_bitmap_obstack);
+
+ if (!do_fre)
+ {
+ 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)
bb->aux = xcalloc (1, sizeof (struct bb_bitmap_sets));
- calculate_dominance_info (CDI_POST_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",
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)
{
- EXP_GEN (bb) = bitmap_set_new ();
- PHI_GEN (bb) = bitmap_set_new ();
- TMP_GEN (bb) = bitmap_set_new ();
+ if (!do_fre)
+ {
+ EXP_GEN (bb) = bitmap_set_new ();
+ PHI_GEN (bb) = bitmap_set_new ();
+ TMP_GEN (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);
+ decl_vh_map = pointer_map_create ();
+ expression_id_map = pointer_map_create ();
}
@@ -3852,19 +3884,24 @@ fini_pre (void)
{
basic_block bb;
unsigned int i;
-
- free (postorder);
- VEC_free (tree, heap, inserted_exprs);
- VEC_free (tree, heap, need_creation);
+
+ if (!in_fre)
+ {
+ 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);
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)
{
@@ -3872,8 +3909,6 @@ fini_pre (void)
bb->aux = NULL;
}
- free_dominance_info (CDI_POST_DOMINATORS);
-
if (!bitmap_empty_p (need_eh_cleanup))
{
tree_purge_all_dead_eh_edges (need_eh_cleanup);
@@ -3881,7 +3916,9 @@ fini_pre (void)
}
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
future we will want them to be persistent though. */
for (i = 0; i < num_ssa_names; i++)
@@ -3895,7 +3932,7 @@ fini_pre (void)
&& TREE_CODE (SSA_NAME_VALUE (name)) == VALUE_HANDLE)
SSA_NAME_VALUE (name) = NULL;
}
- if (current_loops != NULL)
+ if (current_loops != NULL && !in_fre)
loop_optimizer_finalize ();
}
@@ -3956,7 +3993,6 @@ execute_pre (bool do_fre)
bsi_commit_edge_inserts ();
free_scc_vn ();
- clear_expression_ids ();
if (!do_fre)
{
remove_dead_inserted_code ();
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 9036e2ed6f9..651f747e479 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -1332,6 +1332,7 @@ expr_has_constants (tree expr)
/* Constants inside reference ops are rarely interesting, but
it can take a lot of looking to find them. */
case tcc_reference:
+ case tcc_declaration:
return false;
default:
return is_gimple_min_invariant (expr);
@@ -1453,7 +1454,7 @@ try_to_simplify (tree stmt, tree rhs)
{
/* For references, see if we find a result for the lookup,
and use it if we do. */
-
+ case tcc_declaration:
case tcc_reference:
{
tree result = vn_reference_lookup (rhs,
@@ -1613,7 +1614,7 @@ visit_use (tree use)
if (TREE_CODE (lhs) == SSA_NAME
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
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);
}
diff --git a/gcc/tree-vn.c b/gcc/tree-vn.c
index d62aeea9398..1afd0fedef4 100644
--- a/gcc/tree-vn.c
+++ b/gcc/tree-vn.c
@@ -83,6 +83,10 @@ expressions_equal_p (tree e1, tree e2)
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)
&& (te1 == te2
|| types_compatible_p (te1, te2))
@@ -99,7 +103,12 @@ 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) || 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)
|| TREE_CODE (e) == CONSTRUCTOR)
get_tree_common_ann (e)->value_handle = v;