Commit 313679b0 by Diego Novillo Committed by Diego Novillo

Move SSA_NAME annotations into tree_ssa_name.

	* tree-dfa.c (create_ssa_name_ann): Remove.
	* tree-flow-inline.h (ssa_name_ann, get_ssa_name_ann): Remove.
	* tree-flow.h (enum tree_ann_type): Remove SSA_NAME_ANN.
	(struct ssa_name_ann_d): Remove.
	(union tree_ann_d): Update.
	(ssa_name_ann_t): Remove.
	* tree-ssa-alias.c: (get_ptr_info): New local function.
	Replace references to ssa_name_ann_t with struct ptr_info_def.
	* tree-ssa-operands.c (get_expr_operands): Likewise.
	* tree.h (SSA_NAME_PTR_INFO): Define.
	(struct ptr_info_def): Declare.
	(struct tree_ssa_name): Add field 'ptr_info'.

From-SVN: r82864
parent 8041d6ab
2004-06-09 Diego Novillo <dnovillo@redhat.com>
Move SSA_NAME annotations into tree_ssa_name.
* tree-dfa.c (create_ssa_name_ann): Remove.
* tree-flow-inline.h (ssa_name_ann, get_ssa_name_ann): Remove.
* tree-flow.h (enum tree_ann_type): Remove SSA_NAME_ANN.
(struct ssa_name_ann_d): Remove.
(union tree_ann_d): Update.
(ssa_name_ann_t): Remove.
* tree-ssa-alias.c: (get_ptr_info): New local function.
Replace references to ssa_name_ann_t with struct ptr_info_def.
* tree-ssa-operands.c (get_expr_operands): Likewise.
* tree.h (SSA_NAME_PTR_INFO): Define.
(struct ptr_info_def): Declare.
(struct tree_ssa_name): Add field 'ptr_info'.
2004-06-09 Danny Smith <dannysmith@users.sourceforge.net> 2004-06-09 Danny Smith <dannysmith@users.sourceforge.net>
* config/i386/winnt.c (i386_pe_output_labelref): Correct * config/i386/winnt.c (i386_pe_output_labelref): Correct
......
...@@ -462,30 +462,6 @@ create_stmt_ann (tree t) ...@@ -462,30 +462,6 @@ create_stmt_ann (tree t)
} }
/* Create a new annotation for an SSA name T. */
ssa_name_ann_t
create_ssa_name_ann (tree t)
{
ssa_name_ann_t ann;
#if defined ENABLE_CHECKING
if (t == NULL_TREE
|| (t->common.ann
&& t->common.ann->common.type != SSA_NAME_ANN))
abort ();
#endif
ann = ggc_alloc (sizeof (*ann));
memset ((void *) ann, 0, sizeof (*ann));
ann->common.type = SSA_NAME_ANN;
t->common.ann = (tree_ann) ann;
return ann;
}
/* Build a temporary. Make sure and register it to be renamed. */ /* Build a temporary. Make sure and register it to be renamed. */
tree tree
......
...@@ -64,27 +64,6 @@ get_stmt_ann (tree stmt) ...@@ -64,27 +64,6 @@ get_stmt_ann (tree stmt)
return (ann) ? ann : create_stmt_ann (stmt); return (ann) ? ann : create_stmt_ann (stmt);
} }
static inline ssa_name_ann_t
ssa_name_ann (tree t)
{
#if defined ENABLE_CHECKING
if (t == NULL_TREE
|| TREE_CODE (t) != SSA_NAME
|| (t->common.ann
&& t->common.ann->common.type != SSA_NAME_ANN))
abort ();
#endif
return (ssa_name_ann_t) t->common.ann;
}
static inline ssa_name_ann_t
get_ssa_name_ann (tree var)
{
ssa_name_ann_t ann = ssa_name_ann (var);
return (ann) ? ann : create_ssa_name_ann (var);
}
static inline enum tree_ann_type static inline enum tree_ann_type
ann_type (tree_ann ann) ann_type (tree_ann ann)
......
...@@ -40,7 +40,7 @@ typedef struct basic_block_def *basic_block; ...@@ -40,7 +40,7 @@ typedef struct basic_block_def *basic_block;
/*--------------------------------------------------------------------------- /*---------------------------------------------------------------------------
Tree annotations stored in tree_common.ann Tree annotations stored in tree_common.ann
---------------------------------------------------------------------------*/ ---------------------------------------------------------------------------*/
enum tree_ann_type { TREE_ANN_COMMON, VAR_ANN, STMT_ANN, SSA_NAME_ANN }; enum tree_ann_type { TREE_ANN_COMMON, VAR_ANN, STMT_ANN };
struct tree_ann_common_d GTY(()) struct tree_ann_common_d GTY(())
{ {
...@@ -255,50 +255,21 @@ struct stmt_ann_d GTY(()) ...@@ -255,50 +255,21 @@ struct stmt_ann_d GTY(())
}; };
struct ssa_name_ann_d GTY(())
{
struct tree_ann_common_d common;
/* Nonzero if points-to analysis couldn't determine where this pointer
is pointing to. */
unsigned int pt_anything : 1;
/* Nonzero if this pointer is the result of a call to malloc. */
unsigned int pt_malloc : 1;
/* Nonzero if the value of this pointer escapes the current function. */
unsigned int value_escapes_p : 1;
/* Set of variables that this pointer may point to. */
bitmap pt_vars;
/* If this pointer has been dereferenced, and points-to information is
more precise than type-based aliasing, indirect references to this
pointer will be represented by this memory tag, instead of the type
tag computed by TBAA. */
tree name_mem_tag;
};
union tree_ann_d GTY((desc ("ann_type ((tree_ann)&%h)"))) union tree_ann_d GTY((desc ("ann_type ((tree_ann)&%h)")))
{ {
struct tree_ann_common_d GTY((tag ("TREE_ANN_COMMON"))) common; struct tree_ann_common_d GTY((tag ("TREE_ANN_COMMON"))) common;
struct var_ann_d GTY((tag ("VAR_ANN"))) decl; struct var_ann_d GTY((tag ("VAR_ANN"))) decl;
struct stmt_ann_d GTY((tag ("STMT_ANN"))) stmt; struct stmt_ann_d GTY((tag ("STMT_ANN"))) stmt;
struct ssa_name_ann_d GTY((tag ("SSA_NAME_ANN"))) ssa_name;
}; };
typedef union tree_ann_d *tree_ann; typedef union tree_ann_d *tree_ann;
typedef struct var_ann_d *var_ann_t; typedef struct var_ann_d *var_ann_t;
typedef struct stmt_ann_d *stmt_ann_t; typedef struct stmt_ann_d *stmt_ann_t;
typedef struct ssa_name_ann_d *ssa_name_ann_t;
static inline var_ann_t var_ann (tree); static inline var_ann_t var_ann (tree);
static inline var_ann_t get_var_ann (tree); static inline var_ann_t get_var_ann (tree);
static inline stmt_ann_t stmt_ann (tree); static inline stmt_ann_t stmt_ann (tree);
static inline stmt_ann_t get_stmt_ann (tree); static inline stmt_ann_t get_stmt_ann (tree);
static inline ssa_name_ann_t ssa_name_ann (tree);
static inline ssa_name_ann_t get_ssa_name_ann (tree);
static inline enum tree_ann_type ann_type (tree_ann); static inline enum tree_ann_type ann_type (tree_ann);
static inline basic_block bb_for_stmt (tree); static inline basic_block bb_for_stmt (tree);
extern void set_bb_for_stmt (tree, basic_block); extern void set_bb_for_stmt (tree, basic_block);
...@@ -487,7 +458,6 @@ extern void dump_generic_bb (FILE *, basic_block, int, int); ...@@ -487,7 +458,6 @@ extern void dump_generic_bb (FILE *, basic_block, int, int);
/* In tree-dfa.c */ /* In tree-dfa.c */
extern var_ann_t create_var_ann (tree); extern var_ann_t create_var_ann (tree);
extern stmt_ann_t create_stmt_ann (tree); extern stmt_ann_t create_stmt_ann (tree);
extern ssa_name_ann_t create_ssa_name_ann (tree);
extern tree create_phi_node (tree, basic_block); extern tree create_phi_node (tree, basic_block);
extern void add_phi_arg (tree *, tree, edge); extern void add_phi_arg (tree *, tree, edge);
extern void remove_phi_arg (tree, basic_block); extern void remove_phi_arg (tree, basic_block);
......
...@@ -155,6 +155,7 @@ static void collect_points_to_info_for (struct alias_info *, tree); ...@@ -155,6 +155,7 @@ static void collect_points_to_info_for (struct alias_info *, tree);
static bool ptr_is_dereferenced_by (tree, tree, bool *); static bool ptr_is_dereferenced_by (tree, tree, bool *);
static void maybe_create_global_var (struct alias_info *ai); static void maybe_create_global_var (struct alias_info *ai);
static void group_aliases (struct alias_info *); static void group_aliases (struct alias_info *);
static struct ptr_info_def *get_ptr_info (tree t);
/* Global declarations. */ /* Global declarations. */
...@@ -427,7 +428,7 @@ collect_points_to_info_for (struct alias_info *ai, tree ptr) ...@@ -427,7 +428,7 @@ collect_points_to_info_for (struct alias_info *ai, tree ptr)
if (!bitmap_bit_p (ai->ssa_names_visited, SSA_NAME_VERSION (ptr))) if (!bitmap_bit_p (ai->ssa_names_visited, SSA_NAME_VERSION (ptr)))
{ {
ssa_name_ann_t ann; struct ptr_info_def *pi;
bitmap_set_bit (ai->ssa_names_visited, SSA_NAME_VERSION (ptr)); bitmap_set_bit (ai->ssa_names_visited, SSA_NAME_VERSION (ptr));
walk_use_def_chains (ptr, collect_points_to_info_r, ai); walk_use_def_chains (ptr, collect_points_to_info_r, ai);
...@@ -436,11 +437,11 @@ collect_points_to_info_for (struct alias_info *ai, tree ptr) ...@@ -436,11 +437,11 @@ collect_points_to_info_for (struct alias_info *ai, tree ptr)
/* If we could not determine where PTR was pointing to, clear all the /* If we could not determine where PTR was pointing to, clear all the
other points-to information. */ other points-to information. */
ann = ssa_name_ann (ptr); pi = SSA_NAME_PTR_INFO (ptr);
if (ann->pt_anything) if (pi->pt_anything)
{ {
ann->pt_malloc = 0; pi->pt_malloc = 0;
ann->pt_vars = NULL; pi->pt_vars = NULL;
} }
} }
} }
...@@ -559,12 +560,13 @@ compute_points_to_and_addr_escape (struct alias_info *ai) ...@@ -559,12 +560,13 @@ compute_points_to_and_addr_escape (struct alias_info *ai)
if (stmt_escapes_p) if (stmt_escapes_p)
block_ann->has_escape_site = 1; block_ann->has_escape_site = 1;
/* Special case for silly ADDR_EXPR tricks. If this /* Special case for silly ADDR_EXPR tricks
statement is an assignment to a non-pointer variable and (gcc.c-torture/unsorted/pass.c). If this statement is an
the RHS takes the address of a variable, assume that the assignment to a non-pointer variable and the RHS takes the
variable on the RHS is call-clobbered. We could add the address of a variable, assume that the variable on the RHS is
LHS to the list of "pointers" and follow it to see if it call-clobbered. We could add the LHS to the list of
really escapes, but it's not worth the pain. */ "pointers" and follow it to see if it really escapes, but it's
not worth the pain. */
if (addr_taken if (addr_taken
&& TREE_CODE (stmt) == MODIFY_EXPR && TREE_CODE (stmt) == MODIFY_EXPR
&& !POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (stmt, 0)))) && !POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (stmt, 0))))
...@@ -580,7 +582,7 @@ compute_points_to_and_addr_escape (struct alias_info *ai) ...@@ -580,7 +582,7 @@ compute_points_to_and_addr_escape (struct alias_info *ai)
{ {
tree op = USE_OP (uses, i); tree op = USE_OP (uses, i);
var_ann_t v_ann = var_ann (SSA_NAME_VAR (op)); var_ann_t v_ann = var_ann (SSA_NAME_VAR (op));
ssa_name_ann_t ptr_ann; struct ptr_info_def *pi;
bool is_store; bool is_store;
/* If the operand's variable may be aliased, keep track /* If the operand's variable may be aliased, keep track
...@@ -598,7 +600,7 @@ compute_points_to_and_addr_escape (struct alias_info *ai) ...@@ -598,7 +600,7 @@ compute_points_to_and_addr_escape (struct alias_info *ai)
collect_points_to_info_for (ai, op); collect_points_to_info_for (ai, op);
ptr_ann = ssa_name_ann (op); pi = SSA_NAME_PTR_INFO (op);
if (ptr_is_dereferenced_by (op, stmt, &is_store)) if (ptr_is_dereferenced_by (op, stmt, &is_store))
{ {
/* If we found OP to point to a set of variables or /* If we found OP to point to a set of variables or
...@@ -609,8 +611,8 @@ compute_points_to_and_addr_escape (struct alias_info *ai) ...@@ -609,8 +611,8 @@ compute_points_to_and_addr_escape (struct alias_info *ai)
FIXME: Cycles in the SSA web and the lack of SSA FIXME: Cycles in the SSA web and the lack of SSA
information for structures will prevent the creation information for structures will prevent the creation
of name tags. Find ways around this limitation. */ of name tags. Find ways around this limitation. */
if (ptr_ann->pt_malloc || ptr_ann->pt_vars) if (pi->pt_malloc || pi->pt_vars)
ptr_ann->name_mem_tag = get_nmt_for (op); pi->name_mem_tag = get_nmt_for (op);
/* Keep track of how many time we've dereferenced each /* Keep track of how many time we've dereferenced each
pointer. Again, we don't need to grow pointer. Again, we don't need to grow
...@@ -632,7 +634,7 @@ compute_points_to_and_addr_escape (struct alias_info *ai) ...@@ -632,7 +634,7 @@ compute_points_to_and_addr_escape (struct alias_info *ai)
will not escape if it is being dereferenced. That's will not escape if it is being dereferenced. That's
why we only check for escape points if OP is not why we only check for escape points if OP is not
dereferenced by STMT. */ dereferenced by STMT. */
ptr_ann->value_escapes_p = 1; pi->value_escapes_p = 1;
/* If the statement makes a function call, assume /* If the statement makes a function call, assume
that pointer OP will be dereferenced in a store that pointer OP will be dereferenced in a store
...@@ -695,15 +697,15 @@ compute_flow_sensitive_aliasing (struct alias_info *ai) ...@@ -695,15 +697,15 @@ compute_flow_sensitive_aliasing (struct alias_info *ai)
{ {
size_t j; size_t j;
tree ptr = VARRAY_TREE (ai->processed_ptrs, i); tree ptr = VARRAY_TREE (ai->processed_ptrs, i);
ssa_name_ann_t ann = ssa_name_ann (ptr); struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr);
var_ann_t v_ann = var_ann (SSA_NAME_VAR (ptr)); var_ann_t v_ann = var_ann (SSA_NAME_VAR (ptr));
if (ann->value_escapes_p || ann->pt_anything) if (pi->value_escapes_p || pi->pt_anything)
{ {
/* If PTR escapes or may point to anything, then its associated /* If PTR escapes or may point to anything, then its associated
memory tags are call-clobbered. */ memory tags are call-clobbered. */
if (ann->name_mem_tag) if (pi->name_mem_tag)
mark_call_clobbered (ann->name_mem_tag); mark_call_clobbered (pi->name_mem_tag);
if (v_ann->type_mem_tag) if (v_ann->type_mem_tag)
mark_call_clobbered (v_ann->type_mem_tag); mark_call_clobbered (v_ann->type_mem_tag);
...@@ -711,7 +713,7 @@ compute_flow_sensitive_aliasing (struct alias_info *ai) ...@@ -711,7 +713,7 @@ compute_flow_sensitive_aliasing (struct alias_info *ai)
/* If PTR may point to anything, mark call-clobbered all the /* If PTR may point to anything, mark call-clobbered all the
addressables with the same alias set as the type pointed-to by addressables with the same alias set as the type pointed-to by
PTR. */ PTR. */
if (ann->pt_anything) if (pi->pt_anything)
{ {
HOST_WIDE_INT ptr_set; HOST_WIDE_INT ptr_set;
ptr_set = get_alias_set (TREE_TYPE (TREE_TYPE (ptr))); ptr_set = get_alias_set (TREE_TYPE (TREE_TYPE (ptr)));
...@@ -730,23 +732,25 @@ compute_flow_sensitive_aliasing (struct alias_info *ai) ...@@ -730,23 +732,25 @@ compute_flow_sensitive_aliasing (struct alias_info *ai)
name memory tag, which will have been marked call-clobbered. name memory tag, which will have been marked call-clobbered.
This will in turn mark the pointed-to variables as This will in turn mark the pointed-to variables as
call-clobbered when we call add_may_alias below. */ call-clobbered when we call add_may_alias below. */
if (ann->value_escapes_p && !ann->name_mem_tag && ann->pt_vars) if (pi->value_escapes_p
EXECUTE_IF_SET_IN_BITMAP (ann->pt_vars, 0, j, && pi->name_mem_tag == NULL_TREE
&& pi->pt_vars)
EXECUTE_IF_SET_IN_BITMAP (pi->pt_vars, 0, j,
mark_call_clobbered (referenced_var (j))); mark_call_clobbered (referenced_var (j)));
} }
/* Set up aliasing information for PTR's name memory tag (if it has /* Set up aliasing information for PTR's name memory tag (if it has
one). Note that only pointers that have been dereferenced will one). Note that only pointers that have been dereferenced will
have a name memory tag. */ have a name memory tag. */
if (ann->name_mem_tag && ann->pt_vars) if (pi->name_mem_tag && pi->pt_vars)
EXECUTE_IF_SET_IN_BITMAP (ann->pt_vars, 0, j, EXECUTE_IF_SET_IN_BITMAP (pi->pt_vars, 0, j,
add_may_alias (ann->name_mem_tag, referenced_var (j))); add_may_alias (pi->name_mem_tag, referenced_var (j)));
/* If the name tag is call clobbered, so is the type tag /* If the name tag is call clobbered, so is the type tag
associated with the base VAR_DECL. */ associated with the base VAR_DECL. */
if (ann->name_mem_tag if (pi->name_mem_tag
&& v_ann->type_mem_tag && v_ann->type_mem_tag
&& is_call_clobbered (ann->name_mem_tag)) && is_call_clobbered (pi->name_mem_tag))
mark_call_clobbered (v_ann->type_mem_tag); mark_call_clobbered (v_ann->type_mem_tag);
} }
} }
...@@ -1050,7 +1054,7 @@ group_aliases (struct alias_info *ai) ...@@ -1050,7 +1054,7 @@ group_aliases (struct alias_info *ai)
{ {
size_t j; size_t j;
tree ptr = VARRAY_TREE (ai->processed_ptrs, i); tree ptr = VARRAY_TREE (ai->processed_ptrs, i);
tree name_tag = ssa_name_ann (ptr)->name_mem_tag; tree name_tag = SSA_NAME_PTR_INFO (ptr)->name_mem_tag;
varray_type aliases; varray_type aliases;
if (name_tag == NULL_TREE) if (name_tag == NULL_TREE)
...@@ -1509,30 +1513,30 @@ add_may_alias (tree var, tree alias) ...@@ -1509,30 +1513,30 @@ add_may_alias (tree var, tree alias)
static void static void
merge_pointed_to_info (struct alias_info *ai, tree dest, tree orig) merge_pointed_to_info (struct alias_info *ai, tree dest, tree orig)
{ {
ssa_name_ann_t dest_ann, orig_ann; struct ptr_info_def *dest_pi, *orig_pi;
/* Make sure we have points-to information for ORIG. */ /* Make sure we have points-to information for ORIG. */
collect_points_to_info_for (ai, orig); collect_points_to_info_for (ai, orig);
dest_ann = get_ssa_name_ann (dest); dest_pi = get_ptr_info (dest);
orig_ann = ssa_name_ann (orig); orig_pi = SSA_NAME_PTR_INFO (orig);
if (orig_ann) if (orig_pi)
{ {
dest_ann->pt_anything |= orig_ann->pt_anything; dest_pi->pt_anything |= orig_pi->pt_anything;
dest_ann->pt_malloc |= orig_ann->pt_malloc; dest_pi->pt_malloc |= orig_pi->pt_malloc;
if (orig_ann->pt_vars) if (orig_pi->pt_vars)
{ {
if (dest_ann->pt_vars == NULL) if (dest_pi->pt_vars == NULL)
{ {
dest_ann->pt_vars = BITMAP_GGC_ALLOC (); dest_pi->pt_vars = BITMAP_GGC_ALLOC ();
bitmap_copy (dest_ann->pt_vars, orig_ann->pt_vars); bitmap_copy (dest_pi->pt_vars, orig_pi->pt_vars);
} }
else else
bitmap_a_or_b (dest_ann->pt_vars, bitmap_a_or_b (dest_pi->pt_vars,
dest_ann->pt_vars, dest_pi->pt_vars,
orig_ann->pt_vars); orig_pi->pt_vars);
} }
} }
} }
...@@ -1543,7 +1547,7 @@ merge_pointed_to_info (struct alias_info *ai, tree dest, tree orig) ...@@ -1543,7 +1547,7 @@ merge_pointed_to_info (struct alias_info *ai, tree dest, tree orig)
static void static void
add_pointed_to_expr (tree ptr, tree value) add_pointed_to_expr (tree ptr, tree value)
{ {
ssa_name_ann_t ann; struct ptr_info_def *pi;
#if defined ENABLE_CHECKING #if defined ENABLE_CHECKING
/* Pointer variables should have been handled by merge_pointed_to_info. */ /* Pointer variables should have been handled by merge_pointed_to_info. */
...@@ -1552,22 +1556,22 @@ add_pointed_to_expr (tree ptr, tree value) ...@@ -1552,22 +1556,22 @@ add_pointed_to_expr (tree ptr, tree value)
abort (); abort ();
#endif #endif
ann = get_ssa_name_ann (ptr); pi = get_ptr_info (ptr);
/* If VALUE is the result of a malloc-like call, then the area pointed to /* If VALUE is the result of a malloc-like call, then the area pointed to
PTR is guaranteed to not alias with anything else. */ PTR is guaranteed to not alias with anything else. */
if (TREE_CODE (value) == CALL_EXPR if (TREE_CODE (value) == CALL_EXPR
&& (call_expr_flags (value) & (ECF_MALLOC | ECF_MAY_BE_ALLOCA))) && (call_expr_flags (value) & (ECF_MALLOC | ECF_MAY_BE_ALLOCA)))
ann->pt_malloc = 1; pi->pt_malloc = 1;
else else
ann->pt_anything = 1; pi->pt_anything = 1;
if (dump_file) if (dump_file)
{ {
fprintf (dump_file, "Pointer "); fprintf (dump_file, "Pointer ");
print_generic_expr (dump_file, ptr, dump_flags); print_generic_expr (dump_file, ptr, dump_flags);
fprintf (dump_file, " points to "); fprintf (dump_file, " points to ");
if (ann->pt_malloc) if (pi->pt_malloc)
fprintf (dump_file, "malloc space: "); fprintf (dump_file, "malloc space: ");
else else
fprintf (dump_file, "an arbitrary address: "); fprintf (dump_file, "an arbitrary address: ");
...@@ -1587,7 +1591,7 @@ add_pointed_to_var (struct alias_info *ai, tree ptr, tree value) ...@@ -1587,7 +1591,7 @@ add_pointed_to_var (struct alias_info *ai, tree ptr, tree value)
if (TREE_CODE (value) == ADDR_EXPR) if (TREE_CODE (value) == ADDR_EXPR)
{ {
tree pt_var; tree pt_var;
ssa_name_ann_t ann; struct ptr_info_def *pi;
size_t uid; size_t uid;
pt_var = TREE_OPERAND (value, 0); pt_var = TREE_OPERAND (value, 0);
...@@ -1596,11 +1600,11 @@ add_pointed_to_var (struct alias_info *ai, tree ptr, tree value) ...@@ -1596,11 +1600,11 @@ add_pointed_to_var (struct alias_info *ai, tree ptr, tree value)
if (pt_var && SSA_VAR_P (pt_var)) if (pt_var && SSA_VAR_P (pt_var))
{ {
ann = get_ssa_name_ann (ptr); pi = get_ptr_info (ptr);
uid = var_ann (pt_var)->uid; uid = var_ann (pt_var)->uid;
if (ann->pt_vars == NULL) if (pi->pt_vars == NULL)
ann->pt_vars = BITMAP_GGC_ALLOC (); pi->pt_vars = BITMAP_GGC_ALLOC ();
bitmap_set_bit (ann->pt_vars, uid); bitmap_set_bit (pi->pt_vars, uid);
bitmap_set_bit (ai->addresses_needed, uid); bitmap_set_bit (ai->addresses_needed, uid);
} }
else else
...@@ -1675,8 +1679,7 @@ collect_points_to_info_r (tree var, tree stmt, void *data) ...@@ -1675,8 +1679,7 @@ collect_points_to_info_r (tree var, tree stmt, void *data)
else if (TREE_CODE (stmt) == ASM_EXPR) else if (TREE_CODE (stmt) == ASM_EXPR)
{ {
/* Pointers defined by __asm__ statements can point anywhere. */ /* Pointers defined by __asm__ statements can point anywhere. */
ssa_name_ann_t ann = get_ssa_name_ann (var); get_ptr_info (var)->pt_anything = 1;
ann->pt_anything = 1;
} }
else if (IS_EMPTY_STMT (stmt)) else if (IS_EMPTY_STMT (stmt))
{ {
...@@ -1810,8 +1813,8 @@ create_memory_tag (tree type, bool is_type_tag) ...@@ -1810,8 +1813,8 @@ create_memory_tag (tree type, bool is_type_tag)
static tree static tree
get_nmt_for (tree ptr) get_nmt_for (tree ptr)
{ {
ssa_name_ann_t ptr_ann = ssa_name_ann (ptr); struct ptr_info_def *pi = get_ptr_info (ptr);
tree tag = ptr_ann->name_mem_tag; tree tag = pi->name_mem_tag;
if (tag == NULL_TREE) if (tag == NULL_TREE)
{ {
...@@ -1823,7 +1826,7 @@ get_nmt_for (tree ptr) ...@@ -1823,7 +1826,7 @@ get_nmt_for (tree ptr)
mark_call_clobbered (tag); mark_call_clobbered (tag);
/* Similarly, if PTR points to malloc, then TAG is a global. */ /* Similarly, if PTR points to malloc, then TAG is a global. */
if (ptr_ann->pt_malloc) if (pi->pt_malloc)
mark_call_clobbered (tag); mark_call_clobbered (tag);
} }
...@@ -1976,40 +1979,65 @@ debug_alias_info (void) ...@@ -1976,40 +1979,65 @@ debug_alias_info (void)
} }
/* Return the alias information associated with pointer T. It creates a
new instance if none existed. */
static struct ptr_info_def *
get_ptr_info (tree t)
{
struct ptr_info_def *pi;
#if defined ENABLE_CHECKING
if (!POINTER_TYPE_P (TREE_TYPE (t)))
abort ();
#endif
pi = SSA_NAME_PTR_INFO (t);
if (pi == NULL)
{
pi = ggc_alloc (sizeof (*pi));
memset ((void *)pi, 0, sizeof (*pi));
SSA_NAME_PTR_INFO (t) = pi;
}
return pi;
}
/* Dump points-to information for SSA_NAME PTR into FILE. */ /* Dump points-to information for SSA_NAME PTR into FILE. */
static void static void
dump_points_to_info_for (FILE *file, tree ptr) dump_points_to_info_for (FILE *file, tree ptr)
{ {
ssa_name_ann_t ann = ssa_name_ann (ptr); struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr);
fprintf (file, "Pointer "); fprintf (file, "Pointer ");
print_generic_expr (file, ptr, dump_flags); print_generic_expr (file, ptr, dump_flags);
if (ann == NULL) if (pi == NULL)
return; return;
if (ann->name_mem_tag) if (pi->name_mem_tag)
{ {
fprintf (file, ", name memory tag: "); fprintf (file, ", name memory tag: ");
print_generic_expr (file, ann->name_mem_tag, dump_flags); print_generic_expr (file, pi->name_mem_tag, dump_flags);
} }
if (ann->value_escapes_p) if (pi->value_escapes_p)
fprintf (file, ", its value escapes"); fprintf (file, ", its value escapes");
if (ann->pt_anything) if (pi->pt_anything)
fprintf (file, ", points-to anything"); fprintf (file, ", points-to anything");
if (ann->pt_malloc) if (pi->pt_malloc)
fprintf (file, ", points-to malloc"); fprintf (file, ", points-to malloc");
if (ann->pt_vars) if (pi->pt_vars)
{ {
unsigned ix; unsigned ix;
fprintf (file, ", points-to vars: { "); fprintf (file, ", points-to vars: { ");
EXECUTE_IF_SET_IN_BITMAP (ann->pt_vars, 0, ix, EXECUTE_IF_SET_IN_BITMAP (pi->pt_vars, 0, ix,
{ {
print_generic_expr (file, referenced_var (ix), dump_flags); print_generic_expr (file, referenced_var (ix), dump_flags);
fprintf (file, " "); fprintf (file, " ");
......
...@@ -886,16 +886,16 @@ get_expr_operands (tree stmt, tree *expr_p, int flags, voperands_t prev_vops) ...@@ -886,16 +886,16 @@ get_expr_operands (tree stmt, tree *expr_p, int flags, voperands_t prev_vops)
} }
else else
{ {
ssa_name_ann_t ptr_ann = NULL; struct ptr_info_def *pi = NULL;
/* If we have computed aliasing already, check if PTR has /* If we have computed aliasing already, check if PTR has
flow-sensitive points-to information. */ flow-sensitive points-to information. */
if (TREE_CODE (ptr) == SSA_NAME if (TREE_CODE (ptr) == SSA_NAME
&& (ptr_ann = ssa_name_ann (ptr)) != NULL && (pi = SSA_NAME_PTR_INFO (ptr)) != NULL
&& ptr_ann->name_mem_tag) && pi->name_mem_tag)
{ {
/* PTR has its own memory tag. Use it. */ /* PTR has its own memory tag. Use it. */
add_stmt_operand (&ptr_ann->name_mem_tag, stmt, flags, add_stmt_operand (&pi->name_mem_tag, stmt, flags,
prev_vops); prev_vops);
} }
else else
...@@ -910,7 +910,7 @@ get_expr_operands (tree stmt, tree *expr_p, int flags, voperands_t prev_vops) ...@@ -910,7 +910,7 @@ get_expr_operands (tree stmt, tree *expr_p, int flags, voperands_t prev_vops)
aliasing again. */ aliasing again. */
if (dump_file if (dump_file
&& TREE_CODE (ptr) == SSA_NAME && TREE_CODE (ptr) == SSA_NAME
&& ptr_ann == NULL) && pi == NULL)
{ {
fprintf (dump_file, fprintf (dump_file,
"NOTE: no flow-sensitive alias info for "); "NOTE: no flow-sensitive alias info for ");
......
...@@ -1174,12 +1174,43 @@ struct tree_exp GTY(()) ...@@ -1174,12 +1174,43 @@ struct tree_exp GTY(())
#define SSA_NAME_OCCURS_IN_ABNORMAL_PHI(NODE) \ #define SSA_NAME_OCCURS_IN_ABNORMAL_PHI(NODE) \
SSA_NAME_CHECK (NODE)->common.asm_written_flag SSA_NAME_CHECK (NODE)->common.asm_written_flag
/* Nonzero if this SSA_NAME expression is currently on the freelist of /* Nonzero if this SSA_NAME expression is currently on the free list of
SSA_NAMES. Using NOTHROW_FLAG seems reasonably safe since throwing SSA_NAMES. Using NOTHROW_FLAG seems reasonably safe since throwing
has no meaning for an SSA_NAME. */ has no meaning for an SSA_NAME. */
#define SSA_NAME_IN_FREE_LIST(NODE) \ #define SSA_NAME_IN_FREE_LIST(NODE) \
SSA_NAME_CHECK (NODE)->common.nothrow_flag SSA_NAME_CHECK (NODE)->common.nothrow_flag
/* Attributes for SSA_NAMEs for pointer-type variables. */
#define SSA_NAME_PTR_INFO(N) \
SSA_NAME_CHECK (N)->ssa_name.ptr_info
#ifndef GCC_BITMAP_H
struct bitmap_head_def;
#endif
/* Aliasing information for SSA_NAMEs representing pointer variables. */
struct ptr_info_def GTY(())
{
/* Nonzero if points-to analysis couldn't determine where this pointer
is pointing to. */
unsigned int pt_anything : 1;
/* Nonzero if this pointer is the result of a call to malloc. */
unsigned int pt_malloc : 1;
/* Nonzero if the value of this pointer escapes the current function. */
unsigned int value_escapes_p : 1;
/* Set of variables that this pointer may point to. */
struct bitmap_head_def *pt_vars;
/* If this pointer has been dereferenced, and points-to information is
more precise than type-based aliasing, indirect references to this
pointer will be represented by this memory tag, instead of the type
tag computed by TBAA. */
tree name_mem_tag;
};
struct tree_ssa_name GTY(()) struct tree_ssa_name GTY(())
{ {
struct tree_common common; struct tree_common common;
...@@ -1189,6 +1220,9 @@ struct tree_ssa_name GTY(()) ...@@ -1189,6 +1220,9 @@ struct tree_ssa_name GTY(())
/* SSA version number. */ /* SSA version number. */
unsigned int version; unsigned int version;
/* Pointer attributes used for alias analysis. */
struct ptr_info_def *ptr_info;
}; };
/* In a PHI_NODE node. */ /* In a PHI_NODE node. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment