#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "tree-flow.h"
#include "tree-inline.h"
#include "tree-pass.h"
#include "langhooks.h"
#include "pointer-set.h"
#include "ggc.h"
#include "ipa-utils.h"
#include "ipa-reference.h"
#include "c-common.h"
#include "tree-gimple.h"
#include "cgraph.h"
#include "output.h"
#include "flags.h"
#include "timevar.h"
#include "diagnostic.h"
#include "langhooks.h"
static GTY((param1_is(int), param2_is(tree)))
splay_tree reference_vars_to_consider;
static bitmap module_statics_escape;
static bitmap module_statics_written;
static bitmap all_module_statics;
static struct pointer_set_t *visited_nodes;
static bitmap_obstack ipa_obstack;
enum initialization_status_t
{
UNINITIALIZED,
RUNNING,
FINISHED
};
tree memory_identifier_string;
static inline ipa_reference_vars_info_t
get_reference_vars_info_from_cgraph (struct cgraph_node * node)
{
return get_function_ann (node->decl)->reference_vars_info;
}
static ipa_reference_local_vars_info_t
get_local_reference_vars_info (tree fn)
{
ipa_reference_vars_info_t info = get_function_ann (fn)->reference_vars_info;
if (info)
return info->local;
else
return NULL;
}
static ipa_reference_global_vars_info_t
get_global_reference_vars_info (tree fn)
{
ipa_reference_vars_info_t info = get_function_ann (fn)->reference_vars_info;
if (info)
return info->global;
else
return NULL;
}
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;
}
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;
}
bitmap
ipa_reference_get_read_global (tree fn)
{
ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
if (g)
return g->statics_read;
else
return NULL;
}
bitmap
ipa_reference_get_written_global (tree fn)
{
ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
if (g)
return g->statics_written;
else
return NULL;
}
bitmap
ipa_reference_get_not_read_global (tree fn)
{
ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
if (g)
return g->statics_not_read;
else
return NULL;
}
bitmap
ipa_reference_get_not_written_global (tree fn)
{
ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
if (g)
return g->statics_not_written;
else
return NULL;
}
static inline void
add_static_var (tree var)
{
int uid = DECL_UID (var);
if (!bitmap_bit_p (all_module_statics, uid))
{
splay_tree_insert (reference_vars_to_consider,
uid, (splay_tree_value)var);
bitmap_set_bit (all_module_statics, uid);
}
}
static inline bool
has_proper_scope_for_analysis (tree t)
{
if (lookup_attribute ("used", DECL_ATTRIBUTES (t)))
return false;
if (TREE_THIS_VOLATILE (t))
return false;
if (!TREE_STATIC (t) && !DECL_EXTERNAL (t))
return false;
if (DECL_EXTERNAL (t) || TREE_PUBLIC (t))
return false;
if (!bitmap_bit_p (all_module_statics, DECL_UID (t)))
add_static_var (t);
return true;
}
static void
check_operand (ipa_reference_local_vars_info_t local,
tree t, bool checking_write)
{
if (!t) return;
if ((TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == FUNCTION_DECL)
&& (has_proper_scope_for_analysis (t)))
{
if (checking_write)
{
if (local)
bitmap_set_bit (local->statics_written, DECL_UID (t));
bitmap_set_bit (module_statics_written, DECL_UID (t));
}
else if (local)
bitmap_set_bit (local->statics_read, DECL_UID (t));
}
}
static void
check_tree (ipa_reference_local_vars_info_t local, tree t, bool checking_write)
{
if ((TREE_CODE (t) == EXC_PTR_EXPR) || (TREE_CODE (t) == FILTER_EXPR))
return;
while (TREE_CODE (t) == REALPART_EXPR
|| TREE_CODE (t) == IMAGPART_EXPR
|| handled_component_p (t))
{
if (TREE_CODE (t) == ARRAY_REF)
check_operand (local, TREE_OPERAND (t, 1), false);
t = TREE_OPERAND (t, 0);
}
if (INDIRECT_REF_P (t))
check_tree (local, TREE_OPERAND (t, 0), false);
if (SSA_VAR_P (t))
check_operand (local, t, checking_write);
}
static void
look_for_address_of (tree t)
{
if (TREE_CODE (t) == ADDR_EXPR)
{
tree x = get_base_var (t);
if (TREE_CODE (x) == VAR_DECL || TREE_CODE (x) == FUNCTION_DECL)
if (has_proper_scope_for_analysis (x))
bitmap_set_bit (module_statics_escape, DECL_UID (x));
}
}
static void
check_rhs_var (ipa_reference_local_vars_info_t local, tree t)
{
look_for_address_of (t);
if (local == NULL)
return;
check_tree(local, t, false);
}
static void
check_lhs_var (ipa_reference_local_vars_info_t local, tree t)
{
if (local == NULL)
return;
check_tree(local, t, true);
}
static void
get_asm_expr_operands (ipa_reference_local_vars_info_t local, tree stmt)
{
int noutputs = list_length (ASM_OUTPUTS (stmt));
const char **oconstraints
= (const char **) alloca ((noutputs) * sizeof (const char *));
int i;
tree link;
const char *constraint;
bool allows_mem, allows_reg, is_inout;
for (i=0, link = ASM_OUTPUTS (stmt); link; ++i, link = TREE_CHAIN (link))
{
oconstraints[i] = constraint
= TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
parse_output_constraint (&constraint, i, 0, 0,
&allows_mem, &allows_reg, &is_inout);
check_lhs_var (local, TREE_VALUE (link));
}
for (link = ASM_INPUTS (stmt); link; link = TREE_CHAIN (link))
{
constraint
= TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
parse_input_constraint (&constraint, 0, 0, noutputs, 0,
oconstraints, &allows_mem, &allows_reg);
check_rhs_var (local, TREE_VALUE (link));
}
for (link = ASM_CLOBBERS (stmt); link; link = TREE_CHAIN (link))
if (simple_cst_equal(TREE_VALUE (link), memory_identifier_string) == 1)
{
local->calls_read_all = true;
local->calls_write_all = true;
}
}
static void
check_call (ipa_reference_local_vars_info_t local, tree call_expr)
{
int flags = call_expr_flags (call_expr);
tree operand_list = TREE_OPERAND (call_expr, 1);
tree operand;
tree callee_t = get_callee_fndecl (call_expr);
enum availability avail = AVAIL_NOT_AVAILABLE;
for (operand = operand_list;
operand != NULL_TREE;
operand = TREE_CHAIN (operand))
{
tree argument = TREE_VALUE (operand);
check_rhs_var (local, argument);
}
if (callee_t)
{
struct cgraph_node* callee = cgraph_node(callee_t);
avail = cgraph_function_body_availability (callee);
}
if (avail == AVAIL_NOT_AVAILABLE || avail == AVAIL_OVERWRITABLE)
if (local)
{
if (flags & ECF_PURE)
local->calls_read_all = true;
else
{
local->calls_read_all = true;
local->calls_write_all = true;
}
}
}
static tree
scan_for_static_refs (tree *tp,
int *walk_subtrees,
void *data)
{
struct cgraph_node *fn = data;
tree t = *tp;
ipa_reference_local_vars_info_t local = NULL;
if (fn)
local = get_reference_vars_info_from_cgraph (fn)->local;
switch (TREE_CODE (t))
{
case VAR_DECL:
if (DECL_INITIAL (t))
walk_tree (&DECL_INITIAL (t), scan_for_static_refs, fn, visited_nodes);
*walk_subtrees = 0;
break;
case MODIFY_EXPR:
{
tree lhs = TREE_OPERAND (t, 0);
tree rhs = TREE_OPERAND (t, 1);
check_lhs_var (local, lhs);
switch (TREE_CODE_CLASS (TREE_CODE (rhs)))
{
case tcc_binary:
case tcc_comparison:
{
tree op0 = TREE_OPERAND (rhs, 0);
tree op1 = TREE_OPERAND (rhs, 1);
check_rhs_var (local, op0);
check_rhs_var (local, op1);
}
break;
case tcc_unary:
{
tree op0 = TREE_OPERAND (rhs, 0);
check_rhs_var (local, op0);
}
break;
case tcc_reference:
check_rhs_var (local, rhs);
break;
case tcc_declaration:
check_rhs_var (local, rhs);
break;
case tcc_expression:
switch (TREE_CODE (rhs))
{
case ADDR_EXPR:
check_rhs_var (local, rhs);
break;
case CALL_EXPR:
check_call (local, rhs);
break;
default:
break;
}
break;
default:
break;
}
*walk_subtrees = 0;
}
break;
case ADDR_EXPR:
check_rhs_var (local, t);
*walk_subtrees = 0;
break;
case LABEL_EXPR:
if (DECL_NONLOCAL (TREE_OPERAND (t, 0)))
{
local->calls_read_all = true;
local->calls_write_all = true;
}
break;
case CALL_EXPR:
check_call (local, t);
*walk_subtrees = 0;
break;
case ASM_EXPR:
get_asm_expr_operands (local, t);
*walk_subtrees = 0;
break;
default:
break;
}
return NULL;
}
static tree
get_static_decl (int index)
{
splay_tree_node stn =
splay_tree_lookup (reference_vars_to_consider, index);
if (stn)
return (tree)stn->value;
return NULL;
}
static const char *
get_static_name (int index)
{
splay_tree_node stn =
splay_tree_lookup (reference_vars_to_consider, index);
if (stn)
return lang_hooks.decl_printable_name ((tree)(stn->value), 2);
return NULL;
}
static void
propagate_bits (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;
y = cgraph_master_clone (y);
if (y)
{
if (get_reference_vars_info_from_cgraph (y))
{
ipa_reference_vars_info_t y_info = get_reference_vars_info_from_cgraph (y);
ipa_reference_global_vars_info_t y_global = y_info->global;
if (x_global->statics_read
!= all_module_statics)
{
if (y_global->statics_read
== all_module_statics)
{
BITMAP_FREE (x_global->statics_read);
x_global->statics_read
= all_module_statics;
}
else if (x_global->statics_read
!= y_global->statics_read)
bitmap_ior_into (x_global->statics_read,
y_global->statics_read);
}
if (x_global->statics_written
!= all_module_statics)
{
if (y_global->statics_written
== all_module_statics)
{
BITMAP_FREE (x_global->statics_written);
x_global->statics_written
= all_module_statics;
}
else if (x_global->statics_written
!= y_global->statics_written)
bitmap_ior_into (x_global->statics_written,
y_global->statics_written);
}
}
else
{
gcc_unreachable ();
}
}
}
}
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;
struct ipa_dfs_info *node_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;
}
static void
ipa_init (void)
{
struct cgraph_node *node;
memory_identifier_string = build_string(7, "memory");
reference_vars_to_consider =
splay_tree_new_ggc (splay_tree_compare_ints);
bitmap_obstack_initialize (&ipa_obstack);
module_statics_escape = BITMAP_ALLOC (&ipa_obstack);
module_statics_written = BITMAP_ALLOC (&ipa_obstack);
all_module_statics = BITMAP_ALLOC (&ipa_obstack);
for (node = cgraph_nodes; node; node = node->next)
has_proper_scope_for_analysis (node->decl);
visited_nodes = pointer_set_create ();
}
static void
analyze_variable (struct cgraph_varpool_node *vnode)
{
tree global = vnode->decl;
if (TREE_CODE (global) == VAR_DECL)
{
if (DECL_INITIAL (global))
walk_tree (&DECL_INITIAL (global), scan_for_static_refs,
NULL, visited_nodes);
}
else gcc_unreachable ();
}
static void
analyze_function (struct cgraph_node *fn)
{
ipa_reference_vars_info_t info
= xcalloc (1, sizeof (struct ipa_reference_vars_info_d));
ipa_reference_local_vars_info_t l
= xcalloc (1, sizeof (struct ipa_reference_local_vars_info_d));
tree decl = fn->decl;
get_function_ann (fn->decl)->reference_vars_info = info;
info->local = l;
l->statics_read = BITMAP_ALLOC (&ipa_obstack);
l->statics_written = BITMAP_ALLOC (&ipa_obstack);
if (dump_file)
fprintf (dump_file, "\n local analysis of %s\n", cgraph_node_name (fn));
{
struct function *this_cfun = DECL_STRUCT_FUNCTION (decl);
basic_block this_block;
FOR_EACH_BB_FN (this_block, this_cfun)
{
block_stmt_iterator bsi;
for (bsi = bsi_start (this_block); !bsi_end_p (bsi); bsi_next (&bsi))
walk_tree (bsi_stmt_ptr (bsi), scan_for_static_refs,
fn, visited_nodes);
}
}
if (DECL_STRUCT_FUNCTION (decl))
{
tree step;
for (step = DECL_STRUCT_FUNCTION (decl)->unexpanded_var_list;
step;
step = TREE_CHAIN (step))
{
tree var = TREE_VALUE (step);
if (TREE_CODE (var) == VAR_DECL
&& DECL_INITIAL (var)
&& !TREE_STATIC (var))
walk_tree (&DECL_INITIAL (var), scan_for_static_refs,
fn, visited_nodes);
}
}
}
static void
clean_function (struct cgraph_node *fn)
{
ipa_reference_vars_info_t info = get_reference_vars_info_from_cgraph (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
&& l->statics_read != all_module_statics)
BITMAP_FREE (l->statics_read);
if (l->statics_written
&&l->statics_written != all_module_statics)
BITMAP_FREE (l->statics_written);
free (l);
}
if (g)
{
if (g->statics_read
&& g->statics_read != all_module_statics)
BITMAP_FREE (g->statics_read);
if (g->statics_written
&& g->statics_written != all_module_statics)
BITMAP_FREE (g->statics_written);
if (g->statics_not_read
&& g->statics_not_read != all_module_statics)
BITMAP_FREE (g->statics_not_read);
if (g->statics_not_written
&& g->statics_not_written != all_module_statics)
BITMAP_FREE (g->statics_not_written);
free (g);
}
free (get_function_ann (fn->decl)->reference_vars_info);
get_function_ann (fn->decl)->reference_vars_info = NULL;
}
static unsigned int
static_execute (void)
{
struct cgraph_node *node;
struct cgraph_varpool_node *vnode;
struct cgraph_node *w;
struct cgraph_node **order =
xcalloc (cgraph_n_nodes, sizeof (struct cgraph_node *));
int order_pos = order_pos = ipa_utils_reduced_inorder (order, false, true);
int i;
ipa_init ();
for (vnode = cgraph_varpool_nodes_queue; vnode; vnode = vnode->next_needed)
analyze_variable (vnode);
for (node = cgraph_nodes; node; node = node->next)
if (node->analyzed
&& (cgraph_is_master_clone (node)
|| (cgraph_function_body_availability (node)
== AVAIL_OVERWRITABLE)))
analyze_function (node);
pointer_set_destroy (visited_nodes);
visited_nodes = NULL;
if (dump_file)
dump_cgraph (dump_file);
{
unsigned int index;
bitmap_iterator bi;
bitmap module_statics_readonly = BITMAP_ALLOC (&ipa_obstack);
bitmap module_statics_const = BITMAP_ALLOC (&ipa_obstack);
bitmap bm_temp = BITMAP_ALLOC (&ipa_obstack);
EXECUTE_IF_SET_IN_BITMAP (module_statics_escape, 0, index, bi)
{
splay_tree_remove (reference_vars_to_consider, index);
}
bitmap_and_compl_into (all_module_statics,
module_statics_escape);
bitmap_and_compl (module_statics_readonly, all_module_statics,
module_statics_written);
EXECUTE_IF_SET_IN_BITMAP (all_module_statics, 0, index, bi)
{
tree var = get_static_decl (index);
TREE_ADDRESSABLE (var) = 0;
if (dump_file)
fprintf (dump_file, "Not TREE_ADDRESSABLE var %s\n",
get_static_name (index));
}
bitmap_and_compl (module_statics_readonly, all_module_statics,
module_statics_written);
EXECUTE_IF_SET_IN_BITMAP (module_statics_readonly, 0, index, bi)
{
tree var = get_static_decl (index);
if (TREE_CODE (var) == FUNCTION_DECL)
continue;
if (DECL_SECTION_NAME (var) == NULL_TREE)
{
TREE_READONLY (var) = 1;
if (dump_file)
fprintf (dump_file, "read-only var %s\n",
get_static_name (index));
}
if (DECL_INITIAL (var)
&& is_gimple_min_invariant (DECL_INITIAL (var)))
{
bitmap_set_bit (module_statics_const, index);
if (dump_file)
fprintf (dump_file, "read-only constant %s\n",
get_static_name (index));
}
}
BITMAP_FREE(module_statics_escape);
BITMAP_FREE(module_statics_written);
if (dump_file)
EXECUTE_IF_SET_IN_BITMAP (all_module_statics, 0, index, bi)
{
fprintf (dump_file, "\nPromotable global:%s",
get_static_name (index));
}
for (i = 0; i < order_pos; i++ )
{
ipa_reference_local_vars_info_t l;
node = order[i];
l = get_reference_vars_info_from_cgraph (node)->local;
bitmap_and_into (l->statics_read,
all_module_statics);
bitmap_and_into (l->statics_written,
all_module_statics);
}
BITMAP_FREE(module_statics_readonly);
BITMAP_FREE(module_statics_const);
BITMAP_FREE(bm_temp);
}
if (dump_file)
{
for (i = 0; i < order_pos; i++ )
{
unsigned int index;
ipa_reference_local_vars_info_t l;
bitmap_iterator bi;
node = order[i];
l = get_reference_vars_info_from_cgraph (node)->local;
fprintf (dump_file,
"\nFunction name:%s/%i:",
cgraph_node_name (node), node->uid);
fprintf (dump_file, "\n locals read: ");
EXECUTE_IF_SET_IN_BITMAP (l->statics_read,
0, index, bi)
{
fprintf (dump_file, "%s ",
get_static_name (index));
}
fprintf (dump_file, "\n locals written: ");
EXECUTE_IF_SET_IN_BITMAP (l->statics_written,
0, index, bi)
{
fprintf(dump_file, "%s ",
get_static_name (index));
}
}
}
order_pos = ipa_utils_reduced_inorder (order, true, true);
if (dump_file)
ipa_utils_print_order(dump_file, "reduced", order, order_pos);
for (i = 0; i < order_pos; i++ )
{
ipa_reference_vars_info_t node_info;
ipa_reference_global_vars_info_t node_g =
xcalloc (1, sizeof (struct ipa_reference_global_vars_info_d));
ipa_reference_local_vars_info_t node_l;
bool read_all;
bool write_all;
struct ipa_dfs_info * w_info;
node = order[i];
node_info = get_reference_vars_info_from_cgraph (node);
if (!node_info)
{
dump_cgraph_node (stderr, node);
dump_cgraph (stderr);
gcc_unreachable ();
}
node_info->global = node_g;
node_l = node_info->local;
read_all = node_l->calls_read_all;
write_all = node_l->calls_write_all;
w_info = node->aux;
w = w_info->next_cycle;
while (w)
{
ipa_reference_local_vars_info_t w_l =
get_reference_vars_info_from_cgraph (w)->local;
read_all |= w_l->calls_read_all;
write_all |= w_l->calls_write_all;
w_info = w->aux;
w = w_info->next_cycle;
}
if (read_all)
node_g->statics_read = all_module_statics;
else
{
node_g->statics_read = BITMAP_ALLOC (&ipa_obstack);
bitmap_copy (node_g->statics_read,
node_l->statics_read);
}
if (write_all)
node_g->statics_written = all_module_statics;
else
{
node_g->statics_written = BITMAP_ALLOC (&ipa_obstack);
bitmap_copy (node_g->statics_written,
node_l->statics_written);
}
w_info = node->aux;
w = w_info->next_cycle;
while (w)
{
ipa_reference_vars_info_t w_ri =
get_reference_vars_info_from_cgraph (w);
ipa_reference_local_vars_info_t w_l = w_ri->local;
w_ri->global = node_g;
if (!read_all)
bitmap_ior_into (node_g->statics_read,
w_l->statics_read);
if (!write_all)
bitmap_ior_into (node_g->statics_written,
w_l->statics_written);
w_info = w->aux;
w = w_info->next_cycle;
}
w = node;
while (w)
{
propagate_bits (w);
w_info = w->aux;
w = w_info->next_cycle;
}
}
for (i = 0; i < order_pos; i++ )
{
struct ipa_dfs_info * w_info;
node = order[i];
merge_callee_local_info (node, node);
w_info = node->aux;
w = w_info->next_cycle;
while (w)
{
merge_callee_local_info (w, w);
w_info = w->aux;
w = w_info->next_cycle;
}
}
if (dump_file)
{
for (i = 0; i < order_pos; i++ )
{
ipa_reference_vars_info_t node_info;
ipa_reference_global_vars_info_t node_g;
ipa_reference_local_vars_info_t node_l;
unsigned int index;
bitmap_iterator bi;
struct ipa_dfs_info * w_info;
node = order[i];
node_info = get_reference_vars_info_from_cgraph (node);
node_g = node_info->global;
node_l = node_info->local;
fprintf (dump_file,
"\nFunction name:%s/%i:",
cgraph_node_name (node), node->uid);
fprintf (dump_file, "\n locals read: ");
EXECUTE_IF_SET_IN_BITMAP (node_l->statics_read,
0, index, bi)
{
fprintf (dump_file, "%s ",
get_static_name (index));
}
fprintf (dump_file, "\n locals written: ");
EXECUTE_IF_SET_IN_BITMAP (node_l->statics_written,
0, index, bi)
{
fprintf(dump_file, "%s ",
get_static_name (index));
}
w_info = node->aux;
w = w_info->next_cycle;
while (w)
{
ipa_reference_vars_info_t w_ri =
get_reference_vars_info_from_cgraph (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);
fprintf (dump_file, "\n locals read: ");
EXECUTE_IF_SET_IN_BITMAP (w_l->statics_read,
0, index, bi)
{
fprintf (dump_file, "%s ",
get_static_name (index));
}
fprintf (dump_file, "\n locals written: ");
EXECUTE_IF_SET_IN_BITMAP (w_l->statics_written,
0, index, bi)
{
fprintf(dump_file, "%s ",
get_static_name (index));
}
w_info = w->aux;
w = w_info->next_cycle;
}
fprintf (dump_file, "\n globals read: ");
EXECUTE_IF_SET_IN_BITMAP (node_g->statics_read,
0, index, bi)
{
fprintf (dump_file, "%s ",
get_static_name (index));
}
fprintf (dump_file, "\n globals written: ");
EXECUTE_IF_SET_IN_BITMAP (node_g->statics_written,
0, index, bi)
{
fprintf (dump_file, "%s ",
get_static_name (index));
}
}
}
for (i = 0; i < order_pos; i++ )
{
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_g = node_info->global;
node_g->statics_not_read = BITMAP_ALLOC (&ipa_obstack);
node_g->statics_not_written = BITMAP_ALLOC (&ipa_obstack);
if (node_g->statics_read != all_module_statics)
{
bitmap_and_compl (node_g->statics_not_read,
all_module_statics,
node_g->statics_read);
}
if (node_g->statics_written
!= all_module_statics)
bitmap_and_compl (node_g->statics_not_written,
all_module_statics,
node_g->statics_written);
}
free (order);
for (node = cgraph_nodes; node; node = node->next)
{
if (node->aux)
{
free (node->aux);
node->aux = NULL;
}
if (node->analyzed
&& (cgraph_function_body_availability (node) == AVAIL_OVERWRITABLE))
clean_function (node);
}
return 0;
}
static bool
gate_reference (void)
{
return (flag_unit_at_a_time != 0 && flag_ipa_reference
&& !(errorcount || sorrycount));
}
struct tree_opt_pass pass_ipa_reference =
{
"static-var",
gate_reference,
static_execute,
NULL,
NULL,
0,
TV_IPA_REFERENCE,
0,
0,
0,
0,
0,
0
};
#include "gt-ipa-reference.h"