#include "tree.h"
#include "varray.h"
#include "ggc.h"
+#include "tree-flow.h"
/* Rewriting a function into SSA form can create a huge number of SSA_NAMEs,
many of which may be thrown away shortly after their creation if jumps
a very well defined lifetime. If someone wants to experiment with that
this is the place to try it. */
-/* Next SSA version number to be allocated. */
-unsigned int highest_ssa_version;
+/* Array of all SSA_NAMEs used in the function. */
+varray_type ssa_names;
/* Free list of SSA_NAMEs. This list is wiped at the end of each function
after we leave SSA form. */
void
init_ssanames (void)
{
- highest_ssa_version = UNUSED_NAME_VERSION + 1;
+ VARRAY_TREE_INIT (ssa_names, 50, "ssa_names table");
+
+ /* Version 0 is special, so reserve the first slot in the table. Though
+ currently unused, we may use version 0 in alias analysis as part of
+ the heuristics used to group aliases when the alias sets are too
+ large. */
+ VARRAY_PUSH_TREE (ssa_names, NULL_TREE);
free_ssanames = NULL;
}
else
{
t = make_node (SSA_NAME);
- SSA_NAME_VERSION (t) = highest_ssa_version++;
+ SSA_NAME_VERSION (t) = num_ssa_names;
+ VARRAY_PUSH_TREE (ssa_names, t);
#ifdef GATHER_STATISTICS
ssa_name_nodes_created++;
#endif
TREE_TYPE (t) = TREE_TYPE (var);
SSA_NAME_VAR (t) = var;
SSA_NAME_DEF_STMT (t) = stmt;
+ SSA_NAME_PTR_INFO (t) = NULL;
+ SSA_NAME_IN_FREE_LIST (t) = 0;
return t;
}
+
/* We no longer need the SSA_NAME expression VAR, release it so that
it may be reused.
void
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 == var_ann (SSA_NAME_VAR (var))->default_def)
+ return;
+
/* release_ssa_name can be called multiple times on a single SSA_NAME.
However, it should only end up on our free list one time. We
keep a status bit in the SSA_NAME node itself to indicate it has
}
}
+/* Creates a duplicate of a ssa name NAME defined in statement STMT. */
+
+tree
+duplicate_ssa_name (tree name, tree stmt)
+{
+ tree new_name = make_ssa_name (SSA_NAME_VAR (name), stmt);
+ struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name);
+ struct ptr_info_def *new_ptr_info;
+
+ if (!old_ptr_info)
+ return new_name;
+
+ new_ptr_info = ggc_alloc (sizeof (struct ptr_info_def));
+ *new_ptr_info = *old_ptr_info;
+
+ if (old_ptr_info->pt_vars)
+ {
+ new_ptr_info->pt_vars = BITMAP_GGC_ALLOC ();
+ bitmap_copy (new_ptr_info->pt_vars, old_ptr_info->pt_vars);
+ }
+
+ SSA_NAME_PTR_INFO (new_name) = new_ptr_info;
+ return new_name;
+}
+
+
+/* Release all the SSA_NAMEs created by STMT. */
+
+void
+release_defs (tree stmt)
+{
+ size_t i;
+ v_may_def_optype v_may_defs;
+ v_must_def_optype v_must_defs;
+ def_optype defs;
+ stmt_ann_t ann;
+
+ ann = stmt_ann (stmt);
+ defs = DEF_OPS (ann);
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ v_must_defs = V_MUST_DEF_OPS (ann);
+
+ for (i = 0; i < NUM_DEFS (defs); i++)
+ release_ssa_name (DEF_OP (defs, i));
+
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
+ release_ssa_name (V_MAY_DEF_RESULT (v_may_defs, i));
+
+ for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+ release_ssa_name (V_MUST_DEF_OP (v_must_defs, i));
+}
+
+
+/* Replace the symbol associated with SSA_NAME with SYM. */
+
+void
+replace_ssa_name_symbol (tree ssa_name, tree sym)
+{
+ SSA_NAME_VAR (ssa_name) = sym;
+ TREE_TYPE (ssa_name) = TREE_TYPE (sym);
+}
+
#include "gt-tree-ssanames.h"