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 #ifdef USE_PCH
00043 #include "lno_pch.h"
00044 #endif // USE_PCH
00045 #pragma hdrstop
00046
00047 #ifdef _KEEP_RCS_ID
00048
00049 static char *rcs_id = "$Source: /home/bos/bk/kpro64-pending/be/lno/SCCS/s.fission.cxx $ $Revision: 1.5 $";
00050 #endif
00051
00052 #include <sys/types.h>
00053 #include "fission.h"
00054 #include "defs.h"
00055 #include "stab.h"
00056 #include "wn.h"
00057 #include "lwn_util.h"
00058 #include "errors.h"
00059 #include "cxx_graph.h"
00060 #include "lnoutils.h"
00061 #include "ff_utils.h"
00062 #include "lnopt_main.h"
00063 #include "cxx_memory.h"
00064 #include "cxx_template.h"
00065 #include "lno_scc.h"
00066 #include "wn_map.h"
00067 #include "opt_du.h"
00068 #include "glob.h"
00069 #include "tlog.h"
00070 #include "prompf.h"
00071 #include "anl_driver.h"
00072
00073 #pragma weak New_Construct_Id
00074
00075 typedef HASH_TABLE<WN *, INT> WN2INT;
00076
00077 extern WN* Get_Only_Loop_Inside(const WN* wn, BOOL regions_ok);
00078
00079 static ARRAY_DIRECTED_GRAPH16 *adg;
00080 static BOOL fission_initialized=FALSE;
00081
00082 MEM_POOL FISSION_default_pool;
00083
00084 const mUINT16 FISSION_BIT_STMT_REORDERING= 0x0001;
00085 const mUINT16 FISSION_BIT_PERFECT_NESTING= 0x0002;
00086 const mUINT16 FISSION_BIT_SINGLY_NESTING= 0x0004;
00087 const mUINT16 FISSION_BIT_SCALAR_EXPANSION= 0x0008;
00088 const mUINT16 FISSION_BIT_EXPRESSION_BASED= 0x0010;
00089 const mUINT16 FISSION_BIT_TWO_LOOPS_ONLY= 0x0020;
00090 const mUINT16 FISSION_BIT_TEST_ONLY= 0x1000;
00091
00092 const mUINT16 OPT_FLAG_STMT_SIMPLE= 0;
00093 const mUINT16 OPT_FLAG_STMT_PERFECT= FISSION_BIT_PERFECT_NESTING;
00094
00095 const mUINT16 OPT_FLAG_STMT_EXPANSION= FISSION_BIT_SCALAR_EXPANSION;
00096 const mUINT16 OPT_FLAG_STMT_REORDERING= FISSION_BIT_STMT_REORDERING;
00097 const mUINT16 OPT_FLAG_STMT_REORDERING_PERFECT= FISSION_BIT_STMT_REORDERING |
00098 FISSION_BIT_PERFECT_NESTING;
00099
00100
00101 const mUINT16 OPT_FLAG_STMT_BEST= FISSION_BIT_STMT_REORDERING ||
00102 FISSION_BIT_PERFECT_NESTING ||
00103 FISSION_BIT_SCALAR_EXPANSION;
00104
00105
00106 static void fission_verbose_info(
00107 BOOL ,
00108 SRCPOS srcpos,
00109 UINT32 fission_level,
00110 const char* message)
00111 {
00112 printf("#### Fission(%d:%d): %s\n",
00113 Srcpos_To_Line(srcpos), fission_level, message);
00114
00115 }
00116
00117 static void fission_analysis_info(
00118 BOOL success,
00119 SRCPOS srcpos,
00120 UINT32 fission_level,
00121 const char* message)
00122 {
00123 if (success)
00124 fprintf(LNO_Analysis,"( LNO_Fission_Success ");
00125 else
00126 fprintf(LNO_Analysis,"( LNO_Fission_Failure ");
00127
00128 fprintf(LNO_Analysis,"(%s %d) %d \"%s\" )\n",
00129 Cur_PU_Name, Srcpos_To_Line(srcpos), fission_level, message);
00130 }
00131
00132 static void fission_tlog_info(
00133 FISSION_FUSION_STATUS status,
00134 WN* loop,
00135 UINT32 level,
00136 const char* message)
00137 {
00138 char in_string[30];
00139 char out_string[30];
00140 SRCPOS srcpos=WN_Get_Linenum(loop);
00141 sprintf(in_string,"%d %d", Srcpos_To_Line(srcpos), level);
00142 sprintf(out_string,"%d", status);
00143 Generate_Tlog("LNO","fission", Srcpos_To_Line(srcpos),
00144 ST_name(WN_st(WN_index(loop))), in_string, out_string, message);
00145 }
00146
00147
00159 extern void
00160 Separate(WN* in_loop,WN* in_stmt, UINT8 level, WN** new_loop, BOOL create_empty_loop)
00161 {
00162
00163 WN* loop_body1;
00164 WN* loop_body2;
00165 WN* wn1;
00166 WN* wn2;
00167
00168 FmtAssert(WN_opcode(in_loop)==OPC_DO_LOOP,
00169 ("non-loop input node in Separate()\n") );
00170 if (in_stmt)
00171 FmtAssert(LWN_Get_Parent(LWN_Get_Parent(in_stmt))==in_loop,
00172 ("Separate point not at the first level in the loop in Separate()\n") );
00173
00174 if (!in_stmt && !create_empty_loop) {
00175 Is_True(0, ("Null stmt passed into LNO:Separate()\n"));
00176 return;
00177 }
00178
00179
00180 if (in_stmt && !create_empty_loop && (WN_next(in_stmt) == NULL)) {
00181
00182 *new_loop=NULL;
00183 return;
00184 }
00185
00186
00187 *new_loop =LWN_CreateDO (
00188 LWN_Copy_Tree(WN_index(in_loop),TRUE,LNO_Info_Map),
00189 LWN_Copy_Tree(WN_start(in_loop),TRUE,LNO_Info_Map),
00190 LWN_Copy_Tree(WN_end(in_loop),TRUE,LNO_Info_Map),
00191 LWN_Copy_Tree(WN_step(in_loop),TRUE,LNO_Info_Map),
00192 WN_CreateBlock()
00193 );
00194
00195 if (!Array_Dependence_Graph->
00196 Add_Deps_To_Copy_Block(WN_start(in_loop), WN_start(*new_loop), FALSE))
00197 LNO_Erase_Dg_From_Here_In(in_loop,Array_Dependence_Graph);
00198 if (!Array_Dependence_Graph->
00199 Add_Deps_To_Copy_Block(WN_end(in_loop), WN_end(*new_loop), FALSE))
00200 LNO_Erase_Dg_From_Here_In(in_loop,Array_Dependence_Graph);
00201 if (!Array_Dependence_Graph->
00202 Add_Deps_To_Copy_Block(WN_step(in_loop), WN_step(*new_loop), FALSE))
00203 LNO_Erase_Dg_From_Here_In(in_loop,Array_Dependence_Graph);
00204
00205 LWN_Copy_Linenumber(WN_do_body(in_loop),WN_do_body(*new_loop));
00206
00207
00208
00209 loop_body1=WN_do_body(in_loop);
00210 loop_body2=WN_do_body(*new_loop);
00211
00212
00213 if (in_stmt){
00214 if (WN_next(in_stmt)!=NULL){
00215 WN_first(loop_body2)=WN_next(in_stmt);
00216 WN_last(loop_body2)=WN_last(loop_body1);
00217 WN_last(loop_body1)=in_stmt;
00218 WN_prev(WN_first(loop_body2))=NULL;
00219 WN_next(WN_last(loop_body2))=NULL;
00220 WN_next(WN_last(loop_body1))=NULL;
00221 }
00222 } else {
00223 WN_first(loop_body2)=WN_first(loop_body1);
00224 WN_last(loop_body2)=WN_last(loop_body1);
00225 WN_first(loop_body1)=NULL;
00226 WN_last(loop_body1)=NULL;
00227 }
00228
00229
00230 for (wn1=WN_first(loop_body2); wn1; wn1=WN_next(wn1)) {
00231 LWN_Set_Parent(wn1,loop_body2);
00232 }
00233
00234 wn1 = in_loop;
00235 wn2 = *new_loop;
00236
00237 LWN_Copy_Linenumber(wn1, wn2);
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254 for (INT i=1; i<level; i++) {
00255 WN* block=WN_CreateBlock();
00256 WN_first(block)=WN_last(block)=wn2;
00257 WN_prev(wn2)=WN_next(wn2)=NULL;
00258 LWN_Set_Parent(wn2,block);
00259
00260 for (WN* stmt=WN_next(wn1); stmt; stmt=WN_next(stmt)) {
00261 LWN_Extract_From_Block(stmt);
00262 LWN_Insert_Block_After(block,wn2,stmt);
00263 LWN_Set_Parent(stmt,block);
00264 wn2=stmt;
00265 }
00266
00267 wn1 = LWN_Get_Parent(LWN_Get_Parent(wn1));
00268 FmtAssert(WN_opcode(wn1)==OPC_DO_LOOP,
00269 ("Not enough level to separate\n"));
00270
00271 wn2 =LWN_CreateDO (
00272 LWN_Copy_Tree(WN_index(wn1),TRUE,LNO_Info_Map),
00273 LWN_Copy_Tree(WN_start(wn1),TRUE,LNO_Info_Map),
00274 LWN_Copy_Tree(WN_end(wn1),TRUE,LNO_Info_Map),
00275 LWN_Copy_Tree(WN_step(wn1),TRUE,LNO_Info_Map),
00276 block
00277 );
00278
00279 if (!Array_Dependence_Graph->
00280 Add_Deps_To_Copy_Block(WN_start(wn1), WN_start(wn2), FALSE))
00281 LNO_Erase_Dg_From_Here_In(wn1,Array_Dependence_Graph);
00282 if (!Array_Dependence_Graph->
00283 Add_Deps_To_Copy_Block(WN_end(wn1), WN_end(wn2), FALSE))
00284 LNO_Erase_Dg_From_Here_In(wn1,Array_Dependence_Graph);
00285 if (!Array_Dependence_Graph->
00286 Add_Deps_To_Copy_Block(WN_step(wn1), WN_step(wn2), FALSE))
00287 LNO_Erase_Dg_From_Here_In(wn1,Array_Dependence_Graph);
00288
00289
00290 LWN_Copy_Linenumber(wn1, wn2);
00291
00292 }
00293 LWN_Insert_Block_After(LWN_Get_Parent(wn1),
00294 wn1,
00295 wn2
00296 );
00297
00298 }
00299
00300
00301
00302
00303
00304
00305
00306
00307 void Separate_And_Update(
00308 WN* in_loop,
00309 DYN_ARRAY<FF_STMT_LIST>& loop,
00310 UINT fission_level,
00311 BOOL rename_loop_var)
00312 {
00313
00314 MEM_POOL_Push(&FISSION_default_pool);
00315 UINT total_loops=loop.Lastidx()+1;
00316
00317 WN*** wn_starts=CXX_NEW_ARRAY(WN**, fission_level, &FISSION_default_pool);
00318 WN*** wn_ends=CXX_NEW_ARRAY(WN**, fission_level, &FISSION_default_pool);
00319 WN*** wn_steps=CXX_NEW_ARRAY(WN**, fission_level, &FISSION_default_pool);
00320
00321 INT i;
00322 for (i=0; i<fission_level; i++) {
00323
00324 wn_starts[i]=CXX_NEW_ARRAY(WN*, total_loops, &FISSION_default_pool);
00325 wn_ends[i]=CXX_NEW_ARRAY(WN*, total_loops, &FISSION_default_pool);
00326 wn_steps[i]=CXX_NEW_ARRAY(WN*, total_loops, &FISSION_default_pool);
00327
00328 }
00329
00330
00331
00332
00333 WN*** new_loop=CXX_NEW_ARRAY(WN**,fission_level,&FISSION_default_pool);
00334
00335 DO_LOOP_INFO* loop_info[LNO_MAX_DO_LOOP_DEPTH];
00336 WN* wn=in_loop;
00337 WN* outer_most_loop;
00338
00339 for (i=fission_level-1; i>=0; i--) {
00340 new_loop[i]=CXX_NEW_ARRAY(WN*,total_loops,&FISSION_default_pool);
00341 new_loop[i][0]=wn;
00342 loop_info[i]=(DO_LOOP_INFO *)WN_MAP_Get(LNO_Info_Map,wn);
00343
00344 wn_starts[i][0]=WN_kid0(WN_start(wn));
00345 wn_ends[i][0]=WN_end(wn);
00346 wn_steps[i][0]=WN_kid0(WN_step(wn));
00347
00348 if (i==0)
00349 outer_most_loop=wn;
00350
00351 wn=LWN_Get_Parent(LWN_Get_Parent(wn));
00352 }
00353
00354 BOOL has_calls_or_gotos_or_inner_loops = FALSE;
00355 if (loop_info[fission_level-1]->Has_Calls ||
00356 loop_info[fission_level-1]->Has_Gotos ||
00357 !loop_info[fission_level-1]->Is_Inner) {
00358 has_calls_or_gotos_or_inner_loops = TRUE;
00359 }
00360
00361 for (i=total_loops-1; i>0; i--) {
00362
00363 WN* loop_body = WN_do_body(in_loop);
00364 WN* first_stmt = loop[i].Head()->Get_Stmt();
00365 FF_STMT_NODE* stmt_node_p;
00366 while(stmt_node_p = loop[i].Remove_Headnode()) {
00367 WN* stmt = stmt_node_p->Get_Stmt();
00368
00369 stmt = LWN_Extract_From_Block(stmt);
00370
00371 LWN_Insert_Block_Before(loop_body,NULL,stmt);
00372
00373 }
00374
00375 Separate(in_loop, WN_prev(first_stmt), fission_level, &wn);
00376
00377
00378
00379
00380 DO_LOOP_INFO* new_loop_info =
00381 CXX_NEW(DO_LOOP_INFO(loop_info[fission_level-1],&LNO_default_pool),
00382 &LNO_default_pool);
00383 WN_MAP_Set(LNO_Info_Map, wn, (void*)new_loop_info);
00384 if (has_calls_or_gotos_or_inner_loops)
00385 FF_Mark_Inner_Loop_Info(wn);
00386
00387 wn_starts[fission_level-1][i]=WN_kid0(WN_start(wn));
00388 wn_ends[fission_level-1][i]=WN_end(wn);
00389 wn_steps[fission_level-1][i]=WN_kid0(WN_step(wn));
00390 new_loop[fission_level-1][i]=wn;
00391
00392
00393 for (INT j=fission_level-2; j>=0; j--) {
00394 wn = LWN_Get_Parent(LWN_Get_Parent(wn));
00395 DO_LOOP_INFO* outer_loop_info =
00396 CXX_NEW(DO_LOOP_INFO(loop_info[j],&LNO_default_pool),
00397 &LNO_default_pool);
00398 outer_loop_info->Has_Calls = new_loop_info->Has_Calls ;
00399 outer_loop_info->Has_Unsummarized_Calls =
00400 new_loop_info->Has_Unsummarized_Calls ;
00401 outer_loop_info->Has_Gotos = new_loop_info->Has_Gotos ;
00402 WN_MAP_Set(LNO_Info_Map, wn, (void*)outer_loop_info);
00403
00404 wn_starts[j][i]=WN_kid0(WN_start(wn));
00405 wn_ends[j][i]=WN_end(wn);
00406 wn_steps[j][i]=WN_kid0(WN_step(wn));
00407 new_loop[j][i]=wn;
00408
00409 }
00410 }
00411
00412
00413
00414 if (has_calls_or_gotos_or_inner_loops)
00415 FF_Mark_Inner_Loop_Info(outer_most_loop);
00416
00417 adg->Fission_Dep_Update(new_loop[0][0], total_loops);
00418
00419
00420 wn=in_loop;
00421 for (i=fission_level-1; i>=0; i--, wn = LWN_Get_Parent(LWN_Get_Parent(wn)))
00422 Fission_DU_Update(Du_Mgr,red_manager,wn_starts[i],wn_ends[i],wn_steps[i],
00423 total_loops,new_loop[i]);
00424
00425 if (rename_loop_var)
00426 for (i=0; i<total_loops-1; i++)
00427 for (INT j=0; j<fission_level; j++)
00428 scalar_rename(LWN_Get_Parent(wn_starts[j][i]));
00429
00430 MEM_POOL_Pop(&FISSION_default_pool);
00431 }
00432
00433
00434
00435
00436
00437 static
00438 UINT16 Merge_loop(DYN_ARRAY<FF_STMT_LIST>& loop, mUINT16 opt_flag,
00439 BOOL prev_loop_has_loops_or_regions, BOOL current_loop_has_loops_or_regions)
00440 {
00441
00442 mUINT16 m = loop.Lastidx();
00443
00444 if (opt_flag & FISSION_BIT_PERFECT_NESTING) {
00445
00446 if (!prev_loop_has_loops_or_regions) {
00447 if (!current_loop_has_loops_or_regions) {
00448 loop[m-1].Append_List(&loop[m]);
00449 } else {
00450 m=loop.Newidx();
00451 loop[m].Clear();
00452 }
00453 } else {
00454 m=loop.Newidx();
00455 loop[m].Clear();
00456 }
00457 } else if (opt_flag & FISSION_BIT_SINGLY_NESTING) {
00458
00459 if (prev_loop_has_loops_or_regions && current_loop_has_loops_or_regions) {
00460 m=loop.Newidx();
00461 loop[m].Clear();
00462 } else {
00463 loop[m-1].Append_List(&loop[m]);
00464 }
00465 } else {
00466 m=loop.Newidx();
00467 loop[m].Clear();
00468 }
00469
00470 loop[m].Init((FF_STMT_NODE*)NULL);
00471 return m;
00472
00473 }
00474
00490 static void
00491 Find_Break_Point(WN* in_loop, mUINT16 opt_flag,
00492 SCC_DIRECTED_GRAPH16 *dep_g_p, WN_MAP dep_graph_map,
00493 DYN_ARRAY<FF_STMT_LIST>& loop, MEM_POOL* pool)
00494
00495 {
00496
00497 WN* begin_stmt;
00498 WN* stmt;
00499
00500 VINDEX16 i;
00501 mUINT16 m;
00502 BOOL prev_loop_has_loops_or_regions = TRUE;
00503
00504 BOOL mapping_is_illegal = FALSE;
00505
00506 for ( i=1,
00507 stmt = WN_first(WN_do_body(in_loop));
00508 stmt;
00509 stmt = WN_next(stmt), i++) {
00510 if ((mUINT32)(INTPTR)(WN_MAP_Get(dep_graph_map, stmt)) != i)
00511 mapping_is_illegal = TRUE;
00512 }
00513
00514 if (mapping_is_illegal == TRUE) {
00515 Is_True(0, ("Illegal mapping\n"));
00516 m=loop.Newidx();
00517 loop[m].Init((FF_STMT_NODE*)NULL);
00518 WN* stmt = WN_first(WN_do_body(in_loop));
00519 while (stmt) {
00520 loop[m].Append(stmt, pool);
00521 stmt=WN_next(stmt);
00522 }
00523 return;
00524 }
00525
00526
00527 m=loop.Newidx();
00528 loop[m].Init((FF_STMT_NODE*)NULL);
00529 begin_stmt = WN_first(WN_do_body(in_loop));
00530 while (begin_stmt) {
00531
00532
00533
00534
00535
00536 VINDEX16 sink_v, end_v;
00537 EINDEX16 e;
00538 WN* sink_stmt;
00539
00540 BOOL current_loop_has_loops_or_regions = FALSE;
00541 for (sink_stmt=begin_stmt,
00542 sink_v=(mUINT32)(INTPTR)WN_MAP_Get(dep_graph_map, begin_stmt),
00543
00544 end_v = sink_v;
00545 sink_v <= end_v;
00546 sink_stmt=WN_next(sink_stmt),sink_v++) {
00547
00548
00549
00550 e = dep_g_p->Get_In_Edge(sink_v);
00551 while (e) {
00552 if (dep_g_p->Get_Source(e) > end_v)
00553 end_v = dep_g_p->Get_Source(e);
00554 e = dep_g_p->Get_Next_In_Edge(e);
00555 }
00556 OPCODE opc=WN_opcode(sink_stmt);
00557 if (opc==OPC_DO_LOOP || opc==OPC_REGION ||
00558 opc==OPC_DO_WHILE || opc==OPC_WHILE_DO ||
00559 (opc==OPC_IF && Get_If_Info(sink_stmt)->Contains_Do_Loops))
00560
00561 current_loop_has_loops_or_regions = TRUE;
00562
00563
00564 loop[m].Append(sink_stmt, pool);
00565
00566 }
00567
00568
00569
00570
00571 begin_stmt = sink_stmt;
00572
00573 m=Merge_loop(loop, opt_flag, prev_loop_has_loops_or_regions,
00574 current_loop_has_loops_or_regions);
00575 prev_loop_has_loops_or_regions = current_loop_has_loops_or_regions;
00576
00577 }
00578
00579
00580 loop.Decidx();
00581
00582
00583 }
00584
00594 static void
00595 SCC_reorder(WN* in_loop, mUINT16 opt_flag, SCC_DIRECTED_GRAPH16 *dep_g_p,
00596 WN_MAP dep_graph_map, DYN_ARRAY<FF_STMT_LIST>& loop, MEM_POOL* pool)
00597 {
00598
00599 FF_STMT_LIST *scc;
00600 DYN_ARRAY<VINDEX16> *scc_group;
00601
00602 mUINT16 *level;
00603
00604 mUINT16 m;
00605 mUINT16 i;
00606
00607 SCC_DIRECTED_GRAPH16 *ac_g;
00608
00609 ac_g = dep_g_p->Acyclic_Condensation(pool);
00610
00611 level = CXX_NEW_ARRAY(mUINT16,ac_g->Get_Vertex_Count()+1,
00612 pool);
00613 mUINT16 max_level = ac_g->Get_Level(level);
00614
00615 CXX_DELETE(ac_g, pool);
00616
00617 VINDEX16 total_scc = dep_g_p->Get_Scc_Count();
00618
00619
00620 scc = CXX_NEW_ARRAY(FF_STMT_LIST, total_scc+1, pool);
00621
00622
00623
00624 scc_group =
00625 CXX_NEW_ARRAY(DYN_ARRAY<VINDEX16>, max_level+1, pool);
00626
00627
00628 for (i=0; i<=max_level; i++) {
00629 scc_group[i].Set_Mem_Pool(pool);
00630 }
00631
00632 for (i=1; i<=total_scc; i++) {
00633 mUINT16 j = level[i];
00634 mUINT16 k = scc_group[j].Newidx();
00635
00636 scc_group[j][k] = i;
00637 }
00638
00639 for (WN* stmt = WN_first(WN_do_body(in_loop)); stmt;
00640 stmt = WN_next(stmt)) {
00641
00642
00643
00644
00645
00646
00647
00648
00649 VINDEX16 scc_id;
00650 scc_id = dep_g_p->Get_Scc_Id(
00651 (mUINT32)(INTPTR)WN_MAP_Get(dep_graph_map, stmt));
00652 scc[scc_id].Append(stmt, pool);
00653 }
00654
00655 BOOL prev_loop_has_loops_or_regions;
00656 BOOL current_loop_has_loops_or_regions;
00657
00658 prev_loop_has_loops_or_regions = TRUE;
00659
00660 m=loop.Newidx();
00661 loop[m].Init((FF_STMT_NODE*)NULL);
00662
00663 for (i = 0; i<=max_level; i++) {
00664
00665
00666
00667 for (mUINT16 j = 0; j<=scc_group[i].Lastidx(); j++) {
00668
00669
00670
00671
00672 mUINT16 k = scc_group[i][j];
00673
00674 WN* stmt;
00675 FF_STMT_NODE* stmt_node;
00676
00677 current_loop_has_loops_or_regions = FALSE;
00678 while(stmt_node = scc[k].Remove_Headnode()) {
00679 stmt = stmt_node->Get_Stmt();
00680
00681 OPCODE opc=WN_opcode(stmt);
00682 if (opc==OPC_DO_LOOP || opc==OPC_REGION ||
00683 opc==OPC_DO_WHILE || opc==OPC_WHILE_DO ||
00684 (opc==OPC_IF && Get_If_Info(stmt)->Contains_Do_Loops))
00685 current_loop_has_loops_or_regions = TRUE;
00686
00687 loop[m].Append(stmt, pool);
00688
00689 }
00690
00691 m=Merge_loop(loop, opt_flag, prev_loop_has_loops_or_regions,
00692 current_loop_has_loops_or_regions);
00693 prev_loop_has_loops_or_regions = current_loop_has_loops_or_regions;
00694
00695 }
00696 }
00697
00698 loop.Decidx();
00699
00700 }
00701
00715 extern void
00716 Form_Loops(WN* in_loop, mUINT16 opt_flag, UINT8 fission_level,
00717 FF_STMT_LIST *stl_1, FF_STMT_LIST *stl_2, ARRAY_DIRECTED_GRAPH16* sdg,
00718 DYN_ARRAY<FF_STMT_LIST>& loop, MEM_POOL* pool)
00719 {
00720 WN_MAP dep_graph_map;
00721 WN* stmt;
00722
00723 SCC_DIRECTED_GRAPH16 *dep_g_p =
00724 CXX_NEW(SCC_DIRECTED_GRAPH16(0, 0), pool);
00725
00726 dep_graph_map = WN_MAP_Create(pool);
00727 FmtAssert(dep_graph_map != -1,("Ran out of mappings in Fission"));
00728
00729
00730 for (stmt = WN_first(WN_do_body(in_loop));
00731 stmt; stmt = WN_next(stmt)) {
00732
00733 union {
00734 VINDEX16 v;
00735 void *p;
00736 } v;
00737 v.p = NULL;
00738 v.v = dep_g_p->Add_Vertex();
00739 if (v.v==0) {
00740 DevWarn("Statement scc graph too big");
00741 INT m=loop.Newidx();
00742 loop[m].Clear();
00743 for (WN* stmt1 = WN_first(WN_do_body(in_loop));
00744 stmt1; stmt1 = WN_next(stmt1))
00745 loop[m].Append(stmt1, pool);
00746 WN_MAP_Delete(dep_graph_map);
00747 CXX_DELETE(dep_g_p, pool);
00748 return;
00749 }
00750 WN_MAP_Set(dep_graph_map, stmt, v.p);
00751
00752 }
00753
00754 DO_LOOP_INFO *loop_info;
00755 loop_info = (DO_LOOP_INFO *)WN_MAP_Get(LNO_Info_Map, in_loop);
00756 UINT8 in_loop_level = loop_info->Depth;
00757 for (stmt = WN_first(WN_do_body(in_loop));
00758 stmt; stmt = WN_next(stmt)) {
00759
00760 VINDEX16 v=sdg->Get_Vertex(stmt);
00761 if (v ==0) {
00762 OPCODE opc=WN_opcode(stmt);
00763 if (opc!=OPC_LABEL && opc!=OPC_RETURN && opc!=OPC_GOTO
00764 #ifdef KEY
00765 && opc!=OPC_GOTO_OUTER_BLOCK
00766 #endif
00767 ) {
00768
00769 DevWarn("Statement dependence graph problem");
00770 INT m=loop.Newidx();
00771 loop[m].Clear();
00772 for (WN* stmt1 = WN_first(WN_do_body(in_loop));
00773 stmt1; stmt1 = WN_next(stmt1))
00774 loop[m].Append(stmt1, pool);
00775 WN_MAP_Delete(dep_graph_map);
00776 CXX_DELETE(dep_g_p, pool);
00777 return;
00778 }
00779 } else {
00780 EINDEX16 e=sdg->Get_Out_Edge(v);
00781 while (e) {
00782
00783 if (sdg->Level(e) >= in_loop_level-fission_level+1) {
00784 VINDEX16 v1 = sdg->Get_Sink(e);
00785 WN* stmt1 = sdg->Get_Wn(v1);
00786
00787 EINDEX16 e1=dep_g_p->Add_Unique_Edge(
00788 (mUINT32)(INTPTR)WN_MAP_Get(dep_graph_map, stmt),
00789 (mUINT32)(INTPTR)WN_MAP_Get(dep_graph_map, stmt1));
00790
00791 if (e1==0) {
00792 DevWarn("Statement scc graph too big");
00793 INT m=loop.Newidx();
00794 loop[m].Clear();
00795 for (WN* stmt1 = WN_first(WN_do_body(in_loop));
00796 stmt1; stmt1 = WN_next(stmt1))
00797 loop[m].Append(stmt1, pool);
00798 WN_MAP_Delete(dep_graph_map);
00799 CXX_DELETE(dep_g_p, pool);
00800 return;
00801 }
00802 }
00803 e = sdg->Get_Next_Out_Edge(e);
00804 }
00805 }
00806
00807 }
00808
00809
00810
00811
00812
00813
00814
00815
00816 if (stl_1 && stl_2) {
00817 FF_STMT_NODE *stmt_node;
00818 WN* stmt1;
00819
00820 FF_STMT_ITER stmt_iter_1(stl_1);
00821 FF_STMT_ITER stmt_iter_2(stl_2);
00822
00823 stmt_node = stmt_iter_1.First();
00824 if (stmt_node)
00825 stmt = stmt_node->Get_Stmt();
00826 FmtAssert(LWN_Get_Parent(LWN_Get_Parent(stmt))==in_loop,
00827 ("Statement not a immediate child of loop in Form_Loops\n"));
00828
00829 for (stmt_node = stmt_iter_1.Next();
00830 stmt_node; stmt_node = stmt_iter_1.Next()) {
00831 stmt1 = stmt_node->Get_Stmt();
00832 EINDEX16 e1=dep_g_p->Add_Unique_Edge(
00833 (mUINT32)(INTPTR)WN_MAP_Get(dep_graph_map, stmt),
00834 (mUINT32)(INTPTR)WN_MAP_Get(dep_graph_map, stmt1));
00835 EINDEX16 e2=dep_g_p->Add_Unique_Edge(
00836 (mUINT32)(INTPTR)WN_MAP_Get(dep_graph_map, stmt1),
00837 (mUINT32)(INTPTR)WN_MAP_Get(dep_graph_map, stmt));
00838 if (e1==0 || e2==0) {
00839 DevWarn("Statement scc graph too big");
00840 INT m=loop.Newidx();
00841 loop[m].Clear();
00842 for (WN* stmt1 = WN_first(WN_do_body(in_loop));
00843 stmt1; stmt1 = WN_next(stmt1))
00844 loop[m].Append(stmt1, pool);
00845 WN_MAP_Delete(dep_graph_map);
00846 CXX_DELETE(dep_g_p, pool);
00847 return;
00848 }
00849 stmt = stmt1;
00850 FmtAssert(LWN_Get_Parent(LWN_Get_Parent(stmt))==in_loop,
00851 ("Statement not a immediate child of loop in Form_Loops\n"));
00852 }
00853
00854 stmt_node = stmt_iter_2.First();
00855 if (stmt_node)
00856 stmt = stmt_node->Get_Stmt();
00857 FmtAssert(LWN_Get_Parent(LWN_Get_Parent(stmt))==in_loop,
00858 ("Statement not a immediate child of loop in Form_Loops\n"));
00859
00860 for (stmt_node = stmt_iter_2.Next();
00861 stmt_node; stmt_node = stmt_iter_2.Next()) {
00862 stmt1 = stmt_node->Get_Stmt();
00863 EINDEX16 e1=dep_g_p->Add_Unique_Edge(
00864 (mUINT32)(INTPTR)WN_MAP_Get(dep_graph_map, stmt),
00865 (mUINT32)(INTPTR)WN_MAP_Get(dep_graph_map, stmt1));
00866 EINDEX16 e2=dep_g_p->Add_Unique_Edge(
00867 (mUINT32)(INTPTR)WN_MAP_Get(dep_graph_map, stmt1),
00868 (mUINT32)(INTPTR)WN_MAP_Get(dep_graph_map, stmt));
00869 if (e1==0 || e2==0) {
00870 DevWarn("Statement scc graph too big");
00871 INT m=loop.Newidx();
00872 loop[m].Clear();
00873 for (WN* stmt1 = WN_first(WN_do_body(in_loop));
00874 stmt1; stmt1 = WN_next(stmt1))
00875 loop[m].Append(stmt1, pool);
00876 WN_MAP_Delete(dep_graph_map);
00877 CXX_DELETE(dep_g_p, pool);
00878 return;
00879 }
00880 stmt = stmt1;
00881 FmtAssert(LWN_Get_Parent(LWN_Get_Parent(stmt))==in_loop,
00882 ("Statement not a immediate child of loop in Form_Loops\n"));
00883 }
00884 }
00885
00886 if (opt_flag & FISSION_BIT_STMT_REORDERING) {
00887
00888 SCC_reorder(in_loop, opt_flag, dep_g_p, dep_graph_map, loop, pool);
00889
00890 } else {
00891
00892
00893 Find_Break_Point(in_loop, opt_flag, dep_g_p, dep_graph_map,
00894 loop, pool);
00895
00896 }
00897
00898 WN_MAP_Delete(dep_graph_map);
00899
00900 CXX_DELETE(dep_g_p, pool);
00901
00902 }
00903
00914 UINT32
00915 Fission_Test(
00916 WN* in_loop, mUINT16 opt_flag, UINT8 fission_level,
00917 WN_MAP loop_map, FF_STMT_LIST *stl_1, FF_STMT_LIST *stl_2)
00918 {
00919 WN* stmt;
00920 FF_STMT_NODE *stmt_node_p;
00921
00922 FmtAssert(WN_opcode(in_loop)==OPC_DO_LOOP,
00923 ("non-loop input node in Fission_Test()\n") );
00924
00925 if (((DO_LOOP_INFO *)WN_MAP_Get(LNO_Info_Map, in_loop))->Depth+1<
00926 fission_level) {
00927 Is_True(0,("Loop level not deep enough for fission with level %d\n",
00928 fission_level));
00929 return 1;
00930 }
00931
00932 SRCPOS srcpos=WN_Get_Linenum(in_loop);
00933
00934 WN* wn = in_loop;
00935 WN* outer_most_loop = in_loop;
00936
00937 INT i;
00938 for (i=1; i<fission_level; i++) {
00939 outer_most_loop = LWN_Get_Parent(LWN_Get_Parent(outer_most_loop));
00940 if (WN_opcode(outer_most_loop)!=OPC_DO_LOOP) {
00941 Is_True(0,("Non-perfect loop for fission\n"));
00942 return 1;
00943 }
00944 }
00945
00946 if (!Do_Loop_Is_Good(outer_most_loop) || Do_Loop_Has_Calls(outer_most_loop)
00947 || Do_Loop_Has_Gotos(outer_most_loop)) {
00948
00949 if (LNO_Verbose)
00950 fission_verbose_info(FALSE,srcpos,fission_level,
00951 "Loops containing calls, exits, bad mem, or gotos cannot be fissioned.");
00952 if (LNO_Analysis)
00953 fission_analysis_info(FALSE,srcpos,fission_level,
00954 "Loops containing calls, exits, bad mem, or gotos cannot be fissioned.");
00955 if ( LNO_Tlog )
00956 fission_tlog_info(Failed, in_loop, fission_level,
00957 "Loops containing calls, exits, bad mem, or gotos cannot be fissioned.");
00958
00959 return 1;
00960 }
00961
00962 MEM_POOL_Push(&FISSION_default_pool);
00963
00964 DYN_ARRAY<FF_STMT_LIST> loop(&FISSION_default_pool);
00965
00966 WN_MAP sdm=WN_MAP_Create(&FISSION_default_pool);
00967
00968 ARRAY_DIRECTED_GRAPH16* sdg=Build_Statement_Dependence_Graph(
00969 outer_most_loop, red_manager, adg, sdm,
00970 &FISSION_default_pool);
00971 Statement_Dependence_Graph = sdg;
00972 if (sdg==NULL) {
00973 DevWarn("Statement dependence graph problem");
00974 loop.Free_array();
00975 WN_MAP_Delete(sdm);
00976 MEM_POOL_Pop(&FISSION_default_pool);
00977 return 1;
00978 }
00979
00980
00981
00982 for (i=1; i<fission_level; i++) {
00983 WN* block = LWN_Get_Parent(wn);
00984 WN2INT* up_hash_table=
00985 CXX_NEW(WN2INT(50, &FISSION_default_pool),&FISSION_default_pool);
00986 WN* stmt = 0;
00987 for (stmt = WN_first(block); stmt && stmt != WN_next(wn);
00988 stmt=WN_next(stmt)) {
00989 up_hash_table->Enter(stmt, 1);
00990 }
00991
00992 for (stmt=wn; stmt; stmt=WN_next(stmt)) {
00993
00994 EINDEX16 dep_e = sdg->Get_Out_Edge(sdg->Get_Vertex(stmt));
00995 while (dep_e) {
00996 VINDEX16 source_v=sdg->Get_Source(dep_e);
00997 VINDEX16 sink_v=sdg->Get_Sink(dep_e);
00998 WN* source_wn=sdg->Get_Wn(source_v);
00999 WN* sink_wn=sdg->Get_Wn(sink_v);
01000 if (up_hash_table->Find(sink_wn)==1)
01001 if (source_v!=sink_v) {
01002 if (LNO_Verbose || LNO_Analysis) {
01003 char message[200];
01004 sprintf(message,
01005 "Fission failed due to dependence from line %d to line %d.",
01006 Srcpos_To_Line(LWN_Get_Linenum(source_wn)),
01007 Srcpos_To_Line(LWN_Get_Linenum(sink_wn)));
01008 if (LNO_Verbose)
01009 fission_verbose_info(FALSE,srcpos,fission_level,message);
01010 if (LNO_Analysis)
01011 fission_analysis_info(FALSE,srcpos,fission_level,message);
01012 if ( LNO_Tlog )
01013 fission_tlog_info(Failed, in_loop, fission_level, message);
01014 }
01015 loop.Free_array();
01016 CXX_DELETE(sdg,&FISSION_default_pool);
01017 WN_MAP_Delete(sdm);
01018 MEM_POOL_Pop(&FISSION_default_pool);
01019 return 1;
01020 }
01021 dep_e = sdg->Get_Next_Out_Edge(dep_e);
01022 }
01023
01024 }
01025
01026 wn = LWN_Get_Parent(LWN_Get_Parent(wn));
01027 }
01028
01029 Form_Loops(in_loop,opt_flag,fission_level, stl_1, stl_2, sdg, loop,
01030 &FISSION_default_pool);
01031
01032 mUINT16 total_loops = loop.Lastidx() + 1;
01033
01034
01035 if (opt_flag & FISSION_BIT_TWO_LOOPS_ONLY) {
01036
01037 for (i=2; i<total_loops; i++) {
01038 while(stmt_node_p = loop[i].Remove_Headnode()) {
01039 loop[1].Append(stmt_node_p);
01040 }
01041 loop.Decidx();
01042 }
01043 total_loops=2;
01044 }
01045
01046
01047 for (i=0; i<total_loops; i++) {
01048
01049 while(stmt_node_p = loop[i].Remove_Headnode()) {
01050 stmt = stmt_node_p->Get_Stmt();
01051 WN_MAP_Set(loop_map, stmt, (void*)(INTPTR)(i+1));
01052 }
01053 }
01054
01055 Statement_Dependence_Graph = NULL;
01056 CXX_DELETE(sdg,&FISSION_default_pool);
01057
01058 loop.Free_array();
01059 WN_MAP_Delete(sdm);
01060
01061 MEM_POOL_Pop(&FISSION_default_pool);
01062
01063 return total_loops;
01064
01065 }
01066
01071 extern FISSION_FUSION_STATUS
01072 Fission(WN* in_loop, WN* stmt, UINT8 fission_level)
01073 {
01074
01075 FmtAssert(WN_opcode(in_loop)==OPC_DO_LOOP,
01076 ("non-loop input node in Fission()\n") );
01077
01078 WN *loop_body = WN_do_body(in_loop);
01079
01080 FmtAssert(LWN_Get_Parent(stmt)==loop_body,
01081 ("Statement not a immediate child of loop in Fission\n"));
01082
01083
01084 if (WN_last(loop_body)==stmt)
01085 return Failed;
01086
01087
01088
01089 FF_STMT_LIST stl_1;
01090 WN *wn;
01091 for (wn=WN_first(loop_body); wn!=stmt; wn=WN_next(wn)) {
01092 stl_1.Append(wn,&FISSION_default_pool);
01093 }
01094 stl_1.Append(stmt,&FISSION_default_pool);
01095 FF_STMT_LIST stl_2;
01096 for (wn=WN_next(stmt); wn; wn=WN_next(wn)) {
01097 stl_2.Append(wn,&FISSION_default_pool);
01098 }
01099
01100
01101 return Fission(in_loop, OPT_FLAG_STMT_SIMPLE, fission_level, -1, 0,
01102 &stl_1, &stl_2);
01103 }
01104
01111 extern FISSION_FUSION_STATUS
01112 Fission(WN* in_loop, WN* stmt1, WN* stmt2, UINT8 fission_level)
01113 {
01114
01115 if (stmt1 == stmt2)
01116 return Failed;
01117
01118 FmtAssert(WN_opcode(in_loop)==OPC_DO_LOOP,
01119 ("non-loop input node in Fission()\n") );
01120
01121 WN *loop_body = WN_do_body(in_loop);
01122
01123 FmtAssert(LWN_Get_Parent(stmt1)==loop_body,
01124 ("Statement not a immediate child of loop in Fission\n"));
01125 FmtAssert(LWN_Get_Parent(stmt2)==loop_body,
01126 ("Statement not a immediate child of loop in Fission\n"));
01127
01128
01129
01130 FF_STMT_LIST stl_1;
01131 WN *wn;
01132 for (wn=WN_first(loop_body); wn!=stmt1; wn=WN_next(wn)) {
01133 stl_1.Append(wn,&FISSION_default_pool);
01134 }
01135 stl_1.Append(stmt1,&FISSION_default_pool);
01136
01137 for (wn=WN_next(stmt1); wn && wn!=stmt2; wn=WN_next(wn));
01138
01139 FmtAssert(wn==stmt2,
01140 ("Incorrect ordering of stmt1 and stmt2 in Fission()\n"));
01141
01142 FF_STMT_LIST stl_2;
01143 for (wn=stmt2; wn; wn=WN_next(wn)) {
01144 stl_2.Append(wn,&FISSION_default_pool);
01145 }
01146
01147
01148
01149 return Fission(in_loop, FISSION_BIT_TWO_LOOPS_ONLY, fission_level, -1, 0,
01150 &stl_1, &stl_2);
01151 }
01152
01161 extern FISSION_FUSION_STATUS
01162 Fission(WN* in_loop, mUINT16 opt_flag, UINT8 fission_level,
01163 WN_MAP loop_map, UINT32 total_loops, FF_STMT_LIST *stl_1, FF_STMT_LIST *stl_2)
01164 {
01165 FF_STMT_NODE *stmt_node_p;
01166 FmtAssert(WN_opcode(in_loop)==OPC_DO_LOOP,
01167 ("non-loop input node in Fission()\n") );
01168
01169 if (Do_Loop_Depth(in_loop)+1<fission_level) {
01170 Is_True(0, ("Loop level not deep enough for fission with level %d\n",
01171 fission_level));
01172 return Failed;
01173 }
01174
01175 DO_LOOP_INFO* dli=Get_Do_Loop_Info(in_loop);
01176 if (dli->Has_Gotos || dli->Has_Calls) {
01177 Is_True(0,("Loop with gotos or calls passed to Fission().\n"));
01178 return Failed;
01179 }
01180 SRCPOS srcpos=WN_Get_Linenum(in_loop);
01181
01182 if (dli->No_Fusion || Do_Loop_Is_Mp(in_loop)) {
01183
01184 if (LNO_Verbose)
01185 fission_verbose_info(FALSE,srcpos,fission_level,
01186 "No_Fusion or MP, Loop cannot be fissioned.");
01187 if (LNO_Analysis)
01188 fission_analysis_info(FALSE,srcpos,fission_level,
01189 "No_Fusion or MP, Loop cannot be fissioned.");
01190 if ( LNO_Tlog )
01191 fission_tlog_info(Failed, in_loop, fission_level,
01192 "No_Fusion or MP, Loop cannot be fissioned.");
01193 return Failed;
01194 }
01195
01196 WN* wn = in_loop;
01197 WN* outer_most_loop = in_loop;
01198
01199 INT i;
01200 for (i=1; i<fission_level; i++) {
01201 outer_most_loop = LWN_Get_Parent(LWN_Get_Parent(outer_most_loop));
01202 FmtAssert (WN_opcode(outer_most_loop)==OPC_DO_LOOP,
01203 ("Non-perfect loop for fission\n"));
01204 }
01205
01206 if (!Do_Loop_Is_Good(outer_most_loop) || Do_Loop_Has_Calls(outer_most_loop)
01207 || Do_Loop_Has_Gotos(outer_most_loop)) {
01208
01209 if (LNO_Verbose)
01210 fission_verbose_info(FALSE,srcpos,fission_level,
01211 "Loops containing calls, exits, or gotos cannot be fissioned.");
01212 if (LNO_Analysis)
01213 fission_analysis_info(FALSE,srcpos,fission_level,
01214 "Loops containing calls, exits, or gotos cannot be fissioned.");
01215 if ( LNO_Tlog )
01216 fission_tlog_info(Failed, in_loop, fission_level,
01217 "Loops containing calls, exits, or gotos cannot be fissioned.");
01218 return Failed;
01219 }
01220
01221 if (WN_next(WN_first(WN_do_body(in_loop)))==NULL) {
01222 if (LNO_Verbose)
01223 fission_verbose_info(FALSE,srcpos,fission_level,
01224 "Loop has only one statement.");
01225 if (LNO_Analysis)
01226 fission_analysis_info(FALSE,srcpos,fission_level,
01227 "Loop has only one statement.");
01228 if ( LNO_Tlog )
01229 fission_tlog_info(Failed, in_loop, fission_level,
01230 "Loop has only one statement.");
01231 return Failed;
01232 }
01233
01234 MEM_POOL_Push(&FISSION_default_pool);
01235
01236 WN_MAP sdm=WN_MAP_Create(&FISSION_default_pool);
01237
01238 ARRAY_DIRECTED_GRAPH16* sdg=Build_Statement_Dependence_Graph(
01239 outer_most_loop, red_manager, adg, sdm,
01240 &FISSION_default_pool);
01241 Statement_Dependence_Graph = sdg;
01242 if (sdg==NULL) {
01243 DevWarn("Statement dependence graph problem");
01244 WN_MAP_Delete(sdm);
01245 MEM_POOL_Pop(&FISSION_default_pool);
01246 if (fission_level==1)
01247 return Failed;
01248 else
01249 return Try_Level_By_Level;
01250 }
01251
01252 DYN_ARRAY<FF_STMT_LIST> loop(&FISSION_default_pool);
01253
01254
01255
01256 for (i=1; i<fission_level; i++) {
01257 WN* block = LWN_Get_Parent(wn);
01258 WN2INT* up_hash_table=
01259 CXX_NEW (WN2INT(50, &FISSION_default_pool), &FISSION_default_pool);
01260 WN* stmt = 0;
01261 for (stmt = WN_first(block); stmt && stmt != WN_next(wn);
01262 stmt=WN_next(stmt)) {
01263 up_hash_table->Enter(stmt, 1);
01264 }
01265
01266 for (stmt=wn; stmt; stmt=WN_next(stmt)) {
01267
01268 VINDEX16 v = sdg->Get_Vertex(stmt);
01269 if (v==0) {
01270 if (LNO_Verbose || LNO_Analysis) {
01271 char message[200];
01272 sprintf(message,
01273 "Fission failed due to conservative dependence from line %d.",
01274 Srcpos_To_Line(LWN_Get_Linenum(stmt)));
01275 if (LNO_Verbose)
01276 fission_verbose_info(FALSE,srcpos,fission_level,message);
01277 if (LNO_Analysis)
01278 fission_analysis_info(FALSE,srcpos,fission_level,message);
01279 if ( LNO_Tlog )
01280 fission_tlog_info(Failed, in_loop, fission_level,message);
01281 }
01282 WN_MAP_Delete(sdm);
01283 loop.Free_array();
01284 CXX_DELETE(sdg,&FISSION_default_pool);
01285 MEM_POOL_Pop(&FISSION_default_pool);
01286 return Try_Level_By_Level;
01287 }
01288 EINDEX16 dep_e = sdg->Get_Out_Edge(sdg->Get_Vertex(stmt));
01289 while (dep_e) {
01290 VINDEX16 source_v=sdg->Get_Source(dep_e);
01291 VINDEX16 sink_v=sdg->Get_Sink(dep_e);
01292 WN* source_wn=sdg->Get_Wn(source_v);
01293 WN* sink_wn=sdg->Get_Wn(sink_v);
01294 if (up_hash_table->Find(sink_wn)==1)
01295 if (source_v!=sink_v) {
01296 if (LNO_Verbose || LNO_Analysis) {
01297 char message[200];
01298 sprintf(message,
01299 "Fission failed due to dependence from line %d to line %d.",
01300 Srcpos_To_Line(LWN_Get_Linenum(source_wn)),
01301 Srcpos_To_Line(LWN_Get_Linenum(sink_wn)));
01302 if (LNO_Verbose)
01303 fission_verbose_info(FALSE,srcpos,fission_level,message);
01304 if (LNO_Analysis)
01305 fission_analysis_info(FALSE,srcpos,fission_level,message);
01306 if ( LNO_Tlog )
01307 fission_tlog_info(Failed, in_loop, fission_level,message);
01308 }
01309 WN_MAP_Delete(sdm);
01310 loop.Free_array();
01311 CXX_DELETE(sdg,&FISSION_default_pool);
01312 MEM_POOL_Pop(&FISSION_default_pool);
01313 return Try_Level_By_Level;
01314 }
01315 dep_e = sdg->Get_Next_Out_Edge(dep_e);
01316 }
01317
01318 }
01319 wn = LWN_Get_Parent(LWN_Get_Parent(wn));
01320 }
01321
01322 BOOL no_input_map = (loop_map== -1);
01323 if (no_input_map) {
01324
01325
01326 Form_Loops(in_loop,opt_flag,fission_level, stl_1, stl_2, sdg,loop,
01327 &FISSION_default_pool);
01328 total_loops = loop.Lastidx() + 1;
01329
01330
01331 if ((opt_flag & FISSION_BIT_TWO_LOOPS_ONLY) && (total_loops>2)) {
01332
01333 for (i=2; i<total_loops; i++) {
01334 while(stmt_node_p = loop[i].Remove_Headnode()) {
01335 loop[1].Append(stmt_node_p);
01336 }
01337 }
01338 for (i=2; i<total_loops; i++)
01339 loop.Decidx();
01340 total_loops=2;
01341 }
01342
01343 } else {
01344
01345 loop.Initidx(total_loops-1);
01346 WN* loop_body = WN_do_body(in_loop);
01347 for (wn=WN_first(loop_body); wn; wn=WN_next(wn)) {
01348 INT loop_id = (INT32)(INTPTR)WN_MAP_Get(loop_map, wn)-1;
01349 loop[loop_id].Append(wn, &FISSION_default_pool);
01350 }
01351
01352 }
01353
01354 if (total_loops==1) {
01355 if (((opt_flag & FISSION_BIT_PERFECT_NESTING) ||
01356 (opt_flag & FISSION_BIT_SINGLY_NESTING)) &&
01357 (Get_Only_Loop_Inside(in_loop,FALSE) || Do_Loop_Is_Inner(in_loop))) {
01358 if (LNO_Verbose)
01359 fission_verbose_info(FALSE,srcpos,fission_level,
01360 "Loop is already in the requested form.");
01361 if (LNO_Analysis)
01362 fission_analysis_info(FALSE,srcpos,fission_level,
01363 "Loop is already in the requested form.");
01364 if ( LNO_Tlog )
01365 fission_tlog_info(Failed, in_loop, fission_level,
01366 "Loop is already in the requested form.");
01367 } else {
01368 if (LNO_Verbose)
01369 fission_verbose_info(FALSE,srcpos,fission_level,
01370 "Failed because of a dependence cycle.");
01371 if (LNO_Analysis)
01372 fission_analysis_info(FALSE,srcpos,fission_level,
01373 "Failed because of a dependence cycle.");
01374 if ( LNO_Tlog )
01375 fission_tlog_info(Failed, in_loop, fission_level,
01376 "Failed because of a dependence cycle.");
01377 }
01378 WN_MAP_Delete(sdm);
01379 loop.Free_array();
01380 CXX_DELETE(sdg,&FISSION_default_pool);
01381 MEM_POOL_Pop(&FISSION_default_pool);
01382 return Failed;
01383 }
01384
01385
01386
01387 INT clone_count = loop.Elements() - 1;
01388 Separate_And_Update(in_loop, loop, fission_level);
01389
01390 if (Prompf_Info != NULL && Prompf_Info->Is_Enabled()) {
01391 WN** wn_clone = CXX_NEW_ARRAY(WN*, clone_count, &PROMPF_pool);
01392 INT loop_count = 0;
01393 WN* wn = 0;
01394 for (wn = in_loop; wn != NULL; wn = LWN_Get_Parent(wn))
01395 if (WN_opcode(wn) == OPC_DO_LOOP && ++loop_count == fission_level)
01396 break;
01397 WN* wn_outer = wn;
01398 INT i = 0;
01399 for (wn = WN_next(wn_outer); i < clone_count; wn = WN_next(wn))
01400 wn_clone[i++] = wn;
01401 STACK<WN*> st_old(&PROMPF_pool);
01402 STACK<WN*> st_new(&PROMPF_pool);
01403 for (i = 0; i < clone_count; i++) {
01404 st_old.Clear();
01405 st_new.Clear();
01406 Prompf_Assign_Ids(wn_outer, wn_clone[i], &st_old, &st_new,
01407 FALSE, fission_level);
01408 INT nloops = st_old.Elements();
01409 if (nloops > 0) {
01410 INT* old_ids = CXX_NEW_ARRAY(INT, nloops, &LNO_local_pool);
01411 INT* new_ids = CXX_NEW_ARRAY(INT, nloops, &LNO_local_pool);
01412 PROMPF_LINES** old_lines = CXX_NEW_ARRAY(PROMPF_LINES*, nloops,
01413 &PROMPF_pool);
01414 PROMPF_LINES** new_lines = CXX_NEW_ARRAY(PROMPF_LINES*, nloops,
01415 &PROMPF_pool);
01416 for (INT i = 0; i < nloops; i++) {
01417 old_ids[i] = WN_MAP32_Get(Prompf_Id_Map, st_old.Bottom_nth(i));
01418 new_ids[i] = WN_MAP32_Get(Prompf_Id_Map, st_new.Bottom_nth(i));
01419 old_lines[i] = CXX_NEW(PROMPF_LINES(st_old.Bottom_nth(i),
01420 &PROMPF_pool), &PROMPF_pool);
01421 new_lines[i] = CXX_NEW(PROMPF_LINES(st_new.Bottom_nth(i),
01422 &PROMPF_pool), &PROMPF_pool);
01423 }
01424 Prompf_Info->Fission(old_ids, old_lines, new_ids, new_lines, nloops);
01425 CXX_DELETE_ARRAY(old_ids, &LNO_local_pool);
01426 CXX_DELETE_ARRAY(new_ids, &LNO_local_pool);
01427 }
01428 }
01429 }
01430
01431 if (LNO_Test_Dump) sdg->Print(stdout);
01432 if (LNO_Test_Dump) adg->Print(stdout);
01433
01434 Statement_Dependence_Graph = NULL;
01435 CXX_DELETE(sdg,&FISSION_default_pool);
01436 WN_MAP_Delete(sdm);
01437 loop.Free_array();
01438 MEM_POOL_Pop(&FISSION_default_pool);
01439
01440 if (total_loops>1) {
01441 if (LNO_Verbose)
01442 fission_verbose_info(TRUE,srcpos,fission_level,
01443 "Successfully fissioned !!");
01444 if (LNO_Analysis)
01445 fission_analysis_info(TRUE,srcpos,fission_level,
01446 "Successfully fissioned !!");
01447 if ( LNO_Tlog )
01448 fission_tlog_info(Succeeded, in_loop, fission_level,
01449 "Successfully fissioned !!");
01450 return Succeeded;
01451 } else
01452 return Failed;
01453
01454 }
01455
01460 extern void Fission_Init()
01461 {
01462 if (!fission_initialized) {
01463 MEM_POOL_Initialize(&FISSION_default_pool,"FISSION_default_pool",FALSE);
01464 MEM_POOL_Push(&FISSION_default_pool);
01465 adg=Array_Dependence_Graph;
01466 fission_initialized=TRUE;
01467 }
01468 }
01469
01470 extern void Fission_Finish()
01471 {
01472 if (fission_initialized) {
01473 MEM_POOL_Pop(&FISSION_default_pool);
01474 MEM_POOL_Delete(&FISSION_default_pool);
01475 fission_initialized=FALSE;
01476 }
01477 }
01478