#include "diagnostic.h"
#include "bitmap.h"
#include "tree-flow.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
#include "tree-inline.h"
#include "varray.h"
#include "timevar.h"
/* This function will combine the partitions in MAP for VAR1 and VAR2. It
Returns the partition which represents the new partition. If the two
- partitions cannot be combined, NO_PARTITION is returned. */
+ partitions cannot be combined, NO_PARTITION is returned. */
int
var_union (var_map map, tree var1, tree var2)
}
+/* Helper function for mark_all_vars_used, called via walk_tree. */
+
+static tree
+mark_all_vars_used_1 (tree *tp, int *walk_subtrees,
+ void *data ATTRIBUTE_UNUSED)
+{
+ tree t = *tp;
+
+ /* Only need to mark VAR_DECLS; parameters and return results are not
+ eliminated as unused. */
+ if (TREE_CODE (t) == VAR_DECL)
+ set_is_used (t);
+
+ if (DECL_P (t) || TYPE_P (t))
+ *walk_subtrees = 0;
+
+ return NULL;
+}
+
+/* Mark all VAR_DECLS under *EXPR_P as used, so that they won't be
+ eliminated during the tree->rtl conversion process. */
+
+static inline void
+mark_all_vars_used (tree *expr_p)
+{
+ walk_tree (expr_p, mark_all_vars_used_1, NULL, NULL);
+}
+
/* This function looks through the program and uses FLAGS to determine what
SSA versioned variables are given entries in a new partition table. This
new partition map is returned. */
{
block_stmt_iterator bsi;
basic_block bb;
- tree *dest, *use;
+ tree dest, use;
tree stmt;
stmt_ann_t ann;
- vuse_optype vuses;
- vdef_optype vdefs;
use_optype uses;
def_optype defs;
unsigned x;
var_map map;
-#if defined ENABLE_CHECKING
+#ifdef ENABLE_CHECKING
sbitmap used_in_real_ops;
sbitmap used_in_virtual_ops;
+ vuse_optype vuses;
+ v_may_def_optype v_may_defs;
+ v_must_def_optype v_must_defs;
#endif
- map = init_var_map (highest_ssa_version + 1);
+ map = init_var_map (num_ssa_names + 1);
-#if defined ENABLE_CHECKING
+#ifdef ENABLE_CHECKING
used_in_real_ops = sbitmap_alloc (num_referenced_vars);
sbitmap_zero (used_in_real_ops);
if (flags & SSA_VAR_MAP_REF_COUNT)
{
map->ref_count
- = (int *)xmalloc (((highest_ssa_version + 1) * sizeof (int)));
- memset (map->ref_count, 0, (highest_ssa_version + 1) * sizeof (int));
+ = (int *)xmalloc (((num_ssa_names + 1) * sizeof (int)));
+ memset (map->ref_count, 0, (num_ssa_names + 1) * sizeof (int));
}
FOR_EACH_BB (bb)
{
tree phi, arg;
- for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
{
int i;
register_ssa_partition (map, PHI_RESULT (phi), false);
arg = PHI_ARG_DEF (phi, i);
if (TREE_CODE (arg) == SSA_NAME)
register_ssa_partition (map, arg, true);
+
+ mark_all_vars_used (&PHI_ARG_DEF_TREE (phi, i));
}
}
uses = USE_OPS (ann);
for (x = 0; x < NUM_USES (uses); x++)
{
- use = USE_OP_PTR (uses, x);
- register_ssa_partition (map, *use, true);
+ use = USE_OP (uses, x);
+ register_ssa_partition (map, use, true);
-#if defined ENABLE_CHECKING
- SET_BIT (used_in_real_ops, var_ann (SSA_NAME_VAR (*use))->uid);
+#ifdef ENABLE_CHECKING
+ SET_BIT (used_in_real_ops, var_ann (SSA_NAME_VAR (use))->uid);
#endif
}
defs = DEF_OPS (ann);
for (x = 0; x < NUM_DEFS (defs); x++)
{
- dest = DEF_OP_PTR (defs, x);
- register_ssa_partition (map, *dest, false);
+ dest = DEF_OP (defs, x);
+ register_ssa_partition (map, dest, false);
-#if defined ENABLE_CHECKING
- SET_BIT (used_in_real_ops, var_ann (SSA_NAME_VAR (*dest))->uid);
+#ifdef ENABLE_CHECKING
+ SET_BIT (used_in_real_ops, var_ann (SSA_NAME_VAR (dest))->uid);
#endif
}
- /* While we do not care about virtual operands for
- out of SSA, we do need to look at them to make sure
- we mark all the variables which are used. */
+#ifdef ENABLE_CHECKING
+ /* Validate that virtual ops don't get used in funny ways. */
vuses = VUSE_OPS (ann);
for (x = 0; x < NUM_VUSES (vuses); x++)
{
tree var = VUSE_OP (vuses, x);
- set_is_used (var);
-
-#if defined ENABLE_CHECKING
SET_BIT (used_in_virtual_ops, var_ann (SSA_NAME_VAR (var))->uid);
-#endif
}
- vdefs = VDEF_OPS (ann);
- for (x = 0; x < NUM_VDEFS (vdefs); x++)
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ for (x = 0; x < NUM_V_MAY_DEFS (v_may_defs); x++)
{
- tree var = VDEF_OP (vdefs, x);
- set_is_used (var);
-
-#if defined ENABLE_CHECKING
+ tree var = V_MAY_DEF_OP (v_may_defs, x);
SET_BIT (used_in_virtual_ops, var_ann (SSA_NAME_VAR (var))->uid);
-#endif
}
+
+ v_must_defs = V_MUST_DEF_OPS (ann);
+ for (x = 0; x < NUM_V_MUST_DEFS (v_must_defs); x++)
+ {
+ tree var = V_MUST_DEF_OP (v_must_defs, x);
+ SET_BIT (used_in_virtual_ops, var_ann (SSA_NAME_VAR (var))->uid);
+ }
+#endif /* ENABLE_CHECKING */
+
+ mark_all_vars_used (bsi_stmt_ptr (bsi));
}
}
basic_block bb;
bitmap saw_def;
tree phi, var, stmt;
- tree *vec;
+ tree op;
edge e;
varray_type stack;
block_stmt_iterator bsi;
- vuse_optype vuses;
- vdef_optype vdefs;
use_optype uses;
def_optype defs;
stmt_ann_t ann;
{
bitmap_clear (saw_def);
- for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
{
for (i = 0; i < PHI_NUM_ARGS (phi); i++)
{
The a_3 referred to in b_3's PHI node is the one incoming on the
edge, *not* the PHI node just seen. */
- for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
{
var = PHI_RESULT (phi);
set_if_valid (map, saw_def, var);
num = NUM_USES (uses);
for (i = 0; i < num; i++)
{
- vec = USE_OP_PTR (uses, i);
- add_livein_if_notdef (live, saw_def, *vec, bb);
- }
-
- vuses = VUSE_OPS (ann);
- num = NUM_VUSES (vuses);
- for (i = 0; i < num; i++)
- {
- var = VUSE_OP (vuses, i);
- add_livein_if_notdef (live, saw_def, var, bb);
- }
-
- vdefs = VDEF_OPS (ann);
- num = NUM_VDEFS (vdefs);
- for (i = 0; i < num; i++)
- {
- var = VDEF_OP (vdefs, i);
- add_livein_if_notdef (live, saw_def, var, bb);
+ op = USE_OP (uses, i);
+ add_livein_if_notdef (live, saw_def, op, bb);
}
defs = DEF_OPS (ann);
num = NUM_DEFS (defs);
for (i = 0; i < num; i++)
{
- vec = DEF_OP_PTR (defs, i);
- set_if_valid (map, saw_def, *vec);
- }
-
- num = NUM_VDEFS (vdefs);
- for (i = 0; i < num; i++)
- {
- var = VDEF_RESULT (vdefs, i);
- set_if_valid (map, saw_def, var);
+ op = DEF_OP (defs, i);
+ set_if_valid (map, saw_def, op);
}
}
}
int z, ok = 0;
for (phi = phi_nodes (e->dest);
phi && !ok;
- phi = TREE_CHAIN (phi))
+ phi = PHI_CHAIN (phi))
{
for (z = 0; z < PHI_NUM_ARGS (phi); z++)
if (var == PHI_ARG_DEF (phi, z))
abort ();
#endif
+ BITMAP_XFREE (saw_def);
+
return live;
}
/* Set all the live-on-exit bits for uses in PHIs. */
FOR_EACH_BB (bb)
{
- for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
for (i = 0; i < PHI_NUM_ARGS (phi); i++)
{
t = PHI_ARG_DEF (phi, i);
}
-/* This function will remove any tree entires from TPA which have only a single
+/* This function will remove any tree entries from TPA which have only a single
element. This will help keep the size of the conflict graph down. The
function returns the number of remaining tree lists. */
This is handled specially here since we may also be interested
in copies between real variables and SSA_NAME variables. We may
be interested in trying to coalesce SSA_NAME variables with
- root variables in some cases. */
+ root variables in some cases. */
if (TREE_CODE (stmt) == MODIFY_EXPR)
{
if (!is_a_copy)
{
- tree *var_p;
+ tree var;
defs = DEF_OPS (ann);
num = NUM_DEFS (defs);
for (x = 0; x < num; x++)
{
- var_p = DEF_OP_PTR (defs, x);
- add_conflicts_if_valid (tpa, graph, map, live, *var_p);
+ var = DEF_OP (defs, x);
+ add_conflicts_if_valid (tpa, graph, map, live, var);
}
uses = USE_OPS (ann);
num = NUM_USES (uses);
for (x = 0; x < num; x++)
{
- var_p = USE_OP_PTR (uses, x);
- set_if_valid (map, live, *var_p);
+ var = USE_OP (uses, x);
+ set_if_valid (map, live, var);
}
}
}
going to be translated out of SSA form we must record a conflict
between the result of the PHI and any variables with are live.
Otherwise the out-of-ssa translation may create incorrect code. */
- for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
{
tree result = PHI_RESULT (phi);
int p = var_to_partition (map, result);
/* Anything which is still live at this point interferes.
In order to implement this efficiently, only conflicts between
partitions which have the same TPA root need be added.
- TPA roots which have been seen are tracked in 'tpa_nodes'. A non-zero
+ TPA roots which have been seen are tracked in 'tpa_nodes'. A nonzero
entry points to an index into 'partition_link', which then indexes
into itself forming a linked list of partitions sharing a tpa root
which have been seen as live up to this point. Since partitions start
continue;
t = 0;
- for (y = 1; y < highest_ssa_version; y++)
+ for (y = 1; y < num_ssa_names; y++)
{
p = partition_find (map->var_partition, y);
if (map->partition_to_compact)
Note we delete PHI nodes in this loop if they are
associated with virtual vars which are going to be
- renamed. */
+ renamed. */
for (phi = phi_nodes (bb); phi; phi = next)
{
tree result = SSA_NAME_VAR (PHI_RESULT (phi));
- next = TREE_CHAIN (phi);
+ next = PHI_CHAIN (phi);
if (bitmap_bit_p (vars, var_ann (result)->uid))
{
if (! is_gimple_reg (result))