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 #ifdef _KEEP_RCS_ID
00051 static const char rcs_id[] = "$Source: /scratch/mee/2.4-65/kpro64-pending/be/cg/SCCS/s.findloops.cxx $ $Revision: 1.2 $";
00052 #endif
00053
00054 #include "defs.h"
00055 #include "config.h"
00056 #include "errors.h"
00057 #include "mempool.h"
00058 #include "tracing.h"
00059 #include "glob.h"
00060 #include "bitset.h"
00061 #include "bb.h"
00062 #include "bb_set.h"
00063 #include "cg_sched_est.h"
00064 #include "dominate.h"
00065 #include "region_util.h"
00066 #include "cg_region.h"
00067 #include "cg_flags.h"
00068 #include "cflow.h"
00069 #include "annotations.h"
00070 #include "whirl2ops.h"
00071 #include "note.h"
00072
00073 #include "findloops.h"
00074
00075 BB_MAP LOOP_DESCR_map;
00076 static BOOL loop_descr_map_initted;
00077 static LOOP_DESCR *the_loops;
00078 static BB_MAP dfo_map;
00079
00080 #if defined(TARG_SL)
00081
00082
00083
00084 VECTOR loop_tree_roots;
00085 #endif
00086
00087 #if defined(TARG_SL)
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 void
00099 LOOP_DESCR_Create_Loop_Tree( MEM_POOL * pool )
00100 {
00101 LOOP_DESCR *cloop, *encl_loop;
00102 INT loop_num = 0;
00103 BOOL not_root = FALSE;
00104
00105
00106
00107
00108
00109
00110 for (cloop = the_loops; cloop != NULL; cloop = LOOP_DESCR_next(cloop) ){
00111 loop_num++;
00112 }
00113
00114 loop_tree_roots = VECTOR_Init( loop_num, pool );
00115
00116 for (cloop = the_loops; cloop != NULL; cloop = LOOP_DESCR_next(cloop)) {
00117
00118 not_root = FALSE;
00119 if( !cloop->children )
00120 cloop->children = VECTOR_Init( loop_num-1, pool );
00121
00122 for (encl_loop = LOOP_DESCR_next(cloop);
00123 encl_loop != NULL;
00124 encl_loop = LOOP_DESCR_next(encl_loop)) {
00125 if( !encl_loop->children )
00126 encl_loop->children = VECTOR_Init( loop_num-1, pool );
00127 if (BB_SET_ContainsP (LOOP_DESCR_bbset(encl_loop),
00128 LOOP_DESCR_bbset(cloop))) {
00129 not_root = TRUE;
00130 VECTOR_Add_Element( encl_loop->children, cloop );
00131
00132
00133
00134
00135
00136
00137 break;
00138 }
00139 }
00140
00141 if( !not_root ){
00142 VECTOR_Add_Element( loop_tree_roots, cloop );
00143 }
00144 }
00145 }
00146 #endif
00147
00148 #if defined(TARG_SL)
00149 void
00150 LOOP_DESCR_Dump_Loop_Brief( LOOP_DESCR* cloop )
00151 {
00152 BB *loophead = LOOP_DESCR_loophead(cloop);
00153 fprintf( TFile,
00154 "[loop head: %d, nest level: %d, # exits: %d]\n",
00155 loophead ? BB_id(loophead) : 0,
00156 LOOP_DESCR_nestlevel(cloop),
00157 LOOP_DESCR_num_exits(cloop) );
00158 return;
00159 }
00160
00161 void
00162 LOOP_DESCR_Dump_Loop( INT indent, LOOP_DESCR* cloop )
00163 {
00164 INT i;
00165 LOOP_DESCR* child_loop;
00166
00167 for( i=0; i < indent; i++ ){
00168 fprintf( TFile, " " );
00169 }
00170
00171 LOOP_DESCR_Dump_Loop_Brief( cloop );
00172
00173 for( i=0; i < VECTOR_count( cloop->children ); i++ ){
00174 child_loop = (LOOP_DESCR*)VECTOR_element( cloop->children, i);
00175 LOOP_DESCR_Dump_Loop( indent+2, child_loop );
00176 }
00177
00178 return;
00179 }
00180 #endif
00181
00182 #if defined(TARG_SL)
00183
00184
00185
00186
00187
00188
00189
00190
00191 void
00192 LOOP_DESCR_Dump_Loop_Tree( void )
00193 {
00194 LOOP_DESCR *root;
00195 INT root_idx;
00196
00197 if( VECTOR_count(loop_tree_roots) == 0 ){
00198 fprintf( TFile, "there is no loops at all !\n");
00199 return;
00200 }
00201
00202 fprintf( TFile, "%s", DBar );
00203 fprintf( TFile, " LOOP TREE \n" );
00204
00205 for( root_idx = 0; root_idx < VECTOR_count(loop_tree_roots); root_idx++ ) {
00206 root = (LOOP_DESCR*)VECTOR_element( loop_tree_roots, root_idx );
00207 LOOP_DESCR_Dump_Loop( 2, root );
00208 }
00209
00210 }
00211 #endif
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 void
00222 LOOP_DESCR_Print_List(void)
00223 {
00224 LOOP_DESCR *cloop;
00225 INT i;
00226 FILE *tfile = TFile;
00227
00228 i = 0;
00229 for (cloop = the_loops; cloop != NULL; cloop = LOOP_DESCR_next(cloop)) {
00230 BB *loophead = LOOP_DESCR_loophead(cloop);
00231 i++;
00232 fprintf (tfile,
00233 "LOOP %d (loop head: %d, nest level: %d, # exits: %d",
00234 i,
00235 loophead ? BB_id(loophead) : 0,
00236 LOOP_DESCR_nestlevel(cloop),
00237 LOOP_DESCR_num_exits(cloop));
00238 if (LOOP_DESCR_loopinfo(cloop) != NULL) {
00239 fprintf (tfile, ", loop-info:\n");
00240 Print_LOOPINFO(LOOP_DESCR_loopinfo(cloop));
00241 } else {
00242 fprintf (tfile, ", loop-info: <none>");
00243 }
00244 fprintf (tfile, ")\n");
00245 BB_SET_Print (LOOP_DESCR_bbset(cloop), tfile);
00246 fprintf (tfile, "\n\n");
00247 }
00248 }
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259 LOOP_DESCR *
00260 LOOP_DESCR_Is_Exit_Edge(BB *bb, BB *succ)
00261 {
00262 LOOP_DESCR *loop, *exitloop;
00263
00264 DevAssert(loop_descr_map_initted, ("<LOOP_DESCR_map> not yet initialized"));
00265 exitloop = NULL;
00266 for (loop = (LOOP_DESCR *)BB_MAP_Get(LOOP_DESCR_map, bb);
00267 loop != NULL; loop = LOOP_DESCR_next(loop)) {
00268 if (BB_SET_MemberP (LOOP_DESCR_bbset(loop), bb) &&
00269 !BB_SET_MemberP (LOOP_DESCR_bbset(loop), succ))
00270 {
00271 if (!BB_Find_Succ(bb, LOOP_DESCR_loophead(loop))) {
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281 LOOPINFO *info = LOOP_DESCR_loopinfo(loop);
00282 if (info) LOOPINFO_trip_count_tn(info) = NULL;
00283 }
00284
00285 exitloop = loop;
00286 if (LOOP_DESCR_nestlevel(exitloop) == 1) break;
00287 }
00288 }
00289 return exitloop;
00290 }
00291
00292
00293
00294
00295
00296
00297 void
00298 LOOP_DESCR_Init_For_PU(void)
00299 {
00300 loop_descr_map_initted = FALSE;
00301 }
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 LOOP_DESCR *
00313 LOOP_DESCR_Detect_Loops (MEM_POOL *pool)
00314 {
00315 LOOP_DESCR *newloop, *cloop, *lastloop, *exitloop, *encl_loop;
00316 BB_SET *loop_set;
00317 BB *bb;
00318 BBLIST *blst;
00319 BB *succ;
00320 ANNOTATION *annot;
00321
00322 the_loops = NULL;
00323 if (loop_descr_map_initted) {
00324 BB_MAP_Delete(LOOP_DESCR_map);
00325 loop_descr_map_initted = FALSE;
00326 }
00327
00328 dfo_map = BB_Depth_First_Map(NULL, NULL);
00329
00330 for (bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
00331 INT32 bb_dfo_id = BB_MAP32_Get(dfo_map, bb);
00332 DevAssert(bb_dfo_id >= 0 && bb_dfo_id <= PU_BB_Count,
00333 ("bad <dfo_map> value"));
00334 if (bb_dfo_id == 0) continue;
00335
00336 FOR_ALL_BB_SUCCS (bb, blst) {
00337 succ = BBLIST_item(blst);
00338 if (bb_dfo_id < BB_MAP32_Get(dfo_map, succ)) continue;
00339 if (!BS_MemberP(BB_dom_set(bb), BB_id(succ))) {
00340
00341
00342
00343 continue;
00344 }
00345
00346 #ifndef TARG_NVISA
00347 if (CFLOW_Trace_Freq)
00348 fprintf (TFile, "BACK EDGE from %d to %d\n", BB_id(bb), BB_id(succ));
00349 #endif
00350
00351 newloop = TYPE_L_ALLOC (LOOP_DESCR);
00352 loop_set = BB_SET_Create_Empty (PU_BB_Count + 2, pool);
00353 BB_SET_Union1D(loop_set, succ, NULL);
00354 if (bb != succ) BB_Add_Ancestors(&loop_set, bb, bb, pool);
00355 newloop->mem_pool = pool;
00356 LOOP_DESCR_bbset(newloop) = loop_set;
00357 LOOP_DESCR_loophead(newloop) = succ;
00358 LOOP_DESCR_nestlevel(newloop) = 1;
00359 LOOP_DESCR_num_exits(newloop) = 0;
00360 LOOP_DESCR_next(newloop) = NULL;
00361 Set_BB_innermost(succ);
00362
00363
00364
00365 LOOP_DESCR_loopinfo(newloop) = NULL;
00366 annot = ANNOT_Get(BB_annotations(succ), ANNOT_LOOPINFO);
00367 if (annot != NULL) LOOP_DESCR_loopinfo(newloop) = ANNOT_loopinfo(annot);
00368
00369 lastloop = NULL;
00370 for (cloop = the_loops; cloop != NULL; cloop = LOOP_DESCR_next(cloop))
00371 {
00372
00373
00374
00375
00376
00377 if (LOOP_DESCR_loophead(cloop) == succ) {
00378 BB_SET_UnionD(LOOP_DESCR_bbset(newloop),
00379 LOOP_DESCR_bbset(cloop), NULL);
00380 if (lastloop == NULL) {
00381 the_loops = LOOP_DESCR_next(the_loops);
00382 }
00383 else {
00384 LOOP_DESCR_next(lastloop) = LOOP_DESCR_next(cloop);
00385 }
00386 }
00387
00388
00389
00390 else if (BB_SET_ContainsP (LOOP_DESCR_bbset(cloop),
00391 LOOP_DESCR_bbset(newloop)))
00392 {
00393 LOOP_DESCR_next(newloop) =
00394 (lastloop == NULL) ? the_loops : LOOP_DESCR_next(lastloop);
00395 break;
00396 }
00397 else {
00398 lastloop = cloop;
00399 }
00400 }
00401 if (lastloop == NULL) {
00402 the_loops = newloop;
00403 }
00404 else {
00405 LOOP_DESCR_next(lastloop) = newloop;
00406 }
00407 }
00408 }
00409
00410
00411
00412
00413
00414 LOOP_DESCR_map = BB_MAP_Create();
00415 loop_descr_map_initted = TRUE;
00416 for (cloop = the_loops; cloop != NULL; cloop = LOOP_DESCR_next(cloop)) {
00417 FOR_ALL_BB_SET_members(LOOP_DESCR_bbset(cloop), bb)
00418 if (!BB_MAP_Get(LOOP_DESCR_map, bb))
00419 BB_MAP_Set(LOOP_DESCR_map, bb, cloop);
00420 for (encl_loop = LOOP_DESCR_next(cloop);
00421 encl_loop != NULL;
00422 encl_loop = LOOP_DESCR_next(encl_loop))
00423 {
00424
00425 if (BB_SET_ContainsP (LOOP_DESCR_bbset(encl_loop),
00426 LOOP_DESCR_bbset(cloop))) {
00427 LOOP_DESCR_nestlevel(cloop)++;
00428 Reset_BB_innermost(LOOP_DESCR_loophead(encl_loop));
00429 }
00430 }
00431 }
00432
00433
00434
00435
00436
00437
00438 for (bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
00439 if (BB_MAP32_Get(dfo_map, bb) == 0) continue;
00440
00441 BB_nest_level(bb) = 0;
00442 cloop = LOOP_DESCR_Find_Loop(bb);
00443 if (cloop != NULL) {
00444 BB *head = LOOP_DESCR_loophead(cloop);
00445 BOOL innermost = BB_innermost(head);
00446 BB_nest_level(bb) = LOOP_DESCR_nestlevel(cloop);
00447 if (innermost) Set_BB_innermost(bb);
00448 else Reset_BB_innermost(bb);
00449 Set_BB_loop_head_bb(bb, head);
00450 FOR_ALL_BB_SUCCS (bb, blst) {
00451 exitloop = LOOP_DESCR_Is_Exit_Edge(bb, BBLIST_item(blst));
00452 if (exitloop != NULL) {
00453 LOOP_DESCR_num_exits(exitloop)++;
00454 }
00455 }
00456 }
00457 }
00458
00459 BB_MAP_Delete(dfo_map);
00460
00461 return the_loops;
00462 }
00463
00464
00465 static void
00466 LOOP_DESCR_Add_BB_Helper (LOOP_DESCR *loop, BB *bb) {
00467
00468 LOOP_DESCR* l = LOOP_DESCR_Next_Enclosing_Loop(loop);
00469 if (l) { LOOP_DESCR_Add_BB_Helper (l, bb); }
00470
00471 LOOP_DESCR_bbset(loop) = BB_SET_Union1D(LOOP_DESCR_bbset(loop),
00472 bb, loop->mem_pool);
00473 }
00474
00475
00476
00477
00478
00479 void
00480 LOOP_DESCR_Add_BB(LOOP_DESCR *loop, BB *bb)
00481 {
00482 DevAssert(LOOP_DESCR_Find_Loop(bb) == NULL,
00483 ("BB:%d already in a loop", BB_id(bb)));
00484
00485 BB_MAP_Set(LOOP_DESCR_map, bb, loop);
00486
00487 LOOP_DESCR_Add_BB_Helper (loop, bb);
00488 }
00489
00490
00491
00492
00493
00494
00495 void
00496 LOOP_DESCR_Delete_BB(LOOP_DESCR *loop, BB *bb)
00497 {
00498 DevAssert(BB_SET_MemberP(LOOP_DESCR_bbset(loop), bb),
00499 ("BB:%d not in <loop>", BB_id(bb)));
00500 DevAssert(LOOP_DESCR_Find_Loop(bb) == loop,
00501 ("<loop> is not innermost containing BB:%d", BB_id(bb)));
00502
00503 BB_MAP_Set(LOOP_DESCR_map, bb, NULL);
00504
00505 do {
00506 LOOP_DESCR_bbset(loop) = BB_SET_Difference1D(LOOP_DESCR_bbset(loop), bb);
00507 loop = LOOP_DESCR_Next_Enclosing_Loop(loop);
00508 } while (loop);
00509 }
00510
00511
00512
00513
00514
00515
00516
00517 LOOP_DESCR*
00518 LOOP_DESCR_Next_Enclosing_Loop(LOOP_DESCR *loop)
00519 {
00520
00521
00522 if (LOOP_DESCR_nestlevel(loop) > 1) {
00523 LOOP_DESCR *enclosing = LOOP_DESCR_next(loop);
00524 while (enclosing &&
00525 (LOOP_DESCR_nestlevel(enclosing) >= LOOP_DESCR_nestlevel(loop) ||
00526 !BB_SET_ContainsP(LOOP_DESCR_bbset(enclosing),
00527 LOOP_DESCR_bbset(loop))))
00528 enclosing = LOOP_DESCR_next(enclosing);
00529 return enclosing;
00530 } else {
00531 return NULL;
00532 }
00533 }
00534
00535
00536
00537
00538
00539 BB*
00540 LOOP_DESCR_Find_Unique_Tail(LOOP_DESCR *loop)
00541 {
00542 BB *tail = NULL;
00543 BBLIST *preds;
00544 FOR_ALL_BB_PREDS(LOOP_DESCR_loophead(loop), preds) {
00545 if (BB_SET_MemberP(LOOP_DESCR_bbset(loop), BBLIST_item(preds))) {
00546 if (tail == NULL) {
00547 tail = BBLIST_item(preds);
00548 } else {
00549 return NULL;
00550 }
00551 }
00552 }
00553 return tail;
00554 }
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564 void
00565 LOOP_DESCR_Retarget_Loop_Entrances(LOOP_DESCR *loop, BB *to)
00566 {
00567 BB *head = LOOP_DESCR_loophead(loop);
00568 BBLIST *preds = BB_preds(head);
00569 while (preds) {
00570 BB *pred = BBLIST_item(preds);
00571 preds = BBLIST_next(preds);
00572 if (!BB_SET_MemberP(LOOP_DESCR_bbset(loop), pred))
00573 if (!BB_Retarget_Branch(pred, head, to))
00574
00575 Change_Succ(pred, head, to);
00576 }
00577 }
00578
00579
00580
00581
00582
00583 BOOL
00584 LOOP_DESCR_Can_Retarget_Loop_Entrances(LOOP_DESCR *loop)
00585 {
00586 BB *head = LOOP_DESCR_loophead(loop);
00587 BBLIST *preds = BB_preds(head);
00588 while (preds) {
00589 BB *pred = BBLIST_item(preds);
00590 preds = BBLIST_next(preds);
00591 if (!BB_SET_MemberP(LOOP_DESCR_bbset(loop), pred)) {
00592 if (BB_next(pred) == head) continue;
00593 if (!BB_Can_Retarget_Branch(pred, head)) return FALSE;
00594 }
00595 }
00596 return TRUE;
00597 }
00598
00599 #ifndef TARG_NVISA
00600
00601
00602
00603
00604 float
00605 LOOP_DESCR_Estimate_Cycles(LOOP_DESCR *loop)
00606 {
00607 BB *bb;
00608 float avg_cycles;
00609 BB *head = LOOP_DESCR_loophead(loop);
00610
00611 BB_MAP sch_est = BB_MAP_Create();
00612 FOR_ALL_BB_SET_members(LOOP_DESCR_bbset(loop), bb) {
00613 CG_SCHED_EST *se =
00614 CG_SCHED_EST_Create(bb, &MEM_local_nz_pool, SCHED_EST_FOR_SWP);
00615 BB_MAP_Set(sch_est, bb, se);
00616 }
00617
00618 avg_cycles = CG_SCHED_EST_Avg_Cycles_Thru(LOOP_DESCR_bbset(loop), head, sch_est, SCHED_EST_FOR_SWP);
00619
00620 return avg_cycles;
00621 }
00622 #endif
00623
00624
00625
00626
00627
00628 BOOL
00629 LOOP_DESCR_Has_Side_Entrance(LOOP_DESCR *loop)
00630 {
00631 BB* bb;
00632 BB* pred;
00633 BBLIST *lst;
00634
00635 FOR_ALL_BB_SET_members(LOOP_DESCR_bbset(loop), bb) {
00636 BB* head = LOOP_DESCR_loophead(loop);
00637 if (bb == head) continue;
00638 FOR_ALL_BB_PREDS (bb, lst) {
00639 pred = BBLIST_item(lst);
00640 if (!BB_SET_MemberP(LOOP_DESCR_bbset(loop), pred)) {
00641 return TRUE;
00642 }
00643 }
00644 }
00645 return FALSE;
00646 }