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 #include "defs.h"
00038 #include "erglob.h"
00039 #include "mempool.h"
00040 #include "bb.h"
00041 #include "cgtarget.h"
00042 #include "freq.h"
00043 #include "cg.h"
00044
00045
00046 #define BBLISTS_PER_BLOCK 670
00047
00048 #define BBLIST_BLOCK_SIZE (BBLISTS_PER_BLOCK * sizeof(BBLIST))
00049
00050 static BBLIST *BBlist_Free_List = NULL;
00051
00052 static INT num_bblist_buffers = 0;
00053
00054
00055
00056
00057
00058 static BBLIST *
00059 bblist_alloc (void)
00060 {
00061 BBLIST *tmp_list;
00062 BBLIST *cur_item;
00063 INT i;
00064
00065 tmp_list = BBlist_Free_List;
00066 if (tmp_list == NULL) {
00067
00068
00069
00070
00071 tmp_list = (BBLIST *) malloc (BBLIST_BLOCK_SIZE);
00072 num_bblist_buffers++;
00073 if (tmp_list == NULL) {
00074 ErrMsg (EC_No_Mem, "bblist_alloc");
00075 }
00076 cur_item = tmp_list;
00077 for (i = 0; i < BBLISTS_PER_BLOCK - 1; i++) {
00078 BBLIST_next(cur_item) = cur_item + 1;
00079 cur_item++;
00080 }
00081 BBLIST_next(cur_item) = NULL;
00082 }
00083 BBlist_Free_List = BBLIST_next(tmp_list);
00084 BBLIST_prob(tmp_list) = 0.0;
00085 BBLIST_next(tmp_list) = NULL;
00086 BBLIST_flags(tmp_list) = 0;
00087 return tmp_list;
00088 }
00089
00090
00091 #if USE_DEBUG_VERSION
00092 static void
00093 bblist_free (BBLIST *lst)
00094 {
00095 BBLIST *p;
00096
00097 FOR_ALL_BBLIST_ITEMS (BBlist_Free_List, p) {
00098 if (p == lst) printf ("*** ERROR in bblist_free\n");
00099 }
00100 BBLIST_next(lst) = BBlist_Free_List;
00101 BBlist_Free_List = lst;
00102 }
00103 #else
00104 #define bblist_free(lst) \
00105 ((BBLIST_next(lst) = BBlist_Free_List), (BBlist_Free_List = lst))
00106 #endif
00107
00108
00109
00110 void
00111 BBlist_Free (BBLIST **lst )
00112 {
00113 BBLIST *tmp1, *tmp2;
00114
00115 for (tmp1 = *lst; tmp1 != NULL; tmp1 = tmp2) {
00116 tmp2 = BBLIST_next(tmp1);
00117 bblist_free (tmp1);
00118 }
00119 *lst = NULL;
00120 }
00121
00122
00123
00124 INT
00125 BBlist_Len (BBLIST *lst)
00126 {
00127 INT count = 0;
00128 BBLIST *p;
00129
00130 FOR_ALL_BBLIST_ITEMS (lst, p)
00131 count++;
00132 return count;
00133 }
00134
00135
00136
00137
00138
00139 BBLIST *
00140 BBlist_Add_BB (BBLIST **lst, BB *bb)
00141 {
00142 BBLIST *p, *last;
00143
00144 p = *lst;
00145
00146 if (p == NULL) {
00147 p = bblist_alloc ();
00148 BBLIST_item(p) = bb;
00149 *lst = p;
00150 return p;
00151 }
00152
00153
00154 last = NULL;
00155 for (;p != NULL; p = BBLIST_next(p)) {
00156 if (BBLIST_item(p) == bb) return p;
00157 last = p;
00158 }
00159
00160
00161 p = bblist_alloc ();
00162 BBLIST_item(p) = bb;
00163 BBLIST_next(last) = p;
00164 return p;
00165 }
00166
00167
00168
00169
00170
00171
00172 BBLIST *
00173 BBlist_Add_BB_with_Prob (BBLIST **lst, BB *bb, float prob,
00174 BOOL via_feedback, BOOL set_prob
00175 #ifdef KEY
00176 ,BOOL via_hint
00177 #endif
00178 ,BOOL incr_prob)
00179 {
00180 BBLIST *p, *last;
00181
00182 p = *lst;
00183
00184 if (p == NULL) {
00185 p = bblist_alloc ();
00186 BBLIST_item(p) = bb;
00187 if (via_feedback || CG_PU_Has_Feedback) {
00188 BBLIST_prob(p) = prob;
00189 Set_BBLIST_prob_fb_based(p);
00190 } if (set_prob || FREQ_Frequencies_Computed()) {
00191 BBLIST_prob(p) = prob;
00192 #if defined(KEY) && defined(TARG_SL)
00193 if(via_hint)
00194 Set_BBLIST_prob_hint_based(p);
00195 #endif
00196 Reset_BBLIST_prob_fb_based(p);
00197 }
00198 *lst = p;
00199 return p;
00200 }
00201
00202
00203 last = NULL;
00204 for (;p != NULL; p = BBLIST_next(p)) {
00205 if (BBLIST_item(p) == bb) {
00206 if (FREQ_Frequencies_Computed() && incr_prob) {
00207 BBLIST_prob(p) += prob;
00208 if (BBLIST_prob(p) >= 1.0f)
00209 BBLIST_prob(p) = 1.0f;
00210 }
00211 return p;
00212 }
00213 last = p;
00214 }
00215
00216
00217 p = bblist_alloc ();
00218 BBLIST_item(p) = bb;
00219 BBLIST_next(last) = p;
00220 if (via_feedback || CG_PU_Has_Feedback) {
00221 BBLIST_prob(p) = prob;
00222 Set_BBLIST_prob_fb_based(p);
00223 } if (
00224 #if defined(KEY)
00225 set_prob ||
00226 #endif
00227 FREQ_Frequencies_Computed()) {
00228 BBLIST_prob(p) = prob;
00229 #if defined(KEY) && defined(TARG_SL)
00230 if(via_hint)
00231 Set_BBLIST_prob_hint_based(p);
00232 #endif
00233 Reset_BBLIST_prob_fb_based(p);
00234 }
00235 return p;
00236 }
00237
00238 static const union { INT32 i; float f; } NaN_u = { 0x7fbfffff };
00239 static const float NaN = NaN_u.f;
00240
00241 void
00242 Link_Pred_Succ (BB *pred, BB *succ)
00243 {
00244 Verify_BB(pred);
00245 Verify_BB(succ);
00246
00247 BBLIST *pedge;
00248 BBlist_Add_BB (&BB_succs(pred), succ);
00249 pedge = BBlist_Add_BB (&BB_preds(succ), pred);
00250
00251
00252
00253 BBLIST_prob(pedge) = NaN;
00254 }
00255
00256 void
00257 Link_Pred_Succ_with_Prob (BB *pred, BB *succ, float prob,
00258 BOOL via_feedback, BOOL set_prob
00259 #ifdef KEY
00260 , BOOL via_hint
00261 #endif
00262 , BOOL incr_prob
00263 )
00264 {
00265 Verify_BB(pred);
00266 Verify_BB(succ);
00267
00268 BBLIST *pedge;
00269 BBlist_Add_BB_with_Prob (&BB_succs(pred), succ, prob,
00270 via_feedback, set_prob
00271 #ifdef KEY
00272 , via_hint
00273 #endif
00274 , incr_prob
00275 );
00276 pedge = BBlist_Add_BB (&BB_preds(succ), pred);
00277
00278
00279
00280 BBLIST_prob(pedge) = NaN;
00281 }
00282
00283
00284
00285 void
00286 BBlist_Delete_BB (BBLIST **lst, BB *bb)
00287 {
00288 BBLIST *p, *last;
00289
00290 last = NULL;
00291 for (p = *lst; p != NULL; p = BBLIST_next(p)) {
00292 if (BBLIST_item(p) == bb) {
00293 if (last == NULL) {
00294 *lst = BBLIST_next(p);
00295 }
00296 else {
00297 BBLIST_next(last) = BBLIST_next(p);
00298 }
00299 bblist_free (p);
00300 break;
00301 }
00302 last = p;
00303 }
00304 }
00305
00306 void
00307 Unlink_Pred_Succ (BB *pred, BB *succ)
00308 {
00309 BBlist_Delete_BB (&BB_succs(pred), succ);
00310 BBlist_Delete_BB (&BB_preds(succ), pred);
00311 }
00312
00313
00314 BBLIST *
00315 BBlist_Find_BB (BBLIST *lst, BB *bb)
00316
00317
00318
00319
00320
00321 {
00322 BBLIST *p;
00323 FOR_ALL_BBLIST_ITEMS(lst, p)
00324 if (BBLIST_item(p) == bb) break;
00325 return p;
00326 }
00327
00328 BBLIST *
00329 BBlist_Fall_Thru_Succ (BB *bb)
00330
00331
00332
00333
00334
00335
00336 {
00337 BB *next = BB_next(bb);
00338 BBLIST *node = NULL;
00339
00340 if (next && (node = BB_Find_Succ(bb, next))) {
00341
00342 OP *br_op = BB_branch_op(bb);
00343 if (br_op) {
00344 INT tfirst, tcount;
00345 CGTARG_Branch_Info(br_op, &tfirst, &tcount);
00346 if (tcount == 0) {
00347
00348 node = NULL;
00349 } else {
00350 TN *dest = OP_opnd(br_op, tfirst);
00351 DevAssert(tcount == 1, ("%d branch targets, expected 1", tcount));
00352 DevAssert(TN_is_label(dest), ("expected label"));
00353 if (Is_Label_For_BB(TN_label(dest), next)) {
00354
00355 BB_Remove_Op(bb, br_op);
00356 } else {
00357 #if defined(TARG_SL)
00358 #ifndef fork_joint
00359 if(!OP_fork(br_op))
00360 #endif
00361 #endif
00362 DevAssert(OP_cond(br_op), ("BB_succs(BB:%d) wrongly contains BB:%d",
00363 BB_id(bb), BB_id(next)));
00364 }
00365 }
00366 }
00367 }
00368 return node;
00369 }
00370
00371 BBLIST *
00372 BBlist_Fall_Thru_Pred (BB *bb)
00373
00374
00375
00376
00377
00378
00379 {
00380 BB *prev = BB_prev(bb);
00381 BBLIST *node = NULL;
00382
00383 if (prev && (node = BB_Find_Pred(bb, prev))) {
00384
00385 OP *br_op = BB_branch_op(prev);
00386 if (br_op) {
00387 INT tfirst, tcount;
00388 CGTARG_Branch_Info(br_op, &tfirst, &tcount);
00389 if (tcount == 0) {
00390
00391 node = NULL;
00392 } else {
00393 TN *dest = OP_opnd(br_op, tfirst);
00394 DevAssert(tcount == 1, ("%d branch targets, expected 1", tcount));
00395 DevAssert(TN_is_label(dest), ("expected label"));
00396 if (Is_Label_For_BB(TN_label(dest), bb)) {
00397
00398 BB_Remove_Op(prev, br_op);
00399 } else {
00400 DevAssert(OP_cond(br_op), ("BB_preds(BB:%d) wrongly contains BB:%d",
00401 BB_id(bb), BB_id(prev)));
00402 }
00403 }
00404 }
00405 }
00406 return node;
00407 }
00408
00409