mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-19 22:41:28 +08:00
re PR middle-end/37448 (cannot compile big function)
PR middle-end/37448 * ipa-reference.c (ipa_reference_local_vars_info_d, ipa_reference_global_vars_info_d, ipa_reference_local_vars_info_t, ipa_reference_global_vars_info_t, ipa_reference_vars_info_t): Move here from ipa-reference.h (node_duplication_hook_holder, node_removal_hook_holder): New. (get_reference_vars_info_from_cgraph): Rename to ... (get_reference_vars_info): ... this one, use cgraph uids. (get_local_reference_vars_info, get_global_reference_vars_info): Use cgraph instead of decl. (ipa_reference_get_read_local, ipa_reference_get_written_local): Remove. (ipa_reference_get_read_global, ipa_reference_get_not_read_global ipa_reference_get_written_global, ipa_reference_get_not_written_global): Use cgraph argument. (check_call): Simplify avail check. (scan_stmt_for_static_refs): Update. (propagate_bits): Update. (merge_callee_local_info): Remove. (init_function_info): Use cgraph nodes. (clean_function_local_data): Break out from ... (clean_function): ... here. (copy_local_bitmap, copy_global_bitmap): New functions. (duplicate_node_data, remove_node_data): New functions. (generate_summary): Register hooks; use visibility instead of master clones. (propafate): Use cgraph nodes; copy bitmap to each node in cycle. * ipa-reference.h (ipa_reference_local_vars_info_d, ipa_reference_global_vars_info_d, ipa_reference_local_vars_info_t, ipa_reference_global_vars_info_t, ipa_reference_vars_info_t): Move to ipa-reference.c (ipa_reference_get_read_local, ipa_reference_get_written_local): Remove. (ipa_reference_get_read_global, ipa_reference_get_written_global, ipa_reference_get_not_read_global, ipa_reference_get_not_written_global): Update prototype. * ipa-pure-const.c (funct_state_vec): Turn into VECtor. (init_state): Remove. (node_duplication_hook_holder, node_removal_hook_holder): New. (get_function_state, set_function_state): Use VECtor. (analyze_function): Check body availability. (add_new_function): Likewise. (duplicate_node_data, remove_node_data): New. (generate_summary): Register hooks; do not care about clones. (propafate): Do not care about clones; recursive functions are not looping. * ipa-utils.c (searchc, ipa_utils_reduced_inorder): Do not skip clones. * ipa-prop.c (edge_removal_hook_holder, node_removal_hook_holder, * edge_duplication_hook_holder, node_duplication_hook_holder): Make static. * tree-flow.h (function_ann_d): Remove reference_vars_info. * tree-ssa-opreands.c (add_call_clobber_ops, add_call_read_ops): Update call of ipa-reference accesors. From-SVN: r140463
This commit is contained in:
parent
52d1bfd8cd
commit
e2c9111c0e
@ -1,3 +1,57 @@
|
||||
2008-09-18 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
PR middle-end/37448
|
||||
* ipa-reference.c (ipa_reference_local_vars_info_d,
|
||||
ipa_reference_global_vars_info_d,
|
||||
ipa_reference_local_vars_info_t, ipa_reference_global_vars_info_t,
|
||||
ipa_reference_vars_info_t): Move here from ipa-reference.h
|
||||
(node_duplication_hook_holder, node_removal_hook_holder): New.
|
||||
(get_reference_vars_info_from_cgraph): Rename to ...
|
||||
(get_reference_vars_info): ... this one, use cgraph uids.
|
||||
(get_local_reference_vars_info, get_global_reference_vars_info):
|
||||
Use cgraph instead of decl.
|
||||
(ipa_reference_get_read_local, ipa_reference_get_written_local): Remove.
|
||||
(ipa_reference_get_read_global, ipa_reference_get_not_read_global
|
||||
ipa_reference_get_written_global, ipa_reference_get_not_written_global): Use
|
||||
cgraph argument.
|
||||
(check_call): Simplify avail check.
|
||||
(scan_stmt_for_static_refs): Update.
|
||||
(propagate_bits): Update.
|
||||
(merge_callee_local_info): Remove.
|
||||
(init_function_info): Use cgraph nodes.
|
||||
(clean_function_local_data): Break out from ...
|
||||
(clean_function): ... here.
|
||||
(copy_local_bitmap, copy_global_bitmap): New functions.
|
||||
(duplicate_node_data, remove_node_data): New functions.
|
||||
(generate_summary): Register hooks; use visibility instead of
|
||||
master clones.
|
||||
(propafate): Use cgraph nodes; copy bitmap to each node in cycle.
|
||||
* ipa-reference.h (ipa_reference_local_vars_info_d,
|
||||
ipa_reference_global_vars_info_d,
|
||||
ipa_reference_local_vars_info_t, ipa_reference_global_vars_info_t,
|
||||
ipa_reference_vars_info_t): Move to ipa-reference.c
|
||||
(ipa_reference_get_read_local, ipa_reference_get_written_local):
|
||||
Remove.
|
||||
(ipa_reference_get_read_global, ipa_reference_get_written_global,
|
||||
ipa_reference_get_not_read_global, ipa_reference_get_not_written_global):
|
||||
Update prototype.
|
||||
* ipa-pure-const.c (funct_state_vec): Turn into VECtor.
|
||||
(init_state): Remove.
|
||||
(node_duplication_hook_holder, node_removal_hook_holder): New.
|
||||
(get_function_state, set_function_state): Use VECtor.
|
||||
(analyze_function): Check body availability.
|
||||
(add_new_function): Likewise.
|
||||
(duplicate_node_data, remove_node_data): New.
|
||||
(generate_summary): Register hooks; do not care about clones.
|
||||
(propafate): Do not care about clones; recursive functions are not looping.
|
||||
* ipa-utils.c (searchc, ipa_utils_reduced_inorder): Do not skip clones.
|
||||
* ipa-prop.c (edge_removal_hook_holder, node_removal_hook_holder,
|
||||
* edge_duplication_hook_holder, node_duplication_hook_holder): Make
|
||||
static.
|
||||
* tree-flow.h (function_ann_d): Remove reference_vars_info.
|
||||
* tree-ssa-opreands.c (add_call_clobber_ops, add_call_read_ops): Update call of
|
||||
ipa-reference accesors.
|
||||
|
||||
2008-09-18 Simon Baldwin <simonb@google.com>
|
||||
|
||||
* c-opts.c (c_common_handle_option): Add handling for
|
||||
|
@ -40,10 +40,10 @@ VEC (ipa_node_params_t, heap) *ipa_node_params_vector;
|
||||
VEC (ipa_edge_args_t, heap) *ipa_edge_args_vector;
|
||||
|
||||
/* Holders of ipa cgraph hooks: */
|
||||
struct cgraph_edge_hook_list *edge_removal_hook_holder;
|
||||
struct cgraph_node_hook_list *node_removal_hook_holder;
|
||||
struct cgraph_2edge_hook_list *edge_duplication_hook_holder;
|
||||
struct cgraph_2node_hook_list *node_duplication_hook_holder;
|
||||
static struct cgraph_edge_hook_list *edge_removal_hook_holder;
|
||||
static struct cgraph_node_hook_list *node_removal_hook_holder;
|
||||
static struct cgraph_2edge_hook_list *edge_duplication_hook_holder;
|
||||
static struct cgraph_2node_hook_list *node_duplication_hook_holder;
|
||||
|
||||
/* Initialize worklist to contain all functions. */
|
||||
struct ipa_func_list *
|
||||
|
@ -94,19 +94,14 @@ typedef struct funct_state_d * funct_state;
|
||||
|
||||
/* Array, indexed by cgraph node uid, of function states. */
|
||||
|
||||
static funct_state *funct_state_vec;
|
||||
DEF_VEC_P (funct_state);
|
||||
DEF_VEC_ALLOC_P (funct_state, heap);
|
||||
static VEC (funct_state, heap) *funct_state_vec;
|
||||
|
||||
/* Holders of ipa cgraph hooks: */
|
||||
static struct cgraph_node_hook_list *function_insertion_hook_holder;
|
||||
|
||||
/* Init the function state. */
|
||||
|
||||
static void
|
||||
init_state (void)
|
||||
{
|
||||
funct_state_vec = XCNEWVEC (funct_state, cgraph_max_uid);
|
||||
}
|
||||
|
||||
static struct cgraph_2node_hook_list *node_duplication_hook_holder;
|
||||
static struct cgraph_node_hook_list *node_removal_hook_holder;
|
||||
|
||||
/* Init the function state. */
|
||||
|
||||
@ -122,7 +117,10 @@ finish_state (void)
|
||||
static inline funct_state
|
||||
get_function_state (struct cgraph_node *node)
|
||||
{
|
||||
return funct_state_vec[node->uid];
|
||||
if (!funct_state_vec
|
||||
|| VEC_length (funct_state, funct_state_vec) <= (unsigned int)node->uid)
|
||||
return NULL;
|
||||
return VEC_index (funct_state, funct_state_vec, node->uid);
|
||||
}
|
||||
|
||||
/* Set the function state S for NODE. */
|
||||
@ -130,7 +128,10 @@ get_function_state (struct cgraph_node *node)
|
||||
static inline void
|
||||
set_function_state (struct cgraph_node *node, funct_state s)
|
||||
{
|
||||
funct_state_vec[node->uid] = s;
|
||||
if (!funct_state_vec
|
||||
|| VEC_length (funct_state, funct_state_vec) <= (unsigned int)node->uid)
|
||||
VEC_safe_grow_cleared (funct_state, heap, funct_state_vec, node->uid + 1);
|
||||
VEC_replace (funct_state, funct_state_vec, node->uid, s);
|
||||
}
|
||||
|
||||
/* Check to see if the use (or definition when CHECKING_WRITE is true)
|
||||
@ -585,6 +586,9 @@ analyze_function (struct cgraph_node *fn)
|
||||
tree decl = fn->decl;
|
||||
funct_state l = XCNEW (struct funct_state_d);
|
||||
|
||||
if (cgraph_function_body_availability (fn) <= AVAIL_OVERWRITABLE)
|
||||
return;
|
||||
|
||||
set_function_state (fn, l);
|
||||
|
||||
l->pure_const_state = IPA_CONST;
|
||||
@ -683,7 +687,8 @@ end:
|
||||
static void
|
||||
add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
|
||||
{
|
||||
funct_state_vec = XRESIZEVEC (funct_state, funct_state_vec, cgraph_max_uid);
|
||||
if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
|
||||
return;
|
||||
/* There are some shared nodes, in particular the initializers on
|
||||
static declarations. We do not need to scan them more than once
|
||||
since all we would be interested in are the addressof
|
||||
@ -694,6 +699,33 @@ add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
|
||||
visited_nodes = NULL;
|
||||
}
|
||||
|
||||
/* Called when new clone is inserted to callgraph late. */
|
||||
|
||||
static void
|
||||
duplicate_node_data (struct cgraph_node *src, struct cgraph_node *dst,
|
||||
void *data ATTRIBUTE_UNUSED)
|
||||
{
|
||||
if (get_function_state (src))
|
||||
{
|
||||
funct_state l = XNEW (struct funct_state_d);
|
||||
gcc_assert (!get_function_state (dst));
|
||||
memcpy (l, get_function_state (src), sizeof (*l));
|
||||
set_function_state (dst, l);
|
||||
}
|
||||
}
|
||||
|
||||
/* Called when new clone is inserted to callgraph late. */
|
||||
|
||||
static void
|
||||
remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
|
||||
{
|
||||
if (get_function_state (node))
|
||||
{
|
||||
free (get_function_state (node));
|
||||
set_function_state (node, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Analyze each function in the cgraph to see if it is locally PURE or
|
||||
CONST. */
|
||||
@ -703,9 +735,12 @@ generate_summary (void)
|
||||
{
|
||||
struct cgraph_node *node;
|
||||
|
||||
node_removal_hook_holder =
|
||||
cgraph_add_node_removal_hook (&remove_node_data, NULL);
|
||||
node_duplication_hook_holder =
|
||||
cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
|
||||
function_insertion_hook_holder =
|
||||
cgraph_add_function_insertion_hook (&add_new_function, NULL);
|
||||
init_state ();
|
||||
/* There are some shared nodes, in particular the initializers on
|
||||
static declarations. We do not need to scan them more than once
|
||||
since all we would be interested in are the addressof
|
||||
@ -714,14 +749,12 @@ generate_summary (void)
|
||||
|
||||
/* Process all of the functions.
|
||||
|
||||
We do not want to process any of the clones so we check that this
|
||||
is a master clone. However, we do NOT process any
|
||||
AVAIL_OVERWRITABLE functions (these are never clones) we cannot
|
||||
We do NOT process any AVAIL_OVERWRITABLE functions, we cannot
|
||||
guarantee that what we learn about the one we see will be true
|
||||
for the one that overrides it.
|
||||
*/
|
||||
for (node = cgraph_nodes; node; node = node->next)
|
||||
if (node->analyzed && cgraph_is_master_clone (node))
|
||||
if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE)
|
||||
analyze_function (node);
|
||||
|
||||
pointer_set_destroy (visited_nodes);
|
||||
@ -745,6 +778,8 @@ propagate (void)
|
||||
struct ipa_dfs_info * w_info;
|
||||
|
||||
cgraph_remove_function_insertion_hook (function_insertion_hook_holder);
|
||||
cgraph_remove_node_duplication_hook (node_duplication_hook_holder);
|
||||
cgraph_remove_node_removal_hook (node_removal_hook_holder);
|
||||
order_pos = ipa_utils_reduced_inorder (order, true, false);
|
||||
if (dump_file)
|
||||
{
|
||||
@ -788,12 +823,8 @@ propagate (void)
|
||||
for (e = w->callees; e; e = e->next_callee)
|
||||
{
|
||||
struct cgraph_node *y = e->callee;
|
||||
/* Only look at the master nodes and skip external nodes. */
|
||||
y = cgraph_master_clone (y);
|
||||
|
||||
if (w == y)
|
||||
looping = true;
|
||||
if (y)
|
||||
if (cgraph_function_body_availability (y) > AVAIL_OVERWRITABLE)
|
||||
{
|
||||
funct_state y_l = get_function_state (y);
|
||||
if (pure_const_state < y_l->pure_const_state)
|
||||
@ -861,11 +892,12 @@ propagate (void)
|
||||
free (node->aux);
|
||||
node->aux = NULL;
|
||||
}
|
||||
if (node->analyzed && cgraph_is_master_clone (node))
|
||||
if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE)
|
||||
free (get_function_state (node));
|
||||
}
|
||||
|
||||
free (order);
|
||||
VEC_free (funct_state, heap, funct_state_vec);
|
||||
finish_state ();
|
||||
return 0;
|
||||
}
|
||||
@ -873,7 +905,7 @@ propagate (void)
|
||||
static bool
|
||||
gate_pure_const (void)
|
||||
{
|
||||
return (flag_ipa_pure_const
|
||||
return (flag_ipa_pure_const
|
||||
/* Don't bother doing anything if the program has errors. */
|
||||
&& !(errorcount || sorrycount));
|
||||
}
|
||||
|
@ -69,6 +69,52 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "diagnostic.h"
|
||||
#include "langhooks.h"
|
||||
|
||||
/* The static variables defined within the compilation unit that are
|
||||
loaded or stored directly by function that owns this structure. */
|
||||
|
||||
struct ipa_reference_local_vars_info_d
|
||||
{
|
||||
bitmap statics_read;
|
||||
bitmap statics_written;
|
||||
|
||||
/* Set when this function calls another function external to the
|
||||
compilation unit or if the function has a asm clobber of memory.
|
||||
In general, such calls are modeled as reading and writing all
|
||||
variables (both bits on) but sometime there are attributes on the
|
||||
called function so we can do better. */
|
||||
bool calls_read_all;
|
||||
bool calls_write_all;
|
||||
};
|
||||
|
||||
/* Statics that are read and written by some set of functions. The
|
||||
local ones are based on the loads and stores local to the function.
|
||||
The global ones are based on the local info as well as the
|
||||
transitive closure of the functions that are called. The
|
||||
structures are separated to allow the global structures to be
|
||||
shared between several functions since every function within a
|
||||
strongly connected component will have the same information. This
|
||||
sharing saves both time and space in the computation of the vectors
|
||||
as well as their translation from decl_uid form to ann_uid
|
||||
form. */
|
||||
|
||||
struct ipa_reference_global_vars_info_d
|
||||
{
|
||||
bitmap statics_read;
|
||||
bitmap statics_written;
|
||||
bitmap statics_not_read;
|
||||
bitmap statics_not_written;
|
||||
};
|
||||
|
||||
typedef struct ipa_reference_local_vars_info_d *ipa_reference_local_vars_info_t;
|
||||
typedef struct ipa_reference_global_vars_info_d *ipa_reference_global_vars_info_t;
|
||||
struct ipa_reference_vars_info_d
|
||||
{
|
||||
ipa_reference_local_vars_info_t local;
|
||||
ipa_reference_global_vars_info_t global;
|
||||
};
|
||||
|
||||
typedef struct ipa_reference_vars_info_d *ipa_reference_vars_info_t;
|
||||
|
||||
/* This splay tree contains all of the static variables that are
|
||||
being considered by the compilation level alias analysis. For
|
||||
module_at_a_time compilation, this is the set of static but not
|
||||
@ -101,6 +147,8 @@ static bitmap_obstack global_info_obstack;
|
||||
|
||||
/* Holders of ipa cgraph hooks: */
|
||||
static struct cgraph_node_hook_list *function_insertion_hook_holder;
|
||||
static struct cgraph_2node_hook_list *node_duplication_hook_holder;
|
||||
static struct cgraph_node_hook_list *node_removal_hook_holder;
|
||||
|
||||
enum initialization_status_t
|
||||
{
|
||||
@ -111,19 +159,37 @@ enum initialization_status_t
|
||||
|
||||
tree memory_identifier_string;
|
||||
|
||||
/* Vector where the reference var infos are actually stored. */
|
||||
DEF_VEC_P (ipa_reference_vars_info_t);
|
||||
DEF_VEC_ALLOC_P (ipa_reference_vars_info_t, heap);
|
||||
static VEC (ipa_reference_vars_info_t, heap) *ipa_reference_vars_vector;
|
||||
|
||||
/* Return the ipa_reference_vars structure starting from the cgraph NODE. */
|
||||
static inline ipa_reference_vars_info_t
|
||||
get_reference_vars_info_from_cgraph (struct cgraph_node * node)
|
||||
get_reference_vars_info (struct cgraph_node *node)
|
||||
{
|
||||
return get_function_ann (node->decl)->reference_vars_info;
|
||||
if (!ipa_reference_vars_vector
|
||||
|| VEC_length (ipa_reference_vars_info_t, ipa_reference_vars_vector) <= (unsigned int)node->uid)
|
||||
return NULL;
|
||||
return VEC_index (ipa_reference_vars_info_t, ipa_reference_vars_vector, node->uid);
|
||||
}
|
||||
|
||||
/* Return the ipa_reference_vars structure starting from the cgraph NODE. */
|
||||
static inline void
|
||||
set_reference_vars_info (struct cgraph_node *node, ipa_reference_vars_info_t info)
|
||||
{
|
||||
if (!ipa_reference_vars_vector
|
||||
|| VEC_length (ipa_reference_vars_info_t, ipa_reference_vars_vector) <= (unsigned int)node->uid)
|
||||
VEC_safe_grow_cleared (ipa_reference_vars_info_t, heap, ipa_reference_vars_vector, node->uid + 1);
|
||||
VEC_replace (ipa_reference_vars_info_t, ipa_reference_vars_vector, node->uid, info);
|
||||
}
|
||||
|
||||
/* Get a bitmap that contains all of the locally referenced static
|
||||
variables for function FN. */
|
||||
static ipa_reference_local_vars_info_t
|
||||
get_local_reference_vars_info (tree fn)
|
||||
get_local_reference_vars_info (struct cgraph_node *fn)
|
||||
{
|
||||
ipa_reference_vars_info_t info = get_function_ann (fn)->reference_vars_info;
|
||||
ipa_reference_vars_info_t info = get_reference_vars_info (fn);
|
||||
|
||||
if (info)
|
||||
return info->local;
|
||||
@ -136,9 +202,9 @@ get_local_reference_vars_info (tree fn)
|
||||
variables for function FN. */
|
||||
|
||||
static ipa_reference_global_vars_info_t
|
||||
get_global_reference_vars_info (tree fn)
|
||||
get_global_reference_vars_info (struct cgraph_node *fn)
|
||||
{
|
||||
ipa_reference_vars_info_t info = get_function_ann (fn)->reference_vars_info;
|
||||
ipa_reference_vars_info_t info = get_reference_vars_info (fn);
|
||||
|
||||
if (info)
|
||||
return info->global;
|
||||
@ -147,40 +213,12 @@ get_global_reference_vars_info (tree fn)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Return a bitmap indexed by VAR_DECL uid for the static variables
|
||||
that may be read locally by the execution of the function fn.
|
||||
Returns NULL if no data is available. */
|
||||
|
||||
bitmap
|
||||
ipa_reference_get_read_local (tree fn)
|
||||
{
|
||||
ipa_reference_local_vars_info_t l = get_local_reference_vars_info (fn);
|
||||
if (l)
|
||||
return l->statics_read;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Return a bitmap indexed by VAR_DECL uid for the static variables
|
||||
that may be written locally by the execution of the function fn.
|
||||
Returns NULL if no data is available. */
|
||||
|
||||
bitmap
|
||||
ipa_reference_get_written_local (tree fn)
|
||||
{
|
||||
ipa_reference_local_vars_info_t l = get_local_reference_vars_info (fn);
|
||||
if (l)
|
||||
return l->statics_written;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Return a bitmap indexed by VAR_DECL uid for the static variables
|
||||
that are read during the execution of the function FN. Returns
|
||||
NULL if no data is available. */
|
||||
|
||||
bitmap
|
||||
ipa_reference_get_read_global (tree fn)
|
||||
ipa_reference_get_read_global (struct cgraph_node *fn)
|
||||
{
|
||||
ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
|
||||
if (g)
|
||||
@ -195,7 +233,7 @@ ipa_reference_get_read_global (tree fn)
|
||||
call. Returns NULL if no data is available. */
|
||||
|
||||
bitmap
|
||||
ipa_reference_get_written_global (tree fn)
|
||||
ipa_reference_get_written_global (struct cgraph_node *fn)
|
||||
{
|
||||
ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
|
||||
if (g)
|
||||
@ -209,7 +247,7 @@ ipa_reference_get_written_global (tree fn)
|
||||
NULL if no data is available. */
|
||||
|
||||
bitmap
|
||||
ipa_reference_get_not_read_global (tree fn)
|
||||
ipa_reference_get_not_read_global (struct cgraph_node *fn)
|
||||
{
|
||||
ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
|
||||
if (g)
|
||||
@ -224,7 +262,7 @@ ipa_reference_get_not_read_global (tree fn)
|
||||
call. Returns NULL if no data is available. */
|
||||
|
||||
bitmap
|
||||
ipa_reference_get_not_written_global (tree fn)
|
||||
ipa_reference_get_not_written_global (struct cgraph_node *fn)
|
||||
{
|
||||
ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
|
||||
if (g)
|
||||
@ -360,7 +398,7 @@ check_call (ipa_reference_local_vars_info_t local, gimple stmt)
|
||||
avail = cgraph_function_body_availability (callee);
|
||||
}
|
||||
|
||||
if (avail == AVAIL_NOT_AVAILABLE || avail == AVAIL_OVERWRITABLE)
|
||||
if (avail <= AVAIL_OVERWRITABLE)
|
||||
if (local)
|
||||
{
|
||||
if (flags & ECF_CONST)
|
||||
@ -393,7 +431,7 @@ scan_stmt_for_static_refs (gimple_stmt_iterator *gsip,
|
||||
bitmap_iterator bi;
|
||||
|
||||
if (fn)
|
||||
local = get_reference_vars_info_from_cgraph (fn)->local;
|
||||
local = get_reference_vars_info (fn)->local;
|
||||
|
||||
if (gimple_loaded_syms (stmt))
|
||||
EXECUTE_IF_SET_IN_BITMAP (gimple_loaded_syms (stmt), 0, i, bi)
|
||||
@ -472,30 +510,30 @@ get_static_name (int index)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Or in all of the bits from every callee into X, the caller's, bit
|
||||
vector. There are several cases to check to avoid the sparse
|
||||
/* Or in all of the bits from every callee of X into X_GLOBAL, the caller's cycle,
|
||||
bit vector. There are several cases to check to avoid the sparse
|
||||
bitmap oring. */
|
||||
|
||||
static void
|
||||
propagate_bits (struct cgraph_node *x)
|
||||
propagate_bits (ipa_reference_global_vars_info_t x_global, struct cgraph_node *x)
|
||||
{
|
||||
ipa_reference_vars_info_t x_info = get_reference_vars_info_from_cgraph (x);
|
||||
ipa_reference_global_vars_info_t x_global = x_info->global;
|
||||
|
||||
struct cgraph_edge *e;
|
||||
for (e = x->callees; e; e = e->next_callee)
|
||||
{
|
||||
struct cgraph_node *y = e->callee;
|
||||
|
||||
/* Only look at the master nodes and skip external nodes. */
|
||||
y = cgraph_master_clone (y);
|
||||
if (y)
|
||||
if (cgraph_function_body_availability (e->callee) > AVAIL_OVERWRITABLE)
|
||||
{
|
||||
if (get_reference_vars_info_from_cgraph (y))
|
||||
if (get_reference_vars_info (y))
|
||||
{
|
||||
ipa_reference_vars_info_t y_info
|
||||
= get_reference_vars_info_from_cgraph (y);
|
||||
= get_reference_vars_info (y);
|
||||
ipa_reference_global_vars_info_t y_global = y_info->global;
|
||||
|
||||
/* Calls in current cycle do not have global computed yet. */
|
||||
if (!y_info->global)
|
||||
continue;
|
||||
|
||||
if (x_global->statics_read
|
||||
!= all_module_statics)
|
||||
@ -539,70 +577,6 @@ propagate_bits (struct cgraph_node *x)
|
||||
}
|
||||
}
|
||||
|
||||
/* Look at all of the callees of X to see which ones represent inlined
|
||||
calls. For each of these callees, merge their local info into
|
||||
TARGET and check their children recursively.
|
||||
|
||||
This function goes away when Jan changes the inliner and IPA
|
||||
analysis so that this is not run between the time when inlining
|
||||
decisions are made and when the inlining actually occurs. */
|
||||
|
||||
static void
|
||||
merge_callee_local_info (struct cgraph_node *target,
|
||||
struct cgraph_node *x)
|
||||
{
|
||||
struct cgraph_edge *e;
|
||||
ipa_reference_local_vars_info_t x_l =
|
||||
get_reference_vars_info_from_cgraph (target)->local;
|
||||
|
||||
/* Make the world safe for tail recursion. */
|
||||
struct ipa_dfs_info *node_info = (struct ipa_dfs_info *) x->aux;
|
||||
|
||||
if (node_info->aux)
|
||||
return;
|
||||
|
||||
node_info->aux = x;
|
||||
|
||||
for (e = x->callees; e; e = e->next_callee)
|
||||
{
|
||||
struct cgraph_node *y = e->callee;
|
||||
if (y->global.inlined_to)
|
||||
{
|
||||
ipa_reference_vars_info_t y_info;
|
||||
ipa_reference_local_vars_info_t y_l;
|
||||
struct cgraph_node* orig_y = y;
|
||||
|
||||
y = cgraph_master_clone (y);
|
||||
if (y)
|
||||
{
|
||||
y_info = get_reference_vars_info_from_cgraph (y);
|
||||
y_l = y_info->local;
|
||||
if (x_l != y_l)
|
||||
{
|
||||
bitmap_ior_into (x_l->statics_read,
|
||||
y_l->statics_read);
|
||||
bitmap_ior_into (x_l->statics_written,
|
||||
y_l->statics_written);
|
||||
}
|
||||
x_l->calls_read_all |= y_l->calls_read_all;
|
||||
x_l->calls_write_all |= y_l->calls_write_all;
|
||||
merge_callee_local_info (target, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "suspect inlining of ");
|
||||
dump_cgraph_node (stderr, orig_y);
|
||||
fprintf(stderr, "\ninto ");
|
||||
dump_cgraph_node (stderr, target);
|
||||
dump_cgraph (stderr);
|
||||
gcc_assert(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
node_info->aux = NULL;
|
||||
}
|
||||
|
||||
/* The init routine for analyzing global static variable usage. See
|
||||
comments at top for description. */
|
||||
static void
|
||||
@ -653,10 +627,9 @@ init_function_info (struct cgraph_node *fn)
|
||||
= XCNEW (struct ipa_reference_vars_info_d);
|
||||
ipa_reference_local_vars_info_t l
|
||||
= XCNEW (struct ipa_reference_local_vars_info_d);
|
||||
tree decl = fn->decl;
|
||||
|
||||
/* Add the info to the tree's annotation. */
|
||||
get_function_ann (decl)->reference_vars_info = info;
|
||||
set_reference_vars_info (fn, info);
|
||||
|
||||
info->local = l;
|
||||
l->statics_read = BITMAP_ALLOC (&local_info_obstack);
|
||||
@ -728,18 +701,12 @@ analyze_function (struct cgraph_node *fn)
|
||||
current_function_decl = NULL;
|
||||
}
|
||||
|
||||
/* If FN is avail == AVAIL_OVERWRITABLE, replace the effects bit
|
||||
vectors with worst case bit vectors. We had to analyze it above to
|
||||
find out if it took the address of any statics. However, now that
|
||||
we know that, we can get rid of all of the other side effects. */
|
||||
|
||||
/* Remove local data associated with function FN. */
|
||||
static void
|
||||
clean_function (struct cgraph_node *fn)
|
||||
clean_function_local_data (struct cgraph_node *fn)
|
||||
{
|
||||
ipa_reference_vars_info_t info = get_reference_vars_info_from_cgraph (fn);
|
||||
ipa_reference_vars_info_t info = get_reference_vars_info (fn);
|
||||
ipa_reference_local_vars_info_t l = info->local;
|
||||
ipa_reference_global_vars_info_t g = info->global;
|
||||
|
||||
if (l)
|
||||
{
|
||||
if (l->statics_read
|
||||
@ -749,8 +716,19 @@ clean_function (struct cgraph_node *fn)
|
||||
&&l->statics_written != all_module_statics)
|
||||
BITMAP_FREE (l->statics_written);
|
||||
free (l);
|
||||
info->local = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove all data associated with function FN. */
|
||||
|
||||
static void
|
||||
clean_function (struct cgraph_node *fn)
|
||||
{
|
||||
ipa_reference_vars_info_t info = get_reference_vars_info (fn);
|
||||
ipa_reference_global_vars_info_t g = info->global;
|
||||
|
||||
clean_function_local_data (fn);
|
||||
if (g)
|
||||
{
|
||||
if (g->statics_read
|
||||
@ -769,10 +747,11 @@ clean_function (struct cgraph_node *fn)
|
||||
&& g->statics_not_written != all_module_statics)
|
||||
BITMAP_FREE (g->statics_not_written);
|
||||
free (g);
|
||||
info->global = NULL;
|
||||
}
|
||||
|
||||
free (get_function_ann (fn->decl)->reference_vars_info);
|
||||
get_function_ann (fn->decl)->reference_vars_info = NULL;
|
||||
free (get_reference_vars_info (fn));
|
||||
set_reference_vars_info (fn, NULL);
|
||||
}
|
||||
|
||||
/* Called when new function is inserted to callgraph late. */
|
||||
@ -787,6 +766,76 @@ add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
|
||||
visited_nodes = NULL;
|
||||
}
|
||||
|
||||
static bitmap
|
||||
copy_local_bitmap (bitmap src)
|
||||
{
|
||||
bitmap dst;
|
||||
if (!src)
|
||||
return NULL;
|
||||
if (src == all_module_statics)
|
||||
return all_module_statics;
|
||||
dst = BITMAP_ALLOC (&local_info_obstack);
|
||||
bitmap_copy (dst, src);
|
||||
return dst;
|
||||
}
|
||||
|
||||
static bitmap
|
||||
copy_global_bitmap (bitmap src)
|
||||
{
|
||||
bitmap dst;
|
||||
if (!src)
|
||||
return NULL;
|
||||
if (src == all_module_statics)
|
||||
return all_module_statics;
|
||||
dst = BITMAP_ALLOC (&global_info_obstack);
|
||||
bitmap_copy (dst, src);
|
||||
return dst;
|
||||
}
|
||||
|
||||
/* Called when new clone is inserted to callgraph late. */
|
||||
|
||||
static void
|
||||
duplicate_node_data (struct cgraph_node *src, struct cgraph_node *dst,
|
||||
void *data ATTRIBUTE_UNUSED)
|
||||
{
|
||||
ipa_reference_global_vars_info_t ginfo;
|
||||
ipa_reference_local_vars_info_t linfo;
|
||||
ipa_reference_global_vars_info_t dst_ginfo;
|
||||
ipa_reference_local_vars_info_t dst_linfo;
|
||||
|
||||
ginfo = get_global_reference_vars_info (src);
|
||||
linfo = get_local_reference_vars_info (src);
|
||||
if (!linfo && !ginfo)
|
||||
return;
|
||||
init_function_info (dst);
|
||||
if (linfo)
|
||||
{
|
||||
dst_linfo = get_local_reference_vars_info (dst);
|
||||
dst_linfo->statics_read = copy_local_bitmap (linfo->statics_read);
|
||||
dst_linfo->statics_written = copy_local_bitmap (linfo->statics_written);
|
||||
dst_linfo->calls_read_all = linfo->calls_read_all;
|
||||
dst_linfo->calls_write_all = linfo->calls_write_all;
|
||||
}
|
||||
if (ginfo)
|
||||
{
|
||||
get_reference_vars_info (dst)->global = XCNEW (struct ipa_reference_global_vars_info_d);
|
||||
dst_ginfo = get_global_reference_vars_info (dst);
|
||||
dst_ginfo->statics_read = copy_global_bitmap (ginfo->statics_read);
|
||||
dst_ginfo->statics_written = copy_global_bitmap (ginfo->statics_written);
|
||||
dst_ginfo->statics_not_read = copy_global_bitmap (ginfo->statics_not_read);
|
||||
dst_ginfo->statics_not_written = copy_global_bitmap (ginfo->statics_not_written);
|
||||
}
|
||||
}
|
||||
|
||||
/* Called when node is removed. */
|
||||
|
||||
static void
|
||||
remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
|
||||
{
|
||||
if (get_reference_vars_info (node))
|
||||
clean_function (node);
|
||||
}
|
||||
|
||||
/* Analyze each function in the cgraph to see which global or statics
|
||||
are read or written. */
|
||||
|
||||
@ -802,6 +851,10 @@ generate_summary (void)
|
||||
|
||||
function_insertion_hook_holder =
|
||||
cgraph_add_function_insertion_hook (&add_new_function, NULL);
|
||||
node_removal_hook_holder =
|
||||
cgraph_add_node_removal_hook (&remove_node_data, NULL);
|
||||
node_duplication_hook_holder =
|
||||
cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
|
||||
ipa_init ();
|
||||
module_statics_readonly = BITMAP_ALLOC (&local_info_obstack);
|
||||
bm_temp = BITMAP_ALLOC (&local_info_obstack);
|
||||
@ -822,10 +875,7 @@ generate_summary (void)
|
||||
replaced with worst case info.
|
||||
*/
|
||||
for (node = cgraph_nodes; node; node = node->next)
|
||||
if (node->analyzed
|
||||
&& (cgraph_is_master_clone (node)
|
||||
|| (cgraph_function_body_availability (node)
|
||||
== AVAIL_OVERWRITABLE)))
|
||||
if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
|
||||
analyze_function (node);
|
||||
|
||||
pointer_set_destroy (visited_nodes);
|
||||
@ -890,13 +940,10 @@ generate_summary (void)
|
||||
}
|
||||
|
||||
for (node = cgraph_nodes; node; node = node->next)
|
||||
if (node->analyzed
|
||||
&& (cgraph_is_master_clone (node)
|
||||
|| (cgraph_function_body_availability (node)
|
||||
== AVAIL_OVERWRITABLE)))
|
||||
if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
|
||||
{
|
||||
ipa_reference_local_vars_info_t l;
|
||||
l = get_reference_vars_info_from_cgraph (node)->local;
|
||||
l = get_reference_vars_info (node)->local;
|
||||
|
||||
/* Any variables that are not in all_module_statics are
|
||||
removed from the local maps. This will include all of the
|
||||
@ -913,16 +960,13 @@ generate_summary (void)
|
||||
|
||||
if (dump_file)
|
||||
for (node = cgraph_nodes; node; node = node->next)
|
||||
if (node->analyzed
|
||||
&& (cgraph_is_master_clone (node)
|
||||
|| (cgraph_function_body_availability (node)
|
||||
== AVAIL_OVERWRITABLE)))
|
||||
if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
|
||||
{
|
||||
ipa_reference_local_vars_info_t l;
|
||||
unsigned int index;
|
||||
bitmap_iterator bi;
|
||||
|
||||
l = get_reference_vars_info_from_cgraph (node)->local;
|
||||
l = get_reference_vars_info (node)->local;
|
||||
fprintf (dump_file,
|
||||
"\nFunction name:%s/%i:",
|
||||
cgraph_node_name (node), node->uid);
|
||||
@ -940,6 +984,10 @@ generate_summary (void)
|
||||
fprintf(dump_file, "%s ",
|
||||
get_static_name (index));
|
||||
}
|
||||
if (l->calls_read_all)
|
||||
fprintf (dump_file, "\n calls read all: ");
|
||||
if (l->calls_write_all)
|
||||
fprintf (dump_file, "\n calls read all: ");
|
||||
}
|
||||
}
|
||||
|
||||
@ -981,7 +1029,7 @@ propagate (void)
|
||||
struct ipa_dfs_info * w_info;
|
||||
|
||||
node = order[i];
|
||||
node_info = get_reference_vars_info_from_cgraph (node);
|
||||
node_info = get_reference_vars_info (node);
|
||||
if (!node_info)
|
||||
{
|
||||
dump_cgraph_node (stderr, node);
|
||||
@ -989,7 +1037,7 @@ propagate (void)
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
node_info->global = node_g;
|
||||
gcc_assert (!node_info->global);
|
||||
node_l = node_info->local;
|
||||
|
||||
read_all = node_l->calls_read_all;
|
||||
@ -1002,7 +1050,7 @@ propagate (void)
|
||||
while (w)
|
||||
{
|
||||
ipa_reference_local_vars_info_t w_l =
|
||||
get_reference_vars_info_from_cgraph (w)->local;
|
||||
get_reference_vars_info (w)->local;
|
||||
read_all |= w_l->calls_read_all;
|
||||
write_all |= w_l->calls_write_all;
|
||||
|
||||
@ -1029,16 +1077,14 @@ propagate (void)
|
||||
node_l->statics_written);
|
||||
}
|
||||
|
||||
propagate_bits (node_g, node);
|
||||
w_info = (struct ipa_dfs_info *) node->aux;
|
||||
w = w_info->next_cycle;
|
||||
while (w)
|
||||
{
|
||||
ipa_reference_vars_info_t w_ri =
|
||||
get_reference_vars_info_from_cgraph (w);
|
||||
get_reference_vars_info (w);
|
||||
ipa_reference_local_vars_info_t w_l = w_ri->local;
|
||||
|
||||
/* All nodes within a cycle share the same global info bitmaps. */
|
||||
w_ri->global = node_g;
|
||||
|
||||
/* These global bitmaps are initialized from the local info
|
||||
of all of the nodes in the region. However there is no
|
||||
@ -1050,36 +1096,25 @@ propagate (void)
|
||||
if (!write_all)
|
||||
bitmap_ior_into (node_g->statics_written,
|
||||
w_l->statics_written);
|
||||
propagate_bits (node_g, w);
|
||||
w_info = (struct ipa_dfs_info *) w->aux;
|
||||
w = w_info->next_cycle;
|
||||
}
|
||||
|
||||
w = node;
|
||||
while (w)
|
||||
{
|
||||
propagate_bits (w);
|
||||
w_info = (struct ipa_dfs_info *) w->aux;
|
||||
w = w_info->next_cycle;
|
||||
}
|
||||
}
|
||||
|
||||
/* Need to fix up the local information sets. The information that
|
||||
has been gathered so far is preinlining. However, the
|
||||
compilation will progress post inlining so the local sets for the
|
||||
inlined calls need to be merged into the callers. Note that the
|
||||
local sets are not shared between all of the nodes in a cycle so
|
||||
those nodes in the cycle must be processed explicitly. */
|
||||
for (i = 0; i < order_pos; i++ )
|
||||
{
|
||||
struct ipa_dfs_info * w_info;
|
||||
node = order[i];
|
||||
merge_callee_local_info (node, node);
|
||||
|
||||
/* All nodes within a cycle have the same global info bitmaps. */
|
||||
node_info->global = node_g;
|
||||
w_info = (struct ipa_dfs_info *) node->aux;
|
||||
w = w_info->next_cycle;
|
||||
while (w)
|
||||
{
|
||||
merge_callee_local_info (w, w);
|
||||
ipa_reference_vars_info_t w_ri =
|
||||
get_reference_vars_info (w);
|
||||
|
||||
gcc_assert (!w_ri->global);
|
||||
w_ri->global = XCNEW (struct ipa_reference_global_vars_info_d);
|
||||
w_ri->global->statics_read = copy_global_bitmap (node_g->statics_read);
|
||||
w_ri->global->statics_written = copy_global_bitmap (node_g->statics_written);
|
||||
|
||||
w_info = (struct ipa_dfs_info *) w->aux;
|
||||
w = w_info->next_cycle;
|
||||
}
|
||||
@ -1097,7 +1132,7 @@ propagate (void)
|
||||
struct ipa_dfs_info * w_info;
|
||||
|
||||
node = order[i];
|
||||
node_info = get_reference_vars_info_from_cgraph (node);
|
||||
node_info = get_reference_vars_info (node);
|
||||
node_g = node_info->global;
|
||||
node_l = node_info->local;
|
||||
fprintf (dump_file,
|
||||
@ -1123,7 +1158,7 @@ propagate (void)
|
||||
while (w)
|
||||
{
|
||||
ipa_reference_vars_info_t w_ri =
|
||||
get_reference_vars_info_from_cgraph (w);
|
||||
get_reference_vars_info (w);
|
||||
ipa_reference_local_vars_info_t w_l = w_ri->local;
|
||||
fprintf (dump_file, "\n next cycle: %s/%i ",
|
||||
cgraph_node_name (w), w->uid);
|
||||
@ -1170,7 +1205,7 @@ propagate (void)
|
||||
ipa_reference_vars_info_t node_info;
|
||||
ipa_reference_global_vars_info_t node_g;
|
||||
node = order[i];
|
||||
node_info = get_reference_vars_info_from_cgraph (node);
|
||||
node_info = get_reference_vars_info (node);
|
||||
node_g = node_info->global;
|
||||
|
||||
/* Create the complimentary sets. These are more useful for
|
||||
@ -1179,11 +1214,9 @@ propagate (void)
|
||||
node_g->statics_not_written = BITMAP_ALLOC (&global_info_obstack);
|
||||
|
||||
if (node_g->statics_read != all_module_statics)
|
||||
{
|
||||
bitmap_and_compl (node_g->statics_not_read,
|
||||
all_module_statics,
|
||||
node_g->statics_read);
|
||||
}
|
||||
bitmap_and_compl (node_g->statics_not_read,
|
||||
all_module_statics,
|
||||
node_g->statics_read);
|
||||
|
||||
if (node_g->statics_written
|
||||
!= all_module_statics)
|
||||
@ -1197,7 +1230,7 @@ propagate (void)
|
||||
for (node = cgraph_nodes; node; node = node->next)
|
||||
{
|
||||
ipa_reference_vars_info_t node_info;
|
||||
node_info = get_reference_vars_info_from_cgraph (node);
|
||||
node_info = get_reference_vars_info (node);
|
||||
/* Get rid of the aux information. */
|
||||
|
||||
if (node->aux)
|
||||
@ -1206,19 +1239,10 @@ propagate (void)
|
||||
node->aux = NULL;
|
||||
}
|
||||
|
||||
if (node->analyzed
|
||||
&& (cgraph_function_body_availability (node) == AVAIL_OVERWRITABLE))
|
||||
if (cgraph_function_body_availability (node) == AVAIL_OVERWRITABLE)
|
||||
clean_function (node);
|
||||
else if (node_info)
|
||||
{
|
||||
/* Remove local info we no longer need. */
|
||||
if (node_info->local->statics_read
|
||||
&& node_info->local->statics_read != all_module_statics)
|
||||
BITMAP_FREE (node_info->local->statics_read);
|
||||
if (node_info->local->statics_written
|
||||
&& node_info->local->statics_written != all_module_statics)
|
||||
BITMAP_FREE (node_info->local->statics_written);
|
||||
}
|
||||
clean_function_local_data (node);
|
||||
}
|
||||
bitmap_obstack_release (&local_info_obstack);
|
||||
return 0;
|
||||
|
@ -23,60 +23,11 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "bitmap.h"
|
||||
#include "tree.h"
|
||||
|
||||
/* The static variables defined within the compilation unit that are
|
||||
loaded or stored directly by function that owns this structure. */
|
||||
|
||||
struct ipa_reference_local_vars_info_d
|
||||
{
|
||||
bitmap statics_read;
|
||||
bitmap statics_written;
|
||||
|
||||
/* Set when this function calls another function external to the
|
||||
compilation unit or if the function has a asm clobber of memory.
|
||||
In general, such calls are modeled as reading and writing all
|
||||
variables (both bits on) but sometime there are attributes on the
|
||||
called function so we can do better. */
|
||||
bool calls_read_all;
|
||||
bool calls_write_all;
|
||||
};
|
||||
|
||||
struct ipa_reference_global_vars_info_d
|
||||
{
|
||||
bitmap statics_read;
|
||||
bitmap statics_written;
|
||||
bitmap statics_not_read;
|
||||
bitmap statics_not_written;
|
||||
};
|
||||
|
||||
/* Statics that are read and written by some set of functions. The
|
||||
local ones are based on the loads and stores local to the function.
|
||||
The global ones are based on the local info as well as the
|
||||
transitive closure of the functions that are called. The
|
||||
structures are separated to allow the global structures to be
|
||||
shared between several functions since every function within a
|
||||
strongly connected component will have the same information. This
|
||||
sharing saves both time and space in the computation of the vectors
|
||||
as well as their translation from decl_uid form to ann_uid
|
||||
form. */
|
||||
|
||||
typedef struct ipa_reference_local_vars_info_d *ipa_reference_local_vars_info_t;
|
||||
typedef struct ipa_reference_global_vars_info_d *ipa_reference_global_vars_info_t;
|
||||
|
||||
struct ipa_reference_vars_info_d
|
||||
{
|
||||
ipa_reference_local_vars_info_t local;
|
||||
ipa_reference_global_vars_info_t global;
|
||||
};
|
||||
|
||||
typedef struct ipa_reference_vars_info_d *ipa_reference_vars_info_t;
|
||||
|
||||
/* In ipa-reference.c */
|
||||
bitmap ipa_reference_get_read_local (tree fn);
|
||||
bitmap ipa_reference_get_written_local (tree fn);
|
||||
bitmap ipa_reference_get_read_global (tree fn);
|
||||
bitmap ipa_reference_get_written_global (tree fn);
|
||||
bitmap ipa_reference_get_not_read_global (tree fn);
|
||||
bitmap ipa_reference_get_not_written_global (tree fn);
|
||||
bitmap ipa_reference_get_read_global (struct cgraph_node *fn);
|
||||
bitmap ipa_reference_get_written_global (struct cgraph_node *fn);
|
||||
bitmap ipa_reference_get_not_read_global (struct cgraph_node *fn);
|
||||
bitmap ipa_reference_get_not_written_global (struct cgraph_node *fn);
|
||||
|
||||
#endif /* GCC_IPA_REFERENCE_H */
|
||||
|
||||
|
@ -100,10 +100,8 @@ searchc (struct searchc_env* env, struct cgraph_node *v)
|
||||
{
|
||||
struct ipa_dfs_info * w_info;
|
||||
struct cgraph_node *w = edge->callee;
|
||||
/* Bypass the clones and only look at the master node. Skip
|
||||
external and other bogus nodes. */
|
||||
w = cgraph_master_clone (w);
|
||||
if (w && w->aux)
|
||||
|
||||
if (w->aux && cgraph_function_body_availability (edge->callee) > AVAIL_OVERWRITABLE)
|
||||
{
|
||||
w_info = (struct ipa_dfs_info *) w->aux;
|
||||
if (w_info->new_node)
|
||||
@ -168,27 +166,29 @@ ipa_utils_reduced_inorder (struct cgraph_node **order,
|
||||
env.reduce = reduce;
|
||||
|
||||
for (node = cgraph_nodes; node; node = node->next)
|
||||
if ((node->analyzed)
|
||||
&& (cgraph_is_master_clone (node)
|
||||
|| (allow_overwritable
|
||||
&& (cgraph_function_body_availability (node) ==
|
||||
AVAIL_OVERWRITABLE))))
|
||||
{
|
||||
/* Reuse the info if it is already there. */
|
||||
struct ipa_dfs_info *info = (struct ipa_dfs_info *) node->aux;
|
||||
if (!info)
|
||||
info = XCNEW (struct ipa_dfs_info);
|
||||
info->new_node = true;
|
||||
info->on_stack = false;
|
||||
info->next_cycle = NULL;
|
||||
node->aux = info;
|
||||
|
||||
splay_tree_insert (env.nodes_marked_new,
|
||||
(splay_tree_key)node->uid,
|
||||
(splay_tree_value)node);
|
||||
}
|
||||
else
|
||||
node->aux = NULL;
|
||||
{
|
||||
enum availability avail = cgraph_function_body_availability (node);
|
||||
|
||||
if (avail > AVAIL_OVERWRITABLE
|
||||
|| (allow_overwritable
|
||||
&& (avail == AVAIL_OVERWRITABLE)))
|
||||
{
|
||||
/* Reuse the info if it is already there. */
|
||||
struct ipa_dfs_info *info = (struct ipa_dfs_info *) node->aux;
|
||||
if (!info)
|
||||
info = XCNEW (struct ipa_dfs_info);
|
||||
info->new_node = true;
|
||||
info->on_stack = false;
|
||||
info->next_cycle = NULL;
|
||||
node->aux = info;
|
||||
|
||||
splay_tree_insert (env.nodes_marked_new,
|
||||
(splay_tree_key)node->uid,
|
||||
(splay_tree_value)node);
|
||||
}
|
||||
else
|
||||
node->aux = NULL;
|
||||
}
|
||||
result = splay_tree_min (env.nodes_marked_new);
|
||||
while (result)
|
||||
{
|
||||
|
@ -1653,8 +1653,8 @@ add_call_clobber_ops (gimple stmt, tree callee ATTRIBUTE_UNUSED)
|
||||
/* Get info for local and module level statics. There is a bit
|
||||
set for each static if the call being processed does not read
|
||||
or write that variable. */
|
||||
not_read_b = callee ? ipa_reference_get_not_read_global (callee) : NULL;
|
||||
not_written_b = callee ? ipa_reference_get_not_written_global (callee) : NULL;
|
||||
not_read_b = callee ? ipa_reference_get_not_read_global (cgraph_node (callee)) : NULL;
|
||||
not_written_b = callee ? ipa_reference_get_not_written_global (cgraph_node (callee)) : NULL;
|
||||
|
||||
/* Add a VDEF operand for every call clobbered variable. */
|
||||
EXECUTE_IF_SET_IN_BITMAP (gimple_call_clobbered_vars (cfun), 0, u, bi)
|
||||
@ -1705,7 +1705,7 @@ add_call_read_ops (gimple stmt, tree callee ATTRIBUTE_UNUSED)
|
||||
if (gimple_call_flags (stmt) & ECF_CONST)
|
||||
return;
|
||||
|
||||
not_read_b = callee ? ipa_reference_get_not_read_global (callee) : NULL;
|
||||
not_read_b = callee ? ipa_reference_get_not_read_global (cgraph_node (callee)) : NULL;
|
||||
|
||||
/* For pure functions we compute non-escaped uses separately. */
|
||||
if (gimple_call_flags (stmt) & ECF_PURE)
|
||||
|
Loading…
x
Reference in New Issue
Block a user