aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDiego Novillo <dnovillo@redhat.com>2006-12-11 20:15:53 +0000
committerDiego Novillo <dnovillo@gcc.gnu.org>2006-12-11 15:15:53 -0500
commitcfaab3a92418d34e14bb0fa447c052fce9f6057b (patch)
tree79969bcc52ffc34edcced0521bbe67cd20e564f5 /gcc
parent7f46c638e6be449fcd80c08babdfaee63b70278e (diff)
downloadgcc-cfaab3a92418d34e14bb0fa447c052fce9f6057b.zip
gcc-cfaab3a92418d34e14bb0fa447c052fce9f6057b.tar.gz
gcc-cfaab3a92418d34e14bb0fa447c052fce9f6057b.tar.bz2
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/ChangeLog25
-rw-r--r--gcc/passes.c1
-rw-r--r--gcc/tree-cfg.c15
-rw-r--r--gcc/tree-data-ref.c11
-rw-r--r--gcc/tree-dfa.c124
-rw-r--r--gcc/tree-flow-inline.h38
-rw-r--r--gcc/tree-flow.h36
-rw-r--r--gcc/tree-into-ssa.c2
-rw-r--r--gcc/tree-outof-ssa.c2
-rw-r--r--gcc/tree-scalar-evolution.c3
-rw-r--r--gcc/tree-ssa-ccp.c28
-rw-r--r--gcc/tree-ssa-dom.c57
-rw-r--r--gcc/tree-ssa-forwprop.c13
-rw-r--r--gcc/tree-ssa-loop-ivopts.c12
-rw-r--r--gcc/tree-ssa-operands.c248
-rw-r--r--gcc/tree-ssa-operands.h5
-rw-r--r--gcc/tree-ssa-pre.c8
-rw-r--r--gcc/tree-ssa-propagate.c16
-rw-r--r--gcc/tree-ssa-reassoc.c2
-rw-r--r--gcc/tree-ssanames.c3
-rw-r--r--gcc/tree-vect-transform.c6
-rw-r--r--gcc/tree-vrp.c2
-rw-r--r--gcc/tree.c3
-rw-r--r--gcc/tree.h8
24 files changed, 498 insertions, 170 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3f740ee..f01ef10 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 e5faaa4..8bacb08 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 f738d40..48893d4 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 fdaaaaf..4d60da0 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 b2d09f4..9c7afce 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 bc4c394..49be48e 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 aa36ad4..2a54764 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 90f3dd3..fa71f5a 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 8197f1a..c65a31a 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 bd47bef..9ce6f6b 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 1dced72..843e056 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 dcd4b86..a2d8f1f 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 492c9a0..638224a 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 ca95823..4543740 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 c92c0e7..cac13eb 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 aecbcdc..17c1f6b 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 c0c5d5e..2427461 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 b787aae..49277a0 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 17c4c6f..5e78261 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 a8716da..5404edd 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 56c7ade..d1caf5c 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 8e9d3ca..483607e 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 2c6f3b8..614de7a 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 6a000ed..a651551 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