Mercurial > hg > CbC > CbC_gcc
comparison gcc/tracer.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
comparison
equal
deleted
inserted
replaced
111:04ced10e8804 | 131:84e7813d76e9 |
---|---|
1 /* The tracer pass for the GNU compiler. | 1 /* The tracer pass for the GNU compiler. |
2 Contributed by Jan Hubicka, SuSE Labs. | 2 Contributed by Jan Hubicka, SuSE Labs. |
3 Adapted to work on GIMPLE instead of RTL by Robert Kidd, UIUC. | 3 Adapted to work on GIMPLE instead of RTL by Robert Kidd, UIUC. |
4 Copyright (C) 2001-2017 Free Software Foundation, Inc. | 4 Copyright (C) 2001-2018 Free Software Foundation, Inc. |
5 | 5 |
6 This file is part of GCC. | 6 This file is part of GCC. |
7 | 7 |
8 GCC is free software; you can redistribute it and/or modify it | 8 GCC is free software; you can redistribute it and/or modify it |
9 under the terms of the GNU General Public License as published by | 9 under the terms of the GNU General Public License as published by |
130 | 130 |
131 /* Return true if E1 is more frequent than E2. */ | 131 /* Return true if E1 is more frequent than E2. */ |
132 static bool | 132 static bool |
133 better_p (const_edge e1, const_edge e2) | 133 better_p (const_edge e1, const_edge e2) |
134 { | 134 { |
135 if (e1->count ().initialized_p () && e2->count ().initialized_p () | 135 if ((e1->count () > e2->count ()) || (e1->count () < e2->count ())) |
136 && ((e1->count () > e2->count ()) || (e1->count () < e2->count ()))) | |
137 return e1->count () > e2->count (); | 136 return e1->count () > e2->count (); |
138 if (EDGE_FREQUENCY (e1) != EDGE_FREQUENCY (e2)) | |
139 return EDGE_FREQUENCY (e1) > EDGE_FREQUENCY (e2); | |
140 /* This is needed to avoid changes in the decision after | 137 /* This is needed to avoid changes in the decision after |
141 CFG is modified. */ | 138 CFG is modified. */ |
142 if (e1->src != e2->src) | 139 if (e1->src != e2->src) |
143 return e1->src->index > e2->src->index; | 140 return e1->src->index > e2->src->index; |
144 return e1->dest->index > e2->dest->index; | 141 return e1->dest->index > e2->dest->index; |
152 edge e; | 149 edge e; |
153 edge best = NULL; | 150 edge best = NULL; |
154 edge_iterator ei; | 151 edge_iterator ei; |
155 | 152 |
156 FOR_EACH_EDGE (e, ei, bb->succs) | 153 FOR_EACH_EDGE (e, ei, bb->succs) |
157 if (!best || better_p (e, best)) | 154 { |
158 best = e; | 155 if (!e->count ().initialized_p ()) |
156 return NULL; | |
157 if (!best || better_p (e, best)) | |
158 best = e; | |
159 } | |
159 if (!best || ignore_bb_p (best->dest)) | 160 if (!best || ignore_bb_p (best->dest)) |
160 return NULL; | 161 return NULL; |
161 if (best->probability.initialized_p () | 162 if (!best->probability.initialized_p () |
162 && best->probability.to_reg_br_prob_base () <= probability_cutoff) | 163 || best->probability.to_reg_br_prob_base () <= probability_cutoff) |
163 return NULL; | 164 return NULL; |
164 return best; | 165 return best; |
165 } | 166 } |
166 | 167 |
167 /* Return most frequent predecessor of basic block BB. */ | 168 /* Return most frequent predecessor of basic block BB. */ |
172 edge e; | 173 edge e; |
173 edge best = NULL; | 174 edge best = NULL; |
174 edge_iterator ei; | 175 edge_iterator ei; |
175 | 176 |
176 FOR_EACH_EDGE (e, ei, bb->preds) | 177 FOR_EACH_EDGE (e, ei, bb->preds) |
177 if (!best || better_p (e, best)) | 178 { |
178 best = e; | 179 if (!e->count ().initialized_p ()) |
180 return NULL; | |
181 if (!best || better_p (e, best)) | |
182 best = e; | |
183 } | |
179 if (!best || ignore_bb_p (best->src)) | 184 if (!best || ignore_bb_p (best->src)) |
180 return NULL; | 185 return NULL; |
181 if (EDGE_FREQUENCY (best) * REG_BR_PROB_BASE | 186 if (bb->count.initialized_p () |
182 < bb->frequency * branch_ratio_cutoff) | 187 && (best->count ().to_frequency (cfun) * REG_BR_PROB_BASE |
188 < bb->count.to_frequency (cfun) * branch_ratio_cutoff)) | |
183 return NULL; | 189 return NULL; |
184 return best; | 190 return best; |
185 } | 191 } |
186 | 192 |
187 /* Find the trace using bb and record it in the TRACE array. | 193 /* Find the trace using bb and record it in the TRACE array. |
192 { | 198 { |
193 int i = 0; | 199 int i = 0; |
194 edge e; | 200 edge e; |
195 | 201 |
196 if (dump_file) | 202 if (dump_file) |
197 fprintf (dump_file, "Trace seed %i [%i]", bb->index, bb->frequency); | 203 fprintf (dump_file, "Trace seed %i [%i]", bb->index, bb->count.to_frequency (cfun)); |
198 | 204 |
199 while ((e = find_best_predecessor (bb)) != NULL) | 205 while ((e = find_best_predecessor (bb)) != NULL) |
200 { | 206 { |
201 basic_block bb2 = e->src; | 207 basic_block bb2 = e->src; |
202 if (bb_seen_p (bb2) || (e->flags & (EDGE_DFS_BACK | EDGE_COMPLEX)) | 208 if (bb_seen_p (bb2) || (e->flags & (EDGE_DFS_BACK | EDGE_COMPLEX)) |
203 || find_best_successor (bb2) != e) | 209 || find_best_successor (bb2) != e) |
204 break; | 210 break; |
205 if (dump_file) | 211 if (dump_file) |
206 fprintf (dump_file, ",%i [%i]", bb->index, bb->frequency); | 212 fprintf (dump_file, ",%i [%i]", bb->index, bb->count.to_frequency (cfun)); |
207 bb = bb2; | 213 bb = bb2; |
208 } | 214 } |
209 if (dump_file) | 215 if (dump_file) |
210 fprintf (dump_file, " forward %i [%i]", bb->index, bb->frequency); | 216 fprintf (dump_file, " forward %i [%i]", bb->index, bb->count.to_frequency (cfun)); |
211 trace[i++] = bb; | 217 trace[i++] = bb; |
212 | 218 |
213 /* Follow the trace in forward direction. */ | 219 /* Follow the trace in forward direction. */ |
214 while ((e = find_best_successor (bb)) != NULL) | 220 while ((e = find_best_successor (bb)) != NULL) |
215 { | 221 { |
216 bb = e->dest; | 222 bb = e->dest; |
217 if (bb_seen_p (bb) || (e->flags & (EDGE_DFS_BACK | EDGE_COMPLEX)) | 223 if (bb_seen_p (bb) || (e->flags & (EDGE_DFS_BACK | EDGE_COMPLEX)) |
218 || find_best_predecessor (bb) != e) | 224 || find_best_predecessor (bb) != e) |
219 break; | 225 break; |
220 if (dump_file) | 226 if (dump_file) |
221 fprintf (dump_file, ",%i [%i]", bb->index, bb->frequency); | 227 fprintf (dump_file, ",%i [%i]", bb->index, bb->count.to_frequency (cfun)); |
222 trace[i++] = bb; | 228 trace[i++] = bb; |
223 } | 229 } |
224 if (dump_file) | 230 if (dump_file) |
225 fprintf (dump_file, "\n"); | 231 fprintf (dump_file, "\n"); |
226 return i; | 232 return i; |
280 | 286 |
281 FOR_EACH_BB_FN (bb, cfun) | 287 FOR_EACH_BB_FN (bb, cfun) |
282 { | 288 { |
283 int n = count_insns (bb); | 289 int n = count_insns (bb); |
284 if (!ignore_bb_p (bb)) | 290 if (!ignore_bb_p (bb)) |
285 blocks[bb->index] = heap.insert (-bb->frequency, bb); | 291 blocks[bb->index] = heap.insert (-bb->count.to_frequency (cfun), bb); |
286 | 292 |
287 counts [bb->index] = n; | 293 counts [bb->index] = n; |
288 ninsns += n; | 294 ninsns += n; |
289 weighted_insns += n * bb->frequency; | 295 weighted_insns += n * bb->count.to_frequency (cfun); |
290 } | 296 } |
291 | 297 |
292 if (profile_info && profile_status_for_fn (cfun) == PROFILE_READ) | 298 if (profile_info && profile_status_for_fn (cfun) == PROFILE_READ) |
293 cover_insns = PARAM_VALUE (TRACER_DYNAMIC_COVERAGE_FEEDBACK); | 299 cover_insns = PARAM_VALUE (TRACER_DYNAMIC_COVERAGE_FEEDBACK); |
294 else | 300 else |
312 gcc_assert (!bb_seen_p (bb)); | 318 gcc_assert (!bb_seen_p (bb)); |
313 | 319 |
314 n = find_trace (bb, trace); | 320 n = find_trace (bb, trace); |
315 | 321 |
316 bb = trace[0]; | 322 bb = trace[0]; |
317 traced_insns += bb->frequency * counts [bb->index]; | 323 traced_insns += bb->count.to_frequency (cfun) * counts [bb->index]; |
318 if (blocks[bb->index]) | 324 if (blocks[bb->index]) |
319 { | 325 { |
320 heap.delete_node (blocks[bb->index]); | 326 heap.delete_node (blocks[bb->index]); |
321 blocks[bb->index] = NULL; | 327 blocks[bb->index] = NULL; |
322 } | 328 } |
328 if (blocks[bb2->index]) | 334 if (blocks[bb2->index]) |
329 { | 335 { |
330 heap.delete_node (blocks[bb2->index]); | 336 heap.delete_node (blocks[bb2->index]); |
331 blocks[bb2->index] = NULL; | 337 blocks[bb2->index] = NULL; |
332 } | 338 } |
333 traced_insns += bb2->frequency * counts [bb2->index]; | 339 traced_insns += bb2->count.to_frequency (cfun) * counts [bb2->index]; |
334 if (EDGE_COUNT (bb2->preds) > 1 | 340 if (EDGE_COUNT (bb2->preds) > 1 |
335 && can_duplicate_block_p (bb2) | 341 && can_duplicate_block_p (bb2) |
336 /* We have the tendency to duplicate the loop header | 342 /* We have the tendency to duplicate the loop header |
337 of all do { } while loops. Do not do that - it is | 343 of all do { } while loops. Do not do that - it is |
338 not profitable and it might create a loop with multiple | 344 not profitable and it might create a loop with multiple |
343 basic_block copy = transform_duplicate (bb, bb2); | 349 basic_block copy = transform_duplicate (bb, bb2); |
344 | 350 |
345 /* Reconsider the original copy of block we've duplicated. | 351 /* Reconsider the original copy of block we've duplicated. |
346 Removing the most common predecessor may make it to be | 352 Removing the most common predecessor may make it to be |
347 head. */ | 353 head. */ |
348 blocks[bb2->index] = heap.insert (-bb2->frequency, bb2); | 354 blocks[bb2->index] = heap.insert (-bb2->count.to_frequency (cfun), bb2); |
349 | 355 |
350 if (dump_file) | 356 if (dump_file) |
351 fprintf (dump_file, "Duplicated %i as %i [%i]\n", | 357 fprintf (dump_file, "Duplicated %i as %i [%i]\n", |
352 bb2->index, copy->index, copy->frequency); | 358 bb2->index, copy->index, copy->count.to_frequency (cfun)); |
353 | 359 |
354 bb2 = copy; | 360 bb2 = copy; |
355 changed = true; | 361 changed = true; |
356 } | 362 } |
357 mark_bb_seen (bb2); | 363 mark_bb_seen (bb2); |