Commit d16a5e36 by Daniel Berlin Committed by Daniel Berlin

tree-ssa-operands.h (ssa_call_clobbered_cache_valid): Remove.

2006-01-16  Daniel Berlin  <dberlin@dberlin.org>

	* tree-ssa-operands.h (ssa_call_clobbered_cache_valid): Remove.
	(ssa_ro_call_cache_valid): Ditto.
	* tree-ssa-alias.c (sort_tags_by_id): New function.
	(init_transitive_clobber_worklist): Ditto.
	(add_to_worklist): Ditto.
	(mark_aliases_call_clobbered): Ditto.
	(compute_tag_properties): Ditto.
	(set_initial_properties): Ditto.
	(compute_call_clobbered): Ditto.
	(compute_may_aliases):	Call compute_call_clobbered and grouping.
	(compute_flow_sensitive_aliasing): Remove clobbering related code.
	(compute_flow_insensitive_aliasing): Grouping now happens in our
	caller.
	(setup_pointers_and_addressables): Remove clobbering related code.
	(add_may_alias): Ditto.
	(replace_may_alias): Ditto.
	(get_nmt_for): Ditto.
	(create_global_var): 
	(is_escape_site): Return an escape_type enumeration.
	* tree-flow-inline.h (is_call_clobbered):  Global var does not
	imply call clobbered.
	(mark_call_clobbered): Take a reason for marking this. Remove
	marking of globalness, and cache invalidation.
	(clear_call_clobbered): Remove cache invalidation code.
	* tree-dfa.c (dump_variable): If details is on, dump the reason
	for escaping.
	* tree-outof-ssa.c (create_temp): Copy escape mask from original
	variable. 
	* tree-flow.h (struct ptr_info_def): Add escape mask member.
	(struct var_ann_d): Ditto.
	(enum escape_type): New.
	(mark_call_clobbered): Adjust prototype.
	* tree-ssa-structalias.c (update_alias_info): Unmodifiable vars
	are never call clobbered. 
	Record reasons for escaping.
	* tree-ssa-structalias.h (is_escape_site): Update prototype.
	* tree-ssa-operands.c (ssa_call_clobbered_cache_valid): Remove.
	(ssa_ro_call_cache_valid): Ditto.
	(clobbered_v_may_defs): Ditto.
	(clobbered_vuses): Ditto.
	(ro_call_vuses): Ditto.
	(clobber_stats): New.
	(init_ssa_operands): Zero out clobber stats.
	(fini_ssa_operands): Print out clobber stats.
	(get_call_expr_operands): Pass callee fndecl to
	add_call_read_ops).
	(add_call_clobber_ops): Remove use of cache.
	Add use of PURE_CONST information.
	(add_call_read_ops): Remove use of cache.
	Add use of static not_read information.

