tree-flow.h (is_hidden_global_store): Remove.
2012-04-27 Richard Guenther <rguenther@suse.de> * tree-flow.h (is_hidden_global_store): Remove. * tree-ssa-sink.c (is_hidden_global_store): Likewise. * tree-ssa-alias.h (ref_may_alias_global_p): Declare. (stmt_may_clobber_global_p): Likewise. * tree-ssa-alias.c (ref_may_alias_global_p): New function. (stmt_may_clobber_global_p): Likewise. * tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Call stmt_may_clobber_global_p. * tree-ssa-dse.c (dse_possible_dead_store_p): Likewise. From-SVN: r186903
This commit is contained in:
parent
c813039daf
commit
209be55309
7 changed files with 62 additions and 77 deletions
|
@ -1,3 +1,15 @@
|
|||
2012-04-27 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
* tree-flow.h (is_hidden_global_store): Remove.
|
||||
* tree-ssa-sink.c (is_hidden_global_store): Likewise.
|
||||
* tree-ssa-alias.h (ref_may_alias_global_p): Declare.
|
||||
(stmt_may_clobber_global_p): Likewise.
|
||||
* tree-ssa-alias.c (ref_may_alias_global_p): New function.
|
||||
(stmt_may_clobber_global_p): Likewise.
|
||||
* tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Call
|
||||
stmt_may_clobber_global_p.
|
||||
* tree-ssa-dse.c (dse_possible_dead_store_p): Likewise.
|
||||
|
||||
2012-04-27 Steven Bosscher <steven@gcc.gnu.org>
|
||||
|
||||
* cfg.c (disconnect_src): Do df_mark_solutions_dirty in the right
|
||||
|
|
|
@ -795,9 +795,6 @@ extern void maybe_remove_unreachable_handlers (void);
|
|||
/* In tree-ssa-pre.c */
|
||||
void debug_value_expressions (unsigned int);
|
||||
|
||||
/* In tree-ssa-sink.c */
|
||||
bool is_hidden_global_store (gimple);
|
||||
|
||||
/* In tree-loop-linear.c */
|
||||
extern void linear_transform_loops (void);
|
||||
extern unsigned perfect_loop_nest_depth (struct loop *);
|
||||
|
|
|
@ -328,6 +328,52 @@ ptr_deref_may_alias_ref_p_1 (tree ptr, ao_ref *ref)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* Return true whether REF may refer to global memory. */
|
||||
|
||||
bool
|
||||
ref_may_alias_global_p (tree ref)
|
||||
{
|
||||
tree base = get_base_address (ref);
|
||||
if (DECL_P (base))
|
||||
return is_global_var (base);
|
||||
else if (TREE_CODE (base) == MEM_REF
|
||||
|| TREE_CODE (base) == TARGET_MEM_REF)
|
||||
return ptr_deref_may_alias_global_p (TREE_OPERAND (base, 0));
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Return true whether STMT may clobber global memory. */
|
||||
|
||||
bool
|
||||
stmt_may_clobber_global_p (gimple stmt)
|
||||
{
|
||||
tree lhs;
|
||||
|
||||
if (!gimple_vdef (stmt))
|
||||
return false;
|
||||
|
||||
/* ??? We can ask the oracle whether an artificial pointer
|
||||
dereference with a pointer with points-to information covering
|
||||
all global memory (what about non-address taken memory?) maybe
|
||||
clobbered by this call. As there is at the moment no convenient
|
||||
way of doing that without generating garbage do some manual
|
||||
checking instead.
|
||||
??? We could make a NULL ao_ref argument to the various
|
||||
predicates special, meaning any global memory. */
|
||||
|
||||
switch (gimple_code (stmt))
|
||||
{
|
||||
case GIMPLE_ASSIGN:
|
||||
lhs = gimple_assign_lhs (stmt);
|
||||
return (TREE_CODE (lhs) != SSA_NAME
|
||||
&& ref_may_alias_global_p (lhs));
|
||||
case GIMPLE_CALL:
|
||||
return true;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Dump alias information on FILE. */
|
||||
|
||||
|
|
|
@ -99,11 +99,13 @@ extern tree ao_ref_base (ao_ref *);
|
|||
extern alias_set_type ao_ref_alias_set (ao_ref *);
|
||||
extern bool ptr_deref_may_alias_global_p (tree);
|
||||
extern bool ptr_derefs_may_alias_p (tree, tree);
|
||||
extern bool ref_may_alias_global_p (tree);
|
||||
extern bool refs_may_alias_p (tree, tree);
|
||||
extern bool refs_may_alias_p_1 (ao_ref *, ao_ref *, bool);
|
||||
extern bool refs_anti_dependent_p (tree, tree);
|
||||
extern bool refs_output_dependent_p (tree, tree);
|
||||
extern bool ref_maybe_used_by_stmt_p (gimple, tree);
|
||||
extern bool stmt_may_clobber_global_p (gimple);
|
||||
extern bool stmt_may_clobber_ref_p (gimple, tree);
|
||||
extern bool stmt_may_clobber_ref_p_1 (gimple, ao_ref *);
|
||||
extern bool call_may_clobber_ref_p (gimple, tree);
|
||||
|
|
|
@ -370,7 +370,7 @@ mark_stmt_if_obviously_necessary (gimple stmt, bool aggressive)
|
|||
return;
|
||||
}
|
||||
|
||||
if (is_hidden_global_store (stmt))
|
||||
if (stmt_may_clobber_global_p (stmt))
|
||||
{
|
||||
mark_stmt_necessary (stmt, true);
|
||||
return;
|
||||
|
|
|
@ -169,7 +169,7 @@ dse_possible_dead_store_p (gimple stmt, gimple *use_stmt)
|
|||
just pretend the stmt makes itself dead. Otherwise fail. */
|
||||
if (!temp)
|
||||
{
|
||||
if (is_hidden_global_store (stmt))
|
||||
if (stmt_may_clobber_global_p (stmt))
|
||||
return false;
|
||||
|
||||
temp = stmt;
|
||||
|
|
|
@ -132,78 +132,6 @@ all_immediate_uses_same_place (gimple stmt)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* Some global stores don't necessarily have VDEF's of global variables,
|
||||
but we still must avoid moving them around. */
|
||||
|
||||
bool
|
||||
is_hidden_global_store (gimple stmt)
|
||||
{
|
||||
/* Check virtual definitions. If we get here, the only virtual
|
||||
definitions we should see are those generated by assignment or call
|
||||
statements. */
|
||||
if (gimple_vdef (stmt))
|
||||
{
|
||||
tree lhs;
|
||||
|
||||
gcc_assert (is_gimple_assign (stmt) || is_gimple_call (stmt));
|
||||
|
||||
/* Note that we must not check the individual virtual operands
|
||||
here. In particular, if this is an aliased store, we could
|
||||
end up with something like the following (SSA notation
|
||||
redacted for brevity):
|
||||
|
||||
foo (int *p, int i)
|
||||
{
|
||||
int x;
|
||||
p_1 = (i_2 > 3) ? &x : p;
|
||||
|
||||
# x_4 = VDEF <x_3>
|
||||
*p_1 = 5;
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
Notice that the store to '*p_1' should be preserved, if we
|
||||
were to check the virtual definitions in that store, we would
|
||||
not mark it needed. This is because 'x' is not a global
|
||||
variable.
|
||||
|
||||
Therefore, we check the base address of the LHS. If the
|
||||
address is a pointer, we check if its name tag or symbol tag is
|
||||
a global variable. Otherwise, we check if the base variable
|
||||
is a global. */
|
||||
lhs = gimple_get_lhs (stmt);
|
||||
|
||||
if (REFERENCE_CLASS_P (lhs))
|
||||
lhs = get_base_address (lhs);
|
||||
|
||||
if (lhs == NULL_TREE)
|
||||
{
|
||||
/* If LHS is NULL, it means that we couldn't get the base
|
||||
address of the reference. In which case, we should not
|
||||
move this store. */
|
||||
return true;
|
||||
}
|
||||
else if (DECL_P (lhs))
|
||||
{
|
||||
/* If the store is to a global symbol, we need to keep it. */
|
||||
if (is_global_var (lhs))
|
||||
return true;
|
||||
|
||||
}
|
||||
else if (INDIRECT_REF_P (lhs)
|
||||
|| TREE_CODE (lhs) == MEM_REF
|
||||
|| TREE_CODE (lhs) == TARGET_MEM_REF)
|
||||
return ptr_deref_may_alias_global_p (TREE_OPERAND (lhs, 0));
|
||||
else if (CONSTANT_CLASS_P (lhs))
|
||||
return true;
|
||||
else
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Find the nearest common dominator of all of the immediate uses in IMM. */
|
||||
|
||||
static basic_block
|
||||
|
|
Loading…
Add table
Reference in a new issue