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
00050
00051
00052
00053
00054
00055
00056
00057 #include <math.h>
00058 #include <alloca.h>
00059
00060 #include "defs.h"
00061 #include "config.h"
00062 #include "errors.h"
00063 #include "mempool.h"
00064 #include "tracing.h"
00065 #include "glob.h"
00066 #include "config_asm.h"
00067 #include "bitset.h"
00068 #include "bb.h"
00069 #include "variants.h"
00070 #include "bb_set.h"
00071 #include "bb_map.h"
00072 #include "dominate.h"
00073 #include "region_util.h"
00074 #include "cg_region.h"
00075 #include "cg_flags.h"
00076 #include "cflow.h"
00077 #include "annotations.h"
00078 #include "cg.h"
00079 #include "whirl2ops.h"
00080 #include "note.h"
00081 #include "findloops.h"
00082 #include "cgtarget.h"
00083 #include "label_util.h"
00084 #include "fb_whirl.h"
00085 #include "DaVinci.h"
00086 #include "freq.h"
00087 #ifdef TARG_IA64
00088 #include "cg_flags.h"
00089 #include "ipfec_options.h"
00090 #endif
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 BOOL FREQ_freqs_computed;
00102 static BB_SET *Never_BBs;
00103 static BB_SET *Frequent_BBs;
00104 static float Frequent_Never_Ratio;
00105 static BB_MAP dfo_map;
00106 static BB **dfo_vec;
00107 static INT32 max_dfo_id;
00108 static float EH_Freq;
00109 #ifdef KEY
00110 static float Non_Local_Target_Freq;
00111 #endif
00112 static LOOP_DESCR *loop_list;
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132 static void
00133 Initialize_Depth_First_Info(MEM_POOL *pool)
00134 {
00135 BB *bb;
00136 dfo_map = BB_Depth_First_Map(NULL, NULL);
00137 dfo_vec = TYPE_MEM_POOL_ALLOC_N(BB *, pool, PU_BB_Count);
00138 max_dfo_id = 0;
00139 for (bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
00140 INT32 dfo_id = BB_MAP32_Get(dfo_map, bb);
00141 DevAssert(dfo_id >= 0 && dfo_id <= PU_BB_Count, ("bad <dfo_map> value"));
00142 if (dfo_id > 0) {
00143 max_dfo_id = MAX(dfo_id, max_dfo_id);
00144 dfo_vec[dfo_id - 1] = bb;
00145 }
00146 }
00147 }
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 inline void
00159 Finalize_Depth_First_Info(void)
00160 {
00161 BB_MAP_Delete(dfo_map);
00162 }
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 typedef struct edge {
00184 struct edge *next_succ;
00185 BB *succ;
00186 BBLIST *slst;
00187 struct edge *next_pred;
00188 BB *pred;
00189 BBLIST *plst;
00190 double prob;
00191 double back_prob;
00192
00193
00194
00195 mUINT16 flags;
00196 } EDGE;
00197
00198
00199
00200 #define EDGE_next_succ(e) (e->next_succ)
00201 #define EDGE_succ(e) (e->succ)
00202 #define EDGE_slst(e) (e->slst)
00203 #define EDGE_next_pred(e) (e->next_pred)
00204 #define EDGE_pred(e) (e->pred)
00205 #define EDGE_plst(e) (e->plst)
00206 #define EDGE_prob(e) (e->prob)
00207 #define EDGE_back_prob(e) (e->back_prob)
00208 #define EDGE_flags(e) (e->flags)
00209
00210 #define EF_PROB_FB_BASED 0x0001
00211 #define EF_FB_PROPAGATED 0x0002
00212 #define EF_PROB_HINT_BASED 0x0004
00213
00214
00215
00216 #define EDGE_prob_fb_based(e) (EDGE_flags(e) & EF_PROB_FB_BASED)
00217 #define Set_EDGE_prob_fb_based(e) (EDGE_flags(e) |= EF_PROB_FB_BASED)
00218 #define Reset_EDGE_prob_fb_based(e) (EDGE_flags(e) &= ~EF_PROB_FB_BASED)
00219
00220
00221
00222 #define EDGE_fb_propagated(e) (EDGE_flags(e) & EF_FB_PROPAGATED)
00223 #define Set_EDGE_fb_propagated(e) (EDGE_flags(e) |= EF_FB_PROPAGATED)
00224 #define Reset_EDGE_fb_propagated(e) (EDGE_flags(e) &= ~EF_FB_PROPAGATED)
00225
00226
00227
00228 #define EDGE_prob_hint_based(e) (EDGE_flags(e) & EF_PROB_HINT_BASED)
00229 #define Set_EDGE_prob_hint_based(e) (EDGE_flags(e) |= EF_PROB_HINT_BASED)
00230 #define Reset_EDGE_prob_hint_based(e) (EDGE_flags(e) &= ~EF_PROB_HINT_BASED)
00231
00232
00233
00234
00235
00236 static EDGE **succ_edges;
00237 static EDGE **pred_edges;
00238
00239
00240
00241 static BOOL using_EDGEs;
00242
00243
00244
00245 #define BB_succ_edges(bb) (succ_edges[BB_id(bb)])
00246 #define BB_pred_edges(bb) (pred_edges[BB_id(bb)])
00247
00248
00249
00250
00251 #define FOR_ALL_SUCC_EDGES(b, e) \
00252 for ((e) = BB_succ_edges(b); (e) != NULL; (e) = EDGE_next_succ(e))
00253 #define FOR_ALL_PRED_EDGES(b, e) \
00254 for ((e) = BB_pred_edges(b); (e) != NULL; (e) = EDGE_next_pred(e))
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266 inline BOOL Is_Loop_Back_Edge(EDGE *e)
00267 {
00268 return EDGE_succ(e) == BB_loop_head_bb(EDGE_pred(e));
00269 }
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281 static EDGE *
00282 BB_Find_Succ_Edge(BB *bb, BB *succ)
00283 {
00284 EDGE *e;
00285 FOR_ALL_SUCC_EDGES(bb, e) if (EDGE_succ(e) == succ) break;
00286 return e;
00287 }
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 static void
00299 Initialize_Freq_Edges(void)
00300 {
00301 BB *bb;
00302
00303
00304
00305 succ_edges = TYPE_MEM_POOL_ALLOC_N(EDGE *,
00306 &MEM_local_pool,
00307 PU_BB_Count + 2);
00308 pred_edges = TYPE_MEM_POOL_ALLOC_N(EDGE *,
00309 &MEM_local_pool,
00310 PU_BB_Count + 2);
00311
00312
00313
00314
00315 for (bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
00316 BBLIST *slst;
00317 BBLIST *plst;
00318
00319
00320
00321
00322 FOR_ALL_BB_SUCCS(bb, slst) {
00323 EDGE *edge = TYPE_MEM_POOL_ALLOC(EDGE, &MEM_local_nz_pool);
00324 BB *succ = BBLIST_item(slst);
00325
00326
00327
00328
00329 EDGE_prob(edge) = 0.0;
00330
00331 EDGE_flags(edge) = 0;
00332 EDGE_next_succ(edge) = BB_succ_edges(bb);
00333 EDGE_slst(edge) = slst;
00334 EDGE_succ(edge) = succ;
00335 BB_succ_edges(bb) = edge;
00336
00337 if (BBLIST_prob(slst) != 0.0
00338 && BBLIST_prob_hint_based(slst)
00339 ) {
00340 EDGE_prob(edge) = BBLIST_prob(slst);
00341 Set_EDGE_prob_hint_based(edge);
00342 }
00343
00344 FOR_ALL_BB_PREDS(succ, plst) {
00345 if (BBLIST_item(plst) == bb) break;
00346 }
00347 FmtAssert(plst,
00348 ("couldn't find matching pred for succ: BB:%d -> BB:%d",
00349 BB_id(bb), BB_id(succ)));
00350
00351 EDGE_next_pred(edge) = BB_pred_edges(succ);
00352 EDGE_plst(edge) = plst;
00353 EDGE_pred(edge) = bb;
00354 BB_pred_edges(succ) = edge;
00355 }
00356 }
00357
00358 using_EDGEs = TRUE;
00359 }
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371 static void
00372 Finalize_Freq_Edges(void)
00373 {
00374 BB *bb;
00375 static const union { INT32 i; float f; } NaN_u = { 0x7fbfffff };
00376 const float NaN = NaN_u.f;
00377
00378 for (bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
00379 EDGE *edge;
00380
00381 FOR_ALL_SUCC_EDGES(bb, edge) {
00382 BBLIST *slst = EDGE_slst(edge);
00383 BBLIST_prob(slst) = EDGE_prob(edge);
00384 if (EDGE_prob_fb_based(edge)) {
00385 Set_BBLIST_prob_fb_based(slst);
00386 } else {
00387 Reset_BBLIST_prob_fb_based(slst);
00388 }
00389
00390
00391
00392
00393 BBLIST_prob(EDGE_plst(edge)) = NaN;
00394 }
00395 }
00396
00397 using_EDGEs = FALSE;
00398
00399 if (CG_warn_bad_freqs) {
00400 FREQ_Check_Consistency("Compute_BB_Frequencies");
00401 }
00402 }
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431 static void
00432 Trace_Frequencies(void)
00433 {
00434 BB *bb;
00435 enum {EDGES_PER_LINE = 3};
00436
00437 for (bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
00438 INT n;
00439 const char *s;
00440 EDGE *edge;
00441
00442
00443
00444 n = EDGES_PER_LINE;
00445 FOR_ALL_PRED_EDGES(bb, edge) {
00446 BB *pred = EDGE_pred(edge);
00447 s = ", ";
00448 if (n == EDGES_PER_LINE) {
00449 n = 0;
00450 s = "\np\t";
00451 }
00452 n++;
00453 fprintf(TFile, "%sBB:%d %#.2f(%#.2f)",
00454 s, BB_id(pred), BB_freq(pred) * EDGE_prob(edge), EDGE_prob(edge));
00455 }
00456
00457
00458
00459 fprintf(TFile, "\nBB:%d freq = %#.2f%s",
00460 BB_id(bb),
00461 BB_freq(bb),
00462 BB_freq_fb_based(bb) ? " (fb based)" : "");
00463
00464
00465
00466 n = EDGES_PER_LINE;
00467 FOR_ALL_SUCC_EDGES(bb, edge) {
00468 BB *succ = EDGE_succ(edge);
00469 s = ", ";
00470 if (n == EDGES_PER_LINE) {
00471 n = 0;
00472 s = "\ns\t";
00473 }
00474 n++;
00475 fprintf(TFile, "%sBB:%d %#.2f(%#.2f)",
00476 s, BB_id(succ), BB_freq(succ) * EDGE_prob(edge), EDGE_prob(edge));
00477 }
00478
00479 fprintf(TFile, "\n");
00480 }
00481 }
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495 #define PROB_LBH 0.88
00496 #define PROB_LEH 0.80
00497 #define PROB_LHH 0.75
00498 #define PROB_CH 0.78
00499 #define PROB_RH 0.72
00500 #define PROB_OH 0.84
00501 #define PROB_PH 0.60
00502 #define PROB_SH 0.55
00503 #ifdef KEY // bug 8546
00504 #define PROB_SBH 0.04
00505 #endif
00506
00507
00508
00509
00510
00511
00512 typedef BOOL (*heuristic_func)(
00513 BB *bb,
00514 BB *s1,
00515 BB *s2,
00516 LOOP_DESCR *loops,
00517 double *s1_taken_prob);
00518
00519
00520
00521 static BOOL Call_Heuristic(BB *, BB *, BB *, LOOP_DESCR *, double *);
00522 static BOOL Return_Heuristic(BB *, BB *, BB *, LOOP_DESCR *, double *);
00523 static BOOL Loop_Header_Heuristic(BB *, BB *, BB *, LOOP_DESCR *, double *);
00524 static BOOL Loop_Exit_Heuristic(BB *, BB *, BB *, LOOP_DESCR *, double *);
00525 static BOOL Opcode_Heuristic(BB *, BB *, BB *, LOOP_DESCR *, double *);
00526 static BOOL Pointer_Heuristic(BB *, BB *, BB *, LOOP_DESCR *, double *);
00527 static BOOL Store_Heuristic(BB *, BB *, BB *, LOOP_DESCR *, double *);
00528 #ifdef KEY
00529 static BOOL Sequential_Branch_Heuristic(BB *, BB *, BB *, LOOP_DESCR *, double *);
00530 #endif
00531
00532
00533
00534 struct heuristic_info {
00535 heuristic_func f;
00536 char name[4];
00537 };
00538
00539 static const struct heuristic_info heuristic[] = {
00540 { Call_Heuristic, "CH" },
00541 { Return_Heuristic, "RH" },
00542 { Loop_Header_Heuristic, "LHH" },
00543 { Loop_Exit_Heuristic, "LEH" },
00544 { Opcode_Heuristic, "OH" },
00545 { Pointer_Heuristic, "PH" },
00546 { Store_Heuristic, "SH" },
00547 #ifdef KEY
00548 { Sequential_Branch_Heuristic, "SBH" },
00549 #endif
00550 };
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561 static BOOL BB_Has_Store(BB *bb)
00562 {
00563 OP *op;
00564
00565 FOR_ALL_BB_OPs(bb, op) if (OP_store(op)) return TRUE;
00566 return FALSE;
00567 }
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580 static BOOL
00581 Is_Store_BB(BB *branchbb, BB *succ)
00582 {
00583 BBLIST *blst;
00584
00585 if (BS_MemberP(BB_pdom_set(branchbb), BB_id(succ))) return FALSE;
00586
00587
00588
00589 if (BB_Has_Store(succ)) return TRUE;
00590
00591
00592
00593 blst = BB_succs(succ);
00594 if (!BBlist_Has_One_Element(blst)) return FALSE;
00595 if (!BS_MemberP(BB_dom_set(BBLIST_item(blst)), BB_id(succ))) return FALSE;
00596 return BB_Has_Store(BBLIST_item(blst));
00597 }
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609 static BOOL
00610 Store_Heuristic(
00611 BB *bb,
00612 BB *s1,
00613 BB *s2,
00614 LOOP_DESCR * ,
00615 double *s1_taken_prob)
00616 {
00617 BOOL s1_has_store = Is_Store_BB(bb, s1);
00618 BOOL s2_has_store = Is_Store_BB(bb, s2);
00619
00620 if (s1_has_store == s2_has_store) {
00621 return FALSE;
00622 } else if (s1_has_store) {
00623 *s1_taken_prob = 1.0 - PROB_SH;
00624 return TRUE;
00625 } else {
00626 *s1_taken_prob = PROB_SH;
00627 return TRUE;
00628 }
00629 }
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641 BOOL WN_Is_Pointer(WN *wn)
00642 {
00643 switch (WN_operator(wn)) {
00644 case OPR_LDA:
00645 case OPR_ARRAY:
00646
00647
00648
00649 return TRUE;
00650
00651 case OPR_LDID:
00652 #if 0
00653 if (WN_class(wn) == CLASS_PREG) {
00654
00655
00656
00657 }
00658 #endif
00659
00660
00661 case OPR_ILOAD:
00662 case OPR_ILOADX:
00663 {
00664 TY_IDX ty = WN_ty(wn);
00665 if (TY_kind(ty) == KIND_POINTER) return TRUE;
00666 }
00667 break;
00668 }
00669
00670 return FALSE;
00671 }
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682 static BOOL Is_Pointer(TN *tn, OP *use_op)
00683 {
00684 OP *op;
00685 TN *use_tn = tn;
00686
00687
00688
00689
00690 for (;;) {
00691 OP *def_op;
00692 DEF_KIND kind;
00693
00694 if (TN_is_register(use_tn) && TN_is_zero_reg(use_tn)) {
00695
00696
00697
00698 return FALSE;
00699 } else if (TN_is_constant(use_tn)) {
00700
00701
00702
00703 if (TN_has_value(use_tn)) return FALSE;
00704 } else if (TN_is_rematerializable(use_tn)) {
00705
00706
00707
00708
00709 WN *home = TN_home(use_tn);
00710 OPERATOR opr = WN_operator(home);
00711 return opr == OPR_LDA;
00712 } else if (use_op && (def_op = TN_Reaching_Value_At_Op(use_tn, use_op, &kind, TRUE))) {
00713 if ( (OP_iadd(def_op) || OP_ior(def_op))
00714 && TN_is_zero_reg(OP_opnd(def_op,0))
00715 && TN_has_value(OP_opnd(def_op,1))
00716 ) {
00717
00718
00719
00720 return FALSE;
00721 } else if (OP_copy(def_op)) {
00722
00723
00724
00725 use_tn = OP_opnd(def_op, OP_COPY_OPND);
00726 use_op = def_op;
00727 continue;
00728 }
00729 }
00730 break;
00731 }
00732
00733
00734
00735
00736
00737 FOR_ALL_BB_OPs(OP_bb(use_op), op) {
00738 if (OP_load(op) && OP_opnd(op,0) == tn) return TRUE;
00739 if (OP_store(op) && OP_opnd(op,1) == tn) return TRUE;
00740 }
00741
00742 return FALSE;
00743 }
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756 static BOOL
00757 Pointer_Heuristic(
00758 BB *bb,
00759 BB *s1,
00760 BB * ,
00761 LOOP_DESCR * ,
00762 double *s1_taken_prob)
00763 {
00764 OPCODE br_opc;
00765 OPERATOR cond_oper;
00766 WN *cond_wn;
00767 TN *tn1;
00768 TN *tn2;
00769 OP *cmp;
00770 VARIANT variant;
00771 BOOL invert = s1 == BB_next(bb);
00772 OP *br_op = BB_branch_op(bb);
00773 WN *br_wn = BB_branch_wn(bb);
00774
00775
00776
00777 if (br_op == NULL || !OP_cond(br_op) || br_wn == NULL) return FALSE;
00778
00779
00780
00781 br_opc = WN_opcode(br_wn);
00782 if (br_opc != OPC_FALSEBR && br_opc != OPC_TRUEBR) return FALSE;
00783
00784 cond_wn = WN_kid0(br_wn);
00785
00786 #if defined(TARG_SL)
00787 if (cond_wn == 0) return FALSE;
00788 #endif
00789
00790 cond_oper = WN_operator(cond_wn);
00791 if (cond_oper != OPR_NE && cond_oper != OPR_EQ) return FALSE;
00792
00793
00794
00795
00796 variant = CGTARG_Analyze_Compare(br_op, &tn1, &tn2, &cmp);
00797 switch (variant) {
00798 case V_BR_I4EQ:
00799 case V_BR_U4EQ:
00800 case V_BR_I8EQ:
00801 case V_BR_U8EQ:
00802 invert = !invert;
00803 break;
00804
00805 case V_BR_I4NE:
00806 case V_BR_U4NE:
00807 case V_BR_I8NE:
00808 case V_BR_U8NE:
00809 break;
00810
00811 default:
00812 return FALSE;
00813 }
00814
00815
00816
00817 if ( !Is_Pointer(tn1, br_op)
00818 && !Is_Pointer(tn2, br_op)
00819 && !WN_Is_Pointer(WN_kid0(cond_wn))
00820 && !WN_Is_Pointer(WN_kid1(cond_wn))
00821 ) return FALSE;
00822
00823
00824
00825 *s1_taken_prob = invert ? 1.0 - PROB_PH : PROB_PH;
00826 return TRUE;
00827 }
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840 static BOOL
00841 Opcode_Heuristic(
00842 BB *bb,
00843 BB *s1,
00844 BB * ,
00845 LOOP_DESCR * ,
00846 double *s1_taken_prob)
00847 {
00848 VARIANT variant;
00849 OP *cmp;
00850 TN *tn1, *tn2;
00851 INT64 val;
00852 BOOL isconst;
00853 BOOL invert = s1 == BB_next(bb);
00854 OP *br_op = BB_branch_op(bb);
00855
00856
00857
00858 if (br_op == NULL || !OP_cond(br_op)) return FALSE;
00859
00860
00861
00862 variant = CGTARG_Analyze_Compare(br_op, &tn1, &tn2, &cmp);
00863
00864
00865
00866
00867 if ( tn2 == NULL
00868 || Is_Pointer(tn1, br_op)
00869 || Is_Pointer(tn2, br_op)) return FALSE;
00870 isconst = TN_Value_At_Op(tn2, br_op, &val);
00871 if (!isconst) {
00872 isconst = TN_Value_At_Op(tn1, br_op, &val);
00873 if (!isconst) return FALSE;
00874 variant = Invert_BR_Variant(variant);
00875 }
00876
00877
00878
00879
00880
00881
00882
00883 WN *br_wn = BB_branch_wn(bb);
00884 if (br_wn) {
00885 WN *cond_wn = WN_kid0(br_wn);
00886 #if defined(TARG_SL)
00887 if (!cond_wn) return FALSE;
00888 #endif
00889 OPERATOR cond_oper = WN_operator(cond_wn);
00890 if (OPERATOR_is_compare(cond_oper)) {
00891 if (WN_Is_Pointer(WN_kid0(cond_wn)) || WN_Is_Pointer(WN_kid1(cond_wn))) {
00892 return FALSE;
00893 }
00894 }
00895 }
00896
00897
00898
00899
00900
00901 switch (variant) {
00902 case V_BR_I4LE:
00903 case V_BR_U4LE:
00904 if ((INT32)val != 0) return FALSE;
00905 invert = !invert;
00906 break;
00907 case V_BR_I8LE:
00908 case V_BR_U8LE:
00909 if (val != 0) return FALSE;
00910 invert = !invert;
00911 break;
00912 case V_BR_I4LT:
00913 case V_BR_U4LT:
00914 if ((UINT32)val > 1) return FALSE;
00915 invert = !invert;
00916 break;
00917 case V_BR_I8LT:
00918 case V_BR_U8LT:
00919 if ((UINT64)val > 1) return FALSE;
00920 invert = !invert;
00921 break;
00922 case V_BR_I4GT:
00923 case V_BR_U4GT:
00924 if ((INT32)val != 0) return FALSE;
00925 break;
00926 case V_BR_I8GT:
00927 case V_BR_U8GT:
00928 if (val != 0) return FALSE;
00929 break;
00930 case V_BR_I4GE:
00931 case V_BR_U4GE:
00932 if ((UINT32)val > 1) return FALSE;
00933 break;
00934 case V_BR_I8GE:
00935 case V_BR_U8GE:
00936 if ((UINT64)val > 1) return FALSE;
00937 break;
00938 case V_BR_I4EQ:
00939 case V_BR_U4EQ:
00940 case V_BR_I8EQ:
00941 case V_BR_U8EQ:
00942 invert = !invert;
00943 break;
00944 case V_BR_I4NE:
00945 case V_BR_U4NE:
00946 case V_BR_I8NE:
00947 case V_BR_U8NE:
00948 break;
00949 default:
00950 #pragma mips_frequency_hint NEVER
00951 DevWarn("Opcode_Heuristic: unexpected branch variant %s",
00952 BR_Variant_Name(variant));
00953 return FALSE;
00954 }
00955
00956
00957
00958
00959 *s1_taken_prob = invert ? 1.0 - PROB_OH : PROB_OH;
00960 return TRUE;
00961 }
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976 static BOOL
00977 LOOPINFO_Trip_Count(LOOPINFO* linfo, INT* tc)
00978 {
00979 TN* trip_tn;
00980 WN* wn;
00981
00982 if (!linfo) {
00983 return FALSE;
00984 } else if ( (trip_tn = LOOPINFO_trip_count_tn(linfo))
00985 && TN_is_constant(trip_tn)
00986 ) {
00987 *tc = TN_value(trip_tn);
00988 return TRUE;
00989 } else if ( (wn = LOOPINFO_wn(linfo))
00990 && WN_loop_trip_est(wn) > 0
00991 ) {
00992 *tc = WN_loop_trip_est(wn);
00993 return TRUE;
00994 } else
00995 return FALSE;
00996 }
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008 static BOOL
01009 Loop_Exit_Heuristic(
01010 BB *bb,
01011 BB *s1,
01012 BB *s2,
01013 LOOP_DESCR *loops,
01014 double *s1_taken_prob)
01015 {
01016 for (; loops; loops = LOOP_DESCR_next(loops)) {
01017 BB_SET *loop_bbs = LOOP_DESCR_bbset(loops);
01018
01019 if (BB_SET_MemberP(loop_bbs, bb)) {
01020 BOOL s1_in_loop = BB_SET_MemberP(loop_bbs, s1);
01021 BOOL s2_in_loop = BB_SET_MemberP(loop_bbs, s2);
01022
01023 if (s1_in_loop == s2_in_loop) {
01024 continue;
01025 } else {
01026 double loop_prob = PROB_LEH;
01027 LOOPINFO *linfo = LOOP_DESCR_loopinfo(loops);
01028 INT tc;
01029 if (LOOPINFO_Trip_Count(linfo,&tc)) {
01030 double trip_count_est = tc;
01031 loop_prob = (trip_count_est - 1) / trip_count_est;
01032 }
01033
01034 *s1_taken_prob = s1_in_loop ? loop_prob : 1.0 - loop_prob;
01035
01036 return TRUE;
01037 }
01038 }
01039 }
01040
01041 return FALSE;
01042 }
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055 static BOOL
01056 Is_Loophead_BB(BB *branchbb, BB *succ)
01057 {
01058 BBLIST *blst;
01059
01060 if (BS_MemberP(BB_pdom_set(branchbb), BB_id(succ))) return FALSE;
01061
01062
01063 if (BB_loophead(succ)) return TRUE;
01064
01065
01066 blst = BB_succs(succ);
01067 if (!BBlist_Has_One_Element(blst)) return FALSE;
01068 if (!BS_MemberP(BB_dom_set(BBLIST_item(blst)), BB_id(succ))) return FALSE;
01069 return BB_loophead(BBLIST_item(blst));
01070 }
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082 static BOOL
01083 Loop_Header_Heuristic(
01084 BB *bb,
01085 BB *s1,
01086 BB *s2,
01087 LOOP_DESCR * ,
01088 double *s1_taken_prob)
01089 {
01090 BOOL s1_is_loophead = Is_Loophead_BB(bb, s1);
01091 BOOL s2_is_loophead = Is_Loophead_BB(bb, s2);
01092
01093 if (s1_is_loophead == s2_is_loophead) {
01094 return FALSE;
01095 } else if (s1_is_loophead) {
01096 *s1_taken_prob = PROB_LHH;
01097 return TRUE;
01098 } else {
01099 *s1_taken_prob = 1.0 - PROB_LHH;
01100 return TRUE;
01101 }
01102 }
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115 static BOOL
01116 Is_Call_BB(BB *branchbb, BB *succ)
01117 {
01118 BBLIST *blst;
01119
01120 if (BS_MemberP(BB_pdom_set(branchbb), BB_id(succ))) return FALSE;
01121
01122
01123
01124 if (BB_call(succ)) return TRUE;
01125
01126
01127
01128 blst = BB_succs(succ);
01129 if (!BBlist_Has_One_Element(blst)) return FALSE;
01130 if (!BS_MemberP(BB_dom_set(BBLIST_item(blst)), BB_id(succ))) return FALSE;
01131 return BB_call(BBLIST_item(blst));
01132 }
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144 static BOOL
01145 Call_Heuristic(
01146 BB *bb,
01147 BB *s1,
01148 BB *s2,
01149 LOOP_DESCR * ,
01150 double *s1_taken_prob)
01151 {
01152 BOOL s1_is_call = Is_Call_BB(bb, s1);
01153 BOOL s2_is_call = Is_Call_BB(bb, s2);
01154
01155 if (s1_is_call == s2_is_call) {
01156 return FALSE;
01157 } else if (s1_is_call) {
01158 *s1_taken_prob = 1.0 - PROB_CH;
01159 return TRUE;
01160 } else {
01161 *s1_taken_prob = PROB_CH;
01162 return TRUE;
01163 }
01164 }
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176 static BOOL
01177 Is_Return_BB(BB *bb)
01178 {
01179 BBLIST *succ;
01180
01181
01182
01183
01184 for (; (succ = BB_succs(bb)) && BB_call(bb); bb = BBLIST_item(succ))
01185 ;
01186
01187
01188
01189 if (succ == NULL) return TRUE;
01190
01191
01192
01193 while (BB_call(BBLIST_item(succ)) && BB_succs(BBLIST_item(succ))) {
01194 succ = BB_succs(BBLIST_item(succ));
01195 }
01196 return BBLIST_next(succ) == NULL && BB_succs(BBLIST_item(succ)) == NULL;
01197 }
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208 static BOOL
01209 Return_Heuristic(
01210 BB * ,
01211 BB *s1,
01212 BB *s2,
01213 LOOP_DESCR * ,
01214 double *s1_taken_prob)
01215 {
01216 BOOL s1_is_return = Is_Return_BB(s1);
01217 BOOL s2_is_return = Is_Return_BB(s2);
01218
01219 if (s1_is_return == s2_is_return) {
01220 return FALSE;
01221 } else if (s1_is_return) {
01222 *s1_taken_prob = 1.0 - PROB_RH;
01223 return TRUE;
01224 } else {
01225
01226 *s1_taken_prob = PROB_RH;
01227 return TRUE;
01228 }
01229 }
01230
01231 #ifdef KEY
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242 static BOOL
01243 Is_Branch_With_Goto_Succ (BB *bb, BB **goto_succ, BB **non_goto_succ,
01244 BB **goto_target)
01245 {
01246 EDGE *edge;
01247 int n_succs = 0;
01248 BB *goto_bb, *non_goto_bb, *goto_target_bb;
01249
01250 if (BB_kind(bb) != BBKIND_LOGIF)
01251 return FALSE;
01252
01253
01254 FOR_ALL_SUCC_EDGES(bb, edge) {
01255 n_succs++;
01256 }
01257 if (n_succs != 2)
01258 return FALSE;
01259
01260
01261 EDGE *edge1 = BB_succ_edges(bb);
01262 EDGE *edge2 = EDGE_next_succ(edge1);
01263 BB *succ1 = EDGE_succ(edge1);
01264 BB *succ2 = EDGE_succ(edge2);
01265
01266
01267 if (BB_kind(succ1) == BBKIND_GOTO) {
01268 *goto_succ = succ1;
01269 *non_goto_succ = succ2;
01270 *goto_target = BBLIST_item(BB_succs(succ1));
01271 } else if (BB_kind(succ2) == BBKIND_GOTO) {
01272 *goto_succ = succ2;
01273 *non_goto_succ = succ1;
01274 *goto_target = BBLIST_item(BB_succs(succ2));
01275 } else
01276 return FALSE;
01277
01278 return TRUE;
01279 }
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295 static BOOL
01296 Sequential_Branch_Heuristic(
01297 BB *bb,
01298 BB *s1,
01299 BB *s2,
01300 LOOP_DESCR * ,
01301 double *s1_taken_prob)
01302 {
01303 BB *goto_succ1, *non_goto_succ1, *goto_target1;
01304 BB *goto_succ2, *non_goto_succ2, *goto_target2;
01305 BB *goto_succ3, *non_goto_succ3, *goto_target3;
01306
01307
01308 if (!Is_Branch_With_Goto_Succ(bb, &goto_succ1, &non_goto_succ1,
01309 &goto_target1))
01310 return FALSE;
01311
01312
01313 if (Is_Branch_With_Goto_Succ(non_goto_succ1, &goto_succ2, &non_goto_succ2,
01314 &goto_target2) &&
01315 goto_target1 == goto_target2) {
01316
01317
01318 if (Is_Branch_With_Goto_Succ(non_goto_succ2, &goto_succ3, &non_goto_succ3,
01319 &goto_target3) &&
01320 goto_target1 == goto_target3) {
01321 *s1_taken_prob = (s1 == goto_succ1) ? PROB_SBH : 1 - PROB_SBH;
01322 return TRUE;
01323 }
01324 }
01325
01326
01327 BB *pred1, *pred2;
01328
01329 if (((pred1 = BB_Unique_Predecessor(bb)) == NULL) ||
01330 ((pred2 = BB_Unique_Predecessor(pred1)) == NULL))
01331 return FALSE;
01332
01333
01334 if (Is_Branch_With_Goto_Succ(pred1, &goto_succ2, &non_goto_succ2,
01335 &goto_target2) &&
01336 goto_target1 == goto_target2) {
01337
01338
01339 if (Is_Branch_With_Goto_Succ(pred2, &goto_succ3, &non_goto_succ3,
01340 &goto_target3) &&
01341 goto_target1 == goto_target3) {
01342 *s1_taken_prob = (s1 == goto_succ1) ? PROB_SBH : 1 - PROB_SBH;
01343 return TRUE;
01344 }
01345 }
01346
01347
01348 return FALSE;
01349 }
01350 #endif
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371 static BOOL
01372 Trip_Loop_Exit_Prob(
01373 BB *bb,
01374 BB *s1,
01375 BB *s2,
01376 LOOP_DESCR *loops,
01377 double *s1_taken_prob)
01378 {
01379 for (; loops; loops = LOOP_DESCR_next(loops)) {
01380 BB_SET *loop_bbs = LOOP_DESCR_bbset(loops);
01381
01382 if (BB_SET_MemberP(loop_bbs, bb)) {
01383 BOOL s1_in_loop = BB_SET_MemberP(loop_bbs, s1);
01384 BOOL s2_in_loop = BB_SET_MemberP(loop_bbs, s2);
01385
01386 if (s1_in_loop == s2_in_loop) {
01387 continue;
01388 } else {
01389 double loop_prob;
01390 double trip_count;
01391 INT tc;
01392
01393 if (!LOOPINFO_Trip_Count(LOOP_DESCR_loopinfo(loops),&tc)) return FALSE;
01394 if (tc < 1) return FALSE;
01395
01396 trip_count = (double)tc;
01397
01398 loop_prob = trip_count == 0.0 ? 0.0 : (trip_count - 1) / trip_count;
01399
01400 *s1_taken_prob = s1_in_loop ? loop_prob : 1.0 - loop_prob;
01401
01402 return TRUE;
01403 }
01404 }
01405 }
01406
01407 return FALSE;
01408 }
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421 static BOOL
01422 Compute_BR_Prob_From_Feedback(BB *bb)
01423 {
01424 EDGE *sedge;
01425 double prob_sum = 0.0;
01426 INT fb_succs = 0;
01427 INT no_fb_succs = 0;
01428
01429
01430
01431
01432
01433 FOR_ALL_SUCC_EDGES(bb, sedge) {
01434 if (EDGE_prob_fb_based(sedge)) {
01435 prob_sum += EDGE_prob(sedge);
01436 ++fb_succs;
01437 } else {
01438 ++no_fb_succs;
01439 }
01440 }
01441 Is_True(fb_succs > 0,
01442 ("Compute_BR_Prob_From_Feedback found no feedback succs for BB:%d",
01443 BB_id(bb)));
01444
01445
01446
01447
01448
01449
01450
01451
01452 if (no_fb_succs != 0) {
01453 double prob = (1.0 - prob_sum) / (double)no_fb_succs;
01454 FOR_ALL_SUCC_EDGES(bb, sedge) {
01455 if (!EDGE_prob_fb_based(sedge)) EDGE_prob(sedge) = prob;
01456 }
01457 }
01458
01459 return TRUE;
01460 }
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473 static void
01474 Find_Freq_Hint_Pragmas(
01475 BB_SET **never,
01476 BB_SET **frequent,
01477 MEM_POOL *pool)
01478 {
01479 BB *bb;
01480
01481 if (never) *never = NULL;
01482 if (frequent) *frequent = NULL;
01483 for (bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
01484 if (BB_has_pragma(bb)) {
01485 ANNOTATION *ant;
01486
01487 for ( ant = ANNOT_First(BB_annotations(bb), ANNOT_PRAGMA);
01488 ant != NULL;
01489 ant = ANNOT_Next(ant, ANNOT_PRAGMA))
01490 {
01491 BB_SET **hint_bbs;
01492 WN *wn = ANNOT_pragma(ant);
01493 WN_PRAGMA_ID pragma = (WN_PRAGMA_ID) WN_pragma(wn);
01494 INT32 arg1 = WN_pragma_arg1(wn);
01495
01496 if (pragma != WN_PRAGMA_MIPS_FREQUENCY_HINT) continue;
01497
01498 switch (arg1) {
01499 case FREQUENCY_HINT_NEVER:
01500 hint_bbs = never;
01501 break;
01502 case FREQUENCY_HINT_FREQUENT:
01503 hint_bbs = frequent;
01504 break;
01505 default:
01506 continue;
01507 }
01508 if (hint_bbs == NULL) continue;
01509
01510 if (*hint_bbs == NULL) {
01511 *hint_bbs = BB_SET_Create_Empty(PU_BB_Count + 2, pool);
01512 }
01513 BB_SET_Union1D(*hint_bbs, bb, NULL);
01514 }
01515 }
01516 }
01517 }
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560 static BOOL
01561 Compute_BR_Prob_From_Hint(BB *bb, INT n_succs)
01562 {
01563 EDGE *sedge;
01564 enum prob_src {ps_heuristic, ps_never, ps_frequent} *prob_src;
01565 INT isucc;
01566 INT n_heuristic;
01567 INT n_never = 0;
01568 INT n_frequent = 0;
01569
01570
01571
01572
01573 prob_src = (enum prob_src *)alloca(sizeof(enum prob_src) * n_succs);
01574
01575
01576
01577
01578 isucc = 0;
01579 FOR_ALL_SUCC_EDGES(bb, sedge) {
01580 BB *succ = EDGE_succ(sedge);
01581 BB_SET *succ_pdom = (BB_SET *)BB_pdom_set(succ);
01582 BOOL frequent = Frequent_BBs && BB_SET_IntersectsP(Frequent_BBs, succ_pdom);
01583 BOOL never = Never_BBs && BB_SET_IntersectsP(Never_BBs, succ_pdom);
01584
01585 prob_src[isucc] = ps_heuristic;
01586
01587 if (never != frequent) {
01588 if (frequent) {
01589 prob_src[isucc] = ps_frequent;
01590 n_frequent++;
01591 } else {
01592 prob_src[isucc] = ps_never;
01593 n_never++;
01594 }
01595 } else if (never) {
01596 DevWarn("FREQ: BB:%d -> BB%d edge as conflicting freq pragmas -- ignored",
01597 BB_id(bb), BB_id(succ));
01598 }
01599
01600 isucc++;
01601 }
01602 n_heuristic = n_succs - n_never - n_frequent;
01603
01604
01605
01606 if (n_heuristic == n_succs) return FALSE;
01607
01608
01609
01610
01611 if (n_heuristic && (n_never == 0 || n_frequent == 0)) {
01612 for (isucc = 0; isucc < n_succs; isucc++) {
01613 if (prob_src[isucc] == ps_heuristic) {
01614 prob_src[isucc] = n_never ? ps_frequent : ps_never;
01615 }
01616 }
01617
01618 if (n_never == 0) {
01619 n_never = n_heuristic;
01620 } else {
01621 n_frequent = n_heuristic;
01622 }
01623 n_heuristic = 0;
01624 }
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650 {
01651 double a = n_never;
01652 double b = n_frequent;
01653 double c = n_heuristic;
01654 double R = Frequent_Never_Ratio;
01655 double sqrt_R = sqrt(R);
01656 double denom = a + (b * R) + (c * sqrt_R);
01657 double n = 1.0 / denom;
01658 double f = R / denom;
01659 double h = sqrt_R / denom;
01660
01661 isucc = 0;
01662 FOR_ALL_SUCC_EDGES(bb, sedge) {
01663 switch (prob_src[isucc]) {
01664 case ps_heuristic:
01665 EDGE_prob(sedge) = h;
01666 break;
01667 case ps_never:
01668 EDGE_prob(sedge) = n;
01669 break;
01670 case ps_frequent:
01671 EDGE_prob(sedge) = f;
01672 break;
01673 }
01674
01675 isucc++;
01676 }
01677 }
01678
01679 return TRUE;
01680 }
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691 static void
01692 Compute_Branch_Probabilities(void)
01693 {
01694 INT i;
01695 LOOP_DESCR *loops = loop_list;
01696
01697 for (i = max_dfo_id - 1; i >= 0; i--) {
01698 BB *succ;
01699 EDGE *edge;
01700 BB *bb = dfo_vec[i];
01701 INT n_succs = 0;
01702 INT n_back_succs = 0;
01703 INT n_fb_edges = 0;
01704
01705
01706
01707
01708 FOR_ALL_SUCC_EDGES(bb, edge) {
01709 succ = EDGE_succ(edge);
01710 if (Is_Loop_Back_Edge(edge)) n_back_succs++;
01711 if (EDGE_prob_fb_based(edge)) n_fb_edges++;
01712 n_succs++;
01713 }
01714
01715 if (CFLOW_Trace_Freq) {
01716 #pragma mips_frequency_hint NEVER
01717 fprintf(TFile, "Computing successor probabilities for BB:%d:\n"
01718 " n_succs: %d, n_back_succs: %d, n_fb_edges: %d\n",
01719 BB_id(bb), n_succs, n_back_succs, n_fb_edges);
01720 }
01721
01722
01723
01724 if (n_succs == 0) {
01725
01726
01727
01728 continue;
01729 } else if (n_succs == 1) {
01730
01731
01732
01733
01734
01735
01736 #if defined (TARG_SL)
01737 if(!BB_freq_unbalanced(bb) || !CG_PU_Has_Feedback)
01738 #endif
01739 EDGE_prob(BB_succ_edges(bb)) = 1.0;
01740 } else if ( (Frequent_BBs || Never_BBs)
01741 && Compute_BR_Prob_From_Hint(bb, n_succs)
01742 ) {
01743 if (CFLOW_Trace_Freq) {
01744 #pragma mips_frequency_hint NEVER
01745
01746
01747
01748 fprintf(TFile, "\n Heuristic ");
01749 FOR_ALL_SUCC_EDGES(bb, edge) {
01750 succ = EDGE_succ(edge);
01751 fprintf(TFile, " BB:%-3d -> BB:%-3d", BB_id(bb), BB_id(succ));
01752 }
01753 fprintf(TFile, "\n %.*s\n"
01754 " hint ",
01755 10 + 17 * n_succs, DBar);
01756 FOR_ALL_SUCC_EDGES(bb, edge) {
01757 succ = EDGE_succ(edge);
01758 fprintf(TFile, " %.13f ", EDGE_prob(edge));
01759 }
01760 fprintf(TFile, "\n");
01761 }
01762 } else if (n_fb_edges > 0 && Compute_BR_Prob_From_Feedback(bb)) {
01763
01764
01765
01766 if (CFLOW_Trace_Freq) {
01767 #pragma mips_frequency_hint NEVER
01768 fprintf(TFile, "\n Heuristic ");
01769 FOR_ALL_SUCC_EDGES(bb, edge) {
01770 succ = EDGE_succ(edge);
01771 fprintf(TFile, " BB:%-3d -> BB:%-3d", BB_id(bb), BB_id(succ));
01772 }
01773 fprintf(TFile, "\n %.*s\n"
01774 " feedback ",
01775 10 + 17 * n_succs, DBar);
01776 FOR_ALL_SUCC_EDGES(bb, edge) {
01777 succ = EDGE_succ(edge);
01778 fprintf(TFile, " %.13f%c ", EDGE_prob(edge),
01779 EDGE_prob_fb_based(edge) ? 'F' : 'H');
01780 }
01781 fprintf(TFile, "\n");
01782 }
01783 } else if (n_back_succs != 0 && n_back_succs < n_succs) {
01784
01785
01786
01787
01788
01789
01790 LOOP_DESCR *loop;
01791 LOOPINFO *linfo;
01792 INT tc;
01793 double prob_taken = PROB_LBH;
01794
01795
01796
01797
01798
01799 loop = LOOP_DESCR_Find_Loop(bb);
01800 linfo = loop ? LOOP_DESCR_loopinfo(loop) : NULL;
01801 if (LOOPINFO_Trip_Count(linfo,&tc)) {
01802 double trip_count = (double)tc;
01803 if (trip_count > 0) {
01804 prob_taken = (trip_count - 1) / trip_count;
01805 } else if (trip_count == 0.0) {
01806 prob_taken = 0.0;
01807 }
01808 }
01809
01810
01811
01812 FOR_ALL_SUCC_EDGES(bb, edge) {
01813 if (Is_Loop_Back_Edge(edge)) {
01814
01815
01816
01817 EDGE_prob(edge) = prob_taken / n_back_succs;
01818 } else {
01819
01820
01821
01822 EDGE_prob(edge) = (1.0 - prob_taken) / (n_succs - n_back_succs);
01823 }
01824 }
01825
01826 if (CFLOW_Trace_Freq) {
01827 #pragma mips_frequency_hint NEVER
01828 fprintf(TFile, "\n Heuristic ");
01829 FOR_ALL_SUCC_EDGES(bb, edge) {
01830 succ = EDGE_succ(edge);
01831 fprintf(TFile, " BB:%-3d -> BB:%-3d", BB_id(bb), BB_id(succ));
01832 }
01833 fprintf(TFile, "\n %.*s\n"
01834 " LBH ",
01835 10 + 17 * n_succs, DBar);
01836 FOR_ALL_SUCC_EDGES(bb, edge) {
01837 succ = EDGE_succ(edge);
01838 fprintf(TFile, " %.13f ", EDGE_prob(edge));
01839 }
01840 fprintf(TFile, "\n");
01841 }
01842 } else if (n_back_succs != 0 || n_succs != 2) {
01843
01844
01845
01846 FOR_ALL_SUCC_EDGES(bb, edge) {
01847 EDGE_prob(edge) = 1.0 / n_succs;
01848 }
01849 }
01850 else if (EDGE_prob_hint_based(BB_succ_edges(bb)) &&
01851 EDGE_prob_hint_based(EDGE_next_succ(BB_succ_edges(bb)))) {
01852 if (CFLOW_Trace_Freq) {
01853 #pragma mips_frequency_hint NEVER
01854 EDGE *edge1 = BB_succ_edges(bb);
01855 EDGE *edge2 = EDGE_next_succ(edge1);
01856 BB *succ1 = EDGE_succ(edge1);
01857 BB *succ2 = EDGE_succ(edge2);
01858
01859 fprintf(TFile, "\n User builtin BB:%-3d -> BB:%-3d BB:%-3d -> BB:%-3d\n"
01860 " ============================================\n",
01861 BB_id(bb), BB_id(succ1), BB_id(bb), BB_id(succ2));
01862 fprintf(TFile, " Combined %.13f %.13f\n",
01863 EDGE_prob(edge1), EDGE_prob(edge2));
01864 }
01865 }
01866 else {
01867
01868
01869
01870 INT i;
01871 double prob_succ1;
01872 double prob_succ2;
01873 EDGE *edge1 = BB_succ_edges(bb);
01874 EDGE *edge2 = EDGE_next_succ(edge1);
01875 BB *succ1 = EDGE_succ(edge1);
01876 BB *succ2 = EDGE_succ(edge2);
01877
01878 if (CFLOW_Trace_Freq) {
01879 #pragma mips_frequency_hint NEVER
01880 fprintf(TFile, "\n Heuristic BB:%-3d -> BB:%-3d BB:%-3d -> BB:%-3d\n"
01881 " ============================================\n",
01882 BB_id(bb), BB_id(succ1), BB_id(bb), BB_id(succ2));
01883 }
01884
01885 if (Trip_Loop_Exit_Prob(bb, succ1, succ2, loops, &prob_succ1)) {
01886 prob_succ2 = 1.0 - prob_succ1;
01887 } else {
01888 #ifdef TARG_IA64
01889 if (IPFEC_Enable_Random_Prob) {
01890 double freq_succ1 = (double)(random() + 1);
01891 double freq_succ2 = (double)(random() + 1);
01892 prob_succ1 = freq_succ1 / (freq_succ1 + freq_succ2);
01893 prob_succ2 = freq_succ2 / (freq_succ1 + freq_succ2);
01894 }
01895 else {
01896 prob_succ1 = 0.5;
01897 prob_succ2 = 0.5;
01898 }
01899 #else
01900 prob_succ1 = 0.5;
01901 prob_succ2 = 0.5;
01902
01903 #endif
01904
01905
01906
01907
01908 for (i = 0; i < sizeof(heuristic) / sizeof(*heuristic); i++) {
01909 double prob_s1_taken;
01910
01911 if ((heuristic[i].f)(bb, succ1, succ2, loops, &prob_s1_taken)) {
01912 double d = prob_succ1 * prob_s1_taken
01913 + prob_succ2 * (1.0 - prob_s1_taken);
01914 prob_succ1 = (prob_succ1 * prob_s1_taken) / d;
01915 prob_succ2 = (prob_succ2 * (1.0 - prob_s1_taken)) / d;
01916
01917 if (CFLOW_Trace_Freq) {
01918 #pragma mips_frequency_hint NEVER
01919 fprintf(TFile, " %3s %.13f %.13f\n",
01920 heuristic[i].name,
01921 prob_s1_taken, 1.0 - prob_s1_taken);
01922 }
01923 }
01924 }
01925 }
01926
01927 if (CFLOW_Trace_Freq) {
01928 #pragma mips_frequency_hint NEVER
01929 fprintf(TFile, " Combined %.13f %.13f\n",
01930 prob_succ1, prob_succ2);
01931 }
01932 EDGE_prob(edge1) = prob_succ1;
01933 EDGE_prob(edge2) = prob_succ2;
01934 }
01935 }
01936 }
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956 static void
01957 Propagate_Freq(
01958 BB *bb,
01959 BB *head,
01960 double head_freq,
01961 BB_SET *to_visit,
01962 BB_SET *visited)
01963 {
01964 EDGE *edge;
01965
01966 if (!BB_SET_MemberP(to_visit, bb)) return;
01967
01968 if (CFLOW_Trace_Freq) {
01969 #pragma mips_frequency_hint NEVER
01970 fprintf(TFile, " Propagate_Freq(%d, %d, %g, ",
01971 BB_id(bb), BB_id(head), head_freq);
01972 BB_SET_Print(to_visit, TFile);
01973 fprintf(TFile, ", ");
01974 BB_SET_Print(visited, TFile);
01975 fprintf(TFile, ")\n");
01976 }
01977
01978
01979
01980 if (bb == head) {
01981 if (!BB_freq_fb_based(bb)) BB_freq(bb) = head_freq;
01982 } else {
01983 double cyclic_prob;
01984 double in_freq;
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994 FOR_ALL_PRED_EDGES(bb, edge) {
01995 BB *pred = EDGE_pred(edge);
01996 if (!BB_SET_MemberP(visited, pred) && !Is_Loop_Back_Edge(edge)) {
01997
01998
01999
02000
02001 #if Is_True_On
02002 if (CFLOW_Trace_Freq) {
02003 #pragma mips_frequency_hint NEVER
02004 fprintf(TFile, " Non-loopback predecessor BB:%d of BB:%d not "
02005 "visited; returning\n",
02006 BB_id(pred), BB_id(bb));
02007 }
02008 #endif
02009 return;
02010 }
02011 #if Is_True_On
02012 else if (CFLOW_Trace_Freq) {
02013 #pragma mips_frequency_hint NEVER
02014 if (BB_SET_MemberP(visited, pred)) {
02015 fprintf(TFile, " Predecessor BB:%d of BB:%d visited; "
02016 "continuing\n", BB_id(pred), BB_id(bb));
02017 } else {
02018 fprintf(TFile, " Unvisited predecessor BB:%d of BB:%d is "
02019 "loopback; continuing\n", BB_id(pred), BB_id(bb));
02020 }
02021 }
02022 #endif
02023 }
02024
02025
02026
02027
02028
02029
02030
02031
02032 in_freq = 0.0;
02033 cyclic_prob = 0.0;
02034
02035 FOR_ALL_PRED_EDGES(bb, edge) {
02036 if (Is_Loop_Back_Edge(edge)) {
02037 cyclic_prob += EDGE_back_prob(edge);
02038 } else {
02039 BB *pred = EDGE_pred(edge);
02040 in_freq += BB_freq(pred) * EDGE_prob(edge);
02041 }
02042 }
02043
02044
02045
02046
02047
02048
02049 if (cyclic_prob != 0.0) {
02050 if (cyclic_prob < 1.0) {
02051 double one_minus_cp = 1.0 - cyclic_prob;
02052 const double big_float = 1e38;
02053 double min_prob = in_freq / big_float;
02054
02055
02056
02057
02058
02059
02060
02061
02062
02063
02064
02065
02066
02067 if (one_minus_cp <= min_prob) {
02068 one_minus_cp = min_prob;
02069 }
02070 if (!BB_freq_fb_based(bb)) BB_freq(bb) = in_freq / one_minus_cp;
02071 } else {
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081 if (!BB_freq_fb_based(bb)) BB_freq(bb) = in_freq / (1.0 - PROB_LBH);
02082 }
02083 } else {
02084 if (!BB_freq_fb_based(bb)) BB_freq(bb) = in_freq;
02085 }
02086
02087 if (CFLOW_Trace_Freq) {
02088 #pragma mips_frequency_hint NEVER
02089 fprintf(TFile, " Setting frequency for BB:%d to %g\n",
02090 BB_id(bb), BB_freq(bb));
02091 }
02092 }
02093
02094
02095
02096 BB_SET_Union1D(visited, bb, NULL);
02097 BB_SET_Difference1D(to_visit, bb);
02098
02099 FOR_ALL_SUCC_EDGES(bb, edge) {
02100 BB *succ = EDGE_succ(edge);
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111 if (succ == head) {
02112 EDGE_back_prob(edge) = EDGE_prob(edge) * BB_freq(bb);
02113 if (CFLOW_Trace_Freq) {
02114 #pragma mips_frequency_hint NEVER
02115 fprintf(TFile, " Back probability set to %g for BB:%d -> BB:%d\n",
02116 EDGE_back_prob(edge), BB_id(bb), BB_id(succ));
02117 }
02118 }
02119 }
02120
02121
02122
02123 FOR_ALL_SUCC_EDGES(bb, edge) {
02124 if (!Is_Loop_Back_Edge(edge)) {
02125 BB *succ = EDGE_succ(edge);
02126 Propagate_Freq(succ, head, 1.0, to_visit, visited);
02127 }
02128 }
02129 }
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140 static void
02141 Set_Reachable(BB *bb, BB_SET *reachable)
02142 {
02143 BBLIST *blst;
02144
02145 BB_SET_Union1D(reachable, bb, NULL);
02146
02147 FOR_ALL_BB_SUCCS(bb, blst) {
02148 BB *succ = BBLIST_item(blst);
02149 if (!BB_SET_MemberP(reachable, succ)) Set_Reachable(succ, reachable);
02150 }
02151 }
02152
02153
02154
02155
02156
02157
02158
02159
02160
02161
02162 static void
02163 Compute_Frequencies(void)
02164 {
02165 BB *bb;
02166 LOOP_DESCR *loops = loop_list;
02167 INT loop_num = 0;
02168 BB_SET *visited = BB_SET_Create(PU_BB_Count + 2, &MEM_local_pool);
02169 BB_SET *to_visit = BB_SET_Create(PU_BB_Count + 2, &MEM_local_nz_pool);
02170
02171
02172
02173 for (bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
02174 EDGE *edge;
02175
02176 FOR_ALL_SUCC_EDGES(bb, edge) {
02177 EDGE_back_prob(edge) = EDGE_prob(edge);
02178 }
02179 }
02180
02181
02182
02183 while (loops) {
02184 BB *head = LOOP_DESCR_loophead(loops);
02185 BB_SET *loop_bbs = LOOP_DESCR_bbset(loops);
02186
02187 if (CFLOW_Trace_Freq) {
02188 #pragma mips_frequency_hint NEVER
02189 ++loop_num;
02190 fprintf(TFile, "LOOP %d:\n", loop_num);
02191 }
02192
02193
02194
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204 BB_SET_CopyD(to_visit, loop_bbs, NULL);
02205 BB_SET_ClearD(visited);
02206
02207 Propagate_Freq(head, head, 1.0, to_visit, visited);
02208
02209 if (CFLOW_Trace_Freq && !BB_SET_EmptyP(to_visit)) {
02210 #pragma mips_frequency_hint NEVER
02211 fprintf(TFile, " BBs unvisited in LOOP %d: ", loop_num);
02212 BB_SET_Print(to_visit, TFile);
02213 fprintf(TFile, "\n");
02214 }
02215
02216 loops = LOOP_DESCR_next(loops);
02217 }
02218
02219
02220
02221 BB_SET_UniverseD(to_visit, PU_BB_Count + 2, NULL);
02222 BB_SET_ClearD(visited);
02223
02224 #ifdef KEY
02225
02226
02227 if (PU_Has_Nonlocal_Goto_Target) {
02228 for (bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
02229 if (!BB_entry(bb) &&
02230 BB_has_non_local_label(bb) &&
02231 BB_preds(bb) == NULL) {
02232 Propagate_Freq(bb, bb, Non_Local_Target_Freq, to_visit, visited);
02233 }
02234 }
02235 }
02236 #endif
02237
02238 if (Compiling_Proper_REGION) {
02239
02240
02241
02242 if (CFLOW_Trace_Freq) {
02243 #pragma mips_frequency_hint NEVER
02244 fprintf(TFile, "Region entry point:\n");
02245 }
02246 bb = CGRIN_entry(RID_Find_Cginfo(REGION_First_BB));
02247 Propagate_Freq(bb, bb, 1.0, to_visit, visited);
02248 } else if (BB_LIST_rest(Entry_BB_Head) == NULL) {
02249
02250
02251
02252 if (CFLOW_Trace_Freq) {
02253 #pragma mips_frequency_hint NEVER
02254 fprintf(TFile, "PU entry point:\n");
02255 }
02256 bb = BB_LIST_first(Entry_BB_Head);
02257 Propagate_Freq(bb, bb, 1.0, to_visit, visited);
02258 } else {
02259
02260
02261
02262 BB_LIST *ent;
02263 INT n_entries;
02264 BB_SET **reachable;
02265 BB **entries;
02266 INT i;
02267
02268
02269
02270 n_entries = 0;
02271 for (ent = Entry_BB_Head; ent != NULL; ent = BB_LIST_rest(ent)) {
02272 n_entries++;
02273 }
02274
02275
02276
02277 reachable = (BB_SET **)alloca(sizeof(BB_SET *) * n_entries);
02278 entries = (BB **)alloca(sizeof(BB *) * n_entries);
02279 for (i = 0, ent = Entry_BB_Head; ent; i++, ent = BB_LIST_rest(ent)) {
02280 bb = BB_LIST_first(ent);
02281 entries[i] = bb;
02282 reachable[i] = BB_SET_Create_Empty(PU_BB_Count + 2, &MEM_local_pool);
02283 if (!BB_handler(bb)) Set_Reachable(bb, reachable[i]);
02284 }
02285
02286
02287
02288
02289
02290 for (i = 0; i < n_entries; i++) {
02291 double freq;
02292 INT j;
02293
02294 bb = entries[i];
02295
02296
02297
02298
02299 if (BB_handler(bb)) {
02300 freq = EH_Freq;
02301 } else {
02302 freq = 1.0;
02303 for (j = (i + 1) % n_entries; j != i; j = ++j % n_entries) {
02304 if (BB_SET_IntersectsP(reachable[i], reachable[j])) {
02305 freq += 1.0;
02306 }
02307 }
02308 freq = 1.0 / freq;
02309 }
02310
02311 if (CFLOW_Trace_Freq) {
02312 #pragma mips_frequency_hint NEVER
02313 fprintf(TFile, "PU entry point %d:\n", i);
02314 }
02315 Propagate_Freq(bb, bb, freq, to_visit, visited);
02316 }
02317 }
02318
02319 if (CFLOW_Trace_Freq && !BB_SET_EmptyP(to_visit)) {
02320 #pragma mips_frequency_hint NEVER
02321 fprintf(TFile, " BBs unvisited (includes dead BBs): ");
02322 BB_SET_Print(to_visit, TFile);
02323 fprintf(TFile, "\n");
02324 }
02325 }
02326
02327
02328
02329
02330
02331
02332
02333
02334
02335
02336
02337 static void
02338 Normalize_BB_Frequencies(void)
02339 {
02340 BB *bb;
02341 float entry_freq;
02342
02343 if (Compiling_Proper_REGION) {
02344 bb = CGRIN_entry(RID_Find_Cginfo(REGION_First_BB));
02345 entry_freq = BB_freq_fb_based(bb) ? BB_freq(bb) : 0.0;
02346 } else if (BB_LIST_rest(Entry_BB_Head) == NULL) {
02347 bb = BB_LIST_first(Entry_BB_Head);
02348 entry_freq = BB_freq_fb_based(bb) ? BB_freq(bb) : 0.0;
02349 } else {
02350
02351
02352
02353
02354
02355 INT i;
02356 mBOOL *counted;
02357 BB_SET **reachable;
02358 BB **entries;
02359 BB_LIST *ent;
02360
02361
02362
02363 INT n_entries = 0;
02364 for (ent = Entry_BB_Head; ent; ent = BB_LIST_rest(ent)) ++n_entries;
02365
02366
02367
02368 counted = (mBOOL *)alloca(sizeof(mBOOL) * n_entries);
02369 reachable = (BB_SET **)alloca(sizeof(BB_SET *) * n_entries);
02370 entries = (BB **)alloca(sizeof(BB *) * n_entries);
02371
02372
02373
02374 for (i = 0, ent = Entry_BB_Head; ent; i++, ent = BB_LIST_rest(ent)) {
02375 bb = BB_LIST_first(ent);
02376 counted[i] = FALSE;
02377 entries[i] = bb;
02378 reachable[i] = BB_SET_Create_Empty(PU_BB_Count + 2, &MEM_local_pool);
02379 Set_Reachable(bb, reachable[i]);
02380 }
02381
02382 for (i = 0; i < n_entries; i++) {
02383 INT j;
02384
02385 bb = entries[i];
02386 if (!counted[i]) {
02387 entry_freq = BB_freq(bb);
02388 for (j = (i + 1) % n_entries; j != i; j = (j + 1) % n_entries) {
02389 if (BB_SET_IntersectsP(reachable[i], reachable[j])) {
02390 counted[j] = TRUE;
02391 entry_freq += BB_freq(entries[j]);
02392 }
02393 }
02394 if (entry_freq != 0.0) {
02395
02396 FOR_ALL_BB_SET_members(reachable[i], bb) {
02397 BB_freq(bb) = BB_freq(bb) / entry_freq;
02398 }
02399 }
02400 }
02401 }
02402 return;
02403 }
02404
02405
02406
02407 if (entry_freq == 0.0) {
02408 #pragma mips_frequency_hint NEVER
02409 DevWarn("Can't normalize feedback freqs for PU \"%s\" -- entry freq is 0",
02410 Cur_PU_Name);
02411 return;
02412 }
02413
02414 for (bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
02415 if (BB_freq_fb_based(bb)) BB_freq(bb) = BB_freq(bb) / entry_freq;
02416 }
02417 }
02418
02419
02420
02421
02422
02423
02424
02425
02426
02427
02428
02429
02430
02431
02432
02433
02434
02435
02436
02437
02438 BB_SET *FREQ_Find_Never_BBs(MEM_POOL *pool)
02439 {
02440 #if 1
02441 BB_SET *pragma_bbs;
02442 BB_SET *never_bbs;
02443 BB *bb;
02444 BB *pragma_bb;
02445
02446 Find_Freq_Hint_Pragmas(&pragma_bbs, NULL, pool);
02447 if (pragma_bbs == NULL) return NULL;
02448
02449 Calculate_Dominators();
02450
02451 never_bbs = BB_SET_Create_Empty(PU_BB_Count + 2, pool);
02452
02453 do {
02454 for (pragma_bb = BB_SET_Choose(pragma_bbs);
02455 pragma_bb != BB_SET_CHOOSE_FAILURE;
02456 pragma_bb = BB_SET_Choose_Next(pragma_bbs, pragma_bb))
02457 {
02458 for (bb = REGION_First_BB; bb; bb = BB_next(bb)) {
02459 BOOL equiv_rev = BB_SET_MemberP(BB_pdom_set(pragma_bb), bb)
02460 && BB_SET_MemberP(BB_dom_set(bb), pragma_bb);
02461 BOOL equiv_fwd = BB_SET_MemberP(BB_pdom_set(bb), pragma_bb)
02462 && BB_SET_MemberP(BB_dom_set(pragma_bb), bb);
02463 if (equiv_rev || equiv_fwd) {
02464 BB_SET_Union1D(never_bbs, bb, NULL);
02465 }
02466 }
02467 }
02468
02469 BB_SET_ClearD(pragma_bbs);
02470
02471 for (bb = REGION_First_BB; bb; bb = BB_next(bb)) {
02472 BBLIST *edge;
02473
02474 if (BB_SET_MemberP(never_bbs, bb)) continue;
02475
02476 edge = BB_preds(bb);
02477 if (edge) {
02478 for (;;) {
02479 BB *pred = BBLIST_item(edge);
02480 if (!BB_SET_MemberP(never_bbs, pred)) break;
02481 edge = BBLIST_next(edge);
02482 if (edge == NULL) {
02483 BB_SET_Union1D(pragma_bbs, bb, NULL);
02484 goto next_bb;
02485 }
02486 }
02487 }
02488
02489 edge = BB_succs(bb);
02490 if (edge) {
02491 for (;;) {
02492 BB *succ = BBLIST_item(edge);
02493 if (!BB_SET_MemberP(never_bbs, succ)) break;
02494 edge = BBLIST_next(edge);
02495 if (edge == NULL) {
02496 BB_SET_Union1D(pragma_bbs, bb, NULL);
02497 break;
02498 }
02499 }
02500 }
02501 next_bb:
02502 ;
02503 }
02504 } while (!BB_SET_EmptyP(pragma_bbs));
02505
02506 Free_Dominators_Memory();
02507 #endif
02508 #if 0
02509 BB_SET *never_bbs;
02510 INT32 i;
02511 BB *bb;
02512 BB_MAP topo_map;
02513 INT32 max_topo_idx;
02514 BB **topo_vec;
02515 BOOL never_bbs_added;
02516
02517 Find_Freq_Hint_Pragmas(&never_bbs, NULL, pool);
02518 if (never_bbs == NULL) return NULL;
02519
02520 topo_map = BB_Topological_Map(NULL, NULL);
02521 topo_vec = (BB **)alloca(sizeof(BB *) * PU_BB_Count);
02522 bzero(topo_vec, sizeof(BB *) * PU_BB_Count);
02523 max_topo_idx = 0;
02524 for (bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
02525 INT32 topo_id = BB_MAP32_Get(topo_map, bb);
02526 DevAssert(topo_id >= 0 && topo_id <= PU_BB_Count, ("bad <topo_map> value"));
02527 if (topo_id > 0) {
02528 max_topo_idx = MAX(topo_id, max_topo_idx);
02529 topo_vec[topo_id - 1] = bb;
02530 }
02531 }
02532 BB_MAP_Delete(topo_map);
02533
02534 do {
02535 never_bbs_added = FALSE;
02536
02537 for (i = 0; i <= max_topo_idx; ++i) {
02538 BBLIST *edge;
02539 BB *bb = topo_vec[i];
02540
02541 if (bb == NULL) continue;
02542
02543 if (BB_preds(bb) && !BB_SET_MemberP(never_bbs, bb)) {
02544 FOR_ALL_BB_PREDS(bb, edge) {
02545 BB *pred = BBLIST_item(edge);
02546 if (!BB_SET_MemberP(never_bbs, pred)) goto next_fwd_bb;
02547 }
02548 BB_SET_Union1D(never_bbs, bb, NULL);
02549 never_bbs_added = TRUE;
02550 }
02551
02552 next_fwd_bb:
02553 ;
02554 }
02555
02556 for (i = max_topo_idx; i >= 0; --i) {
02557 BBLIST *edge;
02558 BB *bb = topo_vec[i];
02559
02560 if (bb == NULL) continue;
02561
02562 if (BB_succs(bb) && !BB_SET_MemberP(never_bbs, bb)) {
02563 FOR_ALL_BB_SUCCS(bb, edge) {
02564 BB *succ = BBLIST_item(edge);
02565 if (!BB_SET_MemberP(never_bbs, succ)) goto next_rev_bb;
02566 }
02567 BB_SET_Union1D(never_bbs, bb, NULL);
02568 never_bbs_added = TRUE;
02569 }
02570
02571 next_rev_bb:
02572 ;
02573 }
02574 } while (never_bbs_added);
02575 #endif
02576
02577 return never_bbs;
02578 }
02579
02580
02581
02582
02583
02584
02585
02586
02587
02588
02589 static UINT FREQ_CHECK_MSG_MAX = 5;
02590
02591 static BOOL
02592 Prob_sum_ok(BB* bb)
02593 {
02594 if (!BB_succs(bb)) return TRUE;
02595
02596 float prob = 0.0F;
02597 BBLIST* edge;
02598 FOR_ALL_BB_SUCCS(bb, edge) prob += BBLIST_prob(edge);
02599
02600 return FREQ_Match(prob, 1.0F);
02601 }
02602
02603 static BOOL
02604 Freq_sum_ok(BB* bb)
02605 {
02606 if (!BB_preds(bb)) return TRUE;
02607
02608 BBLIST* edge;
02609 float in_freq = 0.0f;
02610 FOR_ALL_BB_PREDS(bb, edge) {
02611 BB *pred = BBLIST_item(edge);
02612 BBLIST *succ_edge = BB_Find_Succ(pred, bb);
02613 float prob = BBLIST_prob(succ_edge);
02614 float freq = BB_freq(pred);
02615 in_freq += freq * prob;
02616 }
02617
02618 return FREQ_Match(in_freq, BB_freq(bb));
02619 }
02620
02621 BOOL
02622 FREQ_Check_Consistency(const char *caller)
02623 {
02624 static INT msg1_cnt = 0;
02625 static INT msg2_cnt = 0;
02626 BOOL is_ok = TRUE;
02627 BB *bb;
02628
02629 for (bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
02630
02631 if (!Prob_sum_ok(bb)) {
02632 is_ok = FALSE;
02633 ++msg1_cnt;
02634 if (msg1_cnt <= FREQ_CHECK_MSG_MAX) {
02635 DevWarn("%s: Succ probs of BB:%d do not sum to 1.0", caller,
02636 BB_id(bb));
02637 } else if (msg1_cnt == FREQ_CHECK_MSG_MAX+1) {
02638 DevWarn("%s: more than %d Succ probs sum msgs - disabling msg\n",
02639 caller, FREQ_CHECK_MSG_MAX);
02640 }
02641 }
02642
02643 if (!Freq_sum_ok(bb)) {
02644 is_ok = FALSE;
02645 ++msg2_cnt;
02646 if (msg2_cnt <= FREQ_CHECK_MSG_MAX) {
02647 DevWarn("%s: BB:%d freq (%g) != the sum of its pred edge freq",
02648 caller, BB_id(bb), BB_freq(bb));
02649 } else if (msg2_cnt == FREQ_CHECK_MSG_MAX+1) {
02650 DevWarn("%s: more than %d sum of pred msgs - disabling msg\n",
02651 caller, FREQ_CHECK_MSG_MAX);
02652 }
02653 }
02654 }
02655 return is_ok;
02656 }
02657
02658
02659
02660
02661
02662
02663
02664
02665
02666
02667 void
02668 FREQ_Print_BB_Note(
02669 BB *bb,
02670 FILE *file
02671 )
02672 {
02673 const char *prefix = file == Asm_File ? ASM_CMNT_LINE : "";
02674 BBLIST *bb_succs = BB_succs(bb);
02675 INT bb_id = BB_id(bb);
02676
02677 if (!FREQ_freqs_computed && !CG_PU_Has_Feedback) return;
02678
02679 fprintf(file, "%s<freq>\n", prefix);
02680
02681 fprintf(file, "%s<freq> BB:%d freq = %#.5f (%s)\n",
02682 prefix, bb_id, BB_freq(bb),
02683 (BB_freq_fb_based(bb) ? "fb" : "heur"));
02684
02685
02686
02687
02688 if (BBlist_Len(bb_succs) > 1) {
02689 BBLIST *succ;
02690
02691 FOR_ALL_BBLIST_ITEMS(bb_succs, succ) {
02692 fprintf(file, "%s<freq> BB:%d => BB:%d prob = %#.3f\n",
02693 prefix,
02694 bb_id,
02695 BB_id(BBLIST_item(succ)),
02696 BBLIST_prob(succ));
02697 }
02698 }
02699
02700 fprintf(file, "%s<freq>\n", prefix);
02701 }
02702
02703
02704
02705
02706
02707
02708
02709
02710
02711
02712 void
02713 FREQ_Region_Initialize(void)
02714 {
02715 static BOOL inited = FALSE;
02716
02717 if (!inited) {
02718 Frequent_Never_Ratio = atof(FREQ_frequent_never_ratio);
02719 EH_Freq = atof(FREQ_eh_freq);
02720 #ifdef KEY
02721 Non_Local_Target_Freq = atof(FREQ_non_local_targ_freq);
02722 #endif
02723 inited = TRUE;
02724 }
02725 FREQ_freqs_computed = FALSE;
02726 }
02727
02728 #if defined(TARG_SL)
02729 static void
02730 Initialize_Freq_BBs(void)
02731 {
02732 for (BB* bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
02733 if(!BB_freq_fb_based(bb) && BB_freq(bb)!=0.0)
02734 BB_freq(bb) = 0.0;
02735 }
02736 return;
02737 }
02738
02739 #endif
02740
02741
02742
02743
02744
02745
02746
02747
02748
02749
02750 static void
02751 Initialize_Compute_BB_Frequencies(void)
02752 {
02753 Calculate_Dominators();
02754
02755 MEM_POOL_Push(&MEM_local_pool);
02756 MEM_POOL_Push(&MEM_local_nz_pool);
02757
02758 Initialize_Depth_First_Info(&MEM_local_pool);
02759
02760 Initialize_Freq_Edges();
02761
02762 #if defined(TARG_SL)
02763
02764
02765
02766 Initialize_Freq_BBs();
02767 #endif
02768
02769 Find_Freq_Hint_Pragmas(&Never_BBs, &Frequent_BBs, &MEM_local_pool);
02770 if (CFLOW_Trace_Freq) {
02771 #pragma mips_frequency_hint NEVER
02772 fprintf(TFile, "BBs with 'frequent' hint pragma: ");
02773 BB_SET_Print(Frequent_BBs, TFile);
02774 fprintf(TFile, "\n");
02775
02776 fprintf(TFile, "BBs with 'never' hint pragma: ");
02777 BB_SET_Print(Never_BBs, TFile);
02778 fprintf(TFile, "\n");
02779 }
02780
02781 loop_list = LOOP_DESCR_Detect_Loops(&MEM_local_pool);
02782 if (CFLOW_Trace_Freq) {
02783 #pragma mips_frequency_hint NEVER
02784 LOOP_DESCR_Print_List();
02785 }
02786 }
02787
02788
02789
02790
02791
02792
02793
02794
02795
02796
02797
02798 static void
02799 Finalize_Compute_BB_Frequencies(void)
02800 {
02801 Finalize_Freq_Edges();
02802
02803 Finalize_Depth_First_Info();
02804
02805 MEM_POOL_Pop(&MEM_local_pool);
02806 MEM_POOL_Pop(&MEM_local_nz_pool);
02807
02808 Free_Dominators_Memory();
02809
02810 FREQ_freqs_computed = TRUE;
02811 }
02812
02813
02814
02815
02816
02817
02818
02819
02820
02821
02822 void
02823 FREQ_Compute_BB_Frequencies(void)
02824 {
02825 if (CFLOW_Trace_Freq) {
02826 #pragma mips_frequency_hint NEVER
02827 fprintf(TFile, "\n%sEnter Freq Estimate for %s\n%s\n",
02828 DBar, Cur_PU_Name, DBar);
02829 }
02830
02831 if (!FREQ_enable) {
02832 BB *bb;
02833
02834
02835
02836
02837 for (bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
02838 if (!BB_freq_fb_based(bb)) BB_freq(bb) = 1.0;
02839 }
02840
02841 if (CFLOW_Trace_Freq) {
02842 #pragma mips_frequency_hint NEVER
02843 fprintf (TFile, "Setting all BB frequencies to 1.0\n");
02844 }
02845 } else {
02846 Initialize_Compute_BB_Frequencies();
02847
02848 Compute_Branch_Probabilities();
02849 Compute_Frequencies();
02850
02851 Finalize_Compute_BB_Frequencies();
02852
02853 if (CFLOW_Trace_Freq) {
02854 #pragma mips_frequency_hint NEVER
02855 BB *bb;
02856 Trace_Frequencies();
02857
02858 fprintf(TFile, "\n%s%s\tIR after Frequency Estimates\n%s%s\n",
02859 DBar, DBar, DBar, DBar);
02860 for (bb = REGION_First_BB; bb; bb = BB_next(bb)) Print_BB(bb);
02861 fprintf(TFile, "%s%s\n", DBar, DBar);
02862 }
02863
02864 if (FREQ_view_cfg) {
02865 #pragma mips_frequency_hint NEVER
02866 FREQ_View_CFG("After heuristic-based freq computation");
02867 }
02868 }
02869
02870 if (CFLOW_Trace_Freq) {
02871 #pragma mips_frequency_hint NEVER
02872 fprintf(TFile, "\n%sLeave Freq Estimate for %s\n%s\n",
02873 DBar, Cur_PU_Name, DBar);
02874 }
02875 }
02876
02877
02878
02879
02880
02881
02882
02883
02884
02885
02886 static const char *
02887 Node_label(BB* bb)
02888 {
02889 static char *buffer = NULL;
02890 static INT buf_size = 0;
02891
02892
02893
02894 const INT size = 25
02895 + BBlist_Len(BB_succs(bb)) * 25;
02896
02897 if (buf_size == 0) {
02898 buffer = (char *)malloc(size);
02899 buf_size = size;
02900 } else if (size > buf_size) {
02901 while (size > buf_size) buf_size *= 2;
02902 buffer = (char *)realloc(buffer, buf_size);
02903 }
02904
02905 char *p = buffer;
02906 p += sprintf(p, "%d: %g", BB_id(bb), BB_freq(bb));
02907
02908 if (using_EDGEs) {
02909 EDGE *sedge;
02910 FOR_ALL_SUCC_EDGES(bb, sedge) {
02911 p += sprintf(p, "\\n-> %d: %g", BB_id(EDGE_succ(sedge)),
02912 EDGE_prob(sedge));
02913 }
02914 } else {
02915 BBLIST *sedge;
02916 FOR_ALL_BB_SUCCS(bb, sedge) {
02917 p += sprintf(p, "\\n-> %d: %g", BB_id(BBLIST_item(sedge)),
02918 BBLIST_prob(sedge));
02919 }
02920 }
02921 FmtAssert(p < buffer + size, ("Node_Label buffer size estimate too small"));
02922
02923 return buffer;
02924 }
02925
02926
02927
02928
02929
02930
02931
02932
02933
02934
02935 void
02936 FREQ_View_CFG(const char *status)
02937 {
02938 if (!DaVinci::enabled(TRUE)) return;
02939
02940 CXX_MEM_POOL dv_pool("DaVinci", FALSE);
02941
02942 DaVinci dv(dv_pool(), NULL);
02943
02944 dv.Title(Cur_PU_Name);
02945 dv.Show_Status(status);
02946
02947
02948
02949 NODE_TYPE nt_known, nt_uninit, nt_bad;
02950 EDGE_TYPE et_known, et_uninit;
02951
02952 nt_uninit.Color("orange");
02953 nt_bad.Color("light sky blue");
02954 et_uninit.Color("red");
02955
02956 dv.Graph_Begin();
02957
02958
02959
02960 for (BB* bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
02961 dv.Node_Begin(NODE_ID(bb), Node_label (bb),
02962 (Prob_sum_ok(bb) && Freq_sum_ok(bb))
02963 ? (BB_freq_fb_based(bb) ? nt_known : nt_uninit)
02964 : nt_bad);
02965 if (using_EDGEs) {
02966 EDGE *sedge;
02967 FOR_ALL_SUCC_EDGES(bb, sedge) {
02968 dv.Out_Edge(EDGE_ID(NODE_ID(bb), NODE_ID(EDGE_succ(sedge))),
02969 EDGE_prob_fb_based(sedge) ? et_known : et_uninit,
02970 NODE_ID(EDGE_succ(sedge)));
02971 }
02972 } else {
02973 BBLIST *sedge;
02974 FOR_ALL_BB_SUCCS(bb, sedge) {
02975 dv.Out_Edge(EDGE_ID(NODE_ID(bb), NODE_ID(BBLIST_item(sedge))),
02976 BBLIST_prob_fb_based(sedge) ? et_known : et_uninit,
02977 NODE_ID(BBLIST_item(sedge)));
02978 }
02979 }
02980 dv.Node_End();
02981 }
02982 dv.Graph_End();
02983
02984 dv.Event_Loop(NULL);
02985 }
02986
02987
02988
02989
02990
02991 typedef enum {
02992 PS_UNKNOWN,
02993 PS_FEEDBACK,
02994 PS_COMPUTED
02995 } PROP_STATE;
02996
02997 typedef struct {
02998 INT unprocessed_pred_count;
02999
03000 PROP_STATE state;
03001 } PROP_STATUS;
03002
03003
03004
03005
03006
03007
03008
03009 inline void BB_PROP_STATUS_Init(
03010 PROP_STATUS *stsvec,
03011 const BB *bb,
03012 INT count,
03013 PROP_STATE st)
03014 {
03015 PROP_STATUS * const status = &stsvec[BB_id(bb)];
03016 status->unprocessed_pred_count = count;
03017 status->state = st;
03018 }
03019
03020 inline PROP_STATUS *BB_PROP_STATUS(PROP_STATUS *stsvec, const BB *bb)
03021 {
03022 return &stsvec[BB_id(bb)];
03023 }
03024
03025 inline BOOL BB_PROP_STATUS_Valid(const PROP_STATUS *stsvec, const BB *bb)
03026 {
03027 const PROP_STATUS * const status = &stsvec[BB_id(bb)];
03028 return status->state != PS_UNKNOWN
03029 && status->unprocessed_pred_count == 0;
03030 }
03031
03032 inline void BB_PROP_STATUS_Set_Valid(
03033 PROP_STATUS *stsvec,
03034 BB *bb,
03035 BOOL feedback_based)
03036 {
03037 PROP_STATUS * const status = &stsvec[BB_id(bb)];
03038 status->unprocessed_pred_count = 0;
03039 status->state = feedback_based ? PS_FEEDBACK : PS_COMPUTED;
03040 }
03041
03042
03043
03044
03045
03046
03047
03048
03049
03050
03051
03052 static void
03053 Propagate_Feedback(PROP_STATUS * const bb_prop_status)
03054 {
03055 INT i;
03056
03057
03058
03059
03060
03061
03062
03063 for (i = max_dfo_id - 1; i >= 0; i--) {
03064 BB *bb = dfo_vec[i];
03065 if (BB_PROP_STATUS_Valid(bb_prop_status, bb) && BB_Has_One_Pred(bb)) {
03066 BB *pred = BBLIST_item(BB_preds(bb));
03067 if (!BB_PROP_STATUS_Valid(bb_prop_status, pred) && BB_Has_One_Succ(pred)) {
03068 BB_freq(pred) = BB_freq(bb);
03069 EDGE *sedge = BB_succ_edges(pred);
03070 EDGE_prob(sedge) = 1.0;
03071 if (BB_freq_fb_based(bb)) {
03072 Set_BB_freq_fb_based(pred);
03073 Set_EDGE_prob_fb_based(sedge);
03074 }
03075 BB_PROP_STATUS_Set_Valid(bb_prop_status, pred, BB_freq_fb_based(bb));
03076 }
03077 }
03078 }
03079
03080
03081
03082
03083
03084
03085 BOOL changed;
03086 do {
03087 changed = FALSE;
03088 for (i = 0; i < max_dfo_id; i++) {
03089 BB *bb = dfo_vec[i];
03090 if (BB_PROP_STATUS_Valid(bb_prop_status, bb)) {
03091 EDGE *sedge;
03092 PROP_STATUS * const status = BB_PROP_STATUS(bb_prop_status, bb);
03093 float bb_freq = BB_freq(bb);
03094 FOR_ALL_SUCC_EDGES(bb, sedge) {
03095 BB *succ = EDGE_succ(sedge);
03096 if ( !BB_PROP_STATUS_Valid(bb_prop_status, succ)
03097 && (bb_freq == 0.0 || EDGE_prob_fb_based(sedge))
03098 && !EDGE_fb_propagated(sedge))
03099 {
03100 PROP_STATUS * const succ_status = BB_PROP_STATUS(bb_prop_status, succ);
03101 float prob = EDGE_prob(sedge);
03102 BB_freq(succ) += bb_freq * prob;
03103 changed = TRUE;
03104
03105 if (succ_status->state == PS_UNKNOWN) {
03106 succ_status->state = status->state;
03107 } else if ( status->state == PS_COMPUTED
03108 || !EDGE_prob_fb_based(sedge))
03109 {
03110 succ_status->state = PS_COMPUTED;
03111 }
03112
03113 if ( --succ_status->unprocessed_pred_count == 0
03114 && succ_status->state == PS_FEEDBACK)
03115 {
03116 Set_BB_freq_fb_based(succ);
03117 }
03118
03119 Set_EDGE_fb_propagated(sedge);
03120 }
03121 }
03122 }
03123 }
03124 } while (changed);
03125 }
03126
03127
03128
03129
03130
03131
03132
03133
03134
03135
03136
03137
03138
03139 static inline float
03140 FB_FREQ_Value(FB_FREQ freq)
03141 {
03142 return freq.Zero() ? 0.0 : freq.Value();
03143 }
03144
03145
03146
03147
03148
03149
03150
03151
03152
03153
03154 void
03155 FREQ_Incorporate_Feedback(const WN* entry)
03156 {
03157 BB *bb;
03158
03159
03160
03161
03162
03163
03164
03165 Initialize_Compute_BB_Frequencies();
03166
03167
03168
03169
03170
03171
03172
03173
03174
03175 for (bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
03176 WN *wn = BB_branch_wn(bb);
03177 if (wn != NULL) {
03178 switch (WN_operator(wn)) {
03179 case OPR_TRUEBR:
03180 case OPR_FALSEBR:
03181 {
03182 FB_FREQ fb_take = Cur_PU_Feedback->Query(wn, FB_EDGE_BRANCH_TAKEN);
03183 FB_FREQ fb_fall = Cur_PU_Feedback->Query(wn, FB_EDGE_BRANCH_NOT_TAKEN);
03184 FB_FREQ fb_bb = fb_take + fb_fall;
03185 if (fb_bb.Known()) {
03186 LABEL_IDX label = WN_label_number(wn);
03187 BB *take_bb = Get_Label_BB(label);
03188 EDGE *take_edge = BB_Find_Succ_Edge(bb, take_bb);
03189 EDGE *fall_edge = BB_Find_Succ_Edge(bb, BB_next(bb));
03190 float freq_bb = FB_FREQ_Value(fb_bb);
03191 BB_freq(bb) = freq_bb;
03192 Set_BB_freq_fb_based(bb);
03193 if (freq_bb != 0.0) {
03194 float freq_take = fb_take.Value();
03195 float freq_fall = fb_fall.Value();
03196 if (take_edge) {
03197 EDGE_prob(take_edge) += freq_take / freq_bb;
03198 Set_EDGE_prob_fb_based(take_edge);
03199 }
03200 if (fall_edge) {
03201 EDGE_prob(fall_edge) += freq_fall / freq_bb;
03202 Set_EDGE_prob_fb_based(fall_edge);
03203 }
03204 }
03205 }
03206 }
03207 break;
03208 case OPR_GOTO:
03209 {
03210 FB_FREQ fb_goto = Cur_PU_Feedback->Query(wn, FB_EDGE_OUTGOING);
03211 if (fb_goto.Known()) {
03212 EDGE *edge = BB_succ_edges(bb);
03213 BB_freq(bb) = fb_goto.Value();
03214 Set_BB_freq_fb_based(bb);
03215 if (edge) {
03216 EDGE_prob(edge) = 1.0;
03217 Set_EDGE_prob_fb_based(edge);
03218 }
03219 }
03220 }
03221 break;
03222 case OPR_XGOTO:
03223 {
03224 INT i;
03225 WN *goto_wn;
03226 INT num_gotos = WN_num_entries(wn);
03227
03228 FB_FREQ fb_bb = FB_FREQ_ZERO;
03229 for (i = 0; i < num_gotos; ++i) {
03230 FB_FREQ fb_case = Cur_PU_Feedback->Query(wn, FB_EDGE_SWITCH(i));
03231 fb_bb += fb_case;
03232 }
03233
03234 if (fb_bb.Known()) {
03235 float freq_bb = FB_FREQ_Value(fb_bb);
03236 BB_freq(bb) = freq_bb;
03237 Set_BB_freq_fb_based(bb);
03238 for (i = 0, goto_wn = WN_first(WN_kid1(wn));
03239 i < num_gotos;
03240 ++i, goto_wn = WN_next(goto_wn))
03241 {
03242 LABEL_IDX label = WN_label_number(goto_wn);
03243 BB *targ_bb = Get_Label_BB(label);
03244 EDGE *edge = BB_Find_Succ_Edge(bb, targ_bb);
03245 if (edge) {
03246 if (freq_bb != 0.0) {
03247 FB_FREQ fb_case = Cur_PU_Feedback->Query(wn,
03248 FB_EDGE_SWITCH(i));
03249 float freq_case = FB_FREQ_Value(fb_case);
03250 EDGE_prob(edge) += freq_case / freq_bb;
03251 Set_EDGE_prob_fb_based(edge);
03252 }
03253 }
03254 }
03255 }
03256 }
03257 break;
03258
03259 #if defined (TARG_SL)
03260 case OPR_SL2_FORK_MAJOR:
03261 case OPR_SL2_FORK_MINOR:
03262 {
03263 INT i;
03264 FB_FREQ fb0 = Cur_PU_Feedback->Query(wn, FB_EDGE_SWITCH(0));
03265 FB_FREQ fb1 = Cur_PU_Feedback->Query(wn, FB_EDGE_SWITCH(1));
03266 if(fb0.Known() && fb1.Known()) {
03267 FmtAssert(fb0 == fb1, (" freq of forked two threads are not equal "));
03268 BB_freq(bb)=FB_FREQ_Value(fb0);
03269 Set_BB_freq_fb_based(bb);
03270
03271 LABEL_IDX label = WN_label_number(wn);
03272 BB *take_bb = Get_Label_BB(label);
03273 EDGE *take_edge = BB_Find_Succ_Edge(bb, take_bb);
03274 EDGE *fall_edge = BB_Find_Succ_Edge(bb, BB_next(bb));
03275 EDGE_prob(take_edge) = 1.0;
03276 Set_EDGE_prob_fb_based(take_edge);
03277 EDGE_prob(fall_edge) = 1.0;
03278 Set_EDGE_prob_fb_based(fall_edge);
03279 }
03280 Set_BB_freq_unbalanced(bb);
03281 }
03282 break;
03283 #endif
03284 }
03285 }
03286 else if (BB_call(bb)) {
03287 ANNOTATION *ant = ANNOT_Get(BB_annotations(bb), ANNOT_CALLINFO);
03288 WN * call_wn = CALLINFO_call_wn(ANNOT_callinfo(ant));
03289 FB_FREQ fb_in = Cur_PU_Feedback->Query(call_wn, FB_EDGE_CALL_INCOMING);
03290 if (fb_in.Known()) {
03291 EDGE *edge = BB_succ_edges(bb);
03292 float freq_in = FB_FREQ_Value(fb_in);
03293 BB_freq(bb) = freq_in;
03294 Set_BB_freq_fb_based(bb);
03295 if (edge) {
03296 FB_FREQ fb_out = Cur_PU_Feedback->Query(call_wn,
03297 FB_EDGE_CALL_OUTGOING);
03298 if (fb_out.Known()) {
03299 if (freq_in != 0.0) {
03300 float freq_out = FB_FREQ_Value(fb_out);
03301 EDGE_prob(edge) = freq_out / freq_in;
03302 Set_EDGE_prob_fb_based(edge);
03303 }
03304 } else {
03305 EDGE_prob(edge) = 1.0;
03306 }
03307 }
03308 }
03309 } else if (BB_Has_One_Succ(bb)) {
03310
03311
03312
03313 EDGE *edge = BB_succ_edges(bb);
03314 #if defined(TARG_SL)
03315 if(!BB_freq_unbalanced(bb))
03316 #endif
03317 if (edge) {
03318 EDGE_prob(edge) = 1.0;
03319 Set_EDGE_prob_fb_based(edge);
03320 }
03321 }
03322 }
03323
03324
03325
03326
03327
03328 for (BB_LIST *elist = Entry_BB_Head; elist; elist = BB_LIST_rest(elist)) {
03329 BB *entry_bb = BB_LIST_first(elist);
03330 if (!BB_freq_fb_based(entry_bb)) {
03331 ANNOTATION *ant = ANNOT_Get(BB_annotations(entry_bb), ANNOT_ENTRYINFO);
03332 ENTRYINFO *ent = ANNOT_entryinfo(ant);
03333 WN *entry_wn = ENTRYINFO_entry_wn(ent);
03334 if (entry_wn != NULL) {
03335 FB_FREQ fb_entry = Cur_PU_Feedback->Query(entry_wn, FB_EDGE_OUTGOING);
03336 if (fb_entry.Known()) {
03337 BB_freq(entry_bb) = FB_FREQ_Value(fb_entry);
03338 Set_BB_freq_fb_based(entry_bb);
03339 }
03340 }
03341 }
03342 }
03343
03344
03345
03346
03347
03348
03349
03350
03351
03352
03353
03354 PROP_STATUS *bb_prop_status = (PROP_STATUS *)alloca( sizeof(PROP_STATUS)
03355 * (PU_BB_Count + 1));
03356 for (bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
03357 if (BB_freq_fb_based(bb)) {
03358 BB_PROP_STATUS_Init(bb_prop_status, bb, 0, PS_FEEDBACK);
03359 } else {
03360 BB_PROP_STATUS_Init(bb_prop_status, bb, BBlist_Len(BB_preds(bb)),
03361 PS_UNKNOWN);
03362 }
03363 }
03364
03365
03366
03367
03368
03369
03370
03371
03372
03373 Propagate_Feedback(bb_prop_status);
03374 if (FREQ_view_cfg) {
03375 #pragma mips_frequency_hint NEVER
03376 FREQ_View_CFG("Before feedback-based freq computation");
03377 }
03378
03379
03380
03381
03382
03383 Normalize_BB_Frequencies();
03384
03385
03386
03387
03388 Compute_Branch_Probabilities();
03389 Compute_Frequencies();
03390 if (FREQ_view_cfg) {
03391 #pragma mips_frequency_hint NEVER
03392 FREQ_View_CFG("After feedback-based freq computation");
03393 }
03394
03395 Finalize_Compute_BB_Frequencies();
03396 }
03397
03398
03399
03400
03401
03402
03403
03404
03405
03406
03407
03408
03409
03410
03411
03412 BOOL
03413 FREQ_Verify(const char *caller)
03414 {
03415 float *bb_total_freq;
03416 BOOL all_ok = TRUE;
03417 BB *bb, *succ;
03418 BBLIST *lst;
03419 float total_prob;
03420 const char *s;
03421
03422 fprintf(TFile,"%s<freq> Freq_Verify after %s\n%s", DBar, caller, DBar);
03423
03424
03425
03426 bb_total_freq = (float *) CXX_NEW_ARRAY( float, PU_BB_Count + 1,
03427 &MEM_local_region_pool );
03428
03429
03430 for (bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
03431 FOR_ALL_BB_SUCCS(bb, lst) {
03432 succ = BBLIST_item(lst);
03433 bb_total_freq[BB_id(succ)] += BB_freq(bb) * BBLIST_prob(lst);
03434 }
03435 }
03436
03437
03438 for (bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
03439
03440
03441 fprintf(TFile, "BB:%d frequency = %#.4f", BB_id(bb), BB_freq(bb));
03442
03443
03444 total_prob = 0.0;
03445 s = "\n\t";
03446 FOR_ALL_BB_SUCCS(bb, lst) {
03447 total_prob += BBLIST_prob(lst);
03448 succ = BBLIST_item(lst);
03449 fprintf(TFile, "%sBB:%d %#.4f(%#.4f)", s, BB_id(succ),
03450 BB_freq(bb) * BBLIST_prob(lst), BBLIST_prob(lst));
03451 s = ", ";
03452 }
03453 fprintf(TFile, "\n");
03454
03455
03456 if (! FREQ_Match(total_prob, 1.0) && BB_succs(bb)) {
03457 #if defined(TARG_SL)
03458 if(!BB_freq_unbalanced(bb) && !CG_PU_Has_Feedback)
03459 #endif
03460 fprintf(TFile, "FAIL total_prob == %#.4f != 1.0\n", total_prob);
03461 all_ok = FALSE;
03462 }
03463
03464
03465 if (! FREQ_Match(bb_total_freq[BB_id(bb)], BB_freq(bb))
03466 && BB_preds(bb)) {
03467 fprintf(TFile, "FAIL total_freq == %#.4f != %f\n",
03468 bb_total_freq[BB_id(bb)], BB_freq(bb));
03469 all_ok = FALSE;
03470 }
03471 }
03472
03473 return all_ok;
03474 }