00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "config.h"
00022 #include "system.h"
00023 #include "coretypes.h"
00024 #include "tm.h"
00025 #include "cgraph.h"
00026
00027
00028
00029
00030 int
00031 cgraph_postorder (struct cgraph_node **order)
00032 {
00033 struct cgraph_node *node, *node2;
00034 int stack_size = 0;
00035 int order_pos = 0;
00036 struct cgraph_edge *edge, last;
00037
00038 struct cgraph_node **stack =
00039 XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
00040
00041
00042
00043
00044
00045 for (node = cgraph_nodes; node; node = node->next)
00046 node->aux = NULL;
00047 for (node = cgraph_nodes; node; node = node->next)
00048 if (!node->aux)
00049 {
00050 node2 = node;
00051 if (!node->callers)
00052 node->aux = &last;
00053 else
00054 node->aux = node->callers;
00055 while (node2)
00056 {
00057 while (node2->aux != &last)
00058 {
00059 edge = node2->aux;
00060 if (edge->next_caller)
00061 node2->aux = edge->next_caller;
00062 else
00063 node2->aux = &last;
00064 if (!edge->caller->aux)
00065 {
00066 if (!edge->caller->callers)
00067 edge->caller->aux = &last;
00068 else
00069 edge->caller->aux = edge->caller->callers;
00070 stack[stack_size++] = node2;
00071 node2 = edge->caller;
00072 break;
00073 }
00074 }
00075 if (node2->aux == &last)
00076 {
00077 order[order_pos++] = node2;
00078 if (stack_size)
00079 node2 = stack[--stack_size];
00080 else
00081 node2 = NULL;
00082 }
00083 }
00084 }
00085 free (stack);
00086 for (node = cgraph_nodes; node; node = node->next)
00087 node->aux = NULL;
00088 return order_pos;
00089 }
00090
00091
00092
00093
00094
00095
00096 bool
00097 cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
00098 {
00099 struct cgraph_node *first = (void *) 1;
00100 struct cgraph_node *node, *next;
00101 bool changed = false;
00102 int insns = 0;
00103
00104 #ifdef ENABLE_CHECKING
00105 verify_cgraph ();
00106 #endif
00107 if (file)
00108 fprintf (file, "\nReclaiming functions:");
00109 #ifdef ENABLE_CHECKING
00110 for (node = cgraph_nodes; node; node = node->next)
00111 gcc_assert (!node->aux);
00112 #endif
00113 for (node = cgraph_nodes; node; node = node->next)
00114 if (node->needed && !node->global.inlined_to
00115 && ((!DECL_EXTERNAL (node->decl))
00116 || !node->analyzed
00117 || before_inlining_p))
00118 {
00119 node->aux = first;
00120 first = node;
00121 }
00122 else
00123 gcc_assert (!node->aux);
00124
00125
00126
00127
00128 while (first != (void *) 1)
00129 {
00130 struct cgraph_edge *e;
00131 node = first;
00132 first = first->aux;
00133
00134 for (e = node->callees; e; e = e->next_callee)
00135 if (!e->callee->aux
00136 && node->analyzed
00137 && (!e->inline_failed || !e->callee->analyzed
00138 || (!DECL_EXTERNAL (e->callee->decl))
00139 || before_inlining_p))
00140 {
00141 e->callee->aux = first;
00142 first = e->callee;
00143 }
00144 }
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 for (node = cgraph_nodes; node; node = next)
00155 {
00156 next = node->next;
00157 if (!node->aux)
00158 {
00159 int local_insns;
00160 tree decl = node->decl;
00161
00162 node->global.inlined_to = NULL;
00163 if (DECL_STRUCT_FUNCTION (decl))
00164 local_insns = node->local.self_insns;
00165 else
00166 local_insns = 0;
00167 if (file)
00168 fprintf (file, " %s", cgraph_node_name (node));
00169 if (!node->analyzed || !DECL_EXTERNAL (node->decl)
00170 || before_inlining_p)
00171 cgraph_remove_node (node);
00172 else
00173 {
00174 struct cgraph_edge *e;
00175
00176 for (e = node->callers; e; e = e->next_caller)
00177 if (e->caller->aux)
00178 break;
00179 if (e || node->needed)
00180 {
00181 struct cgraph_node *clone;
00182
00183 for (clone = node->next_clone; clone;
00184 clone = clone->next_clone)
00185 if (clone->aux)
00186 break;
00187 if (!clone)
00188 {
00189 DECL_SAVED_TREE (node->decl) = NULL;
00190 DECL_STRUCT_FUNCTION (node->decl) = NULL;
00191 DECL_INITIAL (node->decl) = error_mark_node;
00192 node->analyzed = false;
00193 }
00194 cgraph_node_remove_callees (node);
00195 node->analyzed = false;
00196 }
00197 else
00198 cgraph_remove_node (node);
00199 }
00200 if (!DECL_SAVED_TREE (decl))
00201 insns += local_insns;
00202 changed = true;
00203 }
00204 }
00205 for (node = cgraph_nodes; node; node = node->next)
00206 node->aux = NULL;
00207 if (file)
00208 fprintf (file, "\nReclaimed %i insns", insns);
00209 return changed;
00210 }