handle retslot in modref
Extend modref and tree-ssa-structalias to handle retslot flags. Since retslot it essentially a hidden argument that is known to be write-only we can do pretty much the same stuff as we do for regular parameters. I plan to add static chain handling similar way. We do not handle IPA propagation of retslot flags (where return slot is initialized via return slot of other function). For this ipa-prop needs to be extended to understand retslot as well. Bootstrapped/regtested x86_64-linux, OK for the gimple bits? Honza gcc/ChangeLog: * gimple.c (gimple_call_retslot_flags): New function. * gimple.h (gimple_call_retslot_flags): Declare. * ipa-modref.c: Include tree-cfg.h. (struct escape_entry): Turn parm_index to signed. (modref_summary_lto::modref_summary_lto): Add retslot_flags. (modref_summary::modref_summary): Initialize retslot_flags. (struct modref_summary_lto): Likewise. (modref_summary::useful_p): Check retslot_flags. (modref_summary_lto::useful_p): Likewise. (modref_summary::dump): Dump retslot_flags. (modref_summary_lto::dump): Likewise. (struct escape_point): Add hidden_args enum. (analyze_ssa_name_flags): Ignore return slot return; use gimple_call_retslot_flags. (record_escape_points): Break out from ... (analyze_parms): ... here; handle retslot_flags. (modref_summaries::duplicate): Duplicate retslot_flags. (modref_summaries_lto::duplicate): Likewise. (modref_write_escape_summary): Stream parm_index as signed. (modref_read_escape_summary): Likewise. (modref_write): Stream retslot_flags. (read_section): Likewise. (struct escape_map): Fix typo in comment. (update_escape_summary_1): Fix whitespace. (ipa_merge_modref_summary_after_inlining): Drop retslot_flags. (modref_merge_call_site_flags): Merge retslot_flags. * ipa-modref.h (struct modref_summary): Add retslot_flags. * tree-ssa-structalias.c (handle_rhs_call): Handle retslot_flags.
This commit is contained in:
parent
4045d5fa42
commit
b8ef019ab9
41
gcc/gimple.c
41
gcc/gimple.c
@ -1597,7 +1597,12 @@ gimple_call_arg_flags (const gcall *stmt, unsigned arg)
|
||||
if (!node->binds_to_current_def_p ())
|
||||
{
|
||||
if ((modref_flags & EAF_UNUSED) && !(flags & EAF_UNUSED))
|
||||
modref_flags &= ~EAF_UNUSED;
|
||||
{
|
||||
modref_flags &= ~EAF_UNUSED;
|
||||
modref_flags |= EAF_NOESCAPE;
|
||||
}
|
||||
if ((modref_flags & EAF_NOREAD) && !(flags & EAF_NOREAD))
|
||||
modref_flags &= ~EAF_NOREAD;
|
||||
if ((modref_flags & EAF_DIRECT) && !(flags & EAF_DIRECT))
|
||||
modref_flags &= ~EAF_DIRECT;
|
||||
}
|
||||
@ -1608,6 +1613,40 @@ gimple_call_arg_flags (const gcall *stmt, unsigned arg)
|
||||
return flags;
|
||||
}
|
||||
|
||||
/* Detects argument flags for return slot on call STMT. */
|
||||
|
||||
int
|
||||
gimple_call_retslot_flags (const gcall *stmt)
|
||||
{
|
||||
int flags = EAF_DIRECT | EAF_NOREAD;
|
||||
|
||||
tree callee = gimple_call_fndecl (stmt);
|
||||
if (callee)
|
||||
{
|
||||
cgraph_node *node = cgraph_node::get (callee);
|
||||
modref_summary *summary = node ? get_modref_function_summary (node)
|
||||
: NULL;
|
||||
|
||||
if (summary)
|
||||
{
|
||||
int modref_flags = summary->retslot_flags;
|
||||
|
||||
/* We have possibly optimized out load. Be conservative here. */
|
||||
if (!node->binds_to_current_def_p ())
|
||||
{
|
||||
if ((modref_flags & EAF_UNUSED) && !(flags & EAF_UNUSED))
|
||||
{
|
||||
modref_flags &= ~EAF_UNUSED;
|
||||
modref_flags |= EAF_NOESCAPE;
|
||||
}
|
||||
}
|
||||
if (dbg_cnt (ipa_mod_ref_pta))
|
||||
flags |= modref_flags;
|
||||
}
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
/* Detects return flags for the call STMT. */
|
||||
|
||||
int
|
||||
|
@ -1589,6 +1589,7 @@ gimple_seq gimple_seq_copy (gimple_seq);
|
||||
bool gimple_call_same_target_p (const gimple *, const gimple *);
|
||||
int gimple_call_flags (const gimple *);
|
||||
int gimple_call_arg_flags (const gcall *, unsigned);
|
||||
int gimple_call_retslot_flags (const gcall *);
|
||||
int gimple_call_return_flags (const gcall *);
|
||||
bool gimple_call_nonnull_result_p (gcall *);
|
||||
tree gimple_call_nonnull_arg (gcall *);
|
||||
|
145
gcc/ipa-modref.c
145
gcc/ipa-modref.c
@ -86,6 +86,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "stringpool.h"
|
||||
#include "tree-ssanames.h"
|
||||
#include "attribs.h"
|
||||
#include "tree-cfg.h"
|
||||
|
||||
|
||||
namespace {
|
||||
@ -133,7 +134,7 @@ static fnspec_summaries_t *fnspec_summaries = NULL;
|
||||
struct escape_entry
|
||||
{
|
||||
/* Parameter that escapes at a given call. */
|
||||
unsigned int parm_index;
|
||||
int parm_index;
|
||||
/* Argument it escapes to. */
|
||||
unsigned int arg;
|
||||
/* Minimal flags known about the argument. */
|
||||
@ -269,7 +270,7 @@ static GTY(()) fast_function_summary <modref_summary_lto *, va_gc>
|
||||
/* Summary for a single function which this pass produces. */
|
||||
|
||||
modref_summary::modref_summary ()
|
||||
: loads (NULL), stores (NULL), writes_errno (NULL)
|
||||
: loads (NULL), stores (NULL), retslot_flags (0), writes_errno (false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -322,6 +323,8 @@ modref_summary::useful_p (int ecf_flags, bool check_flags)
|
||||
if (check_flags && eaf_flags_useful_p (arg_flags, ecf_flags))
|
||||
return true;
|
||||
arg_flags.release ();
|
||||
if (check_flags && remove_useless_eaf_flags (retslot_flags, ecf_flags, false))
|
||||
return true;
|
||||
if (ecf_flags & ECF_CONST)
|
||||
return false;
|
||||
if (loads && !loads->every_base)
|
||||
@ -363,6 +366,7 @@ struct GTY(()) modref_summary_lto
|
||||
modref_records_lto *loads;
|
||||
modref_records_lto *stores;
|
||||
auto_vec<eaf_flags_t> GTY((skip)) arg_flags;
|
||||
eaf_flags_t retslot_flags;
|
||||
bool writes_errno;
|
||||
|
||||
modref_summary_lto ();
|
||||
@ -374,7 +378,7 @@ struct GTY(()) modref_summary_lto
|
||||
/* Summary for a single function which this pass produces. */
|
||||
|
||||
modref_summary_lto::modref_summary_lto ()
|
||||
: loads (NULL), stores (NULL), writes_errno (NULL)
|
||||
: loads (NULL), stores (NULL), retslot_flags (0), writes_errno (false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -400,6 +404,8 @@ modref_summary_lto::useful_p (int ecf_flags, bool check_flags)
|
||||
if (check_flags && eaf_flags_useful_p (arg_flags, ecf_flags))
|
||||
return true;
|
||||
arg_flags.release ();
|
||||
if (check_flags && remove_useless_eaf_flags (retslot_flags, ecf_flags, false))
|
||||
return true;
|
||||
if (ecf_flags & ECF_CONST)
|
||||
return false;
|
||||
if (loads && !loads->every_base)
|
||||
@ -608,6 +614,11 @@ modref_summary::dump (FILE *out)
|
||||
dump_eaf_flags (out, arg_flags[i]);
|
||||
}
|
||||
}
|
||||
if (retslot_flags)
|
||||
{
|
||||
fprintf (out, " Retslot flags:");
|
||||
dump_eaf_flags (out, retslot_flags);
|
||||
}
|
||||
}
|
||||
|
||||
/* Dump summary. */
|
||||
@ -630,6 +641,11 @@ modref_summary_lto::dump (FILE *out)
|
||||
dump_eaf_flags (out, arg_flags[i]);
|
||||
}
|
||||
}
|
||||
if (retslot_flags)
|
||||
{
|
||||
fprintf (out, " Retslot flags:");
|
||||
dump_eaf_flags (out, retslot_flags);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get function summary for FUNC if it exists, return NULL otherwise. */
|
||||
@ -1396,6 +1412,11 @@ namespace {
|
||||
|
||||
struct escape_point
|
||||
{
|
||||
/* Extra hidden args we keep track of. */
|
||||
enum hidden_args
|
||||
{
|
||||
retslot_arg = -1
|
||||
};
|
||||
/* Value escapes to this call. */
|
||||
gcall *call;
|
||||
/* Argument it escapes to. */
|
||||
@ -1705,7 +1726,11 @@ analyze_ssa_name_flags (tree name, vec<modref_lattice> &lattice, int depth,
|
||||
Returning name counts as an use by tree-ssa-structalias.c */
|
||||
if (greturn *ret = dyn_cast <greturn *> (use_stmt))
|
||||
{
|
||||
if (gimple_return_retval (ret) == name)
|
||||
/* Returning through return slot is seen as memory write earlier. */
|
||||
if (DECL_RESULT (current_function_decl)
|
||||
&& DECL_BY_REFERENCE (DECL_RESULT (current_function_decl)))
|
||||
;
|
||||
else if (gimple_return_retval (ret) == name)
|
||||
lattice[index].merge (~(EAF_UNUSED | EAF_NOT_RETURNED));
|
||||
else if (memory_access_to (gimple_return_retval (ret), name))
|
||||
{
|
||||
@ -1748,7 +1773,7 @@ analyze_ssa_name_flags (tree name, vec<modref_lattice> &lattice, int depth,
|
||||
may make LHS to escape. See PR 98499. */
|
||||
if (gimple_call_return_slot_opt_p (call)
|
||||
&& TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (call))))
|
||||
lattice[index].merge (EAF_NOREAD | EAF_DIRECT);
|
||||
lattice[index].merge (gimple_call_retslot_flags (call));
|
||||
}
|
||||
|
||||
/* We do not track accesses to the static chain (we could)
|
||||
@ -1777,7 +1802,7 @@ analyze_ssa_name_flags (tree name, vec<modref_lattice> &lattice, int depth,
|
||||
lattice[index].merge (call_flags);
|
||||
else
|
||||
lattice[index].add_escape_point (call, i,
|
||||
call_flags, true);
|
||||
call_flags, true);
|
||||
}
|
||||
if (!ignore_retval)
|
||||
merge_call_lhs_flags (call, i, index, false,
|
||||
@ -1912,6 +1937,29 @@ analyze_ssa_name_flags (tree name, vec<modref_lattice> &lattice, int depth,
|
||||
lattice[index].known = true;
|
||||
}
|
||||
|
||||
/* Record escape points of PARM_INDEX according to LATTICE. */
|
||||
|
||||
static void
|
||||
record_escape_points (modref_lattice &lattice, int parm_index, int flags)
|
||||
{
|
||||
if (lattice.escape_points.length ())
|
||||
{
|
||||
escape_point *ep;
|
||||
unsigned int ip;
|
||||
cgraph_node *node = cgraph_node::get (current_function_decl);
|
||||
|
||||
FOR_EACH_VEC_ELT (lattice.escape_points, ip, ep)
|
||||
if ((ep->min_flags & flags) != flags)
|
||||
{
|
||||
cgraph_edge *e = node->get_edge (ep->call);
|
||||
struct escape_entry ee = {parm_index, ep->arg,
|
||||
ep->min_flags, ep->direct};
|
||||
|
||||
escape_summaries->get_create (e)->esc.safe_push (ee);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine EAF flags for function parameters. */
|
||||
|
||||
static void
|
||||
@ -1921,16 +1969,22 @@ analyze_parms (modref_summary *summary, modref_summary_lto *summary_lto,
|
||||
unsigned int parm_index = 0;
|
||||
unsigned int count = 0;
|
||||
int ecf_flags = flags_from_decl_or_type (current_function_decl);
|
||||
tree retslot = NULL;
|
||||
|
||||
/* For novops functions we have nothing to gain by EAF flags. */
|
||||
if (ecf_flags & ECF_NOVOPS)
|
||||
return;
|
||||
|
||||
/* If there is return slot, look up its SSA name. */
|
||||
if (DECL_RESULT (current_function_decl)
|
||||
&& DECL_BY_REFERENCE (DECL_RESULT (current_function_decl)))
|
||||
retslot = ssa_default_def (cfun, DECL_RESULT (current_function_decl));
|
||||
|
||||
for (tree parm = DECL_ARGUMENTS (current_function_decl); parm;
|
||||
parm = TREE_CHAIN (parm))
|
||||
count++;
|
||||
|
||||
if (!count)
|
||||
if (!count && !retslot)
|
||||
return;
|
||||
|
||||
auto_vec<modref_lattice> lattice;
|
||||
@ -1984,24 +2038,24 @@ analyze_parms (modref_summary *summary, modref_summary_lto *summary_lto,
|
||||
summary_lto->arg_flags.safe_grow_cleared (count, true);
|
||||
summary_lto->arg_flags[parm_index] = flags;
|
||||
}
|
||||
if (lattice[SSA_NAME_VERSION (name)].escape_points.length ())
|
||||
{
|
||||
escape_point *ep;
|
||||
unsigned int ip;
|
||||
cgraph_node *node = cgraph_node::get (current_function_decl);
|
||||
record_escape_points (lattice[SSA_NAME_VERSION (name)],
|
||||
parm_index, flags);
|
||||
}
|
||||
}
|
||||
if (retslot)
|
||||
{
|
||||
analyze_ssa_name_flags (retslot, lattice, 0, ipa);
|
||||
int flags = lattice[SSA_NAME_VERSION (retslot)].flags;
|
||||
|
||||
gcc_checking_assert (ipa);
|
||||
FOR_EACH_VEC_ELT
|
||||
(lattice[SSA_NAME_VERSION (name)].escape_points, ip, ep)
|
||||
if ((ep->min_flags & flags) != flags)
|
||||
{
|
||||
cgraph_edge *e = node->get_edge (ep->call);
|
||||
struct escape_entry ee = {parm_index, ep->arg,
|
||||
ep->min_flags, ep->direct};
|
||||
|
||||
escape_summaries->get_create (e)->esc.safe_push (ee);
|
||||
}
|
||||
}
|
||||
flags = remove_useless_eaf_flags (flags, ecf_flags, false);
|
||||
if (flags)
|
||||
{
|
||||
if (summary)
|
||||
summary->retslot_flags = flags;
|
||||
if (summary_lto)
|
||||
summary_lto->retslot_flags = flags;
|
||||
record_escape_points (lattice[SSA_NAME_VERSION (retslot)],
|
||||
escape_point::retslot_arg, flags);
|
||||
}
|
||||
}
|
||||
if (ipa)
|
||||
@ -2287,6 +2341,7 @@ modref_summaries::duplicate (cgraph_node *, cgraph_node *dst,
|
||||
dst_data->writes_errno = src_data->writes_errno;
|
||||
if (src_data->arg_flags.length ())
|
||||
dst_data->arg_flags = src_data->arg_flags.copy ();
|
||||
dst_data->retslot_flags = src_data->retslot_flags;
|
||||
}
|
||||
|
||||
/* Called when new clone is inserted to callgraph late. */
|
||||
@ -2312,6 +2367,7 @@ modref_summaries_lto::duplicate (cgraph_node *, cgraph_node *,
|
||||
dst_data->writes_errno = src_data->writes_errno;
|
||||
if (src_data->arg_flags.length ())
|
||||
dst_data->arg_flags = src_data->arg_flags.copy ();
|
||||
dst_data->retslot_flags = src_data->retslot_flags;
|
||||
}
|
||||
|
||||
namespace
|
||||
@ -2551,7 +2607,7 @@ modref_write_escape_summary (struct bitpack_d *bp, escape_summary *esum)
|
||||
escape_entry *ee;
|
||||
FOR_EACH_VEC_ELT (esum->esc, i, ee)
|
||||
{
|
||||
bp_pack_var_len_unsigned (bp, ee->parm_index);
|
||||
bp_pack_var_len_int (bp, ee->parm_index);
|
||||
bp_pack_var_len_unsigned (bp, ee->arg);
|
||||
bp_pack_var_len_unsigned (bp, ee->min_flags);
|
||||
bp_pack_value (bp, ee->direct, 1);
|
||||
@ -2571,7 +2627,7 @@ modref_read_escape_summary (struct bitpack_d *bp, cgraph_edge *e)
|
||||
for (unsigned int i = 0; i < n; i++)
|
||||
{
|
||||
escape_entry ee;
|
||||
ee.parm_index = bp_unpack_var_len_unsigned (bp);
|
||||
ee.parm_index = bp_unpack_var_len_int (bp);
|
||||
ee.arg = bp_unpack_var_len_unsigned (bp);
|
||||
ee.min_flags = bp_unpack_var_len_unsigned (bp);
|
||||
ee.direct = bp_unpack_value (bp, 1);
|
||||
@ -2628,6 +2684,7 @@ modref_write ()
|
||||
streamer_write_uhwi (ob, r->arg_flags.length ());
|
||||
for (unsigned int i = 0; i < r->arg_flags.length (); i++)
|
||||
streamer_write_uhwi (ob, r->arg_flags[i]);
|
||||
streamer_write_uhwi (ob, r->retslot_flags);
|
||||
|
||||
write_modref_records (r->loads, ob);
|
||||
write_modref_records (r->stores, ob);
|
||||
@ -2724,6 +2781,11 @@ read_section (struct lto_file_decl_data *file_data, const char *data,
|
||||
if (modref_sum_lto)
|
||||
modref_sum_lto->arg_flags.quick_push (flags);
|
||||
}
|
||||
eaf_flags_t flags = streamer_read_uhwi (&ib);
|
||||
if (modref_sum)
|
||||
modref_sum->retslot_flags = flags;
|
||||
if (modref_sum_lto)
|
||||
modref_sum_lto->retslot_flags = flags;
|
||||
read_modref_records (&ib, data_in,
|
||||
modref_sum ? &modref_sum->loads : NULL,
|
||||
modref_sum_lto ? &modref_sum_lto->loads : NULL);
|
||||
@ -3098,7 +3160,7 @@ struct escape_map
|
||||
bool direct;
|
||||
};
|
||||
|
||||
/* Update escape map fo E. */
|
||||
/* Update escape map for E. */
|
||||
|
||||
static void
|
||||
update_escape_summary_1 (cgraph_edge *e,
|
||||
@ -3117,7 +3179,10 @@ update_escape_summary_1 (cgraph_edge *e,
|
||||
{
|
||||
unsigned int j;
|
||||
struct escape_map *em;
|
||||
if (ee->parm_index >= map.length ())
|
||||
/* TODO: We do not have jump functions for return slots, so we
|
||||
never propagate them to outer function. */
|
||||
if (ee->parm_index >= (int)map.length ()
|
||||
|| ee->parm_index < 0)
|
||||
continue;
|
||||
FOR_EACH_VEC_ELT (map[ee->parm_index], j, em)
|
||||
{
|
||||
@ -3125,7 +3190,7 @@ update_escape_summary_1 (cgraph_edge *e,
|
||||
if (ee->direct && !em->direct)
|
||||
min_flags = deref_flags (min_flags, ignore_stores);
|
||||
struct escape_entry entry = {em->parm_index, ee->arg,
|
||||
ee->min_flags,
|
||||
ee->min_flags,
|
||||
ee->direct & em->direct};
|
||||
sum->esc.safe_push (entry);
|
||||
}
|
||||
@ -3245,7 +3310,11 @@ ipa_merge_modref_summary_after_inlining (cgraph_edge *edge)
|
||||
FOR_EACH_VEC_ELT (sum->esc, i, ee)
|
||||
{
|
||||
bool needed = false;
|
||||
if (to_info && to_info->arg_flags.length () > ee->parm_index)
|
||||
/* TODO: We do not have jump functions for return slots, so we
|
||||
never propagate them to outer function. */
|
||||
if (ee->parm_index < 0)
|
||||
continue;
|
||||
if (to_info && (int)to_info->arg_flags.length () > ee->parm_index)
|
||||
{
|
||||
int flags = callee_info
|
||||
&& callee_info->arg_flags.length () > ee->arg
|
||||
@ -3259,7 +3328,7 @@ ipa_merge_modref_summary_after_inlining (cgraph_edge *edge)
|
||||
if (to_info->arg_flags[ee->parm_index])
|
||||
needed = true;
|
||||
}
|
||||
if (to_info_lto && to_info_lto->arg_flags.length () > ee->parm_index)
|
||||
if (to_info_lto && (int)to_info_lto->arg_flags.length () > ee->parm_index)
|
||||
{
|
||||
int flags = callee_info_lto
|
||||
&& callee_info_lto->arg_flags.length () > ee->arg
|
||||
@ -3798,29 +3867,31 @@ modref_merge_call_site_flags (escape_summary *sum,
|
||||
if (flags_lto & EAF_NOESCAPE)
|
||||
flags_lto |= EAF_NODIRECTESCAPE;
|
||||
if (!(flags & EAF_UNUSED)
|
||||
&& cur_summary && ee->parm_index < cur_summary->arg_flags.length ())
|
||||
&& cur_summary && ee->parm_index < (int)cur_summary->arg_flags.length ())
|
||||
{
|
||||
int f = cur_summary->arg_flags[ee->parm_index];
|
||||
eaf_flags_t &f = ee->parm_index == escape_point::retslot_arg
|
||||
? cur_summary->retslot_flags
|
||||
: cur_summary->arg_flags[ee->parm_index];
|
||||
if ((f & flags) != f)
|
||||
{
|
||||
f = remove_useless_eaf_flags
|
||||
(f & flags, ecf_flags,
|
||||
VOID_TYPE_P (TREE_TYPE (TREE_TYPE (caller))));
|
||||
cur_summary->arg_flags[ee->parm_index] = f;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (!(flags_lto & EAF_UNUSED)
|
||||
&& cur_summary_lto
|
||||
&& ee->parm_index < cur_summary_lto->arg_flags.length ())
|
||||
&& ee->parm_index < (int)cur_summary_lto->arg_flags.length ())
|
||||
{
|
||||
int f = cur_summary_lto->arg_flags[ee->parm_index];
|
||||
eaf_flags_t &f = ee->parm_index == escape_point::retslot_arg
|
||||
? cur_summary_lto->retslot_flags
|
||||
: cur_summary_lto->arg_flags[ee->parm_index];
|
||||
if ((f & flags_lto) != f)
|
||||
{
|
||||
f = remove_useless_eaf_flags
|
||||
(f & flags_lto, ecf_flags,
|
||||
VOID_TYPE_P (TREE_TYPE (TREE_TYPE (caller))));
|
||||
cur_summary_lto->arg_flags[ee->parm_index] = f;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ struct GTY(()) modref_summary
|
||||
modref_records *loads;
|
||||
modref_records *stores;
|
||||
auto_vec<eaf_flags_t> GTY((skip)) arg_flags;
|
||||
eaf_flags_t retslot_flags;
|
||||
bool writes_errno;
|
||||
|
||||
modref_summary ();
|
||||
|
@ -4254,17 +4254,28 @@ handle_rhs_call (gcall *stmt, vec<ce_s> *results,
|
||||
&& gimple_call_lhs (stmt) != NULL_TREE
|
||||
&& TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (stmt))))
|
||||
{
|
||||
auto_vec<ce_s> tmpc;
|
||||
struct constraint_expr *c;
|
||||
unsigned i;
|
||||
int flags = gimple_call_retslot_flags (stmt);
|
||||
if ((flags & (EAF_NOESCAPE | EAF_NOT_RETURNED))
|
||||
!= (EAF_NOESCAPE | EAF_NOT_RETURNED))
|
||||
{
|
||||
auto_vec<ce_s> tmpc;
|
||||
|
||||
get_constraint_for_address_of (gimple_call_lhs (stmt), &tmpc);
|
||||
get_constraint_for_address_of (gimple_call_lhs (stmt), &tmpc);
|
||||
|
||||
make_constraints_to (callescape->id, tmpc);
|
||||
if (writes_global_memory)
|
||||
make_constraints_to (escaped_id, tmpc);
|
||||
FOR_EACH_VEC_ELT (tmpc, i, c)
|
||||
results->safe_push (*c);
|
||||
if (!(flags & (EAF_NOESCAPE | EAF_NODIRECTESCAPE)))
|
||||
{
|
||||
make_constraints_to (callescape->id, tmpc);
|
||||
if (writes_global_memory)
|
||||
make_constraints_to (escaped_id, tmpc);
|
||||
}
|
||||
if (!(flags & EAF_NOT_RETURNED))
|
||||
{
|
||||
struct constraint_expr *c;
|
||||
unsigned i;
|
||||
FOR_EACH_VEC_ELT (tmpc, i, c)
|
||||
results->safe_push (*c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user