00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "config.h"
00024 #include "system.h"
00025 #include "coretypes.h"
00026 #include "tm.h"
00027 #include "tree.h"
00028 #include "tree-flow.h"
00029 #include "tree-inline.h"
00030 #include "tree-pass.h"
00031 #include "langhooks.h"
00032 #include "pointer-set.h"
00033 #include "ggc.h"
00034 #include "ipa-utils.h"
00035 #include "ipa-reference.h"
00036 #include "c-common.h"
00037 #include "tree-gimple.h"
00038 #include "cgraph.h"
00039 #include "output.h"
00040 #include "flags.h"
00041 #include "timevar.h"
00042 #include "diagnostic.h"
00043 #include "langhooks.h"
00044
00045
00046
00047
00048
00049 void
00050 ipa_utils_print_order (FILE* out,
00051 const char * note,
00052 struct cgraph_node** order,
00053 int count)
00054 {
00055 int i;
00056 fprintf (out, "\n\n ordered call graph: %s\n", note);
00057
00058 for (i = count - 1; i >= 0; i--)
00059 dump_cgraph_node(dump_file, order[i]);
00060 fprintf (out, "\n");
00061 fflush(out);
00062 }
00063
00064
00065 struct searchc_env {
00066 struct cgraph_node **stack;
00067 int stack_size;
00068 struct cgraph_node **result;
00069 int order_pos;
00070 splay_tree nodes_marked_new;
00071 bool reduce;
00072 int count;
00073 };
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 static void
00086 searchc (struct searchc_env* env, struct cgraph_node *v)
00087 {
00088 struct cgraph_edge *edge;
00089 struct ipa_dfs_info *v_info = v->aux;
00090
00091
00092 v_info->new = false;
00093 splay_tree_remove (env->nodes_marked_new, v->uid);
00094
00095 v_info->dfn_number = env->count;
00096 v_info->low_link = env->count;
00097 env->count++;
00098 env->stack[(env->stack_size)++] = v;
00099 v_info->on_stack = true;
00100
00101 for (edge = v->callees; edge; edge = edge->next_callee)
00102 {
00103 struct ipa_dfs_info * w_info;
00104 struct cgraph_node *w = edge->callee;
00105
00106
00107 w = cgraph_master_clone (w);
00108 if (w && w->aux)
00109 {
00110 w_info = w->aux;
00111 if (w_info->new)
00112 {
00113 searchc (env, w);
00114 v_info->low_link =
00115 (v_info->low_link < w_info->low_link) ?
00116 v_info->low_link : w_info->low_link;
00117 }
00118 else
00119 if ((w_info->dfn_number < v_info->dfn_number)
00120 && (w_info->on_stack))
00121 v_info->low_link =
00122 (w_info->dfn_number < v_info->low_link) ?
00123 w_info->dfn_number : v_info->low_link;
00124 }
00125 }
00126
00127
00128 if (v_info->low_link == v_info->dfn_number)
00129 {
00130 struct cgraph_node *last = NULL;
00131 struct cgraph_node *x;
00132 struct ipa_dfs_info *x_info;
00133 do {
00134 x = env->stack[--(env->stack_size)];
00135 x_info = x->aux;
00136 x_info->on_stack = false;
00137
00138 if (env->reduce)
00139 {
00140 x_info->next_cycle = last;
00141 last = x;
00142 }
00143 else
00144 env->result[env->order_pos++] = x;
00145 }
00146 while (v != x);
00147 if (env->reduce)
00148 env->result[env->order_pos++] = v;
00149 }
00150 }
00151
00152
00153
00154
00155
00156
00157 int
00158 ipa_utils_reduced_inorder (struct cgraph_node **order,
00159 bool reduce, bool allow_overwritable)
00160 {
00161 struct cgraph_node *node;
00162 struct searchc_env env;
00163 splay_tree_node result;
00164 env.stack = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
00165 env.stack_size = 0;
00166 env.result = order;
00167 env.order_pos = 0;
00168 env.nodes_marked_new = splay_tree_new (splay_tree_compare_ints, 0, 0);
00169 env.count = 1;
00170 env.reduce = reduce;
00171
00172 for (node = cgraph_nodes; node; node = node->next)
00173 if ((node->analyzed)
00174 && (cgraph_is_master_clone (node)
00175 || (allow_overwritable
00176 && (cgraph_function_body_availability (node) ==
00177 AVAIL_OVERWRITABLE))))
00178 {
00179
00180 struct ipa_dfs_info *info = node->aux;
00181 if (!info)
00182 info = xcalloc (1, sizeof (struct ipa_dfs_info));
00183 info->new = true;
00184 info->on_stack = false;
00185 info->next_cycle = NULL;
00186 node->aux = info;
00187
00188 splay_tree_insert (env.nodes_marked_new,
00189 (splay_tree_key)node->uid,
00190 (splay_tree_value)node);
00191 }
00192 else
00193 node->aux = NULL;
00194 result = splay_tree_min (env.nodes_marked_new);
00195 while (result)
00196 {
00197 node = (struct cgraph_node *)result->value;
00198 searchc (&env, node);
00199 result = splay_tree_min (env.nodes_marked_new);
00200 }
00201 splay_tree_delete (env.nodes_marked_new);
00202 free (env.stack);
00203
00204 return env.order_pos;
00205 }
00206
00207
00208
00209
00210
00211
00212 tree
00213 get_base_var (tree t)
00214 {
00215 if ((TREE_CODE (t) == EXC_PTR_EXPR) || (TREE_CODE (t) == FILTER_EXPR))
00216 return t;
00217
00218 while (!SSA_VAR_P (t)
00219 && (!CONSTANT_CLASS_P (t))
00220 && TREE_CODE (t) != LABEL_DECL
00221 && TREE_CODE (t) != FUNCTION_DECL
00222 && TREE_CODE (t) != CONST_DECL)
00223 {
00224 t = TREE_OPERAND (t, 0);
00225 }
00226 return t;
00227 }
00228