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 #include "defs.h"
00037 #include "config.h"
00038 #include "tracing.h"
00039 #include "timing.h"
00040 #include "cgir.h"
00041 #include "cg.h"
00042 #include "cg_flags.h"
00043 #include "ttype.h"
00044 #include "bitset.h"
00045 #include "bb_set.h"
00046 #include "freq.h"
00047 #include "whirl2ops.h"
00048 #include "gra_live.h"
00049 #include "bb.h"
00050 #include "bb_map.h"
00051 #include "tn_map.h"
00052
00053 #include "hb.h"
00054 #include "hb_trace.h"
00055
00057 static void
00058 Check_Tail_Duplication(HB* hb, BB* bb, BB_MAP unduplicated,
00059 HB_bb_list& need_duplication)
00061
00062
00063
00064
00065
00067 {
00068 BBLIST* blp;
00069
00070 if (bb == HB_Entry(hb)) {
00071 return;
00072 }
00073
00074 if (BB_MAP32_Get(unduplicated, bb)) {
00075 return;
00076 }
00077
00078 FOR_ALL_BB_PREDS(bb, blp) {
00079 BB* pred = BBLIST_item(blp);
00080 if (!HB_Contains_Block(hb, pred) || BB_MAP32_Get(unduplicated, pred)) {
00081 BB_MAP32_Set(unduplicated, bb, 1);
00082 if (HB_Trace(HB_TRACE_DUP)) {
00083 fprintf(HB_TFile, "<HB> BB%d is a side entrance.\n", BB_id(bb));
00084 }
00085 need_duplication.push_front(bb);
00086 BBLIST* bls;
00087 FOR_ALL_BB_SUCCS(bb, bls) {
00088 BB* succ = BBLIST_item(bls);
00089
00090
00091
00092 if (succ != HB_Entry(hb) && HB_Contains_Block(hb, succ)) {
00093 Check_Tail_Duplication(hb, succ, unduplicated, need_duplication);
00094 }
00095 }
00096 break;
00097 }
00098 }
00099 }
00100
00101
00103 static BOOL
00104 Unduplicated_Preds(BB* bb, BB_MAP unduplicated)
00106
00107
00108
00109
00111 {
00112 BBLIST* bl;
00113 FOR_ALL_BB_PREDS(bb, bl) {
00114 BB* pred = BBLIST_item(bl);
00115 if (BB_MAP32_Get(unduplicated, pred)) {
00116 return TRUE;
00117 }
00118 }
00119 return FALSE;
00120 }
00121
00123 static void
00124 Fixup_Arcs(HB* hb, BB* old_bb, BB* new_bb, BB_MAP duplicate, BB** fall_thru,
00125 HB_bb_list& duplicate_bbs)
00127
00128
00129
00130
00132 {
00133 BBLIST* bl;
00134 float new_freq = 0.0;
00135
00136
00137
00138
00139 for (bl = BB_preds(old_bb); bl != NULL;) {
00140 BB* pred = BBLIST_item(bl);
00141 bl = BBLIST_next(bl);
00142
00143
00144
00145
00146 BBLIST* blsucc = BB_Find_Succ(pred, old_bb);
00147
00148
00149
00150
00151
00152
00153 BB* dup = (BB*) BB_MAP_Get(duplicate, pred);
00154 if (dup) {
00155 new_freq += BB_freq(pred) * BBLIST_prob(blsucc);
00156
00157
00158
00159
00160
00161 #ifdef TARG_IA64
00162 Remove_Explicit_Branch(pred);
00163 #endif
00164 if (BB_Fall_Thru_Successor(pred) == old_bb) {
00165 Link_Pred_Succ_with_Prob(dup, new_bb, BBLIST_prob(blsucc));
00166 } else if (BB_kind(dup) == BBKIND_LOGIF) {
00167 Target_Cond_Branch(dup, new_bb, BBLIST_prob(blsucc));
00168 } else {
00169 BB_Remove_Branch(dup);
00170 Add_Goto(dup, new_bb);
00171 }
00172 } else if (HB_Contains_Block(hb, pred)) {
00173 continue;
00174 } else {
00175 new_freq += BB_freq(pred) * BBLIST_prob(blsucc);
00176 #ifdef TARG_IA64
00177 Remove_Explicit_Branch(pred);
00178 #endif
00179 if (BB_Fall_Thru_Successor(pred) == old_bb) {
00180 Change_Succ(pred, old_bb, new_bb);
00181 } else {
00182 BB_Retarget_Branch(pred, old_bb, new_bb);
00183 }
00184 }
00185 }
00186
00187 BB_freq(new_bb) = new_freq;
00188
00189
00190
00191
00192
00193 FOR_ALL_BB_SUCCS(old_bb, bl) {
00194 BB* succ = BBLIST_item(bl);
00195 if (!HB_Contains_Block(hb, succ) || succ == HB_Entry(hb)) {
00196 #ifdef TARG_IA64
00197 Remove_Explicit_Branch(old_bb);
00198 #endif
00199 if (BB_Fall_Thru_Successor(old_bb) == succ) {
00200
00201
00202
00203
00204
00205
00206
00207 BB* new_succ = Gen_And_Insert_BB_After(new_bb);
00208 Link_Pred_Succ(new_bb, new_succ);
00209 Add_Goto(new_succ, succ);
00210 Link_Pred_Succ(new_succ, succ);
00211 GRA_LIVE_Compute_Liveness_For_BB(new_succ);
00212 duplicate_bbs.push_front(new_succ);
00213 *fall_thru = new_succ;
00214 } else {
00215 Link_Pred_Succ_with_Prob(new_bb, succ, BBLIST_prob(bl));
00216 }
00217 }
00218 }
00219 }
00220
00222 static void
00223 Rename_Locals(OP* op, hTN_MAP dup_tn_map)
00225
00226
00227
00228
00229
00230
00232 {
00233 INT i = 0;
00234 TN* res;
00235
00236 for (i = 0; i < OP_results(op); i++) {
00237 res = OP_result(op, i);
00238 if (TN_is_register(res) &&
00239 !(TN_is_dedicated(res) || TN_is_global_reg(res))) {
00240 TN* new_tn = Dup_TN(res);
00241 hTN_MAP_Set(dup_tn_map, res, new_tn);
00242 Set_OP_result(op, i, new_tn);
00243 }
00244 }
00245
00246 i = 0;
00247 for (INT opndnum = 0; opndnum < OP_opnds(op); opndnum++) {
00248 res = OP_opnd(op, opndnum);
00249 if (TN_is_register(res) &&
00250 !(TN_is_dedicated(res) || TN_is_global_reg(res))) {
00251 res = (TN*) hTN_MAP_Get(dup_tn_map, res);
00252 Set_OP_opnd(op, i, res);
00253 }
00254 i++;
00255 }
00256 }
00257
00258 #if !defined(TARG_IA64) && !defined(TARG_SL) && !defined(TARG_MIPS)
00259 static
00260 #endif
00262 BB*
00263 Copy_BB_For_Tail_Duplication(HB* hb, BB* old_bb)
00265
00266
00267
00268
00270 {
00271 BB* new_bb = NULL;
00272
00273 new_bb = Gen_BB_Like(old_bb);
00274
00275
00276
00277
00278
00279 OP *op;
00280 MEM_POOL_Push(&MEM_local_pool);
00281 hTN_MAP dup_tn_map = hTN_MAP_Create(&MEM_local_pool);
00282
00283 FOR_ALL_BB_OPs_FWD(old_bb, op) {
00284 OP *new_op = Dup_OP(op);
00285 Copy_WN_For_Memory_OP(new_op, op);
00286 BB_Append_Op(new_bb, new_op);
00287 Rename_Locals(new_op, dup_tn_map);
00288 }
00289 MEM_POOL_Pop(&MEM_local_pool);
00290
00291
00292
00293
00294 switch (BB_kind(old_bb)) {
00295 case BBKIND_CALL:
00296 BB_Copy_Annotations(new_bb, old_bb, ANNOT_CALLINFO);
00297 break;
00298
00299 case BBKIND_TAIL_CALL:
00300 BB_Copy_Annotations(new_bb, old_bb, ANNOT_CALLINFO);
00301
00302
00303
00304 case BBKIND_RETURN:
00305 {
00306 BB_Copy_Annotations(new_bb, old_bb, ANNOT_EXITINFO);
00307 OP *b_op;
00308 OP *suc_op;
00309 ANNOTATION *ant = ANNOT_Get(BB_annotations(new_bb), ANNOT_EXITINFO);
00310 EXITINFO *exit_info = ANNOT_exitinfo(ant);
00311 EXITINFO *new_info = TYPE_PU_ALLOC(EXITINFO);
00312 OP *sp_adj = EXITINFO_sp_adj(exit_info);
00313 *new_info = *exit_info;
00314 if (sp_adj) {
00315 for (suc_op = BB_last_op(old_bb), b_op = BB_last_op(new_bb);
00316 suc_op != sp_adj;
00317 suc_op = OP_prev(suc_op), b_op = OP_prev(b_op))
00318 ;
00319 EXITINFO_sp_adj(new_info) = b_op;
00320 }
00321 ant->info = new_info;
00322
00323 Set_BB_exit(new_bb);
00324 Exit_BB_Head = BB_LIST_Push(new_bb, Exit_BB_Head, &MEM_pu_pool);
00325 break;
00326 }
00327 }
00328
00329 return new_bb;
00330 }
00331
00333 static void
00334 Tail_Duplicate(HB* hb, BB* side_entrance, BB_MAP unduplicated,
00335 BB_MAP duplicate, BB** last, HB_bb_list& duplicate_bbs)
00337
00338
00339
00341 {
00342 BBLIST* bl;
00343 BB* dup = Copy_BB_For_Tail_Duplication(hb, side_entrance);
00344 duplicate_bbs.push_front(dup);
00345
00346 if (HB_Trace(HB_TRACE_DUP)) {
00347 fprintf(HB_TFile, "<HB> Tail duplicating BB:%d. Duplicate BB%d\n",
00348 BB_id(side_entrance), BB_id(dup));
00349 }
00350
00351
00352
00353
00354 BB_MAP32_Set(unduplicated, side_entrance, 0);
00355 BB_MAP_Set(duplicate, side_entrance, dup);
00356
00357
00358
00359
00360
00361
00362 FOR_ALL_BB_PREDS(side_entrance, bl) {
00363 BB* pred = BBLIST_item(bl);
00364 #ifdef TARG_IA64
00365 Remove_Explicit_Branch(pred);
00366 #endif
00367 if (side_entrance == BB_Fall_Thru_Successor(pred)) {
00368 BB* fall_dup = (BB*) BB_MAP_Get(duplicate, pred);
00369 if (fall_dup) {
00370 *last = fall_dup;
00371 } else if (!HB_Contains_Block(hb, pred)) {
00372 *last = pred;
00373 }
00374 break;
00375 }
00376 }
00377
00378
00379
00380
00381 BB* fall_thru = NULL;
00382 Fixup_Arcs(hb, side_entrance, dup, duplicate, &fall_thru, duplicate_bbs);
00383
00384
00385
00386
00387
00388 Insert_BB(dup, *last);
00389 if (fall_thru) {
00390 Insert_BB(fall_thru, dup);
00391 *last = fall_thru;
00392 } else {
00393 *last = dup;
00394 }
00395 }
00396
00398 BOOL
00399 HB_Tail_Duplicate(HB* hb, BB_MAP duplicate,
00400 HB_bb_list& duplicate_bbs,
00401 BOOL post_tail_duplication)
00403
00404
00405
00407 {
00408 BB* bb;
00409 HB_bb_list need_duplication;
00410 BB_MAP unduplicated = BB_MAP32_Create();
00411
00412 FOR_ALL_BB_SET_members(HB_Blocks(hb), bb) {
00413 Check_Tail_Duplication(hb, bb, unduplicated, need_duplication);
00414 }
00415
00416 if (need_duplication.empty()) {
00417 BB_MAP_Delete(unduplicated);
00418 return TRUE;
00419 }
00420 if (post_tail_duplication) {
00421
00422
00423
00424
00425 BB_MAP_Delete(unduplicated);
00426 return FALSE;
00427 }
00428
00429 if (!HB_allow_tail_duplication) {
00430 BB_MAP_Delete(unduplicated);
00431 return FALSE;
00432 }
00433
00434 HB_did_tail_duplication = TRUE;
00435
00436
00437
00438
00439 BB* last_duplicated;
00440 for (bb = HB_Entry(hb); bb && HB_Contains_Block(hb, bb);
00441 last_duplicated = bb, bb = BB_next(bb));
00442 #ifdef TARG_IA64
00443 Remove_Explicit_Branch(bb);
00444 #endif
00445 if (bb) {
00446
00447
00448
00449 for (; bb && BB_Fall_Thru_Successor(bb); bb = BB_next(bb));
00450 #ifdef TARG_IA64
00451 Remove_Explicit_Branch(bb);
00452 #endif
00453 last_duplicated = bb;
00454 }
00455
00456
00457
00458
00459
00460
00461 while (!need_duplication.empty()) {
00462 HB_bb_list::iterator bbi, cur;
00463 for (bbi = need_duplication.begin(); bbi != need_duplication.end();) {
00464 cur = bbi++;
00465 if (!Unduplicated_Preds(*cur, unduplicated)) {
00466 Tail_Duplicate(hb, *cur, unduplicated, duplicate, &last_duplicated,
00467 duplicate_bbs);
00468 need_duplication.erase(cur);
00469 }
00470 }
00471 }
00472
00473 BB_MAP_Delete(unduplicated);
00474
00475
00476
00477
00478 return TRUE;
00479 }