comparison gcc/ipa-utils.c @ 55:77e2b8dfacca gcc-4.4.5

update it from 4.4.3 to 4.5.0
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Fri, 12 Feb 2010 23:39:51 +0900
parents a06113de4d67
children 04ced10e8804
comparison
equal deleted inserted replaced
52:c156f1bd5cd9 55:77e2b8dfacca
26 #include "tree-flow.h" 26 #include "tree-flow.h"
27 #include "tree-inline.h" 27 #include "tree-inline.h"
28 #include "tree-pass.h" 28 #include "tree-pass.h"
29 #include "langhooks.h" 29 #include "langhooks.h"
30 #include "pointer-set.h" 30 #include "pointer-set.h"
31 #include "splay-tree.h"
31 #include "ggc.h" 32 #include "ggc.h"
32 #include "ipa-utils.h" 33 #include "ipa-utils.h"
33 #include "ipa-reference.h" 34 #include "ipa-reference.h"
34 #include "c-common.h"
35 #include "gimple.h" 35 #include "gimple.h"
36 #include "cgraph.h" 36 #include "cgraph.h"
37 #include "output.h" 37 #include "output.h"
38 #include "flags.h" 38 #include "flags.h"
39 #include "timevar.h" 39 #include "timevar.h"
42 42
43 /* Debugging function for postorder and inorder code. NOTE is a string 43 /* Debugging function for postorder and inorder code. NOTE is a string
44 that is printed before the nodes are printed. ORDER is an array of 44 that is printed before the nodes are printed. ORDER is an array of
45 cgraph_nodes that has COUNT useful nodes in it. */ 45 cgraph_nodes that has COUNT useful nodes in it. */
46 46
47 void 47 void
48 ipa_utils_print_order (FILE* out, 48 ipa_utils_print_order (FILE* out,
49 const char * note, 49 const char * note,
50 struct cgraph_node** order, 50 struct cgraph_node** order,
51 int count) 51 int count)
52 { 52 {
53 int i; 53 int i;
54 fprintf (out, "\n\n ordered call graph: %s\n", note); 54 fprintf (out, "\n\n ordered call graph: %s\n", note);
55 55
56 for (i = count - 1; i >= 0; i--) 56 for (i = count - 1; i >= 0; i--)
57 dump_cgraph_node(dump_file, order[i]); 57 dump_cgraph_node(dump_file, order[i]);
58 fprintf (out, "\n"); 58 fprintf (out, "\n");
59 fflush(out); 59 fflush(out);
60 } 60 }
79 ipa_utils_reduced_inorder. ENV is a stack env and would be 79 ipa_utils_reduced_inorder. ENV is a stack env and would be
80 unnecessary if C had nested functions. V is the node to start 80 unnecessary if C had nested functions. V is the node to start
81 searching from. */ 81 searching from. */
82 82
83 static void 83 static void
84 searchc (struct searchc_env* env, struct cgraph_node *v) 84 searchc (struct searchc_env* env, struct cgraph_node *v,
85 bool (*ignore_edge) (struct cgraph_edge *))
85 { 86 {
86 struct cgraph_edge *edge; 87 struct cgraph_edge *edge;
87 struct ipa_dfs_info *v_info = (struct ipa_dfs_info *) v->aux; 88 struct ipa_dfs_info *v_info = (struct ipa_dfs_info *) v->aux;
88 89
89 /* mark node as old */ 90 /* mark node as old */
90 v_info->new_node = false; 91 v_info->new_node = false;
91 splay_tree_remove (env->nodes_marked_new, v->uid); 92 splay_tree_remove (env->nodes_marked_new, v->uid);
92 93
93 v_info->dfn_number = env->count; 94 v_info->dfn_number = env->count;
94 v_info->low_link = env->count; 95 v_info->low_link = env->count;
95 env->count++; 96 env->count++;
96 env->stack[(env->stack_size)++] = v; 97 env->stack[(env->stack_size)++] = v;
97 v_info->on_stack = true; 98 v_info->on_stack = true;
98 99
99 for (edge = v->callees; edge; edge = edge->next_callee) 100 for (edge = v->callees; edge; edge = edge->next_callee)
100 { 101 {
101 struct ipa_dfs_info * w_info; 102 struct ipa_dfs_info * w_info;
102 struct cgraph_node *w = edge->callee; 103 struct cgraph_node *w = edge->callee;
104
105 if (ignore_edge && ignore_edge (edge))
106 continue;
103 107
104 if (w->aux && cgraph_function_body_availability (edge->callee) > AVAIL_OVERWRITABLE) 108 if (w->aux && cgraph_function_body_availability (edge->callee) > AVAIL_OVERWRITABLE)
105 { 109 {
106 w_info = (struct ipa_dfs_info *) w->aux; 110 w_info = (struct ipa_dfs_info *) w->aux;
107 if (w_info->new_node) 111 if (w_info->new_node)
108 { 112 {
109 searchc (env, w); 113 searchc (env, w, ignore_edge);
110 v_info->low_link = 114 v_info->low_link =
111 (v_info->low_link < w_info->low_link) ? 115 (v_info->low_link < w_info->low_link) ?
112 v_info->low_link : w_info->low_link; 116 v_info->low_link : w_info->low_link;
113 } 117 }
114 else 118 else
115 if ((w_info->dfn_number < v_info->dfn_number) 119 if ((w_info->dfn_number < v_info->dfn_number)
116 && (w_info->on_stack)) 120 && (w_info->on_stack))
117 v_info->low_link = 121 v_info->low_link =
118 (w_info->dfn_number < v_info->low_link) ? 122 (w_info->dfn_number < v_info->low_link) ?
119 w_info->dfn_number : v_info->low_link; 123 w_info->dfn_number : v_info->low_link;
120 } 124 }
121 } 125 }
122 126
123 127
124 if (v_info->low_link == v_info->dfn_number) 128 if (v_info->low_link == v_info->dfn_number)
125 { 129 {
126 struct cgraph_node *last = NULL; 130 struct cgraph_node *last = NULL;
127 struct cgraph_node *x; 131 struct cgraph_node *x;
128 struct ipa_dfs_info *x_info; 132 struct ipa_dfs_info *x_info;
129 do { 133 do {
130 x = env->stack[--(env->stack_size)]; 134 x = env->stack[--(env->stack_size)];
131 x_info = (struct ipa_dfs_info *) x->aux; 135 x_info = (struct ipa_dfs_info *) x->aux;
132 x_info->on_stack = false; 136 x_info->on_stack = false;
133 137
134 if (env->reduce) 138 if (env->reduce)
135 { 139 {
136 x_info->next_cycle = last; 140 x_info->next_cycle = last;
137 last = x; 141 last = x;
138 } 142 }
139 else 143 else
140 env->result[env->order_pos++] = x; 144 env->result[env->order_pos++] = x;
141 } 145 }
142 while (v != x); 146 while (v != x);
143 if (env->reduce) 147 if (env->reduce)
144 env->result[env->order_pos++] = v; 148 env->result[env->order_pos++] = v;
145 } 149 }
146 } 150 }
147 151
148 /* Topsort the call graph by caller relation. Put the result in ORDER. 152 /* Topsort the call graph by caller relation. Put the result in ORDER.
149 153
150 The REDUCE flag is true if you want the cycles reduced to single 154 The REDUCE flag is true if you want the cycles reduced to single
151 nodes. Only consider nodes that have the output bit set. */ 155 nodes. Only consider nodes that have the output bit set. */
152 156
153 int 157 int
154 ipa_utils_reduced_inorder (struct cgraph_node **order, 158 ipa_utils_reduced_inorder (struct cgraph_node **order,
155 bool reduce, bool allow_overwritable) 159 bool reduce, bool allow_overwritable,
160 bool (*ignore_edge) (struct cgraph_edge *))
156 { 161 {
157 struct cgraph_node *node; 162 struct cgraph_node *node;
158 struct searchc_env env; 163 struct searchc_env env;
159 splay_tree_node result; 164 splay_tree_node result;
160 env.stack = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes); 165 env.stack = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
162 env.result = order; 167 env.result = order;
163 env.order_pos = 0; 168 env.order_pos = 0;
164 env.nodes_marked_new = splay_tree_new (splay_tree_compare_ints, 0, 0); 169 env.nodes_marked_new = splay_tree_new (splay_tree_compare_ints, 0, 0);
165 env.count = 1; 170 env.count = 1;
166 env.reduce = reduce; 171 env.reduce = reduce;
167 172
168 for (node = cgraph_nodes; node; node = node->next) 173 for (node = cgraph_nodes; node; node = node->next)
169 { 174 {
170 enum availability avail = cgraph_function_body_availability (node); 175 enum availability avail = cgraph_function_body_availability (node);
171 176
172 if (avail > AVAIL_OVERWRITABLE 177 if (avail > AVAIL_OVERWRITABLE
173 || (allow_overwritable 178 || (allow_overwritable
174 && (avail == AVAIL_OVERWRITABLE))) 179 && (avail == AVAIL_OVERWRITABLE)))
175 { 180 {
176 /* Reuse the info if it is already there. */ 181 /* Reuse the info if it is already there. */
177 struct ipa_dfs_info *info = (struct ipa_dfs_info *) node->aux; 182 struct ipa_dfs_info *info = (struct ipa_dfs_info *) node->aux;
178 if (!info) 183 if (!info)
179 info = XCNEW (struct ipa_dfs_info); 184 info = XCNEW (struct ipa_dfs_info);
180 info->new_node = true; 185 info->new_node = true;
181 info->on_stack = false; 186 info->on_stack = false;
182 info->next_cycle = NULL; 187 info->next_cycle = NULL;
183 node->aux = info; 188 node->aux = info;
184 189
185 splay_tree_insert (env.nodes_marked_new, 190 splay_tree_insert (env.nodes_marked_new,
186 (splay_tree_key)node->uid, 191 (splay_tree_key)node->uid,
187 (splay_tree_value)node); 192 (splay_tree_value)node);
188 } 193 }
189 else 194 else
190 node->aux = NULL; 195 node->aux = NULL;
191 } 196 }
192 result = splay_tree_min (env.nodes_marked_new); 197 result = splay_tree_min (env.nodes_marked_new);
193 while (result) 198 while (result)
194 { 199 {
195 node = (struct cgraph_node *)result->value; 200 node = (struct cgraph_node *)result->value;
196 searchc (&env, node); 201 searchc (&env, node, ignore_edge);
197 result = splay_tree_min (env.nodes_marked_new); 202 result = splay_tree_min (env.nodes_marked_new);
198 } 203 }
199 splay_tree_delete (env.nodes_marked_new); 204 splay_tree_delete (env.nodes_marked_new);
200 free (env.stack); 205 free (env.stack);
201 206
208 INDIRECT_REFS. */ 213 INDIRECT_REFS. */
209 214
210 tree 215 tree
211 get_base_var (tree t) 216 get_base_var (tree t)
212 { 217 {
213 if ((TREE_CODE (t) == EXC_PTR_EXPR) || (TREE_CODE (t) == FILTER_EXPR)) 218 while (!SSA_VAR_P (t)
214 return t;
215
216 while (!SSA_VAR_P (t)
217 && (!CONSTANT_CLASS_P (t)) 219 && (!CONSTANT_CLASS_P (t))
218 && TREE_CODE (t) != LABEL_DECL 220 && TREE_CODE (t) != LABEL_DECL
219 && TREE_CODE (t) != FUNCTION_DECL 221 && TREE_CODE (t) != FUNCTION_DECL
220 && TREE_CODE (t) != CONST_DECL) 222 && TREE_CODE (t) != CONST_DECL
223 && TREE_CODE (t) != CONSTRUCTOR)
221 { 224 {
222 t = TREE_OPERAND (t, 0); 225 t = TREE_OPERAND (t, 0);
223 } 226 }
224 return t; 227 return t;
225 } 228 }
226 229