Cleanup modref interfaces.
* ipa-fnsummary.c (refs_local_or_readonly_memory_p): New function. (points_to_local_or_readonly_memory_p): New function. * ipa-fnsummary.h (refs_local_or_readonly_memory_p): Declare. (points_to_local_or_readonly_memory_p): Declare. * ipa-modref.c (record_access_p): Use refs_local_or_readonly_memory_p. * ipa-pure-const.c (check_op): Likewise. * gcc.dg/tree-ssa/local-pure-const.c: Update template.
This commit is contained in:
parent
e92779db33
commit
e977dd5edb
@ -2430,6 +2430,47 @@ fp_expression_p (gimple *stmt)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Return true if T references memory location that is local
|
||||
for the function (that means, dead after return) or read-only. */
|
||||
|
||||
bool
|
||||
refs_local_or_readonly_memory_p (tree t)
|
||||
{
|
||||
/* Non-escaping memory is fine. */
|
||||
t = get_base_address (t);
|
||||
if ((TREE_CODE (t) == MEM_REF
|
||||
|| TREE_CODE (t) == TARGET_MEM_REF))
|
||||
return points_to_local_or_readonly_memory_p (TREE_OPERAND (t, 0));
|
||||
|
||||
/* Automatic variables are fine. */
|
||||
if (DECL_P (t)
|
||||
&& auto_var_in_fn_p (t, current_function_decl))
|
||||
return true;
|
||||
|
||||
/* Read-only variables are fine. */
|
||||
if (DECL_P (t) && TREE_READONLY (t))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Return true if T is a pointer pointing to memory location that is local
|
||||
for the function (that means, dead after return) or read-only. */
|
||||
|
||||
bool
|
||||
points_to_local_or_readonly_memory_p (tree t)
|
||||
{
|
||||
/* See if memory location is clearly invalid. */
|
||||
if (integer_zerop (t))
|
||||
return flag_delete_null_pointer_checks;
|
||||
if (TREE_CODE (t) == SSA_NAME)
|
||||
return !ptr_deref_may_alias_global_p (t);
|
||||
if (TREE_CODE (t) == ADDR_EXPR)
|
||||
return refs_local_or_readonly_memory_p (TREE_OPERAND (t, 0));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* Analyze function body for NODE.
|
||||
EARLY indicates run from early optimization pipeline. */
|
||||
|
||||
|
@ -357,6 +357,8 @@ void estimate_ipcp_clone_size_and_time (struct cgraph_node *,
|
||||
void ipa_merge_fn_summary_after_inlining (struct cgraph_edge *edge);
|
||||
void ipa_update_overall_fn_summary (struct cgraph_node *node, bool reset = true);
|
||||
void compute_fn_summary (struct cgraph_node *, bool);
|
||||
bool refs_local_or_readonly_memory_p (tree);
|
||||
bool points_to_local_or_readonly_memory_p (tree);
|
||||
|
||||
|
||||
void evaluate_properties_for_edge (struct cgraph_edge *e,
|
||||
|
@ -62,6 +62,9 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "calls.h"
|
||||
#include "ipa-modref-tree.h"
|
||||
#include "ipa-modref.h"
|
||||
#include "value-range.h"
|
||||
#include "ipa-prop.h"
|
||||
#include "ipa-fnsummary.h"
|
||||
|
||||
/* Class (from which there is one global instance) that holds modref summaries
|
||||
for all analyzed functions. */
|
||||
@ -347,36 +350,12 @@ record_access_lto (modref_records_lto *tt, ao_ref *ref)
|
||||
static bool
|
||||
record_access_p (tree expr)
|
||||
{
|
||||
/* Non-escaping memory is fine */
|
||||
tree t = get_base_address (expr);
|
||||
if (t && (INDIRECT_REF_P (t)
|
||||
|| TREE_CODE (t) == MEM_REF
|
||||
|| TREE_CODE (t) == TARGET_MEM_REF)
|
||||
&& TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME
|
||||
&& !ptr_deref_may_alias_global_p (TREE_OPERAND (t, 0)))
|
||||
if (refs_local_or_readonly_memory_p (expr))
|
||||
{
|
||||
if (dump_file)
|
||||
fprintf (dump_file, " - Non-escaping memory, ignoring.\n");
|
||||
fprintf (dump_file, " - Read-only or local, ignoring.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Automatic variables are fine. */
|
||||
if (DECL_P (t)
|
||||
&& auto_var_in_fn_p (t, current_function_decl))
|
||||
{
|
||||
if (dump_file)
|
||||
fprintf (dump_file, " - Automatic variable, ignoring.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Read-only variables are fine. */
|
||||
if (DECL_P (t) && TREE_READONLY (t))
|
||||
{
|
||||
if (dump_file)
|
||||
fprintf (dump_file, " - Read-only variable, ignoring.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -381,13 +381,11 @@ check_op (funct_state local, tree t, bool checking_write)
|
||||
fprintf (dump_file, " Volatile indirect ref is not const/pure\n");
|
||||
return;
|
||||
}
|
||||
else if (t
|
||||
&& (INDIRECT_REF_P (t) || TREE_CODE (t) == MEM_REF)
|
||||
&& TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME
|
||||
&& !ptr_deref_may_alias_global_p (TREE_OPERAND (t, 0)))
|
||||
else if (refs_local_or_readonly_memory_p (t))
|
||||
{
|
||||
if (dump_file)
|
||||
fprintf (dump_file, " Indirect ref to local memory is OK\n");
|
||||
fprintf (dump_file, " Indirect ref to local or readonly "
|
||||
"memory is OK\n");
|
||||
return;
|
||||
}
|
||||
else if (checking_write)
|
||||
|
@ -12,5 +12,5 @@ t(int a, int b, int c)
|
||||
p = &c;
|
||||
return *p;
|
||||
}
|
||||
/* { dg-final { scan-tree-dump-times "local memory is OK" 1 "local-pure-const1"} } */
|
||||
/* { dg-final { scan-tree-dump-times "local or readonly memory is OK" 1 "local-pure-const1"} } */
|
||||
/* { dg-final { scan-tree-dump-times "found to be const" 1 "local-pure-const1"} } */
|
||||
|
Loading…
Reference in New Issue
Block a user