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
00058
00059
00060
00061
00062
00063 #define __STDC_LIMIT_MACROS
00064 #include <stdint.h>
00065 #ifdef USE_PCH
00066 #include "lno_pch.h"
00067 #endif // USE_PCH
00068 #pragma hdrstop
00069
00070 #ifdef _KEEP_RCS_ID
00071
00072 static char *rcs_id = "$Source: /home/bos/bk/kpro64-pending/be/lno/SCCS/s.fis_gthr.cxx $ $Revision: 1.5 $";
00073 #endif
00074
00075 #include <sys/types.h>
00076 #include <stdlib.h>
00077 #include "defs.h"
00078 #include "wn.h"
00079 #include "wn_map.h"
00080 #include "model.h"
00081 #include "mempool.h"
00082 #include "cxx_memory.h"
00083 #include "lwn_util.h"
00084 #include "ff_utils.h"
00085 #include "scalar_expand.h"
00086 #include "fission.h"
00087 #include "lnopt_main.h"
00088 #include "opt_du.h"
00089 #include "access_vector.h"
00090 #include "btree.h"
00091 #include "reduc.h"
00092 #include "lno_bv.h"
00093 #include "snl.h"
00094 #include "name.h"
00095 #include "inner_fission.h"
00096
00097 #include "targ_sim.h"
00098 #include "config_targ_opt.h"
00099 #include "config_targ.h"
00100 #include "cxx_template.h"
00101 #include "cxx_hash.h"
00102 #include "wintrinsic.h"
00103 #include "stab.h"
00104 #include "fis_gthr.h"
00105 #include "sxlimit.h"
00106 #include "prompf.h"
00107 #include "anl_driver.h"
00108
00109 #pragma weak New_Construct_Id
00110
00111 typedef HASH_TABLE<WN*,VINDEX16> WN2VINDEX;
00112 typedef HASH_TABLE<WN*,UINT> WN2UINT;
00113 typedef HASH_TABLE<WN*,INT> WN2INT;
00114 typedef DYN_ARRAY<UINT> UINT_DYN_ARRAY;
00115 typedef DYN_ARRAY<VINDEX16> VINDEX16_DYN_ARRAY;
00116
00117 #define ESTIMATED_SIZE 100 // used to initialized hash table, etc.
00118 #define Iteration_Count_Threshold 10 // threshold to determine if a loop
00119
00120
00121 extern REDUCTION_MANAGER *red_manager;
00122 static ARRAY_DIRECTED_GRAPH16 *adg;
00123 extern DU_MANAGER *Du_Mgr;
00124
00125 static MEM_POOL PHASE25_default_pool;
00126 static INT index_counter = 0;
00127 static INT64 access_counter = 0;
00128
00129 extern "C" {
00130 void dump_tree (WN *wn);
00131 void dump_wn (WN *wn);
00132 }
00133
00134 static BOOL has_unbalanced_if(WN *loop)
00135 {
00136 Is_True(WN_opcode(loop) == OPC_DO_LOOP, ("loop must be an OPC_DO_LOOP"));
00137
00138 for (WN* stmt=WN_first(WN_do_body(loop)); stmt; stmt=WN_next(stmt)){
00139 if ((WN_opcode(stmt)==OPC_IF) && WN_else_is_empty(stmt))
00140 return TRUE;
00141 }
00142
00143 return FALSE;
00144 }
00145
00146 static
00147 void Gather_Scatter_Walk(WN *wn) {
00148 OPCODE opc=WN_opcode(wn);
00149
00150 if (!OPCODE_is_scf(opc))
00151 return;
00152 else if (opc==OPC_DO_LOOP) {
00153 if (Do_Loop_Is_Good(wn) && Do_Loop_Is_Inner(wn) &&
00154 !Do_Loop_Has_Gotos(wn) &&
00155 !Do_Loop_Has_Calls(wn) && !Do_Loop_Is_Mp(wn) && has_unbalanced_if(wn)){
00156 Fiss_Gather_Inner_Loop(wn);
00157 } else
00158 Gather_Scatter_Walk(WN_do_body(wn));
00159 } else if (opc==OPC_BLOCK)
00160 for (WN* stmt=WN_first(wn); stmt;) {
00161 Gather_Scatter_Walk(stmt);
00162 stmt = WN_next(stmt);
00163 }
00164 else
00165 for (UINT kidno=0; kidno<WN_kid_count(wn); kidno++) {
00166 Gather_Scatter_Walk(WN_kid(wn,kidno));
00167 }
00168 }
00169
00170
00171
00172 extern void Fiss_Gather_Loop(WN* func_nd,
00173 ARRAY_DIRECTED_GRAPH16 *array_dependence_graph)
00174 {
00175 adg = array_dependence_graph;
00176 MEM_POOL_Initialize(&PHASE25_default_pool, "PHASE25_default_pool", FALSE);
00177 MEM_POOL_Push(&PHASE25_default_pool);
00178 Gather_Scatter_Walk(func_nd);
00179 MEM_POOL_Pop(&PHASE25_default_pool);
00180 MEM_POOL_Delete(&PHASE25_default_pool);
00181 }
00182
00183
00184
00185
00186 static void separate_loop_by_scc
00187 (
00188 UINT_DYN_ARRAY* new_loops,
00189 FF_STMT_LIST* scc,
00190 WN* loop,
00191 WN* result_loops[],
00192 WN* if_handles[],
00193 BOOL first_loop_empty=FALSE)
00194 {
00195 WN* body=WN_do_body(loop);
00196 UINT total_loops= new_loops->Elements();
00197 UINT *loop_size=CXX_NEW_ARRAY(UINT,total_loops,&PHASE25_default_pool);
00198
00199 UINT i = 0;
00200 if (first_loop_empty){
00201 loop_size[0] = 0;
00202 i = 1;
00203 }
00204
00205
00206 for (; i<total_loops; i++) {
00207 UINT seed_scc=(*new_loops)[i];
00208 UINT total_stmt=0;
00209 FF_STMT_ITER s_iter(&scc[seed_scc]);
00210 for (FF_STMT_NODE* stmt_node = s_iter.First(); !s_iter.Is_Empty();
00211 stmt_node=s_iter.Next()) {
00212 WN* stmt=stmt_node->Get_Stmt();
00213 LWN_Insert_Block_Before(body,NULL,LWN_Extract_From_Block(stmt));
00214 total_stmt++;
00215 }
00216 loop_size[i]=total_stmt;
00217 }
00218
00219
00220 if (total_loops>1) {
00221 BOOL has_calls_or_gotos_or_inner_loops = FALSE;
00222 DO_LOOP_INFO* loop_info=Get_Do_Loop_Info(loop, FALSE);
00223 if (loop_info->Has_Calls || loop_info->Has_Gotos || !loop_info->Is_Inner) {
00224 has_calls_or_gotos_or_inner_loops = TRUE;
00225 }
00226
00227 WN* tmp_loop1=loop;
00228 WN** wn_starts=CXX_NEW_ARRAY(WN*, total_loops, &PHASE25_default_pool);
00229 WN** wn_ends=CXX_NEW_ARRAY(WN*, total_loops, &PHASE25_default_pool);
00230 WN** wn_steps=CXX_NEW_ARRAY(WN*, total_loops, &PHASE25_default_pool);
00231 WN** new_loops=CXX_NEW_ARRAY(WN*, total_loops, &PHASE25_default_pool);
00232
00233 wn_starts[0]=WN_kid0(WN_start(tmp_loop1));
00234 wn_ends[0]=WN_end(tmp_loop1);
00235 wn_steps[0]=WN_kid0(WN_step(tmp_loop1));
00236 new_loops[0]=loop;
00237 result_loops[0]=loop;
00238 WN* stmt=WN_first(body);
00239
00240 for (i=0; i<total_loops-1; i++) {
00241
00242 INT size=loop_size[i];
00243
00244 for (INT j=0; j<size; j++)
00245 stmt=WN_next(stmt);
00246
00247 WN* tmp_loop2;
00248 Separate(tmp_loop1, WN_prev(stmt), 1, &tmp_loop2, (i==0 && first_loop_empty));
00249 LWN_Parentize(tmp_loop2);
00250 DO_LOOP_INFO* new_loop_info =
00251 CXX_NEW(DO_LOOP_INFO(loop_info,&LNO_default_pool), &LNO_default_pool);
00252 Set_Do_Loop_Info(tmp_loop2,new_loop_info);
00253 if (has_calls_or_gotos_or_inner_loops) {
00254
00255
00256 }
00257 wn_starts[i+1]=WN_kid0(WN_start(tmp_loop2));
00258 wn_ends[i+1]=WN_end(tmp_loop2);
00259 wn_steps[i+1]=WN_kid0(WN_step(tmp_loop2));
00260 new_loops[i+1]=tmp_loop2;
00261 result_loops[i+1] = tmp_loop2;
00262
00263
00264 WN *do_body = WN_do_body(tmp_loop2);
00265 WN *if_stmt = WN_first(do_body);
00266 WN *then_body = WN_then(if_stmt);
00267
00268 if (WN_prev(if_stmt)!=NULL) {
00269 stmt = WN_prev(if_stmt);
00270 } else
00271 stmt = WN_first(body);
00272
00273 WN* ins_loc = WN_prev(if_stmt);
00274 LWN_Extract_From_Block(if_stmt);
00275
00276
00277 LWN_Copy_Frequency(do_body,then_body);
00278 WN* kid;
00279 while ((kid = WN_first(then_body)) != NULL) {
00280 LWN_Insert_Block_After(do_body,ins_loc,LWN_Extract_From_Block(kid));
00281 ins_loc=kid;
00282 }
00283
00284 stmt = ins_loc;
00285
00286
00287 LWN_Insert_Block_Before(WN_do_body(result_loops[0]), NULL, if_stmt);
00288
00289
00290 if_handles[i+1] = if_stmt;
00291
00292 tmp_loop1=tmp_loop2;
00293 }
00294
00295 if (Prompf_Info != NULL && Prompf_Info->Is_Enabled()) {
00296 INT old_id = WN_MAP32_Get(Prompf_Id_Map, new_loops[0]);
00297 PROMPF_LINES* old_lines = CXX_NEW(PROMPF_LINES(new_loops[0],
00298 &PROMPF_pool), &PROMPF_pool);
00299 INT* new_ids = CXX_NEW_ARRAY(INT, total_loops - 1, &PROMPF_pool);
00300 PROMPF_LINES** new_lines = CXX_NEW_ARRAY(PROMPF_LINES*, total_loops - 1,
00301 &PROMPF_pool);
00302 INT i;
00303 for (i = 0; i < total_loops - 1; i++) {
00304 new_ids[i] = New_Construct_Id();
00305 WN_MAP32_Set(Prompf_Id_Map, new_loops[i + 1], new_ids[i]);
00306 }
00307 for (i = 0; i < total_loops - 1; i++)
00308 new_lines[i] = CXX_NEW(PROMPF_LINES(new_loops[i + 1], &PROMPF_pool),
00309 &PROMPF_pool);
00310 Prompf_Info->Gather_Scatter(old_id, old_lines, new_ids, new_lines,
00311 total_loops - 1);
00312 }
00313
00314 Fission_DU_Update(Du_Mgr,red_manager,wn_starts,wn_ends,wn_steps,total_loops,new_loops,TRUE);
00315
00316 adg->Fission_Dep_Update(new_loops[0],total_loops);
00317 } else
00318 result_loops[0]=loop;
00319
00320 if (LNO_Test_Dump)
00321 Print_Def_Use(LWN_Get_Parent(loop), stdout);
00322
00323 }
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334 static void
00335 Gather_Scatter_Scalar_Expand(WN* loop,
00336 WN* inc_ld,
00337 WN* tile_loop,
00338 WN* use_loop,
00339 const DYN_ARRAY<SCALAR_NODE*>& symbol,
00340 const DYN_ARRAY<SCALAR_NODE*>& use_site,
00341 WN* ins_before,
00342 WN** alloc_loop,
00343 WN** dealloc_loop
00344 )
00345
00346 {
00347 FmtAssert(WN_opcode(loop) == OPC_DO_LOOP, ("loop must be an OPC_DO_LOOP"));
00348 FmtAssert(WN_opcode(use_loop) == OPC_DO_LOOP, ("use_loop must be an OPC_DO_LOOP"));
00349
00350 UINT total_var = symbol.Elements();
00351
00352 Is_True(total_var>0,("No scalar to expand \n"));
00353 if (total_var<=0) return;
00354
00355 static INT unique_gs_id = 0;
00356 unique_gs_id = unique_gs_id + total_var;
00357
00358
00359 WN** indxs = CXX_NEW_ARRAY(WN*, total_var, &PHASE25_default_pool);
00360
00361
00362 WN** incxs = CXX_NEW_ARRAY(WN*, total_var, &PHASE25_default_pool);
00363
00364 if (LNO_Verbose){
00365 for (INT i=0; i<total_var; ++i){
00366 fprintf(stdout, "Gather/Scatter scalar expanding variable %s\n",
00367 symbol[i]->_scalar.Name());
00368 fprintf(TFile, "Gather/Scatter scalar expanding variable %s\n",
00369 symbol[i]->_scalar.Name());
00370 }
00371 }
00372
00373
00374
00375
00376
00377 TYPE_ID wtype = symbol[0]->_scalar.Type;
00378 INT sz0 = (wtype == MTYPE_I8 || wtype == MTYPE_U8 ||
00379 wtype == MTYPE_F8 || wtype == MTYPE_C4) ? 8 :
00380 (wtype == MTYPE_I4 || wtype == MTYPE_U4 ||
00381 wtype == MTYPE_F4) ? 4 :
00382 #if defined(TARG_IA64)
00383 (wtype == MTYPE_F10) ? 16 :
00384 #endif
00385 (wtype == MTYPE_FQ || wtype == MTYPE_C8) ? 16 :
00386 #if defined(TARG_IA64)
00387 (wtype == MTYPE_C10 || wtype == MTYPE_CQ) ? 32 :
00388 #else
00389 (wtype == MTYPE_CQ) ? 32 :
00390 #endif
00391 (wtype == MTYPE_I2 || wtype == MTYPE_U2) ? 2 :
00392 (wtype == MTYPE_I1 || wtype == MTYPE_U1) ? 1 : 0 ;
00393
00394 FmtAssert(sz0 > 0, ("Bad type in gather/scatter scalar expansion"));
00395
00396 UINT sz = sz0 * total_var;
00397
00398 TYPE_ID bsztype = Do_Wtype(loop);
00399
00400 WN* bsz = LWN_Make_Icon(Promote_Type(bsztype), sz);
00401
00402 OPCODE opmpy = OPCODE_make_op(OPR_MPY, Promote_Type(bsztype), MTYPE_V);
00403
00404 WN* d = loop;
00405 TYPE_ID ty = WN_desc(WN_start(d));
00406 OPCODE opsubty = OPCODE_make_op(OPR_SUB, Promote_Type(ty), MTYPE_V);
00407 OPCODE opldty = OPCODE_make_op(OPR_LDID, Promote_Type(ty), ty);
00408 OPCODE opaddty = OPCODE_make_op(OPR_ADD, Promote_Type(ty), MTYPE_V);
00409 OPCODE opminty = OPCODE_make_op(OPR_MIN, Promote_Type(ty), MTYPE_V);
00410
00411
00412
00413 WN* bexp = NULL;
00414 if (tile_loop == NULL) {
00415 WN* one = LWN_Make_Icon(Promote_Type(ty), 1);
00416 WN* lb = LWN_Copy_Tree(WN_kid0(WN_start(d)));
00417 LWN_Copy_Def_Use(WN_kid0(WN_start(d)), lb, Du_Mgr);
00418 Upper_Bound_Standardize(WN_end(loop));
00419 WN* ub = LWN_Copy_Tree(SNL_UBexp(WN_end(d)));
00420 LWN_Copy_Def_Use(SNL_UBexp(WN_end(d)), ub, Du_Mgr);
00421 bexp = LWN_CreateExp2(opsubty, ub, LWN_CreateExp2(opsubty, lb, one));
00422 } else {
00423 WN* one = LWN_Make_Icon(Promote_Type(ty), 1);
00424 WN* lb = LWN_Copy_Tree(WN_kid0(WN_start(tile_loop)));
00425 LWN_Copy_Def_Use(WN_kid0(WN_start(tile_loop)), lb, Du_Mgr);
00426 Upper_Bound_Standardize(WN_end(tile_loop));
00427 WN* ub = LWN_Copy_Tree(SNL_UBexp(WN_end(tile_loop)));
00428 LWN_Copy_Def_Use(SNL_UBexp(WN_end(tile_loop)), ub, Du_Mgr);
00429 WN* sb1exp = LWN_CreateExp2(opsubty, ub, LWN_CreateExp2(opsubty, lb, one));
00430 WN* sb2exp = LWN_Make_Icon(Promote_Type(bsztype), (INT) Step_Size(tile_loop, 0));
00431 bexp = LWN_CreateExp2(opminty, sb1exp, sb2exp);
00432 }
00433 WN* bound = LWN_Copy_Tree(bexp);
00434 LWN_Copy_Def_Use(bexp, bound, Du_Mgr);
00435
00436
00437 UINT i;
00438 for (i=0; i<total_var; ++i){
00439 WN* indx_ldid = LWN_CreateLdid(opldty, WN_step(use_loop));
00440 SNL_Add_Du_To_Index_Ldid(use_loop, indx_ldid, Du_Mgr, TRUE);
00441 WN* num_var = LWN_Make_Icon(Promote_Type(bsztype), total_var);
00442
00443 WN* incx_ldid = LWN_Copy_Tree(inc_ld);
00444 LWN_Copy_Def_Use(inc_ld,incx_ldid,Du_Mgr);
00445
00446 WN* indx_con = LWN_Make_Icon(Promote_Type(bsztype), i);
00447 indxs[i] = LWN_CreateExp2(opaddty,
00448 LWN_CreateExp2(opmpy,
00449 num_var,
00450 indx_ldid),
00451 indx_con);
00452
00453 num_var = LWN_Make_Icon(Promote_Type(bsztype), total_var);
00454 indx_con = LWN_Make_Icon(Promote_Type(bsztype), i);
00455 incxs[i] = LWN_CreateExp2(opaddty,
00456 LWN_CreateExp2(opmpy,
00457 num_var,
00458 incx_ldid),
00459 indx_con);
00460 }
00461
00462 bsz = LWN_CreateExp2(opmpy, bsz, LWN_Int_Type_Conversion(bexp, bsztype));
00463 bsz = LWN_Int_Type_Conversion(bsz, Pointer_type);
00464
00465
00466 char gs[3]="gs";
00467
00468 SYMBOL gs_ptrsym;
00469 SE_Symbols_For_SE(&gs_ptrsym, gs, unique_gs_id, wtype);
00470 Update_MP_Local_Var(gs_ptrsym.St(), 0, LWN_Get_Parent(*alloc_loop));
00471 WN* newstdf =
00472 Get_Expansion_Space(gs_ptrsym,bsz,gs,unique_gs_id,wtype,
00473 *alloc_loop,use_loop,*dealloc_loop);
00474
00475
00476 if (!LNO_Use_Malloc) {
00477
00478
00479 *alloc_loop = newstdf;
00480 while (WN_operator(*alloc_loop) != OPR_INTRINSIC_CALL ||
00481 ((WN_intrinsic(*alloc_loop) != INTRN_U8READSTACKPOINTER) &&
00482 (WN_intrinsic(*alloc_loop) != INTRN_U4READSTACKPOINTER))) {
00483 *alloc_loop = WN_prev(*alloc_loop);
00484 }
00485
00486 while (WN_operator(*dealloc_loop) != OPR_INTRINSIC_CALL ||
00487 ((WN_intrinsic(*dealloc_loop) != INTRN_U8I8SETSTACKPOINTER) &&
00488 (WN_intrinsic(*dealloc_loop) != INTRN_U4I4SETSTACKPOINTER))) {
00489 *dealloc_loop = WN_next(*dealloc_loop);
00490 }
00491 }
00492 Is_True(newstdf,("No memory was allocated for scalar expansion \n"));
00493
00494 OPCODE ldop = OPCODE_make_op(OPR_LDID, Pointer_type, Pointer_type);
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511 MEM_POOL_Push(&PHASE25_default_pool);
00512 {
00513 DYN_ARRAY<WN_REFERENCE_INFO> deflist(&PHASE25_default_pool);
00514 DYN_ARRAY<WN_REFERENCE_INFO> uselist(&PHASE25_default_pool);
00515
00516 INT lexcount = 0;
00517
00518
00519
00520
00521
00522
00523
00524 WN * alias_host = NULL;
00525 INT each_var;
00526 for (each_var=0; each_var<total_var; ++each_var){
00527
00528
00529 OPCODE op_array = OPCODE_make_op(OPR_ARRAY, Pointer_type, MTYPE_V);
00530 WN* wn_array = WN_Create(op_array, 1+1+1);
00531
00532 WN_element_size(wn_array) = sz0;
00533 WN_array_base(wn_array) = WN_CreateLdid(ldop, gs_ptrsym.WN_Offset(),
00534 gs_ptrsym.St(),
00535 ST_type(gs_ptrsym.St()));
00536
00537
00538 LWN_Set_Parent(WN_array_base(wn_array), wn_array);
00539 WN_array_index(wn_array,0) = LWN_Copy_Tree(incxs[each_var]);
00540 WN_array_dim(wn_array,0) = LWN_Copy_Tree(bound);
00541 LWN_Set_Parent(WN_array_index(wn_array,0), wn_array);
00542 LWN_Set_Parent(WN_array_dim(wn_array,0), wn_array);
00543 LWN_Copy_Def_Use(incxs[each_var], WN_array_index(wn_array,0),Du_Mgr);
00544 LWN_Copy_Def_Use(bound, WN_array_dim(wn_array,0),Du_Mgr);
00545
00546 WN* one_use = use_site[each_var]->Bottom_nth(0)->Wn;
00547 Is_True(one_use, ("Cannot find the use node of an expanded variable"));
00548
00549 DEF_LIST * defs = Du_Mgr->Ud_Get_Def(one_use);
00550 WN *loop_stmt = (defs) ? defs->Loop_stmt() : NULL;
00551
00552 if (SYMBOL(one_use) == SYMBOL(WN_start(loop))){
00553 loop_stmt = loop;
00554 }
00555
00556
00557 OPCODE loadop = OPCODE_make_op(OPR_LDID, Promote_Type(wtype), wtype);
00558 WN* rhs = LWN_CreateLdid(loadop,one_use);
00559
00560
00561 for (INT each_def=0; each_def<symbol[each_var]->Elements(); ++each_def){
00562 WN* cur_def = symbol[each_var]->Bottom_nth(each_def)->Wn;
00563 Is_True(cur_def,("No definition site for an expanded variable \n"));
00564 Du_Mgr->Add_Def_Use(cur_def,rhs);
00565 Du_Mgr->Ud_Get_Def(rhs)->Set_loop_stmt(loop_stmt);
00566 }
00567
00568 OPCODE storeop = OPCODE_make_op(OPR_ISTORE, MTYPE_V, wtype);
00569 TY_IDX pty = Make_Pointer_Type(Be_Type_Tbl(wtype));
00570 FmtAssert(pty, ("null ty pointer for wtype=%d", wtype));
00571 WN* store = LWN_CreateIstore(storeop, 0, pty, rhs, wn_array);
00572
00573
00574 if (alias_host==NULL) {
00575 Create_unique_pointer_alias(Alias_Mgr, gs_ptrsym.St(),
00576 WN_array_base(wn_array), store);
00577 alias_host = store;
00578 Copy_alias_info(Alias_Mgr, WN_array_base(wn_array), newstdf);
00579 } else {
00580 Copy_alias_info(Alias_Mgr, newstdf, WN_array_base(wn_array));
00581 Copy_alias_info(Alias_Mgr, alias_host, store);
00582 }
00583
00584 Du_Mgr->Add_Def_Use(newstdf, WN_array_base(wn_array));
00585
00586
00587
00588 LWN_Copy_Frequency_Tree(store, ins_before);
00589
00590 LWN_Insert_Block_Before(WN_do_body(loop), ins_before, store);
00591
00592 LWN_Copy_Linenumber(use_loop,store);
00593 INT idx = deflist.Newidx();
00594 deflist[idx].wn = LWN_Get_Parent(wn_array);
00595 deflist[idx].lexcount = lexcount++;
00596
00597
00598
00599
00600 DOLOOP_STACK do_stack(&PHASE25_default_pool);
00601 Build_Doloop_Stack(LWN_Get_Parent(wn_array), &do_stack);
00602 LNO_Build_Access(wn_array, &do_stack, &LNO_default_pool);
00603 VINDEX16 new_sv = adg->Add_Vertex(LWN_Get_Parent(wn_array));
00604 if (new_sv == 0)
00605 LNO_Erase_Dg_From_Here_In(LWN_Get_Parent(wn_array), adg);
00606 }
00607
00608
00609
00610
00611
00612 for (each_var=total_var-1; each_var>=0; --each_var){
00613
00614
00615 OPCODE op_array = OPCODE_make_op(OPR_ARRAY, Pointer_type, MTYPE_V);
00616 WN* wn_array = WN_Create(op_array, 1+1+1);
00617 WN_element_size(wn_array) = sz0;
00618 WN_array_base(wn_array) = WN_CreateLdid(ldop, gs_ptrsym.WN_Offset(),
00619 gs_ptrsym.St(),
00620 ST_type(gs_ptrsym.St()));
00621
00622 Copy_alias_info(Alias_Mgr, newstdf, WN_array_base(wn_array));
00623 Du_Mgr->Add_Def_Use(newstdf, WN_array_base(wn_array));
00624 LWN_Set_Parent(WN_array_base(wn_array), wn_array);
00625
00626 WN_array_index(wn_array,0) = LWN_Copy_Tree(indxs[each_var]);
00627 WN_array_dim(wn_array,0) = LWN_Copy_Tree(bound);
00628
00629 LWN_Set_Parent(WN_array_index(wn_array,0), wn_array);
00630 LWN_Set_Parent(WN_array_dim(wn_array,0), wn_array);
00631 LWN_Copy_Def_Use(indxs[each_var], WN_array_index(wn_array,0),Du_Mgr);
00632 LWN_Copy_Def_Use(bound, WN_array_dim(wn_array,0),Du_Mgr);
00633
00634 OPCODE loadop = OPCODE_make_op(OPR_ILOAD, Promote_Type(wtype), wtype);
00635 TY_IDX wty = Be_Type_Tbl(wtype);
00636 TY_IDX pty = Make_Pointer_Type(Be_Type_Tbl(wtype));
00637 WN* load = LWN_CreateIload(loadop, 0, wty, pty, wn_array);
00638
00639 Is_True(alias_host!=NULL,("No alias info is available\n"));
00640 Copy_alias_info(Alias_Mgr, alias_host, load);
00641
00642
00643
00644
00645
00646
00647 WN* one_use = use_site[each_var]->Bottom_nth(0)->Wn;
00648 Is_True(one_use, ("Cannot find the use node of an expanded variable"));
00649 OPCODE stop = OPCODE_make_op(OPR_STID, MTYPE_V, wtype);
00650 WN* store = LWN_CreateStid(stop,one_use,load);
00651
00652 LWN_Insert_Block_After(WN_do_body(use_loop), NULL, store);
00653 LWN_Copy_Linenumber(use_loop,store);
00654
00655 LWN_Copy_Frequency_Tree(store, WN_do_body(use_loop));
00656
00657
00658 SYMBOL old_sym(store);
00659 char new_name[64];
00660 if (strlen(old_sym.Name())<48)
00661 sprintf(new_name, "%s_gs_rn_%d", old_sym.Name(), index_counter++);
00662 else
00663 sprintf(new_name, "%s_gs_rn_%d", "name_too_long", index_counter++);
00664
00665 SYMBOL new_sym = Create_Preg_Symbol(new_name, wtype);
00666
00667
00668 for (INT each_use=0; each_use<use_site[each_var]->Elements(); ++each_use){
00669 WN* cur_use = use_site[each_var]->Bottom_nth(each_use)->Wn;
00670
00671
00672 DEF_LIST * def_list = Du_Mgr->Ud_Get_Def(cur_use);
00673
00674 def_list->Set_loop_stmt(NULL);
00675
00676 DEF_LIST_ITER iter_def(def_list);
00677 for (DU_NODE* def_node=iter_def.First(); !iter_def.Is_Empty(); ){
00678 WN* def = def_node->Wn();
00679 def_node= (DU_NODE *) iter_def.Next();
00680
00681 WN* stmt_loc = Find_Stmt_Under(def,WN_do_body(use_loop));
00682 if (stmt_loc == NULL){
00683 Du_Mgr->Delete_Def_Use(def,cur_use);
00684 }
00685 }
00686
00687
00688 Du_Mgr->Add_Def_Use(store,cur_use);
00689
00690
00691
00692 if (red_manager && red_manager->Which_Reduction(cur_use) != RED_NONE)
00693 red_manager->Erase(cur_use);
00694
00695 Replace_Symbol(cur_use,old_sym,new_sym,NULL);
00696 Create_alias(Alias_Mgr,cur_use);
00697
00698 }
00699
00700 Replace_Symbol(store,old_sym,new_sym,NULL);
00701 Create_alias(Alias_Mgr,store);
00702
00703 INT idx = uselist.Newidx();
00704 uselist[idx].wn = LWN_Get_Parent(wn_array);
00705 uselist[idx].lexcount = lexcount++;
00706
00707
00708
00709
00710 DOLOOP_STACK do_stack(&PHASE25_default_pool);
00711 Build_Doloop_Stack(LWN_Get_Parent(wn_array), &do_stack);
00712 LNO_Build_Access(wn_array, &do_stack, &LNO_default_pool);
00713 VINDEX16 new_sv = adg->Add_Vertex(LWN_Get_Parent(wn_array));
00714 if (!new_sv)
00715 LNO_Erase_Dg_From_Here_In(LWN_Get_Parent(wn_array), adg);
00716 }
00717
00718
00719 SE_Fix_Dependence(deflist,uselist);
00720
00721
00722 DOLOOP_STACK do_stack(&PHASE25_default_pool);
00723 Build_Doloop_Stack(LWN_Get_Parent(use_loop), &do_stack);
00724 LNO_Build_Access(use_loop, &do_stack, &LNO_default_pool);
00725
00726 for (i = 0; i < total_var; i++) {
00727 LWN_Delete_Tree(indxs[i]);
00728 LWN_Delete_Tree(incxs[i]);
00729 }
00730
00731 LWN_Delete_Tree(bound);
00732
00733 CXX_DELETE_ARRAY(indxs, &PHASE25_default_pool);
00734 CXX_DELETE_ARRAY(incxs, &PHASE25_default_pool);
00735 }
00736
00737 MEM_POOL_Pop(&PHASE25_default_pool);
00738 }
00739
00740
00741 extern INT64 Gather_Scalar_References(WN *wn,
00742 STACK<WN*> *writes,
00743 STACK<WN*> *reads)
00744 {
00745
00746 WN *kid;
00747
00748
00749 if (WN_opcode(wn) == OPC_BLOCK) {
00750 kid = WN_first(wn);
00751 while (kid) {
00752 Gather_Scalar_References(kid,writes,reads);
00753 kid = WN_next(kid);
00754 }
00755 return access_counter;
00756 }
00757
00758 if (OPCODE_is_load(WN_opcode(wn)) ||
00759 OPCODE_is_store(WN_opcode(wn)))
00760 access_counter++;
00761
00762 if (WN_operator(wn)==OPR_LDID && reads!=NULL)
00763 reads->Push(wn);
00764 else if (WN_operator(wn)==OPR_STID && writes!=NULL)
00765 writes->Push(wn);
00766 else {
00767
00768 for (INT kidno=0; kidno<WN_kid_count(wn); kidno++) {
00769 kid = WN_kid(wn,kidno);
00770 Gather_Scalar_References(kid,writes,reads);
00771 }
00772 }
00773
00774 return access_counter;
00775 }
00776
00777
00778 static BOOL Good_for_gath(WN* if_stmt)
00779 {
00780 Is_True(WN_opcode(if_stmt) == OPC_IF, ("stmt must be an OPC_IF \n"));
00781 if (LNO_Gather_Scatter==2) return TRUE;
00782
00783 LWN_ITER* wniter = LWN_WALK_TreeIter(WN_then(if_stmt));
00784 while (wniter){
00785 WN *ref = wniter->wn;
00786 wniter = LWN_WALK_TreeNext(wniter);
00787 if (WN_opcode(ref) == OPC_IF) {
00788 LWN_WALK_Abort(wniter);
00789 return FALSE;
00790 }
00791 }
00792 return TRUE;
00793 }
00794
00795
00796 static BOOL movable_if_test(WN* if_stmt, WN* loop)
00797 {
00798 Is_True(WN_opcode(if_stmt) == OPC_IF, ("stmt must be a OPC_IF \n"));
00799
00800 LWN_ITER* wniter = LWN_WALK_TreeIter(WN_if_test(if_stmt));
00801 while (wniter){
00802 WN *ref = wniter->wn;
00803 wniter = LWN_WALK_TreeNext(wniter);
00804
00805 if (OPCODE_is_load(WN_opcode(ref))){
00806 OPERATOR opr = WN_operator(ref);
00807
00808 if (opr==OPR_LDID){
00809
00810 DEF_LIST* def_list = Du_Mgr->Ud_Get_Def(ref);
00811 DEF_LIST_ITER iter_def(def_list);
00812
00813 for (DU_NODE* def_node=iter_def.First(); !iter_def.Is_Empty();
00814 def_node=(DU_NODE *) iter_def.Next()){
00815
00816
00817 WN* def = def_node->Wn();
00818 Is_True(def,("Null pointer in def-use chain \n"));
00819
00820 WN* stmt_block = Find_Stmt_Under(def,if_stmt);
00821
00822 if (stmt_block != NULL) {
00823 if (wniter)
00824 LWN_WALK_Abort(wniter);
00825 return FALSE;
00826 }
00827 }
00828
00829 } else if ((WN_kid_count(ref)==1) &&
00830 (WN_offset(ref) == 0) &&
00831 (WN_operator(WN_kid0(ref)) == OPR_ARRAY)){
00832
00833 VINDEX16 array_v=adg->Get_Vertex(ref);
00834 Is_True(array_v!=0, ("Array reference on in dependence graph \n"));
00835
00836 EINDEX16 in_edge=adg->Get_In_Edge(array_v);
00837 while (in_edge){
00838 if (adg->Depv_Array(in_edge)->Max_Level() >= Do_Loop_Depth(loop)){
00839 WN* src_ref=adg->Get_Wn(adg->Get_Source(in_edge));
00840 WN* stmt_block = Find_Stmt_Under(src_ref,if_stmt);
00841 if (stmt_block != NULL) return FALSE;
00842 }
00843 in_edge = adg->Get_Next_In_Edge(in_edge);
00844 }
00845
00846 } else {
00847 if (wniter)
00848 LWN_WALK_Abort(wniter);
00849 return FALSE;
00850 }
00851
00852 }
00853
00854 }
00855
00856 return TRUE;
00857
00858 }
00859
00860
00861 INT64 Get_FP_Counts(WN* wn)
00862 {
00863 OPCODE opcode = WN_opcode(wn);
00864 if (OPCODE_is_leaf(opcode))
00865 return 0;
00866 else if (opcode == OPC_BLOCK) {
00867 WN *kid = WN_first(wn);
00868 INT64 count = 0;
00869 while (kid) {
00870 count++;
00871 count += Get_FP_Counts(kid);
00872 kid = WN_next(kid);
00873 }
00874 return count;
00875 }
00876
00877 OPERATOR oper = OPCODE_operator(opcode);
00878
00879 INT64 count = 0;
00880 if ((oper == OPR_TRUNC) || (oper == OPR_RND) ||
00881 (oper == OPR_CEIL) || (oper == OPR_FLOOR) || (oper == OPR_INTRINSIC_OP)) {
00882 count++;
00883 } else if ((oper == OPR_REALPART) || (oper == OPR_IMAGPART) ||
00884 (oper == OPR_PARM) || (oper == OPR_PAREN)) {
00885
00886 } else if (OPCODE_is_expression(opcode) && !OPCODE_is_load(opcode) &&
00887 (oper != OPR_CONST)) {
00888
00889 if ((OPCODE_desc(opcode)==MTYPE_FQ) || (OPCODE_rtype(opcode)==MTYPE_FQ) ||
00890 (OPCODE_desc(opcode)==MTYPE_CQ) || (OPCODE_rtype(opcode)==MTYPE_CQ) ||
00891 (OPCODE_desc(opcode)==MTYPE_F4) || (OPCODE_desc(opcode)==MTYPE_F8) ||
00892 (OPCODE_rtype(opcode)==MTYPE_F4)||
00893 (OPCODE_rtype(opcode)==MTYPE_F8)|| (OPCODE_desc(opcode)==MTYPE_C4) ||
00894 (OPCODE_desc(opcode)==MTYPE_C8) || (OPCODE_rtype(opcode)==MTYPE_C4)||
00895 #if defined(TARG_IA64)
00896 OPCODE_desc(opcode) == MTYPE_F10 || OPCODE_rtype(opcode) == MTYPE_F10 ||
00897 OPCODE_desc(opcode) == MTYPE_C10 || OPCODE_rtype(opcode) == MTYPE_C10 ||
00898 #endif
00899 (OPCODE_rtype(opcode)==MTYPE_C8)) {
00900
00901 if ((oper == OPR_MAX) || (oper == OPR_MIN) ||
00902 (oper == OPR_ADD) || (oper == OPR_SUB) || (oper == OPR_MPY) ||
00903 (oper == OPR_NEG))
00904 count++;
00905 else if ((oper == OPR_DIV || oper == OPR_SQRT))
00906 count = count + 10;
00907 }
00908 }
00909
00910 for (INT kidno=0; kidno<WN_kid_count(wn); kidno++) {
00911 WN *kid = WN_kid(wn,kidno);
00912 count += Get_FP_Counts(kid);
00913 }
00914
00915 return count;
00916
00917 }
00918
00919
00920
00921
00922
00923 extern void
00924 Perform_Gather_Scatter(
00925 SCC_DIRECTED_GRAPH16 *dep_g_p,
00926 UINT total_scc,
00927 FF_STMT_LIST* scc,
00928 WN* loop,
00929 SCC_DIRECTED_GRAPH16 *scc_dep_g,
00930 WN2VINDEX* stmt_to_vertex)
00931 {
00932
00933
00934
00935 UINT_DYN_ARRAY *cond_scc = CXX_NEW(UINT_DYN_ARRAY(&PHASE25_default_pool),
00936 &PHASE25_default_pool);
00937
00938 UINT_DYN_ARRAY *cond_scc1 = CXX_NEW(UINT_DYN_ARRAY(&PHASE25_default_pool),
00939 &PHASE25_default_pool);
00940
00941
00942 UINT_DYN_ARRAY *other_scc=CXX_NEW(UINT_DYN_ARRAY(&PHASE25_default_pool),
00943 &PHASE25_default_pool);
00944
00945
00946 UINT_DYN_ARRAY *new_scc=CXX_NEW(UINT_DYN_ARRAY(&PHASE25_default_pool),
00947 &PHASE25_default_pool);
00948
00949 VINDEX16 *queue=CXX_NEW_ARRAY(VINDEX16,total_scc,&PHASE25_default_pool);
00950 scc_dep_g->Level_Sort(queue);
00951
00952
00953
00954
00955
00956
00957 UINT i;
00958 for (i=0; i<total_scc; ++i) {
00959 UINT cur = queue[i];
00960 FF_STMT_LIST* scc_cur = &scc[cur];
00961
00962 FF_STMT_NODE* node = scc_cur->Head();
00963 if (scc_dep_g->Get_Out_Edge(cur) == 0 && node->Next() == NULL){
00964
00965 WN* stmt = node->Get_Stmt();
00966
00967 if (WN_opcode(stmt)==OPC_IF && WN_else_is_empty(stmt)
00968 && Good_for_gath(stmt))
00969
00970
00971
00972
00973
00974
00975
00976 cond_scc->AddElement(cur);
00977 else
00978 other_scc->AddElement(cur);
00979 } else
00980 other_scc->AddElement(cur);
00981 }
00982
00983
00984 if (!cond_scc->Elements()){
00985 CXX_DELETE(cond_scc, &PHASE25_default_pool);
00986 CXX_DELETE(new_scc, &PHASE25_default_pool);
00987 CXX_DELETE(other_scc, &PHASE25_default_pool);
00988 CXX_DELETE_ARRAY(queue, &PHASE25_default_pool);
00989 return;
00990 }
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009 SCALAR_STACK** exposed_use = CXX_NEW_ARRAY(SCALAR_STACK*,
01010 cond_scc->Elements(),
01011 &PHASE25_default_pool);
01012 SCALAR_STACK** exposed_site = CXX_NEW_ARRAY(SCALAR_STACK*,
01013 cond_scc->Elements(),
01014 &PHASE25_default_pool);
01015
01016
01017 STACK<WN*> all_use(&PHASE25_default_pool);
01018
01019 INT64 *size_est = CXX_NEW_ARRAY(INT64,cond_scc->Elements(),&PHASE25_default_pool);
01020
01021 UINT ind_new_scc=0;
01022 for (i=0; i<cond_scc->Elements(); ++i) {
01023 WN* if_stmt = scc[(*cond_scc)[i]].Head()->Get_Stmt();
01024
01025 exposed_use[i] = CXX_NEW(SCALAR_STACK(&PHASE25_default_pool),
01026 &PHASE25_default_pool);
01027 exposed_site[i] = CXX_NEW(SCALAR_STACK(&PHASE25_default_pool),
01028 &PHASE25_default_pool);
01029
01030
01031 if (!movable_if_test(if_stmt,loop)){
01032 other_scc->AddElement((*cond_scc)[i]);
01033 continue;
01034 }
01035
01036 all_use.Clear();
01037 WN* if_body = WN_then(if_stmt);
01038
01039
01040 access_counter=0;
01041 Gather_Scalar_References(if_body,NULL,&all_use);
01042
01043 size_est[ind_new_scc] = Get_FP_Counts(if_body);
01044 if (LNO_Verbose)
01045 fprintf(stdout, "Size estimate is %lld\n", size_est[ind_new_scc]);
01046
01047
01048 for (UINT j=0; j<all_use.Elements(); ++j){
01049 WN* ref = all_use.Bottom_nth(j);
01050 BOOL use_stored=FALSE;
01051
01052 DEF_LIST* def_list = Du_Mgr->Ud_Get_Def(ref);
01053 if (!def_list || def_list->Incomplete()) continue;
01054
01055 DEF_LIST_ITER iter_def(def_list);
01056 for (DU_NODE* def_node=iter_def.First(); !iter_def.Is_Empty();
01057 def_node=(DU_NODE *) iter_def.Next()){
01058
01059
01060
01061 WN* def = def_node->Wn();
01062 Is_True(def,("Null pointer in def-use chain \n"));
01063
01064 WN* stmt_block = Find_Stmt_Under(def,WN_do_body(loop));
01065
01066
01067
01068
01069 if (stmt_block != NULL){
01070
01071 VINDEX16 scc_id = dep_g_p->Get_Scc_Id(stmt_to_vertex->Find(stmt_block));
01072 if (scc_id != (*cond_scc)[i]){
01073
01074
01075
01076 if (Scalar_Expandable(ref, loop, Du_Mgr) != SE_NONE) {
01077
01078
01079 exposed_use[ind_new_scc]->Add_Scalar(def,0);
01080
01081 if (!use_stored){
01082 exposed_site[ind_new_scc]->Add_Scalar(ref,0);
01083 use_stored = TRUE;
01084 }
01085 }
01086 }
01087 } else if (def == WN_start(loop) || stmt_block == WN_step(loop)){
01088
01089 exposed_use[ind_new_scc]->Add_Scalar(def,0);
01090 if (!use_stored){
01091 exposed_site[ind_new_scc]->Add_Scalar(ref,0);
01092 use_stored = TRUE;
01093 }
01094 }
01095 }
01096 }
01097
01098 IF_INFO *ii = Get_If_Info(if_stmt, TRUE);
01099 if (size_est[ind_new_scc] > 3 +
01100 2 * exposed_use[ind_new_scc]->Elements() ||
01101 (ii!=NULL && ii->Freq_True>=0.0 &&
01102 (1-ii->Freq_True)*size_est[ind_new_scc] >
01103 3 + 2 * exposed_use[ind_new_scc]->Elements())) {
01104 cond_scc1->AddElement((*cond_scc)[i]);
01105 ind_new_scc++;
01106 } else {
01107 exposed_site[ind_new_scc]->Clear();
01108 exposed_use[ind_new_scc]->Clear();
01109 other_scc->AddElement((*cond_scc)[i]);
01110 }
01111
01112 }
01113
01114
01115 if (!cond_scc1->Elements()){
01116 CXX_DELETE(cond_scc, &PHASE25_default_pool);
01117 CXX_DELETE(cond_scc1, &PHASE25_default_pool);
01118 CXX_DELETE(new_scc, &PHASE25_default_pool);
01119 CXX_DELETE(other_scc, &PHASE25_default_pool);
01120 CXX_DELETE_ARRAY(size_est, &PHASE25_default_pool);
01121 CXX_DELETE_ARRAY(queue, &PHASE25_default_pool);
01122 CXX_DELETE_ARRAY(exposed_use, &PHASE25_default_pool);
01123 CXX_DELETE_ARRAY(exposed_site, &PHASE25_default_pool);
01124 return;
01125 }
01126
01127 if (LNO_Verbose){
01128 fprintf(stdout, "Gather/Scatter create %d new loops\n",
01129 cond_scc1->Elements());
01130 fprintf(TFile, "Gather/Scatter create %d new loops\n",
01131 cond_scc1->Elements());
01132 }
01133
01134
01135
01136 WN* tile_loop = NULL;
01137 if (!Get_Trace(TP_LNOPT, TT_LNO_BIG_SCALAR_TILES)) {
01138 tile_loop = SE_Tile_Inner_Loop(loop, &LNO_default_pool);
01139 if (Prompf_Info != NULL && Prompf_Info->Is_Enabled()) {
01140 if (tile_loop != NULL) {
01141 INT old_id = WN_MAP32_Get(Prompf_Id_Map, loop);
01142 INT new_id = New_Construct_Id();
01143 WN_MAP32_Set(Prompf_Id_Map, tile_loop, new_id);
01144 Prompf_Info->Se_Tile(old_id, new_id);
01145 }
01146 }
01147 }
01148
01149
01150
01151
01152
01153 INT big_o = -1;
01154 if (other_scc->Elements()){
01155 big_o = (*other_scc)[0];
01156 new_scc->AddElement(big_o);
01157
01158 for (i=1; i<other_scc->Elements(); ++i){
01159
01160 UINT cur = (*other_scc)[i];
01161 scc[big_o].Append_List(&scc[cur]);
01162 }
01163 } else
01164 new_scc->AddElement(0);
01165
01166
01167 for (i=0; i<cond_scc1->Elements(); ++i){
01168 new_scc->AddElement((*cond_scc1)[i]);
01169 }
01170
01171
01172 INT num_loop = new_scc->Elements();
01173 WN** result_loops = CXX_NEW_ARRAY(WN*,num_loop,&PHASE25_default_pool);
01174 WN** if_handles = CXX_NEW_ARRAY(WN*,num_loop,&PHASE25_default_pool);
01175 separate_loop_by_scc(new_scc, scc, loop, result_loops, if_handles, (big_o<0));
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188 WN* loop_first = result_loops[0];
01189 TYPE_ID ind_type = Do_Wtype(loop_first);
01190 OPCODE stop = OPCODE_make_op(OPR_STID, MTYPE_V, ind_type);
01191 OPCODE ldop = OPCODE_make_op(OPR_LDID, Promote_Type(ind_type), ind_type);
01192 OPCODE addop = OPCODE_make_op(OPR_ADD, Promote_Type(ind_type), MTYPE_V);
01193 OPCODE ltop = OPCODE_make_op(OPR_LT, Boolean_type, Promote_Type(ind_type));
01194 WN* alloc_loop = tile_loop == NULL ? loop_first : tile_loop;
01195
01196 for (i=1; i<num_loop; ++i){
01197 WN* loop_current = result_loops[i];
01198 WN* dealloc_loop = tile_loop == NULL ? loop_current : tile_loop;
01199
01200
01201 char newinc_name[64];
01202
01203
01204 sprintf(newinc_name, "$inc_%d", index_counter);
01205 SYMBOL new_inc = Create_Preg_Symbol(newinc_name, ind_type);
01206
01207
01208 WN* cons_0 = LWN_Make_Icon(Promote_Type(ind_type),0);
01209 WN* store_init = LWN_CreateStid(stop,
01210 new_inc.WN_Offset(),
01211 new_inc.St(),
01212 Be_Type_Tbl(ind_type),
01213 cons_0);
01214 LWN_Copy_Linenumber(loop_current,store_init);
01215 LWN_Insert_Block_Before(LWN_Get_Parent(loop_first), loop_first, store_init);
01216
01217
01218
01219 WN *if_stmt = if_handles[i];
01220 WN *then_body = WN_then(if_stmt);
01221
01222
01223
01224 WN* ld_inc = LWN_CreateLdid(ldop, store_init);
01225 WN* cons_1 = LWN_Make_Icon(Promote_Type(ind_type), 1);
01226 WN* step_expr = LWN_CreateExp2(addop, ld_inc, cons_1);
01227 WN* new_store = LWN_CreateStid(stop,
01228 new_inc.WN_Offset(),
01229 new_inc.St(),
01230 Be_Type_Tbl(ind_type),
01231 step_expr);
01232 Du_Mgr->Add_Def_Use(store_init,ld_inc);
01233 Du_Mgr->Add_Def_Use(new_store,ld_inc);
01234
01235 LWN_Copy_Frequency_Tree(new_store,then_body);
01236 LWN_Copy_Linenumber(then_body,new_store);
01237
01238
01239 LWN_Insert_Block_Before(then_body, NULL, new_store);
01240
01241
01242
01243
01244 char newind_name[64];
01245 sprintf(newind_name, "$ind_%d", index_counter++);
01246 SYMBOL new_ind = Create_Preg_Symbol(newind_name, ind_type);
01247
01248
01249 SYMBOL old_symbol(WN_index(loop_current));
01250 Replace_Symbol(WN_index(loop_current),old_symbol,new_ind,NULL);
01251
01252
01253 WN* wn_start = WN_start(loop_current);
01254 Replace_Symbol(wn_start,old_symbol,new_ind,NULL);
01255 cons_0 = LWN_Copy_Tree(cons_0);
01256 WN* old_value = WN_kid0(wn_start);
01257 WN_kid0(wn_start) = cons_0;
01258 LWN_Set_Parent(cons_0,wn_start);
01259 LWN_Copy_Frequency(cons_0,old_value);
01260
01261 LWN_Delete_Tree(old_value);
01262
01263
01264 WN* wn_step = WN_step(loop_current);
01265
01266 #if 0
01267 DEF_LIST *def_list=Du_Mgr->Ud_Get_Def(WN_kid0(WN_kid0(wn_step)));
01268 Is_True(def_list,("Empty definition nodes \n"));
01269 DEF_LIST_ITER d_iter(def_list);
01270 for (DU_NODE *def_node=(DU_NODE *)d_iter.First();
01271 !d_iter.Is_Empty(); def_node = (DU_NODE *)d_iter.Next()){
01272 WN* def=def_node->Wn();
01273 Dump_WN(def,stdout,1,2,2);
01274 }
01275 #endif
01276
01277 Replace_Symbol(wn_step,old_symbol,new_ind,NULL);
01278 cons_1 = LWN_Copy_Tree(cons_1);
01279 step_expr = WN_kid0(wn_step);
01280 WN* old_inc = WN_kid1(step_expr);
01281 WN_kid1(step_expr) = cons_1;
01282 LWN_Set_Parent(cons_1,step_expr);
01283 LWN_Delete_Tree(old_inc);
01284 LWN_Copy_Frequency_Tree(wn_step, then_body);
01285
01286
01287 WN* ld_ind = LWN_CreateLdid(ldop, WN_start(loop_current));
01288 WN* ld_inc_copy = LWN_Copy_Tree(ld_inc);
01289 LWN_Copy_Def_Use(ld_inc,ld_inc_copy,Du_Mgr);
01290
01291 WN* new_end = LWN_CreateExp2(ltop,ld_ind,ld_inc_copy);
01292 WN* wn_end = WN_end(loop_current);
01293 WN_end(loop_current) = new_end;
01294 LWN_Set_Parent(new_end,loop_current);
01295 LWN_Delete_Tree(wn_end);
01296 LWN_Copy_Frequency_Tree(new_end, then_body);
01297
01298 Du_Mgr->Add_Def_Use(wn_start,ld_ind);
01299 Du_Mgr->Add_Def_Use(wn_step,ld_ind);
01300 Du_Mgr->Ud_Get_Def(ld_ind)->Set_loop_stmt(loop_current);
01301
01302
01303
01304 DOLOOP_STACK do_stack(&PHASE25_default_pool);
01305 Build_Doloop_Stack(LWN_Get_Parent(loop_current), &do_stack);
01306 LNO_Build_Do_Access(loop_current, &do_stack);
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316 DYN_ARRAY<SCALAR_NODE*> use_I8(&PHASE25_default_pool);
01317 DYN_ARRAY<SCALAR_NODE*> site_I8(&PHASE25_default_pool);
01318 DYN_ARRAY<SCALAR_NODE*> use_U8(&PHASE25_default_pool);
01319 DYN_ARRAY<SCALAR_NODE*> site_U8(&PHASE25_default_pool);
01320 DYN_ARRAY<SCALAR_NODE*> use_F8(&PHASE25_default_pool);
01321 DYN_ARRAY<SCALAR_NODE*> site_F8(&PHASE25_default_pool);
01322 DYN_ARRAY<SCALAR_NODE*> use_C4(&PHASE25_default_pool);
01323 DYN_ARRAY<SCALAR_NODE*> site_C4(&PHASE25_default_pool);
01324 DYN_ARRAY<SCALAR_NODE*> use_I4(&PHASE25_default_pool);
01325 DYN_ARRAY<SCALAR_NODE*> site_I4(&PHASE25_default_pool);
01326 DYN_ARRAY<SCALAR_NODE*> use_U4(&PHASE25_default_pool);
01327 DYN_ARRAY<SCALAR_NODE*> site_U4(&PHASE25_default_pool);
01328 DYN_ARRAY<SCALAR_NODE*> use_F4(&PHASE25_default_pool);
01329 DYN_ARRAY<SCALAR_NODE*> site_F4(&PHASE25_default_pool);
01330 DYN_ARRAY<SCALAR_NODE*> use_FQ(&PHASE25_default_pool);
01331 DYN_ARRAY<SCALAR_NODE*> site_FQ(&PHASE25_default_pool);
01332 DYN_ARRAY<SCALAR_NODE*> use_C8(&PHASE25_default_pool);
01333 DYN_ARRAY<SCALAR_NODE*> site_C8(&PHASE25_default_pool);
01334 DYN_ARRAY<SCALAR_NODE*> use_CQ(&PHASE25_default_pool);
01335 DYN_ARRAY<SCALAR_NODE*> site_CQ(&PHASE25_default_pool);
01336 DYN_ARRAY<SCALAR_NODE*> use_I2(&PHASE25_default_pool);
01337 DYN_ARRAY<SCALAR_NODE*> site_I2(&PHASE25_default_pool);
01338 DYN_ARRAY<SCALAR_NODE*> use_U2(&PHASE25_default_pool);
01339 DYN_ARRAY<SCALAR_NODE*> site_U2(&PHASE25_default_pool);
01340 DYN_ARRAY<SCALAR_NODE*> use_I1(&PHASE25_default_pool);
01341 DYN_ARRAY<SCALAR_NODE*> site_I1(&PHASE25_default_pool);
01342 DYN_ARRAY<SCALAR_NODE*> use_U1(&PHASE25_default_pool);
01343 DYN_ARRAY<SCALAR_NODE*> site_U1(&PHASE25_default_pool);
01344 #if defined(TARG_IA64)
01345 DYN_ARRAY<SCALAR_NODE*> use_F10(&PHASE25_default_pool);
01346 DYN_ARRAY<SCALAR_NODE*> site_F10(&PHASE25_default_pool);
01347 DYN_ARRAY<SCALAR_NODE*> use_C10(&PHASE25_default_pool);
01348 DYN_ARRAY<SCALAR_NODE*> site_C10(&PHASE25_default_pool);
01349 #endif
01350
01351 for (UINT j=0; j<exposed_use[i-1]->Elements(); ++j){
01352 SYMBOL& cur_use = exposed_use[i-1]->Bottom_nth(j)->_scalar;
01353
01354 switch (cur_use.Type){
01355 case MTYPE_I8:
01356 use_I8.AddElement(exposed_use[i-1]->Bottom_nth(j));
01357 site_I8.AddElement(exposed_site[i-1]->Bottom_nth(j));
01358 break;
01359 case MTYPE_U8:
01360 use_U8.AddElement(exposed_use[i-1]->Bottom_nth(j));
01361 site_U8.AddElement(exposed_site[i-1]->Bottom_nth(j));
01362 break;
01363 case MTYPE_F8:
01364 use_F8.AddElement(exposed_use[i-1]->Bottom_nth(j));
01365 site_F8.AddElement(exposed_site[i-1]->Bottom_nth(j));
01366 break;
01367 case MTYPE_C4:
01368 use_C4.AddElement(exposed_use[i-1]->Bottom_nth(j));
01369 site_C4.AddElement(exposed_site[i-1]->Bottom_nth(j));
01370 break;
01371 case MTYPE_I4:
01372 use_I4.AddElement(exposed_use[i-1]->Bottom_nth(j));
01373 site_I4.AddElement(exposed_site[i-1]->Bottom_nth(j));
01374 break;
01375 case MTYPE_U4:
01376 use_U4.AddElement(exposed_use[i-1]->Bottom_nth(j));
01377 site_U4.AddElement(exposed_site[i-1]->Bottom_nth(j));
01378 break;
01379 case MTYPE_F4:
01380 use_F4.AddElement(exposed_use[i-1]->Bottom_nth(j));
01381 site_F4.AddElement(exposed_site[i-1]->Bottom_nth(j));
01382 break;
01383 case MTYPE_FQ:
01384 use_FQ.AddElement(exposed_use[i-1]->Bottom_nth(j));
01385 site_FQ.AddElement(exposed_site[i-1]->Bottom_nth(j));
01386 break;
01387 case MTYPE_C8:
01388 use_C8.AddElement(exposed_use[i-1]->Bottom_nth(j));
01389 site_C8.AddElement(exposed_site[i-1]->Bottom_nth(j));
01390 break;
01391 case MTYPE_CQ:
01392 use_CQ.AddElement(exposed_use[i-1]->Bottom_nth(j));
01393 site_CQ.AddElement(exposed_site[i-1]->Bottom_nth(j));
01394 break;
01395 case MTYPE_I2:
01396 use_I2.AddElement(exposed_use[i-1]->Bottom_nth(j));
01397 site_I2.AddElement(exposed_site[i-1]->Bottom_nth(j));
01398 break;
01399 case MTYPE_U2:
01400 use_U2.AddElement(exposed_use[i-1]->Bottom_nth(j));
01401 site_U2.AddElement(exposed_site[i-1]->Bottom_nth(j));
01402 break;
01403 case MTYPE_I1:
01404 use_I1.AddElement(exposed_use[i-1]->Bottom_nth(j));
01405 site_I1.AddElement(exposed_site[i-1]->Bottom_nth(j));
01406 break;
01407 case MTYPE_U1:
01408 use_U1.AddElement(exposed_use[i-1]->Bottom_nth(j));
01409 site_U1.AddElement(exposed_site[i-1]->Bottom_nth(j));
01410 break;
01411 #if defined(TARG_IA64)
01412 case MTYPE_F10:
01413 use_F10.AddElement(exposed_use[i-1]->Bottom_nth(j));
01414 site_F10.AddElement(exposed_site[i-1]->Bottom_nth(j));
01415 break;
01416 case MTYPE_C10:
01417 use_C10.AddElement(exposed_use[i-1]->Bottom_nth(j));
01418 site_C10.AddElement(exposed_site[i-1]->Bottom_nth(j));
01419 break;
01420 #endif
01421 default:
01422 FmtAssert(0, ("Bad type in scalar memorization"));
01423 }
01424 }
01425
01426 if (use_I8.Elements())
01427 Gather_Scatter_Scalar_Expand(loop_first, ld_inc, tile_loop,
01428 loop_current, use_I8, site_I8,
01429 if_stmt, &alloc_loop,&dealloc_loop);
01430 if (use_U8.Elements())
01431 Gather_Scatter_Scalar_Expand(loop_first, ld_inc, tile_loop,
01432 loop_current, use_U8, site_U8,
01433 if_stmt, &alloc_loop,&dealloc_loop);
01434 if (use_F8.Elements())
01435 Gather_Scatter_Scalar_Expand(loop_first, ld_inc, tile_loop,
01436 loop_current, use_F8, site_F8,
01437 if_stmt, &alloc_loop,&dealloc_loop);
01438 if (use_C4.Elements())
01439 Gather_Scatter_Scalar_Expand(loop_first, ld_inc, tile_loop,
01440 loop_current, use_C4, site_C4,
01441 if_stmt, &alloc_loop,&dealloc_loop);
01442 if (use_I4.Elements())
01443 Gather_Scatter_Scalar_Expand(loop_first, ld_inc, tile_loop,
01444 loop_current, use_I4, site_I4,
01445 if_stmt, &alloc_loop,&dealloc_loop);
01446 if (use_U4.Elements())
01447 Gather_Scatter_Scalar_Expand(loop_first, ld_inc, tile_loop,
01448 loop_current, use_U4, site_U4,
01449 if_stmt, &alloc_loop,&dealloc_loop);
01450 if (use_F4.Elements())
01451 Gather_Scatter_Scalar_Expand(loop_first, ld_inc, tile_loop,
01452 loop_current, use_F4, site_F4,
01453 if_stmt, &alloc_loop,&dealloc_loop);
01454 if (use_FQ.Elements())
01455 Gather_Scatter_Scalar_Expand(loop_first, ld_inc, tile_loop,
01456 loop_current, use_FQ, site_FQ,
01457 if_stmt, &alloc_loop,&dealloc_loop);
01458 if (use_C8.Elements())
01459 Gather_Scatter_Scalar_Expand(loop_first, ld_inc, tile_loop,
01460 loop_current, use_C8, site_C8,
01461 if_stmt, &alloc_loop,&dealloc_loop);
01462 if (use_CQ.Elements())
01463 Gather_Scatter_Scalar_Expand(loop_first, ld_inc, tile_loop,
01464 loop_current, use_CQ, site_CQ,
01465 if_stmt, &alloc_loop,&dealloc_loop);
01466 if (use_I2.Elements())
01467 Gather_Scatter_Scalar_Expand(loop_first, ld_inc, tile_loop,
01468 loop_current, use_I2, site_I2,
01469 if_stmt, &alloc_loop,&dealloc_loop);
01470 if (use_U2.Elements())
01471 Gather_Scatter_Scalar_Expand(loop_first, ld_inc, tile_loop,
01472 loop_current, use_U2, site_U2,
01473 if_stmt, &alloc_loop,&dealloc_loop);
01474 if (use_I1.Elements())
01475 Gather_Scatter_Scalar_Expand(loop_first, ld_inc, tile_loop,
01476 loop_current, use_I1, site_I1,
01477 if_stmt, &alloc_loop,&dealloc_loop);
01478 if (use_U1.Elements())
01479 Gather_Scatter_Scalar_Expand(loop_first, ld_inc, tile_loop,
01480 loop_current, use_U1, site_U1,
01481 if_stmt, &alloc_loop,&dealloc_loop);
01482 #if defined(TARG_IA64)
01483 if (use_F10.Elements())
01484 Gather_Scatter_Scalar_Expand(loop_first, ld_inc, tile_loop,
01485 loop_current, use_F10, site_F10,
01486 if_stmt, &alloc_loop,&dealloc_loop);
01487 if (use_C10.Elements())
01488 Gather_Scatter_Scalar_Expand(loop_first, ld_inc, tile_loop,
01489 loop_current, use_C10, site_C10,
01490 if_stmt, &alloc_loop,&dealloc_loop);
01491 #endif
01492 }
01493
01494 CXX_DELETE(cond_scc, &PHASE25_default_pool);
01495 CXX_DELETE(new_scc, &PHASE25_default_pool);
01496 CXX_DELETE(other_scc, &PHASE25_default_pool);
01497 CXX_DELETE_ARRAY(queue, &PHASE25_default_pool);
01498 CXX_DELETE_ARRAY(exposed_use, &PHASE25_default_pool);
01499 CXX_DELETE_ARRAY(exposed_site, &PHASE25_default_pool);
01500
01501 }
01502
01503
01504
01505
01506
01507
01508 extern INT Fiss_Gather_Inner_Loop(WN* innerloop)
01509 {
01510
01511 DO_LOOP_INFO* dli=Get_Do_Loop_Info(innerloop);
01512 Is_True(dli,("Fiss_Gather_Inner_Loop:No DO_LOOP_INFO for the loop"));
01513
01514
01515 if (dli->Est_Num_Iterations < Iteration_Count_Threshold)
01516 return 1;
01517
01518
01519 WN* ub = WN_end(innerloop);
01520
01521
01522 if (Do_Loop_Is_Unsigned(innerloop) &&
01523 (UBvar(ub) == NULL || WN_operator(ub) != OPR_LE))
01524 return 0;
01525
01526
01527 BOOL ok = Solve_For(ub, SYMBOL(WN_index(innerloop)));
01528 if (ok == FALSE) return 0;
01529
01530
01531 OPCODE opc = WN_opcode(ub);
01532 OPERATOR opr = OPCODE_operator(opc);
01533 if (opr != OPR_LT && opr != OPR_LE) return 0;
01534
01535 MEM_POOL_Push(&PHASE25_default_pool);
01536 {
01537
01538
01539 BINARY_TREE<NAME2BIT> *mapping_dictionary =
01540 CXX_NEW(BINARY_TREE<NAME2BIT>(&PHASE25_default_pool),&PHASE25_default_pool);
01541
01542
01543 SCC_DIRECTED_GRAPH16 *dep_g_p =
01544 CXX_NEW(SCC_DIRECTED_GRAPH16(ESTIMATED_SIZE,ESTIMATED_SIZE),
01545 &PHASE25_default_pool);
01546
01547
01548
01549 WN2VINDEX *stmt_to_vertex=
01550 CXX_NEW(WN2VINDEX(ESTIMATED_SIZE, &PHASE25_default_pool),
01551 &PHASE25_default_pool);
01552
01553
01554 WN2UINT *stmt_id=
01555 CXX_NEW(WN2UINT(ESTIMATED_SIZE, &PHASE25_default_pool),&PHASE25_default_pool);
01556
01557
01558
01559 REF_LIST_STACK *writes = CXX_NEW(REF_LIST_STACK(&PHASE25_default_pool),
01560 &PHASE25_default_pool);
01561 REF_LIST_STACK *reads = CXX_NEW(REF_LIST_STACK(&PHASE25_default_pool),
01562 &PHASE25_default_pool);
01563
01564 SCALAR_STACK *scalar_writes = CXX_NEW(SCALAR_STACK(&PHASE25_default_pool),
01565 &PHASE25_default_pool);
01566 SCALAR_STACK *scalar_reads = CXX_NEW(SCALAR_STACK(&PHASE25_default_pool),
01567 &PHASE25_default_pool);
01568 SCALAR_REF_STACK *params =
01569 CXX_NEW(SCALAR_REF_STACK(&PHASE25_default_pool), &PHASE25_default_pool);
01570
01571
01572 DOLOOP_STACK stack(&PHASE25_default_pool);
01573 Build_Doloop_Stack(innerloop, &stack);
01574
01575
01576
01577
01578 WN* body=WN_do_body(innerloop);
01579 WN* stmt;
01580 UINT stmt_count=0;
01581 INT32 gather_status=0;
01582 Init_Ref_Stmt_Counter();
01583 for (stmt=WN_first(body); stmt && gather_status != -1; stmt=WN_next(stmt)) {
01584 stmt_to_vertex->Enter(stmt, dep_g_p->Add_Vertex());
01585 stmt_id->Enter(stmt, stmt_count++);
01586 gather_status=New_Gather_References(stmt,writes,reads,&stack,
01587 scalar_writes,scalar_reads,params,&PHASE25_default_pool);
01588 }
01589 if (gather_status == -1) {
01590 DevWarn("Error in gathering references");
01591 MEM_POOL_Pop(&PHASE25_default_pool);
01592 return 0;
01593 }
01594
01595
01596 FF_STMT_LIST expandable_ref_list;
01597
01598
01599
01600
01601
01602 UINT sym_count=inner_fission_2(innerloop, scalar_reads, scalar_writes,
01603 reads, writes, mapping_dictionary,
01604 expandable_ref_list, &PHASE25_default_pool);
01605
01606
01607
01608
01609 BIT_VECTOR* stmt_name_set=
01610 CXX_NEW_ARRAY(BIT_VECTOR, stmt_count, &PHASE25_default_pool);
01611
01612
01613
01614 UINT i;
01615 for (i=0; i<stmt_count; i++)
01616 stmt_name_set[i].Init(sym_count, &PHASE25_default_pool);
01617
01618
01619 BIT_VECTOR Expandable_Scalar_Set(sym_count, &PHASE25_default_pool);
01620
01621
01622
01623 FF_STMT_ITER e_iter(&expandable_ref_list);
01624 for (FF_STMT_NODE* ref_node=e_iter.First(); !e_iter.Is_Empty();
01625 ref_node=e_iter.Next()) {
01626 NAME2BIT temp_map;
01627 temp_map.Set_Symbol(ref_node->Get_Stmt());
01628 Expandable_Scalar_Set.Set(mapping_dictionary->Find(temp_map)->
01629 Get_Data()->Get_Bit_Position());
01630 }
01631
01632 if (LNO_Test_Dump) {
01633 printf("Expandable_Scalar_Set=\n");
01634 Expandable_Scalar_Set.Print(stdout);
01635 }
01636
01637 Register_Name_To_Statement(innerloop,scalar_reads,scalar_writes,reads,writes,
01638 stmt_id,stmt_name_set,mapping_dictionary);
01639
01640 WN_MAP sdm=WN_MAP_Create(&PHASE25_default_pool);
01641 ARRAY_DIRECTED_GRAPH16 *sdg =
01642 CXX_NEW(ARRAY_DIRECTED_GRAPH16(100,500,sdm,LEVEL_ARRAY_GRAPH),
01643 &PHASE25_default_pool);
01644
01645 for (stmt = WN_first(body); stmt; stmt = WN_next(stmt)) {
01646 if (!Map_Stmt_To_Level_Graph(stmt,sdg)) {
01647 DevWarn("Error in mapping stmt to level graph\n");
01648 WN_MAP_Delete(sdm);
01649 MEM_POOL_Pop(&PHASE25_default_pool);
01650 return 0;
01651 }
01652 }
01653
01654 BOOL status=Generate_Scalar_Dependence_For_Statement_Dependence_Graph
01655 (innerloop, scalar_reads, scalar_writes, params, sdg, red_manager,
01656 &Expandable_Scalar_Set, mapping_dictionary);
01657 if (status==FALSE) {
01658 DevWarn("Statement dependence graph problem");
01659 WN_MAP_Delete(sdm);
01660 MEM_POOL_Pop(&PHASE25_default_pool);
01661 return(0);
01662 }
01663
01664 status=Generate_Array_Dependence_For_Statement_Dependence_Graph
01665 (innerloop, reads, writes, sdg, red_manager, adg);
01666 if (status==FALSE) {
01667 DevWarn("Statement dependence graph problem");
01668 WN_MAP_Delete(sdm);
01669 MEM_POOL_Pop(&PHASE25_default_pool);
01670 return(0);
01671 }
01672
01673
01674 if (LNO_Test_Dump) {
01675 printf("Statement Dependence Graph of Phase 2.5:\n");
01676 sdg->Print(stdout);
01677 }
01678
01679
01680 EINDEX16 e=sdg->Get_Edge();
01681 while (e) {
01682 WN* source=sdg->Get_Wn(sdg->Get_Source(e));
01683 WN* sink=sdg->Get_Wn(sdg->Get_Sink(e));
01684 if (LWN_Get_Parent(source) == body || LWN_Get_Parent(sink) == body)
01685
01686 dep_g_p->Add_Unique_Edge(
01687 stmt_to_vertex->Find(source),
01688 stmt_to_vertex->Find(sink));
01689 e=sdg->Get_Next_Edge(e);
01690 }
01691
01692
01693 if (LNO_Test_Dump) {
01694 printf("Statement SCC Graph of Phase 2.5:\n");
01695 dep_g_p->Print(stdout);
01696 }
01697
01698
01699
01700
01701 SCC_DIRECTED_GRAPH16 *ac_g;
01702 ac_g = dep_g_p->Acyclic_Condensation(&PHASE25_default_pool);
01703
01704
01705 if (LNO_Test_Dump) {
01706 printf("SCC Dependence Graph of Phase 2.5:\n");
01707 ac_g->Print(stdout);
01708 }
01709
01710
01711 VINDEX16 total_scc = dep_g_p->Get_Scc_Count();
01712
01713
01714 FF_STMT_LIST *scc;
01715 scc = CXX_NEW_ARRAY(FF_STMT_LIST, total_scc+1, &PHASE25_default_pool);
01716
01717
01718 for (stmt = WN_first(WN_do_body(innerloop)); stmt; stmt = WN_next(stmt)) {
01719 VINDEX16 scc_id;
01720 scc_id = dep_g_p->Get_Scc_Id(stmt_to_vertex->Find(stmt));
01721 scc[scc_id].Append(stmt, &PHASE25_default_pool);
01722 }
01723
01724 if (LNO_Test_Dump)
01725 for (i=1; i<=total_scc; i++) {
01726
01727 printf("PHASE 2.5:scc %d:", i);
01728 FF_STMT_ITER s_iter(&scc[i]);
01729 INT j=0;
01730 for (FF_STMT_NODE *stmt_node=s_iter.First(); !s_iter.Is_Empty();
01731 stmt_node=s_iter.Next()) {
01732 stmt=stmt_node->Get_Stmt();
01733 Dump_WN(stmt,stdout,TRUE,4,4);
01734 j++;
01735 }
01736 }
01737
01738
01739 Perform_Gather_Scatter(dep_g_p,total_scc,scc,
01740 innerloop, ac_g, stmt_to_vertex);
01741
01742
01743
01744 CXX_DELETE(ac_g, &PHASE25_default_pool);
01745 CXX_DELETE(dep_g_p, &PHASE25_default_pool);
01746 CXX_DELETE(sdg, &PHASE25_default_pool);
01747 WN_MAP_Delete(sdm);
01748 }
01749 MEM_POOL_Pop(&PHASE25_default_pool);
01750
01751 if (LNO_Test_Dump) {
01752 printf("The dependence graph is \n");
01753 Array_Dependence_Graph->Print(stdout);
01754 }
01755
01756 return 1;
01757
01758 }
01759