diff options
author | Diego Novillo <dnovillo@redhat.com> | 2006-12-11 20:15:53 +0000 |
---|---|---|
committer | Diego Novillo <dnovillo@gcc.gnu.org> | 2006-12-11 15:15:53 -0500 |
commit | cfaab3a92418d34e14bb0fa447c052fce9f6057b (patch) | |
tree | 79969bcc52ffc34edcced0521bbe67cd20e564f5 /gcc | |
parent | 7f46c638e6be449fcd80c08babdfaee63b70278e (diff) | |
download | gcc-cfaab3a92418d34e14bb0fa447c052fce9f6057b.tar.gz |
tree-ssa-operands.h (create_ssa_artificial_load_stmt): Rename from create_ssa_artficial_load_stmt.
* tree-ssa-operands.h (create_ssa_artificial_load_stmt):
Rename from create_ssa_artficial_load_stmt. Update all users.
* tree-into-ssa.c (register_new_def): Make static.
* tree.c (is_global_var): Handle SSA_NAMEs.
* tree.h (SSA_NAME_IS_DEFAULT_DEF): Define. Update all users
that used to call gimple_default_def.
* tree-ssa-operands.c (push_stmt_changes): New.
(pop_stmt_changes): New. Update every pass that modifies
statements to bracket modifications with
push_stmt_changes/pop_stmt_changes.
(discard_stmt_changes): New.
* tree-ssa-dom.c (stmts_to_rescan): Change to stack of
'tree *' instead of 'tree'. Update all users.
* tree-flow-inline.h (zero_imm_uses_p): New.
(symbol_mem_tag): New. Update every function that used
to access the annotation directly.
(set_symbol_mem_tag): Likewise.
* tree-dfa.c (dump_variable): Always show the escape mask.
(mark_symbols_for_renaming): Rename from
mark_new_vars_to_rename. Update all users.
Only mark to rename naked symbols in real and virtual
operands.
From-SVN: r119746
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 25 | ||||
-rw-r--r-- | gcc/passes.c | 1 | ||||
-rw-r--r-- | gcc/tree-cfg.c | 15 | ||||
-rw-r--r-- | gcc/tree-data-ref.c | 11 | ||||
-rw-r--r-- | gcc/tree-dfa.c | 124 | ||||
-rw-r--r-- | gcc/tree-flow-inline.h | 38 | ||||
-rw-r--r-- | gcc/tree-flow.h | 36 | ||||
-rw-r--r-- | gcc/tree-into-ssa.c | 2 | ||||
-rw-r--r-- | gcc/tree-outof-ssa.c | 2 | ||||
-rw-r--r-- | gcc/tree-scalar-evolution.c | 3 | ||||
-rw-r--r-- | gcc/tree-ssa-ccp.c | 28 | ||||
-rw-r--r-- | gcc/tree-ssa-dom.c | 57 | ||||
-rw-r--r-- | gcc/tree-ssa-forwprop.c | 13 | ||||
-rw-r--r-- | gcc/tree-ssa-loop-ivopts.c | 12 | ||||
-rw-r--r-- | gcc/tree-ssa-operands.c | 248 | ||||
-rw-r--r-- | gcc/tree-ssa-operands.h | 5 | ||||
-rw-r--r-- | gcc/tree-ssa-pre.c | 8 | ||||
-rw-r--r-- | gcc/tree-ssa-propagate.c | 16 | ||||
-rw-r--r-- | gcc/tree-ssa-reassoc.c | 2 | ||||
-rw-r--r-- | gcc/tree-ssanames.c | 3 | ||||
-rw-r--r-- | gcc/tree-vect-transform.c | 6 | ||||
-rw-r--r-- | gcc/tree-vrp.c | 2 | ||||
-rw-r--r-- | gcc/tree.c | 3 | ||||
-rw-r--r-- | gcc/tree.h | 8 |
24 files changed, 498 insertions, 170 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3f740eeb483..f01ef107787 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,28 @@ +2006-12-11 Diego Novillo <dnovillo@redhat.com> + + * tree-ssa-operands.h (create_ssa_artificial_load_stmt): + Rename from create_ssa_artficial_load_stmt. Update all users. + * tree-into-ssa.c (register_new_def): Make static. + * tree.c (is_global_var): Handle SSA_NAMEs. + * tree.h (SSA_NAME_IS_DEFAULT_DEF): Define. Update all users + that used to call gimple_default_def. + * tree-ssa-operands.c (push_stmt_changes): New. + (pop_stmt_changes): New. Update every pass that modifies + statements to bracket modifications with + push_stmt_changes/pop_stmt_changes. + (discard_stmt_changes): New. + * tree-ssa-dom.c (stmts_to_rescan): Change to stack of + 'tree *' instead of 'tree'. Update all users. + * tree-flow-inline.h (zero_imm_uses_p): New. + (symbol_mem_tag): New. Update every function that used + to access the annotation directly. + (set_symbol_mem_tag): Likewise. + * tree-dfa.c (dump_variable): Always show the escape mask. + (mark_symbols_for_renaming): Rename from + mark_new_vars_to_rename. Update all users. + Only mark to rename naked symbols in real and virtual + operands. + 2006-12-11 Andreas Schwab <schwab@suse.de> * varasm.c (elf_record_gcc_switches): Cast second argument of diff --git a/gcc/passes.c b/gcc/passes.c index e5faaa464f3..8bacb08d511 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -885,6 +885,7 @@ execute_one_pass (struct tree_opt_pass *pass) free ((char *) dump_file_name); dump_file_name = NULL; } + if (dump_file) { dump_end (pass->static_pass_number, dump_file); diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index f738d409d53..48893d4f214 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -1248,6 +1248,9 @@ replace_uses_by (tree name, tree val) FOR_EACH_IMM_USE_STMT (stmt, imm_iter, name) { + if (TREE_CODE (stmt) != PHI_NODE) + push_stmt_changes (&stmt); + FOR_EACH_IMM_USE_ON_STMT (use, imm_iter) { replace_exp (use, val); @@ -1265,21 +1268,25 @@ replace_uses_by (tree name, tree val) } } } + if (TREE_CODE (stmt) != PHI_NODE) { tree rhs; fold_stmt_inplace (stmt); + + /* FIXME. This should go in pop_stmt_changes. */ rhs = get_rhs (stmt); if (TREE_CODE (rhs) == ADDR_EXPR) recompute_tree_invariant_for_addr_expr (rhs); maybe_clean_or_replace_eh_stmt (stmt, stmt); - mark_new_vars_to_rename (stmt); + + pop_stmt_changes (&stmt); } } - gcc_assert (num_imm_uses (name) == 0); + gcc_assert (zero_imm_uses_p (name)); /* Also update the trees stored in loop structures. */ if (current_loops) @@ -3996,7 +4003,7 @@ tree_make_forwarder_block (edge fallthru) if (single_pred_p (bb)) return; - /* If we redirected a branch we must create new phi nodes at the + /* If we redirected a branch we must create new PHI nodes at the start of BB. */ for (phi = phi_nodes (dummy); phi; phi = PHI_CHAIN (phi)) { @@ -5684,7 +5691,7 @@ gimplify_val (block_stmt_iterator *bsi, tree type, tree exp) bsi_insert_before (bsi, new_stmt, BSI_SAME_STMT); if (gimple_in_ssa_p (cfun)) - mark_new_vars_to_rename (new_stmt); + mark_symbols_for_renaming (new_stmt); return t; } diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c index fdaaaafac93..4d60da027bb 100644 --- a/gcc/tree-data-ref.c +++ b/gcc/tree-data-ref.c @@ -149,7 +149,7 @@ ptr_decl_may_alias_p (tree ptr, tree decl, if (pi) tag = pi->name_mem_tag; if (!tag) - tag = get_var_ann (SSA_NAME_VAR (ptr))->symbol_mem_tag; + tag = symbol_mem_tag (SSA_NAME_VAR (ptr)); if (!tag) tag = DR_MEMTAG (ptr_dr); if (!tag) @@ -180,13 +180,13 @@ ptr_ptr_may_alias_p (tree ptr_a, tree ptr_b, } else { - tag_a = get_var_ann (SSA_NAME_VAR (ptr_a))->symbol_mem_tag; + tag_a = symbol_mem_tag (SSA_NAME_VAR (ptr_a)); if (!tag_a) tag_a = DR_MEMTAG (dra); if (!tag_a) return false; - tag_b = get_var_ann (SSA_NAME_VAR (ptr_b))->symbol_mem_tag; + tag_b = symbol_mem_tag (SSA_NAME_VAR (ptr_b)); if (!tag_b) tag_b = DR_MEMTAG (drb); if (!tag_b) @@ -1729,10 +1729,9 @@ object_analysis (tree memref, tree stmt, bool is_read, switch (TREE_CODE (base_address)) { case SSA_NAME: - *memtag = get_var_ann (SSA_NAME_VAR (base_address))->symbol_mem_tag; + *memtag = symbol_mem_tag (SSA_NAME_VAR (base_address)); if (!(*memtag) && TREE_CODE (TREE_OPERAND (memref, 0)) == SSA_NAME) - *memtag = get_var_ann ( - SSA_NAME_VAR (TREE_OPERAND (memref, 0)))->symbol_mem_tag; + *memtag = symbol_mem_tag (SSA_NAME_VAR (TREE_OPERAND (memref, 0))); break; case ADDR_EXPR: *memtag = TREE_OPERAND (base_address, 0); diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c index b2d09f4b031..9c7afceccab 100644 --- a/gcc/tree-dfa.c +++ b/gcc/tree-dfa.c @@ -334,33 +334,30 @@ dump_variable (FILE *file, tree var) if (is_call_clobbered (var)) { + var_ann_t va = var_ann (var); + unsigned int escape_mask = va->escape_mask; + fprintf (file, ", call clobbered"); - if (dump_flags & TDF_DETAILS) - { - var_ann_t va = var_ann (var); - unsigned int escape_mask = va->escape_mask; - - fprintf (file, " ("); - if (escape_mask & ESCAPE_STORED_IN_GLOBAL) - fprintf (file, ", stored in global"); - if (escape_mask & ESCAPE_TO_ASM) - fprintf (file, ", goes through ASM"); - if (escape_mask & ESCAPE_TO_CALL) - fprintf (file, ", passed to call"); - if (escape_mask & ESCAPE_BAD_CAST) - fprintf (file, ", bad cast"); - if (escape_mask & ESCAPE_TO_RETURN) - fprintf (file, ", returned from func"); - if (escape_mask & ESCAPE_TO_PURE_CONST) - fprintf (file, ", passed to pure/const"); - if (escape_mask & ESCAPE_IS_GLOBAL) - fprintf (file, ", is global var"); - if (escape_mask & ESCAPE_IS_PARM) - fprintf (file, ", is incoming pointer"); - if (escape_mask & ESCAPE_UNKNOWN) - fprintf (file, ", unknown escape"); - fprintf (file, " )"); - } + fprintf (file, " ("); + if (escape_mask & ESCAPE_STORED_IN_GLOBAL) + fprintf (file, ", stored in global"); + if (escape_mask & ESCAPE_TO_ASM) + fprintf (file, ", goes through ASM"); + if (escape_mask & ESCAPE_TO_CALL) + fprintf (file, ", passed to call"); + if (escape_mask & ESCAPE_BAD_CAST) + fprintf (file, ", bad cast"); + if (escape_mask & ESCAPE_TO_RETURN) + fprintf (file, ", returned from func"); + if (escape_mask & ESCAPE_TO_PURE_CONST) + fprintf (file, ", passed to pure/const"); + if (escape_mask & ESCAPE_IS_GLOBAL) + fprintf (file, ", is global var"); + if (escape_mask & ESCAPE_IS_PARM) + fprintf (file, ", is incoming pointer"); + if (escape_mask & ESCAPE_UNKNOWN) + fprintf (file, ", unknown escape"); + fprintf (file, " )"); } if (gimple_default_def (cfun, var)) @@ -688,8 +685,12 @@ set_default_def (tree var, tree def) else { h = (struct int_tree_map *) *loc; + SSA_NAME_IS_DEFAULT_DEF (h->to) = false; h->to = def; } + + /* Mark DEF as the default definition for VAR. */ + SSA_NAME_IS_DEFAULT_DEF (def) = true; } /* Add VAR to the list of referenced variables if it isn't already there. */ @@ -751,72 +752,27 @@ get_virtual_var (tree var) return var; } -/* Mark all the non-SSA variables found in STMT's operands to be - processed by update_ssa. */ +/* Mark all the naked symbols in STMT for SSA renaming. + + NOTE: This function should only be used for brand new statements. + If the caller is modifying an existing statement, it should use the + combination push_stmt_changes/pop_stmt_changes. */ void -mark_new_vars_to_rename (tree stmt) +mark_symbols_for_renaming (tree stmt) { + tree op; ssa_op_iter iter; - tree val; - bitmap vars_in_vops_to_rename; - bool found_exposed_symbol = false; - int v_may_defs_before, v_may_defs_after; - int v_must_defs_before, v_must_defs_after; - - if (TREE_CODE (stmt) == PHI_NODE) - return; - - get_stmt_ann (stmt); - vars_in_vops_to_rename = BITMAP_ALLOC (NULL); - - /* Before re-scanning the statement for operands, mark the existing - virtual operands to be renamed again. We do this because when new - symbols are exposed, the virtual operands that were here before due to - aliasing will probably be removed by the call to get_stmt_operand. - Therefore, we need to flag them to be renamed beforehand. - - We flag them in a separate bitmap because we don't really want to - rename them if there are not any newly exposed symbols in the - statement operands. */ - v_may_defs_before = NUM_SSA_OPERANDS (stmt, SSA_OP_VMAYDEF); - v_must_defs_before = NUM_SSA_OPERANDS (stmt, SSA_OP_VMUSTDEF); - FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, - SSA_OP_VMAYDEF | SSA_OP_VUSE | SSA_OP_VMUSTDEF) - { - if (!DECL_P (val)) - val = SSA_NAME_VAR (val); - bitmap_set_bit (vars_in_vops_to_rename, DECL_UID (val)); - } - - /* Now force an operand re-scan on the statement and mark any newly - exposed variables. */ update_stmt (stmt); - v_may_defs_after = NUM_SSA_OPERANDS (stmt, SSA_OP_VMAYDEF); - v_must_defs_after = NUM_SSA_OPERANDS (stmt, SSA_OP_VMUSTDEF); - - FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, SSA_OP_ALL_OPERANDS) - if (DECL_P (val)) - { - found_exposed_symbol = true; - mark_sym_for_renaming (val); - } - - /* If we found any newly exposed symbols, or if there are fewer VDEF - operands in the statement, add the variables we had set in - VARS_IN_VOPS_TO_RENAME to VARS_TO_RENAME. We need to check for - vanishing VDEFs because in those cases, the names that were formerly - generated by this statement are not going to be available anymore. */ - if (found_exposed_symbol - || v_may_defs_before > v_may_defs_after - || v_must_defs_before > v_must_defs_after) - mark_set_for_renaming (vars_in_vops_to_rename); - - BITMAP_FREE (vars_in_vops_to_rename); + /* Mark all the operands for renaming. */ + FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_ALL_OPERANDS) + if (DECL_P (op)) + mark_sym_for_renaming (op); } + /* Find all variables within the gimplified statement that were not previously visible to the function and add them to the referenced variables list. */ @@ -845,7 +801,7 @@ find_new_referenced_vars (tree *stmt_p) } -/* If REF is a handled component reference for a structure, return the +/* If EXP is a handled component reference for a structure, return the base variable. The access range is delimited by bit positions *POFFSET and *POFFSET + *PMAX_SIZE. The access size is *PSIZE bits. If either *PSIZE or *PMAX_SIZE is -1, they could not be determined. If *PSIZE diff --git a/gcc/tree-flow-inline.h b/gcc/tree-flow-inline.h index bc4c3946335..49be48e1009 100644 --- a/gcc/tree-flow-inline.h +++ b/gcc/tree-flow-inline.h @@ -587,7 +587,14 @@ num_imm_uses (tree var) return num; } - +/* Return true if VAR has no immediate uses. */ +static inline bool +zero_imm_uses_p (tree var) +{ + ssa_use_operand_t *ptr = &(SSA_NAME_IMM_USE_NODE (var)); + return (ptr == ptr->next); +} + /* Return the tree pointer to by USE. */ static inline tree get_use_from_ptr (use_operand_p use) @@ -1712,6 +1719,35 @@ overlap_subvar (unsigned HOST_WIDE_INT offset, unsigned HOST_WIDE_INT size, } +/* Return the memory tag associated with symbol SYM. */ + +static inline tree +symbol_mem_tag (tree sym) +{ + tree tag = get_var_ann (sym)->symbol_mem_tag; + +#if defined ENABLE_CHECKING + if (tag) + gcc_assert (TREE_CODE (tag) == SYMBOL_MEMORY_TAG); +#endif + + return tag; +} + + +/* Set the memory tag associated with symbol SYM. */ + +static inline void +set_symbol_mem_tag (tree sym, tree tag) +{ +#if defined ENABLE_CHECKING + if (tag) + gcc_assert (TREE_CODE (tag) == SYMBOL_MEMORY_TAG); +#endif + + get_var_ann (sym)->symbol_mem_tag = tag; +} + /* 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 returns NULL_TREE. diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index aa36ad4940d..2a547642282 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -675,7 +675,7 @@ extern void dump_subvars_for (FILE *, tree); extern void debug_subvars_for (tree); extern tree get_virtual_var (tree); extern void add_referenced_var (tree); -extern void mark_new_vars_to_rename (tree); +extern void mark_symbols_for_renaming (tree); extern void find_new_referenced_vars (tree *); extern tree make_rename_temp (tree, const char *); @@ -733,7 +733,6 @@ extern bool tree_ssa_useless_type_conversion (tree); extern bool tree_ssa_useless_type_conversion_1 (tree, tree); extern void verify_ssa (bool); extern void delete_tree_ssa (void); -extern void register_new_def (tree, VEC(tree,heap) **); extern void walk_use_def_chains (tree, walk_use_def_chains_fn, void *, bool); extern bool stmt_references_memory_p (tree); @@ -746,7 +745,7 @@ bool need_ssa_update_p (void); bool name_mappings_registered_p (void); bool name_registered_for_update_p (tree); bitmap ssa_names_to_replace (void); -void release_ssa_name_after_update_ssa (tree name); +void release_ssa_name_after_update_ssa (tree); void compute_global_livein (bitmap, bitmap); tree duplicate_ssa_name (tree, tree); void mark_sym_for_renaming (tree); @@ -906,21 +905,22 @@ extern enum move_pos movement_possibility (tree); /* The reasons a variable may escape a function. */ enum escape_type - { - NO_ESCAPE = 0, /* Doesn't escape. */ - ESCAPE_STORED_IN_GLOBAL = 1 << 1, - ESCAPE_TO_ASM = 1 << 2, /* Passed by address to an assembly - statement. */ - ESCAPE_TO_CALL = 1 << 3, /* Escapes to a function call. */ - ESCAPE_BAD_CAST = 1 << 4, /* Cast from pointer to integer */ - ESCAPE_TO_RETURN = 1 << 5, /* Returned from function. */ - ESCAPE_TO_PURE_CONST = 1 << 6, /* Escapes to a pure or constant - function call. */ - ESCAPE_IS_GLOBAL = 1 << 7, /* Is a global variable. */ - ESCAPE_IS_PARM = 1 << 8, /* Is an incoming function parameter. */ - ESCAPE_UNKNOWN = 1 << 9 /* We believe it escapes for some reason - not enumerated above. */ - }; +{ + NO_ESCAPE = 0, /* Doesn't escape. */ + ESCAPE_STORED_IN_GLOBAL = 1 << 1, + ESCAPE_TO_ASM = 1 << 2, /* Passed by address to an assembly + statement. */ + ESCAPE_TO_CALL = 1 << 3, /* Escapes to a function call. */ + ESCAPE_BAD_CAST = 1 << 4, /* Cast from pointer to integer */ + ESCAPE_TO_RETURN = 1 << 5, /* Returned from function. */ + ESCAPE_TO_PURE_CONST = 1 << 6, /* Escapes to a pure or constant + function call. */ + ESCAPE_IS_GLOBAL = 1 << 7, /* Is a global variable. */ + ESCAPE_IS_PARM = 1 << 8, /* Is an incoming function argument. */ + ESCAPE_UNKNOWN = 1 << 9 /* We believe it escapes for + some reason not enumerated + above. */ +}; /* In tree-flow-inline.h */ static inline bool is_call_clobbered (tree); diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c index 90f3dd359d3..fa71f5a5ac7 100644 --- a/gcc/tree-into-ssa.c +++ b/gcc/tree-into-ssa.c @@ -1225,7 +1225,7 @@ insert_phi_nodes (bitmap *dfs) variable (SSA_NAME_VAR (DEF)) and push VAR's current reaching definition into the stack pointed to by BLOCK_DEFS_P. */ -void +static void register_new_def (tree def, VEC(tree,heap) **block_defs_p) { tree var = SSA_NAME_VAR (def); diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c index 8197f1ac9b8..c65a31a1c0b 100644 --- a/gcc/tree-outof-ssa.c +++ b/gcc/tree-outof-ssa.c @@ -125,7 +125,7 @@ create_temp (tree t) /* add_referenced_var will create the annotation and set up some of the flags in the annotation. However, some flags we need to inherit from our original variable. */ - var_ann (tmp)->symbol_mem_tag = var_ann (t)->symbol_mem_tag; + set_symbol_mem_tag (tmp, symbol_mem_tag (t)); if (is_call_clobbered (t)) mark_call_clobbered (tmp, var_ann (t)->escape_mask); diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c index bd47befd679..9ce6f6bd2e8 100644 --- a/gcc/tree-scalar-evolution.c +++ b/gcc/tree-scalar-evolution.c @@ -1844,12 +1844,11 @@ pointer_used_p (tree ptr) imm_use_iterator imm_iter; tree stmt, rhs; struct ptr_info_def *pi = get_ptr_info (ptr); - var_ann_t v_ann = var_ann (SSA_NAME_VAR (ptr)); /* Check whether the pointer has a memory tag; if it does, it is (or at least used to be) dereferenced. */ if ((pi != NULL && pi->name_mem_tag != NULL) - || v_ann->symbol_mem_tag) + || symbol_mem_tag (SSA_NAME_VAR (ptr))) return true; FOR_EACH_IMM_USE_FAST (use_p, imm_iter, ptr) diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index 1dced722942..843e056f7c9 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -1436,9 +1436,13 @@ struct tree_opt_pass pass_ccp = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_cleanup_cfg | TODO_dump_func | TODO_update_ssa - | TODO_ggc_collect | TODO_verify_ssa - | TODO_verify_stmts | TODO_update_smt_usage, /* todo_flags_finish */ + TODO_cleanup_cfg + | TODO_dump_func + | TODO_update_ssa + | TODO_ggc_collect + | TODO_verify_ssa + | TODO_verify_stmts + | TODO_update_smt_usage, /* todo_flags_finish */ 0 /* letter */ }; @@ -1474,10 +1478,13 @@ struct tree_opt_pass pass_store_ccp = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_update_ssa - | TODO_ggc_collect | TODO_verify_ssa + TODO_dump_func + | TODO_update_ssa + | TODO_ggc_collect + | TODO_verify_ssa | TODO_cleanup_cfg - | TODO_verify_stmts | TODO_update_smt_usage, /* todo_flags_finish */ + | TODO_verify_stmts + | TODO_update_smt_usage, /* todo_flags_finish */ 0 /* letter */ }; @@ -2512,7 +2519,7 @@ convert_to_gimple_builtin (block_stmt_iterator *si_p, tree expr, bool ignore) tree new_stmt = tsi_stmt (ti); find_new_referenced_vars (tsi_stmt_ptr (ti)); bsi_insert_before (si_p, new_stmt, BSI_NEW_STMT); - mark_new_vars_to_rename (bsi_stmt (*si_p)); + mark_symbols_for_renaming (new_stmt); bsi_next (si_p); } @@ -2574,6 +2581,8 @@ execute_fold_all_builtins (void) print_generic_stmt (dump_file, *stmtp, dump_flags); } + push_stmt_changes (stmtp); + if (!set_rhs (stmtp, result)) { result = convert_to_gimple_builtin (&i, result, @@ -2582,11 +2591,12 @@ execute_fold_all_builtins (void) if (result) { bool ok = set_rhs (stmtp, result); - gcc_assert (ok); } } - mark_new_vars_to_rename (*stmtp); + + pop_stmt_changes (stmtp); + if (maybe_clean_or_replace_eh_stmt (old_stmt, *stmtp) && tree_purge_dead_eh_edges (bb)) cfg_changed = true; diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c index dcd4b86b42a..a2d8f1fecb3 100644 --- a/gcc/tree-ssa-dom.c +++ b/gcc/tree-ssa-dom.c @@ -101,7 +101,11 @@ static VEC(tree,heap) *avail_exprs_stack; expressions are removed from AVAIL_EXPRS. Else we may change the hash code for an expression and be unable to find/remove it from AVAIL_EXPRS. */ -static VEC(tree,heap) *stmts_to_rescan; +typedef tree *tree_p; +DEF_VEC_P(tree_p); +DEF_VEC_ALLOC_P(tree_p,heap); + +static VEC(tree_p,heap) *stmts_to_rescan; /* Structure for entries in the expression hash table. @@ -247,7 +251,7 @@ tree_ssa_dominator_optimize (void) avail_exprs = htab_create (1024, real_avail_expr_hash, avail_expr_eq, free); avail_exprs_stack = VEC_alloc (tree, heap, 20); const_and_copies_stack = VEC_alloc (tree, heap, 20); - stmts_to_rescan = VEC_alloc (tree, heap, 20); + stmts_to_rescan = VEC_alloc (tree_p, heap, 20); need_eh_cleanup = BITMAP_ALLOC (NULL); /* Setup callbacks for the generic dominator tree walker. */ @@ -359,7 +363,7 @@ tree_ssa_dominator_optimize (void) VEC_free (tree, heap, avail_exprs_stack); VEC_free (tree, heap, const_and_copies_stack); - VEC_free (tree, heap, stmts_to_rescan); + VEC_free (tree_p, heap, stmts_to_rescan); return 0; } @@ -701,16 +705,17 @@ dom_opt_finalize_block (struct dom_walk_data *walk_data, basic_block bb) /* If we queued any statements to rescan in this block, then go ahead and rescan them now. */ - while (VEC_length (tree, stmts_to_rescan) > 0) + while (VEC_length (tree_p, stmts_to_rescan) > 0) { - tree stmt = VEC_last (tree, stmts_to_rescan); + tree *stmt_p = VEC_last (tree_p, stmts_to_rescan); + tree stmt = *stmt_p; basic_block stmt_bb = bb_for_stmt (stmt); if (stmt_bb != bb) break; - VEC_pop (tree, stmts_to_rescan); - mark_new_vars_to_rename (stmt); + VEC_pop (tree_p, stmts_to_rescan); + pop_stmt_changes (stmt_p); } } @@ -1557,9 +1562,7 @@ eliminate_redundant_computations (tree stmt) Detect and record those equivalences. */ static void -record_equivalences_from_stmt (tree stmt, - int may_optimize_p, - stmt_ann_t ann) +record_equivalences_from_stmt (tree stmt, int may_optimize_p, stmt_ann_t ann) { tree lhs = GIMPLE_STMT_OPERAND (stmt, 0); enum tree_code lhs_code = TREE_CODE (lhs); @@ -1588,6 +1591,7 @@ record_equivalences_from_stmt (tree stmt, vops and recording the result in the available expression table, we may be able to expose more redundant loads. */ if (!ann->has_volatile_ops + && stmt_references_memory_p (stmt) && (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == SSA_NAME || is_gimple_min_invariant (GIMPLE_STMT_OPERAND (stmt, 1))) && !is_gimple_reg (lhs)) @@ -1621,7 +1625,7 @@ record_equivalences_from_stmt (tree stmt, /* Build a new statement with the RHS and LHS exchanged. */ new = build2_gimple (GIMPLE_MODIFY_STMT, rhs, lhs); - create_ssa_artficial_load_stmt (new, stmt); + create_ssa_artificial_load_stmt (new, stmt); /* Finally enter the statement into the available expression table. */ @@ -1741,7 +1745,7 @@ cprop_operand (tree stmt, use_operand_p op_p) known value for that SSA_NAME (or NULL if no value is known). Propagate values from CONST_AND_COPIES into the uses, vuses and - v_may_def_ops of STMT. */ + vdef_ops of STMT. */ static bool cprop_into_stmt (tree stmt) @@ -1793,6 +1797,7 @@ optimize_stmt (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, ann = stmt_ann (stmt); opt_stats.num_stmts++; may_have_exposed_new_symbols = false; + push_stmt_changes (bsi_stmt_ptr (si)); if (dump_file && (dump_flags & TDF_DETAILS)) { @@ -1800,7 +1805,7 @@ optimize_stmt (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, print_generic_stmt (dump_file, stmt, TDF_SLIM); } - /* Const/copy propagate into USES, VUSES and the RHS of V_MAY_DEFs. */ + /* Const/copy propagate into USES, VUSES and the RHS of VDEFs. */ may_have_exposed_new_symbols = cprop_into_stmt (stmt); /* If the statement has been modified with constant replacements, @@ -1856,9 +1861,7 @@ optimize_stmt (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, /* Record any additional equivalences created by this statement. */ if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT) - record_equivalences_from_stmt (stmt, - may_optimize_p, - ann); + record_equivalences_from_stmt (stmt, may_optimize_p, ann); /* If STMT is a COND_EXPR and it was modified, then we may know where it goes. If that is the case, then mark the CFG as altered. @@ -1885,7 +1888,6 @@ optimize_stmt (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, Ultimately I suspect we're going to need to change the interface into the SSA_NAME manager. */ - if (ann->modified) { tree val = NULL; @@ -1909,7 +1911,20 @@ optimize_stmt (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, } if (may_have_exposed_new_symbols) - VEC_safe_push (tree, heap, stmts_to_rescan, bsi_stmt (si)); + { + /* Queue the statement to be re-scanned after all the + AVAIL_EXPRS have been processed. The change buffer stack for + all the pushed statements will be processed when this queue + is emptied. */ + VEC_safe_push (tree_p, heap, stmts_to_rescan, bsi_stmt_ptr (si)); + } + else + { + /* Otherwise, just discard the recently pushed change buffer. If + not, the STMTS_TO_RESCAN queue will get out of synch with the + change buffer stack. */ + discard_stmt_changes (bsi_stmt_ptr (si)); + } } /* Search for an existing instance of STMT in the AVAIL_EXPRS table. If @@ -2185,6 +2200,8 @@ propagate_rhs_into_lhs (tree stmt, tree lhs, tree rhs, bitmap interesting_names) fprintf (dump_file, "\n"); } + push_stmt_changes (&use_stmt); + /* Propagate the RHS into this use of the LHS. */ FOR_EACH_IMM_USE_ON_STMT (use_p, iter) propagate_value (use_p, rhs); @@ -2219,6 +2236,8 @@ propagate_rhs_into_lhs (tree stmt, tree lhs, tree rhs, bitmap interesting_names) tree result = get_lhs_or_phi_result (use_stmt); bitmap_set_bit (interesting_names, SSA_NAME_VERSION (result)); } + + discard_stmt_changes (&use_stmt); continue; } @@ -2231,7 +2250,7 @@ propagate_rhs_into_lhs (tree stmt, tree lhs, tree rhs, bitmap interesting_names) /* Sometimes propagation can expose new operands to the renamer. Note this will call update_stmt at the appropriate time. */ - mark_new_vars_to_rename (use_stmt); + pop_stmt_changes (&use_stmt); /* Dump details. */ if (dump_file && (dump_flags & TDF_DETAILS)) diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index 492c9a0ada4..638224a8035 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -586,7 +586,7 @@ tidy_after_forward_propagate_addr (tree stmt) if (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == ADDR_EXPR) recompute_tree_invariant_for_addr_expr (GIMPLE_STMT_OPERAND (stmt, 1)); - mark_new_vars_to_rename (stmt); + mark_symbols_for_renaming (stmt); } /* STMT defines LHS which is contains the address of the 0th element @@ -856,9 +856,13 @@ forward_propagate_addr_expr (tree stmt, bool *some) continue; } + push_stmt_changes (&use_stmt); + result = forward_propagate_addr_expr_1 (stmt, use_stmt, some); *some |= result; all &= result; + + pop_stmt_changes (&use_stmt); } return all; @@ -1051,8 +1055,9 @@ struct tree_opt_pass pass_forwprop = { 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + TODO_dump_func | TODO_ggc_collect - | TODO_update_ssa | TODO_verify_ssa, - 0 /* letter */ + | TODO_update_ssa + | TODO_verify_ssa, /* todo_flags_finish */ + 0 /* letter */ }; diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c index ca95823f6a2..454374010aa 100644 --- a/gcc/tree-ssa-loop-ivopts.c +++ b/gcc/tree-ssa-loop-ivopts.c @@ -5556,7 +5556,7 @@ get_ref_tag (tree ref, tree orig) } var = SSA_NAME_VAR (var); - tag = var_ann (var)->symbol_mem_tag; + tag = symbol_mem_tag (var); gcc_assert (tag != NULL_TREE); return tag; } @@ -5565,7 +5565,7 @@ get_ref_tag (tree ref, tree orig) if (!DECL_P (var)) return NULL_TREE; - tag = var_ann (var)->symbol_mem_tag; + tag = symbol_mem_tag (var); if (tag) return tag; @@ -5657,9 +5657,10 @@ rewrite_use_compare (struct ivopts_data *data, /* Rewrites USE using candidate CAND. */ static void -rewrite_use (struct ivopts_data *data, - struct iv_use *use, struct iv_cand *cand) +rewrite_use (struct ivopts_data *data, struct iv_use *use, struct iv_cand *cand) { + push_stmt_changes (&use->stmt); + switch (use->type) { case USE_NONLINEAR_EXPR: @@ -5677,7 +5678,8 @@ rewrite_use (struct ivopts_data *data, default: gcc_unreachable (); } - mark_new_vars_to_rename (use->stmt); + + pop_stmt_changes (&use->stmt); } /* Rewrite the uses using the selected induction variables. */ diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c index c92c0e72a2c..cac13ebf469 100644 --- a/gcc/tree-ssa-operands.c +++ b/gcc/tree-ssa-operands.c @@ -121,6 +121,49 @@ static void get_expr_operands (tree, tree *, int); /* Number of functions with initialized ssa_operands. */ static int n_initialized = 0; +/* Statement change buffer. Data structure used to record state + information for statements. This is used to determine what needs + to be done in order to update the SSA web after a statement is + modified by a pass. If STMT is a statement that has just been + created, or needs to be folded via fold_stmt, or anything that + changes its physical structure then the pass should: + + 1- Call push_stmt_changes (&stmt) to record the current state of + STMT before any modifications are made. + + 2- Make all appropriate modifications to the statement. + + 3- Call pop_stmt_changes (&stmt) to find new symbols that + need to be put in SSA form, SSA name mappings for names that + have disappeared, recompute invariantness for address + expressions, cleanup EH information, etc. + + If it is possible to determine that the statement was not modified, + instead of calling pop_stmt_changes it is quicker to call + discard_stmt_changes to avoid the expensive and unnecessary operand + re-scan and change comparison. */ + +struct scb_d +{ + /* Pointer to the statement being modified. */ + tree *stmt_p; + + /* If the statement references memory these are the sets of symbols + loaded and stored by the statement. */ + bitmap loads; + bitmap stores; +}; + +typedef struct scb_d *scb_t; +DEF_VEC_P(scb_t); +DEF_VEC_ALLOC_P(scb_t,heap); + +/* Stack of statement change buffers (SCB). Every call to + push_stmt_changes pushes a new buffer onto the stack. Calls to + pop_stmt_changes pop a buffer off of the stack and compute the set + of changes for the popped statement. */ +static VEC(scb_t,heap) *scb_stack; + /* Allocates operand OP of given TYPE from the appropriate free list, or of the new value if the list is empty. */ @@ -2277,7 +2320,7 @@ copy_virtual_operands (tree dest, tree src) values stored. */ void -create_ssa_artficial_load_stmt (tree new_stmt, tree old_stmt) +create_ssa_artificial_load_stmt (tree new_stmt, tree old_stmt) { stmt_ann_t ann; tree op; @@ -2567,3 +2610,206 @@ debug_immediate_uses_for (tree var) { dump_immediate_uses_for (stderr, var); } + + +/* Create a new change buffer for the statement pointed by STMT_P and + push the buffer into SCB_STACK. Each change buffer + records state information needed to determine what changed in the + statement. Mainly, this keeps track of symbols that may need to be + put into SSA form, SSA name replacements and other information + needed to keep the SSA form up to date. */ + +void +push_stmt_changes (tree *stmt_p) +{ + tree stmt; + scb_t buf; + + stmt = *stmt_p; + + /* It makes no sense to keep track of PHI nodes. */ + if (TREE_CODE (stmt) == PHI_NODE) + return; + + buf = xmalloc (sizeof *buf); + memset (buf, 0, sizeof *buf); + + buf->stmt_p = stmt_p; + + if (stmt_references_memory_p (stmt)) + { + tree op; + ssa_op_iter i; + + FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_VUSE) + { + tree sym = TREE_CODE (op) == SSA_NAME ? SSA_NAME_VAR (op) : op; + if (buf->loads == NULL) + buf->loads = BITMAP_ALLOC (NULL); + bitmap_set_bit (buf->loads, DECL_UID (sym)); + } + + FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_VIRTUAL_DEFS) + { + tree sym = TREE_CODE (op) == SSA_NAME ? SSA_NAME_VAR (op) : op; + if (buf->stores == NULL) + buf->stores = BITMAP_ALLOC (NULL); + bitmap_set_bit (buf->stores, DECL_UID (sym)); + } + } + + VEC_safe_push (scb_t, heap, scb_stack, buf); +} + + +/* Given two sets S1 and S2, mark the symbols that differ in S1 and S2 + for renaming. The set to mark for renaming is (S1 & ~S2) | (S2 & ~S1). */ + +static void +mark_difference_for_renaming (bitmap s1, bitmap s2) +{ + if (s1 == NULL && s2 == NULL) + return; + + if (s1 && s2 == NULL) + mark_set_for_renaming (s1); + else if (s1 == NULL && s2) + mark_set_for_renaming (s2); + else if (!bitmap_equal_p (s1, s2)) + { + bitmap t1 = BITMAP_ALLOC (NULL); + bitmap t2 = BITMAP_ALLOC (NULL); + + bitmap_and_compl (t1, s1, s2); + bitmap_and_compl (t2, s2, s1); + bitmap_ior_into (t1, t2); + mark_set_for_renaming (t1); + + BITMAP_FREE (t1); + BITMAP_FREE (t2); + } +} + + +/* Pop the top SCB from SCB_STACK and act on the differences between + what was recorded by push_stmt_changes and the current state of + the statement. */ + +void +pop_stmt_changes (tree *stmt_p) +{ + tree op, stmt; + ssa_op_iter iter; + bitmap loads, stores; + scb_t buf; + + stmt = *stmt_p; + + /* It makes no sense to keep track of PHI nodes. */ + if (TREE_CODE (stmt) == PHI_NODE) + return; + + buf = VEC_pop (scb_t, scb_stack); + gcc_assert (stmt_p == buf->stmt_p); + + /* Force an operand re-scan on the statement and mark any newly + exposed variables. */ + update_stmt (stmt); + + /* Determine whether any memory symbols need to be renamed. If the + sets of loads and stores are different after the statement is + modified, then the affected symbols need to be renamed. + + Note that it may be possible for the statement to not reference + memory anymore, but we still need to act on the differences in + the sets of symbols. */ + loads = stores = NULL; + if (stmt_references_memory_p (stmt)) + { + tree op; + ssa_op_iter i; + + FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_VUSE) + { + tree sym = TREE_CODE (op) == SSA_NAME ? SSA_NAME_VAR (op) : op; + if (loads == NULL) + loads = BITMAP_ALLOC (NULL); + bitmap_set_bit (loads, DECL_UID (sym)); + } + + FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_VIRTUAL_DEFS) + { + tree sym = TREE_CODE (op) == SSA_NAME ? SSA_NAME_VAR (op) : op; + if (stores == NULL) + stores = BITMAP_ALLOC (NULL); + bitmap_set_bit (stores, DECL_UID (sym)); + + /* If a V_MAY_DEF turned into a V_MUST_DEF, we will keep + referencing the same symbol, but we still need to mark it + for renaming since the operand scanner stripped its + SSA_NAME. */ + if (op == sym) + mark_sym_for_renaming (sym); + } + } + + /* If LOADS is different from BUF->LOADS, the affected + symbols need to be marked for renaming. */ + mark_difference_for_renaming (loads, buf->loads); + + /* Similarly for STORES and BUF->STORES. */ + mark_difference_for_renaming (stores, buf->stores); + + /* Mark all the naked GIMPLE register operands for renaming. */ + FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_DEF|SSA_OP_USE) + if (DECL_P (op)) + mark_sym_for_renaming (op); + + /* FIXME, need to add more finalizers here. Cleanup EH info, + recompute invariants for address expressions, add + SSA replacement mappings, etc. For instance, given + testsuite/gcc.c-torture/compile/pr16808.c, we fold a statement of + the form: + + # SMT.4_20 = VDEF <SMT.4_16> + D.1576_11 = 1.0e+0; + + So, the VDEF will disappear, but instead of marking SMT.4 for + renaming it would be far more efficient to establish a + replacement mapping that would replace every reference of + SMT.4_20 with SMT.4_16. */ + + /* Free memory used by the buffer. */ + BITMAP_FREE (buf->loads); + BITMAP_FREE (buf->stores); + BITMAP_FREE (loads); + BITMAP_FREE (stores); + buf->stmt_p = NULL; + free (buf); +} + + +/* Discard the topmost change buffer from SCB_STACK. This is useful + when the caller realized that it did not actually modified the + statement. It avoids the expensive operand re-scan. */ + +void +discard_stmt_changes (tree *stmt_p) +{ + scb_t buf; + tree stmt; + + /* It makes no sense to keep track of PHI nodes. */ + stmt = *stmt_p; + if (TREE_CODE (stmt) == PHI_NODE) + return; + + buf = VEC_pop (scb_t, scb_stack); + gcc_assert (stmt_p == buf->stmt_p); + + /* Free memory used by the buffer. */ + BITMAP_FREE (buf->loads); + BITMAP_FREE (buf->stores); + buf->stmt_p = NULL; + free (buf); +} diff --git a/gcc/tree-ssa-operands.h b/gcc/tree-ssa-operands.h index aecbcdc314d..17c1f6bb8e3 100644 --- a/gcc/tree-ssa-operands.h +++ b/gcc/tree-ssa-operands.h @@ -171,7 +171,7 @@ extern void update_stmt_operands (tree); extern bool verify_imm_links (FILE *f, tree var); extern void copy_virtual_operands (tree, tree); -extern void create_ssa_artficial_load_stmt (tree, tree); +extern void create_ssa_artificial_load_stmt (tree, tree); extern void dump_immediate_uses (FILE *file); extern void dump_immediate_uses_for (FILE *file, tree var); @@ -181,6 +181,9 @@ extern void debug_immediate_uses_for (tree var); extern bool ssa_operands_active (void); extern void add_to_addressable_set (tree, bitmap *); +extern void push_stmt_changes (tree *); +extern void pop_stmt_changes (tree *); +extern void discard_stmt_changes (tree *); enum ssa_op_iter_type { ssa_op_iter_none = 0, diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index c0c5d5eabfd..24274619914 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -2616,7 +2616,7 @@ create_expression_by_pieces (basic_block block, tree expr, tree stmts) vn_add (forcedname, val); bitmap_value_replace_in_set (NEW_SETS (block), forcedname); bitmap_value_replace_in_set (AVAIL_OUT (block), forcedname); - mark_new_vars_to_rename (stmt); + mark_symbols_for_renaming (stmt); } tsi = tsi_last (stmts); tsi_link_after (&tsi, forced_stmts, TSI_CONTINUE_LINKING); @@ -2644,7 +2644,9 @@ create_expression_by_pieces (basic_block block, tree expr, tree stmts) tsi = tsi_last (stmts); tsi_link_after (&tsi, newexpr, TSI_CONTINUE_LINKING); VEC_safe_push (tree, heap, inserted_exprs, newexpr); - mark_new_vars_to_rename (newexpr); + + /* All the symbols in NEWEXPR should be put into SSA form. */ + mark_symbols_for_renaming (newexpr); /* Add a value handle to the temporary. The value may already exist in either NEW_SETS, or AVAIL_OUT, because @@ -3543,7 +3545,7 @@ insert_fake_stores (void) lhs = make_ssa_name (storetemp, new); GIMPLE_STMT_OPERAND (new, 0) = lhs; - create_ssa_artficial_load_stmt (new, stmt); + create_ssa_artificial_load_stmt (new, stmt); NECESSARY (new) = 0; VEC_safe_push (tree, heap, inserted_exprs, new); diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c index b787aae70ba..49277a037c2 100644 --- a/gcc/tree-ssa-propagate.c +++ b/gcc/tree-ssa-propagate.c @@ -1176,6 +1176,9 @@ substitute_and_fold (prop_value_t *prop_value, bool use_ranges_p) && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == ASSERT_EXPR) continue; + /* Record the state of the statement before replacements. */ + push_stmt_changes (bsi_stmt_ptr (i)); + /* Replace the statement with its folded version and mark it folded. */ did_replace = false; @@ -1211,10 +1214,6 @@ substitute_and_fold (prop_value_t *prop_value, bool use_ranges_p) fold_stmt (bsi_stmt_ptr (i)); stmt = bsi_stmt (i); - /* If we folded a builtin function, we'll likely - need to rename VDEFs. */ - mark_new_vars_to_rename (stmt); - /* If we cleaned up EH information from the statement, remove EH edges. */ if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt)) @@ -1232,6 +1231,14 @@ substitute_and_fold (prop_value_t *prop_value, bool use_ranges_p) print_generic_stmt (dump_file, stmt, TDF_SLIM); fprintf (dump_file, "\n"); } + + /* Determine what needs to be done to update the SSA form. */ + pop_stmt_changes (bsi_stmt_ptr (i)); + } + else + { + /* The statement was not modified, discard the change buffer. */ + discard_stmt_changes (bsi_stmt_ptr (i)); } /* Some statements may be simplified using ranges. For @@ -1242,7 +1249,6 @@ substitute_and_fold (prop_value_t *prop_value, bool use_ranges_p) statement. */ if (use_ranges_p) simplify_stmt_using_ranges (stmt); - } } diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index 17c4c6f4a52..5e782615072 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -264,7 +264,7 @@ get_rank (tree e) int i; if (TREE_CODE (SSA_NAME_VAR (e)) == PARM_DECL - && e == gimple_default_def (cfun, SSA_NAME_VAR (e))) + && SSA_NAME_IS_DEFAULT_DEF (e)) return find_operand_rank (e)->rank; stmt = SSA_NAME_DEF_STMT (e); diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c index a8716dad8d1..5404edded82 100644 --- a/gcc/tree-ssanames.c +++ b/gcc/tree-ssanames.c @@ -152,6 +152,7 @@ make_ssa_name (tree var, tree stmt) SSA_NAME_DEF_STMT (t) = stmt; SSA_NAME_PTR_INFO (t) = NULL; SSA_NAME_IN_FREE_LIST (t) = 0; + SSA_NAME_IS_DEFAULT_DEF (t) = 0; imm = &(SSA_NAME_IMM_USE_NODE (t)); imm->use = NULL; imm->prev = imm; @@ -178,7 +179,7 @@ release_ssa_name (tree var) /* Never release the default definition for a symbol. It's a special SSA name that should always exist once it's created. */ - if (var == gimple_default_def (cfun, SSA_NAME_VAR (var))) + if (SSA_NAME_IS_DEFAULT_DEF (var)) return; /* If VAR has been registered for SSA updating, don't remove it. diff --git a/gcc/tree-vect-transform.c b/gcc/tree-vect-transform.c index 56c7adee0f3..d1caf5c92eb 100644 --- a/gcc/tree-vect-transform.c +++ b/gcc/tree-vect-transform.c @@ -3162,7 +3162,7 @@ vect_permute_load_chain (VEC(tree,heap) *dr_chain, data_ref = make_ssa_name (perm_dest, perm_stmt); GIMPLE_STMT_OPERAND (perm_stmt, 0) = data_ref; vect_finish_stmt_generation (stmt, perm_stmt, bsi); - mark_new_vars_to_rename (perm_stmt); + mark_symbols_for_renaming (perm_stmt); VEC_replace (tree, *result_chain, j/2, data_ref); @@ -3176,7 +3176,7 @@ vect_permute_load_chain (VEC(tree,heap) *dr_chain, data_ref = make_ssa_name (perm_dest, perm_stmt); GIMPLE_STMT_OPERAND (perm_stmt, 0) = data_ref; vect_finish_stmt_generation (stmt, perm_stmt, bsi); - mark_new_vars_to_rename (perm_stmt); + mark_symbols_for_renaming (perm_stmt); VEC_replace (tree, *result_chain, j/2+length/2, data_ref); } @@ -3540,7 +3540,7 @@ vectorizable_load (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt) GIMPLE_STMT_OPERAND (new_stmt, 0) = new_temp; vect_finish_stmt_generation (stmt, new_stmt, bsi); copy_virtual_operands (new_stmt, stmt); - mark_new_vars_to_rename (new_stmt); + mark_symbols_for_renaming (new_stmt); /* 3. Handle explicit realignment if necessary/supported. */ if (alignment_support_cheme == dr_unaligned_software_pipeline) diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 8e9d3cad7a5..483607ec554 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -273,7 +273,7 @@ get_value_range (tree var) /* If VAR is a default definition, the variable can take any value in VAR's type. */ sym = SSA_NAME_VAR (var); - if (var == gimple_default_def (cfun, sym)) + if (SSA_NAME_IS_DEFAULT_DEF (var)) { /* Try to use the "nonnull" attribute to create ~[0, 0] anti-ranges for pointers. Note that this is only valid with diff --git a/gcc/tree.c b/gcc/tree.c index 2c6f3b855b0..614de7aab78 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -7306,6 +7306,9 @@ is_global_var (tree t) bool needs_to_live_in_memory (tree t) { + if (TREE_CODE (t) == SSA_NAME) + t = SSA_NAME_VAR (t); + return (TREE_ADDRESSABLE (t) || is_global_var (t) || (TREE_CODE (t) == RESULT_DECL diff --git a/gcc/tree.h b/gcc/tree.h index 6a000edce83..a6515517f9b 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -1762,6 +1762,14 @@ struct tree_exp GTY(()) #define SSA_NAME_IN_FREE_LIST(NODE) \ SSA_NAME_CHECK (NODE)->base.nothrow_flag +/* Nonzero if this SSA_NAME is the default definition for the + underlying symbol. A default SSA name is created for symbol S if + the very first reference to S in the function is a read operation. + Default definitions are always created by an empty statement and + belong to no basic block. */ +#define SSA_NAME_IS_DEFAULT_DEF(NODE) \ + SSA_NAME_CHECK (NODE)->base.volatile_flag + /* Attributes for SSA_NAMEs for pointer-type variables. */ #define SSA_NAME_PTR_INFO(N) \ SSA_NAME_CHECK (N)->ssa_name.ptr_info |