/* Copy propagation and SSA_NAME replacement support routines.
- Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to
-the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA. */
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
tree type_d = TREE_TYPE (dest);
tree type_o = TREE_TYPE (orig);
+ /* For memory partitions, copies are OK as long as the memory symbol
+ belongs to the partition. */
+ if (TREE_CODE (dest) == SSA_NAME
+ && TREE_CODE (SSA_NAME_VAR (dest)) == MEMORY_PARTITION_TAG)
+ return (TREE_CODE (orig) == SSA_NAME
+ && !is_gimple_reg (orig)
+ && (SSA_NAME_VAR (dest) == SSA_NAME_VAR (orig)
+ || bitmap_bit_p (MPT_SYMBOLS (SSA_NAME_VAR (dest)),
+ DECL_UID (SSA_NAME_VAR (orig)))));
+
+ if (TREE_CODE (orig) == SSA_NAME
+ && TREE_CODE (SSA_NAME_VAR (orig)) == MEMORY_PARTITION_TAG)
+ return (TREE_CODE (dest) == SSA_NAME
+ && !is_gimple_reg (dest)
+ && (SSA_NAME_VAR (dest) == SSA_NAME_VAR (orig)
+ || bitmap_bit_p (MPT_SYMBOLS (SSA_NAME_VAR (orig)),
+ DECL_UID (SSA_NAME_VAR (dest)))));
+
/* Do not copy between types for which we *do* need a conversion. */
- if (!tree_ssa_useless_type_conversion_1 (type_d, type_o))
+ if (!useless_type_conversion_p (type_d, type_o))
return false;
/* FIXME. GIMPLE is allowing pointer assignments and comparisons of
&& POINTER_TYPE_P (type_d)
&& POINTER_TYPE_P (type_o))
{
- tree mt_dest = var_ann (SSA_NAME_VAR (dest))->symbol_mem_tag;
- tree mt_orig = var_ann (SSA_NAME_VAR (orig))->symbol_mem_tag;
+ tree mt_dest = symbol_mem_tag (SSA_NAME_VAR (dest));
+ tree mt_orig = symbol_mem_tag (SSA_NAME_VAR (orig));
if (mt_dest && mt_orig && mt_dest != mt_orig)
return false;
- else if (!lang_hooks.types_compatible_p (type_d, type_o))
+ else if (!useless_type_conversion_p (type_d, type_o))
return false;
else if (get_alias_set (TREE_TYPE (type_d)) !=
get_alias_set (TREE_TYPE (type_o)))
return false;
+
+ /* Also verify flow-sensitive information is compatible. */
+ if (SSA_NAME_PTR_INFO (orig) && SSA_NAME_PTR_INFO (dest))
+ {
+ struct ptr_info_def *orig_ptr_info = SSA_NAME_PTR_INFO (orig);
+ struct ptr_info_def *dest_ptr_info = SSA_NAME_PTR_INFO (dest);
+
+ if (orig_ptr_info->name_mem_tag
+ && dest_ptr_info->name_mem_tag
+ && orig_ptr_info->pt_vars
+ && dest_ptr_info->pt_vars
+ && !bitmap_intersect_p (dest_ptr_info->pt_vars,
+ orig_ptr_info->pt_vars))
+ return false;
+ }
}
/* If the destination is a SSA_NAME for a virtual operand, then we have
they both share the same memory tags. */
void
-merge_alias_info (tree orig, tree new)
+merge_alias_info (tree orig_name, tree new_name)
{
- tree new_sym = SSA_NAME_VAR (new);
- tree orig_sym = SSA_NAME_VAR (orig);
+ tree new_sym = SSA_NAME_VAR (new_name);
+ tree orig_sym = SSA_NAME_VAR (orig_name);
var_ann_t new_ann = var_ann (new_sym);
var_ann_t orig_ann = var_ann (orig_sym);
- gcc_assert (POINTER_TYPE_P (TREE_TYPE (orig)));
- gcc_assert (POINTER_TYPE_P (TREE_TYPE (new)));
+ /* No merging necessary when memory partitions are involved. */
+ if (factoring_name_p (new_name))
+ {
+ gcc_assert (!is_gimple_reg (orig_sym));
+ return;
+ }
+ else if (factoring_name_p (orig_name))
+ {
+ gcc_assert (!is_gimple_reg (new_sym));
+ return;
+ }
+
+ gcc_assert (POINTER_TYPE_P (TREE_TYPE (orig_name)));
+ gcc_assert (POINTER_TYPE_P (TREE_TYPE (new_name)));
#if defined ENABLE_CHECKING
- gcc_assert (lang_hooks.types_compatible_p (TREE_TYPE (orig),
- TREE_TYPE (new)));
+ gcc_assert (useless_type_conversion_p (TREE_TYPE (orig_name),
+ TREE_TYPE (new_name)));
/* If the pointed-to alias sets are different, these two pointers
would never have the same memory tag. In this case, NEW should
Since we cannot distinguish one case from another in this
function, we can only make sure that if P_i and Q_j have
flow-sensitive information, they should be compatible. */
- if (SSA_NAME_PTR_INFO (orig) && SSA_NAME_PTR_INFO (new))
+ if (SSA_NAME_PTR_INFO (orig_name) && SSA_NAME_PTR_INFO (new_name))
{
- struct ptr_info_def *orig_ptr_info = SSA_NAME_PTR_INFO (orig);
- struct ptr_info_def *new_ptr_info = SSA_NAME_PTR_INFO (new);
+ struct ptr_info_def *orig_ptr_info = SSA_NAME_PTR_INFO (orig_name);
+ struct ptr_info_def *new_ptr_info = SSA_NAME_PTR_INFO (new_name);
/* Note that pointer NEW and ORIG may actually have different
pointed-to variables (e.g., PR 18291 represented in
if (TREE_CODE (stmt) == PHI_NODE)
return !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (stmt));
- if (TREE_CODE (stmt) != MODIFY_EXPR)
+ if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
return false;
- lhs = TREE_OPERAND (stmt, 0);
- rhs = TREE_OPERAND (stmt, 1);
+ lhs = GIMPLE_STMT_OPERAND (stmt, 0);
+ rhs = GIMPLE_STMT_OPERAND (stmt, 1);
ann = stmt_ann (stmt);
/* If the statement has volatile operands, it won't generate a
/* Evaluate the RHS of STMT. If it produces a valid copy, set the LHS
value and store the LHS into *RESULT_P. If STMT generates more
than one name (i.e., STMT is an aliased store), it is enough to
- store the first name in the V_MAY_DEF list into *RESULT_P. After
+ store the first name in the VDEF list into *RESULT_P. After
all, the names generated will be VUSEd in the same statements. */
static enum ssa_prop_result
tree lhs, rhs;
prop_value_t *rhs_val;
- lhs = TREE_OPERAND (stmt, 0);
- rhs = TREE_OPERAND (stmt, 1);
+ lhs = GIMPLE_STMT_OPERAND (stmt, 0);
+ rhs = GIMPLE_STMT_OPERAND (stmt, 1);
gcc_assert (TREE_CODE (rhs) == SSA_NAME);
}
else if (stmt_makes_single_store (stmt))
{
- /* Otherwise, set the names in V_MAY_DEF/V_MUST_DEF operands
- to be a copy of RHS. */
+ /* Otherwise, set the names in VDEF operands to be a copy
+ of RHS. */
ssa_op_iter i;
tree vdef;
bool changed;
fprintf (dump_file, "\n");
}
- if (TREE_CODE (stmt) == MODIFY_EXPR
- && TREE_CODE (TREE_OPERAND (stmt, 1)) == SSA_NAME
+ if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
+ && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == SSA_NAME
&& (do_store_copy_prop
- || TREE_CODE (TREE_OPERAND (stmt, 0)) == SSA_NAME))
+ || TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == SSA_NAME))
{
/* If the statement is a copy assignment, evaluate its RHS to
see if the lattice value of its output has changed. */
retval = copy_prop_visit_assignment (stmt, result_p);
}
- else if (TREE_CODE (stmt) == MODIFY_EXPR
- && TREE_CODE (TREE_OPERAND (stmt, 0)) == SSA_NAME
+ else if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
+ && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == SSA_NAME
&& do_store_copy_prop
&& stmt_makes_single_load (stmt))
{
if (val
&& val->mem_ref
&& is_gimple_reg (val->value)
- && operand_equal_p (val->mem_ref, TREE_OPERAND (stmt, 1), 0))
+ && operand_equal_p (val->mem_ref, GIMPLE_STMT_OPERAND (stmt, 1), 0))
{
bool changed;
- changed = set_copy_of_val (TREE_OPERAND (stmt, 0),
+ changed = set_copy_of_val (GIMPLE_STMT_OPERAND (stmt, 0),
val->value, val->mem_ref);
if (changed)
{
- *result_p = TREE_OPERAND (stmt, 0);
+ *result_p = GIMPLE_STMT_OPERAND (stmt, 0);
retval = SSA_PROP_INTERESTING;
}
else
{
basic_block bb;
- copy_of = XNEWVEC (prop_value_t, num_ssa_names);
- memset (copy_of, 0, num_ssa_names * sizeof (*copy_of));
+ copy_of = XCNEWVEC (prop_value_t, num_ssa_names);
- cached_last_copy_of = XNEWVEC (tree, num_ssa_names);
- memset (cached_last_copy_of, 0, num_ssa_names * sizeof (*cached_last_copy_of));
+ cached_last_copy_of = XCNEWVEC (tree, num_ssa_names);
FOR_EACH_BB (bb)
{
if (stmt_ends_bb_p (stmt))
DONT_SIMULATE_AGAIN (stmt) = false;
else if (stmt_may_generate_copy (stmt)
- && loop_depth_of_name (TREE_OPERAND (stmt, 1)) <= depth)
+ && loop_depth_of_name (GIMPLE_STMT_OPERAND (stmt, 1)) <= depth)
DONT_SIMULATE_AGAIN (stmt) = false;
else
DONT_SIMULATE_AGAIN (stmt) = true;
/* Set the final copy-of value for each variable by traversing the
copy-of chains. */
- tmp = XNEWVEC (prop_value_t, num_ssa_names);
- memset (tmp, 0, num_ssa_names * sizeof (*tmp));
+ tmp = XCNEWVEC (prop_value_t, num_ssa_names);
for (i = 1; i < num_ssa_names; i++)
{
tree var = ssa_name (i);
NULL, /* next */
0, /* static_pass_number */
TV_TREE_COPY_PROP, /* tv_id */
- PROP_ssa | PROP_alias | PROP_cfg, /* properties_required */
+ PROP_ssa | PROP_cfg, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */