#include "gimple.h"
#include "tree-pass.h"
#include "ipa-utils.h"
-#include "except.h"
/* Context of record_reference. */
struct record_reference_ctx
return NULL_TREE;
}
-/* Record references to typeinfos in the type list LIST. */
-
-static void
-record_type_list (struct cgraph_node *node, tree list)
-{
- for (; list; list = TREE_CHAIN (list))
- {
- tree type = TREE_VALUE (list);
-
- if (TYPE_P (type))
- type = lookup_type_for_runtime (type);
- STRIP_NOPS (type);
- if (TREE_CODE (type) == ADDR_EXPR)
- {
- type = TREE_OPERAND (type, 0);
- if (TREE_CODE (type) == VAR_DECL)
- {
- struct varpool_node *vnode = varpool_node (type);
- varpool_mark_needed_node (vnode);
- ipa_record_reference (node, NULL,
- NULL, vnode,
- IPA_REF_ADDR, NULL);
- }
- }
- }
-}
-
-/* Record all references we will introduce by producing EH tables
- for NODE. */
-
-static void
-record_eh_tables (struct cgraph_node *node, struct function *fun)
-{
- eh_region i;
-
- i = fun->eh->region_tree;
- if (!i)
- return;
-
- while (1)
- {
- switch (i->type)
- {
- case ERT_CLEANUP:
- case ERT_MUST_NOT_THROW:
- break;
-
- case ERT_TRY:
- {
- eh_catch c;
- for (c = i->u.eh_try.first_catch; c; c = c->next_catch)
- record_type_list (node, c->type_list);
- }
- break;
-
- case ERT_ALLOWED_EXCEPTIONS:
- record_type_list (node, i->u.allowed.type_list);
- break;
- }
- /* If there are sub-regions, process them. */
- if (i->inner)
- i = i->inner;
- /* If there are peers, process them. */
- else if (i->next_peer)
- i = i->next_peer;
- /* Otherwise, step back up the tree to the next peer. */
- else
- {
- do
- {
- i = i->outer;
- if (i == NULL)
- return;
- }
- while (i->next_peer == NULL);
- i = i->next_peer;
- }
- }
-}
-
/* Reset inlining information of all incoming call edges of NODE. */
void
&& (TREE_STATIC (decl) && !DECL_EXTERNAL (decl)))
varpool_finalize_decl (decl);
}
- record_eh_tables (node, cfun);
pointer_set_destroy (visited_nodes);
return 0;
walk_stmt_load_store_addr_ops (gsi_stmt (gsi), node,
mark_load, mark_store, mark_address);
}
- record_eh_tables (node, cfun);
gcc_assert (!node->global.inlined_to);
return 0;
}
-/* Rebuild cgraph edges for current function node. This needs to be run after
- passes that don't update the cgraph. */
-
-void
-cgraph_rebuild_references (void)
-{
- basic_block bb;
- struct cgraph_node *node = cgraph_node (current_function_decl);
- gimple_stmt_iterator gsi;
-
- ipa_remove_all_references (&node->ref_list);
-
- node->count = ENTRY_BLOCK_PTR->count;
-
- FOR_EACH_BB (bb)
- {
- for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
- {
- gimple stmt = gsi_stmt (gsi);
-
- walk_stmt_load_store_addr_ops (stmt, node, mark_load,
- mark_store, mark_address);
-
- }
- for (gsi = gsi_start (phi_nodes (bb)); !gsi_end_p (gsi); gsi_next (&gsi))
- walk_stmt_load_store_addr_ops (gsi_stmt (gsi), node,
- mark_load, mark_store, mark_address);
- }
- record_eh_tables (node, cfun);
-}
-
struct gimple_opt_pass pass_rebuild_cgraph_edges =
{
{