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 #ifdef USE_PCH
00053 #include "lno_pch.h"
00054 #endif // USE_PCH
00055 #pragma hdrstop
00056
00057 const static char *source_file = __FILE__;
00058
00059 #ifdef _KEEP_RCS_ID
00060 static char *rcs_id = "$Source$ $Revision$";
00061 static char **rcs_dummy[] = { &rcs_id, (char **)&rcs_dummy,
00062 (char **)&source_file };
00063 #endif
00064
00065 #include <sys/types.h>
00066 #include <ctype.h>
00067 #include <limits.h>
00068 #include <alloca.h>
00069
00070 #include "pu_info.h"
00071 #include "stdlib.h"
00072 #include "lnopt_main.h"
00073 #include "config_targ.h"
00074 #include "lwn_util.h"
00075 #include "lnoutils.h"
00076 #include "lego_opts.h"
00077 #include "lego_pragma.h"
00078 #include "lego_util.h"
00079 #include "lego.h"
00080 #include "lego_gen.h"
00081 #include "wn_simp.h"
00082 #include "wn_core.h"
00083 #include "tile.h"
00084 #include "targ_sim.h"
00085
00086
00087
00088
00089
00090 extern WN *Generate_Bounds(const WN *doloop,
00091 SYMBOL **new_lb, SYMBOL **new_ub,
00092 SYMBOL **new_step, INT bound);
00093 extern BOOL Loop_Bounds_Simple(const WN *doloop);
00094
00095
00096
00097
00098
00099 static WN *Generate_Block_Bounds(DISTR_INFO *dinfo,
00100 LEGO_INFO *lego_info,
00101 const WN *doloop, SYMBOL **new_lb,
00102 SYMBOL **new_ub);
00103 static WN *Generate_Block_Bounds_Negative(DISTR_INFO *dinfo,
00104 LEGO_INFO *lego_info,
00105 const WN *doloop, SYMBOL **new_lb,
00106 SYMBOL **new_ub);
00107 static WN *Generate_Cyclic_Bounds(DISTR_INFO *dinfo,
00108 LEGO_INFO *lego_info,
00109 const WN *doloop, SYMBOL **new_lb,
00110 SYMBOL **new_ub,SYMBOL **new_step);
00111 static WN *Generate_Blkcyc_Bounds(DISTR_INFO *dinfo,
00112 LEGO_INFO *lego_info,
00113 const WN *doloop, SYMBOL **new_lb,
00114 SYMBOL **new_ub,SYMBOL **new_step,
00115 INT bound);
00116 static WN *Generate_Runtime_Cyclic_Bounds(DISTR_INFO *dinfo,
00117 LEGO_INFO *lego_info,
00118 const WN *doloop, SYMBOL **new_lb,
00119 SYMBOL **new_ub, SYMBOL **new_step);
00120 static WN* Generate_Simple_Bounds(const WN* wn_loop, SYMBOL** new_lb,
00121 SYMBOL** new_ub, DU_MANAGER* du,
00122 ARRAY_DIRECTED_GRAPH16* dg);
00123 static WN* Generate_Interleaved_Bounds(const WN* wn_loop,
00124 SYMBOL** new_lb,
00125 SYMBOL** new_ub,
00126 SYMBOL** new_step,
00127 DU_MANAGER* du,
00128 INT bound);
00129 static WN* Generate_Dynamic_Bounds(LEGO_INFO *lego_info,
00130 const WN *doloop,
00131 SYMBOL **new_lb,
00132 SYMBOL **new_ub,
00133 SYMBOL **new_step,
00134 INT bound);
00135 static INT64 Get_Step_Multiplier(WN *doloop, SYMBOL *var);
00136 static BOOL Symbols_Equiv(WN *wn_ldid, SYMBOL *var);
00137
00138
00139
00140
00141
00142
00143
00144 static char Str_Buf[256];
00145
00146
00147
00148
00149
00150 WN *Generate_Bounds(const WN *doloop,
00151 SYMBOL **new_lb,
00152 SYMBOL **new_ub,
00153 SYMBOL **new_step,
00154 INT bound)
00155 {
00156 WN *bounds_code = NULL;
00157 DO_LOOP_INFO* dli = Get_Do_Loop_Info(doloop);
00158 LEGO_INFO* lego_info = dli->Lego_Info;
00159 MP_INFO* mp_info = dli->Mp_Info;
00160 *new_lb = NULL;
00161 *new_ub = NULL;
00162 *new_step = NULL;
00163
00164 if (!doloop)
00165 return NULL;
00166
00167 if (lego_info == NULL) {
00168
00169 Is_True(Upper_Bound_Standardize(WN_end(doloop), TRUE),
00170 ("Don't lower untransformable do_across loops."));
00171 FmtAssert(mp_info != NULL, ("No lego info, must be do_across"));
00172 switch(mp_info->Sched_Type()) {
00173 case MP_SCHED_SIMPLE:
00174 bounds_code = Generate_Simple_Bounds(doloop, new_lb, new_ub,
00175 Du_Mgr, Array_Dependence_Graph);
00176 break;
00177 case MP_SCHED_INTERLEAVE:
00178 bounds_code = Generate_Interleaved_Bounds(doloop, new_lb, new_ub,
00179 new_step, Du_Mgr, bound);
00180 break;
00181 default:
00182 FmtAssert(TRUE, ("Generate_Bounds does not support this sched type."));
00183 }
00184
00185 } else {
00186
00187 Is_True(Loop_Bounds_Simple(doloop),
00188 ("Generate_Bounds cannot generate code for loop %s with complex bounds",
00189 ST_name(WN_st(WN_index(doloop)))));
00190
00191 Is_True(lego_info, ("Generate_Bounds passed empty LEGO_INFO"));
00192 SYMBOL *array_sym = lego_info->Array();
00193 if (!array_sym) return NULL;
00194
00195 if (lego_info->Dynamic_Affinity())
00196 return Generate_Dynamic_Bounds(lego_info, doloop, new_lb, new_ub,
00197 new_step, bound);
00198
00199 DISTR_ARRAY *dact = Lookup_DACT(array_sym->St());
00200 Is_True(dact, ("Generate_Bounds: No DACT for array %s in LEGO_INFO",
00201 ST_name(array_sym->St())));
00202
00203 DISTR_INFO *dinfo = dact->Dinfo();
00204 INT num_dim = dinfo->Num_Dim();
00205 INT curr_dim = lego_info->Dim_Num();
00206 Is_True((curr_dim >= 0) && (curr_dim < num_dim),
00207 ("Generate_Bounds: Bad dimension (%d) in LEGO_INFO, 0..%d expected",
00208 curr_dim, num_dim-1));
00209 FmtAssert(lego_info->Stride() > 0 || dact->Get_Dim(curr_dim)->Distr_Type()
00210 == DISTRIBUTE_BLOCK, ("Only can handle negative strides with BLOCK"));
00211 switch (dact->Get_Dim(curr_dim)->Distr_Type()) {
00212 case DISTRIBUTE_BLOCK:
00213
00214
00215
00216 if (lego_info->Stride() < 0) {
00217 bounds_code = Generate_Block_Bounds_Negative(dinfo, lego_info,
00218 doloop, new_lb, new_ub);
00219 } else {
00220 bounds_code = Generate_Block_Bounds(dinfo, lego_info, doloop,
00221 new_lb, new_ub);
00222 }
00223 break;
00224 case DISTRIBUTE_STAR:
00225
00226
00227
00228 return NULL;
00229
00230 case DISTRIBUTE_CYCLIC_CONST: {
00231 if (dact->Get_Dim(curr_dim)->Chunk_Const_Val() == 1) {
00232
00233
00234
00235 bounds_code = Generate_Cyclic_Bounds(dinfo, lego_info, doloop,
00236 new_lb, new_ub, new_step);
00237 } else {
00238
00239
00240
00241 bounds_code = Generate_Blkcyc_Bounds(dinfo, lego_info, doloop,
00242 new_lb, new_ub, new_step,
00243 bound);
00244 }
00245 break;
00246 }
00247
00248
00249
00250 case DISTRIBUTE_CYCLIC_EXPR: {
00251 bounds_code = Generate_Blkcyc_Bounds(dinfo, lego_info, doloop,
00252 new_lb, new_ub, new_step, bound);
00253 }
00254 }
00255
00256 }
00257
00258 return bounds_code;
00259 }
00260
00261
00262
00263
00264
00265
00266
00267
00268 BOOL
00269 Loop_Bounds_Simple(const WN *doloop)
00270 {
00271 INT64 step = Step_Size((WN *)doloop);
00272 if (step != 1) return FALSE;
00273
00274 BOOL ub_ok = Upper_Bound_Standardize(WN_end(doloop), TRUE);
00275 return (ub_ok);
00276 }
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290 static WN* Highest_Unique_Definition(WN* wn_ldid,
00291 DU_MANAGER* du)
00292 {
00293 if (WN_operator(wn_ldid) != OPR_LDID)
00294 return wn_ldid;
00295 DEF_LIST* def_list = du->Ud_Get_Def(wn_ldid);
00296 if (def_list == NULL || def_list->Incomplete())
00297 return wn_ldid;
00298 DEF_LIST_ITER iter(def_list);
00299 const DU_NODE* node = NULL;
00300 INT count = 0;
00301 WN* wn_def = NULL;
00302 for (node = iter.First(); !iter.Is_Empty(); node = iter.Next()) {
00303 wn_def = node->Wn();
00304 if (WN_operator(wn_def) != OPR_STID
00305 || SYMBOL(wn_def) != SYMBOL(wn_ldid) || ++count > 1)
00306 return wn_ldid;
00307 }
00308 return Highest_Unique_Definition(WN_kid0(wn_def), du);
00309 }
00310
00311
00312
00313
00314
00315
00316
00317
00318 static WN* LWN_Copy_Tree_With_High_Defs(WN* wn_tree,
00319 DU_MANAGER* du)
00320 {
00321 WN* wn_tree_copy = LWN_Copy_Tree(wn_tree);
00322 LWN_Copy_Def_Use(wn_tree, wn_tree_copy, du);
00323 LWN_ITER* itr_next = NULL;
00324 LWN_ITER* itr = LWN_WALK_TreeIter(wn_tree_copy);
00325 for (; itr != NULL; itr = itr_next) {
00326 WN* wn = itr->wn;
00327 itr_next = LWN_WALK_TreeNext(itr);
00328 if (WN_operator(wn) != OPR_LDID)
00329 continue;
00330 WN* new_def = Highest_Unique_Definition(wn, du);
00331 if (new_def == wn)
00332 continue;
00333 WN* wn_new = Replace_Wnexp_With_Exp_Copy(wn, new_def, du);
00334 if (wn == wn_tree_copy)
00335 wn_tree_copy = wn_new;
00336 }
00337 return wn_tree_copy;
00338 }
00339
00340
00341
00342
00343
00344
00345
00346
00347 static WN* Affinity_Array_Lower_Bound(const WN* wn_loop)
00348 {
00349 TYPE_ID index_type = WN_desc(WN_start(wn_loop));
00350 return LWN_Make_Icon(index_type, 0);
00351 }
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361 static WN* Affinity_Array_Upper_Bound(const WN* wn_loop)
00362 {
00363 TYPE_ID index_type = WN_desc(WN_start(wn_loop));
00364 WN* wn_one = LWN_Make_Icon(index_type, 1);
00365 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn_loop);
00366 SYMBOL* sym = dli->Lego_Info->Array();
00367 DISTR_ARRAY* dact = Lookup_DACT(sym->St());
00368 WN* wn_size = dact->Array_Size_WN(dli->Lego_Info->Dim_Num());
00369 WN* wn_upper_bound = AWN_Sub(index_type, wn_size, wn_one);
00370 return wn_upper_bound;
00371 }
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386 static BOOL Lower_Bound_In_Affinity_Range(const WN* wn_loop,
00387 BOOL negative_stride,
00388 DU_MANAGER* du)
00389 {
00390 BOOL result = FALSE;
00391 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn_loop);
00392 LEGO_INFO* lego_info = dli->Lego_Info;
00393 FmtAssert(lego_info != NULL,
00394 ("Lower_Bound_In_Affinity_Range() called on loop w/o LEGO_INFO\n"));
00395 WN* wn_bound_array = negative_stride ? Affinity_Array_Upper_Bound(wn_loop)
00396 : Affinity_Array_Lower_Bound(wn_loop);
00397 if (wn_bound_array == NULL)
00398 return FALSE;
00399 TYPE_ID index_type = WN_desc(WN_start(wn_loop));
00400 WN* wn_stride = LWN_Make_Icon(index_type, lego_info->Stride());
00401 WN* wn_offset = LWN_Make_Icon(index_type, lego_info->Offset());
00402 WN* wn_lb_loop = LWN_Copy_Tree_With_High_Defs(WN_kid0(WN_start(wn_loop)), du);
00403 WN* wn_mul = AWN_Mpy(index_type, wn_stride, wn_lb_loop);
00404 WN* wn_affinity = AWN_Add(index_type, wn_mul, wn_offset);
00405 WN* wn_cmpzero = AWN_Sub(index_type, wn_affinity, wn_bound_array);
00406 wn_cmpzero = WN_Simplify_Tree(wn_cmpzero);
00407 if (negative_stride) {
00408 result = (WN_operator(wn_cmpzero) == OPR_INTCONST
00409 && WN_const_val(wn_cmpzero) <= 0);
00410 } else {
00411 result = (WN_operator(wn_cmpzero) == OPR_INTCONST
00412 && WN_const_val(wn_cmpzero) >= 0);
00413 }
00414 LWN_Delete_Tree(wn_cmpzero);
00415 return result;
00416 }
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432 static BOOL Upper_Bound_In_Affinity_Range(const WN* wn_loop,
00433 BOOL negative_stride,
00434 DU_MANAGER* du)
00435
00436 {
00437 BOOL result = FALSE;
00438 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn_loop);
00439 LEGO_INFO* lego_info = dli->Lego_Info;
00440 FmtAssert(lego_info != NULL,
00441 ("Lower_Bound_In_Affinity_Range() called on loop w/o LEGO_INFO\n"));
00442 WN* wn_bound_array_orig = negative_stride ?
00443 Affinity_Array_Lower_Bound(wn_loop) : Affinity_Array_Upper_Bound(wn_loop);
00444 if (wn_bound_array_orig == NULL)
00445 return FALSE;
00446 if (!Upper_Bound_Standardize(WN_end(wn_loop), TRUE))
00447 return FALSE;
00448 WN* wn_ub_loop = LWN_Copy_Tree_With_High_Defs(UBexp(WN_end(wn_loop)), du);
00449 WN* wn_bound_array = LWN_Copy_Tree_With_High_Defs(wn_bound_array_orig, du);
00450 LWN_Delete_Tree(wn_bound_array_orig);
00451 TYPE_ID index_type = WN_desc(WN_start(wn_loop));
00452 WN* wn_stride = LWN_Make_Icon(index_type, lego_info->Stride());
00453 WN* wn_offset = LWN_Make_Icon(index_type, lego_info->Offset());
00454 WN* wn_mul = AWN_Mpy(index_type, wn_stride, wn_ub_loop);
00455 WN* wn_affinity = AWN_Add(index_type, wn_mul, wn_offset);
00456 WN* wn_cmpzero = AWN_Sub(index_type, wn_affinity, wn_bound_array);
00457 wn_cmpzero = WN_Simplify_Tree(wn_cmpzero);
00458 if (negative_stride) {
00459 result = (WN_operator(wn_cmpzero) == OPR_INTCONST
00460 && WN_const_val(wn_cmpzero) >= 0);
00461 } else {
00462 result = (WN_operator(wn_cmpzero) == OPR_INTCONST
00463 && WN_const_val(wn_cmpzero) <= 0);
00464 }
00465 LWN_Delete_Tree(wn_cmpzero);
00466 return result;
00467 }
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478 static WN* Extended_Lower_Bound(WN* wn_gen,
00479 const WN* wn_loop,
00480 TYPE_ID type,
00481 SYMBOL* new_lb,
00482 BOOL negative_stride,
00483 DU_MANAGER* du)
00484 {
00485 WN* wn_gen_rhs = WN_kid0(wn_gen);
00486 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn_loop);
00487 SYMBOL* pid = dli->Lego_Info->Pid_Sym0();
00488 WN* wn_cond = NULL;
00489 if (negative_stride) {
00490 WN* wn_num_threads = Get_Numthreads_Ldid(dli->Lego_Info);
00491 TYPE_ID desc = WN_desc(wn_num_threads);
00492 TYPE_ID index_type = Max_Wtype(type, desc);
00493 WN* wn_one = LWN_Make_Icon(index_type, 1);
00494 OPCODE subop = OPCODE_make_op(OPR_SUB, index_type, MTYPE_V);
00495 WN* wn_proc_ub = LWN_CreateExp2(subop, wn_num_threads, wn_one);
00496 OPCODE eq_op = OPCODE_make_op(OPR_EQ, Boolean_type, index_type);
00497 wn_cond = LWN_CreateExp2(eq_op, AWN_LdidSym(pid), wn_proc_ub);
00498 } else {
00499 WN* wn_proc_lb = LWN_Make_Icon(type, 0);
00500 OPCODE eq_op =
00501 OPCODE_make_op(OPR_EQ, Boolean_type, type);
00502 wn_cond = LWN_CreateExp2(eq_op, AWN_LdidSym(pid), wn_proc_lb);
00503 }
00504 WN* wn_orig = LWN_Copy_Tree(WN_kid0(WN_start(wn_loop)));
00505 LWN_Copy_Def_Use(WN_kid0(WN_start(wn_loop)), wn_orig, du);
00506 WN* wn_else = wn_gen;
00507 WN* wn_gen_copy = LWN_Copy_Tree(wn_gen_rhs);
00508 LWN_Copy_Def_Use(wn_gen_rhs, wn_gen_copy, du);
00509 WN* wn_then = AWN_Min(type, wn_orig, wn_gen_copy);
00510 wn_then = AWN_StidIntoSym(new_lb, wn_then);
00511 WN* wn_if = LWN_CreateIf(wn_cond, WN_CreateBlock(), WN_CreateBlock());
00512 LWN_Insert_Block_After(WN_then(wn_if), NULL, wn_then);
00513 LWN_Insert_Block_After(WN_else(wn_if), NULL, wn_else);
00514 WN_Set_Linenum(wn_if, WN_Get_Linenum(wn_loop));
00515 IF_INFO *ii =
00516 CXX_NEW(IF_INFO(&LNO_default_pool, FALSE, FALSE), &LNO_default_pool);
00517 WN_MAP_Set(LNO_Info_Map, wn_if, (void *) ii);
00518 DOLOOP_STACK *stack = CXX_NEW(DOLOOP_STACK(LEGO_pool), LEGO_pool);
00519 Build_Doloop_Stack(wn_if, stack);
00520 LNO_Build_If_Access(wn_if, stack);
00521 CXX_DELETE(stack, LEGO_pool);
00522 return wn_if;
00523 }
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534 static WN* Extended_Upper_Bound(WN* wn_gen,
00535 const WN* wn_loop,
00536 TYPE_ID type,
00537 SYMBOL* new_ub,
00538 BOOL negative_stride,
00539 DU_MANAGER* du)
00540 {
00541 WN* wn_gen_rhs = WN_kid0(wn_gen);
00542 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn_loop);
00543 SYMBOL* pid = dli->Lego_Info->Pid_Sym0();
00544 FmtAssert(!dli->Lego_Info->Dynamic_Affinity(),
00545 ("Should not call this lego tiling with dynamic affinity"));
00546 WN* wn_cond = NULL;
00547 if (negative_stride) {
00548 WN* wn_proc_lb = LWN_Make_Icon(type, 0);
00549 OPCODE eq_op =
00550 OPCODE_make_op(OPR_EQ, Boolean_type, type);
00551 wn_cond = LWN_CreateExp2(eq_op, AWN_LdidSym(pid), wn_proc_lb);
00552 } else {
00553 WN* wn_num_threads = Get_Numthreads_Ldid(dli->Lego_Info);
00554 TYPE_ID desc = WN_desc(wn_num_threads);
00555 TYPE_ID index_type = Max_Wtype(type, desc);
00556 WN* wn_one = LWN_Make_Icon(index_type, 1);
00557 OPCODE subop = OPCODE_make_op(OPR_SUB, index_type, MTYPE_V);
00558 WN* wn_proc_ub = LWN_CreateExp2(subop, wn_num_threads, wn_one);
00559 OPCODE eq_op = OPCODE_make_op(OPR_EQ, Boolean_type, index_type);
00560 wn_cond = LWN_CreateExp2(eq_op, AWN_LdidSym(pid), wn_proc_ub);
00561 }
00562 WN* wn_orig = LWN_Copy_Tree(UBexp(WN_end(wn_loop)));
00563 LWN_Copy_Def_Use(UBexp(WN_end(wn_loop)), wn_orig, du);
00564 WN* wn_else = wn_gen;
00565 WN* wn_gen_copy = LWN_Copy_Tree(wn_gen_rhs);
00566 LWN_Copy_Def_Use(wn_gen_rhs, wn_gen_copy, du);
00567 WN* wn_then = AWN_Max(type, wn_orig, wn_gen_copy);
00568 wn_then = AWN_StidIntoSym(new_ub, wn_then);
00569 WN* wn_if = LWN_CreateIf(wn_cond, WN_CreateBlock(), WN_CreateBlock());
00570 LWN_Insert_Block_After(WN_then(wn_if), NULL, wn_then);
00571 LWN_Insert_Block_After(WN_else(wn_if), NULL, wn_else);
00572 WN_Set_Linenum(wn_if, WN_Get_Linenum(wn_loop));
00573 IF_INFO *ii =
00574 CXX_NEW(IF_INFO(&LNO_default_pool, FALSE, FALSE), &LNO_default_pool);
00575 WN_MAP_Set(LNO_Info_Map, wn_if, (void *) ii);
00576 DOLOOP_STACK *stack = CXX_NEW(DOLOOP_STACK(LEGO_pool), LEGO_pool);
00577 Build_Doloop_Stack(wn_if, stack);
00578 LNO_Build_If_Access(wn_if, stack);
00579 CXX_DELETE(stack, LEGO_pool);
00580 return wn_if;
00581 }
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601 WN *
00602 Generate_Block_Bounds(DISTR_INFO *dinfo,
00603 LEGO_INFO *lego_info,
00604 const WN *doloop,
00605 SYMBOL **new_lb,
00606 SYMBOL **new_ub)
00607 {
00608 INT64 linenum = WN_Get_Linenum(doloop);
00609 WN *bounds_code = WN_CreateBlock();
00610 WN_Set_Linenum(bounds_code, linenum);
00611
00612 WN *curr_lb_wn = WN_kid0(WN_start(doloop));
00613 WN *curr_ub_wn = UBexp(WN_end(doloop));
00614 INT curr_dim = lego_info->Dim_Num();
00615
00616 SYMBOL *my_pid = lego_info->Pid_Sym0();
00617 SYMBOL *dim_size = dinfo->Get_Dimsize(curr_dim);
00618
00619 Is_True(my_pid && dim_size,
00620 ("Generate_Block_Bounds: Bad pid and/or dim_size\n"));
00621
00622 FmtAssert((lego_info->Stride() > 0),
00623 ("Generate_Block_Bounds called with stride <= 0"));
00624
00625
00626
00627
00628 TYPE_ID type = Promote_Type(Do_Wtype((WN *) doloop));
00629 WN *new_lb_wn = AWN_Mpy(type,AWN_LdidSym(my_pid),dinfo->Dimsize(curr_dim));
00630 new_lb_wn = AWN_Sub(type, new_lb_wn,
00631 LWN_Make_Icon(type, lego_info->Offset()));
00632 if (lego_info->Stride() != 1) {
00633 new_lb_wn = LWN_CreateDivceil(type, new_lb_wn,
00634 LWN_Make_Icon(type, lego_info->Stride()));
00635 }
00636
00637 WN *curr_lb_copy = LWN_Copy_Tree(curr_lb_wn);
00638 LWN_Copy_Def_Use(curr_lb_wn, curr_lb_copy, Du_Mgr);
00639 new_lb_wn = AWN_Max(type, new_lb_wn, curr_lb_copy);
00640 sprintf(Str_Buf, "$dsm_block_lb%d", WN_map_id(doloop));
00641 *new_lb = CXX_NEW(SYMBOL(Create_Preg_Symbol(Str_Buf, type)), LEGO_pool);
00642 new_lb_wn = AWN_StidIntoSym(*new_lb, new_lb_wn);
00643 if (!Lower_Bound_In_Affinity_Range(doloop, FALSE, Du_Mgr))
00644 new_lb_wn = Extended_Lower_Bound(new_lb_wn, doloop, type, *new_lb,
00645 FALSE, Du_Mgr);
00646 WN_Set_Linenum(new_lb_wn, linenum);
00647 LWN_Insert_Block_After(bounds_code, NULL, new_lb_wn);
00648
00649
00650
00651
00652 WN *new_ub_wn = AWN_Add(type, AWN_LdidSym(my_pid), LWN_Make_Icon(type, 1));
00653 new_ub_wn = AWN_Mpy(type, new_ub_wn, dinfo->Dimsize(curr_dim));
00654 new_ub_wn = AWN_Sub(type, new_ub_wn, LWN_Make_Icon(type, lego_info->Offset() + 1));
00655
00656 if (lego_info->Stride() != 1) {
00657 new_ub_wn = LWN_CreateDivfloor(type, new_ub_wn,
00658 LWN_Make_Icon(type, lego_info->Stride()));
00659 }
00660
00661 WN *curr_ub_copy = LWN_Copy_Tree(curr_ub_wn);
00662 LWN_Copy_Def_Use(curr_ub_wn, curr_ub_copy, Du_Mgr);
00663 new_ub_wn = AWN_Min(type, new_ub_wn, curr_ub_copy);
00664 sprintf(Str_Buf, "$dsm_block_ub%d", WN_map_id(doloop));
00665 *new_ub = CXX_NEW(SYMBOL(Create_Preg_Symbol(Str_Buf, type)), LEGO_pool);
00666 new_ub_wn = AWN_StidIntoSym(*new_ub, new_ub_wn);
00667 if (!Upper_Bound_In_Affinity_Range(doloop, FALSE, Du_Mgr))
00668 new_ub_wn = Extended_Upper_Bound(new_ub_wn, doloop, type, *new_ub,
00669 FALSE, Du_Mgr);
00670 WN_Set_Linenum(new_ub_wn, linenum);
00671 LWN_Insert_Block_After(bounds_code, NULL, new_ub_wn);
00672
00673
00674
00675
00676 DO_LOOP_INFO* dli = Get_Do_Loop_Info(doloop);
00677 if (dli->Mp_Info != NULL) {
00678 FmtAssert(WN_operator(WN_end(doloop)) == OPR_LE,
00679 ("Loop is not in standard form"));
00680 WN* wn_ub_loop = LWN_Copy_Tree(WN_kid1(WN_end(doloop)));
00681 LWN_Copy_Def_Use(WN_kid1(WN_end(doloop)), wn_ub_loop, Du_Mgr);
00682 WN* wn_stride = LWN_Make_Icon(type, lego_info->Stride());
00683 WN* wn_offset = LWN_Make_Icon(type, lego_info->Offset());
00684 WN* wn_mul = AWN_Mpy(type, wn_stride, wn_ub_loop);
00685 WN* wn_index = AWN_Add(type, wn_mul, wn_offset);
00686 WN* wn_div = AWN_Div_Safe(type, wn_index, dinfo->Dimsize(curr_dim));
00687 FmtAssert(!dli->Lego_Info->Dynamic_Affinity(),
00688 ("Should not call this lego tiling with dynamic affinity"));
00689 WN* wn_last_proc = AWN_Min(type, wn_div, Get_Numthreads_Ldid(lego_info));
00690 OPCODE op_eq = OPCODE_make_op(OPR_EQ, Boolean_type, type);
00691 WN* wn_cond = LWN_CreateExp2(op_eq, AWN_LdidSym(my_pid), wn_last_proc);
00692 sprintf(Str_Buf, "$da_last_iter%d", WN_map_id(doloop));
00693 SYMBOL* sym_last_iter = CXX_NEW(SYMBOL(Create_Preg_Symbol(Str_Buf, type)),
00694 &LNO_default_pool);
00695 WN* wn_last_iter = AWN_StidIntoSym(sym_last_iter, wn_cond);
00696 WN_Set_Linenum(wn_last_iter, linenum);
00697 LWN_Insert_Block_After(bounds_code, NULL, wn_last_iter);
00698 if (dli->Mp_Info->Nest_Total() == 1)
00699 Du_Mgr->Add_Def_Use(wn_last_iter, Return_Node(Current_Func_Node));
00700 WN* wn_region = NULL;
00701 for (wn_region = (WN*) doloop; wn_region != NULL;
00702 wn_region = LWN_Get_Parent(wn_region))
00703 if (WN_opcode(wn_region) == OPC_REGION)
00704 break;
00705 FmtAssert(wn_region != NULL, ("Could not find region."));
00706 WN* wn_pragma = WN_CreatePragma(WN_PRAGMA_MPSCHEDTYPE,
00707 ST_IDX_ZERO,
00708 (INT32) WN_PRAGMA_SCHEDTYPE_PSEUDOLOWERED,
00709 0);
00710 LWN_Insert_Block_Before(WN_region_pragmas(wn_region), NULL, wn_pragma);
00711 Add_Pragma_To_MP_Region(doloop, sym_last_iter->St(),
00712 sym_last_iter->WN_Offset(), WN_PRAGMA_LASTTHREAD);
00713 }
00714
00715 return bounds_code;
00716 }
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744 static WN* Generate_Block_Bounds_Negative(DISTR_INFO *dinfo,
00745 LEGO_INFO *lego_info,
00746 const WN *doloop,
00747 SYMBOL **new_lb,
00748 SYMBOL **new_ub)
00749 {
00750 INT64 linenum = WN_Get_Linenum(doloop);
00751 WN *bounds_code = WN_CreateBlock();
00752 WN_Set_Linenum(bounds_code, linenum);
00753
00754 WN* curr_lb_wn = WN_kid0(WN_start(doloop));
00755 WN* curr_ub_wn = UBexp(WN_end(doloop));
00756 WN* curr_step_wn = Loop_Step((WN*) doloop);
00757 INT curr_dim = lego_info->Dim_Num();
00758
00759 SYMBOL *my_pid = lego_info->Pid_Sym0();
00760 SYMBOL *dim_size = dinfo->Get_Dimsize(curr_dim);
00761 SYMBOL* new_tmp = NULL;
00762
00763 Is_True(my_pid && dim_size,
00764 ("Generate_Block_Bounds: Bad pid and/or dim_size\n"));
00765
00766
00767
00768 TYPE_ID type = Promote_Type(Do_Wtype((WN *) doloop));
00769 WN* wn_add = AWN_Add(type, AWN_LdidSym(my_pid), LWN_Make_Icon(type, 1));
00770 WN* wn_prod = AWN_Mpy(type, dinfo->Dimsize(curr_dim), wn_add);
00771 WN* wn_const = LWN_Make_Icon(type, lego_info->Offset() + 1);
00772 WN* wn_sub = AWN_Sub(type, wn_const, wn_prod);
00773 WN* wn_abs_stride = LWN_Make_Icon(type, -lego_info->Stride());
00774 WN* wn_divceil = LWN_CreateDivceil(type, wn_sub, wn_abs_stride);
00775 WN* new_lb_wn = NULL;
00776 WN* wn_lb_copy = LWN_Copy_Tree(curr_lb_wn);
00777 LWN_Copy_Def_Use(curr_lb_wn, wn_lb_copy, Du_Mgr);
00778 WN* wn_max = AWN_Max(type, wn_lb_copy, wn_divceil);
00779 sprintf(Str_Buf, "$dsm_block_lb%d", WN_map_id(doloop));
00780 *new_lb = CXX_NEW(SYMBOL(Create_Preg_Symbol(Str_Buf, type)), LEGO_pool);
00781 new_lb_wn = AWN_StidIntoSym(*new_lb, wn_max);
00782 if (!Lower_Bound_In_Affinity_Range(doloop, TRUE, Du_Mgr))
00783 new_lb_wn = Extended_Lower_Bound(new_lb_wn, doloop, type, *new_lb,
00784 TRUE, Du_Mgr);
00785 WN_Set_Linenum(new_lb_wn, linenum);
00786 LWN_Insert_Block_After(bounds_code, NULL, new_lb_wn);
00787
00788
00789
00790
00791 wn_prod = AWN_Mpy(type, AWN_LdidSym(my_pid), dinfo->Dimsize(curr_dim));
00792 wn_sub = AWN_Sub(type, LWN_Make_Icon(type, lego_info->Offset()), wn_prod);
00793 wn_abs_stride = LWN_Make_Icon(type, -lego_info->Stride());
00794 WN* wn_divfloor = LWN_CreateDivfloor(type, wn_sub, wn_abs_stride);
00795 WN* wn_ub_copy = LWN_Copy_Tree(curr_ub_wn);
00796 LWN_Copy_Def_Use(curr_ub_wn, wn_ub_copy, Du_Mgr);
00797 WN* wn_min = AWN_Min(type, wn_ub_copy, wn_divfloor);
00798 sprintf(Str_Buf, "$dsm_block_ub%d", WN_map_id(doloop));
00799 *new_ub = CXX_NEW(SYMBOL(Create_Preg_Symbol(Str_Buf, type)), LEGO_pool);
00800 WN* new_ub_wn = AWN_StidIntoSym(*new_ub, wn_min);
00801 if (!Upper_Bound_In_Affinity_Range(doloop, TRUE, Du_Mgr))
00802 new_ub_wn = Extended_Upper_Bound(new_ub_wn, doloop, type, *new_ub,
00803 TRUE, Du_Mgr);
00804 WN_Set_Linenum(new_ub_wn, linenum);
00805 LWN_Insert_Block_After(bounds_code, NULL, new_ub_wn);
00806
00807
00808
00809
00810 DO_LOOP_INFO* dli = Get_Do_Loop_Info(doloop);
00811 if (dli->Mp_Info != NULL) {
00812 FmtAssert(WN_operator(WN_end(doloop)) == OPR_LE,
00813 ("Loop is not in standard form"));
00814 WN* wn_ub_loop = LWN_Copy_Tree(WN_kid1(WN_end(doloop)));
00815 LWN_Copy_Def_Use(WN_kid1(WN_end(doloop)), wn_ub_loop, Du_Mgr);
00816 WN* wn_stride = LWN_Make_Icon(type, lego_info->Stride());
00817 WN* wn_offset = LWN_Make_Icon(type, lego_info->Offset());
00818 WN* wn_mul = AWN_Mpy(type, wn_stride, wn_ub_loop);
00819 WN* wn_index = AWN_Add(type, wn_mul, wn_offset);
00820 WN* wn_div = AWN_Div_Safe(type, wn_index, dinfo->Dimsize(curr_dim));
00821 FmtAssert(!dli->Lego_Info->Dynamic_Affinity(),
00822 ("Should not call this lego tiling with dynamic affinity"));
00823 WN* wn_last_proc = AWN_Max(type, wn_div, LWN_Make_Icon(type, 0));
00824 OPCODE op_eq = OPCODE_make_op(OPR_EQ, Boolean_type, type);
00825 WN* wn_cond = LWN_CreateExp2(op_eq, AWN_LdidSym(my_pid), wn_last_proc);
00826 sprintf(Str_Buf, "$da_last_iter%d", WN_map_id(doloop));
00827 SYMBOL* sym_last_iter = CXX_NEW(SYMBOL(Create_Preg_Symbol(Str_Buf, type)),
00828 &LNO_default_pool);
00829 WN* wn_last_iter = AWN_StidIntoSym(sym_last_iter, wn_cond);
00830 WN_Set_Linenum(wn_last_iter, linenum);
00831 LWN_Insert_Block_After(bounds_code, NULL, wn_last_iter);
00832 if (dli->Mp_Info->Nest_Total() == 1)
00833 Du_Mgr->Add_Def_Use(wn_last_iter, Return_Node(Current_Func_Node));
00834 WN* wn_region = NULL;
00835 for (wn_region = (WN*) doloop; wn_region != NULL;
00836 wn_region = LWN_Get_Parent(wn_region))
00837 if (WN_opcode(wn_region) == OPC_REGION)
00838 break;
00839 FmtAssert(wn_region != NULL, ("Could not find region."));
00840 WN* wn_pragma = WN_CreatePragma(WN_PRAGMA_MPSCHEDTYPE,
00841 ST_IDX_ZERO,
00842 (INT32) WN_PRAGMA_SCHEDTYPE_PSEUDOLOWERED,
00843 0);
00844 LWN_Insert_Block_Before(WN_region_pragmas(wn_region), NULL, wn_pragma);
00845 Add_Pragma_To_MP_Region(doloop, sym_last_iter->St(),
00846 sym_last_iter->WN_Offset(), WN_PRAGMA_LASTTHREAD);
00847 }
00848
00849 return bounds_code;
00850 }
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872 WN *
00873 Generate_Cyclic_Bounds(DISTR_INFO *dinfo,
00874 LEGO_INFO *lego_info,
00875 const WN *doloop,
00876 SYMBOL **new_lb,
00877 SYMBOL **new_ub,
00878 SYMBOL **new_step)
00879 {
00880 if (lego_info->Stride() > 1) {
00881 return Generate_Runtime_Cyclic_Bounds(dinfo, lego_info, doloop,
00882 new_lb, new_ub, new_step);
00883 }
00884
00885 INT64 linenum = WN_Get_Linenum(doloop);
00886 WN *bounds_code = WN_CreateBlock();
00887 WN_Set_Linenum(bounds_code, linenum);
00888
00889 WN *curr_lb_wn = WN_kid0(WN_start(doloop));
00890 WN *curr_ub_wn = UBexp(WN_end(doloop));
00891
00892 INT curr_dim = lego_info->Dim_Num();
00893
00894 SYMBOL *my_pid = lego_info->Pid_Sym0();
00895 SYMBOL *num_procs = dinfo->Get_Numprocs(curr_dim);
00896
00897 Is_True(my_pid && num_procs,
00898 ("Generate_Cyclic_Bounds: Bad pid and/or num_procs\n"));
00899
00900 FmtAssert((lego_info->Stride() > 0),
00901 ("Generate_Cyclic_Bounds called with stride <= 0"));
00902
00903
00904
00905
00906 TYPE_ID type = Promote_Type(Do_Wtype((WN *) doloop));
00907 WN *curr_lb_copy = LWN_Copy_Tree(curr_lb_wn);
00908 LWN_Copy_Def_Use(curr_lb_wn, curr_lb_copy, Du_Mgr);
00909 WN *new_lb_wn = AWN_Sub(type, AWN_LdidSym(my_pid), curr_lb_copy);
00910 new_lb_wn = AWN_Sub(type, new_lb_wn,
00911 LWN_Make_Icon(type, lego_info->Offset()));
00912 new_lb_wn = AWN_Mod_Safe(type, new_lb_wn, dinfo->Numprocs(curr_dim));
00913
00914 curr_lb_copy = LWN_Copy_Tree(curr_lb_wn);
00915 LWN_Copy_Def_Use(curr_lb_wn, curr_lb_copy, Du_Mgr);
00916 new_lb_wn = AWN_Add(type, new_lb_wn, curr_lb_copy);
00917
00918 sprintf(Str_Buf, "$dsm_cyclic_lb%d", WN_map_id(doloop));
00919 *new_lb = CXX_NEW(SYMBOL(Create_Preg_Symbol(Str_Buf, type)), LEGO_pool);
00920 new_lb_wn = AWN_StidIntoSym(*new_lb, new_lb_wn);
00921 WN_Set_Linenum(new_lb_wn, linenum);
00922 LWN_Insert_Block_After(bounds_code, NULL, new_lb_wn);
00923
00924
00925
00926
00927 WN *curr_ub_copy = LWN_Copy_Tree(curr_ub_wn);
00928 LWN_Copy_Def_Use(curr_ub_wn, curr_ub_copy, Du_Mgr);
00929
00930 sprintf(Str_Buf, "$dsm_cyclic_ub%d", WN_map_id(doloop));
00931 *new_ub = CXX_NEW(SYMBOL(Create_Preg_Symbol(Str_Buf, type)), LEGO_pool);
00932 WN *new_ub_wn = AWN_StidIntoSym(*new_ub, curr_ub_copy);
00933 WN_Set_Linenum(new_ub_wn, linenum);
00934 LWN_Insert_Block_After(bounds_code, NULL, new_ub_wn);
00935
00936
00937
00938
00939 sprintf(Str_Buf, "$dsm_cyclic_step%d", WN_map_id(doloop));
00940 *new_step = CXX_NEW(SYMBOL(Create_Preg_Symbol(Str_Buf, type)), LEGO_pool);
00941 WN *new_step_wn = AWN_StidIntoSym(*new_step, dinfo->Numprocs(curr_dim));
00942 WN_Set_Linenum(new_step_wn, linenum);
00943 LWN_Insert_Block_After(bounds_code, NULL, new_step_wn);
00944
00945
00946
00947
00948 DO_LOOP_INFO* dli = Get_Do_Loop_Info(doloop);
00949 if (dli->Mp_Info != NULL) {
00950 FmtAssert(WN_operator(WN_end(doloop)) == OPR_LE,
00951 ("Loop is not in standard form"));
00952 WN* wn_ub_loop = LWN_Copy_Tree(WN_kid1(WN_end(doloop)));
00953 LWN_Copy_Def_Use(WN_kid1(WN_end(doloop)), wn_ub_loop, Du_Mgr);
00954 WN* wn_stride = LWN_Make_Icon(type, lego_info->Stride());
00955 WN* wn_offset = LWN_Make_Icon(type, lego_info->Offset());
00956 WN* wn_mul = AWN_Mpy(type, wn_stride, wn_ub_loop);
00957 WN* wn_index = AWN_Add(type, wn_mul, wn_offset);
00958 FmtAssert(!dli->Lego_Info->Dynamic_Affinity(),
00959 ("Should not call this lego tiling with dynamic affinity"));
00960 WN* wn_last_proc = AWN_Mod_Safe(type, wn_index,
00961 Get_Numthreads_Ldid(lego_info));
00962 OPCODE op_eq = OPCODE_make_op(OPR_EQ, Boolean_type, type);
00963 WN* wn_cond = LWN_CreateExp2(op_eq, AWN_LdidSym(my_pid), wn_last_proc);
00964 sprintf(Str_Buf, "$da_last_iter%d", WN_map_id(doloop));
00965 SYMBOL* sym_last_iter = CXX_NEW(SYMBOL(Create_Preg_Symbol(Str_Buf, type)),
00966 &LNO_default_pool);
00967 WN* wn_last_iter = AWN_StidIntoSym(sym_last_iter, wn_cond);
00968 WN_Set_Linenum(wn_last_iter, linenum);
00969 LWN_Insert_Block_After(bounds_code, NULL, wn_last_iter);
00970 if (dli->Mp_Info->Nest_Total() == 1)
00971 Du_Mgr->Add_Def_Use(wn_last_iter, Return_Node(Current_Func_Node));
00972 WN* wn_region = NULL;
00973 for (wn_region = (WN*) doloop; wn_region != NULL;
00974 wn_region = LWN_Get_Parent(wn_region))
00975 if (WN_opcode(wn_region) == OPC_REGION)
00976 break;
00977 FmtAssert(wn_region != NULL, ("Could not find region."));
00978 WN* wn_pragma = WN_CreatePragma(WN_PRAGMA_MPSCHEDTYPE,
00979 ST_IDX_ZERO,
00980 (INT32) WN_PRAGMA_SCHEDTYPE_PSEUDOLOWERED,
00981 0);
00982 LWN_Insert_Block_Before(WN_region_pragmas(wn_region), NULL, wn_pragma);
00983 Add_Pragma_To_MP_Region(doloop, sym_last_iter->St(),
00984 sym_last_iter->WN_Offset(), WN_PRAGMA_LASTTHREAD);
00985 }
00986
00987 return bounds_code;
00988 }
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017 WN *
01018 Generate_Blkcyc_Bounds(DISTR_INFO *dinfo,
01019 LEGO_INFO *lego_info,
01020 const WN *doloop,
01021 SYMBOL **new_lb,
01022 SYMBOL **new_ub,
01023 SYMBOL **new_step,
01024 INT bound)
01025 {
01026 INT64 linenum = WN_Get_Linenum(doloop);
01027 WN *bounds_code = WN_CreateBlock();
01028 WN_Set_Linenum(bounds_code, linenum);
01029
01030 WN *curr_lb_wn = WN_kid0(WN_start(doloop));
01031 WN *curr_ub_wn = UBexp(WN_end(doloop));
01032
01033 INT curr_dim = lego_info->Dim_Num();
01034
01035 SYMBOL *my_pid0 = lego_info->Pid_Sym0();
01036 SYMBOL *my_pid1 = lego_info->Pid_Sym1();
01037 SYMBOL *num_procs = dinfo->Get_Numprocs(curr_dim);
01038
01039 Is_True(my_pid0 && my_pid1 && num_procs,
01040 ("Generate_Blkcyc_Bounds: Bad pid and/or num_procs\n"));
01041
01042 FmtAssert((lego_info->Stride() > 0),
01043 ("Generate_BlkCyc_Bounds called with stride <= 0"));
01044
01045 TYPE_ID type = Promote_Type(Do_Wtype((WN*) doloop));
01046 if (bound == 0) {
01047
01048
01049
01050
01051 WN *num_cycles_wn = AWN_Mpy(type, dinfo->Chunksize(curr_dim),
01052 dinfo->Numprocs(curr_dim));
01053
01054 WN *curr_lb_copy = LWN_Copy_Tree(curr_lb_wn);
01055 LWN_Copy_Def_Use(curr_lb_wn, curr_lb_copy, Du_Mgr);
01056 WN *new_lb_wn = AWN_Mpy(type, curr_lb_copy,
01057 LWN_Make_Icon(type,lego_info->Stride()));
01058 new_lb_wn = AWN_Add(type, new_lb_wn,
01059 LWN_Make_Icon(type, lego_info->Offset() + 1));
01060
01061 WN *num_cycles_copy = LWN_Copy_Tree(num_cycles_wn);
01062 LWN_Copy_Def_Use(num_cycles_wn, num_cycles_copy, Du_Mgr);
01063 new_lb_wn = LWN_CreateDivceil(type, new_lb_wn, num_cycles_copy);
01064 new_lb_wn = AWN_Sub(type, new_lb_wn, LWN_Make_Icon(type, 1));
01065
01066 sprintf(Str_Buf, "$dsm_blkcyc_outer_lb%d", WN_map_id(doloop));
01067 *new_lb = CXX_NEW(SYMBOL(Create_Preg_Symbol(Str_Buf, type)), LEGO_pool);
01068 new_lb_wn = AWN_StidIntoSym(*new_lb, new_lb_wn);
01069 WN_Set_Linenum(new_lb_wn, linenum);
01070 LWN_Insert_Block_After(bounds_code, NULL, new_lb_wn);
01071
01072
01073
01074
01075 WN *curr_ub_copy = LWN_Copy_Tree(curr_ub_wn);
01076 LWN_Copy_Def_Use(curr_ub_wn, curr_ub_copy, Du_Mgr);
01077 WN *new_ub_wn = AWN_Mpy(type, curr_ub_copy,
01078 LWN_Make_Icon(type,lego_info->Stride()));
01079 new_ub_wn = AWN_Add(type, new_ub_wn,
01080 LWN_Make_Icon(type, lego_info->Offset() + 1));
01081
01082 num_cycles_copy = LWN_Copy_Tree(num_cycles_wn);
01083 LWN_Copy_Def_Use(num_cycles_wn, num_cycles_copy, Du_Mgr);
01084 new_ub_wn = LWN_CreateDivceil(type, new_ub_wn, num_cycles_copy);
01085 new_ub_wn = AWN_Sub(type, new_ub_wn, LWN_Make_Icon(type, 1));
01086
01087 sprintf(Str_Buf, "$dsm_blkcyc_outer_ub%d", WN_map_id(doloop));
01088 *new_ub = CXX_NEW(SYMBOL(Create_Preg_Symbol(Str_Buf, type)), LEGO_pool);
01089 new_ub_wn = AWN_StidIntoSym(*new_ub, new_ub_wn);
01090 WN_Set_Linenum(new_ub_wn, linenum);
01091 LWN_Insert_Block_After(bounds_code, NULL, new_ub_wn);
01092
01093
01094
01095
01096 sprintf(Str_Buf, "$dsm_blkcyc_outer_step%d", WN_map_id(doloop));
01097 *new_step = CXX_NEW(SYMBOL(Create_Preg_Symbol(Str_Buf, type)), LEGO_pool);
01098 WN *new_step_wn = AWN_StidIntoSym(*new_step, LWN_Make_Icon(type, 1));
01099 WN_Set_Linenum(new_step_wn, linenum);
01100 LWN_Insert_Block_After(bounds_code, NULL, new_step_wn);
01101
01102 LWN_Delete_Tree(num_cycles_wn);
01103
01104
01105
01106
01107 DO_LOOP_INFO* dli = Get_Do_Loop_Info(doloop);
01108 if (dli->Mp_Info != NULL) {
01109 FmtAssert(WN_operator(WN_end(doloop)) == OPR_LE,
01110 ("Loop is not in standard form"));
01111 WN* wn_ub_loop = LWN_Copy_Tree(WN_kid1(WN_end(doloop)));
01112 LWN_Copy_Def_Use(WN_kid1(WN_end(doloop)), wn_ub_loop, Du_Mgr);
01113 WN* wn_stride = LWN_Make_Icon(type, lego_info->Stride());
01114 WN* wn_offset = LWN_Make_Icon(type, lego_info->Offset());
01115 WN* wn_mul = AWN_Mpy(type, wn_stride, wn_ub_loop);
01116 WN* wn_index = AWN_Add(type, wn_mul, wn_offset);
01117 WN* wn_div = AWN_Div_Safe(type, wn_index, dinfo->Chunksize(curr_dim));
01118 FmtAssert(!dli->Lego_Info->Dynamic_Affinity(),
01119 ("Should not call this lego tiling with dynamic affinity"));
01120 WN* wn_last_proc = AWN_Mod_Safe(type, wn_div,
01121 Get_Numthreads_Ldid(lego_info));
01122 OPCODE op_eq = OPCODE_make_op(OPR_EQ, Boolean_type, type);
01123 WN* wn_cond = LWN_CreateExp2(op_eq, AWN_LdidSym(my_pid0), wn_last_proc);
01124 sprintf(Str_Buf, "$da_last_iter%d", WN_map_id(doloop));
01125 SYMBOL* sym_last_iter = CXX_NEW(SYMBOL(Create_Preg_Symbol(Str_Buf, type)),
01126 &LNO_default_pool);
01127 WN* wn_last_iter = AWN_StidIntoSym(sym_last_iter, wn_cond);
01128 WN_Set_Linenum(wn_last_iter, linenum);
01129 LWN_Insert_Block_After(bounds_code, NULL, wn_last_iter);
01130 if (dli->Mp_Info->Nest_Total() == 1)
01131 Du_Mgr->Add_Def_Use(wn_last_iter, Return_Node(Current_Func_Node));
01132 WN* wn_region = NULL;
01133 for (wn_region = (WN*) doloop; wn_region != NULL;
01134 wn_region = LWN_Get_Parent(wn_region))
01135 if (WN_opcode(wn_region) == OPC_REGION)
01136 break;
01137 FmtAssert(wn_region != NULL, ("Could not find region."));
01138 WN* wn_pragma = WN_CreatePragma(WN_PRAGMA_MPSCHEDTYPE,
01139 ST_IDX_ZERO,
01140 (INT32)WN_PRAGMA_SCHEDTYPE_PSEUDOLOWERED,
01141 0);
01142 LWN_Insert_Block_Before(WN_region_pragmas(wn_region), NULL, wn_pragma);
01143 Add_Pragma_To_MP_Region(doloop, sym_last_iter->St(),
01144 sym_last_iter->WN_Offset(), WN_PRAGMA_LASTTHREAD);
01145 }
01146
01147 } else {
01148
01149 FmtAssert(bound == 1,
01150 ("Generate_Blkcyc_Bounds: Only bound = {0,1} is valid."));
01151
01152
01153
01154
01155 WN *curr_cycle_wn = AWN_Mpy(type, dinfo->Chunksize(curr_dim),
01156 dinfo->Numprocs(curr_dim));
01157 curr_cycle_wn = AWN_Mpy(type, curr_cycle_wn, AWN_LdidSym(my_pid1));
01158 WN *new_lb_wn = AWN_Mpy(type, dinfo->Chunksize(curr_dim),
01159 AWN_LdidSym(my_pid0));
01160 new_lb_wn = AWN_Sub(type, new_lb_wn, LWN_Make_Icon(type,
01161 lego_info->Offset()));
01162
01163 WN *curr_cycle_copy = LWN_Copy_Tree(curr_cycle_wn);
01164 LWN_Copy_Def_Use(curr_cycle_wn, curr_cycle_copy, Du_Mgr);
01165 new_lb_wn = AWN_Add(type, new_lb_wn, curr_cycle_copy);
01166
01167 if (lego_info->Stride() != 1) {
01168 new_lb_wn = LWN_CreateDivceil(type, new_lb_wn,
01169 LWN_Make_Icon(type, lego_info->Stride()));
01170 }
01171
01172 WN *curr_lb_copy = LWN_Copy_Tree(curr_lb_wn);
01173 LWN_Copy_Def_Use(curr_lb_wn, curr_lb_copy, Du_Mgr);
01174 new_lb_wn = AWN_Max(type, curr_lb_copy, new_lb_wn);
01175
01176 sprintf(Str_Buf, "$dsm_blkcyc_inner_lb%d", WN_map_id(doloop));
01177 *new_lb = CXX_NEW(SYMBOL(Create_Preg_Symbol(Str_Buf, type)), LEGO_pool);
01178 new_lb_wn = AWN_StidIntoSym(*new_lb, new_lb_wn);
01179 WN_Set_Linenum(new_lb_wn, linenum);
01180 LWN_Insert_Block_After(bounds_code, NULL, new_lb_wn);
01181
01182
01183
01184
01185 WN *new_ub_wn = AWN_Add(type, AWN_LdidSym(my_pid0), LWN_Make_Icon(type, 1));
01186 new_ub_wn = AWN_Mpy(type, new_ub_wn, dinfo->Chunksize(curr_dim));
01187 new_ub_wn = AWN_Sub(type, new_ub_wn,
01188 LWN_Make_Icon(type, lego_info->Offset() + 1));
01189
01190 curr_cycle_copy = LWN_Copy_Tree(curr_cycle_wn);
01191 LWN_Copy_Def_Use(curr_cycle_wn, curr_cycle_copy, Du_Mgr);
01192 new_ub_wn = AWN_Add(type, new_ub_wn, curr_cycle_copy);
01193
01194 if (lego_info->Stride() != 1) {
01195 new_ub_wn = LWN_CreateDivfloor(type, new_ub_wn,
01196 LWN_Make_Icon(type, lego_info->Stride()));
01197 }
01198
01199 WN *curr_ub_copy = LWN_Copy_Tree(curr_ub_wn);
01200 LWN_Copy_Def_Use(curr_ub_wn, curr_ub_copy, Du_Mgr);
01201 new_ub_wn = AWN_Min(type, curr_ub_copy, new_ub_wn);
01202
01203 sprintf(Str_Buf, "$dsm_blkcyc_inner_ub%d", WN_map_id(doloop));
01204 *new_ub = CXX_NEW(SYMBOL(Create_Preg_Symbol(Str_Buf, type)), LEGO_pool);
01205 new_ub_wn = AWN_StidIntoSym(*new_ub, new_ub_wn);
01206 WN_Set_Linenum(new_ub_wn, linenum);
01207 LWN_Insert_Block_After(bounds_code, NULL, new_ub_wn);
01208
01209 LWN_Delete_Tree(curr_cycle_wn);
01210 }
01211
01212 return bounds_code;
01213 }
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226 WN* Generate_Runtime_Cyclic_Bounds(DISTR_INFO *dinfo,
01227 LEGO_INFO *lego_info,
01228 const WN *doloop,
01229 SYMBOL **new_lb,
01230 SYMBOL **new_ub,
01231 SYMBOL **new_step)
01232 {
01233 INT64 linenum = WN_Get_Linenum(doloop);
01234 WN *bounds_code = WN_CreateBlock();
01235 WN_Set_Linenum(bounds_code, linenum);
01236 TYPE_ID ty_out = Promote_Type(Do_Wtype((WN*) doloop));
01237
01238 WN *curr_lb_wn = WN_kid0(WN_start(doloop));
01239 WN *curr_ub_wn = UBexp(WN_end(doloop));
01240
01241 INT64 step = Step_Size((WN *)doloop);
01242 Is_True(step == 1, ("Generate_Runtime_Cyclic_Bounds: Got step != 1"));
01243 FmtAssert(step != 0, ("Got a non-constant or zero step"));
01244
01245 INT curr_dim = lego_info->Dim_Num();
01246
01247 SYMBOL *my_pid = lego_info->Pid_Sym0();
01248 Is_True(my_pid, ("Generate_Runtime_Cyclic_Bounds: Bad pid\n"));
01249
01250
01251 OPCODE call_op = OPCODE_make_op(OPR_CALL, MTYPE_V, MTYPE_V);
01252 WN *call_wn = WN_Create(call_op, 12);
01253 WN_st_idx(call_wn) = ST_st_idx(distr_st_entries[Cyclic_Bounds]);
01254 Set_Runtime_Call_Side_Effects (call_wn);
01255 WN_Set_Linenum(call_wn, linenum);
01256 LWN_Insert_Block_Before(bounds_code, NULL, call_wn);
01257 Array_Dependence_Graph->Add_Vertex(call_wn);
01258
01259
01260
01261
01262
01263
01264 WN *kid = dinfo->DART_Ldid();
01265 WN *parm_wn = WN_CreateParm(Pointer_type, kid, Be_Type_Tbl(Pointer_type),
01266 WN_PARM_BY_REFERENCE);
01267 LWN_Set_Parent(kid, parm_wn);
01268 WN_kid(call_wn, 0) = parm_wn;
01269 LWN_Set_Parent(parm_wn, call_wn);
01270
01271
01272 kid = LWN_Make_Icon(MTYPE_I8, curr_dim);
01273 parm_wn = WN_CreateParm(MTYPE_I8, kid, Be_Type_Tbl(MTYPE_I8),
01274 WN_PARM_BY_VALUE);
01275 LWN_Set_Parent(kid, parm_wn);
01276 WN_kid(call_wn, 1) = parm_wn;
01277 LWN_Set_Parent(parm_wn, call_wn);
01278
01279
01280 kid = AWN_LdidSym(my_pid);
01281 if (WN_rtype(kid) != MTYPE_I8)
01282 kid = LWN_Integer_Cast(kid, MTYPE_I8, WN_rtype(kid));
01283 parm_wn = WN_CreateParm(MTYPE_I8, kid, Be_Type_Tbl(MTYPE_I8),
01284 WN_PARM_BY_VALUE);
01285 LWN_Set_Parent(kid, parm_wn);
01286 WN_kid(call_wn, 2) = parm_wn;
01287 LWN_Set_Parent(parm_wn, call_wn);
01288
01289
01290 kid = LWN_Make_Icon(MTYPE_I8, lego_info->Stride());
01291 parm_wn = WN_CreateParm(MTYPE_I8, kid, Be_Type_Tbl(MTYPE_I8),
01292 WN_PARM_BY_VALUE);
01293 LWN_Set_Parent(kid, parm_wn);
01294 WN_kid(call_wn, 3) = parm_wn;
01295 LWN_Set_Parent(parm_wn, call_wn);
01296
01297
01298 kid = LWN_Make_Icon(MTYPE_I8, lego_info->Offset());
01299 parm_wn = WN_CreateParm(MTYPE_I8, kid, Be_Type_Tbl(MTYPE_I8),
01300 WN_PARM_BY_VALUE);
01301 LWN_Set_Parent(kid, parm_wn);
01302 WN_kid(call_wn, 4) = parm_wn;
01303 LWN_Set_Parent(parm_wn, call_wn);
01304
01305
01306 kid = LWN_Copy_Tree(curr_lb_wn);
01307 LWN_Copy_Def_Use(curr_lb_wn, kid, Du_Mgr);
01308 if (WN_rtype(curr_lb_wn) != MTYPE_I8)
01309 kid = LWN_Integer_Cast(kid, MTYPE_I8, WN_rtype(curr_lb_wn));
01310 parm_wn = WN_CreateParm(MTYPE_I8, kid, Be_Type_Tbl(MTYPE_I8),
01311 WN_PARM_BY_VALUE);
01312 LWN_Set_Parent(kid, parm_wn);
01313 WN_kid(call_wn, 5) = parm_wn;
01314 LWN_Set_Parent(parm_wn, call_wn);
01315
01316
01317 kid = LWN_Copy_Tree(curr_ub_wn);
01318 LWN_Copy_Def_Use(curr_ub_wn, kid, Du_Mgr);
01319 if (WN_rtype(curr_ub_wn) != MTYPE_I8)
01320 kid = LWN_Integer_Cast(kid, MTYPE_I8, WN_rtype(curr_ub_wn));
01321 parm_wn = WN_CreateParm(MTYPE_I8, kid, Be_Type_Tbl(MTYPE_I8),
01322 WN_PARM_BY_VALUE);
01323 LWN_Set_Parent(kid, parm_wn);
01324 WN_kid(call_wn, 6) = parm_wn;
01325 LWN_Set_Parent(parm_wn, call_wn);
01326
01327
01328 kid = LWN_Make_Icon(MTYPE_I8, step);
01329 parm_wn = WN_CreateParm(MTYPE_I8, kid, Be_Type_Tbl(MTYPE_I8),
01330 WN_PARM_BY_VALUE);
01331 LWN_Set_Parent(kid, parm_wn);
01332 WN_kid(call_wn, 7) = parm_wn;
01333 LWN_Set_Parent(parm_wn, call_wn);
01334
01335
01336 sprintf(Str_Buf, "$dsm_temp_lb%d", WN_map_id(doloop));
01337 SYMBOL *temp_lb = CXX_NEW(SYMBOL(Create_Stack_Symbol(Str_Buf, MTYPE_I8)),
01338 LEGO_pool);
01339 Add_Pragma_To_MP_Region(doloop, temp_lb->St(), temp_lb->WN_Offset(),
01340 WN_PRAGMA_LOCAL);
01341
01342 OPCODE lda_op = OPCODE_make_op(OPR_LDA, Pointer_type, MTYPE_V);
01343 TY_IDX i8_ptr_ty = Make_Pointer_Type(Be_Type_Tbl(MTYPE_I8));
01344 kid = WN_CreateLda(lda_op,temp_lb->WN_Offset(),i8_ptr_ty, temp_lb->St());
01345 #ifdef _NEW_SYMTAB
01346 Clear_ST_addr_not_passed(temp_lb->St());
01347 #else
01348 Set_ST_addr_taken_passed(temp_lb->St());
01349 #endif
01350 parm_wn = WN_CreateParm(Pointer_type, kid, i8_ptr_ty, WN_PARM_BY_REFERENCE);
01351 LWN_Set_Parent(kid, parm_wn);
01352 WN_kid(call_wn, 8) = parm_wn;
01353 LWN_Set_Parent(parm_wn, call_wn);
01354
01355 sprintf(Str_Buf, "$dsm_rt_lb%d", WN_map_id(doloop));
01356 *new_lb = CXX_NEW(SYMBOL(Create_Preg_Symbol(Str_Buf, ty_out)), LEGO_pool);
01357 WN *new_lb_wn = AWN_LdidSym(temp_lb);
01358 Du_Mgr->Add_Def_Use(parm_wn, new_lb_wn);
01359 Create_local_alias(Alias_Mgr, parm_wn);
01360 Copy_alias_info(Alias_Mgr, parm_wn, new_lb_wn);
01361 lego_info->Set_Runtime_Lb_Sym(*new_lb);
01362 if (ty_out != MTYPE_I8)
01363 new_lb_wn = LWN_Integer_Cast(new_lb_wn, ty_out, MTYPE_I8);
01364 new_lb_wn = AWN_StidIntoSym(*new_lb, new_lb_wn);
01365 WN_Set_Linenum(new_lb_wn, linenum);
01366 LWN_Insert_Block_Before(bounds_code, NULL, new_lb_wn);
01367
01368
01369 sprintf(Str_Buf, "$dsm_temp_ub%d", WN_map_id(doloop));
01370 SYMBOL *temp_ub = CXX_NEW(SYMBOL(Create_Stack_Symbol(Str_Buf, MTYPE_I8)),
01371 LEGO_pool);
01372 Add_Pragma_To_MP_Region(doloop, temp_ub->St(), temp_ub->WN_Offset(),
01373 WN_PRAGMA_LOCAL);
01374
01375 kid = WN_CreateLda(lda_op, temp_ub->WN_Offset(),i8_ptr_ty,temp_ub->St());
01376 #ifdef _NEW_SYMTAB
01377 Clear_ST_addr_not_passed(temp_ub->St());
01378 #else
01379 Set_ST_addr_taken_passed(temp_ub->St());
01380 #endif
01381 parm_wn = WN_CreateParm(Pointer_type, kid, i8_ptr_ty, WN_PARM_BY_REFERENCE);
01382 LWN_Set_Parent(kid, parm_wn);
01383 WN_kid(call_wn, 9) = parm_wn;
01384 LWN_Set_Parent(parm_wn, call_wn);
01385
01386 sprintf(Str_Buf, "$dsm_rt_ub%d", WN_map_id(doloop));
01387 *new_ub = CXX_NEW(SYMBOL(Create_Preg_Symbol(Str_Buf, ty_out)), LEGO_pool);
01388 WN *new_ub_wn = AWN_LdidSym(temp_ub);
01389 Du_Mgr->Add_Def_Use(parm_wn, new_ub_wn);
01390 Create_local_alias(Alias_Mgr, parm_wn);
01391 Copy_alias_info(Alias_Mgr, parm_wn, new_ub_wn);
01392 lego_info->Set_Runtime_Ub_Sym(*new_ub);
01393 if (ty_out != MTYPE_I8)
01394 new_ub_wn = LWN_Integer_Cast(new_ub_wn, ty_out, MTYPE_I8);
01395 new_ub_wn = AWN_StidIntoSym(*new_ub, new_ub_wn);
01396 WN_Set_Linenum(new_ub_wn, linenum);
01397 LWN_Insert_Block_Before(bounds_code, NULL, new_ub_wn);
01398
01399
01400 sprintf(Str_Buf, "$dsm_temp_step%d", WN_map_id(doloop));
01401 SYMBOL *temp_step = CXX_NEW(SYMBOL(Create_Stack_Symbol(Str_Buf, MTYPE_I8)),
01402 LEGO_pool);
01403 Add_Pragma_To_MP_Region(doloop, temp_step->St(), temp_step->WN_Offset(),
01404 WN_PRAGMA_LOCAL);
01405
01406 kid = WN_CreateLda(lda_op, temp_step->WN_Offset(), i8_ptr_ty,
01407 temp_step->St());
01408 #ifdef _NEW_SYMTAB
01409 Clear_ST_addr_not_passed(temp_step->St());
01410 #else
01411 Set_ST_addr_taken_passed(temp_step->St());
01412 #endif
01413 parm_wn = WN_CreateParm(Pointer_type, kid, i8_ptr_ty, WN_PARM_BY_REFERENCE);
01414 LWN_Set_Parent(kid, parm_wn);
01415 WN_kid(call_wn, 10) = parm_wn;
01416 LWN_Set_Parent(parm_wn, call_wn);
01417
01418 sprintf(Str_Buf, "$dsm_rt_step%d", WN_map_id(doloop));
01419 *new_step = CXX_NEW(SYMBOL(Create_Preg_Symbol(Str_Buf, ty_out)),
01420 LEGO_pool);
01421 WN *new_step_wn = AWN_LdidSym(temp_step);
01422 Du_Mgr->Add_Def_Use(parm_wn, new_step_wn);
01423 Create_local_alias(Alias_Mgr, parm_wn);
01424 Copy_alias_info(Alias_Mgr, parm_wn, new_step_wn);
01425 lego_info->Set_Runtime_Step_Sym(*new_step);
01426 if (ty_out != MTYPE_I8)
01427 new_step_wn = LWN_Integer_Cast(new_step_wn, ty_out, MTYPE_I8);
01428 new_step_wn = AWN_StidIntoSym(*new_step, new_step_wn);
01429 WN_Set_Linenum(new_step_wn, linenum);
01430 LWN_Insert_Block_Before(bounds_code, NULL, new_step_wn);
01431
01432
01433 sprintf(Str_Buf, "$dsm_temp_lastlocal%d", WN_map_id(doloop));
01434 SYMBOL *temp_last = CXX_NEW(SYMBOL(Create_Stack_Symbol(Str_Buf,MTYPE_I4)),
01435 LEGO_pool);
01436 Add_Pragma_To_MP_Region(doloop, temp_last->St(), temp_last->WN_Offset(),
01437 WN_PRAGMA_LOCAL);
01438 TY_IDX i4_ptr_ty = Make_Pointer_Type(Be_Type_Tbl(MTYPE_I4));
01439 kid = WN_CreateLda(lda_op, temp_last->WN_Offset(), i4_ptr_ty,
01440 temp_last->St());
01441 #ifdef _NEW_SYMTAB
01442 Clear_ST_addr_not_passed(temp_last->St());
01443 #else
01444 Set_ST_addr_taken_passed(temp_last->St());
01445 #endif
01446 parm_wn = WN_CreateParm(Pointer_type, kid, i4_ptr_ty, WN_PARM_BY_REFERENCE);
01447 Create_local_alias(Alias_Mgr, parm_wn);
01448 LWN_Set_Parent(kid, parm_wn);
01449 WN_kid(call_wn, 11) = parm_wn;
01450 LWN_Set_Parent(parm_wn, call_wn);
01451 DO_LOOP_INFO* dli = Get_Do_Loop_Info(doloop);
01452 if (dli->Mp_Info != NULL) {
01453 WN* wn_region = NULL;
01454 for (wn_region = (WN*) doloop; wn_region != NULL;
01455 wn_region = LWN_Get_Parent(wn_region))
01456 if (WN_opcode(wn_region) == OPC_REGION)
01457 break;
01458 FmtAssert(wn_region != NULL, ("Could not find region."));
01459 WN* wn_pragma = WN_CreatePragma(WN_PRAGMA_MPSCHEDTYPE,
01460 ST_IDX_ZERO,
01461 (INT32) WN_PRAGMA_SCHEDTYPE_PSEUDOLOWERED,
01462 0);
01463 LWN_Insert_Block_Before(WN_region_pragmas(wn_region), NULL, wn_pragma);
01464 Add_Pragma_To_MP_Region(doloop, temp_last->St(), temp_last->WN_Offset(),
01465 WN_PRAGMA_LASTTHREAD);
01466 }
01467
01468 return bounds_code;
01469 }
01470
01471 static WN* Generate_Dynamic_Bounds(LEGO_INFO *lego_info,
01472 const WN *doloop,
01473 SYMBOL **new_lb,
01474 SYMBOL **new_ub,
01475 SYMBOL **new_step,
01476 INT bound)
01477 {
01478 INT64 linenum = WN_Get_Linenum(doloop);
01479 WN *bounds_code = WN_CreateBlock();
01480 WN_Set_Linenum(bounds_code, linenum);
01481
01482 WN *curr_lb_wn = WN_kid0(WN_start(doloop));
01483 WN *curr_ub_wn = UBexp(WN_end(doloop));
01484 WN *curr_step_wn = Loop_Step((WN*) doloop);
01485
01486 INT curr_dim = lego_info->Dim_Num();
01487
01488 TYPE_ID ty_out = Promote_Type(Do_Wtype((WN*) doloop));
01489
01490
01491 OPCODE call_op = OPCODE_make_op(OPR_CALL, MTYPE_V, MTYPE_V);
01492 WN *call_wn = WN_Create(call_op, 14);
01493 WN_st_idx(call_wn) = ST_st_idx(distr_st_entries[Dynamic_Affinity_Bounds]);
01494 WN_Set_Call_Parm_Mod(call_wn);
01495 WN_Set_Call_Parm_Ref(call_wn);
01496 WN_Set_Linenum(call_wn, linenum);
01497 LWN_Insert_Block_Before(bounds_code, NULL, call_wn);
01498 Array_Dependence_Graph->Add_Vertex(call_wn);
01499
01500
01501
01502
01503
01504
01505 WN* kid = Load_Distr_Array(lego_info->Array()->St());
01506 WN* parm_wn = WN_CreateParm(Pointer_type, kid,
01507 Be_Type_Tbl(Pointer_type), WN_PARM_BY_VALUE);
01508 LWN_Set_Parent(kid, parm_wn);
01509 WN_kid(call_wn, 0) = parm_wn;
01510 LWN_Set_Parent(parm_wn, call_wn);
01511
01512
01513 kid = LWN_Make_Icon(MTYPE_I8, curr_dim);
01514 parm_wn = WN_CreateParm(MTYPE_I8, kid, Be_Type_Tbl(MTYPE_I8),
01515 WN_PARM_BY_VALUE);
01516 LWN_Set_Parent(kid, parm_wn);
01517 WN_kid(call_wn, 1) = parm_wn;
01518 LWN_Set_Parent(parm_wn, call_wn);
01519
01520
01521 SYMBOL* outer_index = lego_info->Pid_Sym0();
01522 kid = AWN_LdidSym(outer_index);
01523 if (WN_rtype(kid) != MTYPE_I8)
01524 kid = LWN_Integer_Cast(kid, MTYPE_I8, outer_index->Type);
01525 parm_wn = WN_CreateParm(MTYPE_I8, kid, Be_Type_Tbl(MTYPE_I8),
01526 WN_PARM_BY_VALUE);
01527 LWN_Set_Parent(kid, parm_wn);
01528 WN_kid(call_wn, 2) = parm_wn;
01529 LWN_Set_Parent(parm_wn, call_wn);
01530
01531
01532 kid = bound == 1 ? AWN_LdidSym(lego_info->Pid_Sym1())
01533 : LWN_Make_Icon(MTYPE_I8, 0);
01534 TYPE_ID my_type = bound == 1 ? lego_info->Pid_Sym1()->Type : MTYPE_I8;
01535 if (WN_rtype(kid) != MTYPE_I8)
01536 kid = LWN_Integer_Cast(kid, MTYPE_I8, WN_rtype(kid));
01537 parm_wn = WN_CreateParm(MTYPE_I8, kid, Be_Type_Tbl(MTYPE_I8),
01538 WN_PARM_BY_VALUE);
01539 LWN_Set_Parent(kid, parm_wn);
01540 WN_kid(call_wn, 3) = parm_wn;
01541 LWN_Set_Parent(parm_wn, call_wn);
01542
01543
01544 kid = LWN_Make_Icon(MTYPE_I8, bound + 1);
01545 parm_wn = WN_CreateParm(MTYPE_I8, kid, Be_Type_Tbl(MTYPE_I8),
01546 WN_PARM_BY_VALUE);
01547 LWN_Set_Parent(kid, parm_wn);
01548 WN_kid(call_wn, 4) = parm_wn;
01549 LWN_Set_Parent(parm_wn, call_wn);
01550
01551
01552 kid = LWN_Make_Icon(MTYPE_I8, lego_info->Stride());
01553 parm_wn = WN_CreateParm(MTYPE_I8, kid, Be_Type_Tbl(MTYPE_I8),
01554 WN_PARM_BY_VALUE);
01555 LWN_Set_Parent(kid, parm_wn);
01556 WN_kid(call_wn, 5) = parm_wn;
01557 LWN_Set_Parent(parm_wn, call_wn);
01558
01559
01560 kid = LWN_Make_Icon(MTYPE_I8, lego_info->Offset());
01561 parm_wn = WN_CreateParm(MTYPE_I8, kid, Be_Type_Tbl(MTYPE_I8),
01562 WN_PARM_BY_VALUE);
01563 LWN_Set_Parent(kid, parm_wn);
01564 WN_kid(call_wn, 6) = parm_wn;
01565 LWN_Set_Parent(parm_wn, call_wn);
01566
01567
01568 kid = LWN_Copy_Tree(curr_lb_wn);
01569 LWN_Copy_Def_Use(curr_lb_wn, kid, Du_Mgr);
01570 if (WN_rtype(kid) != MTYPE_I8)
01571 kid = LWN_Integer_Cast(kid, MTYPE_I8, WN_rtype(kid));
01572 parm_wn = WN_CreateParm(MTYPE_I8, kid, Be_Type_Tbl(MTYPE_I8),
01573 WN_PARM_BY_VALUE);
01574 LWN_Set_Parent(kid, parm_wn);
01575 WN_kid(call_wn, 7) = parm_wn;
01576 LWN_Set_Parent(parm_wn, call_wn);
01577
01578
01579 kid = LWN_Copy_Tree(curr_ub_wn);
01580 LWN_Copy_Def_Use(curr_ub_wn, kid, Du_Mgr);
01581 if (WN_rtype(kid) != MTYPE_I8)
01582 kid = LWN_Integer_Cast(kid, MTYPE_I8, WN_rtype(kid));
01583 parm_wn = WN_CreateParm(MTYPE_I8, kid, Be_Type_Tbl(MTYPE_I8),
01584 WN_PARM_BY_VALUE);
01585 LWN_Set_Parent(kid, parm_wn);
01586 WN_kid(call_wn, 8) = parm_wn;
01587 LWN_Set_Parent(parm_wn, call_wn);
01588
01589
01590 kid = LWN_Copy_Tree(curr_step_wn);
01591 LWN_Copy_Def_Use(curr_step_wn, kid, Du_Mgr);
01592 if (WN_rtype(kid) != MTYPE_I8)
01593 kid = LWN_Integer_Cast(kid, MTYPE_I8, WN_rtype(kid));
01594 parm_wn = WN_CreateParm(MTYPE_I8, kid, Be_Type_Tbl(MTYPE_I8),
01595 WN_PARM_BY_VALUE);
01596 LWN_Set_Parent(kid, parm_wn);
01597 WN_kid(call_wn, 9) = parm_wn;
01598 LWN_Set_Parent(parm_wn, call_wn);
01599
01600
01601 sprintf(Str_Buf, "$dsm_temp_lb%d", WN_map_id(doloop));
01602 SYMBOL *temp_lb = CXX_NEW(SYMBOL(Create_Stack_Symbol(Str_Buf, MTYPE_I8)),
01603 LEGO_pool);
01604 Add_Pragma_To_MP_Region(doloop, temp_lb->St(), temp_lb->WN_Offset(),
01605 WN_PRAGMA_LOCAL);
01606
01607 OPCODE lda_op = OPCODE_make_op(OPR_LDA, Pointer_type, MTYPE_V);
01608 TY_IDX i8_ptr_ty = Make_Pointer_Type(Be_Type_Tbl(MTYPE_I8));
01609 kid = WN_CreateLda(lda_op,temp_lb->WN_Offset(),i8_ptr_ty, temp_lb->St());
01610 #ifdef _NEW_SYMTAB
01611 Clear_ST_addr_not_passed(temp_lb->St());
01612 #else
01613 Set_ST_addr_taken_passed(temp_lb->St());
01614 #endif
01615 parm_wn = WN_CreateParm(Pointer_type, kid, i8_ptr_ty, WN_PARM_BY_REFERENCE);
01616 LWN_Set_Parent(kid, parm_wn);
01617 WN_kid(call_wn, 10) = parm_wn;
01618 LWN_Set_Parent(parm_wn, call_wn);
01619
01620 sprintf(Str_Buf, "$dsm_rt_lb%d", WN_map_id(doloop));
01621 *new_lb = CXX_NEW(SYMBOL(Create_Preg_Symbol(Str_Buf, ty_out)), LEGO_pool);
01622 WN *new_lb_wn = AWN_LdidSym(temp_lb);
01623 Du_Mgr->Add_Def_Use(parm_wn, new_lb_wn);
01624 Create_local_alias(Alias_Mgr, parm_wn);
01625 Copy_alias_info(Alias_Mgr, parm_wn, new_lb_wn);
01626 lego_info->Set_Runtime_Lb_Sym(*new_lb);
01627 if (ty_out != MTYPE_I8)
01628 new_lb_wn = LWN_Integer_Cast(new_lb_wn, ty_out, MTYPE_I8);
01629
01630 new_lb_wn = AWN_StidIntoSym(*new_lb, new_lb_wn);
01631 WN_Set_Linenum(new_lb_wn, linenum);
01632 LWN_Insert_Block_Before(bounds_code, NULL, new_lb_wn);
01633
01634
01635 sprintf(Str_Buf, "$dsm_temp_ub%d", WN_map_id(doloop));
01636 SYMBOL *temp_ub = CXX_NEW(SYMBOL(Create_Stack_Symbol(Str_Buf, MTYPE_I8)),
01637 LEGO_pool);
01638 Add_Pragma_To_MP_Region(doloop, temp_ub->St(), temp_ub->WN_Offset(),
01639 WN_PRAGMA_LOCAL);
01640
01641 kid = WN_CreateLda(lda_op,temp_ub->WN_Offset(),i8_ptr_ty, temp_ub->St());
01642 #ifdef _NEW_SYMTAB
01643 Clear_ST_addr_not_passed(temp_ub->St());
01644 #else
01645 Set_ST_addr_taken_passed(temp_ub->St());
01646 #endif
01647 parm_wn = WN_CreateParm(Pointer_type, kid, i8_ptr_ty, WN_PARM_BY_REFERENCE);
01648 LWN_Set_Parent(kid, parm_wn);
01649 WN_kid(call_wn, 11) = parm_wn;
01650 LWN_Set_Parent(parm_wn, call_wn);
01651
01652 sprintf(Str_Buf, "$dsm_rt_ub%d", WN_map_id(doloop));
01653 *new_ub = CXX_NEW(SYMBOL(Create_Preg_Symbol(Str_Buf, ty_out)), LEGO_pool);
01654 WN *new_ub_wn = AWN_LdidSym(temp_ub);
01655 Du_Mgr->Add_Def_Use(parm_wn, new_ub_wn);
01656 Create_local_alias(Alias_Mgr, parm_wn);
01657 Copy_alias_info(Alias_Mgr, parm_wn, new_ub_wn);
01658 lego_info->Set_Runtime_Ub_Sym(*new_ub);
01659 if (ty_out != MTYPE_I8)
01660 new_ub_wn = LWN_Integer_Cast(new_ub_wn, ty_out, MTYPE_I8);
01661
01662 new_ub_wn = AWN_StidIntoSym(*new_ub, new_ub_wn);
01663 WN_Set_Linenum(new_ub_wn, linenum);
01664 LWN_Insert_Block_Before(bounds_code, NULL, new_ub_wn);
01665
01666
01667 sprintf(Str_Buf, "$dsm_temp_step%d", WN_map_id(doloop));
01668 SYMBOL *temp_step = CXX_NEW(SYMBOL(Create_Stack_Symbol(Str_Buf, MTYPE_I8)),
01669 LEGO_pool);
01670 Add_Pragma_To_MP_Region(doloop, temp_step->St(), temp_step->WN_Offset(),
01671 WN_PRAGMA_LOCAL);
01672
01673 kid = WN_CreateLda(lda_op, temp_step->WN_Offset(), i8_ptr_ty,
01674 temp_step->St());
01675 #ifdef _NEW_SYMTAB
01676 Clear_ST_addr_not_passed(temp_step->St());
01677 #else
01678 Set_ST_addr_taken_passed(temp_step->St());
01679 #endif
01680 parm_wn = WN_CreateParm(Pointer_type, kid, i8_ptr_ty, WN_PARM_BY_REFERENCE);
01681 LWN_Set_Parent(kid, parm_wn);
01682 WN_kid(call_wn, 12) = parm_wn;
01683 LWN_Set_Parent(parm_wn, call_wn);
01684
01685 sprintf(Str_Buf, "$dsm_rt_step%d", WN_map_id(doloop));
01686 *new_step = CXX_NEW(SYMBOL(Create_Preg_Symbol(Str_Buf, ty_out)),
01687 LEGO_pool);
01688 WN *new_step_wn = AWN_LdidSym(temp_step);
01689 Du_Mgr->Add_Def_Use(parm_wn, new_step_wn);
01690 Create_local_alias(Alias_Mgr, parm_wn);
01691 Copy_alias_info(Alias_Mgr, parm_wn, new_step_wn);
01692 lego_info->Set_Runtime_Step_Sym(*new_step);
01693 if (ty_out != MTYPE_I8)
01694 new_step_wn = LWN_Integer_Cast(new_step_wn, ty_out, MTYPE_I8);
01695
01696 new_step_wn = AWN_StidIntoSym(*new_step, new_step_wn);
01697 WN_Set_Linenum(new_step_wn, linenum);
01698 LWN_Insert_Block_Before(bounds_code, NULL, new_step_wn);
01699
01700
01701 sprintf(Str_Buf, "$da_is_last%d", WN_map_id(doloop));
01702 SYMBOL* is_last = CXX_NEW(SYMBOL(Create_Stack_Symbol(Str_Buf, MTYPE_I4)),
01703 &LNO_default_pool);
01704 TY_IDX i4_ptr_ty = Make_Pointer_Type(Be_Type_Tbl(MTYPE_I4));
01705 OPCODE op_lda = OPCODE_make_op(OPR_LDA, Pointer_type, MTYPE_V);
01706 kid = WN_CreateLda(op_lda, is_last->WN_Offset(), i4_ptr_ty,
01707 is_last->St());
01708 #ifdef _NEW_SYMTAB
01709 Clear_ST_addr_not_passed(is_last->St());
01710 #else
01711 Set_ST_addr_taken_passed(is_last->St());
01712 #endif
01713 parm_wn = WN_CreateParm(Pointer_type, kid, i4_ptr_ty,
01714 WN_PARM_BY_REFERENCE);
01715 Create_local_alias(Alias_Mgr, parm_wn);
01716 WN_kid(call_wn, 13) = parm_wn;
01717 LWN_Set_Parent(kid, parm_wn);
01718 LWN_Set_Parent(parm_wn, call_wn);
01719 Add_Pragma_To_MP_Region(doloop, is_last->St(), is_last->WN_Offset(),
01720 WN_PRAGMA_LOCAL);
01721 DO_LOOP_INFO* dli = Get_Do_Loop_Info(doloop);
01722 if (dli->Mp_Info != NULL)
01723 Add_Pragma_To_MP_Region(doloop, is_last->St(), is_last->WN_Offset(),
01724 WN_PRAGMA_LASTTHREAD);
01725
01726 return bounds_code;
01727 }
01728
01729
01730
01731
01732
01733
01734
01735
01736 static WN* Generate_Simple_Bounds(const WN* wn_loop,
01737 SYMBOL** new_lb,
01738 SYMBOL** new_ub,
01739 DU_MANAGER* du,
01740 ARRAY_DIRECTED_GRAPH16* dg)
01741 {
01742
01743 INT64 linenum = WN_Get_Linenum(wn_loop);
01744 WN *bounds_code = WN_CreateBlock();
01745 WN_Set_Linenum(bounds_code, linenum);
01746 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn_loop);
01747 WN* wn_region = NULL;
01748 for (wn_region = (WN*) wn_loop; wn_region != NULL;
01749 wn_region = LWN_Get_Parent(wn_region))
01750 if (WN_opcode(wn_region) == OPC_REGION)
01751 break;
01752 FmtAssert(wn_region != NULL, ("Could not find region."));
01753 TYPE_ID ty_out = Promote_Type(Do_Wtype((WN*) wn_loop));
01754
01755
01756 OPCODE op_call = OPCODE_make_op(OPR_CALL, MTYPE_V, MTYPE_V);
01757 WN* wn_call = WN_Create(op_call, 8);
01758 WN_st_idx(wn_call) = ST_st_idx(distr_st_entries[Simple_Bounds]);
01759 WN_Set_Call_Parm_Mod(wn_call);
01760 WN_Set_Call_Parm_Ref(wn_call);
01761 WN_Set_Linenum(wn_call, linenum);
01762 LWN_Insert_Block_Before(bounds_code, NULL, wn_call);
01763 dg->Add_Vertex(wn_call);
01764
01765
01766
01767 WN* wn_orig_lb = WN_kid0(WN_start(wn_loop));
01768 WN* wn_cp_orig_lb = LWN_Copy_Tree(wn_orig_lb);
01769 LWN_Copy_Def_Use(wn_orig_lb, wn_cp_orig_lb, du);
01770 TYPE_ID type = WN_rtype(wn_cp_orig_lb);
01771 if (type != MTYPE_I8)
01772 wn_cp_orig_lb = LWN_Integer_Cast(wn_cp_orig_lb, MTYPE_I8, type);
01773 WN* wn_parm = WN_CreateParm(MTYPE_I8, wn_cp_orig_lb, Be_Type_Tbl(MTYPE_I8),
01774 WN_PARM_BY_VALUE);
01775 LWN_Set_Parent(wn_cp_orig_lb, wn_parm);
01776 WN_kid(wn_call, 0) = wn_parm;
01777 LWN_Set_Parent(wn_parm, wn_call);
01778
01779
01780 WN* wn_orig_ub = UBexp(WN_end(wn_loop));
01781 WN* wn_cp_orig_ub = LWN_Copy_Tree(wn_orig_ub);
01782 LWN_Copy_Def_Use(wn_orig_ub, wn_cp_orig_ub, du);
01783 type = WN_rtype(wn_cp_orig_ub);
01784 if (type != MTYPE_I8)
01785 wn_cp_orig_ub = LWN_Integer_Cast(wn_cp_orig_ub, MTYPE_I8, type);
01786 wn_parm = WN_CreateParm(MTYPE_I8, wn_cp_orig_ub, Be_Type_Tbl(MTYPE_I8),
01787 WN_PARM_BY_VALUE);
01788 LWN_Set_Parent(wn_cp_orig_ub, wn_parm);
01789 WN_kid(wn_call, 1) = wn_parm;
01790 LWN_Set_Parent(wn_parm, wn_call);
01791
01792
01793 WN* wn_orig_step = Loop_Step((WN*) wn_loop);
01794 WN* wn_cp_orig_step = LWN_Copy_Tree(wn_orig_step);
01795 LWN_Copy_Def_Use(wn_orig_step, wn_cp_orig_step, du);
01796 type = WN_rtype(wn_cp_orig_step);
01797 if (type != MTYPE_I8)
01798 wn_cp_orig_step = LWN_Integer_Cast(wn_cp_orig_step, MTYPE_I8, type);
01799 wn_parm = WN_CreateParm(MTYPE_I8, wn_cp_orig_step, Be_Type_Tbl(MTYPE_I8),
01800 WN_PARM_BY_VALUE);
01801 LWN_Set_Parent(wn_cp_orig_step, wn_parm);
01802 WN_kid(wn_call, 2) = wn_parm;
01803 LWN_Set_Parent(wn_parm, wn_call);
01804
01805
01806 WN* wn_num_threads = NULL;
01807 if (dli->Mp_Info->Nest_Total() == 1) {
01808 wn_num_threads = dli->Mp_Info->Is_Pdo()
01809 ? (Is_Versioned_Mp_Loop((WN*) wn_loop)
01810 ? Get_Runtime_Cur_Numthreads_Ldid()
01811 : Get_Runtime_Cur_Numthreads_Func((WN*) wn_loop))
01812 : Get_Frozen_Numthreads_Ldid((WN*) wn_loop);
01813 } else {
01814 wn_num_threads = AWN_LdidSym(dli->Mp_Info->Nest_Layout());
01815 WN* wn_outer_loop = (WN*) wn_loop;
01816 for (WN* wn = (WN*) wn_loop; wn != NULL; wn = LWN_Get_Parent(wn))
01817 if (WN_opcode(wn) == OPC_DO_LOOP)
01818 wn_outer_loop = wn;
01819 WN* wn_stid = Find_Node(dli->Mp_Info->Nest_Layout(),
01820 LWN_Get_Parent(wn_outer_loop));
01821 du->Add_Def_Use(wn_stid, wn_num_threads);
01822 }
01823 type = WN_rtype(wn_num_threads);
01824 if (type != MTYPE_I8)
01825 wn_num_threads = LWN_Integer_Cast(wn_num_threads, MTYPE_I8, type);
01826 wn_parm = WN_CreateParm(MTYPE_I8, wn_num_threads, Be_Type_Tbl(MTYPE_I8),
01827 WN_PARM_BY_VALUE);
01828 LWN_Set_Parent(wn_num_threads, wn_parm);
01829 WN_kid(wn_call, 3) = wn_parm;
01830 LWN_Set_Parent(wn_parm, wn_call);
01831
01832
01833 SYMBOL* my_pid = dli->Mp_Info->Pid_Sym0();
01834 WN* wn_pid = AWN_LdidSym(my_pid);
01835 if (WN_rtype(wn_pid) != MTYPE_I8)
01836 wn_pid = LWN_Integer_Cast(wn_pid, MTYPE_I8, WN_rtype(wn_pid));
01837 if (dli->Is_Backward && dli->Auto_Parallelized) {
01838 WN* wn_num_threads1=LWN_Copy_Tree(wn_num_threads);
01839 LWN_Copy_Def_Use(wn_num_threads,wn_num_threads1,du);
01840 wn_pid=LWN_CreateExp2(OPCODE_make_op(OPR_SUB, MTYPE_I8, MTYPE_V),
01841 wn_num_threads1, wn_pid);
01842 wn_pid=LWN_CreateExp2(OPCODE_make_op(OPR_SUB, MTYPE_I8, MTYPE_V),
01843 wn_pid, LWN_Make_Icon(MTYPE_I8,1));
01844 LWN_Parentize(wn_pid);
01845 }
01846 wn_parm = WN_CreateParm(MTYPE_I8, wn_pid, Be_Type_Tbl(MTYPE_I8),
01847 WN_PARM_BY_VALUE);
01848 LWN_Set_Parent(wn_pid, wn_parm);
01849 WN_kid(wn_call, 4) = wn_parm;
01850 LWN_Set_Parent(wn_parm, wn_call);
01851
01852
01853 sprintf(Str_Buf, "$da_temp_lb%d", WN_map_id(wn_loop));
01854 SYMBOL* temp_lb = CXX_NEW(SYMBOL(Create_Stack_Symbol(Str_Buf, MTYPE_I8)),
01855 &LNO_default_pool);
01856 OPCODE op_lda = OPCODE_make_op(OPR_LDA, Pointer_type, MTYPE_V);
01857 TY_IDX i8_ptr_ty = Make_Pointer_Type(Be_Type_Tbl(MTYPE_I8));
01858 WN* wn_kid = WN_CreateLda(op_lda, temp_lb->WN_Offset(), i8_ptr_ty,
01859 temp_lb->St());
01860 #ifdef _NEW_SYMTAB
01861 Clear_ST_addr_not_passed(temp_lb->St());
01862 #else
01863 Set_ST_addr_taken_passed(temp_lb->St());
01864 #endif
01865 wn_parm=WN_CreateParm(Pointer_type, wn_kid, i8_ptr_ty, WN_PARM_BY_REFERENCE);
01866 WN_kid(wn_call, 5) = wn_parm;
01867 LWN_Set_Parent(wn_parm, wn_call);
01868 LWN_Set_Parent(wn_kid, wn_parm);
01869 sprintf(Str_Buf, "$da_lb%d", WN_map_id(wn_loop));
01870 *new_lb = CXX_NEW(SYMBOL(Create_Preg_Symbol(Str_Buf, ty_out)),
01871 &LNO_default_pool);
01872 WN *wn_new_lb = AWN_LdidSym(temp_lb);
01873 Du_Mgr->Add_Def_Use(wn_parm, wn_new_lb);
01874 Create_local_alias(Alias_Mgr, wn_parm);
01875 Copy_alias_info(Alias_Mgr, wn_parm, wn_new_lb);
01876 if (ty_out != MTYPE_I8)
01877 wn_new_lb = LWN_Integer_Cast(wn_new_lb, ty_out, MTYPE_I8);
01878 wn_new_lb = AWN_StidIntoSym(*new_lb, wn_new_lb);
01879 WN_Set_Linenum(wn_new_lb, linenum);
01880 LWN_Insert_Block_Before(bounds_code, NULL, wn_new_lb);
01881 Add_Pragma_To_MP_Region(wn_loop, temp_lb->St(), temp_lb->WN_Offset(),
01882 WN_PRAGMA_LOCAL);
01883
01884
01885 sprintf(Str_Buf, "$da_temp_ub%d", WN_map_id(wn_loop));
01886 SYMBOL* temp_ub = CXX_NEW(SYMBOL(Create_Stack_Symbol(Str_Buf, MTYPE_I8)),
01887 &LNO_default_pool);
01888 wn_kid = WN_CreateLda(op_lda, temp_ub->WN_Offset(), i8_ptr_ty,
01889 temp_ub->St());
01890 #ifdef _NEW_SYMTAB
01891 Clear_ST_addr_not_passed(temp_ub->St());
01892 #else
01893 Set_ST_addr_taken_passed(temp_ub->St());
01894 #endif
01895 wn_parm=WN_CreateParm(Pointer_type, wn_kid, i8_ptr_ty, WN_PARM_BY_REFERENCE);
01896 WN_kid(wn_call, 6) = wn_parm;
01897 LWN_Set_Parent(wn_parm, wn_call);
01898 LWN_Set_Parent(wn_kid, wn_parm);
01899 sprintf(Str_Buf, "$da_ub%d", WN_map_id(wn_loop));
01900 *new_ub = CXX_NEW(SYMBOL(Create_Preg_Symbol(Str_Buf, ty_out)),
01901 &LNO_default_pool);
01902 WN *wn_new_ub = AWN_LdidSym(temp_ub);
01903 Du_Mgr->Add_Def_Use(wn_parm, wn_new_ub);
01904 Create_local_alias(Alias_Mgr, wn_parm);
01905 Copy_alias_info(Alias_Mgr, wn_parm, wn_new_ub);
01906 if (ty_out != MTYPE_I8)
01907 wn_new_ub = LWN_Integer_Cast(wn_new_ub, ty_out, MTYPE_I8);
01908 wn_new_ub = AWN_StidIntoSym(*new_ub, wn_new_ub);
01909 WN_Set_Linenum(wn_new_ub, linenum);
01910 LWN_Insert_Block_Before(bounds_code, NULL, wn_new_ub);
01911 Add_Pragma_To_MP_Region(wn_loop, temp_ub->St(), temp_ub->WN_Offset(),
01912 WN_PRAGMA_LOCAL);
01913
01914
01915 sprintf(Str_Buf, "$da_is_last%d", WN_map_id(wn_loop));
01916 SYMBOL* is_last = CXX_NEW(SYMBOL(Create_Stack_Symbol(Str_Buf, MTYPE_I4)),
01917 &LNO_default_pool);
01918 TY_IDX i4_ptr_ty = Make_Pointer_Type(Be_Type_Tbl(MTYPE_I4));
01919 wn_kid = WN_CreateLda(op_lda, is_last->WN_Offset(), i4_ptr_ty,
01920 is_last->St());
01921 #ifdef _NEW_SYMTAB
01922 Clear_ST_addr_not_passed(is_last->St());
01923 #else
01924 Set_ST_addr_taken_passed(is_last->St());
01925 #endif
01926 wn_parm=WN_CreateParm(Pointer_type, wn_kid, i4_ptr_ty, WN_PARM_BY_REFERENCE);
01927 Create_local_alias(Alias_Mgr, wn_parm);
01928 WN_kid(wn_call, 7) = wn_parm;
01929 LWN_Set_Parent(wn_kid, wn_parm);
01930 LWN_Set_Parent(wn_parm, wn_call);
01931 Add_Pragma_To_MP_Region(wn_loop, is_last->St(), is_last->WN_Offset(),
01932 WN_PRAGMA_LOCAL);
01933
01934
01935 if (dli->Mp_Info->Nest_Index() == 0) {
01936 WN* wn_first = WN_first(WN_region_pragmas(wn_region));
01937 WN* wn = NULL;
01938 for (wn = wn_first; wn != NULL; wn = WN_next(wn)) {
01939 if (WN_opcode(wn) == OPC_PRAGMA) {
01940 if (WN_pragma(wn) == WN_PRAGMA_MPSCHEDTYPE
01941 && WN_pragma_arg1(wn) == WN_PRAGMA_SCHEDTYPE_SIMPLE) {
01942 WN_pragma_arg1(wn) = WN_PRAGMA_SCHEDTYPE_PSEUDOLOWERED;
01943 break;
01944 }
01945 }
01946 }
01947 if (wn == NULL) {
01948 WN* wn_pragma = WN_CreatePragma(WN_PRAGMA_MPSCHEDTYPE,
01949 ST_IDX_ZERO,
01950 (INT32)WN_PRAGMA_SCHEDTYPE_PSEUDOLOWERED,
01951 0);
01952 LWN_Insert_Block_Before(WN_region_pragmas(wn_region), NULL, wn_pragma);
01953 }
01954 }
01955 Add_Pragma_To_MP_Region(wn_loop, is_last->St(), is_last->WN_Offset(),
01956 WN_PRAGMA_LASTTHREAD);
01957 return bounds_code;
01958 }
01959
01960
01961
01962
01963
01964
01965
01966
01967 extern WN* Interleaved_Pragma_Chunksize(const WN* wn_loop,
01968 DU_MANAGER* du)
01969 {
01970 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn_loop);
01971 MP_INFO* mp_info = dli->Mp_Info;
01972 WN *wn;
01973
01974 FmtAssert(mp_info != NULL, ("Expected a doacross loop"));
01975 FmtAssert(mp_info->Sched_Type() == MP_SCHED_INTERLEAVE,
01976 ("Expected INTERLEAVED sched type"));
01977 for (wn = (WN*) wn_loop; wn != NULL; wn = LWN_Get_Parent(wn))
01978 if (WN_opcode(wn) == OPC_REGION)
01979 break;
01980 WN* wn_region = wn;
01981 FmtAssert(wn_region != NULL, ("Could not find doacross region"));
01982 WN* wn_first = WN_first(WN_region_pragmas(wn_region));
01983 WN* wn_chunksize = NULL;
01984 for (wn = wn_first; wn != NULL; wn = WN_next(wn)) {
01985 if (WN_opcode(wn) == OPC_XPRAGMA
01986 && (WN_pragma(wn) == WN_PRAGMA_CHUNKSIZE)) {
01987 wn_chunksize = WN_kid0(wn);
01988 break;
01989 }
01990 }
01991 WN* wn_cp_chunksize = NULL;
01992 if (wn_chunksize == NULL) {
01993 wn_cp_chunksize = LWN_Make_Icon(Do_Wtype((WN*) wn_loop), 1);
01994 } else {
01995 wn_cp_chunksize = LWN_Copy_Tree(wn_chunksize);
01996 LWN_Copy_Def_Use(wn_chunksize, wn_cp_chunksize, du);
01997 }
01998 return wn_cp_chunksize;
01999 }
02000
02001
02002
02003
02004
02005
02006
02007
02008 static WN* Generate_Interleaved_Bounds(const WN* wn_loop,
02009 SYMBOL** new_lb,
02010 SYMBOL** new_ub,
02011 SYMBOL** new_step,
02012 DU_MANAGER* du,
02013 INT bound)
02014 {
02015 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn_loop);
02016 INT64 linenum = WN_Get_Linenum(wn_loop);
02017 WN* wn_stride = Loop_Step((WN*) wn_loop);
02018 TYPE_ID type = Promote_Type(Do_Wtype((WN *) wn_loop));
02019 WN* bounds_code = WN_CreateBlock();
02020 WN *wn;
02021
02022 for (wn = (WN*) wn_loop; wn != NULL; wn = LWN_Get_Parent(wn))
02023 if (WN_opcode(wn) == OPC_REGION)
02024 break;
02025 WN* wn_region = wn;
02026 FmtAssert(wn_region != NULL, ("Could not find doacross region"));
02027 if (bound == 0) {
02028
02029
02030 WN* wn_cp_stride = LWN_Copy_Tree(wn_stride);
02031 LWN_Copy_Def_Use(wn_stride, wn_cp_stride, du);
02032 WN* wn_cp_chunksize = Interleaved_Pragma_Chunksize(wn_loop, du);
02033 WN* wn_stride_chunk = AWN_Mpy(type, wn_cp_stride, wn_cp_chunksize);
02034 WN* wn_stride_chunk2 = LWN_Copy_Tree(wn_stride_chunk);
02035 LWN_Copy_Def_Use(wn_stride_chunk, wn_stride_chunk2, du);
02036 WN* wn_lb = LWN_Copy_Tree(WN_kid0(WN_start(wn_loop)));
02037 LWN_Copy_Def_Use(WN_kid0(WN_start(wn_loop)), wn_lb, du);
02038 WN* wn_pid0 = AWN_LdidSym(dli->Mp_Info->Pid_Sym0());
02039 WN* wn_base_increment = AWN_Mpy(type, wn_pid0, wn_stride_chunk);
02040 WN* wn_base = AWN_Add(type, wn_lb, wn_base_increment);
02041 sprintf(Str_Buf, "$da_lb%d", WN_map_id(wn_loop));
02042 *new_lb = CXX_NEW(SYMBOL(Create_Preg_Symbol(Str_Buf, type)),
02043 &LNO_default_pool);
02044 WN* wn_new_lb = AWN_StidIntoSym(*new_lb, wn_base);
02045 WN_Set_Linenum(wn_new_lb, linenum);
02046 LWN_Insert_Block_After(bounds_code, NULL, wn_new_lb);
02047 Add_Pragma_To_MP_Region(wn_loop, (*new_lb)->St(), (*new_lb)->WN_Offset(),
02048 WN_PRAGMA_LOCAL);
02049
02050
02051 WN* wn_ub = LWN_Copy_Tree(UBexp(WN_end(wn_loop)));
02052 LWN_Copy_Def_Use(UBexp(WN_end(wn_loop)), wn_ub, du);
02053 sprintf(Str_Buf, "$da_ub%d", WN_map_id(wn_loop));
02054 *new_ub = CXX_NEW(SYMBOL(Create_Preg_Symbol(Str_Buf, type)),
02055 &LNO_default_pool);
02056 WN* wn_new_ub = AWN_StidIntoSym(*new_ub, wn_ub);
02057 WN_Set_Linenum(wn_new_ub, linenum);
02058 LWN_Insert_Block_After(bounds_code, NULL, wn_new_ub);
02059 Add_Pragma_To_MP_Region(wn_loop, (*new_ub)->St(), (*new_ub)->WN_Offset(),
02060 WN_PRAGMA_LOCAL);
02061
02062
02063 WN* wn_num_threads = NULL;
02064 if (dli->Mp_Info->Nest_Total() == 1) {
02065 wn_num_threads = dli->Mp_Info->Is_Pdo()
02066 ? (Is_Versioned_Mp_Loop((WN*) wn_loop)
02067 ? Get_Runtime_Cur_Numthreads_Ldid()
02068 : Get_Runtime_Cur_Numthreads_Func((WN*) wn_loop))
02069 : Get_Frozen_Numthreads_Ldid((WN*) wn_loop);
02070 } else {
02071 wn_num_threads = AWN_LdidSym(dli->Mp_Info->Nest_Layout());
02072 WN* wn_outer_loop = (WN*) wn_loop;
02073 for (WN* wn = (WN*) wn_loop; wn != NULL; wn = LWN_Get_Parent(wn))
02074 if (WN_opcode(wn) == OPC_DO_LOOP)
02075 wn_outer_loop = wn;
02076 WN* wn_stid = Find_Node(dli->Mp_Info->Nest_Layout(),
02077 LWN_Get_Parent(wn_outer_loop));
02078 du->Add_Def_Use(wn_stid, wn_num_threads);
02079 }
02080 WN* wn_step = AWN_Mpy(type, wn_num_threads, wn_stride_chunk2);
02081 sprintf(Str_Buf, "$da_step%d", WN_map_id(wn_loop));
02082 *new_step = CXX_NEW(SYMBOL(Create_Preg_Symbol(Str_Buf, type)),
02083 &LNO_default_pool);
02084 WN* wn_new_step = AWN_StidIntoSym(*new_step, wn_step);
02085 WN_Set_Linenum(wn_new_step, linenum);
02086 LWN_Insert_Block_After(bounds_code, NULL, wn_new_step);
02087 Add_Pragma_To_MP_Region(wn_loop, (*new_step)->St(),
02088 (*new_step)->WN_Offset(), WN_PRAGMA_LOCAL);
02089
02090
02091 wn_ub = LWN_Copy_Tree(UBexp(WN_end(wn_loop)));
02092 LWN_Copy_Def_Use(UBexp(WN_end(wn_loop)), wn_ub, du);
02093 wn_lb = LWN_Copy_Tree(WN_kid0(WN_start(wn_loop)));
02094 LWN_Copy_Def_Use(WN_kid0(WN_start(wn_loop)), wn_lb, du);
02095 WN* wn_diff = AWN_Sub(type, wn_ub, wn_lb);
02096 wn_cp_stride = LWN_Copy_Tree(wn_stride);
02097 LWN_Copy_Def_Use(wn_stride, wn_cp_stride, du);
02098 wn_cp_chunksize = Interleaved_Pragma_Chunksize(wn_loop, du);
02099 wn_stride_chunk = AWN_Mpy(type, wn_cp_stride, wn_cp_chunksize);
02100 wn_stride_chunk2 = LWN_Copy_Tree(wn_stride_chunk);
02101 LWN_Copy_Def_Use(wn_stride_chunk, wn_stride_chunk2, du);
02102 if (dli->Mp_Info->Nest_Total() == 1) {
02103 wn_num_threads = dli->Mp_Info->Is_Pdo()
02104 ? (Is_Versioned_Mp_Loop((WN*) wn_loop)
02105 ? Get_Runtime_Cur_Numthreads_Ldid()
02106 : Get_Runtime_Cur_Numthreads_Func((WN*) wn_loop))
02107 : Get_Frozen_Numthreads_Ldid((WN*) wn_loop);
02108 } else {
02109 wn_num_threads = AWN_LdidSym(dli->Mp_Info->Nest_Layout());
02110 WN* wn_outer_loop = (WN*) wn_loop;
02111 for (WN* wn = (WN*) wn_loop; wn != NULL; wn = LWN_Get_Parent(wn))
02112 if (WN_opcode(wn) == OPC_DO_LOOP)
02113 wn_outer_loop = wn;
02114 WN* wn_stid = Find_Node(dli->Mp_Info->Nest_Layout(),
02115 LWN_Get_Parent(wn_outer_loop));
02116 du->Add_Def_Use(wn_stid, wn_num_threads);
02117 }
02118 wn_step = AWN_Mpy(type, wn_num_threads, wn_stride_chunk2);
02119 WN* wn_num = AWN_Mod_Safe(type, wn_diff, wn_step);
02120 WN* wn_last_proc = AWN_Div_Safe(type, wn_num, wn_stride_chunk);
02121 wn_pid0 = AWN_LdidSym(dli->Mp_Info->Pid_Sym0());
02122 OPCODE eq_op =
02123 OPCODE_make_op(OPR_EQ, Boolean_type, type);
02124 WN* wn_cond = LWN_CreateExp2(eq_op, wn_pid0, wn_last_proc);
02125 sprintf(Str_Buf, "$da_last_iter%d", WN_map_id(wn_loop));
02126 SYMBOL* sym_last_iter = CXX_NEW(SYMBOL(Create_Preg_Symbol(Str_Buf, type)),
02127 &LNO_default_pool);
02128 WN* wn_last_iter = AWN_StidIntoSym(sym_last_iter, wn_cond);
02129 WN_Set_Linenum(wn_last_iter, linenum);
02130 LWN_Insert_Block_After(bounds_code, NULL, wn_last_iter);
02131 Add_Pragma_To_MP_Region(wn_loop, sym_last_iter->St(),
02132 sym_last_iter->WN_Offset(), WN_PRAGMA_LOCAL);
02133 if (dli->Mp_Info->Nest_Total() == 1)
02134 du->Add_Def_Use(wn_last_iter, Return_Node(Current_Func_Node));
02135
02136
02137 WN* wn_first = WN_first(WN_region_pragmas(wn_region));
02138 for (WN* wn = wn_first; wn != NULL; wn = WN_next(wn)) {
02139 if (WN_opcode(wn) == OPC_PRAGMA) {
02140 if (WN_pragma(wn) == WN_PRAGMA_MPSCHEDTYPE
02141 && WN_pragma_arg1(wn) == WN_PRAGMA_SCHEDTYPE_INTERLEAVE) {
02142 WN_pragma_arg1(wn) = WN_PRAGMA_SCHEDTYPE_PSEUDOLOWERED;
02143 break;
02144 }
02145 }
02146 }
02147 Add_Pragma_To_MP_Region(wn_loop,
02148 sym_last_iter->St(), sym_last_iter->WN_Offset(),
02149 WN_PRAGMA_LASTTHREAD);
02150
02151 } else {
02152
02153
02154 WN* wn_pid1 = AWN_LdidSym(dli->Mp_Info->Pid_Sym1());
02155 sprintf(Str_Buf, "$da_lb%d", WN_map_id(wn_loop));
02156 *new_lb = CXX_NEW(SYMBOL(Create_Preg_Symbol(Str_Buf, type)),
02157 &LNO_default_pool);
02158 WN* wn_new_lb = AWN_StidIntoSym(*new_lb, wn_pid1);
02159 WN_Set_Linenum(wn_new_lb, linenum);
02160 LWN_Insert_Block_After(bounds_code, NULL, wn_new_lb);
02161 Add_Pragma_To_MP_Region(wn_loop, (*new_lb)->St(), (*new_lb)->WN_Offset(),
02162 WN_PRAGMA_LOCAL);
02163
02164
02165 WN* wn_cp_stride = LWN_Copy_Tree(wn_stride);
02166 LWN_Copy_Def_Use(wn_stride, wn_cp_stride, du);
02167 WN* wn_cp_chunksize = Interleaved_Pragma_Chunksize(wn_loop, du);
02168 WN* wn_stride_chunk = AWN_Mpy(type, wn_cp_stride, wn_cp_chunksize);
02169 wn_cp_stride = LWN_Copy_Tree(wn_stride);
02170 LWN_Copy_Def_Use(wn_stride, wn_cp_stride, du);
02171 WN* wn_base_increment = AWN_Sub(type, wn_stride_chunk, wn_cp_stride);
02172 wn_pid1 = AWN_LdidSym(dli->Mp_Info->Pid_Sym1());
02173 WN* wn_base = AWN_Add(type, wn_pid1, wn_base_increment);
02174 WN* wn_ub = LWN_Copy_Tree(UBexp(WN_end(wn_loop)));
02175 LWN_Copy_Def_Use(UBexp(WN_end(wn_loop)), wn_ub, du);
02176 wn_ub = AWN_Min(type, wn_base, wn_ub);
02177 sprintf(Str_Buf, "$da_ub%d", WN_map_id(wn_loop));
02178 *new_ub = CXX_NEW(SYMBOL(Create_Preg_Symbol(Str_Buf, type)),
02179 &LNO_default_pool);
02180 WN* wn_new_ub = AWN_StidIntoSym(*new_ub, wn_ub);
02181 WN_Set_Linenum(wn_new_ub, linenum);
02182 LWN_Insert_Block_After(bounds_code, NULL, wn_new_ub);
02183 Add_Pragma_To_MP_Region(wn_loop, (*new_ub)->St(), (*new_ub)->WN_Offset(),
02184 WN_PRAGMA_LOCAL);
02185
02186
02187 wn_cp_stride = LWN_Copy_Tree(wn_stride);
02188 sprintf(Str_Buf, "$da_step%d", WN_map_id(wn_loop));
02189 *new_step = CXX_NEW(SYMBOL(Create_Preg_Symbol(Str_Buf, type)),
02190 &LNO_default_pool);
02191 WN* wn_new_step = AWN_StidIntoSym(*new_step, wn_cp_stride);
02192 WN_Set_Linenum(wn_new_step, linenum);
02193 LWN_Insert_Block_After(bounds_code, NULL, wn_new_step);
02194 Add_Pragma_To_MP_Region(wn_loop, (*new_step)->St(),
02195 (*new_step)->WN_Offset(), WN_PRAGMA_LOCAL);
02196
02197
02198 WN* wn_first = WN_first(WN_region_pragmas(wn_region));
02199 for (WN* wn = wn_first; wn != NULL; wn = WN_next(wn)) {
02200 if (WN_opcode(wn) == OPC_XPRAGMA
02201 && (WN_pragma(wn) == WN_PRAGMA_CHUNKSIZE)) {
02202 LWN_Extract_From_Block(LWN_Get_Parent(wn), wn);
02203 LWN_Delete_Tree(wn);
02204 break;
02205 }
02206 }
02207 }
02208
02209 return bounds_code;
02210 }
02211
02212
02213
02214
02215
02216
02217
02218
02219
02220
02221 INT64
02222 Get_Step_Multiplier(WN *doloop, SYMBOL *var)
02223 {
02224 if ((var == NULL) || (doloop == NULL) || (WN_opcode(doloop) != OPC_DO_LOOP)) return 0;
02225
02226 WN *step_wn = WN_step(doloop);
02227 WN *index_wn = WN_index(doloop);
02228
02229 if ((WN_st(step_wn) != WN_st(index_wn)) ||
02230 (WN_offset(step_wn) != WN_offset(index_wn))) {
02231
02232 DevWarn("Get_Step_Multiplier: index %s/%d but assignment to %s/%d in step",
02233 ST_name(WN_st(step_wn)), WN_offset(step_wn),
02234 ST_name(WN_st(index_wn)), WN_offset(index_wn));
02235 return 0;
02236 }
02237
02238 if (WN_operator(step_wn) != OPR_STID) {
02239 DevWarn("Get_Step_Multiplier: step expression not STID, got opcode=%d",
02240 WN_operator(step_wn));
02241 return 0;
02242 }
02243
02244 WN *kid = WN_kid0(step_wn);
02245 if (WN_operator(kid) != OPR_ADD) return 0;
02246
02247 WN *exprkid = WN_kid1(kid);
02248
02249
02250
02251 if ((WN_operator(exprkid) == OPR_LDID) &&
02252 (Symbols_Equiv(exprkid, var))) {
02253
02254 return 1;
02255 }
02256
02257 if (WN_operator(exprkid) != OPR_MPY) return 0;
02258
02259
02260
02261 WN *constkid = NULL;
02262 WN *varkid = NULL;
02263 if ((WN_operator(WN_kid0(exprkid)) == OPR_INTCONST) &&
02264 (WN_operator(WN_kid1(exprkid)) == OPR_LDID)) {
02265
02266 constkid = WN_kid0(exprkid);
02267 varkid = WN_kid1(exprkid);
02268 if (!Symbols_Equiv(varkid, var)) return 0;
02269
02270 } else if ((WN_operator(WN_kid1(exprkid)) == OPR_INTCONST) &&
02271 (WN_operator(WN_kid0(exprkid)) == OPR_LDID)) {
02272
02273 varkid = WN_kid0(exprkid);
02274 constkid = WN_kid1(exprkid);
02275 if (WN_st(varkid) != var->St()) return 0;
02276 } else {
02277 return 0;
02278 }
02279
02280 return (WN_const_val(constkid));
02281 }
02282
02283
02284
02285
02286
02287
02288 BOOL
02289 Symbols_Equiv(WN *wn_ldid,
02290 SYMBOL *var)
02291 {
02292 if (WN_operator(wn_ldid) != OPR_LDID) return FALSE;
02293
02294 DEF_LIST *defs = Du_Mgr->Ud_Get_Def(wn_ldid);
02295 if (defs && defs->Len() == 1) {
02296 WN *def_wn = defs->Head()->Wn();
02297
02298 if ((WN_operator(def_wn) != OPR_STID) ||
02299 (SYMBOL(def_wn) != SYMBOL(wn_ldid))) {
02300
02301 return FALSE;
02302 }
02303 WN* rhs_wn = WN_kid0(def_wn);
02304 if (WN_operator(rhs_wn) == OPR_CVTL ||
02305 WN_operator(rhs_wn) == OPR_CVT)
02306 rhs_wn = WN_kid0(rhs_wn);
02307
02308 if (!OPCODE_is_load(WN_opcode(rhs_wn))) return FALSE;
02309
02310 if (SYMBOL(rhs_wn) == *var) {
02311 return TRUE;
02312 }
02313
02314 return (Symbols_Equiv(WN_kid0(def_wn), var));
02315 }
02316
02317 return FALSE;
02318 }
02319
02320
02321
02322
02323
02324
02325 LEGO_INFO::LEGO_INFO(SYMBOL *array) :
02326 _local_index_wn(LEGO_pool),
02327 _dynamic_affinity(FALSE)
02328 {
02329 Init(array, 0, 1, 0, 0, 0);
02330 }
02331
02332 LEGO_INFO::LEGO_INFO(SYMBOL *array,
02333 INT32 dim,
02334 INT32 stride,
02335 INT32 offset) :
02336 _local_index_wn(LEGO_pool),
02337 _dynamic_affinity(FALSE)
02338 {
02339 Init(array, dim, stride, offset, 0, 0);
02340 }
02341
02342 LEGO_INFO::LEGO_INFO(SYMBOL *array,
02343 INT32 dim,
02344 INT32 stride,
02345 INT32 offset,
02346 INT32 front_peel,
02347 INT32 back_peel) :
02348 _local_index_wn(LEGO_pool),
02349 _dynamic_affinity(FALSE)
02350 {
02351 Init(array, dim, stride, offset, front_peel, back_peel);
02352 }
02353
02354 LEGO_INFO::~LEGO_INFO()
02355 {
02356 CXX_DELETE(_array, LEGO_pool);
02357 FmtAssert(_pid_sym0 == NULL, ("_pid_sym0 should be NULL"));
02358 FmtAssert(_pid_sym1 == NULL, ("_pid_sym1 should be NULL"));
02359 FmtAssert(_local_index_sym == NULL, ("_local_index_sym should be NULL"));
02360 FmtAssert(_runtime_lb_sym == NULL, ("_runtime_lb_sym should be NULL"));
02361 FmtAssert(_runtime_ub_sym == NULL, ("_runtime_ub_sym should be NULL"));
02362 FmtAssert(_runtime_step_sym == NULL, ("_runtime_step_sym should be NULL"));
02363 }
02364
02365 void LEGO_INFO::Init(SYMBOL *array,
02366 INT32 dim,
02367 INT32 stride,
02368 INT32 offset,
02369 INT32 front_peel,
02370 INT32 back_peel)
02371 {
02372 _dynamic_affinity = FALSE;
02373 _array = array;
02374 _dim_num = dim;
02375 _stride = stride;
02376 _offset = offset;
02377 _front_peel = front_peel;
02378 _back_peel = back_peel;
02379 _min_offset = 0;
02380 _max_offset = 0;
02381 _too_messy = FALSE;
02382 _pid_sym0 = NULL;
02383 _pid_sym1 = NULL;
02384 _local_index_sym = NULL;
02385 _runtime_lb_sym = NULL;
02386 _runtime_ub_sym = NULL;
02387 _runtime_step_sym = NULL;
02388 }
02389
02390 LEGO_INFO::LEGO_INFO(LEGO_INFO* lego_info,
02391 MEM_POOL *pool) :
02392 _local_index_wn(LEGO_pool),
02393 _dynamic_affinity(FALSE)
02394 {
02395 _array = CXX_NEW(SYMBOL(lego_info->_array), pool);
02396 _dim_num = lego_info->_dim_num;
02397 _stride = lego_info->_stride;
02398 _offset = lego_info->_offset;
02399 _front_peel = lego_info->_front_peel;
02400 _back_peel = lego_info->_back_peel;
02401 _min_offset = lego_info->_min_offset;
02402 _max_offset = lego_info->_max_offset;
02403 _too_messy = lego_info->_too_messy;
02404 _pid_sym0 = lego_info->_pid_sym0 != NULL ?
02405 CXX_NEW(SYMBOL(lego_info->_pid_sym0), pool) : NULL;
02406 _pid_sym1 = lego_info->_pid_sym1 != NULL ?
02407 CXX_NEW(SYMBOL(lego_info->_pid_sym1), pool) : NULL;
02408 _local_index_sym = NULL;
02409
02410 _runtime_lb_sym = lego_info->_runtime_lb_sym != NULL ?
02411 CXX_NEW(SYMBOL(lego_info->_runtime_lb_sym), pool) : NULL;
02412 _runtime_ub_sym = lego_info->_runtime_ub_sym != NULL ?
02413 CXX_NEW(SYMBOL(lego_info->_runtime_ub_sym), pool) : NULL;
02414 _runtime_step_sym = lego_info->_runtime_step_sym != NULL ?
02415 CXX_NEW(SYMBOL(lego_info->_runtime_step_sym), pool) : NULL;
02416 }
02417
02418 WN* LEGO_INFO::Pid0(WN* curr_wn)
02419 {
02420 Is_True (Pid_Sym0(), ("Pid0: pid_sym0 is NULL\n"));
02421
02422 WN *ldid_wn = NULL;
02423 TYPE_ID type = Pid_Sym0()->Type;
02424
02425 if (ST_class(Pid_Sym0()->St()) == CLASS_PREG) {
02426 ldid_wn = AWN_LdidSym (Pid_Sym0());
02427 } else {
02428 OPCODE op = OPCODE_make_op(OPR_LDID, type, type);
02429 ldid_wn = WN_CreateLdid(op, Pid_Sym0()->WN_Offset(), Pid_Sym0()->St(),
02430 Be_Type_Tbl(type));
02431 }
02432
02433
02434
02435
02436 WN *pid_loop = curr_wn;
02437 while (pid_loop) {
02438 if ((WN_opcode(pid_loop) == OPC_DO_LOOP) &&
02439 (SYMBOL(WN_index(pid_loop)) == *(Pid_Sym0()))) {
02440 break;
02441 } else {
02442 pid_loop = LWN_Get_Parent(pid_loop);
02443 }
02444 }
02445
02446 if (pid_loop != NULL) {
02447 Du_Mgr->Add_Def_Use(WN_start(pid_loop), ldid_wn);
02448 Du_Mgr->Add_Def_Use(WN_step(pid_loop), ldid_wn);
02449 Du_Mgr->Ud_Get_Def(ldid_wn)->Set_loop_stmt(pid_loop);
02450 Copy_alias_info(Alias_Mgr, WN_start(pid_loop), ldid_wn);
02451 return ldid_wn;
02452 }
02453
02454 WN* wn_stid = NULL;
02455 for (WN* wn = curr_wn; wn != NULL; wn = LWN_Get_Parent(wn)) {
02456 if (WN_opcode(wn) != OPC_DO_LOOP)
02457 continue;
02458 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn);
02459 if (!dli->Is_Outer_Lego_Tile)
02460 continue;
02461 if (!dli->Is_Processor_Tile)
02462 continue;
02463 pid_loop = wn;
02464 break;
02465 }
02466 FmtAssert(pid_loop != NULL, ("Could not find pid loop for pid0"));
02467 WN* wn_first = WN_first(WN_do_body(pid_loop));
02468 for (WN* wnn = wn_first; wnn != NULL; wnn = WN_next(wnn)) {
02469 if (WN_operator(wnn) == OPR_STID
02470 && SYMBOL(wnn) == *(Pid_Sym0())) {
02471 wn_stid = wnn;
02472 break;
02473 }
02474 }
02475 FmtAssert(wn_stid != NULL, ("Could not find pid0"));
02476 Du_Mgr->Add_Def_Use(wn_stid, ldid_wn);
02477 Du_Mgr->Ud_Get_Def(ldid_wn)->Set_loop_stmt(NULL);
02478 Copy_alias_info(Alias_Mgr, wn_stid, ldid_wn);
02479 return ldid_wn;
02480 }
02481
02482 WN* LEGO_INFO::Pid1(WN* curr_wn)
02483 {
02484 Is_True (Pid_Sym1(), ("Pid: pid_sym1 is NULL\n"));
02485
02486 WN *ldid_wn = NULL;
02487 TYPE_ID type = Pid_Sym1()->Type;
02488
02489 if (ST_class(Pid_Sym1()->St()) == CLASS_PREG) {
02490 ldid_wn = AWN_LdidSym (Pid_Sym1());
02491 } else {
02492 OPCODE op = OPCODE_make_op(OPR_LDID, type, type);
02493 ldid_wn = WN_CreateLdid(op, Pid_Sym1()->WN_Offset(), Pid_Sym1()->St(),
02494 Be_Type_Tbl(type));
02495 }
02496
02497
02498
02499
02500
02501 WN *pid_loop = curr_wn;
02502 while (pid_loop) {
02503 if ((WN_opcode(pid_loop) == OPC_DO_LOOP) &&
02504 (SYMBOL(WN_index(pid_loop)) == *(Pid_Sym1()))) {
02505 break;
02506 } else {
02507 pid_loop = LWN_Get_Parent(pid_loop);
02508 }
02509 }
02510
02511 if (pid_loop != NULL) {
02512 Du_Mgr->Add_Def_Use(WN_start(pid_loop), ldid_wn);
02513 Du_Mgr->Add_Def_Use(WN_step(pid_loop), ldid_wn);
02514 Du_Mgr->Ud_Get_Def(ldid_wn)->Set_loop_stmt(pid_loop);
02515 Copy_alias_info(Alias_Mgr, WN_start(pid_loop), ldid_wn);
02516 return ldid_wn;
02517 }
02518
02519 WN* wn_stid = NULL;
02520 for (WN* wn = curr_wn; wn != NULL; wn = LWN_Get_Parent(wn)) {
02521 if (WN_opcode(wn) != OPC_DO_LOOP)
02522 continue;
02523 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn);
02524 if (!dli->Is_Outer_Lego_Tile)
02525 continue;
02526 if (!dli->Is_Processor_Tile)
02527 continue;
02528 pid_loop = wn;
02529 break;
02530 }
02531 FmtAssert(pid_loop != NULL, ("Could not find pid loop for pid1"));
02532 WN* wn_first = WN_first(WN_do_body(pid_loop));
02533 for (WN* wnn = wn_first; wnn != NULL; wnn = WN_next(wnn)) {
02534 if (WN_operator(wnn) == OPR_STID
02535 && SYMBOL(wnn) == *(Pid_Sym1())) {
02536 wn_stid = wnn;
02537 break;
02538 }
02539 }
02540 FmtAssert(wn_stid != NULL, ("Could not find pid1"));
02541 Du_Mgr->Add_Def_Use(wn_stid, ldid_wn);
02542 Du_Mgr->Ud_Get_Def(ldid_wn)->Set_loop_stmt(NULL);
02543 Copy_alias_info(Alias_Mgr, wn_stid, ldid_wn);
02544 return ldid_wn;
02545 }
02546
02547
02548 WN *LEGO_INFO::Local_Index()
02549 {
02550 Is_True(Local_Index_Sym() && (_local_index_wn.Elements() > 0),
02551 ("Local_Index: local_index and/or local_index_wn are empty\n"));
02552
02553 Is_True(ST_class(Local_Index_Sym()->St()) == CLASS_PREG,
02554 ("Local_Index: local_index is not a PREG, got class %d\n",
02555 ST_class(Local_Index_Sym()->St())));
02556
02557 WN *ldid_wn = NULL;
02558 ldid_wn = AWN_LdidSym(Local_Index_Sym());
02559 WN *def_wn = NULL;
02560
02561 for (INT i = 0; i < _local_index_wn.Elements(); i++) {
02562 def_wn = _local_index_wn[i];
02563
02564 Is_True(OPCODE_is_store(WN_opcode(def_wn)),
02565 ("Local_Index: def_wn is not a store, got opcode=%d\n",
02566 WN_operator(def_wn)));
02567
02568 Du_Mgr->Add_Def_Use(def_wn, ldid_wn);
02569 }
02570
02571 Copy_alias_info(Alias_Mgr, def_wn, ldid_wn);
02572
02573 return ldid_wn;
02574 }
02575
02576
02577 void LEGO_INFO::Set_Pid0(SYMBOL *pid_sym)
02578 {
02579 _pid_sym0 = pid_sym;
02580 }
02581
02582 void LEGO_INFO::Set_Pid1(SYMBOL *pid_sym)
02583 {
02584 _pid_sym1 = pid_sym;
02585 }
02586
02587
02588 void LEGO_INFO::Create_Local_Index(WN *doloop)
02589 {
02590 if (Has_Local_Index()) return;
02591
02592
02593
02594 SYMBOL *array_sym = Array();
02595 DISTR_ARRAY *dact = Lookup_DACT(array_sym->St());
02596 Is_True(dact, ("Create_Local_Index: No DACT for array %s in LEGO_INFO",
02597 ST_name(array_sym->St())));
02598
02599
02600
02601 WN *curr_lb_wn = WN_kid0(WN_start(doloop));
02602 TYPE_ID type = WN_rtype(curr_lb_wn);
02603
02604 sprintf(Str_Buf, "$local_index%d", WN_map_id(doloop));
02605 _local_index_sym =
02606 CXX_NEW(SYMBOL(Create_Preg_Symbol(Str_Buf, type)), LEGO_pool);
02607
02608
02609
02610 WN *curr_lb_copy = LWN_Copy_Tree(curr_lb_wn);
02611 LWN_Copy_Def_Use(curr_lb_wn, curr_lb_copy, Du_Mgr);
02612
02613 WN *init_wn = AWN_Mpy(type, curr_lb_copy, LWN_Make_Icon(type, Stride()));
02614 init_wn = AWN_Add(type, init_wn, LWN_Make_Icon(type, Offset()));
02615
02616
02617
02618
02619
02620
02621
02622 switch (dact->Dims()[Dim_Num()].Distr_Type()) {
02623
02624
02625
02626 case DISTRIBUTE_BLOCK: {
02627 WN *dimsize = dact->Dinfo()->Dimsize(Dim_Num());
02628 init_wn = AWN_Rem_Safe(type, init_wn, dimsize);
02629 break;
02630 }
02631
02632
02633
02634 case DISTRIBUTE_STAR: {
02635 FmtAssert(FALSE, ("Create_Local_Index: Got DISTRIBUTE_STAR\n"));
02636 break;
02637 }
02638
02639 case DISTRIBUTE_CYCLIC_CONST: {
02640 if (dact->Dims()[Dim_Num()].Chunk_Const_Val() == 1) {
02641
02642
02643
02644 WN *numprocs = dact->Dinfo()->Numprocs(Dim_Num());
02645 init_wn = AWN_Div_Safe(type, init_wn, numprocs);
02646
02647 } else {
02648
02649
02650
02651 WN *chunk_nd = LWN_Make_Icon(type, dact->Dims()[Dim_Num()].Chunk_Const_Val());
02652 init_wn = AWN_Rem_Safe(type, init_wn, chunk_nd);
02653 }
02654 break;
02655 }
02656
02657
02658
02659 case DISTRIBUTE_CYCLIC_EXPR: {
02660 WN *chunk_nd = dact->Chunksize(Dim_Num());
02661 init_wn = AWN_Rem_Safe(type, init_wn, chunk_nd);
02662 break;
02663 }
02664 }
02665
02666 init_wn = AWN_StidIntoSym(_local_index_sym, init_wn);
02667 WN_Set_Linenum(init_wn, WN_Get_Linenum(doloop));
02668
02669 LWN_Insert_Block_Before(LWN_Get_Parent(doloop), doloop, init_wn);
02670 _local_index_wn[_local_index_wn.Newidx()] = init_wn;
02671
02672
02673
02674
02675 WN *ldid_wn = AWN_LdidSym (_local_index_sym);
02676 Du_Mgr->Add_Def_Use(init_wn, ldid_wn);
02677
02678 INT64 step = Get_Local_Step(doloop);
02679
02680 FmtAssert(step != 0, ("Create_Local_Index: Bad step size in loop %s\n",
02681 ST_name(WN_st(WN_index(doloop)))));
02682
02683 WN *incr_wn = AWN_Add(type, ldid_wn, LWN_Make_Icon(type, step*Stride()));
02684 incr_wn = AWN_StidIntoSym(_local_index_sym, incr_wn);
02685 WN_Set_Linenum(incr_wn, WN_Get_Linenum(doloop));
02686
02687 Copy_alias_info(Alias_Mgr, init_wn, incr_wn);
02688 Du_Mgr->Add_Def_Use (incr_wn, ldid_wn);
02689
02690
02691 LWN_Insert_Block_Before(WN_do_body(doloop), NULL, incr_wn);
02692 _local_index_wn[_local_index_wn.Newidx()] = incr_wn;
02693
02694 if (LNO_enabled && !Get_Trace(TP_LNOPT2, TT_LEGO_DISABLE_HOIST)) {
02695
02696
02697 extern void Try_Hoist_Expression (WN* expr_wn);
02698
02699 Try_Hoist_Expression (WN_kid0(init_wn));
02700 }
02701 }
02702
02703
02704 INT64 LEGO_INFO::Get_Local_Step(WN *doloop)
02705 {
02706
02707
02708 SYMBOL *array_sym = Array();
02709 DISTR_ARRAY *dact = Lookup_DACT(array_sym->St());
02710 Is_True(dact, ("Get_Local_Step: No DACT for array %s in LEGO_INFO",
02711 ST_name(array_sym->St())));
02712
02713 INT64 step = 0;
02714
02715 switch (dact->Dims()[Dim_Num()].Distr_Type()) {
02716
02717
02718
02719 case DISTRIBUTE_BLOCK: {
02720
02721 step = Step_Size(doloop);
02722
02723 if (step == 0) step = Get_Step_Multiplier(doloop, Runtime_Step_Sym());
02724 break;
02725 }
02726
02727
02728
02729 case DISTRIBUTE_STAR: {
02730 step = Step_Size(doloop);
02731 break;
02732 }
02733
02734 case DISTRIBUTE_CYCLIC_CONST: {
02735 if (dact->Dims()[Dim_Num()].Chunk_Const_Val() == 1) {
02736
02737
02738
02739
02740
02741 step = Get_Step_Multiplier(doloop, dact->Dinfo()->Get_Numprocs(Dim_Num()));
02742
02743 if (step == 0) step = Get_Step_Multiplier(doloop, Runtime_Step_Sym());
02744
02745 } else {
02746
02747
02748
02749
02750
02751 step = Step_Size(doloop);
02752
02753 if (step == 0) step = Get_Step_Multiplier(doloop, Runtime_Step_Sym());
02754 }
02755 break;
02756 }
02757
02758
02759
02760 case DISTRIBUTE_CYCLIC_EXPR: {
02761
02762 step = Step_Size(doloop);
02763
02764 if (step == 0) step = Get_Step_Multiplier(doloop, Runtime_Step_Sym());
02765 break;
02766 }
02767 }
02768
02769 return step;
02770 }
02771
02772
02773 void LEGO_INFO::Print(FILE* fp)
02774 {
02775 if (Is_Too_Messy()) {
02776 fprintf(fp, "Lego loop info too messy\n");
02777 return;
02778 }
02779 if (Array()) {
02780 fprintf(fp, "Lego loop info for %s: dim(%d) = %dx+%d\n",
02781 ST_name(Array()->St()), Dim_Num(), Stride(), Offset());
02782 if (Pid_Sym0() != NULL) {
02783 const char* name = ST_class(Pid_Sym0()->St()) != CLASS_PREG
02784 ? ST_name(Pid_Sym0()->St())
02785 : Pid_Sym0()->WN_Offset() > Last_Dedicated_Preg_Offset
02786 ? Preg_Name(Pid_Sym0()->WN_Offset()) : "DEDICATED PREG";
02787 fprintf(fp, " Pid_Sym0 = %s\n", name);
02788 }
02789 if (Pid_Sym1() != NULL) {
02790 const char* name = ST_class(Pid_Sym1()->St()) != CLASS_PREG
02791 ? ST_name(Pid_Sym1()->St())
02792 : Pid_Sym1()->WN_Offset() > Last_Dedicated_Preg_Offset
02793 ? Preg_Name(Pid_Sym1()->WN_Offset()) : "DEDICATED PREG";
02794 fprintf(fp, " Pid_Sym1 = %s\n", name);
02795 }
02796 if (Dynamic_Affinity())
02797 fprintf(fp, " Dynamic");
02798 }
02799 fprintf(fp, "\n Front Peel = %d\n", Front_Peel());
02800 fprintf(fp, " Back Peel = %d\n", Back_Peel());
02801 fprintf(fp, " Min Offset = %d\n", Min_Offset());
02802 fprintf(fp, " Max Offset = %d\n", Max_Offset());
02803 if (Has_Local_Index())
02804 fprintf(fp, "Has Local Index\n");
02805 }
02806
02807
02808 RR_INFO::RR_INFO (INT ndims) {
02809 _ndims = ndims;
02810 _rrdim = CXX_NEW_ARRAY (RR_DIM, ndims, LEGO_pool);
02811 for (INT i=0; i<ndims; i++) _rrdim[i].Init (0, NULL, -1);
02812 }
02813
02814 RR_INFO::RR_INFO (RR_INFO* rri) {
02815 _ndims = rri->_ndims;
02816 _rrdim = CXX_NEW_ARRAY (RR_DIM, _ndims, LEGO_pool);
02817 for (INT i=0; i<_ndims; i++) _rrdim[i].Init (rri->Dim(i));
02818 }
02819
02820 RR_INFO::~RR_INFO () {
02821 CXX_DELETE_ARRAY (_rrdim, LEGO_pool);
02822 }
02823
02824 extern RR_INFO* Get_RR_Map (WN* wn) {
02825 return (RR_INFO*) WN_MAP_Get (RR_Map, wn);
02826 }
02827
02828 extern void Set_RR_Map (WN* wn, RR_INFO* rri) {
02829 WN_MAP_Set (RR_Map, wn, (void*) rri);
02830 }
02831
02832
02833
02834
02835
02836
02837 static WN* Find_Proc_Tile_Loop (WN* do_wn) {
02838 Is_True (do_wn && WN_operator(do_wn) == OPR_DO_LOOP,
02839 ("Find_Proc_Tile_Loop must be called with a do-loop"));
02840
02841 DO_LOOP_INFO* dli = Get_Do_Loop_Info (do_wn);
02842 LEGO_INFO* li = dli->Lego_Info;
02843
02844 Is_True (dli->Is_Inner_Lego_Tile,
02845 ("Find_Proc_Tile_Loop must be called with lego inner-tile loop"));
02846
02847 Is_True (dli->Lego_Mp_Key_Lower == dli->Lego_Mp_Key_Upper &&
02848 dli->Lego_Mp_Key_Depth > 0,
02849 ("Find_Proc_Tile_Loop: inconsistent lower/upper key values"));
02850
02851 WN* proc_wn = LWN_Get_Parent (do_wn);
02852 while (proc_wn) {
02853 if (WN_operator(proc_wn) == OPR_DO_LOOP) {
02854 DO_LOOP_INFO* pdli = Get_Do_Loop_Info(proc_wn);
02855 if (pdli->Is_Processor_Tile &&
02856 pdli->Lego_Mp_Key_Depth == 0 &&
02857 dli->Lego_Mp_Key_Lower >= pdli->Lego_Mp_Key_Lower &&
02858 dli->Lego_Mp_Key_Lower <= pdli->Lego_Mp_Key_Upper) {
02859
02860 return proc_wn;
02861 }
02862 }
02863 proc_wn = LWN_Get_Parent(proc_wn);
02864 }
02865 Is_True (FALSE, ("Find_Proc_Tile_Loop: could not find proc-tile loop"));
02866 return NULL;
02867 }
02868
02869
02870
02871
02872
02873
02874
02875 static void RR_Map_Refs (WN* do_wn, WN* ref_wn) {
02876 if (!ref_wn) return;
02877
02878 OPERATOR opr = WN_operator(ref_wn);
02879 if (opr == OPR_ARRAY) {
02880 WN* base_wn = WN_array_base(ref_wn);
02881 if (WN_operator(base_wn) != OPR_LDID &&
02882 WN_operator(base_wn) != OPR_LDA)
02883 goto recurse;
02884
02885 DISTR_INFO* dinfo = da_hash->Find(WN_st(base_wn));
02886 if (!dinfo || !dinfo->IsReshaped())
02887 goto recurse;
02888
02889
02890 DISTR_ARRAY* my_dact = dinfo->Get_Dact(0);
02891 ACCESS_ARRAY* aa = (ACCESS_ARRAY*) WN_MAP_Get(LNO_Info_Map, ref_wn);
02892 DO_LOOP_INFO* dli = Get_Do_Loop_Info (do_wn);
02893 LEGO_INFO* li = dli->Lego_Info;
02894 DISTR_ARRAY* aff_dact= Lookup_DACT(li->Array()->St());
02895 INT dim_num = li->Dim_Num();
02896
02897 for (INT i=0; i<aa->Num_Vec(); i++) {
02898 ACCESS_VECTOR* av = aa->Dim(i);
02899 INT64 stride, offset;
02900 mINT32 depth;
02901
02902 if (!Single_Loop_Coeff (av, &stride, &offset, &depth)) continue;
02903 if (dli->Depth != depth) continue;
02904 if (li->Stride() != stride) continue;
02905
02906
02907 if (!my_dact->DACT_Equiv(aff_dact, i, dim_num)) continue;
02908
02909 RR_INFO* rri = Get_RR_Map (ref_wn);
02910 if (!rri) {
02911 rri = CXX_NEW (RR_INFO(aa->Num_Vec()), LEGO_pool);
02912 Set_RR_Map (ref_wn, rri);
02913 }
02914 RR_DIM* rrdim = rri->Dim(i);
02915 Is_True (rrdim->Do_Loop() == NULL,
02916 ("RR_Map: map already has a proc-tile loop"));
02917
02918
02919 WN* proc_wn = Find_Proc_Tile_Loop (do_wn);
02920 DO_LOOP_INFO* pdli = Get_Do_Loop_Info (proc_wn);
02921
02922 rrdim->Init (offset-li->Offset(), proc_wn,
02923 (dli->Lego_Mp_Key_Lower-pdli->Lego_Mp_Key_Lower));
02924 }
02925 }
02926
02927 recurse:
02928 if (opr == OPR_BLOCK) {
02929 WN* kid = WN_first(ref_wn);
02930 while (kid) {
02931 RR_Map_Refs(do_wn, kid);
02932 kid = WN_next(kid);
02933 }
02934 return;
02935 }
02936
02937 for (INT i=0; i<WN_kid_count(ref_wn); i++) {
02938 RR_Map_Refs(do_wn, WN_kid(ref_wn,i));
02939 }
02940 }
02941
02942
02943
02944
02945
02946
02947
02948 DISTRIBUTE_TYPE Get_Lego_Affinity_Distr_Type (WN* do_wn) {
02949
02950 Is_True (do_wn && WN_operator(do_wn) == OPR_DO_LOOP,
02951 ("Get_Lego_Affinity_Distr_Type not called with a do-loop"));
02952
02953 DO_LOOP_INFO* dli = Get_Do_Loop_Info (do_wn);
02954 Is_True (dli->Is_Inner_Lego_Tile,
02955 ("Get_Lego_Affinity_Distr_Type not called with inner-lego-tile-loop"));
02956 LEGO_INFO* li = dli->Lego_Info;
02957
02958 DISTR_ARRAY* dact = Lookup_DACT(li->Array()->St());
02959 DISTR_INFO* dinfo = dact->Dinfo();
02960
02961
02962 return (dact->Get_Dim(li->Dim_Num())->Distr_Type());
02963 }
02964
02965
02966
02967
02968
02969
02970
02971
02972 extern void RR_Map_Setup_InnerLoop (WN* do_wn) {
02973
02974
02975 if (Get_Lego_Affinity_Distr_Type (do_wn) != DISTRIBUTE_BLOCK)
02976 return;
02977
02978
02979
02980
02981
02982
02983
02984 WN* body_wn = WN_do_body(do_wn);
02985 RR_Map_Refs (do_wn, body_wn);
02986 }
02987
02988
02989
02990
02991
02992
02993
02994
02995
02996
02997 static void RR_Map_Setup_Traverse (WN* wn) {
02998 if (!wn) return;
02999 if (!OPCODE_is_scf(WN_opcode(wn))) return;
03000
03001 OPERATOR opr = WN_operator(wn);
03002
03003 if (opr == OPR_DO_LOOP) {
03004
03005 DO_LOOP_INFO* dli = Get_Do_Loop_Info (wn);
03006 LEGO_INFO* li = dli->Lego_Info;
03007 if (dli->Is_Inner_Lego_Tile && li && !li->Dynamic_Affinity()) {
03008 WN* proc_wn = Find_Proc_Tile_Loop (wn);
03009
03010
03011 DO_LOOP_INFO* pdli = Get_Do_Loop_Info (proc_wn);
03012 if (pdli->Lego_LB_Symbols == NULL) {
03013 INT nloops = pdli->Lego_Mp_Key_Upper - pdli->Lego_Mp_Key_Lower + 1;
03014 pdli->Lego_LB_Symbols = CXX_NEW_ARRAY (SYMBOL, nloops, LEGO_pool);
03015 }
03016
03017
03018 Is_True (dli->Lego_Mp_Key_Lower == dli->Lego_Mp_Key_Upper,
03019 ("Unequal key values in inner lego-tile loop"));
03020
03021 INT myidx = dli->Lego_Mp_Key_Lower - pdli->Lego_Mp_Key_Lower;
03022 SYMBOL* sym = pdli->Lego_LB_Symbols;
03023 char name[64];
03024 sprintf (name, "$store_lb_%d", myidx);
03025 sym[myidx] =
03026 Create_Preg_Symbol (name, TY_mtype(ST_type(WN_st(WN_index(wn)))));
03027
03028
03029 WN* lb_wn = LWN_Copy_Tree(WN_kid0(WN_start(wn)), TRUE, LNO_Info_Map);
03030 LWN_Copy_Def_Use (WN_kid0(WN_start(wn)), lb_wn, Du_Mgr);
03031 WN* stid_wn = AWN_StidIntoSym (&(sym[myidx]), lb_wn);
03032 Du_Mgr->Add_Def_Use (stid_wn, Return_Node (Current_Func_Node));
03033 LWN_Insert_Block_Before (NULL, wn, stid_wn);
03034
03035
03036 RR_Map_Setup_InnerLoop (wn);
03037 }
03038 }
03039
03040 if (opr == OPR_BLOCK) {
03041 WN* kid = WN_first(wn);
03042 while (kid) {
03043 RR_Map_Setup_Traverse(kid);
03044 kid = WN_next(kid);
03045 }
03046 }
03047 else {
03048 for (INT i=0; i<WN_kid_count(wn); i++)
03049 RR_Map_Setup_Traverse(WN_kid(wn, i));
03050 }
03051 }
03052
03053
03054
03055
03056
03057
03058 extern void RR_Map_Setup (WN* func_wn) {
03059 if (disable_rr_maps)
03060 return;
03061
03062 RR_Map_Setup_Traverse(func_wn);
03063 }
03064
03065
03066
03067
03068
03069
03070
03071
03072
03073
03074
03075
03076 static void Pre_Peel_Map_Refs (WN* do_wn, WN* old_wn, WN* new_wn) {
03077 if (!old_wn) return;
03078
03079 Is_True (WN_operator(old_wn) ==
03080 WN_operator(new_wn),
03081 ("Pre_Peel: expected identical old/new nodes"));
03082
03083 OPERATOR opr = WN_operator(old_wn);
03084 if (opr == OPR_ARRAY) {
03085 WN* base_wn = WN_array_base(old_wn);
03086 if (WN_operator(base_wn) != OPR_LDID &&
03087 WN_operator(base_wn) != OPR_LDA)
03088 goto recurse;
03089
03090 DISTR_INFO* dinfo = da_hash->Find(WN_st(base_wn));
03091 if (!dinfo || !dinfo->IsReshaped())
03092 goto recurse;
03093
03094
03095 DISTR_ARRAY* my_dact = dinfo->Get_Dact(0);
03096 ACCESS_ARRAY* aa = (ACCESS_ARRAY*)WN_MAP_Get(LNO_Info_Map,old_wn);
03097 DO_LOOP_INFO* dli = Get_Do_Loop_Info (do_wn);
03098 LEGO_INFO* li = dli->Lego_Info;
03099 DISTR_ARRAY* aff_dact= Lookup_DACT(li->Array()->St());
03100 INT dim_num = li->Dim_Num();
03101
03102 for (INT i=0; i<aa->Num_Vec(); i++) {
03103 ACCESS_VECTOR* av = aa->Dim(i);
03104 INT64 stride, offset;
03105 mINT32 depth;
03106
03107 if (!Single_Loop_Coeff (av, &stride, &offset, &depth)) continue;
03108 if (dli->Depth != depth) continue;
03109 if (li->Stride() != stride) continue;
03110
03111
03112 if (!my_dact->DACT_Equiv(aff_dact, i, dim_num)) continue;
03113
03114 RR_INFO* old_rri = Get_RR_Map (old_wn);
03115 Is_True (old_rri, ("Pre_Peel: missing RR-Map"));
03116
03117
03118
03119 RR_INFO* gomi_rri = Get_RR_Map(new_wn);
03120 FmtAssert (gomi_rri, ("Pre-Peel: expected a map"));
03121 CXX_DELETE (gomi_rri, LEGO_pool);
03122
03123
03124 RR_INFO* new_rri = CXX_NEW (RR_INFO(old_rri), LEGO_pool);
03125 Set_RR_Map (new_wn, new_rri);
03126
03127
03128 RR_DIM* old_rrdim = old_rri->Dim(i);
03129 RR_DIM* new_rrdim = new_rri->Dim(i);
03130 INT dimoff = offset-li->Offset();
03131 if (dimoff == 0) {
03132
03133 } else if (dimoff < 0) {
03134
03135 new_rrdim->Remotize ();
03136 }
03137 else {
03138
03139
03140
03141 new_rrdim->Remotize ();
03142 }
03143 }
03144 }
03145
03146 recurse:
03147 if (opr == OPR_BLOCK) {
03148 WN* kid_old = WN_first(old_wn);
03149 WN* kid_new = WN_first(new_wn);
03150 while (kid_old) {
03151 Pre_Peel_Map_Refs(do_wn, kid_old, kid_new);
03152 kid_old = WN_next(kid_old);
03153 kid_new = WN_next(kid_new);
03154 }
03155 return;
03156 }
03157
03158 for (INT i=0; i<WN_kid_count(old_wn); i++) {
03159 Pre_Peel_Map_Refs(do_wn, WN_kid(old_wn,i), WN_kid(new_wn, i));
03160 }
03161 }
03162
03163
03164
03165
03166
03167
03168
03169
03170
03171
03172 extern void Pre_Peel_RR_Map_Update(WN* do_wn, WN* prev_wn, BOOL create_loop)
03173 {
03174 if (disable_rr_maps)
03175 return;
03176
03177 if (Get_Lego_Affinity_Distr_Type (do_wn) != DISTRIBUTE_BLOCK)
03178 return;
03179
03180 WN* peel_wn;
03181 if (prev_wn) peel_wn = WN_next(prev_wn);
03182 else peel_wn = WN_first(LWN_Get_Parent(do_wn));
03183
03184 if (create_loop) {
03185 Is_True (WN_operator(peel_wn) == OPR_IF,
03186 ("Pre-peel: expected an IF"));
03187 WN* peel_body_wn = WN_first(WN_then(peel_wn));
03188 Is_True (WN_operator(peel_body_wn) == OPR_DO_LOOP,
03189 ("Pre-peel: expected a do-loop"));
03190 Pre_Peel_Map_Refs (do_wn, WN_do_body(do_wn), WN_do_body(peel_body_wn));
03191 }
03192 else {
03193 LEGO_INFO* li = Get_Do_Loop_Info(do_wn)->Lego_Info;
03194 Is_True (li->Front_Peel() > 0,
03195 ("Pre_Peel: front_peel is %d", li->Front_Peel()));
03196 for (INT i=0; i<li->Front_Peel(); i++) {
03197 WN* body_wn = WN_first(WN_do_body(do_wn));
03198 Is_True (WN_operator(peel_wn) == OPR_IF,
03199 ("Pre-peel: expected an IF"));
03200 WN* peel_body_wn = WN_first(WN_then(peel_wn));
03201 while (body_wn) {
03202 Pre_Peel_Map_Refs (do_wn, body_wn, peel_body_wn);
03203 peel_body_wn = WN_next(peel_body_wn);
03204 body_wn = WN_next(body_wn);
03205 }
03206 peel_wn = WN_next(peel_wn);
03207 }
03208 Is_True (peel_wn == do_wn,
03209 ("peel should have reached do loop by now"));
03210 }
03211 }
03212
03213
03214
03215
03216
03217
03218
03219
03220
03221
03222
03223
03224 static void Post_Peel_Map_Refs (WN* do_wn, WN* old_wn, WN* new_wn) {
03225 if (!old_wn) return;
03226
03227 Is_True (WN_operator(old_wn) ==
03228 WN_operator(new_wn),
03229 ("Post_Peel: expected identical old/new nodes"));
03230
03231 OPERATOR opr = WN_operator(old_wn);
03232 if (opr == OPR_ARRAY) {
03233 WN* base_wn = WN_array_base(old_wn);
03234 if (WN_operator(base_wn) != OPR_LDID &&
03235 WN_operator(base_wn) != OPR_LDA)
03236 goto recurse;
03237
03238 DISTR_INFO* dinfo = da_hash->Find(WN_st(base_wn));
03239 if (!dinfo || !dinfo->IsReshaped())
03240 goto recurse;
03241
03242
03243 DISTR_ARRAY* my_dact = dinfo->Get_Dact(0);
03244 ACCESS_ARRAY* aa = (ACCESS_ARRAY*)WN_MAP_Get(LNO_Info_Map,old_wn);
03245 DO_LOOP_INFO* dli = Get_Do_Loop_Info (do_wn);
03246 LEGO_INFO* li = dli->Lego_Info;
03247 DISTR_ARRAY* aff_dact= Lookup_DACT(li->Array()->St());
03248 INT dim_num = li->Dim_Num();
03249
03250 for (INT i=0; i<aa->Num_Vec(); i++) {
03251 ACCESS_VECTOR* av = aa->Dim(i);
03252 INT64 stride, offset;
03253 mINT32 depth;
03254
03255 if (!Single_Loop_Coeff (av, &stride, &offset, &depth)) continue;
03256 if (dli->Depth != depth) continue;
03257 if (li->Stride() != stride) continue;
03258
03259
03260 if (!my_dact->DACT_Equiv(aff_dact, i, dim_num)) continue;
03261
03262 RR_INFO* old_rri = Get_RR_Map (old_wn);
03263 Is_True (old_rri, ("Post_Peel: missing RR-Map"));
03264
03265
03266
03267 RR_INFO* gomi_rri = Get_RR_Map(new_wn);
03268 FmtAssert (gomi_rri, ("Post-Peel: expected a map"));
03269 CXX_DELETE (gomi_rri, LEGO_pool);
03270
03271
03272 RR_INFO* new_rri = CXX_NEW (RR_INFO(old_rri), LEGO_pool);
03273 Set_RR_Map (new_wn, new_rri);
03274
03275
03276 RR_DIM* old_rrdim = old_rri->Dim(i);
03277 RR_DIM* new_rrdim = new_rri->Dim(i);
03278 INT dimoff = offset-li->Offset();
03279 if (dimoff == 0) {
03280
03281 } else if (dimoff < 0) {
03282
03283 new_rrdim->Remotize ();
03284 }
03285 else {
03286
03287
03288
03289 new_rrdim->Remotize ();
03290 }
03291 }
03292 }
03293
03294 recurse:
03295 if (opr == OPR_BLOCK) {
03296 WN* kid_old = WN_first(old_wn);
03297 WN* kid_new = WN_first(new_wn);
03298 while (kid_old) {
03299 Post_Peel_Map_Refs(do_wn, kid_old, kid_new);
03300 kid_old = WN_next(kid_old);
03301 kid_new = WN_next(kid_new);
03302 }
03303 return;
03304 }
03305
03306 for (INT i=0; i<WN_kid_count(old_wn); i++) {
03307 Post_Peel_Map_Refs(do_wn, WN_kid(old_wn,i), WN_kid(new_wn, i));
03308 }
03309 }
03310
03311
03312
03313
03314
03315
03316
03317
03318
03319
03320 extern void Post_Peel_RR_Map_Update(WN* do_wn, WN* next_wn, BOOL create_loop)
03321 {
03322
03323 if (disable_rr_maps)
03324 return;
03325
03326 if (Get_Lego_Affinity_Distr_Type (do_wn) != DISTRIBUTE_BLOCK)
03327 return;
03328
03329 WN* peel_wn;
03330 if (next_wn) peel_wn = WN_prev(next_wn);
03331 else peel_wn = WN_last(LWN_Get_Parent(do_wn));
03332
03333 if (create_loop) {
03334 Is_True (WN_operator(peel_wn) == OPR_IF,
03335 ("Pre-peel: expected an IF"));
03336 WN* peel_body_wn = WN_first(WN_then(peel_wn));
03337 Is_True (WN_operator(peel_body_wn) == OPR_DO_LOOP,
03338 ("Pre-peel: expected a do-loop"));
03339 Post_Peel_Map_Refs (do_wn, WN_do_body(do_wn), WN_do_body(peel_body_wn));
03340 }
03341 else {
03342 LEGO_INFO* li = Get_Do_Loop_Info(do_wn)->Lego_Info;
03343 Is_True (li->Back_Peel() > 0,
03344 ("Post_Peel: back_peel is %d", li->Back_Peel()));
03345 for (INT i=0; i<li->Back_Peel(); i++) {
03346 WN* body_wn = WN_first(WN_do_body(do_wn));
03347 Is_True (WN_operator(peel_wn) == OPR_IF,
03348 ("Pre-peel: expected an IF"));
03349 WN* peel_body_wn = WN_first(WN_then(peel_wn));
03350 while (body_wn) {
03351 Post_Peel_Map_Refs (do_wn, body_wn, peel_body_wn);
03352 peel_body_wn = WN_next(peel_body_wn);
03353 body_wn = WN_next(body_wn);
03354 }
03355 peel_wn = WN_prev(peel_wn);
03356 }
03357 Is_True (peel_wn == do_wn,
03358 ("peel should have reached do loop by now"));
03359 }
03360 }