diff options
Diffstat (limited to 'gcc/cgraph.c')
-rw-r--r-- | gcc/cgraph.c | 114 |
1 files changed, 89 insertions, 25 deletions
diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 7d1cca20df1..61e745c2d82 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -95,6 +95,12 @@ The varpool data structure: #include "varray.h" #include "output.h" #include "intl.h" +/* APPLE LOCAL Selective inlining of functions that use Altivec 3837835 */ +#include "function.h" + +static void cgraph_node_remove_callers (struct cgraph_node *node); +static inline void cgraph_edge_remove_caller (struct cgraph_edge *e); +static inline void cgraph_edge_remove_callee (struct cgraph_edge *e); /* Hash table used to convert declarations into nodes. */ static GTY((param_is (struct cgraph_node))) htab_t cgraph_hash; @@ -289,30 +295,55 @@ cgraph_create_edge (struct cgraph_node *caller, struct cgraph_node *callee, edge->caller = caller; edge->callee = callee; edge->call_expr = call_expr; + edge->prev_caller = NULL; edge->next_caller = callee->callers; + if (callee->callers) + callee->callers->prev_caller = edge; + edge->prev_callee = NULL; edge->next_callee = caller->callees; + if (caller->callees) + caller->callees->prev_callee = edge; caller->callees = edge; callee->callers = edge; return edge; } -/* Remove the edge E the cgraph. */ +/* Remove the edge E from the list of the callers of the callee. */ + +static inline void +cgraph_edge_remove_callee (struct cgraph_edge *e) +{ + if (e->prev_caller) + e->prev_caller->next_caller = e->next_caller; + if (e->next_caller) + e->next_caller->prev_caller = e->prev_caller; + if (!e->prev_caller) + e->callee->callers = e->next_caller; +} + +/* Remove the edge E from the list of the callees of the caller. */ + +static inline void +cgraph_edge_remove_caller (struct cgraph_edge *e) +{ + if (e->prev_callee) + e->prev_callee->next_callee = e->next_callee; + if (e->next_callee) + e->next_callee->prev_callee = e->prev_callee; + if (!e->prev_callee) + e->caller->callees = e->next_callee; +} + +/* Remove the edge E in the cgraph. */ void cgraph_remove_edge (struct cgraph_edge *e) { - struct cgraph_edge **edge, **edge2; + /* Remove from callers list of the callee. */ + cgraph_edge_remove_callee (e); - for (edge = &e->callee->callers; *edge && *edge != e; - edge = &((*edge)->next_caller)) - continue; - gcc_assert (*edge); - *edge = (*edge)->next_caller; - for (edge2 = &e->caller->callees; *edge2 && *edge2 != e; - edge2 = &(*edge2)->next_callee) - continue; - gcc_assert (*edge2); - *edge2 = (*edge2)->next_callee; + /* Remove from callees list of the callers. */ + cgraph_edge_remove_caller (e); } /* Redirect callee of E to N. The function does not update underlying @@ -321,16 +352,46 @@ cgraph_remove_edge (struct cgraph_edge *e) void cgraph_redirect_edge_callee (struct cgraph_edge *e, struct cgraph_node *n) { - struct cgraph_edge **edge; + /* Remove from callers list of the current callee. */ + cgraph_edge_remove_callee (e); - for (edge = &e->callee->callers; *edge && *edge != e; - edge = &((*edge)->next_caller)) - continue; - gcc_assert (*edge); - *edge = (*edge)->next_caller; - e->callee = n; + /* Insert to callers list of the new callee. */ + e->prev_caller = NULL; + if (n->callers) + n->callers->prev_caller = e; e->next_caller = n->callers; n->callers = e; + e->callee = n; +} + +/* Remove all callees from the node. */ + +void +cgraph_node_remove_callees (struct cgraph_node *node) +{ + struct cgraph_edge *e; + + /* It is sufficient to remove the edges from the lists of callers of + the callees. The callee list of the node can be zapped with one + assignment. */ + for (e = node->callees; e; e = e->next_callee) + cgraph_edge_remove_callee (e); + node->callees = NULL; +} + +/* Remove all callers from the node. */ + +static void +cgraph_node_remove_callers (struct cgraph_node *node) +{ + struct cgraph_edge *e; + + /* It is sufficient to remove the edges from the lists of callees of + the callers. The caller list of the node can be zapped with one + assignment. */ + for (e = node->callers; e; e = e->next_caller) + cgraph_edge_remove_caller (e); + node->callers = NULL; } /* Remove the node from cgraph. */ @@ -341,10 +402,8 @@ cgraph_remove_node (struct cgraph_node *node) void **slot; bool check_dead = 1; - while (node->callers) - cgraph_remove_edge (node->callers); - while (node->callees) - cgraph_remove_edge (node->callees); + cgraph_node_remove_callers (node); + cgraph_node_remove_callees (node); while (node->nested) cgraph_remove_node (node->nested); if (node->origin) @@ -417,6 +476,7 @@ cgraph_mark_reachable_node (struct cgraph_node *node) { notice_global_symbol (node->decl); node->reachable = 1; + gcc_assert (!cgraph_global_info_ready); node->next_needed = cgraph_nodes_queue; cgraph_nodes_queue = node; @@ -511,6 +571,10 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node) fprintf (f, " inlinable"); if (TREE_ASM_WRITTEN (node->decl)) fprintf (f, " asm_written"); + /* APPLE LOCAL begin Selective inlining of functions that use Altivec 3837835 */ + if (DECL_STRUCT_FUNCTION (node->decl) && DECL_STRUCT_FUNCTION (node->decl)->uses_vector) + fprintf (f, " uses_vector"); + /* APPLE LOCAL end Selective inlining of functions that use Altivec 3837835 */ fprintf (f, "\n called by: "); for (edge = node->callers; edge; edge = edge->next_caller) @@ -670,11 +734,11 @@ cgraph_varpool_assemble_pending_decls (void) while (cgraph_varpool_nodes_queue) { - tree decl = cgraph_varpool_nodes_queue->decl; struct cgraph_varpool_node *node = cgraph_varpool_nodes_queue; + tree decl = node->decl; cgraph_varpool_nodes_queue = cgraph_varpool_nodes_queue->next_needed; - if (!TREE_ASM_WRITTEN (decl)) + if (!TREE_ASM_WRITTEN (decl) && !node->alias) { assemble_variable (decl, 0, 1, 0); changed = true; |