-/* Mark tree T as having address taken. */
-
-static void
-mark_address_taken (tree x)
-{
- if (TREE_CODE (x) == VAR_DECL
- && module_statics_escape && has_proper_scope_for_analysis (x))
- bitmap_set_bit (module_statics_escape, DECL_UID (x));
-}
-
-/* Wrapper around mark_address_taken for the stmt walker. */
-
-static bool
-mark_address (gimple stmt ATTRIBUTE_UNUSED, tree addr,
- void *data ATTRIBUTE_UNUSED)
-{
- while (handled_component_p (addr))
- addr = TREE_OPERAND (addr, 0);
- mark_address_taken (addr);
- return false;
-}
-
-/* Mark load of T. */
-
-static bool
-mark_load (gimple stmt ATTRIBUTE_UNUSED, tree t, void *data)
-{
- ipa_reference_local_vars_info_t local = (ipa_reference_local_vars_info_t)data;
- if (TREE_CODE (t) == VAR_DECL
- && has_proper_scope_for_analysis (t))
- bitmap_set_bit (local->statics_read, DECL_UID (t));
- return false;
-}
-
-/* Mark store of T. */
-
-static bool
-mark_store (gimple stmt ATTRIBUTE_UNUSED, tree t, void *data)
-{
- ipa_reference_local_vars_info_t local = (ipa_reference_local_vars_info_t)data;
- if (TREE_CODE (t) == VAR_DECL
- && has_proper_scope_for_analysis (t))
- {
- if (local)
- bitmap_set_bit (local->statics_written, DECL_UID (t));
- /* Mark the write so we can tell which statics are
- readonly. */
- if (module_statics_written)
- bitmap_set_bit (module_statics_written, DECL_UID (t));
- }
- return false;
-}
-
-/* Look for memory clobber and set read_all/write_all if present. */
-
-static void
-check_asm_memory_clobber (ipa_reference_local_vars_info_t local, gimple stmt)
-{
- size_t i;
- tree op;
-
- for (i = 0; i < gimple_asm_nclobbers (stmt); i++)
- {
- op = gimple_asm_clobber_op (stmt, i);
- if (simple_cst_equal(TREE_VALUE (op), memory_identifier_string) == 1)
- {
- /* Abandon all hope, ye who enter here. */
- local->calls_read_all = true;
- local->calls_write_all = true;
- }
- }
-}
-
-/* Look for external calls and set read_all/write_all correspondingly. */
-
-static void
-check_call (ipa_reference_local_vars_info_t local, gimple stmt)
-{
- int flags = gimple_call_flags (stmt);
- tree callee_t = gimple_call_fndecl (stmt);
- enum availability avail = AVAIL_NOT_AVAILABLE;
-
- if (callee_t)
- {
- struct cgraph_node* callee = cgraph_node(callee_t);
- avail = cgraph_function_body_availability (callee);
- }
-
- if (avail <= AVAIL_OVERWRITABLE)
- if (local)
- {
- if (flags & ECF_CONST)
- ;
- else if (flags & ECF_PURE)
- local->calls_read_all = true;
- else
- {
- local->calls_read_all = true;
- local->calls_write_all = true;
- }
- }
- /* TODO: To be able to produce sane results, we should also handle
- common builtins, in particular throw.
- Indirect calls hsould be only counted and as inliner is replacing them
- by direct calls, we can conclude if any indirect calls are left in body */
-}
-
-/* TP is the part of the tree currently under the microscope.
- WALK_SUBTREES is part of the walk_tree api but is unused here.
- DATA is cgraph_node of the function being walked. */
-
-static tree
-scan_stmt_for_static_refs (gimple_stmt_iterator *gsip,
- struct cgraph_node *fn)
-{
- gimple stmt = gsi_stmt (*gsip);
- ipa_reference_local_vars_info_t local = NULL;
-
- if (fn)
- local = get_reference_vars_info (fn)->local;
-
- /* Look for direct loads and stores. */
- walk_stmt_load_store_addr_ops (stmt, local, mark_load, mark_store,
- mark_address);
-
- if (is_gimple_call (stmt))
- check_call (local, stmt);
- else if (gimple_code (stmt) == GIMPLE_ASM)
- check_asm_memory_clobber (local, stmt);
-
- return NULL;
-}
-
-/* Call-back to scan variable initializers for static references.
- Called using walk_tree. */
-
-static tree
-scan_initializer_for_static_refs (tree *tp, int *walk_subtrees,
- void *data ATTRIBUTE_UNUSED)
-{
- tree t = *tp;
-
- if (TREE_CODE (t) == ADDR_EXPR)
- {
- mark_address_taken (get_base_var (t));
- *walk_subtrees = 0;
- }
- /* Save some cycles by not walking types and declaration as we
- won't find anything useful there anyway. */
- else if (IS_TYPE_OR_DECL_P (*tp))
- *walk_subtrees = 0;
-
- return NULL;
-}
-