From-SVN: r109938
parent c8db7d5c
2006-01-16 Daniel Berlin <dberlin@dberlin.org>
* tree-ssa-operands.h (ssa_call_clobbered_cache_valid): Remove.
(ssa_ro_call_cache_valid): Ditto.
* tree-ssa-alias.c (sort_tags_by_id): New function.
(init_transitive_clobber_worklist): Ditto.
(add_to_worklist): Ditto.
(mark_aliases_call_clobbered): Ditto.
(compute_tag_properties): Ditto.
(set_initial_properties): Ditto.
(compute_call_clobbered): Ditto.
(compute_may_aliases): Call compute_call_clobbered and grouping.
(compute_flow_sensitive_aliasing): Remove clobbering related code.
(compute_flow_insensitive_aliasing): Grouping now happens in our
caller.
(setup_pointers_and_addressables): Remove clobbering related code.
(add_may_alias): Ditto.
(replace_may_alias): Ditto.
(get_nmt_for): Ditto.
(create_global_var):
(is_escape_site): Return an escape_type enumeration.
* tree-flow-inline.h (is_call_clobbered): Global var does not
imply call clobbered.
(mark_call_clobbered): Take a reason for marking this. Remove
marking of globalness, and cache invalidation.
(clear_call_clobbered): Remove cache invalidation code.
* tree-dfa.c (dump_variable): If details is on, dump the reason
for escaping.
* tree-outof-ssa.c (create_temp): Copy escape mask from original
variable.
* tree-flow.h (struct ptr_info_def): Add escape mask member.
(struct var_ann_d): Ditto.
(enum escape_type): New.
(mark_call_clobbered): Adjust prototype.
* tree-ssa-structalias.c (update_alias_info): Unmodifiable vars
are never call clobbered.
Record reasons for escaping.
* tree-ssa-structalias.h (is_escape_site): Update prototype.
* tree-ssa-operands.c (ssa_call_clobbered_cache_valid): Remove.
(ssa_ro_call_cache_valid): Ditto.
(clobbered_v_may_defs): Ditto.
(clobbered_vuses): Ditto.
(ro_call_vuses): Ditto.
(clobber_stats): New.
(init_ssa_operands): Zero out clobber stats.
(fini_ssa_operands): Print out clobber stats.
(get_call_expr_operands): Pass callee fndecl to
add_call_read_ops).
(add_call_clobber_ops): Remove use of cache.
Add use of PURE_CONST information.
(add_call_read_ops): Remove use of cache.
Add use of static not_read information.
2006-01-18 Alexandre Oliva <aoliva@redhat.com> 2006-01-18 Alexandre Oliva <aoliva@redhat.com>
Introduce TLS descriptors for i386 and x86_64. Introduce TLS descriptors for i386 and x86_64.
......
2006-01-18 Daniel Berlin <dberlin@dberlin.org>
* gcc.dg/tree-ssa/pr24287.c: New test
2006-01-18 Eric Christopher <echristo@apple.com> 2006-01-18 Eric Christopher <echristo@apple.com>
* g++.dg/eh/table.C: New. * g++.dg/eh/table.C: New.
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-optimized" } */
int g1(int);
int h(int *a, int *b)__attribute__((pure));
void link_error();
/* The calls to link_error should be eliminated, since nothing escapes to
non-pure functions. */
int g(void)
{
int t = 0, t1 = 2;
int t2 = h(&t, &t1);
if (t != 0)
link_error ();
if (t1 != 2)
link_error ();
g1(t2);
if (t != 0)
link_error ();
if (t1 != 2)
link_error ();
return t2 == 2;
}
/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized"} } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
...@@ -363,7 +363,35 @@ dump_variable (FILE *file, tree var) ...@@ -363,7 +363,35 @@ dump_variable (FILE *file, tree var)
fprintf (file, ", is volatile"); fprintf (file, ", is volatile");
if (is_call_clobbered (var)) if (is_call_clobbered (var))
fprintf (file, ", call clobbered"); {
fprintf (file, ", call clobbered");
if (dump_flags & TDF_DETAILS)
{
var_ann_t va = var_ann (var);
unsigned int escape_mask = va->escape_mask;
fprintf (file, " (");
if (escape_mask & ESCAPE_STORED_IN_GLOBAL)
fprintf (file, ", stored in global");
if (escape_mask & ESCAPE_TO_ASM)
fprintf (file, ", goes through ASM");
if (escape_mask & ESCAPE_TO_CALL)
fprintf (file, ", passed to call");
if (escape_mask & ESCAPE_BAD_CAST)
fprintf (file, ", bad cast");
if (escape_mask & ESCAPE_TO_RETURN)
fprintf (file, ", returned from func");
if (escape_mask & ESCAPE_TO_PURE_CONST)
fprintf (file, ", passed to pure/const");
if (escape_mask & ESCAPE_IS_GLOBAL)
fprintf (file, ", is global var");
if (escape_mask & ESCAPE_IS_PARM)
fprintf (file, ", is incoming pointer");
if (escape_mask & ESCAPE_UNKNOWN)
fprintf (file, ", unknown escape");
fprintf (file, " )");
}
}
if (default_def (var)) if (default_def (var))
{ {
...@@ -719,15 +747,11 @@ add_referenced_var (tree var, struct walk_state *walk_state) ...@@ -719,15 +747,11 @@ add_referenced_var (tree var, struct walk_state *walk_state)
*slot = (void *) var; *slot = (void *) var;
referenced_var_insert (DECL_UID (var), var); referenced_var_insert (DECL_UID (var), var);
/* Global variables are always call-clobbered. */
if (is_global_var (var))
mark_call_clobbered (var);
/* Tag's don't have DECL_INITIAL. */ /* Tag's don't have DECL_INITIAL. */
if (MTAG_P (var)) if (MTAG_P (var))
return; return;
/* Scan DECL_INITIAL for pointer variables as they may contain /* Scan DECL_INITIAL for pointer variables as they may contain
address arithmetic referencing the address of other address arithmetic referencing the address of other
variables. */ variables. */
......
...@@ -843,34 +843,26 @@ loop_containing_stmt (tree stmt) ...@@ -843,34 +843,26 @@ loop_containing_stmt (tree stmt)
static inline bool static inline bool
is_call_clobbered (tree var) is_call_clobbered (tree var)
{ {
return is_global_var (var) return bitmap_bit_p (call_clobbered_vars, DECL_UID (var));
|| bitmap_bit_p (call_clobbered_vars, DECL_UID (var));
} }
/* Mark variable VAR as being clobbered by function calls. */ /* Mark variable VAR as being clobbered by function calls. */
static inline void static inline void
mark_call_clobbered (tree var) mark_call_clobbered (tree var, unsigned int escape_type)
{ {
/* If VAR is a memory tag, then we need to consider it a global var_ann (var)->escape_mask |= escape_type;
variable. This is because the pointer that VAR represents has
been found to point to either an arbitrary location or to a known
location in global memory. */
if (MTAG_P (var) && TREE_CODE (var) != STRUCT_FIELD_TAG)
MTAG_GLOBAL (var) = 1;
bitmap_set_bit (call_clobbered_vars, DECL_UID (var)); bitmap_set_bit (call_clobbered_vars, DECL_UID (var));
ssa_call_clobbered_cache_valid = false;
ssa_ro_call_cache_valid = false;
} }
/* Clear the call-clobbered attribute from variable VAR. */ /* Clear the call-clobbered attribute from variable VAR. */
static inline void static inline void
clear_call_clobbered (tree var) clear_call_clobbered (tree var)
{ {
var_ann_t ann = var_ann (var);
ann->escape_mask = 0;
if (MTAG_P (var) && TREE_CODE (var) != STRUCT_FIELD_TAG) if (MTAG_P (var) && TREE_CODE (var) != STRUCT_FIELD_TAG)
MTAG_GLOBAL (var) = 0; MTAG_GLOBAL (var) = 0;
bitmap_clear_bit (call_clobbered_vars, DECL_UID (var)); bitmap_clear_bit (call_clobbered_vars, DECL_UID (var));
ssa_call_clobbered_cache_valid = false;
ssa_ro_call_cache_valid = false;
} }
/* Mark variable VAR as being non-addressable. */ /* Mark variable VAR as being non-addressable. */
...@@ -879,8 +871,6 @@ mark_non_addressable (tree var) ...@@ -879,8 +871,6 @@ mark_non_addressable (tree var)
{ {
bitmap_clear_bit (call_clobbered_vars, DECL_UID (var)); bitmap_clear_bit (call_clobbered_vars, DECL_UID (var));
TREE_ADDRESSABLE (var) = 0; TREE_ADDRESSABLE (var) = 0;
ssa_call_clobbered_cache_valid = false;
ssa_ro_call_cache_valid = false;
} }
/* Return the common annotation for T. Return NULL if the annotation /* Return the common annotation for T. Return NULL if the annotation
......
...@@ -92,6 +92,9 @@ struct ptr_info_def GTY(()) ...@@ -92,6 +92,9 @@ struct ptr_info_def GTY(())
pointer will be represented by this memory tag, instead of the type pointer will be represented by this memory tag, instead of the type
tag computed by TBAA. */ tag computed by TBAA. */
tree name_mem_tag; tree name_mem_tag;
/* Mask of reasons this pointer's value escapes the function */
unsigned int escape_mask;
}; };
...@@ -213,6 +216,10 @@ struct var_ann_d GTY(()) ...@@ -213,6 +216,10 @@ struct var_ann_d GTY(())
/* If this variable is a structure, this fields holds a list of /* If this variable is a structure, this fields holds a list of
symbols representing each of the fields of the structure. */ symbols representing each of the fields of the structure. */
subvar_t subvars; subvar_t subvars;
/* Mask of values saying the reasons why this variable has escaped
the function. */
unsigned int escape_mask;
}; };
struct function_ann_d GTY(()) struct function_ann_d GTY(())
...@@ -751,9 +758,27 @@ enum move_pos ...@@ -751,9 +758,27 @@ enum move_pos
}; };
extern enum move_pos movement_possibility (tree); extern enum move_pos movement_possibility (tree);
/* The reasons a variable may escape a function. */
enum escape_type
{
NO_ESCAPE = 0, /* Doesn't escape. */
ESCAPE_STORED_IN_GLOBAL = 1 << 1,
ESCAPE_TO_ASM = 1 << 2, /* Passed by address to an assembly
statement. */
ESCAPE_TO_CALL = 1 << 3, /* Escapes to a function call. */
ESCAPE_BAD_CAST = 1 << 4, /* Cast from pointer to integer */
ESCAPE_TO_RETURN = 1 << 5, /* Returned from function. */
ESCAPE_TO_PURE_CONST = 1 << 6, /* Escapes to a pure or constant
function call. */
ESCAPE_IS_GLOBAL = 1 << 7, /* Is a global variable. */
ESCAPE_IS_PARM = 1 << 8, /* Is an incoming function parameter. */
ESCAPE_UNKNOWN = 1 << 9 /* We believe it escapes for some reason
not enumerated above. */
};
/* In tree-flow-inline.h */ /* In tree-flow-inline.h */
static inline bool is_call_clobbered (tree); static inline bool is_call_clobbered (tree);
static inline void mark_call_clobbered (tree); static inline void mark_call_clobbered (tree, unsigned int);
static inline void set_is_used (tree); static inline void set_is_used (tree);
static inline bool unmodifiable_var_p (tree); static inline bool unmodifiable_var_p (tree);
......
...@@ -177,7 +177,7 @@ create_temp (tree t) ...@@ -177,7 +177,7 @@ create_temp (tree t)
inherit from our original variable. */ inherit from our original variable. */
var_ann (tmp)->type_mem_tag = var_ann (t)->type_mem_tag; var_ann (tmp)->type_mem_tag = var_ann (t)->type_mem_tag;
if (is_call_clobbered (t)) if (is_call_clobbered (t))
mark_call_clobbered (tmp); mark_call_clobbered (tmp, var_ann (t)->escape_mask);
return tmp; return tmp;
} }
......
...@@ -165,9 +165,6 @@ extern void dump_immediate_uses_for (FILE *file, tree var); ...@@ -165,9 +165,6 @@ extern void dump_immediate_uses_for (FILE *file, tree var);
extern void debug_immediate_uses (void); extern void debug_immediate_uses (void);
extern void debug_immediate_uses_for (tree var); extern void debug_immediate_uses_for (tree var);
extern bool ssa_call_clobbered_cache_valid;
extern bool ssa_ro_call_cache_valid;
extern bool ssa_operands_active (void); extern bool ssa_operands_active (void);
extern void add_to_addressable_set (tree, bitmap *); extern void add_to_addressable_set (tree, bitmap *);
......
...@@ -2953,7 +2953,7 @@ update_alias_info (tree stmt, struct alias_info *ai) ...@@ -2953,7 +2953,7 @@ update_alias_info (tree stmt, struct alias_info *ai)
bitmap addr_taken; bitmap addr_taken;
use_operand_p use_p; use_operand_p use_p;
ssa_op_iter iter; ssa_op_iter iter;
bool stmt_escapes_p = is_escape_site (stmt, ai); enum escape_type stmt_escape_type = is_escape_site (stmt, ai);
tree op; tree op;
/* Mark all the variables whose address are taken by the statement. */ /* Mark all the variables whose address are taken by the statement. */
...@@ -2964,13 +2964,17 @@ update_alias_info (tree stmt, struct alias_info *ai) ...@@ -2964,13 +2964,17 @@ update_alias_info (tree stmt, struct alias_info *ai)
/* If STMT is an escape point, all the addresses taken by it are /* If STMT is an escape point, all the addresses taken by it are
call-clobbered. */ call-clobbered. */
if (stmt_escapes_p) if (stmt_escape_type != NO_ESCAPE)
{ {
bitmap_iterator bi; bitmap_iterator bi;
unsigned i; unsigned i;
EXECUTE_IF_SET_IN_BITMAP (addr_taken, 0, i, bi) EXECUTE_IF_SET_IN_BITMAP (addr_taken, 0, i, bi)
mark_call_clobbered (referenced_var (i)); {
tree rvar = referenced_var (i);
if (!unmodifiable_var_p (rvar))
mark_call_clobbered (rvar, stmt_escape_type);
}
} }
} }
...@@ -3094,13 +3098,14 @@ update_alias_info (tree stmt, struct alias_info *ai) ...@@ -3094,13 +3098,14 @@ update_alias_info (tree stmt, struct alias_info *ai)
bitmap_set_bit (ai->dereferenced_ptrs_load, DECL_UID (var)); bitmap_set_bit (ai->dereferenced_ptrs_load, DECL_UID (var));
} }
if (stmt_escapes_p && num_derefs < num_uses) if (stmt_escape_type != NO_ESCAPE && num_derefs < num_uses)
{ {
/* If STMT is an escape point and STMT contains at /* If STMT is an escape point and STMT contains at
least one direct use of OP, then the value of OP least one direct use of OP, then the value of OP
escapes and so the pointed-to variables need to escapes and so the pointed-to variables need to
be marked call-clobbered. */ be marked call-clobbered. */
pi->value_escapes_p = 1; pi->value_escapes_p = 1;
pi->escape_mask |= stmt_escape_type;
/* 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
......
...@@ -80,7 +80,7 @@ struct alias_info ...@@ -80,7 +80,7 @@ struct alias_info
#define NUM_REFERENCES_SET(ANN, VAL) (ANN)->common.aux = (void*) ((void *)(VAL)) #define NUM_REFERENCES_SET(ANN, VAL) (ANN)->common.aux = (void*) ((void *)(VAL))
/* In tree-ssa-alias.c. */ /* In tree-ssa-alias.c. */
bool is_escape_site (tree, struct alias_info *); enum escape_type is_escape_site (tree, struct alias_info *);
/* In tree-ssa-structalias.c. */ /* In tree-ssa-structalias.c. */
extern void compute_points_to_sets (struct alias_info *); extern void compute_points_to_sets (struct alias_info *);
......
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