From 70ae6476fa55847f2c1422691a16c8d405efa002 Mon Sep 17 00:00:00 2001 From: dberlin Date: Sat, 7 Jul 2007 03:25:29 +0000 Subject: [PATCH] 2007-07-06 Daniel Berlin 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 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@126434 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 27 ++++ gcc/Makefile.in | 2 +- gcc/testsuite/ChangeLog | 5 + gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-6.c | 6 + gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-17.c | 17 +++ gcc/tree-flow-inline.h | 10 +- gcc/tree-flow.h | 3 +- gcc/tree-ssa-pre.c | 226 +++++++++++++++++------------ gcc/tree-ssa-sccvn.c | 5 +- gcc/tree-vn.c | 11 +- 10 files changed, 211 insertions(+), 101 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-6.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-17.c 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 + + 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 * 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 + + * 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 * 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; -- 2.11.0