static void eliminate_phi (edge, int, elim_graph);
static tree_live_info_p coalesce_ssa_name (var_map, int);
static void assign_vars (var_map);
-static bool replace_variable (var_map, tree *, tree *);
+static bool replace_use_variable (var_map, use_operand_p, tree *);
+static bool replace_def_variable (var_map, def_operand_p, tree *);
static void eliminate_virtual_phis (void);
static void coalesce_abnormal_edges (var_map, conflict_graph, root_var_p);
static void print_exprs (FILE *, const char *, tree, const char *, tree,
}
-/* Replace *P with whatever variable it has been rewritten to based on the
- partitions in MAP. EXPR is an optional expression vector over SSA versions
- which is used to replace *P with an expression instead of a variable.
+/* Replace use operand P with whatever variable it has been rewritten to based
+ on the partitions in MAP. EXPR is an optional expression vector over SSA
+ versions which is used to replace P with an expression instead of a variable.
If the stmt is changed, return true. */
static inline bool
-replace_variable (var_map map, tree *p, tree *expr)
+replace_use_variable (var_map map, use_operand_p p, tree *expr)
{
tree new_var;
- tree var = *p;
+ tree var = USE_FROM_PTR (p);
/* Check if we are replacing this variable with an expression. */
if (expr)
{
- int version = SSA_NAME_VERSION (*p);
+ int version = SSA_NAME_VERSION (var);
if (expr[version])
{
tree new_expr = TREE_OPERAND (expr[version], 1);
- *p = new_expr;
+ SET_USE (p, new_expr);
/* Clear the stmt's RHS, or GC might bite us. */
TREE_OPERAND (expr[version], 1) = NULL_TREE;
return true;
new_var = var_to_partition_to_var (map, var);
if (new_var)
{
- *p = new_var;
+ SET_USE (p, new_var);
+ set_is_used (new_var);
+ return true;
+ }
+ return false;
+}
+
+
+/* Replace def operand DEF_P with whatever variable it has been rewritten to
+ based on the partitions in MAP. EXPR is an optional expression vector over
+ SSA versions which is used to replace DEF_P with an expression instead of a
+ variable. If the stmt is changed, return true. */
+
+static inline bool
+replace_def_variable (var_map map, def_operand_p def_p, tree *expr)
+{
+ tree new_var;
+ tree var = DEF_FROM_PTR (def_p);
+
+ /* Check if we are replacing this variable with an expression. */
+ if (expr)
+ {
+ int version = SSA_NAME_VERSION (var);
+ if (expr[version])
+ {
+ tree new_expr = TREE_OPERAND (expr[version], 1);
+ SET_DEF (def_p, new_expr);
+ /* Clear the stmt's RHS, or GC might bite us. */
+ TREE_OPERAND (expr[version], 1) = NULL_TREE;
+ return true;
+ }
+ }
+
+ new_var = var_to_partition_to_var (map, var);
+ if (new_var)
+ {
+ SET_DEF (def_p, new_var);
set_is_used (new_var);
return true;
}
it is replaced with the RHS of the defining expression. */
-/* Dependancy list element. This can contain either a partition index or a
+/* Dependency list element. This can contain either a partition index or a
version number, depending on which list it is in. */
typedef struct value_expr_d
value_expr_p pending_dependence;
} *temp_expr_table_p;
-/* Used to indicate a dependancy on V_MAY_DEFs. */
+/* Used to indicate a dependency on V_MAY_DEFs. */
#define VIRTUAL_PARTITION(table) (table->virtual_partition)
static temp_expr_table_p new_temp_expr_table (var_map);
}
-/* Add a dependancy between the def of ssa VERSION and VAR. if VAR is
- replaceable by an expression, add a dependance each of the elements of the
+/* Add a dependency between the def of ssa VERSION and VAR. If VAR is
+ replaceable by an expression, add a dependence each of the elements of the
expression. These are contained in the pending list. TAB is the
expression table. */
version = SSA_NAME_VERSION (def);
- /* Add this expression to the dependancy list for each use partition. */
+ /* Add this expression to the dependency list for each use partition. */
for (i = 0; i < num_use_ops; i++)
{
var = USE_OP (uses, i);
value_expr_p info, tmp;
int partition;
- /* Remove this expression from its dependent lists. The partition dependance
+ /* Remove this expression from its dependent lists. The partition dependence
list is retained and transfered later to whomever uses this version. */
for (info = (value_expr_p) tab->version_info[version]; info; info = tmp)
{
abort ();
#endif
free_value_expr (tab, tmp);
- /* Only clear the bit when the dependancy list is emptied via
+ /* Only clear the bit when the dependency list is emptied via
a replacement. Otherwise kill_expr will take care of it. */
if (!(tab->partition_dep_list[partition]) && replace)
bitmap_clear_bit (tab->partition_in_use, partition);
{
value_expr_p ptr;
- /* Mark every active expr dependant on this var as not replaceable. */
+ /* Mark every active expr dependent on this var as not replaceable. */
while ((ptr = tab->partition_dep_list[partition]) != NULL)
finish_expr (tab, ptr->value, false);
}
-/* This function kills all expressions in TAB which are dependant on virtual
+/* This function kills all expressions in TAB which are dependent on virtual
DEFs. CLEAR_BIT determines whether partition_in_use gets cleared. */
static inline void
if (!ann->has_volatile_ops)
check_replaceable (tab, stmt);
- /* Free any unused dependancy lists. */
+ /* Free any unused dependency lists. */
while ((p = tab->pending_dependence))
{
tab->pending_dependence = p->next;
if (TYPE_P (t) || DECL_P (t))
*walk_subtrees = 0;
- else if (TREE_CODE (t) == ARRAY_REF)
+ else if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
{
- while ((TREE_CODE (t) == ARRAY_REF
- && is_gimple_min_invariant (TREE_OPERAND (t, 1)))
+ while (((TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
+ && is_gimple_min_invariant (TREE_OPERAND (t, 1))
+ && (!TREE_OPERAND (t, 2)
+ || is_gimple_min_invariant (TREE_OPERAND (t, 2))))
|| (TREE_CODE (t) == COMPONENT_REF
- || TREE_CODE (t) == BIT_FIELD_REF
- || TREE_CODE (t) == REALPART_EXPR
- || TREE_CODE (t) == IMAGPART_EXPR))
+ && (!TREE_OPERAND (t,2)
+ || is_gimple_min_invariant (TREE_OPERAND (t, 2))))
+ || TREE_CODE (t) == BIT_FIELD_REF
+ || TREE_CODE (t) == REALPART_EXPR
+ || TREE_CODE (t) == IMAGPART_EXPR
+ || TREE_CODE (t) == VIEW_CONVERT_EXPR
+ || TREE_CODE (t) == NOP_EXPR
+ || TREE_CODE (t) == CONVERT_EXPR)
t = TREE_OPERAND (t, 0);
- if (TREE_CODE (t) == ARRAY_REF)
+ if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
{
t = get_base_address (t);
if (t && DECL_P (t))
use_optype uses;
def_optype defs;
tree stmt = bsi_stmt (si);
- tree *use_p = NULL;
+ use_operand_p use_p;
int remove = 0, is_copy = 0;
stmt_ann_t ann;
for (i = 0; i < num_uses; i++)
{
use_p = USE_OP_PTR (uses, i);
- if (replace_variable (map, use_p, values))
+ if (replace_use_variable (map, use_p, values))
changed = true;
}
{
for (i = 0; i < num_defs; i++)
{
- tree *def_p = DEF_OP_PTR (defs, i);
+ def_operand_p def_p = DEF_OP_PTR (defs, i);
- if (replace_variable (map, def_p, NULL))
+ if (replace_def_variable (map, def_p, NULL))
changed = true;
/* If both SSA_NAMEs coalesce to the same variable,
mark the now redundant copy for removal. */
if (is_copy
&& num_uses == 1
- && use_p
- && def_p
- && (*def_p == *use_p))
+ && (DEF_FROM_PTR (def_p) == USE_OP (uses, 0)))
remove = 1;
}
if (changed)
SSA_NAME_DEF_STMT (new_name) = copy;
/* Now make the argument reference our new SSA_NAME. */
- PHI_ARG_DEF (phi, i) = new_name;
+ SET_PHI_ARG_DEF (phi, i, new_name);
/* Queue the statement for insertion. */
bsi_insert_on_edge (PHI_ARG_EDGE (phi, i), copy);