00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 #include "config.h"
00050 #include "system.h"
00051 #include "coretypes.h"
00052 #include "tm.h"
00053 #include "tree.h"
00054 #include "rtl.h"
00055 #include "hard-reg-set.h"
00056 #include "regs.h"
00057 #include "flags.h"
00058 #include "output.h"
00059 #include "function.h"
00060 #include "except.h"
00061 #include "toplev.h"
00062 #include "tm_p.h"
00063 #include "alloc-pool.h"
00064 #include "timevar.h"
00065 #include "ggc.h"
00066
00067
00068
00069 struct bitmap_obstack reg_obstack;
00070
00071
00072
00073 int n_basic_blocks;
00074
00075
00076
00077 int last_basic_block;
00078
00079
00080
00081 int n_edges;
00082
00083
00084
00085 varray_type basic_block_info;
00086
00087
00088 basic_block ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR;
00089
00090
00091 alloc_pool rbi_pool;
00092
00093 void debug_flow_info (void);
00094 static void free_edge (edge);
00095
00096
00097 enum profile_status profile_status;
00098
00099
00100
00101 void
00102 init_flow (void)
00103 {
00104 n_edges = 0;
00105
00106 ENTRY_BLOCK_PTR = ggc_alloc_cleared (sizeof (*ENTRY_BLOCK_PTR));
00107 ENTRY_BLOCK_PTR->index = ENTRY_BLOCK;
00108 EXIT_BLOCK_PTR = ggc_alloc_cleared (sizeof (*EXIT_BLOCK_PTR));
00109 EXIT_BLOCK_PTR->index = EXIT_BLOCK;
00110 ENTRY_BLOCK_PTR->next_bb = EXIT_BLOCK_PTR;
00111 EXIT_BLOCK_PTR->prev_bb = ENTRY_BLOCK_PTR;
00112 }
00113
00114
00115
00116
00117 static void
00118 free_edge (edge e ATTRIBUTE_UNUSED)
00119 {
00120 n_edges--;
00121 ggc_free (e);
00122 }
00123
00124
00125
00126 void
00127 clear_edges (void)
00128 {
00129 basic_block bb;
00130 edge e;
00131 edge_iterator ei;
00132
00133 FOR_EACH_BB (bb)
00134 {
00135 FOR_EACH_EDGE (e, ei, bb->succs)
00136 free_edge (e);
00137 VEC_truncate (edge, bb->succs, 0);
00138 VEC_truncate (edge, bb->preds, 0);
00139 }
00140
00141 FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
00142 free_edge (e);
00143 VEC_truncate (edge, EXIT_BLOCK_PTR->preds, 0);
00144 VEC_truncate (edge, ENTRY_BLOCK_PTR->succs, 0);
00145
00146 gcc_assert (!n_edges);
00147 }
00148
00149
00150
00151 basic_block
00152 alloc_block (void)
00153 {
00154 basic_block bb;
00155 bb = ggc_alloc_cleared (sizeof (*bb));
00156 return bb;
00157 }
00158
00159
00160
00161 void
00162 alloc_rbi_pool (void)
00163 {
00164 rbi_pool = create_alloc_pool ("rbi pool",
00165 sizeof (struct reorder_block_def),
00166 n_basic_blocks + 2);
00167 }
00168
00169
00170
00171 void
00172 free_rbi_pool (void)
00173 {
00174 free_alloc_pool (rbi_pool);
00175 }
00176
00177
00178
00179
00180 void
00181 initialize_bb_rbi (basic_block bb)
00182 {
00183 gcc_assert (!bb->rbi);
00184 bb->rbi = pool_alloc (rbi_pool);
00185 memset (bb->rbi, 0, sizeof (struct reorder_block_def));
00186 }
00187
00188
00189 void
00190 link_block (basic_block b, basic_block after)
00191 {
00192 b->next_bb = after->next_bb;
00193 b->prev_bb = after;
00194 after->next_bb = b;
00195 b->next_bb->prev_bb = b;
00196 }
00197
00198
00199 void
00200 unlink_block (basic_block b)
00201 {
00202 b->next_bb->prev_bb = b->prev_bb;
00203 b->prev_bb->next_bb = b->next_bb;
00204 b->prev_bb = NULL;
00205 b->next_bb = NULL;
00206 }
00207
00208
00209 void
00210 compact_blocks (void)
00211 {
00212 int i;
00213 basic_block bb;
00214
00215 i = 0;
00216 FOR_EACH_BB (bb)
00217 {
00218 BASIC_BLOCK (i) = bb;
00219 bb->index = i;
00220 i++;
00221 }
00222
00223 gcc_assert (i == n_basic_blocks);
00224
00225 for (; i < last_basic_block; i++)
00226 BASIC_BLOCK (i) = NULL;
00227
00228 last_basic_block = n_basic_blocks;
00229 }
00230
00231
00232
00233 void
00234 expunge_block (basic_block b)
00235 {
00236 unlink_block (b);
00237 BASIC_BLOCK (b->index) = NULL;
00238 n_basic_blocks--;
00239
00240
00241
00242
00243
00244 }
00245
00246
00247
00248
00249
00250 edge
00251 unchecked_make_edge (basic_block src, basic_block dst, int flags)
00252 {
00253 edge e;
00254 e = ggc_alloc_cleared (sizeof (*e));
00255 n_edges++;
00256
00257 VEC_safe_push (edge, src->succs, e);
00258 VEC_safe_push (edge, dst->preds, e);
00259
00260 e->src = src;
00261 e->dest = dst;
00262 e->flags = flags;
00263 e->dest_idx = EDGE_COUNT (dst->preds) - 1;
00264
00265 execute_on_growing_pred (e);
00266
00267 return e;
00268 }
00269
00270
00271
00272
00273 edge
00274 cached_make_edge (sbitmap *edge_cache, basic_block src, basic_block dst, int flags)
00275 {
00276 if (edge_cache == NULL
00277 || src == ENTRY_BLOCK_PTR
00278 || dst == EXIT_BLOCK_PTR)
00279 return make_edge (src, dst, flags);
00280
00281
00282 if (! TEST_BIT (edge_cache[src->index], dst->index))
00283 {
00284
00285
00286 SET_BIT (edge_cache[src->index], dst->index);
00287 return unchecked_make_edge (src, dst, flags);
00288 }
00289
00290
00291
00292 if (flags)
00293 {
00294 edge e = find_edge (src, dst);
00295 e->flags |= flags;
00296 }
00297
00298 return NULL;
00299 }
00300
00301
00302
00303
00304 edge
00305 make_edge (basic_block src, basic_block dest, int flags)
00306 {
00307 edge e = find_edge (src, dest);
00308
00309
00310 if (e)
00311 {
00312 e->flags |= flags;
00313 return NULL;
00314 }
00315
00316 return unchecked_make_edge (src, dest, flags);
00317 }
00318
00319
00320
00321
00322 edge
00323 make_single_succ_edge (basic_block src, basic_block dest, int flags)
00324 {
00325 edge e = make_edge (src, dest, flags);
00326
00327 e->probability = REG_BR_PROB_BASE;
00328 e->count = src->count;
00329 return e;
00330 }
00331
00332
00333
00334 void
00335 remove_edge (edge e)
00336 {
00337 edge tmp;
00338 basic_block src, dest;
00339 unsigned int dest_idx;
00340 bool found = false;
00341 edge_iterator ei;
00342
00343 execute_on_shrinking_pred (e);
00344
00345 src = e->src;
00346 dest = e->dest;
00347 dest_idx = e->dest_idx;
00348
00349 for (ei = ei_start (src->succs); (tmp = ei_safe_edge (ei)); )
00350 {
00351 if (tmp == e)
00352 {
00353 VEC_unordered_remove (edge, src->succs, ei.index);
00354 found = true;
00355 break;
00356 }
00357 else
00358 ei_next (&ei);
00359 }
00360
00361 gcc_assert (found);
00362
00363 VEC_unordered_remove (edge, dest->preds, dest_idx);
00364
00365
00366
00367 if (dest_idx < EDGE_COUNT (dest->preds))
00368 EDGE_PRED (dest, dest_idx)->dest_idx = dest_idx;
00369
00370 free_edge (e);
00371 }
00372
00373
00374
00375 void
00376 redirect_edge_succ (edge e, basic_block new_succ)
00377 {
00378 basic_block dest = e->dest;
00379 unsigned int dest_idx = e->dest_idx;
00380
00381 execute_on_shrinking_pred (e);
00382
00383 VEC_unordered_remove (edge, dest->preds, dest_idx);
00384
00385
00386
00387 if (dest_idx < EDGE_COUNT (dest->preds))
00388 EDGE_PRED (dest, dest_idx)->dest_idx = dest_idx;
00389
00390
00391 VEC_safe_push (edge, new_succ->preds, e);
00392 e->dest = new_succ;
00393 e->dest_idx = EDGE_COUNT (new_succ->preds) - 1;
00394 execute_on_growing_pred (e);
00395 }
00396
00397
00398
00399 edge
00400 redirect_edge_succ_nodup (edge e, basic_block new_succ)
00401 {
00402 edge s;
00403
00404 s = find_edge (e->src, new_succ);
00405 if (s && s != e)
00406 {
00407 s->flags |= e->flags;
00408 s->probability += e->probability;
00409 if (s->probability > REG_BR_PROB_BASE)
00410 s->probability = REG_BR_PROB_BASE;
00411 s->count += e->count;
00412 remove_edge (e);
00413 e = s;
00414 }
00415 else
00416 redirect_edge_succ (e, new_succ);
00417
00418 return e;
00419 }
00420
00421
00422
00423 void
00424 redirect_edge_pred (edge e, basic_block new_pred)
00425 {
00426 edge tmp;
00427 edge_iterator ei;
00428 bool found = false;
00429
00430
00431 for (ei = ei_start (e->src->succs); (tmp = ei_safe_edge (ei)); )
00432 {
00433 if (tmp == e)
00434 {
00435 VEC_unordered_remove (edge, e->src->succs, ei.index);
00436 found = true;
00437 break;
00438 }
00439 else
00440 ei_next (&ei);
00441 }
00442
00443 gcc_assert (found);
00444
00445
00446 VEC_safe_push (edge, new_pred->succs, e);
00447 e->src = new_pred;
00448 }
00449
00450
00451 void
00452 clear_bb_flags (void)
00453 {
00454 basic_block bb;
00455
00456 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
00457 bb->flags = BB_PARTITION (bb);
00458 }
00459
00460
00461
00462
00463
00464
00465 void
00466 check_bb_profile (basic_block bb, FILE * file)
00467 {
00468 edge e;
00469 int sum = 0;
00470 gcov_type lsum;
00471 edge_iterator ei;
00472
00473 if (profile_status == PROFILE_ABSENT)
00474 return;
00475
00476 if (bb != EXIT_BLOCK_PTR)
00477 {
00478 FOR_EACH_EDGE (e, ei, bb->succs)
00479 sum += e->probability;
00480 if (EDGE_COUNT (bb->succs) && abs (sum - REG_BR_PROB_BASE) > 100)
00481 fprintf (file, "Invalid sum of outgoing probabilities %.1f%%\n",
00482 sum * 100.0 / REG_BR_PROB_BASE);
00483 lsum = 0;
00484 FOR_EACH_EDGE (e, ei, bb->succs)
00485 lsum += e->count;
00486 if (EDGE_COUNT (bb->succs)
00487 && (lsum - bb->count > 100 || lsum - bb->count < -100))
00488 fprintf (file, "Invalid sum of outgoing counts %i, should be %i\n",
00489 (int) lsum, (int) bb->count);
00490 }
00491 if (bb != ENTRY_BLOCK_PTR)
00492 {
00493 sum = 0;
00494 FOR_EACH_EDGE (e, ei, bb->preds)
00495 sum += EDGE_FREQUENCY (e);
00496 if (abs (sum - bb->frequency) > 100)
00497 fprintf (file,
00498 "Invalid sum of incoming frequencies %i, should be %i\n",
00499 sum, bb->frequency);
00500 lsum = 0;
00501 FOR_EACH_EDGE (e, ei, bb->preds)
00502 lsum += e->count;
00503 if (lsum - bb->count > 100 || lsum - bb->count < -100)
00504 fprintf (file, "Invalid sum of incoming counts %i, should be %i\n",
00505 (int) lsum, (int) bb->count);
00506 }
00507 }
00508
00509 void
00510 dump_flow_info (FILE *file)
00511 {
00512 int i;
00513 basic_block bb;
00514
00515
00516 if (reg_n_info && !reload_completed)
00517 {
00518 int max_regno = max_reg_num ();
00519 fprintf (file, "%d registers.\n", max_regno);
00520 for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
00521 if (REG_N_REFS (i))
00522 {
00523 enum reg_class class, altclass;
00524
00525 fprintf (file, "\nRegister %d used %d times across %d insns",
00526 i, REG_N_REFS (i), REG_LIVE_LENGTH (i));
00527 if (REG_BASIC_BLOCK (i) >= 0)
00528 fprintf (file, " in block %d", REG_BASIC_BLOCK (i));
00529 if (REG_N_SETS (i))
00530 fprintf (file, "; set %d time%s", REG_N_SETS (i),
00531 (REG_N_SETS (i) == 1) ? "" : "s");
00532 if (regno_reg_rtx[i] != NULL && REG_USERVAR_P (regno_reg_rtx[i]))
00533 fprintf (file, "; user var");
00534 if (REG_N_DEATHS (i) != 1)
00535 fprintf (file, "; dies in %d places", REG_N_DEATHS (i));
00536 if (REG_N_CALLS_CROSSED (i) == 1)
00537 fprintf (file, "; crosses 1 call");
00538 else if (REG_N_CALLS_CROSSED (i))
00539 fprintf (file, "; crosses %d calls", REG_N_CALLS_CROSSED (i));
00540 if (regno_reg_rtx[i] != NULL
00541 && PSEUDO_REGNO_BYTES (i) != UNITS_PER_WORD)
00542 fprintf (file, "; %d bytes", PSEUDO_REGNO_BYTES (i));
00543
00544 class = reg_preferred_class (i);
00545 altclass = reg_alternate_class (i);
00546 if (class != GENERAL_REGS || altclass != ALL_REGS)
00547 {
00548 if (altclass == ALL_REGS || class == ALL_REGS)
00549 fprintf (file, "; pref %s", reg_class_names[(int) class]);
00550 else if (altclass == NO_REGS)
00551 fprintf (file, "; %s or none", reg_class_names[(int) class]);
00552 else
00553 fprintf (file, "; pref %s, else %s",
00554 reg_class_names[(int) class],
00555 reg_class_names[(int) altclass]);
00556 }
00557
00558 if (regno_reg_rtx[i] != NULL && REG_POINTER (regno_reg_rtx[i]))
00559 fprintf (file, "; pointer");
00560 fprintf (file, ".\n");
00561 }
00562 }
00563
00564 fprintf (file, "\n%d basic blocks, %d edges.\n", n_basic_blocks, n_edges);
00565 FOR_EACH_BB (bb)
00566 {
00567 edge e;
00568 edge_iterator ei;
00569
00570 fprintf (file, "\nBasic block %d ", bb->index);
00571 fprintf (file, "prev %d, next %d, ",
00572 bb->prev_bb->index, bb->next_bb->index);
00573 fprintf (file, "loop_depth %d, count ", bb->loop_depth);
00574 fprintf (file, HOST_WIDEST_INT_PRINT_DEC, bb->count);
00575 fprintf (file, ", freq %i", bb->frequency);
00576 if (maybe_hot_bb_p (bb))
00577 fprintf (file, ", maybe hot");
00578 if (probably_never_executed_bb_p (bb))
00579 fprintf (file, ", probably never executed");
00580 fprintf (file, ".\n");
00581
00582 fprintf (file, "Predecessors: ");
00583 FOR_EACH_EDGE (e, ei, bb->preds)
00584 dump_edge_info (file, e, 0);
00585
00586 fprintf (file, "\nSuccessors: ");
00587 FOR_EACH_EDGE (e, ei, bb->succs)
00588 dump_edge_info (file, e, 1);
00589
00590 if (bb->global_live_at_start)
00591 {
00592 fprintf (file, "\nRegisters live at start:");
00593 dump_regset (bb->global_live_at_start, file);
00594 }
00595
00596 if (bb->global_live_at_end)
00597 {
00598 fprintf (file, "\nRegisters live at end:");
00599 dump_regset (bb->global_live_at_end, file);
00600 }
00601
00602 putc ('\n', file);
00603 check_bb_profile (bb, file);
00604 }
00605
00606 putc ('\n', file);
00607 }
00608
00609 void
00610 debug_flow_info (void)
00611 {
00612 dump_flow_info (stderr);
00613 }
00614
00615 void
00616 dump_edge_info (FILE *file, edge e, int do_succ)
00617 {
00618 basic_block side = (do_succ ? e->dest : e->src);
00619
00620 if (side == ENTRY_BLOCK_PTR)
00621 fputs (" ENTRY", file);
00622 else if (side == EXIT_BLOCK_PTR)
00623 fputs (" EXIT", file);
00624 else
00625 fprintf (file, " %d", side->index);
00626
00627 if (e->probability)
00628 fprintf (file, " [%.1f%%] ", e->probability * 100.0 / REG_BR_PROB_BASE);
00629
00630 if (e->count)
00631 {
00632 fprintf (file, " count:");
00633 fprintf (file, HOST_WIDEST_INT_PRINT_DEC, e->count);
00634 }
00635
00636 if (e->flags)
00637 {
00638 static const char * const bitnames[] = {
00639 "fallthru", "ab", "abcall", "eh", "fake", "dfs_back",
00640 "can_fallthru", "irreducible", "sibcall", "loop_exit",
00641 "true", "false", "exec"
00642 };
00643 int comma = 0;
00644 int i, flags = e->flags;
00645
00646 fputs (" (", file);
00647 for (i = 0; flags; i++)
00648 if (flags & (1 << i))
00649 {
00650 flags &= ~(1 << i);
00651
00652 if (comma)
00653 fputc (',', file);
00654 if (i < (int) ARRAY_SIZE (bitnames))
00655 fputs (bitnames[i], file);
00656 else
00657 fprintf (file, "%d", i);
00658 comma = 1;
00659 }
00660
00661 fputc (')', file);
00662 }
00663 }
00664
00665
00666
00667 static struct obstack block_aux_obstack;
00668 static void *first_block_aux_obj = 0;
00669 static struct obstack edge_aux_obstack;
00670 static void *first_edge_aux_obj = 0;
00671
00672
00673
00674
00675 inline void
00676 alloc_aux_for_block (basic_block bb, int size)
00677 {
00678
00679 gcc_assert (!bb->aux && first_block_aux_obj);
00680 bb->aux = obstack_alloc (&block_aux_obstack, size);
00681 memset (bb->aux, 0, size);
00682 }
00683
00684
00685
00686
00687 void
00688 alloc_aux_for_blocks (int size)
00689 {
00690 static int initialized;
00691
00692 if (!initialized)
00693 {
00694 gcc_obstack_init (&block_aux_obstack);
00695 initialized = 1;
00696 }
00697 else
00698
00699 gcc_assert (!first_block_aux_obj);
00700
00701 first_block_aux_obj = obstack_alloc (&block_aux_obstack, 0);
00702 if (size)
00703 {
00704 basic_block bb;
00705
00706 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
00707 alloc_aux_for_block (bb, size);
00708 }
00709 }
00710
00711
00712
00713 void
00714 clear_aux_for_blocks (void)
00715 {
00716 basic_block bb;
00717
00718 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
00719 bb->aux = NULL;
00720 }
00721
00722
00723
00724
00725 void
00726 free_aux_for_blocks (void)
00727 {
00728 gcc_assert (first_block_aux_obj);
00729 obstack_free (&block_aux_obstack, first_block_aux_obj);
00730 first_block_aux_obj = NULL;
00731
00732 clear_aux_for_blocks ();
00733 }
00734
00735
00736
00737
00738 inline void
00739 alloc_aux_for_edge (edge e, int size)
00740 {
00741
00742 gcc_assert (!e->aux && first_edge_aux_obj);
00743 e->aux = obstack_alloc (&edge_aux_obstack, size);
00744 memset (e->aux, 0, size);
00745 }
00746
00747
00748
00749
00750 void
00751 alloc_aux_for_edges (int size)
00752 {
00753 static int initialized;
00754
00755 if (!initialized)
00756 {
00757 gcc_obstack_init (&edge_aux_obstack);
00758 initialized = 1;
00759 }
00760 else
00761
00762 gcc_assert (!first_edge_aux_obj);
00763
00764 first_edge_aux_obj = obstack_alloc (&edge_aux_obstack, 0);
00765 if (size)
00766 {
00767 basic_block bb;
00768
00769 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
00770 {
00771 edge e;
00772 edge_iterator ei;
00773
00774 FOR_EACH_EDGE (e, ei, bb->succs)
00775 alloc_aux_for_edge (e, size);
00776 }
00777 }
00778 }
00779
00780
00781
00782 void
00783 clear_aux_for_edges (void)
00784 {
00785 basic_block bb;
00786 edge e;
00787
00788 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
00789 {
00790 edge_iterator ei;
00791 FOR_EACH_EDGE (e, ei, bb->succs)
00792 e->aux = NULL;
00793 }
00794 }
00795
00796
00797
00798
00799 void
00800 free_aux_for_edges (void)
00801 {
00802 gcc_assert (first_edge_aux_obj);
00803 obstack_free (&edge_aux_obstack, first_edge_aux_obj);
00804 first_edge_aux_obj = NULL;
00805
00806 clear_aux_for_edges ();
00807 }
00808
00809 void
00810 debug_bb (basic_block bb)
00811 {
00812 dump_bb (bb, stderr, 0);
00813 }
00814
00815 basic_block
00816 debug_bb_n (int n)
00817 {
00818 basic_block bb = BASIC_BLOCK (n);
00819 dump_bb (bb, stderr, 0);
00820 return bb;
00821 }
00822
00823
00824
00825 static void
00826 dump_cfg_bb_info (FILE *file, basic_block bb)
00827 {
00828 unsigned i;
00829 edge_iterator ei;
00830 bool first = true;
00831 static const char * const bb_bitnames[] =
00832 {
00833 "dirty", "new", "reachable", "visited", "irreducible_loop", "superblock"
00834 };
00835 const unsigned n_bitnames = sizeof (bb_bitnames) / sizeof (char *);
00836 edge e;
00837
00838 fprintf (file, "Basic block %d", bb->index);
00839 for (i = 0; i < n_bitnames; i++)
00840 if (bb->flags & (1 << i))
00841 {
00842 if (first)
00843 fprintf (file, " (");
00844 else
00845 fprintf (file, ", ");
00846 first = false;
00847 fprintf (file, bb_bitnames[i]);
00848 }
00849 if (!first)
00850 fprintf (file, ")");
00851 fprintf (file, "\n");
00852
00853 fprintf (file, "Predecessors: ");
00854 FOR_EACH_EDGE (e, ei, bb->preds)
00855 dump_edge_info (file, e, 0);
00856
00857 fprintf (file, "\nSuccessors: ");
00858 FOR_EACH_EDGE (e, ei, bb->succs)
00859 dump_edge_info (file, e, 1);
00860 fprintf (file, "\n\n");
00861 }
00862
00863
00864
00865 void
00866 brief_dump_cfg (FILE *file)
00867 {
00868 basic_block bb;
00869
00870 FOR_EACH_BB (bb)
00871 {
00872 dump_cfg_bb_info (file, bb);
00873 }
00874 }
00875
00876
00877
00878
00879
00880
00881
00882
00883 void
00884 update_bb_profile_for_threading (basic_block bb, int edge_frequency,
00885 gcov_type count, edge taken_edge)
00886 {
00887 edge c;
00888 int prob;
00889 edge_iterator ei;
00890
00891 bb->count -= count;
00892 if (bb->count < 0)
00893 bb->count = 0;
00894
00895
00896
00897 if (bb->frequency)
00898 prob = edge_frequency * REG_BR_PROB_BASE / bb->frequency;
00899 else
00900 prob = 0;
00901 if (prob > taken_edge->probability)
00902 {
00903 if (dump_file)
00904 fprintf (dump_file, "Jump threading proved probability of edge "
00905 "%i->%i too small (it is %i, should be %i).\n",
00906 taken_edge->src->index, taken_edge->dest->index,
00907 taken_edge->probability, prob);
00908 prob = taken_edge->probability;
00909 }
00910
00911
00912 taken_edge->probability -= prob;
00913 prob = REG_BR_PROB_BASE - prob;
00914 bb->frequency -= edge_frequency;
00915 if (bb->frequency < 0)
00916 bb->frequency = 0;
00917 if (prob <= 0)
00918 {
00919 if (dump_file)
00920 fprintf (dump_file, "Edge frequencies of bb %i has been reset, "
00921 "frequency of block should end up being 0, it is %i\n",
00922 bb->index, bb->frequency);
00923 EDGE_SUCC (bb, 0)->probability = REG_BR_PROB_BASE;
00924 ei = ei_start (bb->succs);
00925 ei_next (&ei);
00926 for (; (c = ei_safe_edge (ei)); ei_next (&ei))
00927 c->probability = 0;
00928 }
00929 else if (prob != REG_BR_PROB_BASE)
00930 {
00931 int scale = REG_BR_PROB_BASE / prob;
00932
00933 FOR_EACH_EDGE (c, ei, bb->succs)
00934 c->probability *= scale;
00935 }
00936
00937 if (bb != taken_edge->src)
00938 abort ();
00939 taken_edge->count -= count;
00940 if (taken_edge->count < 0)
00941 taken_edge->count = 0;
00942 }