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 #define __STDC_LIMIT_MACROS
00039 #include <stdint.h>
00040 #ifdef USE_PCH
00041 #include "lno_pch.h"
00042 #endif // USE_PCH
00043 #pragma hdrstop
00044
00045 #include <sys/types.h>
00046 #include <limits.h>
00047 #include <math.h>
00048 #include "pu_info.h"
00049 #include "lnopt_main.h"
00050 #include "config_targ.h"
00051 #include "glob.h"
00052 #include "ara_loop.h"
00053 #include "lwn_util.h"
00054 #include "dep_graph.h"
00055 #include "lnoutils.h"
00056 #include "ff_utils.h"
00057 #include "opt_alias_interface.h"
00058 #include "opt_alias_mgr.h"
00059 #include "opt_du.h"
00060 #include "region_util.h"
00061 #include "wn_pragmas.h"
00062 #include "fusion.h"
00063 #include "ara_utils.h"
00064 #include "debug.h"
00065 #include "lego_util.h"
00066 #include "snl.h"
00067 #include "snl_deps.h"
00068 #include "snl_utils.h"
00069 #include "parallel.h"
00070 #include "const.h"
00071 #include "targ_const.h"
00072 #include "parmodel.h"
00073 #include "config.h"
00074 #include "prompf.h"
00075 #include "anl_driver.h"
00076 #include "stab.h"
00077 #include <alloca.h>
00078 #include "fiz_fuse.h"
00079 #include "parids.h"
00080 #include "call_info.h"
00081 #include "cxx_hash.h"
00082 #include "omp_lower.h"
00083 #include "tlog.h"
00084 #include "be_symtab.h"
00085 #include "ipa_lno_read.h"
00086 #include "lnodriver.h"
00087 #include "ipa_lno_cost.h"
00088
00089
00090 #pragma weak New_Construct_Id
00091
00092 extern INT Parallel_Debug_Level;
00093 extern ARRAY_DIRECTED_GRAPH16 *Array_Dependence_Graph;
00094
00095 extern REDUCTION_MANAGER *red_manager;
00096 extern ALIAS_MANAGER *Alias_Mgr;
00097 extern DU_MANAGER *Du_Mgr;
00098 #ifdef KEY // bug 7772
00099 #define MAX_PROCS (LNO_Num_Processors == 0 ? 8 : LNO_Num_Processors)
00100 #else
00101 const INT MAX_PROCS = 128;
00102 #endif
00103
00104 ARA_LOOP_INFO::ARA_LOOP_INFO():
00105 _children(&ARA_memory_pool),
00106 _def(&ARA_memory_pool),
00107 _may_def(&ARA_memory_pool),
00108 _use(&ARA_memory_pool),
00109 _pri(&ARA_memory_pool),
00110 _scalar_def(&ARA_memory_pool),
00111 _scalar_use(&ARA_memory_pool),
00112 _scalar_pri(&ARA_memory_pool),
00113 _scalar_may_def(&ARA_memory_pool),
00114 _scalar_last_value(&ARA_memory_pool),
00115 _bad_alias(&ARA_memory_pool),
00116 _scalar_always_defined(&ARA_memory_pool),
00117 _scalar_vars(&ARA_memory_pool),
00118 _scalar_alias(&ARA_memory_pool),
00119 _scalar_no_final(&ARA_memory_pool),
00120 _dep_vars(&ARA_memory_pool),
00121 _dep_source(&ARA_memory_pool),
00122 _dep_sink(&ARA_memory_pool),
00123 _ln_dep_source(&ARA_memory_pool),
00124 _ln_dep_sink(&ARA_memory_pool),
00125 _scalar_bad_peel(&ARA_memory_pool),
00126 _ln_scalar_bad_peel(&ARA_memory_pool),
00127 _dep_bad_peel(&ARA_memory_pool),
00128 _ln_dep_bad_peel(&ARA_memory_pool),
00129 _partial_array_sec(&ARA_memory_pool),
00130 _call_no_dep_vars(&ARA_memory_pool),
00131 _ln_call_no_dep_vars(&ARA_memory_pool),
00132 _array_no_dep_vars(&ARA_memory_pool),
00133 _ln_array_no_dep_vars(&ARA_memory_pool),
00134 _ln_misc_no_dep_vars(&ARA_memory_pool),
00135 _reduction(&ARA_memory_pool)
00136 {
00137 }
00138
00139 ARA_LOOP_INFO::ARA_LOOP_INFO(WN* wn,
00140 ARA_LOOP_INFO *p,
00141 const BOOL inv):
00142 _children(&ARA_memory_pool),
00143 _def(&ARA_memory_pool),
00144 _may_def(&ARA_memory_pool),
00145 _use(&ARA_memory_pool),
00146 _pri(&ARA_memory_pool),
00147 _scalar_def(&ARA_memory_pool),
00148 _scalar_use(&ARA_memory_pool),
00149 _scalar_pri(&ARA_memory_pool),
00150 _scalar_may_def(&ARA_memory_pool),
00151 _scalar_last_value(&ARA_memory_pool),
00152 _bad_alias(&ARA_memory_pool),
00153 _scalar_always_defined(&ARA_memory_pool),
00154 _scalar_vars(&ARA_memory_pool),
00155 _scalar_alias(&ARA_memory_pool),
00156 _scalar_no_final(&ARA_memory_pool),
00157 _dep_vars(&ARA_memory_pool),
00158 _dep_source(&ARA_memory_pool),
00159 _dep_sink(&ARA_memory_pool),
00160 _ln_dep_source(&ARA_memory_pool),
00161 _ln_dep_sink(&ARA_memory_pool),
00162 _scalar_bad_peel(&ARA_memory_pool),
00163 _ln_scalar_bad_peel(&ARA_memory_pool),
00164 _dep_bad_peel(&ARA_memory_pool),
00165 _ln_dep_bad_peel(&ARA_memory_pool),
00166 _partial_array_sec(&ARA_memory_pool),
00167 _call_no_dep_vars(&ARA_memory_pool),
00168 _ln_call_no_dep_vars(&ARA_memory_pool),
00169 _array_no_dep_vars(&ARA_memory_pool),
00170 _ln_array_no_dep_vars(&ARA_memory_pool),
00171 _ln_misc_no_dep_vars(&ARA_memory_pool),
00172 _reduction(&ARA_memory_pool)
00173 {
00174 _peel_value = -1;
00175 _is_good = TRUE;
00176 _dep_dist = 0;
00177 _parent = p;
00178 _loop = wn;
00179 _live_use = NULL;
00180 _info = NULL;
00181 _do_stack = NULL;
00182 _invariant_symbols = CXX_NEW(STACK<WN*>(&ARA_memory_pool), &ARA_memory_pool);
00183 _processed = CXX_NEW(STACK<WN*>(&ARA_memory_pool), &ARA_memory_pool);
00184 _kernels = CXX_NEW(KERNEL_LIST, &ARA_memory_pool);
00185 _invariant = FALSE;
00186 _has_last_value_array = FALSE;
00187 _has_bad_region = FALSE;
00188 _inner_loop_is_suggested_parallel = FALSE;
00189 if (wn != NULL && WN_opcode(wn) == OPC_DO_LOOP){
00190 _info = Get_Do_Loop_Info(wn);
00191 Is_True(_info,("ARA_LOOP_INFO::ARA_LOOP_INFO: No DO_LOOP_INFO"));
00192 _invariant = inv && _info && !_info->Has_Exits
00193 &&!_info->Has_Bad_Mem;
00194 _do_stack = CXX_NEW(DOLOOP_STACK(&ARA_memory_pool), &ARA_memory_pool);
00195 Build_Doloop_Stack(wn, _do_stack);
00196 }
00197 }
00198
00199 ARA_LOOP_INFO::ARA_LOOP_INFO(ARA_LOOP_INFO* p):
00200 _children(&ARA_memory_pool),
00201 _reduction(&ARA_memory_pool),
00202 _def(&ARA_memory_pool),
00203 _may_def(&ARA_memory_pool),
00204 _use(&ARA_memory_pool),
00205 _pri(&ARA_memory_pool),
00206 _scalar_def(&ARA_memory_pool),
00207 _scalar_use(&ARA_memory_pool),
00208 _scalar_pri(&ARA_memory_pool),
00209 _scalar_may_def(&ARA_memory_pool),
00210 _scalar_last_value(&ARA_memory_pool),
00211 _bad_alias(&ARA_memory_pool),
00212 _scalar_always_defined(&ARA_memory_pool),
00213 _scalar_vars(&ARA_memory_pool),
00214 _scalar_alias(&ARA_memory_pool),
00215 _scalar_no_final(&ARA_memory_pool),
00216 _scalar_bad_peel(&ARA_memory_pool),
00217 _ln_scalar_bad_peel(&ARA_memory_pool),
00218 _dep_vars(&ARA_memory_pool),
00219 _dep_source(&ARA_memory_pool),
00220 _dep_sink(&ARA_memory_pool),
00221 _ln_dep_source(&ARA_memory_pool),
00222 _ln_dep_sink(&ARA_memory_pool),
00223 _dep_bad_peel(&ARA_memory_pool),
00224 _ln_dep_bad_peel(&ARA_memory_pool),
00225 _partial_array_sec(&ARA_memory_pool),
00226 _call_no_dep_vars(&ARA_memory_pool),
00227 _ln_call_no_dep_vars(&ARA_memory_pool),
00228 _array_no_dep_vars(&ARA_memory_pool),
00229 _ln_array_no_dep_vars(&ARA_memory_pool),
00230 _ln_misc_no_dep_vars(&ARA_memory_pool)
00231 {
00232 INT i;
00233 FmtAssert(p != NULL, ("ARA_LOOP_INFO: NULL pointer passed"));
00234 _invariant = p->_invariant;
00235 for (i = 0; i < _children.Elements(); i++)
00236 _children.Push(p->_children.Bottom_nth(i));
00237 _parent = p->_parent;
00238 _loop = p->_loop;
00239 _info = p->_info;
00240 _kernels = NULL;
00241 KERNEL_SLIST_ITER kiter(p->_kernels);
00242 for (KERNEL_IMAGE* k = kiter.First(); !kiter.Is_Empty(); k = kiter.Next())
00243 _kernels->Append(CXX_NEW(KERNEL_IMAGE(k), &ARA_memory_pool));
00244 _do_stack = NULL;
00245 if (p->_do_stack != NULL) {
00246 _do_stack = CXX_NEW(DOLOOP_STACK(&ARA_memory_pool), &ARA_memory_pool);
00247 for (i = 0; i < p->_do_stack->Elements(); i++)
00248 _do_stack->Push(p->_do_stack->Bottom_nth(i));
00249 }
00250 _invariant_symbols = CXX_NEW(STACK<WN*>(&ARA_memory_pool), &ARA_memory_pool);
00251 if (p->_invariant_symbols != NULL)
00252 for (i = 0; i < p->_invariant_symbols->Elements(); i++)
00253 _invariant_symbols->Push(p->_invariant_symbols->Bottom_nth(i));
00254 _processed = CXX_NEW(STACK<WN*>(&ARA_memory_pool), &ARA_memory_pool);
00255 if (p->_processed != NULL)
00256 for (i = 0; i < p->_processed->Elements(); i++)
00257 _processed->Push(p->_processed->Bottom_nth(i));
00258 for (i = 0; i < p->_reduction.Elements(); i++)
00259 _reduction.Push(p->_reduction.Bottom_nth(i));
00260 _inner_loop_is_suggested_parallel = p->_inner_loop_is_suggested_parallel;
00261 _has_bad_region = p->_has_bad_region;
00262 for (i = 0; i < p->_def.Elements(); i++)
00263 _def.Push(p->_def.Bottom_nth(i));
00264 for (i = 0; i < p->_may_def.Elements(); i++)
00265 _may_def.Push(p->_may_def.Bottom_nth(i));
00266 for (i = 0; i < p->_use.Elements(); i++)
00267 _use.Push(p->_use.Bottom_nth(i));
00268 for (i = 0; i < p->_pri.Elements(); i++)
00269 _pri.Push(p->_pri.Bottom_nth(i));
00270 for (i = 0; i < p->_scalar_def.Elements(); i++)
00271 _scalar_def.Add_Scalar_Node(p->_scalar_def.Bottom_nth(i));
00272 for (i = 0; i < p->_scalar_use.Elements(); i++)
00273 _scalar_use.Add_Scalar_Node(p->_scalar_use.Bottom_nth(i));
00274 for (i = 0; i < p->_scalar_pri.Elements(); i++)
00275 _scalar_pri.Add_Scalar_Node(p->_scalar_pri.Bottom_nth(i));
00276 for (i = 0; i < p->_scalar_may_def.Elements(); i++)
00277 _scalar_may_def.Add_Scalar_Node(p->_scalar_may_def.Bottom_nth(i));
00278 for (i = 0; i < p->_scalar_last_value.Elements(); i++)
00279 _scalar_last_value.Push(p->_scalar_last_value.Bottom_nth(i));
00280 for (i = 0; i < p->_bad_alias.Elements(); i++)
00281 _bad_alias.Push(p->_bad_alias.Bottom_nth(i));
00282 for (i = 0; i < p->_scalar_always_defined.Elements(); i++)
00283 _scalar_always_defined.Push(p->_scalar_always_defined.Bottom_nth(i));
00284 _dep_dist = p->_dep_dist;
00285 _is_good = p->_is_good;
00286 _has_last_value_array = p->_has_last_value_array;
00287 _peel_value = p->_peel_value;
00288 for (i = 0; i < p->_scalar_vars.Elements(); i++)
00289 _scalar_vars.Push(p->_scalar_vars.Bottom_nth(i));
00290 for (i = 0; i < p->_scalar_alias.Elements(); i++)
00291 _scalar_alias.Push(p->_scalar_alias.Bottom_nth(i));
00292 for (i = 0; i < p->_scalar_no_final.Elements(); i++)
00293 _scalar_no_final.Push(p->_scalar_no_final.Bottom_nth(i));
00294 for (i = 0; i < p->_scalar_bad_peel.Elements(); i++)
00295 _scalar_bad_peel.Push(p->_scalar_bad_peel.Bottom_nth(i));
00296 for (i = 0; i < p->_ln_scalar_bad_peel.Elements(); i++)
00297 _ln_scalar_bad_peel.Push(p->_ln_scalar_bad_peel.Bottom_nth(i));
00298 for (i = 0; i < p->_dep_vars.Elements(); i++)
00299 _dep_vars.Push(p->_dep_vars.Bottom_nth(i));
00300 for (i = 0; i < p->_dep_source.Elements(); i++)
00301 _dep_source.Push(p->_dep_source.Bottom_nth(i));
00302 for (i = 0; i < p->_dep_sink.Elements(); i++)
00303 _dep_sink.Push(p->_dep_sink.Bottom_nth(i));
00304 for (i = 0; i < p->_ln_dep_source.Elements(); i++)
00305 _ln_dep_source.Push(p->_ln_dep_source.Bottom_nth(i));
00306 for (i = 0; i < p->_ln_dep_sink.Elements(); i++)
00307 _ln_dep_sink.Push(p->_ln_dep_sink.Bottom_nth(i));
00308 for (i = 0; i < p->_dep_bad_peel.Elements(); i++)
00309 _dep_bad_peel.Push(p->_dep_bad_peel.Bottom_nth(i));
00310 for (i = 0; i < p->_ln_dep_bad_peel.Elements(); i++)
00311 _ln_dep_bad_peel.Push(p->_ln_dep_bad_peel.Bottom_nth(i));
00312 for (i = 0; i < p->_partial_array_sec.Elements(); i++)
00313 _partial_array_sec.Push(p->_partial_array_sec.Bottom_nth(i));
00314 for (i = 0; i < p->_call_no_dep_vars.Elements(); i++)
00315 _call_no_dep_vars.Push(p->_call_no_dep_vars.Bottom_nth(i));
00316 for (i = 0; i < p->_ln_call_no_dep_vars.Elements(); i++)
00317 _ln_call_no_dep_vars.Push(p->_ln_call_no_dep_vars.Bottom_nth(i));
00318 for (i = 0; i < p->_array_no_dep_vars.Elements(); i++)
00319 _array_no_dep_vars.Push(p->_array_no_dep_vars.Bottom_nth(i));
00320 for (i = 0; i < p->_ln_array_no_dep_vars.Elements(); i++)
00321 _ln_array_no_dep_vars.Push(p->_ln_array_no_dep_vars.Bottom_nth(i));
00322 for (i = 0; i < p->_ln_misc_no_dep_vars.Elements(); i++)
00323 _ln_misc_no_dep_vars.Push(p->_ln_misc_no_dep_vars.Bottom_nth(i));
00324 _live_use = NULL;
00325 if (p->_live_use != NULL) {
00326 HASH_TABLE_ITER<ST*,BOOL> hiter(p->_live_use);
00327 ST* st;
00328 BOOL b;
00329 while (hiter.Step(&st, &b))
00330 _live_use->Enter(st, b);
00331 }
00332 }
00333
00334 void ARA_LOOP_INFO::Copy_Some_Values(ARA_LOOP_INFO *p)
00335 {
00336 _peel_value = p->_peel_value;
00337 _is_good = p->_is_good;
00338 _dep_dist = 0;
00339 _parent = p;
00340 _loop = p->_loop;
00341 _live_use = p->_live_use;
00342 _info = p->_info;
00343 _do_stack = p->_do_stack;
00344 _invariant_symbols = p->_invariant_symbols;
00345 _processed = p->_processed;
00346 _kernels = p->_kernels;
00347 _invariant = p->_invariant;
00348 _has_last_value_array = p->_has_last_value_array;
00349 _has_bad_region = p->_has_bad_region;
00350 _inner_loop_is_suggested_parallel = p->_inner_loop_is_suggested_parallel;
00351 _info = p->_info;
00352 _do_stack = p->_do_stack;
00353 }
00354
00355 ARA_LOOP_INFO::~ARA_LOOP_INFO()
00356 {
00357 if (_live_use)
00358 CXX_DELETE(_live_use, &ARA_memory_pool);
00359 }
00360
00361 KERNEL_IMAGE::KERNEL_IMAGE(KERNEL_IMAGE* k)
00362 {
00363 INT i;
00364 _kernel = CXX_NEW(ACCESS_ARRAY(k->_kernel, &ARA_memory_pool),
00365 &ARA_memory_pool);
00366 _region = CXX_NEW(REGION(k->_region), &ARA_memory_pool);
00367 _depth = k->_depth;
00368 _projected_level = k->_projected_level;
00369 _decoupled = k->_decoupled;
00370 _is_independent = CXX_NEW_ARRAY(BOOL, _depth, &ARA_memory_pool);
00371 for (i = 0; i < _depth; i++)
00372 _is_independent[i] = k->_is_independent[i];
00373 _changed = CXX_NEW_ARRAY(BOOL, _kernel->Num_Vec(), &ARA_memory_pool);
00374 for (i = 0; i < _depth; i++)
00375 _changed[i] = k->_changed[i];
00376 }
00377
00378 KERNEL_IMAGE::KERNEL_IMAGE(const ACCESS_ARRAY * a, ARA_LOOP_INFO *ara_info)
00379 {
00380
00381 _kernel = (ACCESS_ARRAY *) a;
00382 _region = NULL;
00383 _depth = ara_info->Depth()+1;
00384 _projected_level= _depth+1;
00385 _decoupled = TRUE;
00386
00387 _is_independent = CXX_NEW_ARRAY(BOOL, _depth, &ARA_memory_pool);
00388
00389 INT i;
00390 for (i=0; i<_depth; ++i)
00391 _is_independent[i]=TRUE;
00392
00393 for (i=0; i<a->Num_Vec(); ++i)
00394 for (INT j=0; j<_depth; ++j)
00395 if (a->Dim(i)->Loop_Coeff(j)!=0) _is_independent[j]=FALSE;
00396
00397 }
00398
00399 KERNEL_IMAGE::KERNEL_IMAGE(const ACCESS_ARRAY * a)
00400 {
00401
00402 _kernel = (ACCESS_ARRAY *) a;
00403 _region = NULL;
00404 if (a->Num_Vec() >= 1)
00405 _depth = a->Dim(0)->Nest_Depth();
00406 else
00407 _depth = -1;
00408 _projected_level= _depth+1;
00409 _decoupled = TRUE;
00410 _is_independent = CXX_NEW_ARRAY(BOOL, _depth, &ARA_memory_pool);
00411 INT i;
00412 for (i=0; i<_depth; ++i)
00413 _is_independent[i]=TRUE;
00414
00415 for (i=0; i<a->Num_Vec(); ++i)
00416 for (INT j=0; j<_depth; ++j)
00417 if (a->Dim(i)->Loop_Coeff(j)!=0) _is_independent[j]=FALSE;
00418
00419 }
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435 BOOL
00436 Is_Same_Array(const SYMBOL &a, INT32 offset_a, const SYMBOL &b, INT32 offset_b)
00437 {
00438 return ((a.St()==b.St()) && (a.WN_Offset()==b.WN_Offset()) &&
00439 (offset_a == offset_b));
00440 }
00441
00442 BOOL ARA_REF::Has_Formal_Parameter()
00443 {
00444 return _image.Has_Formal_Parameter();
00445 }
00446
00447 void
00448 ARA_REF::Set_Whole_Array(BOOL set_invariant)
00449 {
00450 ST* st = _array->St();
00451
00452 TY_IDX ty = ST_type(st);
00453
00454 if ((ST_sclass(st) == SCLASS_FORMAL) && (TY_kind(ty) == KIND_POINTER) ||
00455 (ST_sclass(st) == SCLASS_PSTATIC || ST_sclass(st) == SCLASS_AUTO ||
00456 (ST_base(st) != st && ST_sclass(ST_base(st)) == SCLASS_AUTO)) &&
00457 (TY_kind(ty) == KIND_POINTER))
00458 ty = TY_pointed(ty);
00459
00460 if (TY_kind(ty) == KIND_ARRAY) {
00461 INT ndims = TY_AR_ndims(ty);
00462 if (ndims == 0) return;
00463 INT i;
00464 for (i = 0; i < ndims; ++i) {
00465 if (!TY_AR_const_lbnd(ty, i))
00466 return;
00467 }
00468
00469 REGION *found = NULL;
00470 REGION_ITER iter(&_image);
00471 for (REGION* cur = iter.First(); !iter.Is_Empty(); cur = iter.Next()) {
00472 if (cur->_dim == ndims && cur->_type == ARA_NORMAL) {
00473 for (i = 0; i < ndims; ++i) {
00474 if (cur->_axle[i].up == NULL) {
00475 break;
00476 } else {
00477 INT64 lb = TY_AR_lbnd_val(ty,i);
00478 INT64 ub = TY_AR_ubnd_val(ty,i);
00479 if (PU_src_lang(Get_Current_PU()) == PU_F77_LANG ||
00480 PU_src_lang(Get_Current_PU()) == PU_F90_LANG) {
00481 lb = lb - 1;
00482 ub = ub - 1;
00483 }
00484 INT64 lb1 = cur->_axle[i].lo->Access_Vector()->Const_Offset;
00485 INT64 ub1 = cur->_axle[i].up->Access_Vector()->Const_Offset;
00486
00487 if (! (cur->_axle[i].step == 1 &&
00488 cur->_axle[i].lo->Coeff() == NULL &&
00489 cur->_axle[i].lo->Access_Vector()->Is_Const() &&
00490 lb1 == lb &&
00491 cur->_axle[i].up->Coeff() == NULL &&
00492 cur->_axle[i].up->Access_Vector()->Is_Const() &&
00493 ub1 == ub ) )
00494 break;
00495 }
00496 }
00497 if (i==ndims) {
00498 found = cur;
00499 found->_type = ARA_TOP;
00500 break;
00501 }
00502 }
00503 }
00504
00505 if (found) {
00506 if (set_invariant) Set_Donot_Care_Invariant();
00507 REGION *prev = NULL;
00508 REGION *cur = iter.First();
00509 while (! iter.Is_Empty() ) {
00510 if (cur != found) {
00511 for (i = 0; i < cur->_wn_list.Elements(); ++i)
00512 found->_wn_list.Push(cur->_wn_list.Bottom_nth(i));
00513 CXX_DELETE(_image.Remove(prev,cur), &ARA_memory_pool);
00514 }
00515 prev = cur;
00516 cur = iter.Next();
00517 }
00518 }
00519
00520 }
00521 }
00522
00523
00524
00525
00526
00527
00528 void
00529 ARA_REF::Add_Ref(ARA_REF *a, const ARA_LOOP_INFO &ali)
00530 {
00531
00532 Is_True(Is_Same_Array(*_array,_offset,*a->_array,a->_offset),
00533 ("ARA_REF::Add_Ref: Try to merge different arrays"));
00534
00535 while (!a->_image.Is_Empty()) {
00536 REGION * a_cur = a->_image.Remove_Headnode();
00537 _image.Add_Region(a_cur, ali);
00538 }
00539
00540 CXX_DELETE(a,&ARA_memory_pool);
00541
00542 }
00543
00544 void
00545 ARA_REF::Print(FILE *fp) const
00546 {
00547 if (_array) {
00548 _array->Print(fp);
00549 if (_has_bad_alias) fprintf(fp,"Has bad alias\n");
00550 _image.Print(fp);
00551 }
00552 }
00553
00554 void
00555 ARA_REF::WB_Print(FILE *fp) const
00556 {
00557 char bf[MAX_TLOG_CHARS];
00558 WB_Print(bf, 0);
00559 fprintf(fp, "%s", bf);
00560 }
00561
00562 INT
00563 ARA_REF::WB_Print(char* bf, INT ccount) const
00564 {
00565 INT new_ccount = ccount;
00566 if (_array) {
00567 new_ccount = _array->Print(bf, new_ccount);
00568 if (_has_bad_alias)
00569 new_ccount = snprintfs(bf, new_ccount, MAX_TLOG_CHARS,
00570 "(Has bad alias)");
00571 new_ccount = _image.WB_Print(bf, new_ccount);
00572 }
00573 return new_ccount;
00574 }
00575
00576 void
00577 ARA_REF::Print_Analysis_Info(FILE *fp, INT indent, DOLOOP_STACK &do_stack)
00578 {
00579
00580 if (_array) {
00581 fprintf(fp,"%s (\n", _array->Name());
00582 _image.Print_Analysis_Info(fp, indent+3, do_stack);
00583 print_indent(fp, indent);
00584 fprintf(fp,")\n");
00585 }
00586
00587 }
00588
00589 void
00590 ARA_LOOP_INFO::Print(FILE *fp, BOOL terse) const
00591 {
00592 if (!terse || _def.Elements() > 0 || _scalar_def.Elements() > 0) {
00593 fprintf(fp,"DEF: \n");
00594 for (INT i = 0; i < _def.Elements(); ++i) {
00595 _def.Bottom_nth(i)->Print(fp);
00596 }
00597 }
00598 if (!terse || _scalar_def.Elements() > 0) {
00599 for (INT i = 0; i < _scalar_def.Elements(); ++i) {
00600 SCALAR_STACK & stk = (SCALAR_STACK &) _scalar_def;
00601 stk.Bottom_nth(i)->_scalar.Print(fp);
00602 fprintf(fp,"\n");
00603 }
00604 }
00605 if (!terse || _may_def.Elements() > 0 || _scalar_may_def.Elements() > 0) {
00606 fprintf(fp,"May DEF: \n");
00607 for (INT i = 0; i < _may_def.Elements(); ++i) {
00608 _may_def.Bottom_nth(i)->Print(fp);
00609 }
00610 }
00611 if (!terse || _scalar_may_def.Elements() > 0) {
00612 for (INT i = 0; i < _scalar_may_def.Elements(); ++i) {
00613 SCALAR_STACK & stk = (SCALAR_STACK &) _scalar_may_def;
00614 stk.Bottom_nth(i)->_scalar.Print(fp);
00615 fprintf(fp,"\n");
00616 }
00617 }
00618 if (!terse || _use.Elements() > 0 || _scalar_use.Elements() > 0) {
00619 fprintf(fp,"USE: \n");
00620 for (INT i = 0; i < _use.Elements(); ++i) {
00621 _use.Bottom_nth(i)->Print(fp);
00622 }
00623 }
00624 if (!terse || _scalar_use.Elements() > 0) {
00625 for (INT i = 0; i < _scalar_use.Elements(); ++i) {
00626 SCALAR_STACK & stk = (SCALAR_STACK &) _scalar_use;
00627 stk.Bottom_nth(i)->_scalar.Print(fp);
00628 fprintf(fp,"\n");
00629 }
00630 }
00631 if (!terse || _pri.Elements() > 0 || _scalar_pri.Elements() > 0) {
00632 fprintf(fp,"PRI: \n");
00633 for (INT i = 0; i < _pri.Elements(); ++i) {
00634 _pri.Bottom_nth(i)->Print(fp);
00635 if (_pri.Bottom_nth(i)->Is_Loop_Invariant())
00636 fprintf(fp, "Loop Invariant\n");
00637 if (_pri.Bottom_nth(i)->Need_Last_Value())
00638 fprintf(fp,"Need Last Value\n");
00639 if (_pri.Bottom_nth(i)->Is_Unknown_Size())
00640 fprintf(fp,"Unknown Size\n");
00641 }
00642 }
00643 if (!terse || _scalar_pri.Elements() > 0) {
00644 for (INT i = 0; i < _scalar_pri.Elements(); ++i) {
00645 SCALAR_STACK & stk = (SCALAR_STACK &) _scalar_pri;
00646 stk.Bottom_nth(i)->_scalar.Print(fp);
00647 if (_scalar_last_value.Elements()>i && _scalar_last_value.Bottom_nth(i))
00648 fprintf(fp,"Need Last Value\n");
00649 fprintf(fp,"\n");
00650 }
00651 }
00652 }
00653
00654 void
00655 ARA_LOOP_INFO::WB_Print(FILE *fp, BOOL terse) const
00656 {
00657 if (_has_last_value_array)
00658 fprintf(fp, "HAS LAST VALUE ARRAY\n");
00659 if (!terse || _def.Elements() > 0 || _scalar_def.Elements() > 0) {
00660 fprintf(fp,"MUST DEFS: \n");
00661 for (INT i = 0; i < _def.Elements(); ++i) {
00662 fprintf(fp, " ");
00663 _def.Bottom_nth(i)->WB_Print(fp);
00664 }
00665 }
00666 if (!terse || _scalar_def.Elements() > 0) {
00667 fprintf(fp, " Scalars: ");
00668 for (INT i = 0; i < _scalar_def.Elements(); ++i) {
00669 SCALAR_STACK & stk = (SCALAR_STACK &) _scalar_def;
00670 stk.Bottom_nth(i)->_scalar.Print(fp);
00671 if (!stk.Bottom_nth(i)->_scalar.Is_Formal()
00672 && ST_class(stk.Bottom_nth(i)->_scalar.St()) == CLASS_PREG)
00673 fprintf(fp, "<PREG>");
00674 if (i < _scalar_def.Elements() - 1)
00675 fprintf(fp, ",");
00676 }
00677 fprintf(fp,"\n");
00678 }
00679 if (!terse || _may_def.Elements() > 0 || _scalar_may_def.Elements() > 0) {
00680 fprintf(fp,"MAY DEFS: \n");
00681 for (INT i = 0; i < _may_def.Elements(); ++i) {
00682 fprintf(fp, " ");
00683 _may_def.Bottom_nth(i)->WB_Print(fp);
00684 }
00685 }
00686 if (!terse || _scalar_may_def.Elements() > 0) {
00687 fprintf(fp, " Scalars: ");
00688 for (INT i = 0; i < _scalar_may_def.Elements(); ++i) {
00689 SCALAR_STACK & stk = (SCALAR_STACK &) _scalar_may_def;
00690 stk.Bottom_nth(i)->_scalar.Print(fp);
00691 if (!stk.Bottom_nth(i)->_scalar.Is_Formal()
00692 && ST_class(stk.Bottom_nth(i)->_scalar.St()) == CLASS_PREG)
00693 fprintf(fp, "<PREG>");
00694 if (i < _scalar_may_def.Elements() - 1)
00695 fprintf(fp, ",");
00696 }
00697 fprintf(fp,"\n");
00698 }
00699 if (!terse || _use.Elements() > 0 || _scalar_use.Elements() > 0) {
00700 fprintf(fp,"USES: \n");
00701 for (INT i = 0; i < _use.Elements(); ++i) {
00702 fprintf(fp, " ");
00703 _use.Bottom_nth(i)->WB_Print(fp);
00704 }
00705 }
00706 if (!terse || _scalar_use.Elements() > 0) {
00707 fprintf(fp, " Scalars: ");
00708 for (INT i = 0; i < _scalar_use.Elements(); ++i) {
00709 SCALAR_STACK & stk = (SCALAR_STACK &) _scalar_use;
00710 stk.Bottom_nth(i)->_scalar.Print(fp);
00711 if (!stk.Bottom_nth(i)->_scalar.Is_Formal()
00712 && ST_class(stk.Bottom_nth(i)->_scalar.St()) == CLASS_PREG)
00713 fprintf(fp, "<PREG>");
00714 if (i < _scalar_use.Elements() - 1)
00715 fprintf(fp, ",");
00716 }
00717 fprintf(fp,"\n");
00718 }
00719 if (!terse || _pri.Elements() > 0 || _scalar_pri.Elements() > 0) {
00720 fprintf(fp,"PRIVATES: \n");
00721 for (INT i = 0; i < _pri.Elements(); ++i) {
00722 fprintf(fp, " ");
00723 _pri.Bottom_nth(i)->WB_Print(fp);
00724 if (_pri.Bottom_nth(i)->Is_Loop_Invariant())
00725 fprintf(fp, " Loop Invariant\n");
00726 if (_pri.Bottom_nth(i)->Need_Last_Value())
00727 fprintf(fp," Need Last Value\n");
00728 }
00729 }
00730 if (!terse || _scalar_pri.Elements() > 0) {
00731 fprintf(fp, " Scalars: ");
00732 for (INT i = 0; i < _scalar_pri.Elements(); ++i) {
00733 SCALAR_STACK & stk = (SCALAR_STACK &) _scalar_pri;
00734 stk.Bottom_nth(i)->_scalar.Print(fp);
00735 if (_scalar_last_value.Elements()>i && _scalar_last_value.Bottom_nth(i))
00736 fprintf(fp," (Need Last Value)");
00737 if (!stk.Bottom_nth(i)->_scalar.Is_Formal()
00738 && ST_class(stk.Bottom_nth(i)->_scalar.St()) == CLASS_PREG)
00739 fprintf(fp, "<PREG>");
00740 if (i < _scalar_pri.Elements() - 1)
00741 fprintf(fp, ",");
00742 }
00743 fprintf(fp,"\n");
00744 }
00745 }
00746
00747 void ARA_LOOP_INFO::CI_Print(FILE* fp)
00748 {
00749 INT i;
00750 for (i = 0; i < _may_def.Elements(); i++) {
00751 fprintf(fp, " ");
00752 fprintf(fp, "MOD Array ");
00753 _may_def.Bottom_nth(i)->WB_Print(fp);
00754 }
00755 for (i = 0; i < _scalar_may_def.Elements(); i++) {
00756 fprintf(fp, " ");
00757 fprintf(fp, "MOD Scalar ");
00758 SCALAR_STACK& stk = (SCALAR_STACK&) _scalar_may_def;
00759 TYPE_ID type_id = stk.Bottom_nth(i)->_scalar.Type;
00760 fprintf(fp, "%s ", MTYPE_name(type_id));
00761 stk.Bottom_nth(i)->_scalar.Print(fp);
00762 fprintf(fp, "\n");
00763 }
00764 for (i = 0; i < _use.Elements(); i++) {
00765 fprintf(fp, " ");
00766 fprintf(fp, "REF Array ");
00767 _use.Bottom_nth(i)->WB_Print(fp);
00768 }
00769 for (i = 0; i < _scalar_use.Elements(); i++) {
00770 fprintf(fp, " ");
00771 fprintf(fp, "REF Scalar ");
00772 SCALAR_STACK& stk = (SCALAR_STACK&) _scalar_use;
00773 TYPE_ID type_id = stk.Bottom_nth(i)->_scalar.Type;
00774 fprintf(fp, "%s ", MTYPE_name(type_id));
00775 stk.Bottom_nth(i)->_scalar.Print(fp);
00776 fprintf(fp, "\n");
00777 }
00778 }
00779
00780 void ARA_LOOP_INFO::Tlog_CI_Print()
00781 {
00782 INT i;
00783 char bf[MAX_TLOG_CHARS];
00784 for (i = 0; i < _may_def.Elements(); i++) {
00785 INT new_ccount = 0;
00786 new_ccount = snprintfs(bf, new_ccount, MAX_TLOG_CHARS, "MOD Array ");
00787 new_ccount = _may_def.Bottom_nth(i)->WB_Print(bf, new_ccount);
00788 Generate_Tlog("LNO", "Call_Info", (SRCPOS) 0, "", "", "", bf);
00789 }
00790 for (i = 0; i < _scalar_may_def.Elements(); i++) {
00791 INT new_ccount = 0;
00792 new_ccount = snprintfs(bf, new_ccount, MAX_TLOG_CHARS, "MOD Scalar ");
00793 SCALAR_STACK& stk = (SCALAR_STACK&) _scalar_may_def;
00794 new_ccount = stk.Bottom_nth(i)->_scalar.Print(bf, new_ccount);
00795 Generate_Tlog("LNO", "Call_Info", (SRCPOS) 0, "", "", "", bf);
00796 }
00797 for (i = 0; i < _use.Elements(); i++) {
00798 INT new_ccount = 0;
00799 new_ccount = snprintfs(bf, new_ccount, MAX_TLOG_CHARS, "REF Array ");
00800 new_ccount = _use.Bottom_nth(i)->WB_Print(bf, new_ccount);
00801 Generate_Tlog("LNO", "Call_Info", (SRCPOS) 0, "", "", "", bf);
00802 }
00803 for (i = 0; i < _scalar_use.Elements(); i++) {
00804 INT new_ccount = 0;
00805 new_ccount = snprintfs(bf, new_ccount, MAX_TLOG_CHARS, "REF Scalar ");
00806 SCALAR_STACK& stk = (SCALAR_STACK&) _scalar_use;
00807 new_ccount = stk.Bottom_nth(i)->_scalar.Print(bf, new_ccount);
00808 Generate_Tlog("LNO", "Call_Info", (SRCPOS) 0, "", "", "", bf);
00809 }
00810 }
00811
00812
00813
00814
00815
00816
00817
00818
00819 static INT Invariant_Loop_Count(WN* wn_outer)
00820 {
00821 INT outer_depth = Do_Loop_Depth(wn_outer);
00822 INT nloops = SNL_Loop_Count(wn_outer);
00823 INT* permutation = CXX_NEW_ARRAY(INT, nloops, &LNO_local_pool);
00824 INT i;
00825 for (i = 0; i < nloops; i++)
00826 permutation[i] = i;
00827 WN* wn_inner = SNL_Get_Inner_Snl_Loop(wn_outer, nloops);
00828 DOLOOP_STACK stack(&LNO_local_pool);
00829 Build_Doloop_Stack(wn_inner, &stack);
00830 INT inner_depth = Do_Loop_Depth(wn_inner);
00831 for (i = 2; i <= nloops; i++) {
00832 if (!General_Permutation(wn_outer, permutation, i))
00833 return i - 1;
00834 for (INT j = 0; j < i - 1; j++)
00835 if (!SNL_Is_Invariant(&stack, outer_depth + j, outer_depth + i - 1))
00836 return i - 1;
00837 }
00838 return nloops;
00839 }
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849 static double Single_Iteration_Cost(WN* wn_loop,
00850 BOOL include_calls)
00851 {
00852 double mach_cost_per_iter = 0, est_num_iters;
00853 INT nloops = SNL_Loop_Count(wn_loop);
00854 double machine_cycles = SNL_Machine_Cost(wn_loop, nloops, 0, NULL,
00855 &mach_cost_per_iter, include_calls);
00856 INT *ident_perm = CXX_NEW_ARRAY(INT, nloops, &LNO_local_pool);
00857 for (INT i = 0; i < nloops; i++)
00858 ident_perm[i] = i;
00859 double cache_cycles = SNL_Cache_Cost(wn_loop, ident_perm, nloops,
00860 Do_Loop_Depth(wn_loop), -1, NULL, &est_num_iters);
00861 CXX_DELETE_ARRAY(ident_perm, &LNO_local_pool);
00862 return Compute_Work_Estimate(mach_cost_per_iter, cache_cycles/est_num_iters);
00863 }
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874 float ARA_LOOP_INFO::Const_Work_Estimate(WN* wn_loop,
00875 BOOL* minimum_only)
00876 {
00877 INT nloops = SNL_Loop_Count(wn_loop);
00878 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn_loop);
00879 float const_work_estimate = (INT) (dli->Has_Calls
00880 ? Single_Iteration_Cost(wn_loop, FALSE) : dli->Work_Estimate);
00881 WN* wn_inner = SNL_Get_Inner_Snl_Loop(wn_loop, nloops);
00882 INT inv_nloops = Invariant_Loop_Count(wn_loop);
00883 INT var_nloops = nloops - inv_nloops;
00884 INT count = 0;
00885 BOOL min_only = FALSE;
00886 if (dli->Has_Calls)
00887 min_only = TRUE;
00888 for (WN* wn = wn_inner; wn != NULL; wn = LWN_Get_Parent(wn)) {
00889 if (WN_opcode(wn) == OPC_DO_LOOP) {
00890 if (count++ < var_nloops
00891 || !Upper_Bound_Standardize(WN_end(wn), TRUE)) {
00892 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn);
00893 const_work_estimate *= dli->Est_Num_Iterations;
00894 } else {
00895 WN* wn_trip_count = Trip_Count(wn);
00896 if (WN_operator(wn_trip_count) != OPR_INTCONST) {
00897 #ifdef KEY
00898 if (Cur_PU_Feedback && LNO_Apo_use_feedback &&
00899 Cur_PU_Feedback->Get_index_loop(wn) != 0) {
00900 FB_Info_Loop loop_freq = Cur_PU_Feedback->Query_loop(wn);
00901 const_work_estimate *= loop_freq.freq_iterate.Value();
00902 if (loop_freq.freq_positive.Value() > 0.0)
00903 const_work_estimate /= loop_freq.freq_positive.Value();
00904 }
00905 else
00906 #endif
00907 min_only = TRUE;
00908 } else {
00909 const_work_estimate *= WN_const_val(wn_trip_count);
00910 }
00911 LWN_Delete_Tree(wn_trip_count);
00912 }
00913 }
00914 if (wn == wn_loop)
00915 break;
00916 }
00917 *minimum_only = min_only;
00918 return const_work_estimate;
00919 }
00920
00921
00922
00923
00924
00925
00926
00927
00928 BOOL ARA_LOOP_INFO::Not_Enough_Parallel_Work()
00929 {
00930 if (LNO_Run_AP == 2)
00931 return FALSE;
00932 DO_LOOP_INFO* dli = Get_Do_Loop_Info(_loop);
00933 if (dli->Has_Calls && dli->Has_Unsummarized_Call_Cost)
00934 return FALSE;
00935 BOOL minimum_only = FALSE;
00936 for (WN* wn = _loop; wn != NULL; wn = LWN_Get_Parent(wn)) {
00937 if (WN_opcode(wn) == OPC_DO_LOOP) {
00938 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn);
00939 if (dli->Not_Enough_Parallel_Work)
00940 return TRUE;
00941 }
00942 }
00943 float const_work_estimate = Const_Work_Estimate(_loop, &minimum_only);
00944 if (const_work_estimate == -1 || minimum_only)
00945 return FALSE;
00946 float tc = Tc_Parallel_Cost();
00947 float tp = Tp_Parallel_Cost();
00948 float W = const_work_estimate;
00949 float p_min = (W - tc) / (2 * tp);
00950 float f_min = tp * p_min * p_min + (tc - W) * p_min + W;
00951 if (f_min >= 0)
00952 return TRUE;
00953 float p_left = ((W - tc) - sqrt((tc - W) * (tc - W) - 4 * tp * W))/(2 * tp);
00954 float p_right = ((W - tc) + sqrt((tc - W) * (tc - W) - 4 * tp * W))/(2 * tp);
00955 if (p_left > (float) MAX_PROCS || p_right < (float) 1)
00956 return TRUE;
00957 return FALSE;
00958 }
00959
00960
00961
00962
00963
00964
00965
00966
00967 BOOL ARA_LOOP_INFO::Always_Enough_Parallel_Work(BOOL* has_left_right,
00968 INT* left,
00969 INT* right)
00970 {
00971 *has_left_right = FALSE;
00972 if (LNO_Run_AP == 2)
00973 return TRUE;
00974 BOOL minimum_only = FALSE;
00975 DO_LOOP_INFO* dli = Get_Do_Loop_Info(_loop);
00976 if (dli->Is_Concurrent_Call && dli->Has_Unsummarized_Call_Cost)
00977 return TRUE;
00978 if (dli->Has_Calls && dli->Has_Unsummarized_Call_Cost)
00979 return TRUE;
00980 float const_work_estimate = Const_Work_Estimate(_loop, &minimum_only);
00981 if (const_work_estimate == -1 || minimum_only)
00982 return FALSE;
00983 float W = const_work_estimate;
00984 float tc = Tc_Parallel_Cost();
00985 float tp = Tp_Parallel_Cost();
00986 float p_min = (W - tc) / (2 * tp);
00987 float f_min = tp * p_min * p_min + (tc - W) * p_min + W;
00988 if (f_min >= 0.0)
00989 return FALSE;
00990 *has_left_right = TRUE;
00991 float p_left = ((W - tc) - sqrt((tc - W) * (tc - W) - 4 * tp * W))/(2 * tp);
00992 float p_right = ((W - tc) + sqrt((tc - W) * (tc - W) - 4 * tp * W))/(2 * tp);
00993 *left = (INT) ceil(p_left);
00994 *right = (INT) p_right;
00995 return (p_left <= 1 && p_right >= MAX_PROCS);
00996 }
00997
00998 void
00999 ARA_LOOP_INFO::Print_Analysis_Info()
01000 {
01001 INT i;
01002 for (i = 0; i < _children.Elements(); ++i)
01003 _children.Bottom_nth(i)->Print_Analysis_Info();
01004
01005 INT indent = 0;
01006 fprintf(LNO_Analysis,"(LNO_ARA_Info\n");
01007 indent += 3;
01008 print_indent(LNO_Analysis,indent);
01009
01010 if (Is_Parallel())
01011 fprintf(LNO_Analysis,"(%s %d %s)\n",
01012 Cur_PU_Name, Srcpos_To_Line(WN_Get_Linenum(_loop)), "PARALLEL");
01013 else {
01014 fprintf(LNO_Analysis,"(%s %d %s)\n",
01015 Cur_PU_Name, Srcpos_To_Line(WN_Get_Linenum(_loop)), "SEQUENTIAL");
01016 for (i = 0; i < _dep_vars.Elements(); ++i) {
01017 print_indent(LNO_Analysis,indent);
01018 fprintf(LNO_Analysis,"(%s %s)\n",
01019 "DEPENDENCE_VAR",_dep_vars.Bottom_nth(i).Name());
01020 }
01021 }
01022
01023 for (i = 0; i < _pri.Elements(); ++i) {
01024 print_indent(LNO_Analysis, indent);
01025 if (_pri.Bottom_nth(i)->Need_Last_Value())
01026 fprintf(LNO_Analysis,"(LAST_LOCAL_ARRAY ");
01027 else
01028 fprintf(LNO_Analysis,"(LOCAL_ARRAY ");
01029 _pri.Bottom_nth(i)->Print_Analysis_Info(LNO_Analysis,indent+3,Do_Stack());
01030 print_indent(LNO_Analysis, indent);
01031 fprintf(LNO_Analysis,")\n");
01032 }
01033
01034 for (i = 0; i < _scalar_pri.Elements(); ++i) {
01035 print_indent(LNO_Analysis, indent);
01036 if (_scalar_last_value.Elements()>i && _scalar_last_value.Bottom_nth(i))
01037 fprintf(LNO_Analysis,"(LAST_LOCAL_SCALAR ");
01038 else
01039 fprintf(LNO_Analysis,"(LOCAL_SCALAR ");
01040 SCALAR_STACK & stk = (SCALAR_STACK &) _scalar_pri;
01041 stk.Bottom_nth(i)->_scalar.Print(LNO_Analysis);
01042 fprintf(LNO_Analysis,")\n");
01043 }
01044
01045 for (i = 0; i < _def.Elements(); ++i) {
01046 print_indent(LNO_Analysis, indent);
01047 fprintf(LNO_Analysis,"(KILL_ARRAY ");
01048 _def.Bottom_nth(i)->Print_Analysis_Info(LNO_Analysis,indent+3,Do_Stack());
01049 print_indent(LNO_Analysis, indent);
01050 fprintf(LNO_Analysis,")\n");
01051 }
01052
01053 for (i = 0; i < _scalar_def.Elements(); ++i) {
01054 print_indent(LNO_Analysis, indent);
01055 fprintf(LNO_Analysis,"(KILL_SCALAR ");
01056 SCALAR_STACK & stk = (SCALAR_STACK &) _scalar_def;
01057 stk.Bottom_nth(i)->_scalar.Print(LNO_Analysis);
01058 fprintf(LNO_Analysis,")\n");
01059 }
01060
01061 for (i = 0; i < _may_def.Elements(); ++i) {
01062 print_indent(LNO_Analysis, indent);
01063 fprintf(LNO_Analysis,"(DEF_ARRAY ");
01064 _may_def.Bottom_nth(i)->Print_Analysis_Info(LNO_Analysis,
01065 indent+3,Do_Stack());
01066 print_indent(LNO_Analysis, indent);
01067 fprintf(LNO_Analysis,")\n");
01068 }
01069 for (i = 0; i < _scalar_may_def.Elements(); ++i) {
01070 print_indent(LNO_Analysis, indent);
01071 fprintf(LNO_Analysis,"(DEF_SCALAR ");
01072 SCALAR_STACK & stk = (SCALAR_STACK &) _scalar_may_def;
01073 stk.Bottom_nth(i)->_scalar.Print(LNO_Analysis);
01074 fprintf(LNO_Analysis,")\n");
01075 }
01076
01077 for (i = 0; i < _use.Elements(); ++i) {
01078 print_indent(LNO_Analysis, indent);
01079 fprintf(LNO_Analysis,"(EXPOSED_ARRAY_USE ");
01080 _use.Bottom_nth(i)->Print_Analysis_Info(LNO_Analysis,indent+3,Do_Stack());
01081 print_indent(LNO_Analysis, indent);
01082 fprintf(LNO_Analysis,")\n");
01083 }
01084
01085 for (i = 0; i < _scalar_use.Elements(); ++i) {
01086 print_indent(LNO_Analysis, indent);
01087 fprintf(LNO_Analysis,"(EXPOSED_SCALAR_USE ");
01088 SCALAR_STACK & stk = (SCALAR_STACK &) _scalar_use;
01089 stk.Bottom_nth(i)->_scalar.Print(LNO_Analysis);
01090 fprintf(LNO_Analysis,")\n");
01091 }
01092
01093 fprintf(LNO_Analysis,")\n");
01094 }
01095
01096 static
01097 BOOL Is_Unknown_Size_Array(const SYMBOL* array)
01098 {
01099 ST* st = array->St();
01100 TY_IDX ty = ST_type(st);
01101
01102 if (ST_class(st) == CLASS_PREG)
01103 return TRUE;
01104
01105 if (TY_kind(ty) == KIND_POINTER) {
01106
01107 ty = TY_pointed(ty);
01108 if (ST_sclass(st) != SCLASS_FORMAL && TY_size(ty) != 0)
01109 return TRUE;
01110 }
01111
01112 if (TY_kind(ty) != KIND_ARRAY)
01113 return TRUE;
01114
01115 INT ndims = TY_AR_ndims(ty);
01116 for (INT i = 0; i < ndims; i++) {
01117 if (!TY_AR_const_lbnd(ty, i))
01118 return TRUE;
01119 if (!TY_AR_const_ubnd(ty,i))
01120 return TRUE;
01121 if (!TY_AR_const_stride(ty,i))
01122 return TRUE;
01123 INT diff = TY_AR_ubnd_val(ty,i) - TY_AR_lbnd_val(ty,i) + 1;
01124 if (diff <= 1)
01125 return TRUE;
01126 }
01127 return FALSE;
01128 }
01129
01130 ARA_REF::ARA_REF(WN *array_wn, INT32 offset, ARA_LOOP_INFO *ali)
01131 {
01132 Is_True(WN_operator(array_wn) == OPR_ARRAY,
01133 ("ARA_REF::ARA_REF called on a non-array"));
01134
01135 WN *base = WN_array_base(array_wn);
01136 while (WN_operator(base) == OPR_ARRAY)
01137 base = WN_array_base(base);
01138
01139 _donot_care_invariant = FALSE;
01140 _is_too_messy = FALSE;
01141
01142 if (WN_operator(base) != OPR_LDID &&
01143 WN_operator(base) != OPR_LDA) {
01144 ali->Set_Bad_Region();
01145 _array = NULL;
01146 _offset = 0;
01147 _has_bad_alias = TRUE;
01148 _is_loop_invariant = FALSE;
01149 _is_too_messy = TRUE;
01150 return;
01151 }
01152
01153 _array = CXX_NEW(SYMBOL(base),&ARA_memory_pool);
01154 _is_unknown_size = Is_Unknown_Size_Array(_array);
01155 _offset = offset;
01156 REGION *new_region = CXX_NEW(REGION(array_wn, ali), &ARA_memory_pool);
01157 _image.Add_Region(new_region, *ali);
01158 _has_bad_alias = FALSE;
01159 _need_last_value = TRUE;
01160 ACCESS_ARRAY *s_array = (ACCESS_ARRAY *) WN_MAP_Get(LNO_Info_Map, array_wn);
01161 if (s_array!=NULL)
01162 _is_loop_invariant = Loop_Invariant_Access(array_wn, ali->Loop()) &&
01163 ! new_region->Is_Too_Messy();
01164 if (Get_Trace(TP_LNOPT2,TT_LNO_ARA_DEBUG)) {
01165 fprintf(stdout,"ARA_REF::ARA_REF: the region is\n");
01166 _image.Print(stdout);
01167 }
01168 }
01169
01170 ARA_REF::ARA_REF(SYMBOL *array_sym, REGION* new_region, ARA_LOOP_INFO *ali,
01171 BOOL is_invariant)
01172 {
01173 _array = CXX_NEW(SYMBOL(array_sym),&ARA_memory_pool);
01174 _is_unknown_size = Is_Unknown_Size_Array(_array);
01175 _offset = array_sym->WN_Offset();
01176 _image.Add_Region(new_region, *ali);
01177 _has_bad_alias = FALSE;
01178 _need_last_value = TRUE;
01179 _is_loop_invariant = is_invariant && ! new_region->Is_Too_Messy();
01180 _is_too_messy = new_region->_type == ARA_TOO_MESSY;
01181 if (Get_Trace(TP_LNOPT2,TT_LNO_ARA_DEBUG)) {
01182 fprintf(stdout,"ARA_REF::ARA_REF: the region is\n");
01183 _image.Print(stdout);
01184 }
01185 }
01186
01187 void
01188 ARA_LOOP_INFO::Annotate_Invariant_Pri()
01189 {
01190
01191 for (INT i = 0; i < _pri.Elements(); ++i) {
01192 _pri.Bottom_nth(i)->Set_Loop_Invariant(_loop);
01193 }
01194
01195 }
01196
01197 void
01198 ARA_LOOP_INFO::Annotate_Invariant_Def()
01199 {
01200
01201 for (INT i = 0; i < _def.Elements(); ++i) {
01202 ARA_REF *cur_def = _def.Bottom_nth(i);
01203 cur_def->Set_Loop_Invariant(_loop);
01204 }
01205
01206 }
01207
01208 ARA_REF * Contains(ARA_REF_ST & ara_st, WN *array_wn)
01209 {
01210
01211 #if 0
01212 Is_True((WN_operator(wn) == OPR_ILOAD) ||
01213 (WN_operator(wn) == OPR_ISTORE),
01214 ("Contains: Bad WN passed in"));
01215 WN* array_wn = (WN_operator(source)== OPR_ILOAD) ?
01216 kid0(wn) : kid1(wn);
01217 #endif
01218 for (INT i = 0; i < ara_st.Elements(); ++i) {
01219 ARA_REF *cur = ara_st.Bottom_nth(i);
01220 if (OPCODE_has_sym(WN_opcode(WN_array_base(array_wn))))
01221 {
01222 if (WN_st(WN_array_base(array_wn)) == cur->Array().St())
01223 if (!cur->Has_Bad_Alias() && cur->Image().Contains(array_wn))
01224 return cur;
01225 }
01226 else
01227 return NULL;
01228 }
01229 return NULL;
01230 }
01231
01232 void
01233 Add_Helper(ARA_REF *ara_ref, ARA_REF_ST & ara_st, ARA_LOOP_INFO &ali)
01234 {
01235 for (INT i = 0; i < ara_st.Elements(); ++i) {
01236 ARA_REF *cur = ara_st.Bottom_nth(i);
01237 if (Is_Same_Array(cur->Array(),cur->Offset(),
01238 ara_ref->Array(),ara_ref->Offset())) {
01239 BOOL donot_care_invariant = ara_ref->Donot_Care_Invariant();
01240 cur->Add_Ref(ara_ref, ali);
01241 if (donot_care_invariant) cur->Set_Donot_Care_Invariant();
01242 cur->Set_Whole_Array();
01243 return;
01244 }
01245 }
01246
01247
01248 ara_st.Push(ara_ref);
01249 ara_ref->Set_Whole_Array();
01250 }
01251
01252 void
01253 ARA_LOOP_INFO::Add_Def(ARA_REF *ara_ref)
01254 {
01255 Add_Helper(ara_ref, _def, *this);
01256 }
01257
01258 void
01259 ARA_LOOP_INFO::Add_May_Def(ARA_REF *ara_ref)
01260 {
01261 Add_Helper(ara_ref, _may_def, *this);
01262 }
01263
01264 void
01265 ARA_LOOP_INFO::Add_Use(ARA_REF *ara_ref)
01266 {
01267 Add_Helper(ara_ref, _use, *this);
01268 }
01269
01270 void
01271 ARA_LOOP_INFO::Add_Pri(ARA_REF *ara_ref)
01272 {
01273 Add_Helper(ara_ref, _pri, *this);
01274 }
01275
01276 void
01277 ARA_LOOP_INFO::Remove_Array_Info()
01278 {
01279 _def.Clear();
01280 _use.Clear();
01281 _may_def.Clear();
01282 _pri.Clear();
01283 }
01284
01285 BOOL
01286 ARA_LOOP_INFO::Is_Covered(ARA_REF *ara_ref)
01287 {
01288
01289 for (INT i = 0; i<_def.Elements(); ++i) {
01290 ARA_REF *cur = _def.Bottom_nth(i);
01291 if (Is_Same_Array(cur->Array(), cur->Offset(),
01292 ara_ref->Array(), ara_ref->Offset())) {
01293 if (cur->Image().Is_Included(ara_ref->Image(), *this)) {
01294 if (cur->Donot_Care_Invariant()) {
01295 ara_ref->Set_Donot_Care_Invariant();
01296 }
01297 return TRUE;
01298 }
01299 else
01300 return FALSE;
01301 }
01302 }
01303
01304 return FALSE;
01305
01306 }
01307
01308 BOOL
01309 Is_Unconditional(WN *wn, WN* do_loop)
01310 {
01311
01312 DOLOOP_STACK doloop_stack(&ARA_memory_pool);
01313 for (WN *wn_temp = wn; wn_temp && wn_temp != do_loop;
01314 wn_temp = LWN_Get_Parent(wn_temp)) {
01315 if (WN_opcode(wn_temp) == OPC_DO_LOOP)
01316 doloop_stack.Push(wn_temp);
01317 else if (WN_opcode(wn_temp) == OPC_IF) {
01318 for (INT i = 0; i < doloop_stack.Elements(); ++i) {
01319 DO_LOOP_INFO *dli = Get_Do_Loop_Info(doloop_stack.Bottom_nth(i));
01320 if (dli && dli->Guard == wn_temp) return TRUE;
01321 }
01322 return FALSE;
01323 } else if (OPCODE_is_scf(WN_opcode(wn_temp)) && WN_opcode(wn_temp) != OPC_BLOCK)
01324 return FALSE;
01325 }
01326
01327 return TRUE;
01328
01329 }
01330
01331
01332
01333
01334 static BOOL Identical(ARA_REF* ara_ref_one,
01335 ARA_REF* ara_ref_two)
01336 {
01337 ST* st_array_one = ara_ref_one->Array().St();
01338 ST* st_array_two = ara_ref_two->Array().St();
01339 return st_array_one == st_array_two;
01340 }
01341
01342 static BOOL Identical(SCALAR_NODE* sn_one,
01343 SCALAR_NODE* sn_two)
01344 {
01345 FmtAssert(!sn_one->_scalar.Is_Formal(),
01346 ("Identical: expecting non-formal: sn_one"));
01347 FmtAssert(!sn_two->_scalar.Is_Formal(),
01348 ("Identical: expecting non-formal: sn_two"));
01349 ST* st_scalar_one = sn_one->_scalar.St();
01350 ST* st_scalar_two = sn_two->_scalar.St();
01351 if (st_scalar_one != st_scalar_two)
01352 return FALSE;
01353 INT64 st_offset_one = sn_one->_scalar.ST_Offset();
01354 INT64 st_offset_two = sn_two->_scalar.ST_Offset();
01355 if (st_offset_one != st_offset_two)
01356 return FALSE;
01357 INT st_size_one = MTYPE_RegisterSize(sn_one->_scalar.Type);
01358 INT st_size_two = MTYPE_RegisterSize(sn_two->_scalar.Type);
01359 if (st_size_one != st_size_two)
01360 return FALSE;
01361 return TRUE;
01362 }
01363
01364 static POINTS_TO* Points_To(ARA_REF* ara_ref)
01365 {
01366 return Points_To(ara_ref, &ARA_memory_pool);
01367 }
01368
01369 static POINTS_TO* Points_To(SCALAR_NODE* sn)
01370 {
01371 return Points_To(sn, &ARA_memory_pool);
01372 }
01373
01374 static BOOL Test_Alias_Ara_Ref_Array(ARA_REF* ara_ref,
01375 POINTS_TO* pt_ref,
01376 ARA_REF_ST* st_array)
01377 {
01378 for (INT j = 0; j < st_array->Elements(); j++) {
01379 ARA_REF* ara_ref_use = st_array->Bottom_nth(j);
01380 if (Identical(ara_ref, ara_ref_use))
01381 continue;
01382 POINTS_TO* pt_use = Points_To(ara_ref_use);
01383 if (Alias_Mgr->Aliased(pt_ref, pt_use)) {
01384 ara_ref->Set_Bad_Alias();
01385 return TRUE;
01386 }
01387 }
01388 return FALSE;
01389 }
01390
01391 static BOOL Test_Alias_Ara_Ref_Scalar(ARA_REF* ara_ref,
01392 POINTS_TO* pt_ref,
01393 SCALAR_STACK* st_scalar)
01394 {
01395 for (INT j = 0; j < st_scalar->Elements(); j++) {
01396 SCALAR_NODE* sn_use = st_scalar->Bottom_nth(j);
01397 POINTS_TO* pt_use = Points_To(sn_use);
01398 if (Alias_Mgr->Aliased(pt_ref, pt_use)) {
01399 ara_ref->Set_Bad_Alias();
01400 return TRUE;
01401 }
01402 }
01403 return FALSE;
01404 }
01405
01406 static BOOL Test_Alias_Scalar_Node_Array(POINTS_TO* pt_ref,
01407 ARA_REF_ST* st_array,
01408 STACK<BOOL>* bad_alias)
01409 {
01410 for (INT j = 0; j < st_array->Elements(); j++) {
01411 ARA_REF* ara_ref_use = st_array->Bottom_nth(j);
01412 POINTS_TO* pt_use = Points_To(ara_ref_use);
01413 if (Alias_Mgr->Aliased(pt_ref, pt_use)) {
01414 bad_alias->Push(TRUE);
01415 return TRUE;
01416 }
01417 }
01418 return FALSE;
01419 }
01420
01421 static BOOL Test_Alias_Scalar_Node_Scalar(SCALAR_NODE* sn_ref,
01422 POINTS_TO* pt_ref,
01423 SCALAR_STACK* st_scalar,
01424 STACK<BOOL>* bad_alias)
01425 {
01426 for (INT j = 0; j < st_scalar->Elements(); j++) {
01427 SCALAR_NODE* sn_use = st_scalar->Bottom_nth(j);
01428 if (Identical(sn_ref, sn_use))
01429 continue;
01430 POINTS_TO* pt_use = Points_To(sn_use);
01431 if (Alias_Mgr->Aliased(pt_ref, pt_use)) {
01432 bad_alias->Push(TRUE);
01433 return TRUE;
01434 }
01435 }
01436 return FALSE;
01437 }
01438
01439 void ARA_LOOP_INFO::Test_Alias()
01440 {
01441 INT i;
01442
01443 for (i = 0; i < _pri.Elements(); i++) {
01444 ARA_REF* ara_ref_pri = _pri.Bottom_nth(i);
01445 POINTS_TO* pt_pri = Points_To(ara_ref_pri);
01446 if (Test_Alias_Ara_Ref_Array(ara_ref_pri, pt_pri, &_use))
01447 continue;
01448 if (Test_Alias_Ara_Ref_Array(ara_ref_pri, pt_pri, &_def))
01449 continue;
01450 if (Test_Alias_Ara_Ref_Scalar(ara_ref_pri, pt_pri, &_scalar_use))
01451 continue;
01452 if (Test_Alias_Ara_Ref_Scalar(ara_ref_pri, pt_pri, &_scalar_may_def))
01453 continue;
01454 }
01455
01456
01457 for (i = 0; i < _scalar_pri.Elements(); i++) {
01458 SCALAR_NODE* sn_pri = _scalar_pri.Bottom_nth(i);
01459 POINTS_TO* pt_pri = Points_To(sn_pri);
01460 if (Test_Alias_Scalar_Node_Array(pt_pri, &_use, &_bad_alias))
01461 continue;
01462 if (Test_Alias_Scalar_Node_Array(pt_pri, &_def, &_bad_alias))
01463 continue;
01464 if (Test_Alias_Scalar_Node_Scalar(sn_pri, pt_pri, &_scalar_use,
01465 &_bad_alias))
01466 continue;
01467 if (Test_Alias_Scalar_Node_Scalar(sn_pri, pt_pri, &_scalar_def,
01468 &_bad_alias))
01469 continue;
01470 if (Test_Alias_Scalar_Node_Scalar(sn_pri, pt_pri, &_scalar_may_def,
01471 &_bad_alias))
01472 continue;
01473 _bad_alias.Push(FALSE);
01474 }
01475 }
01476
01477 void
01478 ARA_LOOP_INFO::Projection()
01479 {
01480
01481 if (Get_Trace(TP_LNOPT2,TT_LNO_ARA_DEBUG)) {
01482 fprintf(stdout, "Before Projection: \n");
01483 this->Print(stdout);
01484 }
01485
01486 INT i;
01487 for (i = 0; i < _def.Elements(); ++i) {
01488 _def.Bottom_nth(i)->Image().RegionUN_Projection(Depth(), *this);
01489 _def.Bottom_nth(i)->Set_Whole_Array(FALSE);
01490 }
01491
01492 for (i = 0; i < _may_def.Elements(); ++i) {
01493 _may_def.Bottom_nth(i)->Image().RegionUN_Projection(Depth(), *this);
01494 _may_def.Bottom_nth(i)->Set_Whole_Array(FALSE);
01495 }
01496
01497 for (i = 0; i < _use.Elements(); ++i) {
01498 _use.Bottom_nth(i)->Image().RegionUN_Projection(Depth(), *this);
01499 _use.Bottom_nth(i)->Set_Whole_Array(FALSE);
01500 }
01501
01502 for (i = 0; i < _pri.Elements(); ++i) {
01503 _pri.Bottom_nth(i)->Image().RegionUN_Projection(Depth(), *this);
01504 _pri.Bottom_nth(i)->Set_Whole_Array(FALSE);
01505 }
01506
01507 if (Get_Trace(TP_LNOPT2,TT_LNO_ARA_DEBUG)) {
01508 fprintf(stdout, "After Projection: \n");
01509 this->Print(stdout);
01510 }
01511
01512 }
01513
01514 void
01515 ARA_LOOP_INFO::Set_Whole_Array()
01516 {
01517 INT i;
01518 for (i = 0; i < _def.Elements(); ++i) {
01519 _def.Bottom_nth(i)->Set_Whole_Array();
01520 }
01521
01522 for (i = 0; i < _may_def.Elements(); ++i) {
01523 _may_def.Bottom_nth(i)->Set_Whole_Array();
01524 }
01525
01526 for (i = 0; i < _use.Elements(); ++i) {
01527 _use.Bottom_nth(i)->Set_Whole_Array();
01528 }
01529
01530 for (i = 0; i < _pri.Elements(); ++i) {
01531 _pri.Bottom_nth(i)->Set_Whole_Array();
01532 }
01533
01534 if (Get_Trace(TP_LNOPT2,TT_LNO_ARA_DEBUG)) {
01535 fprintf(stdout, "After Set_Whole_Array: \n");
01536 this->Print(stdout);
01537 }
01538 }
01539
01540
01541
01542 BOOL Loop_Invariant_Inside(ACCESS_ARRAY* array, const WN* loop) {
01543
01544 if (WN_operator(loop) != OPR_DO_LOOP)
01545 return FALSE;
01546
01547 INT loopno=Do_Loop_Depth((WN *) loop);
01548
01549 if (array->Non_Const_Loops() > loopno)
01550 return FALSE;
01551 for (INT i=0; i<array->Num_Vec(); i++) {
01552 ACCESS_VECTOR *av = array->Dim(i);
01553 if (av->Too_Messy)
01554 return FALSE;
01555 for (INT j=loopno; j < av->Nest_Depth(); j++) {
01556 if (Get_Trace(TP_LNOPT2,TT_LNO_ARA_DEBUG))
01557 fprintf(stdout,"Loop coefficient is: %d\n", av->Loop_Coeff(j));
01558 if ((av->Loop_Coeff(j) != 0))
01559 return FALSE;
01560 }
01561 }
01562
01563 return TRUE;
01564 }
01565
01566 BOOL Loop_Invariant_Access(ACCESS_ARRAY *array, const WN *loop)
01567 {
01568 if (WN_operator(loop) != OPR_DO_LOOP)
01569 return FALSE;
01570 INT loopno = Do_Loop_Depth((WN *) loop);
01571 if (array->Non_Const_Loops() > loopno)
01572 return FALSE;
01573
01574 for (INT i=0; i<array->Num_Vec(); i++) {
01575 ACCESS_VECTOR *av = array->Dim(i);
01576 if (av->Too_Messy)
01577 return FALSE;
01578 for (INT j=0; j<=loopno; j++) {
01579 if (Get_Trace(TP_LNOPT2,TT_LNO_ARA_DEBUG))
01580 fprintf(stdout,"Loop coefficient is: %d\n", av->Loop_Coeff(j));
01581 if (av->Loop_Coeff(j) != 0)
01582 return FALSE;
01583 }
01584 }
01585 return TRUE;
01586 }
01587
01588
01589 BOOL Loop_Invariant_Access(WN* wn_array, const WN* loop)
01590 {
01591 ACCESS_ARRAY *array =
01592 (ACCESS_ARRAY *) WN_MAP_Get(LNO_Info_Map, wn_array);
01593 if (WN_operator(loop) != OPR_DO_LOOP)
01594 return FALSE;
01595
01596 INT loopno = Do_Loop_Depth((WN *) loop);
01597 if (array->Non_Const_Loops() > loopno)
01598 return FALSE;
01599
01600 WN *wn;
01601 for (wn = wn_array; wn != NULL; wn = LWN_Get_Parent(wn))
01602 if (WN_opcode(wn) == OPC_DO_LOOP)
01603 break;
01604 WN* wn_inner = wn;
01605 DOLOOP_STACK stack(&LNO_local_pool);
01606 Build_Doloop_Stack(wn_inner, &stack);
01607
01608 for (INT i=0; i<array->Num_Vec(); i++) {
01609 ACCESS_VECTOR *av = array->Dim(i);
01610 if (av->Too_Messy)
01611 return FALSE;
01612 INT j;
01613 for (j=0; j<=loopno; j++) {
01614 if (Get_Trace(TP_LNOPT2,TT_LNO_ARA_DEBUG))
01615 fprintf(stdout,"Loop coefficient is: %d\n", av->Loop_Coeff(j));
01616 if (av->Loop_Coeff(j) != 0)
01617 return FALSE;
01618 }
01619 for (j = 0; j < av->Nest_Depth(); j++) {
01620 if (av->Loop_Coeff(j) != 0) {
01621 WN* wn_loop = stack.Bottom_nth(j);
01622 DO_LOOP_INFO* dli_loop = Get_Do_Loop_Info(wn_loop);
01623 INT k;
01624 for (k = 0; k < dli_loop->LB->Num_Vec(); k++) {
01625 ACCESS_VECTOR* avk = dli_loop->LB->Dim(k);
01626 if (avk->Too_Messy)
01627 return FALSE;
01628 if (avk->Non_Const_Loops() > loopno)
01629 return FALSE;
01630 }
01631 for (k = 0; k < dli_loop->UB->Num_Vec(); k++) {
01632 ACCESS_VECTOR* avk = dli_loop->UB->Dim(k);
01633 if (avk->Too_Messy)
01634 return FALSE;
01635 if (avk->Non_Const_Loops() > loopno)
01636 return FALSE;
01637 }
01638 }
01639 }
01640 }
01641
01642 return TRUE;
01643 }
01644
01645 void
01646 ARA_REF::Set_Loop_Invariant(WN *loop)
01647 {
01648
01649 if (!_is_loop_invariant && !_donot_care_invariant) {
01650 REGION_ITER iter(&_image);
01651 for (REGION *cur = iter.First(); !iter.Is_Empty(); cur = iter.Next()) {
01652 if (!cur->Is_Loop_Invariant(loop)) return;
01653 for (INT i = 0; i < cur->_wn_list.Elements(); ++ i) {
01654 ACCESS_ARRAY *s_array =
01655 (ACCESS_ARRAY *) WN_MAP_Get(LNO_Info_Map, cur->_wn_list.Bottom_nth(i));
01656 if (!Loop_Invariant_Access(s_array,loop))
01657 return;
01658 }
01659 }
01660 _is_loop_invariant = TRUE;
01661 }
01662
01663 }
01664
01665
01666
01667
01668
01669
01670
01671 BOOL ARA_LOOP_INFO::Is_Privatizable(WN* wn, BOOL definitely)
01672 {
01673
01674 if ((WN_operator(wn) == OPR_ILOAD) &&
01675 (WN_operator(WN_kid0(wn)) == OPR_ARRAY)) {
01676 #ifdef KEY // bug 10707: screen out cases where the variable is of complex type
01677
01678 if (WN_operator(WN_kid0(WN_kid0(wn))) == OPR_LDID) {
01679 TY_IDX ty = ST_type(WN_st(WN_kid0(WN_kid0(wn))));
01680 if (TY_kind(ty) == KIND_POINTER)
01681 ty = TY_pointed(ty);
01682 if (TY_kind(ty) == KIND_ARRAY) {
01683 ty = TY_etype(ty);
01684 if (! MTYPE_is_complex(WN_rtype(wn)) && MTYPE_is_complex(TY_mtype(ty)))
01685 return FALSE;
01686 }
01687 }
01688 #endif
01689
01690
01691 ACCESS_ARRAY * s_array = (ACCESS_ARRAY *) WN_MAP_Get(LNO_Info_Map, WN_kid0(wn));
01692 Is_True(s_array, ("ARA_LOOP_INFO::Is_Privatizable: No acccess array for source"));
01693 ARA_REF * found = Contains(_pri, WN_kid0(wn));
01694 BOOL is_ok = (found && found->Is_Loop_Invariant() &&
01695 !found->Is_Unknown_Size());
01696 if (!definitely)
01697 return is_ok;
01698 else
01699 return (is_ok && (!found->Need_Last_Value() ||
01700 Is_Covered(found)));
01701
01702 } else if ((WN_operator(wn) == OPR_ISTORE) &&
01703 (WN_operator(WN_kid1(wn)) == OPR_ARRAY)) {
01704 #ifdef KEY // bug 10707: screen out cases where the variable is of complex type
01705
01706 if (WN_operator(WN_kid0(WN_kid1(wn))) == OPR_LDID) {
01707 TY_IDX ty = ST_type(WN_st(WN_kid0(WN_kid1(wn))));
01708 if (TY_kind(ty) == KIND_POINTER)
01709 ty = TY_pointed(ty);
01710 if (TY_kind(ty) == KIND_ARRAY) {
01711 ty = TY_etype(ty);
01712 if (! MTYPE_is_complex(WN_desc(wn)) && MTYPE_is_complex(TY_mtype(ty)))
01713 return FALSE;
01714 }
01715 }
01716 #endif
01717
01718
01719 ACCESS_ARRAY * s_array = (ACCESS_ARRAY *) WN_MAP_Get(LNO_Info_Map, WN_kid1(wn));
01720 Is_True(s_array, ("ARA_LOOP_INFO::Is_Privatizable: No acccess array for source"));
01721
01722 ARA_REF * found = Contains(_def, WN_kid1(wn));
01723 if (found) return (found->Is_Loop_Invariant() && !found->Is_Unknown_Size());
01724
01725 found = Contains(_pri, WN_kid1(wn));
01726 if (found) return (found->Is_Loop_Invariant() &&
01727 !found->Is_Unknown_Size() &&
01728 (!found->Need_Last_Value() || Is_Covered(found)));
01729
01730 }
01731
01732 return FALSE;
01733
01734 }
01735
01736 void
01737 ARA_LOOP_INFO::Print_Loop_Property()
01738 {
01739
01740 for (INT i = 0; i < _children.Elements(); ++i)
01741 _children.Bottom_nth(i)->Print_Loop_Property();
01742
01743 if (Is_Parallel()) {
01744 fprintf(stdout,"Loop %s is parallel\n", WB_Whirl_Symbol(_loop));
01745 } else {
01746 fprintf(stdout,"Loop %s is sequential\n", WB_Whirl_Symbol(_loop));
01747 if (_info == NULL)
01748 fprintf(stdout, "_info is NULL\n");
01749 if (_info != NULL && _info->Has_Gotos)
01750 fprintf(stdout, "_info has gotos\n");
01751 if (_info != NULL && _info->Has_Gotos_This_Level)
01752 fprintf(stdout, "_info has gotos this level\n");
01753 if (_info != NULL && _info->Has_Exits)
01754 fprintf(stdout, "_info has exits\n");
01755 if (_info != NULL &&_info->Has_Bad_Mem)
01756 fprintf(stdout, "_info has bad mem\n");
01757 if (_info != NULL &&_info->Has_Calls)
01758 fprintf(stdout, "_info has calls\n");
01759 if (!_is_good)
01760 fprintf(stdout, "has bad dependence\n");
01761 if (_dep_dist!=0)
01762 fprintf(stdout, "has loop carried dependence\n");
01763 if (!Upper_Bound_Standardize(WN_end(_loop),TRUE))
01764 fprintf(stdout, "non-standard upper bound\n");
01765 if (_info != NULL && _info->Pragma_Cannot_Concurrentize)
01766 fprintf(stdout, "has NO CONCURRENTIZE directive");
01767 if (_info != NULL && _info->Serial_Version_of_Concurrent_Loop)
01768 fprintf(stdout, "is in serial version of concurrent loop");
01769 }
01770 this->Print(stdout);
01771
01772 }
01773
01774
01775
01776
01777
01778
01779 void
01780 ARA_LOOP_INFO::Merge_Info(ARA_LOOP_INFO *ali, BOOL seen_non_scf)
01781 {
01782 INT i;
01783
01784 for (i = 0; i < ali->_use.Elements(); ++i) {
01785 ARA_REF *cur_clone = CXX_NEW(ARA_REF(*(ali->_use.Bottom_nth(i))),
01786 &ARA_memory_pool);
01787 if (Is_Covered(cur_clone))
01788 Add_Pri(cur_clone);
01789 else
01790 Add_Use(cur_clone);
01791 }
01792
01793 for (i = 0; i < ali->_pri.Elements(); ++i) {
01794 ARA_REF *cur_clone = CXX_NEW(ARA_REF(*(ali->_pri.Bottom_nth(i))),
01795 &ARA_memory_pool);
01796 Add_Pri(cur_clone);
01797
01798 }
01799
01800 if (!Info()->Has_Gotos ||
01801 ((!Info()->Has_Gotos_This_Level || !seen_non_scf) && !Info()->Has_Exits)) {
01802 for (i = 0; i < ali->_def.Elements(); ++i) {
01803 ARA_REF *cur_clone = CXX_NEW(ARA_REF(*(ali->_def.Bottom_nth(i))),
01804 &ARA_memory_pool);
01805 Add_Def(cur_clone);
01806 }
01807 }
01808
01809 for (i = 0; i < ali->_may_def.Elements(); ++i) {
01810 ARA_REF *cur_clone = CXX_NEW(ARA_REF(*(ali->_may_def.Bottom_nth(i))),
01811 &ARA_memory_pool);
01812 Add_May_Def(cur_clone);
01813 }
01814
01815
01816 Merge_Scalar_List(&ali->_scalar_may_def, &_scalar_may_def);
01817 Merge_Scalar_List_Covered(&ali->_scalar_use, this, &_scalar_pri,
01818 &_scalar_use);
01819
01820 for (i = 0; i < ali->_reduction.Elements(); ++i)
01821 if (Is_Covered(ali->_reduction.Bottom_nth(i)) )
01822 _scalar_pri.Add_Scalar(ali->_reduction.Bottom_nth(i),0);
01823 else
01824 _reduction.Push(ali->_reduction.Bottom_nth(i));
01825
01826 Merge_Scalar_List(&ali->_scalar_pri, &_scalar_pri);
01827
01828 if (!Info()->Has_Gotos ||
01829 ((!Info()->Has_Gotos_This_Level ||
01830 !seen_non_scf) && !Info()->Has_Exits)) {
01831 Merge_Scalar_List(&ali->_scalar_def, &_scalar_def);
01832 }
01833
01834 if (Get_Trace(TP_LNOPT2,TT_LNO_ARA_DEBUG)) {
01835 fprintf(stdout, "After Merge_Info: \n");
01836 this->Print(stdout);
01837 }
01838
01839 }
01840
01841
01842
01843
01844 ARA_REF *
01845 ARA_LOOP_INFO::Has_Matching(ARA_REF_ST &ara_s, ARA_REF *a)
01846 {
01847 for (INT i = 0; i < ara_s.Elements(); ++i) {
01848 ARA_REF *cur = ara_s.Bottom_nth(i);
01849 if (Is_Same_Array(cur->Array(), cur->Offset(),
01850 a->Array(), a->Offset())) {
01851 if (cur->Image().Is_Included(a->Image(), *this) &&
01852 a->Image().Is_Included(cur->Image(), *this))
01853 return cur;
01854 }
01855 }
01856
01857 return NULL;
01858 }
01859
01860 SCALAR_NODE *
01861 ARA_LOOP_INFO::Has_Matching(SCALAR_STACK &st, SCALAR_NODE *sn)
01862 {
01863 for (INT i = 0; i < st.Elements(); ++i) {
01864 SCALAR_NODE *cur = st.Bottom_nth(i);
01865 if (cur->_scalar == sn->_scalar)
01866 return cur;
01867 }
01868 return NULL;
01869 }
01870
01871
01872
01873
01874 void ARA_LOOP_INFO::Merge_then_else(ARA_LOOP_INFO *ara_then,
01875 ARA_LOOP_INFO *ara_else)
01876 {
01877 INT i;
01878
01879
01880 for (i = 0; i < ara_then->_use.Elements(); ++i) {
01881 ARA_REF *cur_clone =
01882 CXX_NEW(ARA_REF(*(ara_then->_use.Bottom_nth(i))), &ARA_memory_pool);
01883 Add_Use(cur_clone);
01884 }
01885 for (i = 0; i < ara_else->_use.Elements(); ++i) {
01886 ARA_REF *cur_clone =
01887 CXX_NEW(ARA_REF(*(ara_else->_use.Bottom_nth(i))), &ARA_memory_pool);
01888 Add_Use(cur_clone);
01889 }
01890
01891 for (i = 0; i < ara_then->_may_def.Elements(); ++i) {
01892 ARA_REF *cur_clone =
01893 CXX_NEW(ARA_REF(*(ara_then->_may_def.Bottom_nth(i))), &ARA_memory_pool);
01894 Add_May_Def(cur_clone);
01895 }
01896 for (i = 0; i < ara_else->_may_def.Elements(); ++i) {
01897 ARA_REF *cur_clone =
01898 CXX_NEW(ARA_REF(*(ara_else->_may_def.Bottom_nth(i))), &ARA_memory_pool);
01899 Add_May_Def(cur_clone);
01900 }
01901 for (i = 0; i < ara_then->_pri.Elements(); ++i) {
01902 ARA_REF *cur = ara_then->_pri.Bottom_nth(i);
01903 ARA_REF *cur_clone = CXX_NEW(ARA_REF(*cur), &ARA_memory_pool);
01904 Add_Pri(cur_clone);
01905 }
01906 for (i = 0; i < ara_else->_pri.Elements(); ++i) {
01907 ARA_REF *cur = ara_else->_pri.Bottom_nth(i);
01908 ARA_REF *cur_clone = CXX_NEW(ARA_REF(*cur), &ARA_memory_pool);
01909 Add_Pri(cur_clone);
01910 }
01911
01912
01913 for (i = 0; i < ara_then->_def.Elements(); ++i) {
01914 ARA_REF *cur = ara_then->_def.Bottom_nth(i);
01915 ARA_REF *match = Has_Matching(ara_else->_def, cur);
01916 if (match != NULL) {
01917 ARA_REF *cur_clone = CXX_NEW(ARA_REF(*cur), &ARA_memory_pool);
01918 Add_Def(cur_clone);
01919 cur_clone = CXX_NEW(ARA_REF(*match), &ARA_memory_pool);
01920 Add_Def(cur_clone);
01921 } else {
01922 ARA_REF *cur_clone = CXX_NEW(ARA_REF(*cur), &ARA_memory_pool);
01923 Add_Pri(cur_clone);
01924 }
01925 }
01926
01927 for (i = 0; i < ara_else->_def.Elements(); ++i) {
01928 ARA_REF *cur = ara_else->_def.Bottom_nth(i);
01929 ARA_REF *match = Has_Matching(ara_then->_def, cur);
01930 if (match == NULL) {
01931 ARA_REF *cur_clone = CXX_NEW(ARA_REF(*cur), &ARA_memory_pool);
01932 Add_Pri(cur_clone);
01933 }
01934 }
01935
01936
01937 Merge_Scalar_List(&ara_then->_scalar_may_def, &_scalar_may_def);
01938 Merge_Scalar_List(&ara_else->_scalar_may_def, &_scalar_may_def);
01939 Merge_Scalar_List(&ara_then->_scalar_use, &_scalar_use);
01940 Merge_Scalar_List(&ara_else->_scalar_use, &_scalar_use);
01941
01942 for (i = 0; i < ara_then->_reduction.Elements(); ++i)
01943 _reduction.Push(ara_then->_reduction.Bottom_nth(i));
01944 for (i = 0; i < ara_else->_reduction.Elements(); ++i)
01945 _reduction.Push(ara_else->_reduction.Bottom_nth(i));
01946
01947 Merge_Scalar_List(&ara_then->_scalar_pri, &_scalar_pri);
01948 Merge_Scalar_List(&ara_else->_scalar_pri, &_scalar_pri);
01949
01950 for (i = 0; i < ara_then->_scalar_def.Elements(); ++i) {
01951 SCALAR_NODE *cur = ara_then->_scalar_def.Bottom_nth(i);
01952 SCALAR_NODE *match = Has_Matching(ara_else->_scalar_def,cur);
01953 if (match != NULL) {
01954 SYMBOL* sym_cur = &cur->_scalar;
01955 SYMBOL* sym_match = &match->_scalar;
01956 INT j;
01957 for (j = 0; j < cur->Elements(); ++j) {
01958 WN* wn_cur = cur->Bottom_nth(j)->Wn;
01959 if (OPCODE_is_call(WN_opcode(wn_cur))
01960 || WN_operator(wn_cur) == OPR_LDA) {
01961 _scalar_def.Add_Scalar(wn_cur, sym_cur, 0);
01962 } else {
01963 _scalar_def.Add_Scalar(wn_cur, 0);
01964 }
01965 }
01966 for (j = 0; j < match->Elements(); ++j) {
01967 WN* wn_match = match->Bottom_nth(j)->Wn;
01968 if (OPCODE_is_call(WN_opcode(wn_match))
01969 || WN_operator(wn_match) == OPR_LDA) {
01970 _scalar_def.Add_Scalar(wn_match, sym_match, 0);
01971 } else {
01972 _scalar_def.Add_Scalar(wn_match, 0);
01973 }
01974 }
01975 }
01976 }
01977
01978 if (Get_Trace(TP_LNOPT2,TT_LNO_ARA_DEBUG)) {
01979 fprintf(stdout, "After Merge_then_else: \n");
01980 this->Print(stdout);
01981 }
01982
01983 }
01984
01985
01986
01987
01988 void ARA_LOOP_INFO::Walk_Rhs(WN *wn, WN *skip_store_id)
01989 {
01990 LWN_ITER *rhs = LWN_WALK_TreeIter(wn);
01991 while (rhs) {
01992
01993 WN* wn = rhs->wn;
01994 rhs = LWN_WALK_TreeNext(rhs);
01995
01996 if (wn == skip_store_id) {
01997 wn = rhs->wn;
01998 rhs = LWN_WALK_TreeNext(rhs);
01999 skip_store_id = NULL;
02000 }
02001
02002 if ((WN_operator(wn) == OPR_ILOAD) &&
02003 (WN_operator(WN_kid0(wn)) == OPR_ARRAY)) {
02004 ARA_REF *new_use
02005 = CXX_NEW(ARA_REF(WN_kid0(wn),WN_offset(wn),this), &ARA_memory_pool);
02006 if (new_use->Has_Bad_Alias())
02007 CXX_DELETE(new_use, &ARA_memory_pool);
02008 else {
02009 if (Is_Covered(new_use))
02010 Add_Pri(new_use);
02011 else
02012 Add_Use(new_use);
02013 }
02014
02015
02016 rhs = LWN_WALK_TreeNext(rhs);
02017 rhs = LWN_WALK_TreeNext(rhs);
02018
02019 } else if (WN_operator(wn) == OPR_LDID
02020 #ifdef KEY
02021 && TY_kind(ST_type(WN_st(wn))) != KIND_STRUCT
02022 #endif
02023 ) {
02024 if (Is_Covered(wn))
02025 _scalar_pri.Add_Scalar(wn,0);
02026 else if (red_manager && red_manager->Which_Reduction(wn) != RED_NONE) {
02027 Add_Reduction(wn);
02028 _scalar_use.Add_Scalar(wn,0);
02029 } else
02030 _scalar_use.Add_Scalar(wn,0);
02031 } else if (WN_operator(wn) == OPR_PARM
02032 && WN_operator(WN_kid0(wn)) == OPR_LDA) {
02033 WN* wn_lda = WN_kid0(wn);
02034 WN* wn_call = LWN_Get_Parent(wn);
02035 INT i;
02036 for (i = 0; i < WN_kid_count(wn_call); i++)
02037 if (WN_kid(wn_call, i) == wn)
02038 break;
02039 TYPE_ID type_id = IPA_LNO_File != NULL
02040 ? Formal_Machine_Type(wn_call, i, IPA_LNO_File)
02041 : TY_mtype(ST_type(WN_st(wn_lda)));
02042 SYMBOL sym_lda(WN_st(wn_lda), WN_offset(wn_lda), type_id);
02043 if (Is_Covered(wn_lda)) {
02044 _scalar_pri.Add_Scalar(wn_lda, &sym_lda, 0);
02045 } else {
02046 _scalar_use.Add_Scalar(wn_lda, &sym_lda, 0);
02047 }
02048 }
02049 }
02050 }
02051
02052
02053
02054
02055 void
02056 ARA_LOOP_INFO::Walk_Block(WN *block_stmt)
02057 {
02058 Is_True(WN_opcode(block_stmt) == OPC_BLOCK,
02059 ("ARA_LOOP_INFO::Walk_Block: not a OPC_BLOCK stmt"));
02060
02061 LWN_ITER *stmt_iter = LWN_WALK_StmtIter(block_stmt);
02062 stmt_iter = LWN_WALK_StmtNext(stmt_iter);
02063
02064 BOOL seen_non_scf = FALSE;
02065 while (stmt_iter) {
02066 WN* stmt = stmt_iter->wn;
02067 stmt_iter = LWN_WALK_StmtNext(stmt_iter);
02068 OPCODE op = WN_opcode(stmt);
02069 OPERATOR opr = OPCODE_operator(op);
02070
02071
02072 if ((opr == OPR_ISTORE) &&
02073 (WN_operator(WN_kid1(stmt)) == OPR_ARRAY)) {
02074
02075
02076 WN* lfs = WN_kid1(stmt);
02077 WN *skip_store_id = WN_kid0(lfs);
02078
02079
02080 Walk_Rhs(stmt, skip_store_id);
02081
02082
02083 ARA_REF* new_def = CXX_NEW(ARA_REF(lfs,WN_offset(lfs),this),&ARA_memory_pool);
02084 if (new_def->Has_Bad_Alias())
02085 CXX_DELETE(new_def, &ARA_memory_pool);
02086 else {
02087 if (!Info()->Has_Gotos||
02088 ((!Info()->Has_Gotos_This_Level || !seen_non_scf)
02089 && !Info()->Has_Exits)) {
02090 Add_Def(new_def);
02091 } else {
02092 Add_May_Def(new_def);
02093 }
02094 }
02095
02096 continue;
02097
02098 } else if (opr == OPR_STID) {
02099
02100
02101 Walk_Rhs(WN_kid0(stmt));
02102
02103
02104 if (!Info()->Has_Gotos||
02105 ((!Info()->Has_Gotos_This_Level || !seen_non_scf)
02106 && !Info()->Has_Exits)) {
02107 #ifdef KEY // bug 10316: cannot privatize a field in a struct because rest of
02108
02109 if (TY_kind(ST_type(WN_st(stmt))) != KIND_STRUCT ||
02110 strncmp(TY_name(ST_type(WN_st(stmt))), ".dope.", 6) != 0)
02111 #endif
02112 _scalar_def.Add_Scalar(stmt,0);
02113 }
02114 _scalar_may_def.Add_Scalar(stmt,0);
02115
02116 continue;
02117
02118 } else if (opr == OPR_CALL) {
02119
02120 if (Has_Call_Info(stmt)==FALSE)
02121 continue;
02122
02123 CALL_INFO* cli = Get_Call_Info(stmt);
02124 ARA_LOOP_INFO* ali = cli->Call_Ara_Info();
02125 Is_True(ali,
02126 ("ARA_LOOP_INFO::Walk_Block: No ARA_LOOP_INFO for this call"));
02127
02128
02129 Merge_Info(ali,seen_non_scf);
02130
02131 continue;
02132
02133 } else if (opr == OPR_DO_LOOP) {
02134
02135 DO_LOOP_INFO* dli = Get_Do_Loop_Info(stmt);
02136 if (dli->Has_Exits) seen_non_scf = TRUE;
02137 Is_True(dli, ("ARA_LOOP_INFO::Walk_Block: No DO_LOOP_INFO for this loop"));
02138 ARA_LOOP_INFO* ali = dli->ARA_Info;
02139 Is_True(ali, ("ARA_LOOP_INFO::Walk_Block: No ARA_LOOP_INFO for this loop"));
02140 ali->Walk_Loop();
02141
02142
02143 Merge_Info(ali,seen_non_scf);
02144
02145
02146
02147 do
02148 stmt_iter = LWN_WALK_StmtNext(stmt_iter);
02149 while (stmt_iter && Wn_Is_Inside(stmt_iter->wn,stmt));
02150
02151 continue;
02152
02153 } else if (opr == OPR_IF) {
02154 seen_non_scf = TRUE;
02155
02156 Walk_Rhs(WN_kid0(stmt));
02157
02158 IF_INFO* ii = Walk_If(stmt);
02159 Is_True(ii, ("ARA_LOOP_INFO::Walk_Block: no IF_INFO"));
02160 ARA_LOOP_INFO *ali = ii->ARA_common();
02161 Is_True(ali, ("ARA_LOOP_INFO::Walk_Block: no ARA_common after Walk_If"));
02162
02163 Merge_Info(ali,seen_non_scf);
02164
02165
02166
02167 do
02168 stmt_iter = LWN_WALK_StmtNext(stmt_iter);
02169 while (stmt_iter && Wn_Is_Inside(stmt_iter->wn,stmt));
02170
02171 continue;
02172
02173 } else if (OPCODE_is_non_scf(op) || OPCODE_is_scf(op)) {
02174 seen_non_scf = TRUE;
02175 } else if (OPCODE_is_not_executable(op) ||
02176 OPCODE_is_prefetch(op))
02177 continue;
02178 #ifdef KEY
02179
02180 else if (opr == OPR_ASM_STMT) {
02181 for (INT kid = 2; kid < WN_kid_count(stmt); ++kid) {
02182 WN* asm_input = WN_kid(stmt, kid);
02183 WN* load = WN_kid0(asm_input);
02184
02185 Walk_Rhs(WN_kid0(asm_input));
02186
02187 continue;
02188 }
02189 }
02190 #endif
02191
02192
02193 if (OPCODE_is_expression(op) || OPCODE_is_non_scf(op)) Walk_Rhs(stmt);
02194
02195 }
02196
02197 }
02198
02199 static BOOL
02200 Is_Loop_Guard(WN *if_stmt)
02201 {
02202 OPERATOR opr = WN_operator(if_stmt);
02203 Is_True(opr == OPR_IF, ("Is_Loop_Guard: not a IF stmt"));
02204
02205 if (WN_else_is_empty(if_stmt)) {
02206 WN *wn_then = WN_then(if_stmt);
02207 WN *wn = WN_first(wn_then);
02208 if (wn) {
02209 opr = WN_operator(wn);
02210 if (wn == WN_last(wn_then) && opr == OPR_DO_LOOP) {
02211 DO_LOOP_INFO *dli = Get_Do_Loop_Info(wn);
02212 Is_True(dli, ("Is_Loop_Guard: No DO_LOOP_INFO for this loop"));
02213 return (dli->Guard == if_stmt);
02214 }
02215 }
02216 }
02217 return FALSE;
02218 }
02219
02220
02221
02222
02223 IF_INFO *
02224 ARA_LOOP_INFO::Walk_If(WN *if_stmt)
02225 {
02226 IF_INFO* ii = (IF_INFO *) WN_MAP_Get(LNO_Info_Map, if_stmt);
02227 Is_True(ii, ("ARA_LOOP_INFO::Walk_If: no IF_INFO"));
02228
02229
02230
02231
02232 if (Is_Loop_Guard(if_stmt)) {
02233 WN *loop = WN_first(WN_then(if_stmt));
02234 DO_LOOP_INFO* dli = Get_Do_Loop_Info(loop);
02235 Is_True(dli, ("ARA_LOOP_INFO::Walk_Loop: No DO_LOOP_INFO for this loop"));
02236 ARA_LOOP_INFO* ali = dli->ARA_Info;
02237 Is_True(ali, ("ARA_LOOP_INFO::Walk_Loop: No ARA_LOOP_INFO for this loop"));
02238 ali->Walk_Loop();
02239 ii->Set_ARA_common(ali);
02240 return ii;
02241 }
02242
02243 ARA_LOOP_INFO *ara_common = CXX_NEW(ARA_LOOP_INFO(), &ARA_memory_pool);
02244 ara_common->Copy_Some_Values(this);
02245 ii->Set_ARA_common(ara_common);
02246
02247 ARA_LOOP_INFO *ara_then = CXX_NEW(ARA_LOOP_INFO(), &ARA_memory_pool);
02248 ara_then->Copy_Some_Values(this);
02249 ii->Set_ARA_then(ara_then);
02250
02251 ARA_LOOP_INFO *ara_else = CXX_NEW(ARA_LOOP_INFO(), &ARA_memory_pool);
02252 ara_else->Copy_Some_Values(this);
02253 ii->Set_ARA_else(ara_else);
02254
02255 ara_then->Walk_Block(WN_then(if_stmt));
02256 ara_else->Walk_Block(WN_else(if_stmt));
02257
02258 ara_common->Merge_then_else(ara_then, ara_else);
02259
02260 return ii;
02261 }
02262
02263 void
02264 ARA_LOOP_INFO::Walk_Loop()
02265 {
02266 if (_info->Suggested_Parallel) {
02267 for (WN* wn = LWN_Get_Parent(_loop);wn != NULL;wn = LWN_Get_Parent(wn)) {
02268 if (WN_opcode(wn) == OPC_DO_LOOP) {
02269 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn);
02270 if (dli->ARA_Info != NULL)
02271 dli->ARA_Info->_inner_loop_is_suggested_parallel = TRUE;
02272 }
02273 }
02274 }
02275
02276 if (!_info || _info->Has_Exits || _info->Has_Bad_Mem) {
02277 Default_For_Bad_Loop();
02278 return;
02279 }
02280
02281
02282 WN *stmt = WN_start(_loop);
02283
02284
02285 Walk_Rhs(WN_kid0(stmt));
02286
02287 _scalar_def.Add_Scalar(stmt,0);
02288 _scalar_may_def.Add_Scalar(stmt,0);
02289
02290
02291 Walk_Block(WN_do_body(_loop));
02292
02293
02294 stmt = WN_step(_loop);
02295
02296 Walk_Rhs(WN_kid0(stmt));
02297
02298 _scalar_def.Add_Scalar(stmt,0);
02299 _scalar_may_def.Add_Scalar(stmt,0);
02300
02301
02302 Walk_Rhs(WN_end(_loop));
02303
02304
02305 Projection();
02306
02307
02308 Test_Alias();
02309
02310 INT i;
02311
02312 for (i = 0; i < _scalar_use.Elements(); ++i) {
02313 BOOL all_reduction = FALSE;
02314 if (red_manager) {
02315 all_reduction = TRUE;
02316 for (INT j = 0;
02317 all_reduction && (j<_scalar_use.Bottom_nth(i)->Elements()); ++j) {
02318 WN * use_wn = _scalar_use.Bottom_nth(i)->Bottom_nth(j)->Wn;
02319 if (red_manager->Which_Reduction(use_wn) == RED_NONE) {
02320 all_reduction = FALSE;
02321 break;
02322 }
02323 }
02324 }
02325
02326 if (!all_reduction) {
02327 SYMBOL & use_sym = _scalar_use.Bottom_nth(i)->_scalar;
02328 for (INT j = 0; j < _scalar_may_def.Elements(); ++j) {
02329 if (use_sym == _scalar_may_def.Bottom_nth(j)->_scalar) {
02330 if (Run_prompf || LNO_Prompl) {
02331 INT k;
02332 for (k = 0; k < _scalar_vars.Elements(); k++)
02333 if (_scalar_vars.Bottom_nth(k) == use_sym)
02334 break;
02335 if (k == _scalar_vars.Elements())
02336 _scalar_vars.Push(use_sym);
02337 }
02338 Set_To_Sequential();
02339 if (Get_Trace(TP_LNOPT2,TT_LNO_ARA_DEBUG)) {
02340 this->Print(stdout);
02341 } else if (!Run_prompf && !LNO_Prompl)
02342 break;
02343 }
02344 }
02345 }
02346 }
02347
02348 if (red_manager) {
02349 for (i = 0; i < _reduction.Elements(); ++i) {
02350 WN *red = _reduction.Bottom_nth(i);
02351 if (WN_operator(red) == OPR_STID || WN_operator(red) == OPR_LDID) {
02352 SYMBOL sym(red);
02353 for (INT j = 0; j < _scalar_may_def.Elements(); ++j) {
02354 SCALAR_NODE * scalar_node = _scalar_may_def.Bottom_nth(j);
02355 if (sym == scalar_node->_scalar) {
02356 for (INT l = 0; l < scalar_node->Elements(); ++l) {
02357 WN * def_scalar = scalar_node->Bottom_nth(l)->Wn;
02358 if (red_manager->Which_Reduction(def_scalar) !=
02359 red_manager->Which_Reduction(red)) {
02360 Set_To_Sequential();
02361 if (Run_prompf || LNO_Prompl) {
02362 INT k;
02363 for (k = 0; k < _scalar_vars.Elements(); k++)
02364 if (_scalar_vars.Bottom_nth(k) == sym)
02365 break;
02366 if (k == _scalar_vars.Elements())
02367 _scalar_vars.Push(sym);
02368 }
02369 break;
02370 }
02371 }
02372 break;
02373 }
02374 }
02375 }
02376 }
02377 }
02378
02379
02380 for (i = 0; i < _scalar_may_def.Elements(); ++i) {
02381 SYMBOL & sym = _scalar_may_def.Bottom_nth(i)->_scalar;
02382 INT j;
02383 for (j = 0; j < _use.Elements(); ++j) {
02384 ARA_REF *ref = _use.Bottom_nth(j);
02385 if (sym == ref->Array()) {
02386 Set_To_Sequential();
02387 if (Run_prompf || LNO_Prompl) {
02388 INT k;
02389 for (k = 0; k < _scalar_vars.Elements(); k++)
02390 if (_scalar_vars.Bottom_nth(k) == sym)
02391 break;
02392 if (k == _scalar_vars.Elements())
02393 _scalar_vars.Push(sym);
02394 }
02395 goto next_s_def;
02396 }
02397 }
02398 for (j = 0; j < _def.Elements(); ++j) {
02399 ARA_REF *ref = _def.Bottom_nth(j);
02400 if (sym == ref->Array()) {
02401 Set_To_Sequential();
02402 if (Run_prompf || LNO_Prompl) {
02403 INT k;
02404 for (k = 0; k < _scalar_vars.Elements(); k++)
02405 if (_scalar_vars.Bottom_nth(k) == sym)
02406 break;
02407 if (k == _scalar_vars.Elements())
02408 _scalar_vars.Push(sym);
02409 }
02410 goto next_s_def;
02411 }
02412 }
02413 for (j = 0; j < _pri.Elements(); ++j) {
02414 ARA_REF *ref = _pri.Bottom_nth(j);
02415 if (sym == ref->Array()) {
02416 Set_To_Sequential();
02417 if (Run_prompf || LNO_Prompl) {
02418 INT k;
02419 for (k = 0; k < _scalar_vars.Elements(); k++)
02420 if (_scalar_vars.Bottom_nth(k) == sym)
02421 break;
02422 if (k == _scalar_vars.Elements())
02423 _scalar_vars.Push(sym);
02424 }
02425 goto next_s_def;
02426 }
02427 }
02428
02429 next_s_def:
02430 ;
02431 }
02432
02433 for (i = 0; i < _bad_alias.Elements(); ++i) {
02434 if (_bad_alias.Bottom_nth(i)) {
02435 if (Run_prompf || LNO_Prompl){
02436 SYMBOL use_sym = _scalar_pri.Bottom_nth(i)->_scalar;
02437 INT j;
02438 for (j = 0; j < _scalar_alias.Elements(); j++)
02439 if (_scalar_alias.Bottom_nth(j) == use_sym)
02440 break;
02441 if (j == _scalar_alias.Elements())
02442 _scalar_alias.Push(use_sym);
02443 }
02444 Set_To_Sequential();
02445 if (Get_Trace(TP_LNOPT2,TT_LNO_ARA_DEBUG)) {
02446 fprintf(stdout,"Loop is sequential because bad alias for scalars\n");
02447 } else if (!Run_prompf && !LNO_Prompl)
02448 break;
02449 }
02450 }
02451
02452
02453 for (i = 0; i < _scalar_def.Elements(); ++i) {
02454 SYMBOL &def_sym = _scalar_def.Bottom_nth(i)->_scalar;
02455 INT j;
02456 for (j = 0; j < _reduction.Elements(); ++j) {
02457 WN * cur = _reduction.Bottom_nth(j);
02458 if (WN_operator(cur) == OPR_LDID) {
02459 SYMBOL symbol(cur);
02460 if (symbol==def_sym) {
02461 goto next_iteration;
02462 }
02463 }
02464 }
02465 for (j = 0; j < _scalar_use.Elements(); ++j) {
02466 if (def_sym == _scalar_use.Bottom_nth(j)->_scalar) {
02467 break;
02468 }
02469 }
02470 if (j==_scalar_use.Elements()) {
02471 SCALAR_NODE* sn_def = _scalar_def.Bottom_nth(i);
02472 SYMBOL* sym_def = &sn_def->_scalar;
02473 for (INT j = 0; j < sn_def->Elements(); ++j) {
02474 WN* wn_def = sn_def->Bottom_nth(j)->Wn;
02475 #ifdef KEY // bug 10316: cannot privatize a field in a struct because rest of
02476
02477 if (WN_operator(wn_def) == OPR_STID &&
02478 TY_kind(ST_type(WN_st(wn_def))) == KIND_STRUCT &&
02479 strncmp(TY_name(ST_type(WN_st(wn_def))), ".dope.", 6) == 0)
02480 break;
02481 #endif
02482 if (OPCODE_is_call(WN_opcode(wn_def))
02483 || WN_operator(wn_def) == OPR_LDA) {
02484 _scalar_pri.Add_Scalar(wn_def, sym_def, 0);
02485 } else {
02486 _scalar_pri.Add_Scalar(wn_def, 0);
02487 }
02488 }
02489 }
02490 next_iteration:
02491 ;
02492 }
02493
02494
02495
02496 Annotate_Invariant_Def();
02497 Annotate_Invariant_Pri();
02498
02499 for (i = 0; i < _def.Elements(); i++) {
02500 if (_def.Bottom_nth(i)->Is_Loop_Invariant()
02501 && Overlap_Exposed_Array(_def.Bottom_nth(i)->Array())) {
02502 Set_To_Sequential();
02503 if (Run_prompf || LNO_Prompl) {
02504 const SYMBOL& sym_array = _def.Bottom_nth(i)->Array();
02505 INT j;
02506 for (j = 0; j < Partial_Array_Sec().Elements(); j++)
02507 if (Partial_Array_Sec().Bottom_nth(j) == sym_array)
02508 break;
02509 if (j == Partial_Array_Sec().Elements())
02510 Partial_Array_Sec().Push(sym_array);
02511 }
02512 break;
02513 }
02514 }
02515
02516 if (Get_Trace(TP_LNOPT2,TT_LNO_ARA_DEBUG)) {
02517 this->Print(stdout);
02518 }
02519
02520 }
02521
02522
02523
02524
02525
02526
02527
02528 void ARA_LOOP_INFO::Bad_Array_Dependence(WN* wn_source,
02529 WN* wn_sink)
02530 {
02531 if (!LNO_Analysis && !Run_prompf && !LNO_Prompl)
02532 return;
02533 INT ln_source = WN_Whirl_Linenum(wn_source);
02534 INT ln_sink = WN_Whirl_Linenum(wn_sink);
02535 WN* wn_array_source = WN_Array_Symbol(wn_source);
02536 WN* wn_array_sink = WN_Array_Symbol(wn_sink);
02537
02538 if (wn_array_source == NULL || wn_array_sink == NULL)
02539 return;
02540 SYMBOL sym_source = SYMBOL(wn_array_source);
02541 SYMBOL sym_sink = SYMBOL(wn_array_sink);
02542 INT i;
02543 for (i = 0; i < Dep_Vars().Elements(); i++)
02544 if (Dep_Source().Bottom_nth(i) == sym_source
02545 && Dep_Sink().Bottom_nth(i) == sym_sink
02546 && Ln_Dep_Source().Bottom_nth(i) == ln_source
02547 && Ln_Dep_Sink().Bottom_nth(i) == ln_sink)
02548 break;
02549 if (i == Dep_Vars().Elements()) {
02550 Dep_Vars().Push(sym_source);
02551 Dep_Source().Push(sym_source);
02552 Dep_Sink().Push(sym_sink);
02553 Ln_Dep_Source().Push(ln_source);
02554 Ln_Dep_Sink().Push(ln_sink);
02555 }
02556 }
02557
02558
02559
02560
02561
02562
02563
02564
02565 void Parallelization_Process_Deps(WN *wn)
02566 {
02567
02568 VINDEX16 array_v = Array_Dependence_Graph->Get_Vertex(wn);
02569 Is_True(array_v,("Parallelization_Process_Deps: WN with NULL vertex"));
02570
02571 for (EINDEX16 in_edge=Array_Dependence_Graph->Get_In_Edge(array_v);
02572 in_edge; in_edge=Array_Dependence_Graph->Get_Next_In_Edge(in_edge)) {
02573 WN *source = Array_Dependence_Graph->Get_Wn(Array_Dependence_Graph->Get_Source(in_edge));
02574 if (Edge_Is_Reduction_Dependence(in_edge, Array_Dependence_Graph, red_manager)) {
02575
02576 if (WN_operator(wn) == OPR_ISTORE ||
02577 WN_operator(wn) == OPR_STID) {
02578 ACCESS_ARRAY *s_array = NULL;
02579 if (WN_operator(wn) == OPR_ISTORE) {
02580 s_array = (ACCESS_ARRAY *) WN_MAP_Get(LNO_Info_Map,WN_kid1(wn));
02581 }
02582
02583 DEPV_ARRAY *d_array = Array_Dependence_Graph->Depv_Array(in_edge);
02584 for (INT i = 0; i < d_array->Num_Vec(); ++i) {
02585 DEPV* depv = d_array->Depv(i);
02586
02587 INT j;
02588 for (j = 0; (j<d_array->Num_Dim()) &&
02589 (DEP_Direction(DEPV_Dep(depv,j))==DIR_EQ); ++j);
02590
02591 if (j==d_array->Num_Dim()) continue;
02592
02593
02594 INT carry_level = j+d_array->Num_Unused_Dim();
02595
02596
02597 WN* common_loop = LNO_Common_Loop(source,wn);
02598 Is_True(common_loop,("Walk_Loop_Dependence: No common loop between source and sink"));
02599
02600 DO_LOOP_INFO* dli = Get_Do_Loop_Info(common_loop);
02601 FmtAssert(dli && (dli->Depth>=carry_level),
02602 ("Walk_Loop_Dependence: No common loop carries the dependence between source and sink"));
02603
02604 while (dli->Depth>carry_level) {
02605 common_loop = Enclosing_Do_Loop(LWN_Get_Parent(common_loop));
02606 dli = Get_Do_Loop_Info(common_loop);
02607 }
02608
02609 Is_True(dli->Depth==carry_level,("Walk_Loop_Dependence: dli->Depth != carry_level"));
02610
02611 ARA_LOOP_INFO* ali = dli->ARA_Info;
02612 Is_True(ali,
02613 ("Parallelization_Process_Deps: No ARA_LOOP_INFO for reduction"));
02614 if (!Run_prompf && !LNO_Prompl && (!ali->Dep_Is_Good() || ali->Dep_Dist() != 0) ) continue;
02615
02616 BOOL is_invariant;
02617 if (s_array == NULL) {
02618
02619 is_invariant = TRUE;
02620 }
02621 else {
02622 is_invariant = s_array&&Loop_Invariant_Inside(s_array,common_loop);
02623 }
02624 #ifdef KEY // bug 10707: screen out cases where the variable is of complex type
02625
02626 if (WN_operator(wn) == OPR_ISTORE &&
02627 WN_operator(WN_kid1(wn)) == OPR_ARRAY &&
02628 WN_operator(WN_kid0(WN_kid1(wn))) == OPR_LDID) {
02629 TY_IDX ty = ST_type(WN_st(WN_kid0(WN_kid1(wn))));
02630 if (TY_kind(ty) == KIND_POINTER)
02631 ty = TY_pointed(ty);
02632 if (TY_kind(ty) == KIND_ARRAY) {
02633 ty = TY_etype(ty);
02634 if (! MTYPE_is_complex(WN_desc(wn)) && MTYPE_is_complex(TY_mtype(ty)))
02635 is_invariant = FALSE;
02636 }
02637 }
02638 #endif
02639 BOOL privatizable = FALSE;
02640
02641
02642
02643 if (WN_operator(source) == OPR_ILOAD) {
02644 privatizable = ali->Is_Privatizable(source);
02645 } else if (WN_operator(wn) == OPR_ILOAD) {
02646 privatizable = ali->Is_Privatizable(wn);
02647 } else {
02648 privatizable = (ali->Is_Privatizable(source) &&
02649 ali->Is_Privatizable(wn));
02650 }
02651
02652 if (privatizable && !ali->Need_Copyin()) continue;
02653
02654 if (!privatizable && is_invariant
02655 #ifdef KEY
02656
02657 && (s_array == NULL || WN_offset(wn) == 0)
02658 #endif
02659 )
02660 ali->Add_Reduction(wn);
02661 else if (DEP_IsDistance(DEPV_Dep(depv,j))) {
02662 ali->Add_Dependence(DEP_Distance(DEPV_Dep(depv,j)));
02663 ali->Bad_Array_Dependence(source, wn);
02664 } else {
02665 ali->Set_To_Sequential();
02666 ali->Bad_Array_Dependence(source, wn);
02667 }
02668 }
02669 }
02670
02671 } else {
02672 DEPV_ARRAY *d_array = Array_Dependence_Graph->Depv_Array(in_edge);
02673 for (INT i = 0; i < d_array->Num_Vec(); ++i) {
02674 DEPV* depv = d_array->Depv(i);
02675
02676 INT j;
02677 for (j = 0; (j<d_array->Num_Dim()) &&
02678 (DEP_Direction(DEPV_Dep(depv,j))==DIR_EQ); ++j);
02679
02680 if (j==d_array->Num_Dim()) continue;
02681
02682
02683 INT carry_level = j+d_array->Num_Unused_Dim();
02684
02685
02686 WN* common_loop = LNO_Common_Loop(source,wn);
02687 Is_True(common_loop,("Walk_Loop_Dependence: No common loop between source and sink"));
02688
02689 DO_LOOP_INFO* dli = Get_Do_Loop_Info(common_loop);
02690 FmtAssert(dli && (dli->Depth>=carry_level),
02691 ("Walk_Loop_Dependence: No common loop carries the dependence between source and sink"));
02692
02693 while (dli->Depth>carry_level) {
02694 common_loop = Enclosing_Do_Loop(LWN_Get_Parent(common_loop));
02695 dli = Get_Do_Loop_Info(common_loop);
02696 }
02697
02698 Is_True(dli->Depth==carry_level,("Walk_Loop_Dependence: dli->Depth != carry_level"));
02699
02700 ARA_LOOP_INFO* ali = dli->ARA_Info;
02701 Is_True(ali,("Walk_Loop_Dependence: No ARA_LOOP_INFO"));
02702
02703 if (!Run_prompf && !LNO_Prompl && (!ali->Dep_Is_Good() || ali->Dep_Dist() != 0) ) continue;
02704
02705
02706
02707
02708 if (WN_operator(source) == OPR_ILOAD) {
02709 if (ali->Is_Privatizable(source) && !ali->Need_Copyin())
02710 continue;
02711 } else if (WN_operator(wn) == OPR_ILOAD) {
02712 if (ali->Is_Privatizable(wn) && !ali->Need_Copyin())
02713 continue;
02714 } else {
02715 if (ali->Is_Privatizable(source) && ali->Is_Privatizable(wn) &&
02716 !ali->Need_Copyin()) continue;
02717 }
02718
02719 if (DEP_IsDistance(DEPV_Dep(depv,j))) {
02720 ali->Add_Dependence(DEP_Distance(DEPV_Dep(depv,j)));
02721 } else {
02722 ali->Set_To_Sequential();
02723 }
02724 ali->Bad_Array_Dependence(source, wn);
02725 }
02726 }
02727 }
02728 }
02729
02730
02731
02732
02733
02734
02735 extern void Walk_Loop_Dependence(WN * func_nd)
02736 {
02737
02738
02739 for (LWN_ITER *iter = LWN_WALK_TreeIter(func_nd);
02740 iter; iter = LWN_WALK_TreeNext(iter)) {
02741
02742 WN * wn = iter->wn;
02743
02744 OPCODE op = WN_opcode(wn);
02745 if (OPCODE_is_load(op) || OPCODE_is_store(op) || OPCODE_is_call(op)) {
02746 if (Array_Dependence_Graph->Get_Vertex(wn))
02747 Parallelization_Process_Deps(wn);
02748 else if (OPCODE_operator(op) != OPR_LDID && OPCODE_operator(op) != OPR_STID) {
02749
02750
02751
02752 for (WN* loop_enc = Enclosing_Loop(wn);
02753 loop_enc; loop_enc = Enclosing_Loop(LWN_Get_Parent(loop_enc))) {
02754 if (WN_operator(loop_enc) == OPR_DO_LOOP) {
02755 DO_LOOP_INFO* dli = Get_Do_Loop_Info(loop_enc);
02756 Is_True(dli,("Walk_Loop_Dependence: No DO_LOOP_INFO"));
02757 ARA_LOOP_INFO* ali = dli->ARA_Info;
02758 Is_True(ali,("Walk_Loop_Dependence: No ARA_LOOP_INFO"));
02759 if (Run_prompf || LNO_Prompl) {
02760 INT ln = WN_Whirl_Linenum(wn);
02761 if (OPCODE_is_call(WN_opcode(wn))) {
02762 const char* call_name = WB_Whirl_Symbol(wn);
02763 if (call_name == NULL)
02764 call_name = "";
02765 INT length = strlen(call_name);
02766 char* name =
02767 CXX_NEW_ARRAY(char, length + 1, &ARA_memory_pool);
02768 strcpy(name, call_name);
02769 if (WN_operator(wn) == OPR_CALL
02770 && PU_src_lang(Get_Current_PU()) == PU_F77_LANG)
02771 name[length - 1] = '\0';
02772 INT i;
02773 for (i = 0; i < ali->Call_No_Dep_Vars().Elements(); i++)
02774 if (!strcmp(ali->Call_No_Dep_Vars().Bottom_nth(i), name)
02775 && ali->Ln_Call_No_Dep_Vars().Bottom_nth(i) == ln)
02776 break;
02777 if (i == ali->Call_No_Dep_Vars().Elements()) {
02778 ali->Call_No_Dep_Vars().Push(name);
02779 ali->Ln_Call_No_Dep_Vars().Push(ln);
02780 }
02781 } else if (WN_operator(wn) == OPR_ISTORE
02782 || WN_operator(wn) == OPR_ILOAD) {
02783 SYMBOL* sym = CXX_NEW(SYMBOL(WN_Array_Symbol(wn)),
02784 &ARA_memory_pool);
02785 INT i;
02786 for (i = 0; i < ali->Array_No_Dep_Vars().Elements(); i++)
02787 if (ali->Array_No_Dep_Vars().Bottom_nth(i) == *sym
02788 && ali->Ln_Array_No_Dep_Vars().Bottom_nth(i) == ln)
02789 break;
02790 if (i == ali->Array_No_Dep_Vars().Elements()) {
02791 ali->Array_No_Dep_Vars().Push(*sym);
02792 ali->Ln_Array_No_Dep_Vars().Push(ln);
02793 }
02794 } else {
02795 INT i;
02796 for (i = 0; i < ali->Ln_Misc_No_Dep_Vars().Elements(); i++)
02797 if (ali->Ln_Misc_No_Dep_Vars().Bottom_nth(i) == ln)
02798 break;
02799 if (i == ali->Ln_Misc_No_Dep_Vars().Elements())
02800 ali->Ln_Misc_No_Dep_Vars().Push(ln);
02801 }
02802 }
02803 ali->Set_To_Sequential();
02804 if (LNO_Analysis) {
02805 WN* wn_array = (WN_operator(wn) == OPR_ISTORE) ?
02806 WN_kid1(wn) : WN_kid0(wn);
02807 if (WN_operator(wn_array) == OPR_PARM)
02808 wn_array = WN_kid0(wn_array);
02809 SYMBOL sym = (WN_operator(wn_array) == OPR_ARRAY)?
02810 SYMBOL(WN_array_base(wn_array)) : SYMBOL(wn_array);
02811 INT i;
02812 for (i = 0; i < ali->Dep_Vars().Elements(); ++i) {
02813 if (sym==ali->Dep_Vars().Bottom_nth(i)) break;
02814 }
02815 if (i==ali->Dep_Vars().Elements())
02816 ali->Dep_Vars().Push(sym);
02817 }
02818
02819 }
02820 }
02821 }
02822 }
02823 }
02824
02825 }
02826
02827 static
02828 void Set_Enclosing_If_Has_Region(WN *wn)
02829 {
02830 for (WN *wn_temp = wn; wn_temp; wn_temp = LWN_Get_Parent(wn_temp)) {
02831 if (WN_opcode(wn_temp) == OPC_IF) {
02832 IF_INFO * ii = Get_If_Info(wn_temp, TRUE);
02833 if (ii) ii->Contains_Regions = TRUE;
02834 }
02835 }
02836 }
02837
02838
02839 static
02840 INT64 Loop_FP_Size(WN* wn)
02841 {
02842 OPCODE opcode = WN_opcode(wn);
02843 if (OPCODE_is_leaf(opcode))
02844 return 1;
02845 else if (OPCODE_is_load(opcode))
02846 return 1;
02847 else if (opcode == OPC_BLOCK) {
02848 WN *kid = WN_first(wn);
02849 INT64 count = 0;
02850 while (kid) {
02851 count += Loop_FP_Size(kid);
02852 kid = WN_next(kid);
02853 }
02854 return count;
02855 } else if (opcode == OPC_DO_LOOP) {
02856 INT64 count = Loop_FP_Size(WN_start(wn));
02857 count += Loop_FP_Size(WN_end(wn));
02858 INT64 count1 = Loop_FP_Size(WN_do_body(wn));
02859 count1 += Loop_FP_Size(WN_step(wn));
02860 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn);
02861 if (dli) {
02862 count1 *= MAX(1,dli->Est_Num_Iterations);
02863 }
02864 return (count+count1);
02865 }
02866
02867 OPERATOR oper = OPCODE_operator(opcode);
02868
02869 INT64 count = 0;
02870 INT kid_cnt = WN_kid_count(wn);
02871
02872 if ((oper == OPR_TRUNC) || (oper == OPR_RND) ||
02873 (oper == OPR_CEIL) || (oper == OPR_FLOOR) || (oper == OPR_INTRINSIC_OP)) {
02874 count++;
02875 } else if ((oper == OPR_REALPART) || (oper == OPR_IMAGPART) ||
02876 (oper == OPR_PARM) || (oper == OPR_PAREN)) {
02877
02878 } else if (OPCODE_is_expression(opcode) && (oper != OPR_CONST)) {
02879 #if 0
02880
02881 if ((OPCODE_desc(opcode)==MTYPE_FQ) || (OPCODE_rtype(opcode)==MTYPE_FQ) ||
02882 (OPCODE_desc(opcode)==MTYPE_CQ) || (OPCODE_rtype(opcode)==MTYPE_CQ) ||
02883 (OPCODE_desc(opcode)==MTYPE_F4) || (OPCODE_desc(opcode)==MTYPE_F8) ||
02884 (OPCODE_rtype(opcode)==MTYPE_F4)||
02885 (OPCODE_rtype(opcode)==MTYPE_F8)|| (OPCODE_desc(opcode)==MTYPE_C4) ||
02886 (OPCODE_desc(opcode)==MTYPE_C8) || (OPCODE_rtype(opcode)==MTYPE_C4)||
02887 (OPCODE_rtype(opcode)==MTYPE_C8)) {
02888 }
02889 #endif
02890 if ((oper == OPR_MAX) || (oper == OPR_MIN) ||
02891 (oper == OPR_ADD) || (oper == OPR_SUB) || (oper == OPR_MPY) ||
02892 (oper == OPR_NEG))
02893 count++;
02894 else if ((oper == OPR_DIV || oper == OPR_SQRT))
02895 count = count + 10;
02896
02897 } else if (OPCODE_is_store(opcode)) {
02898 count++;
02899 kid_cnt = kid_cnt - 1;
02900 }
02901
02902 for (INT kidno=0; kidno<kid_cnt; kidno++) {
02903 WN *kid = WN_kid(wn,kidno);
02904 count += Loop_FP_Size(kid);
02905 }
02906
02907 return count;
02908
02909 }
02910
02911
02912
02913
02914 BOOL
02915 ARA_LOOP_INFO::Bounds_Depend_On_Index(INT depth)
02916 {
02917 if (!_info) return FALSE;
02918
02919 INT i;
02920 if (!_info->LB->Too_Messy) {
02921 for (i = 0; i < _info->LB->Num_Vec(); ++i) {
02922 if (!_info->LB->Too_Messy && _info->LB->Dim(i)->Loop_Coeff(depth)!=0)
02923 return TRUE;
02924 }
02925 }
02926 if (!_info->UB->Too_Messy) {
02927 for (i = 0; i < _info->UB->Num_Vec(); ++i) {
02928 if (!_info->UB->Too_Messy && _info->UB->Dim(i)->Loop_Coeff(depth)!=0)
02929 return TRUE;
02930 }
02931 }
02932 for (i = 0; i < _children.Elements(); ++i) {
02933 if (_children.Bottom_nth(i)->Bounds_Depend_On_Index(depth))
02934 return TRUE;
02935 }
02936
02937 return FALSE;
02938 }
02939
02940 BOOL
02941 ARA_LOOP_INFO::Variable_Load()
02942 {
02943 for (INT i = 0; i < _children.Elements(); ++i) {
02944 if (_children.Bottom_nth(i)->Bounds_Depend_On_Index(Depth())) return TRUE;
02945 }
02946 return FALSE;
02947 }
02948
02949 WN* ARA_LOOP_INFO::Create_Old_IF_Clause()
02950 {
02951 INT64 fpcount = Loop_FP_Size(WN_do_body(_loop));
02952 fpcount += Loop_FP_Size(WN_step(_loop));
02953 if (fpcount==0) {
02954 return LWN_Make_Icon(Boolean_type, 0);
02955 }
02956
02957 INT64 threshed = 1200/fpcount;
02958 if (threshed<2) {
02959 return LWN_Make_Icon(Boolean_type, 1);
02960 }
02961
02962 ACCESS_VECTOR *svec = _info->Step;
02963 if (svec->Too_Messy || !svec->Is_Const() || (svec->Const_Offset == 0))
02964 return NULL;
02965 threshed *= svec->Const_Offset;
02966 threshed -= svec->Const_Offset;
02967
02968 WN* init = LWN_Copy_Tree(WN_kid0(WN_start(_loop)));
02969 LWN_Copy_Def_Use(WN_kid0(WN_start(_loop)), init, Du_Mgr);
02970 WN* end = LWN_Copy_Tree(WN_kid1(WN_end(_loop)));
02971 LWN_Copy_Def_Use(WN_kid1(WN_end(_loop)), end, Du_Mgr);
02972
02973 TYPE_ID ind_type = Do_Wtype(_loop);
02974 OPCODE subop = OPCODE_make_op(OPR_SUB, Promote_Type(ind_type), MTYPE_V);
02975 WN* cons_threshed = LWN_Make_Icon(Promote_Type(ind_type), threshed);
02976 WN* trip_count = LWN_CreateExp2(subop, end, init);
02977
02978 WN *if_clause = NULL;
02979 if (svec->Const_Offset > 0) {
02980 OPCODE geop = OPCODE_make_op(OPR_GE, Boolean_type, Promote_Type(ind_type));
02981 if_clause = LWN_CreateExp2(geop, trip_count, cons_threshed);
02982 } else {
02983 OPCODE leop = OPCODE_make_op(OPR_LE, Boolean_type, Promote_Type(ind_type));
02984 if_clause = LWN_CreateExp2(leop, trip_count, cons_threshed);
02985 }
02986 return if_clause;
02987 }
02988
02989
02990
02991
02992
02993
02994
02995
02996 static WN* Current_Numprocs(WN* wn_loop,
02997 BOOL is_pdo)
02998 {
02999 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn_loop);
03000 WN* wn_num_threads = NULL;
03001 if (!LNO_Pseudo_Lower || dli->Mp_Info != NULL
03002 && dli->Mp_Info->Plower_Disabled()) {
03003 wn_num_threads = LWN_Make_Icon(MTYPE_I4, NOMINAL_PROCS);
03004 } else if (is_pdo) {
03005 wn_num_threads = Get_Runtime_Cur_Numthreads_Ldid();
03006 } else {
03007 wn_num_threads = Get_Runtime_Numthreads_Ldid();
03008 }
03009 return wn_num_threads;
03010 }
03011
03012
03013
03014
03015 static ST *
03016 Find_Reduction_Array_Base(WN *wn_array)
03017 {
03018 Is_True(WN_operator(wn_array) == OPR_ARRAY, ("not an ARRAY node"));
03019 WN *base = WN_kid0(wn_array);
03020 Is_True(base, ("NULL array base?!?"));
03021
03022 switch (WN_operator(base)) {
03023 case OPR_LDA:
03024 case OPR_LDID:
03025 Is_True(WN_st(base), ("NULL array base?!?"));
03026 return WN_st(base);
03027 case OPR_ILOAD:
03028 return Find_Reduction_Array_Base(WN_kid0(base));
03029 default:
03030 break;
03031 }
03032
03033 Fail_FmtAssertion("unexpected operator %d in base expression",
03034 (INT) WN_operator(base));
03035 return NULL;
03036 }
03037
03038 static void
03039 Set_Reduction_Array_Base_is_shared_auto(WN *wn_array)
03040 {
03041 Is_True(WN_operator(wn_array) == OPR_ARRAY, ("not an ARRAY node"));
03042 WN *base = WN_kid0(wn_array);
03043 Is_True(base, ("NULL array base?!?"));
03044
03045 switch (WN_operator(base)) {
03046 case OPR_LDA:
03047 if (WN_sclass(base) == SCLASS_AUTO)
03048 Set_ST_is_shared_auto(*WN_st(base));
03049 break;
03050 case OPR_LDID:
03051 break;
03052
03053 default:
03054 break;
03055 }
03056 }
03057
03058
03059
03060
03061 void ARA_LOOP_INFO::Reduction_List(REDUCTION_LIST *rlist)
03062 {
03063 REDUCTION_MANAGER *rm = red_manager;
03064 if (rm == NULL || _reduction.Elements() == 0)
03065 return;
03066
03067
03068 DYN_ARRAY<WN *> reductions(&LNO_local_pool);
03069 INT i;
03070 for (i = 0; i < _reduction.Elements(); i++) {
03071 WN *wn = _reduction.Bottom_nth(i), *prag;
03072 if (WN_operator(wn) == OPR_ISTORE) {
03073 prag = WN_CreateXpragma(WN_PRAGMA_REDUCTION, ST_IDX_ZERO, 1);
03074 WN_kid0(prag) = LWN_Copy_Tree(WN_kid1(wn));
03075 } else
03076 prag = WN_CreatePragma(WN_PRAGMA_REDUCTION, WN_st(wn),
03077 WN_offset(wn), 0);
03078
03079 reductions.AddElement(prag);
03080 }
03081
03082
03083 HASH_TABLE<WN *, WN *> redn_to_store(17, &LNO_local_pool);
03084
03085 LWN_ITER* itr = LWN_WALK_TreeIter(_loop);
03086 for (; itr != NULL; itr = LWN_WALK_TreeNext(itr)) {
03087 WN* wn = itr->wn;
03088 OPERATOR opr = WN_operator(wn);
03089
03090 if ((opr != OPR_STID && opr != OPR_ISTORE) ||
03091 rm->Which_Reduction(wn) == RED_NONE)
03092 continue;
03093
03094 for (i = 0; i < reductions.Elements(); i++) {
03095 WN *redn = reductions[i];
03096 if (WN_Store_Target_Matches_Reduction(wn, redn) &&
03097 !redn_to_store.Find(redn)) {
03098 redn_to_store.Enter(redn, wn);
03099 rlist->AddElement(wn);
03100 }
03101 }
03102 }
03103
03104 #ifdef Is_True_On
03105
03106 for (i = 0; i < reductions.Elements(); i++) {
03107 WN *redn = reductions[i];
03108 if (redn_to_store.Find(redn))
03109 continue;
03110 Fail_FmtAssertion("could not find any store nodes for reduction");
03111 }
03112 #endif
03113
03114 for (i = 0; i < reductions.Elements(); i++)
03115 LWN_Delete_Tree(reductions[i]);
03116 }
03117
03118
03119
03120
03121
03122
03123
03124 float ARA_LOOP_INFO::Tc_Parallel_Cost()
03125 {
03126 BOOL dummy;
03127 DO_LOOP_INFO* dli = Get_Do_Loop_Info(_loop);
03128 REDUCTION_LIST rlist(&LNO_local_pool);
03129 Reduction_List(&rlist);
03130 float Basic_Overhead = (float) LNO_Parallel_Overhead;
03131 float Doacross_Overhead = dli->Is_Doacross
03132 ? (float) dli->Doacross_Overhead : 0.0;
03133 float Reduction_Overhead = rlist.Elements() > 0
03134 ? (float) MP_Reduction_Combine_Cycles(&rlist, &dummy) : 0.0;
03135 return Basic_Overhead + Doacross_Overhead + Reduction_Overhead;
03136 }
03137
03138
03139
03140
03141
03142
03143
03144 float ARA_LOOP_INFO::Tp_Parallel_Cost()
03145 {
03146 #ifdef KEY // bug 7772
03147 return LNO_Parallel_per_proc_overhead;
03148 #else
03149 return 123.0;
03150 #endif
03151 }
03152
03153
03154
03155
03156
03157
03158
03159
03160
03161 static WN* WN_Single_Iteration_Cost(WN* wn_loop,
03162 BOOL include_calls)
03163 {
03164 double cost_wo_calls = Single_Iteration_Cost(wn_loop, FALSE);
03165 if (!include_calls)
03166 return Make_Const(Host_To_Targ_Float(MTYPE_F8, (float) cost_wo_calls));
03167 WN* wn_base = NULL;
03168 LWN_ITER* itr = LWN_WALK_TreeIter(wn_loop);
03169 for (; itr != NULL; itr = LWN_WALK_TreeNext(itr)) {
03170 WN* wn = itr->wn;
03171 if (WN_operator(wn) == OPR_CALL) {
03172 WN* wn_call_cost = Execution_Cost(IPA_LNO_File, wn, MTYPE_I4);
03173 if (wn_base == NULL) {
03174 wn_base = wn_call_cost;
03175 } else {
03176 TYPE_ID mtype = Cast_Float_Operands(&wn_base, &wn_call_cost);
03177 OPCODE op = OPCODE_make_op(OPR_ADD, mtype, MTYPE_V);
03178 wn_base = LWN_CreateExp2(op, wn_base, wn_call_cost);
03179 }
03180 }
03181 }
03182 WN* wn_float_call_cost = wn_base;
03183 TYPE_ID mtype_start = OPCODE_rtype(WN_opcode(wn_base));
03184 if (mtype_start != MTYPE_F8) {
03185 OPCODE op_cvt = OPCODE_make_op(OPR_CVT, MTYPE_F8, mtype_start);
03186 wn_float_call_cost = LWN_CreateExp1(op_cvt, wn_base);
03187 }
03188 WN* wn_float_other_cost
03189 = Make_Const(Host_To_Targ_Float(MTYPE_F8, (float) cost_wo_calls));
03190 OPCODE op_add = OPCODE_make_op(OPR_ADD, MTYPE_F8, MTYPE_V);
03191 return LWN_CreateExp2(op_add, wn_float_call_cost, wn_float_other_cost);
03192 }
03193
03194
03195
03196
03197
03198
03199
03200
03201
03202
03203
03204
03205
03206
03207
03208
03209
03210
03211
03212
03213
03214
03215
03216
03217
03218
03219
03220
03221
03222
03223
03224
03225
03226
03227
03228
03229
03230 WN* ARA_LOOP_INFO::Create_New_IF_Clause(BOOL is_pdo)
03231 {
03232 if (!PU_has_mp(Get_Current_PU()))
03233 Mp_File_Init();
03234 WN* wn_outer = _loop;
03235 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn_outer);
03236 if (dli->Suggested_Parallel && dli->Work_Estimate == 0)
03237 DevWarn("Work Estimate for loop %s at %d is 0", WB_Whirl_Symbol(wn_outer),
03238 (INT) WN_linenum(wn_outer));
03239 if (!dli->Suggested_Parallel) {
03240
03241
03242
03243
03244
03245 dli->Work_Estimate = Single_Iteration_Cost(wn_outer, TRUE);
03246 DevWarn("Parallelizing Unexpected Loop: Using Work Estimate of %.2f",
03247 dli->Work_Estimate);
03248 }
03249
03250
03251 if (Not_Enough_Parallel_Work())
03252 return LWN_Make_Icon(MTYPE_I4, 0);
03253
03254
03255 BOOL has_left_right = FALSE;
03256 INT left = -1;
03257 INT right = -1;
03258 if (Always_Enough_Parallel_Work(&has_left_right, &left, &right))
03259 return LWN_Make_Icon(MTYPE_I4, 1);
03260
03261
03262 if (has_left_right) {
03263 if (left > 1 && right < MAX_PROCS) {
03264 WN* wn_procs1 = Current_Numprocs(_loop, is_pdo);
03265 WN* wn_left = LWN_Make_Icon(WN_rtype(wn_procs1), left);
03266 OPCODE op_ge = OPCODE_make_op(OPR_GE, Boolean_type, WN_rtype(wn_procs1));
03267 WN* wn_lb = LWN_CreateExp2(op_ge, wn_procs1, wn_left);
03268 WN* wn_procs2 = Current_Numprocs(_loop, is_pdo);
03269 WN* wn_right = LWN_Make_Icon(WN_rtype(wn_procs2), right);
03270 OPCODE op_le = OPCODE_make_op(OPR_LE, Boolean_type, WN_rtype(wn_procs2));
03271 WN* wn_ub = LWN_CreateExp2(op_le, wn_procs2, wn_right);
03272 OPCODE op_land = OPCODE_make_op(OPR_LAND, Boolean_type, MTYPE_V);
03273 return LWN_CreateExp2(op_land, wn_lb, wn_ub);
03274 } else if (left > 1) {
03275 WN* wn_procs1 = Current_Numprocs(_loop, is_pdo);
03276 WN* wn_left = LWN_Make_Icon(WN_rtype(wn_procs1), left);
03277 OPCODE op_ge = OPCODE_make_op(OPR_GE, Boolean_type, WN_rtype(wn_procs1));
03278 return LWN_CreateExp2(op_ge, wn_procs1, wn_left);
03279 } else if (right < MAX_PROCS) {
03280 WN* wn_procs2 = Current_Numprocs(_loop, is_pdo);
03281 WN* wn_right = LWN_Make_Icon(WN_rtype(wn_procs2), right);
03282 OPCODE op_le = OPCODE_make_op(OPR_LE, Boolean_type, WN_rtype(wn_procs2));
03283 return LWN_CreateExp2(op_le, wn_procs2, wn_right);
03284 }
03285 }
03286
03287
03288 INT nloops = SNL_Loop_Count(wn_outer);
03289 WN* wn_inner = SNL_Get_Inner_Snl_Loop(wn_outer, nloops);
03290 INT inv_nloops = Invariant_Loop_Count(wn_outer);
03291 INT var_nloops = nloops - inv_nloops;
03292 INT count = 0;
03293 WN* wn_base = NULL;
03294 if (LNO_IPA_Enabled && dli->Has_Calls) {
03295 wn_base = WN_Single_Iteration_Cost(wn_outer, TRUE);
03296 } else {
03297 wn_base = Make_Const(Host_To_Targ_Float(MTYPE_F8, (float)
03298 dli->Work_Estimate));
03299 }
03300 #ifdef KEY // bug 7772
03301 INT64 wn_base_ival = 0;
03302 WN* wn_prod_trips = NULL;
03303 if (WN_operator(wn_base) == OPR_CONST)
03304 wn_base_ival = (INT64)TCON_dval(ST_tcon_val(WN_st(wn_base)));
03305 #endif
03306 for (WN* wn = wn_inner; wn != NULL; wn = LWN_Get_Parent(wn)) {
03307 if (WN_opcode(wn) == OPC_DO_LOOP) {
03308 WN* wn_prod = NULL;
03309 if (count++ < var_nloops
03310 || !Upper_Bound_Standardize(WN_end(wn), TRUE)) {
03311 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn);
03312 #ifdef KEY // bug 7772
03313 wn_prod = LWN_Make_Icon(MTYPE_I4, dli->Est_Num_Iterations);
03314 #else
03315 wn_prod = Make_Const(Host_To_Targ_Float(MTYPE_F8,
03316 (float) dli->Est_Num_Iterations));
03317 #endif
03318 } else {
03319 WN* wn_trip_count = Trip_Count(wn);
03320 #ifdef KEY // bug 7772
03321 wn_prod = wn_trip_count;
03322 #else
03323 wn_prod = LWN_CreateExp1(OPCODE_make_op(OPR_CVT, MTYPE_F8,
03324 Promote_Type(Do_Wtype(wn))), wn_trip_count);
03325 #endif
03326 }
03327 #ifdef KEY // bug 7772
03328 if (wn == wn_inner)
03329 wn_prod_trips = wn_prod;
03330 else wn_prod_trips = LWN_CreateExp2(OPC_I4MPY, wn_prod_trips, wn_prod);
03331 #else
03332 wn_base = LWN_CreateExp2(OPC_F8MPY, wn_base, wn_prod);
03333 #endif
03334 }
03335 if (wn == wn_outer)
03336 break;
03337 }
03338
03339
03340
03341
03342 WN* wn_procs1 = Current_Numprocs(_loop, is_pdo);
03343 WN* wn_one = LWN_Make_Icon(MTYPE_I4, 1);
03344 TYPE_ID proc_type;
03345 if (OPCODE_is_load(WN_opcode(wn_procs1))) {
03346 proc_type = WN_desc(wn_procs1);
03347 } else {
03348 proc_type = WN_rtype(wn_procs1);
03349 }
03350 OPCODE subop = OPCODE_make_op(OPR_SUB, proc_type, MTYPE_V);
03351 WN* wn_pminus1 = LWN_CreateExp2(subop, wn_procs1, wn_one);
03352 #ifdef KEY // bug 7772
03353 WN* wn_rhs = LWN_CreateExp2(OPC_I4MPY, wn_prod_trips, wn_pminus1);
03354
03355 WN* wn_procs2 = Current_Numprocs(_loop, is_pdo);
03356 WN* wn_Tp = LWN_Make_Icon(MTYPE_I4, (INT) Tp_Parallel_Cost());
03357 WN* wn_PTp = LWN_CreateExp2(OPC_I4MPY, wn_procs2, wn_Tp);
03358
03359 WN* wn_Tc = LWN_Make_Icon(MTYPE_I4, (INT) Tc_Parallel_Cost());
03360 WN* wn_lhs_sum = LWN_CreateExp2(OPC_I4ADD, wn_Tc, wn_PTp);
03361 WN* wn_procs3 = Current_Numprocs(_loop, is_pdo);
03362 WN* wn_lhs = LWN_CreateExp2(OPC_I4MPY, wn_procs3, wn_lhs_sum);
03363 WN* wn_result;
03364 if (wn_base_ival != 0) {
03365 if (WN_operator(wn_lhs) == OPR_INTCONST) {
03366 WN_const_val(wn_lhs) = WN_const_val(wn_lhs) / wn_base_ival;
03367 wn_result = LWN_CreateExp2(OPC_I4I4GT, wn_rhs, wn_lhs);
03368 }
03369 else wn_result = LWN_CreateExp2(OPC_I4I4GT,
03370 LWN_CreateExp2(OPC_I4MPY, wn_rhs,
03371 LWN_Make_Icon(MTYPE_I4, wn_base_ival)),
03372 wn_lhs);
03373 }
03374 else {
03375 wn_rhs = LWN_CreateExp1(OPCODE_make_op(OPR_CVT, MTYPE_F8, MTYPE_I4),wn_rhs);
03376 wn_lhs = LWN_CreateExp1(OPCODE_make_op(OPR_CVT, MTYPE_F8, MTYPE_I4),wn_lhs);
03377 wn_result = LWN_CreateExp2(OPC_I4F8GT,
03378 LWN_CreateExp2(OPC_F8MPY, wn_rhs, wn_base),
03379 wn_lhs);
03380 }
03381 #else
03382 WN* wn_pminus1_float = LWN_CreateExp1(OPCODE_make_op(OPR_CVT, MTYPE_F8,
03383 MTYPE_I4), wn_pminus1);
03384
03385 WN* wn_rhs = LWN_CreateExp2(OPC_F8MPY, wn_base, wn_pminus1_float);
03386
03387 WN* wn_procs2 = Current_Numprocs(_loop, is_pdo);
03388 WN* wn_p_float = LWN_CreateExp1(OPCODE_make_op(OPR_CVT, MTYPE_F8, MTYPE_I4),
03389 wn_procs2);
03390 WN* wn_Tp = Make_Const(Host_To_Targ_Float(MTYPE_F8, Tp_Parallel_Cost()));
03391 WN* wn_PTp = LWN_CreateExp2(OPC_F8MPY, wn_p_float, wn_Tp);
03392
03393 WN* wn_Tc = Make_Const(Host_To_Targ_Float(MTYPE_F8, Tc_Parallel_Cost()));
03394 WN* wn_lhs_sum = LWN_CreateExp2(OPC_F8ADD, wn_Tc, wn_PTp);
03395 WN* wn_procs3 = Current_Numprocs(_loop, is_pdo);
03396 WN* wn_p_float2 = LWN_CreateExp1(OPCODE_make_op(OPR_CVT, MTYPE_F8,
03397 MTYPE_I4), wn_procs3);
03398 WN* wn_lhs = LWN_CreateExp2(OPC_F8MPY, wn_p_float2, wn_lhs_sum);
03399
03400 WN* wn_result = LWN_CreateExp2(OPC_I4F8GT, wn_rhs, wn_lhs);
03401 #endif
03402 return wn_result;
03403 }
03404
03405
03406 WN* ARA_LOOP_INFO::Create_IF_Clause(BOOL is_pdo)
03407 {
03408 if (Get_Trace(TP_LNOPT2, TT_LNO_NO_AUTO_PARALLEL))
03409 return Create_Old_IF_Clause();
03410 else
03411 return Create_New_IF_Clause(is_pdo);
03412 }
03413
03414
03415
03416
03417
03418
03419
03420 extern BOOL Has_No_Concurrentize_Directive(WN* wn_loop)
03421 {
03422 for (WN* wn = WN_prev(wn_loop); wn != NULL; wn = WN_prev(wn)) {
03423 if (WN_opcode(wn) == OPC_PRAGMA
03424 && WN_pragma(wn) == WN_PRAGMA_KAP_NOCONCURRENTIZE)
03425 return TRUE;
03426 if (WN_opcode(wn) == OPC_DO_LOOP)
03427 break;
03428 }
03429 return FALSE;
03430 }
03431
03432
03433
03434
03435
03436
03437
03438 extern BOOL Inside_Lego_Tiled_Loop(WN* wn_loop)
03439 {
03440 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn_loop);
03441 for (WN* wn = wn_loop; wn != NULL; wn = LWN_Get_Parent(wn)) {
03442 if (WN_opcode(wn) == OPC_DO_LOOP) {
03443 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn);
03444 if (dli->Is_Outer_Lego_Tile || dli->Is_Inner_Lego_Tile)
03445 return TRUE;
03446 }
03447 }
03448 return FALSE;
03449 }
03450
03451
03452
03453
03454
03455
03456
03457 static void Print_Non_Parallel_Loop(FILE* fp,
03458 WN* wn_loop)
03459 {
03460 fprintf(fp, "NOT Auto Parallelizing Loop %s at %d (SMALL TRIP COUNT)\n",
03461 WB_Whirl_Symbol(wn_loop), (INT) WN_linenum(wn_loop));
03462 }
03463
03464 #ifdef KEY
03465 static void Replace_Preg_With_Symbol (WN* node, WN* replace, WN* def,
03466 WN_OFFSET preg_num, ST* preg_st)
03467 {
03468 if (WN_operator(node) == OPR_BLOCK) {
03469 for (WN* stmt = WN_first(node); stmt; stmt = WN_next(stmt))
03470 Replace_Preg_With_Symbol(stmt, replace, def, preg_num, preg_st);
03471 }
03472 else if (WN_operator(node) == OPR_LDID) {
03473 if (ST_class(WN_st(node)) == CLASS_PREG &&
03474 WN_st(node) == preg_st &&
03475 WN_offset(node) == preg_num) {
03476 WN* parent = LWN_Get_Parent(node);
03477 INT kid = 0;
03478 WN *ldid = LWN_Copy_Tree(replace);
03479 for (; kid < WN_kid_count(parent); kid ++)
03480 if (WN_kid(parent, kid) == node) break;
03481 WN_kid(parent, kid) = ldid;
03482 Du_Mgr->Add_Def_Use(def, ldid);
03483
03484
03485 DEF_LIST *def_list = Du_Mgr->Ud_Get_Def(node);
03486 DEF_LIST_ITER iter(def_list);
03487 const DU_NODE *du_node = iter.First();
03488 const DU_NODE *next;
03489 Is_True(!iter.Is_Empty(),("Empty def list in Delete_Def_Use"));
03490 for(next = iter.Next(); du_node; du_node=next, next=iter.Next()){
03491 WN *def_node = (WN *) du_node->Wn();
03492
03493
03494 Du_Mgr->Add_Def_Use(def_node, WN_kid0(def));
03495 Du_Mgr->Delete_Def_Use(def_node,node);
03496 }
03497 LWN_Delete_Tree(node);
03498 }
03499 }
03500
03501 else
03502 for (INT kid = 0; kid < WN_kid_count(node); kid ++)
03503 Replace_Preg_With_Symbol(WN_kid(node, kid), replace, def,
03504 preg_num, preg_st);
03505 }
03506 #endif
03507
03508
03509
03510
03511
03512
03513
03514
03515
03516
03517 void
03518 ARA_LOOP_INFO::Generate_Parallel_Pragma()
03519 {
03520 #ifdef KEY
03521 Last_Apo_Loop_Id++;
03522 if (Last_Apo_Loop_Id > LNO_Apo_Loop_Skip_After ||
03523 Last_Apo_Loop_Id < LNO_Apo_Loop_Skip_Before ||
03524 Last_Apo_Loop_Id == LNO_Apo_Loop_Skip_Equal)
03525 return;
03526 #endif
03527
03528
03529 INT parallel_debug_level = Get_Trace(TP_LNOPT2, TT_LNO_PARALLEL_DEBUG)
03530 ? Parallel_Debug_Level : 0;
03531
03532
03533 if (_info->Mp_Info)
03534 return;
03535
03536
03537 DO_LOOP_INFO* dli = Get_Do_Loop_Info(_loop);
03538 #ifdef KEY //bug 14284 : don't parallelize if contains calls to nested functions
03539 if(!dli || dli->Has_Nested_Calls)
03540 return;
03541 #endif
03542 if (dli->Suggested_Parallel && _peel_value == -1) {
03543 dli->Suggested_Parallel = FALSE;
03544 if (Get_Trace(TP_LNOPT2, TT_LNO_PARALLEL_DEBUG))
03545 fprintf(stdout,
03546 "Convex Problem: Not parallelizing %s\n", WB_Whirl_Symbol(_loop));
03547 }
03548
03549 if (Is_Parallel()) {
03550
03551 if (!Get_Trace(TP_LNOPT2, TT_LNO_NO_AUTO_PARALLEL)
03552 && !_info->Suggested_Parallel)
03553 DevWarn("Auto-parallelizing unexpected loop %s at %d",
03554 WB_Whirl_Symbol(_loop), (INT) WN_linenum(_loop));
03555
03556 _info->Auto_Parallelized = TRUE;
03557 if (Has_Last_Value_Array()) {
03558 Generate_Copyout_Loop();
03559 return;
03560 }
03561 WN *if_cond = NULL;
03562
03563 if (LNO_Run_AP==1 && !_info->Pragma_Prefer_Concurrentize) {
03564 if_cond = Create_IF_Clause(FALSE);
03565 if (if_cond && WN_operator(if_cond) == OPR_INTCONST) {
03566 if (WN_const_val(if_cond) == 0) {
03567 LWN_Delete_Tree(if_cond);
03568 DO_LOOP_INFO* dli = Get_Do_Loop_Info(_loop);
03569 dli->Suggested_Parallel = FALSE;
03570 dli->Not_Enough_Parallel_Work = TRUE;
03571 dli->Auto_Parallelized = FALSE;
03572 if (LNO_Verbose || parallel_debug_level >= 1) {
03573 Print_Non_Parallel_Loop(stdout, _loop);
03574 Print_Non_Parallel_Loop(TFile, _loop);
03575 }
03576 return;
03577 } else {
03578 LWN_Delete_Tree(if_cond);
03579 if_cond = NULL;
03580 }
03581 }
03582 }
03583
03584 if (_peel_value > 0) {
03585 Last_Value_Peeling_On();
03586 Post_loop_peeling(_loop, _peel_value, TRUE);
03587 Last_Value_Peeling_Off();
03588 }
03589
03590 WN * interleave = NULL;
03591 if (Variable_Load()) {
03592 interleave = WN_CreatePragma(WN_PRAGMA_MPSCHEDTYPE,
03593 ST_IDX_ZERO,
03594 (INT32) WN_PRAGMA_SCHEDTYPE_INTERLEAVE,
03595 0);
03596 WN_set_pragma_compiler_generated(interleave);
03597 }
03598
03599 WN * parent_block = LWN_Get_Parent(_loop);
03600 WN * wn_after_loop = WN_next(_loop);
03601 RID *p_rid = Get_Enclosing_Region_ID(_loop);
03602 FmtAssert(p_rid, ("ARA_LOOP_INFO::Generate_Parallel_Pragma: can't find parent RID"));
03603
03604 WN * do_loop = LWN_Extract_From_Block(_loop);
03605
03606
03607 WN * region = WN_CreateRegion(REGION_KIND_MP,do_loop,NULL,NULL,
03608 RID_CREATE_NEW_ID,(INITO_IDX) NULL);
03609 if (Prompf_Info != NULL && Prompf_Info->Is_Enabled()) {
03610 INT loop_id = WN_MAP32_Get(Prompf_Id_Map, do_loop);
03611 WN_MAP32_Set(Prompf_Id_Map, region, loop_id);
03612 }
03613 REGION_INFO* rgi = CXX_NEW(REGION_INFO(TRUE), &LNO_default_pool);
03614 WN_MAP_Set(LNO_Info_Map, region, (void *) rgi);
03615
03616
03617 WN *prag = WN_CreatePragma(WN_PRAGMA_PARALLEL_DO, ST_IDX_ZERO, 0, 1);
03618 WN_set_pragma_compiler_generated(prag);
03619 if (Prompf_Info != NULL && Prompf_Info->Is_Enabled()) {
03620 INT loop_id = WN_MAP32_Get(Prompf_Id_Map, do_loop);
03621 WN_MAP32_Set(Prompf_Id_Map, prag, loop_id);
03622 }
03623
03624 WN_Set_Linenum(prag, WN_Get_Linenum(_loop));
03625 LWN_Insert_Block_Before(WN_region_pragmas(region),NULL,prag);
03626
03627 if (if_cond != NULL) {
03628 prag = WN_CreateXpragma(WN_PRAGMA_IF, ST_IDX_ZERO, 1);
03629 WN_kid0(prag) = if_cond;
03630 LWN_Insert_Block_Before(WN_region_pragmas(region), NULL, prag);
03631 }
03632
03633 if (interleave != NULL) {
03634 LWN_Insert_Block_Before(WN_region_pragmas(region), NULL, interleave);
03635 }
03636
03637 INT i;
03638 for (i = 0; i < _pri.Elements(); ++i) {
03639 if (_pri.Bottom_nth(i)->Is_Loop_Invariant() &&
03640 !_pri.Bottom_nth(i)->Is_Unknown_Size()) {
03641 if (_pri.Bottom_nth(i)->Need_Last_Value()) {
03642 prag = WN_CreatePragma(WN_PRAGMA_LASTLOCAL,
03643 _pri.Bottom_nth(i)->Array().St(),
03644 _pri.Bottom_nth(i)->Array().WN_Offset(), 0);
03645 WN_set_pragma_compiler_generated(prag);
03646 } else {
03647 prag = WN_CreatePragma(WN_PRAGMA_LOCAL,
03648 _pri.Bottom_nth(i)->Array().St(),
03649 _pri.Bottom_nth(i)->Array().WN_Offset(), 0);
03650 WN_set_pragma_compiler_generated(prag);
03651 }
03652 } else {
03653 prag = WN_CreatePragma(WN_PRAGMA_SHARED,
03654 _pri.Bottom_nth(i)->Array().St(),
03655 _pri.Bottom_nth(i)->Array().WN_Offset(), 0);
03656 WN_set_pragma_compiler_generated(prag);
03657 }
03658 WN_Set_Linenum(prag, WN_Get_Linenum(_loop));
03659 LWN_Insert_Block_Before(WN_region_pragmas(region),NULL,prag);
03660 }
03661
03662 for (i = 0; i < _scalar_pri.Elements(); ++i) {
03663 if (_scalar_last_value.Bottom_nth(i)) {
03664 prag = WN_CreatePragma(WN_PRAGMA_LASTLOCAL,
03665 _scalar_pri.Bottom_nth(i)->_scalar.St(),
03666 _scalar_pri.Bottom_nth(i)->_scalar.WN_Offset(), 0);
03667 WN_set_pragma_compiler_generated(prag);
03668 }
03669 else {
03670 prag = WN_CreatePragma(WN_PRAGMA_LOCAL,
03671 _scalar_pri.Bottom_nth(i)->_scalar.St(),
03672 _scalar_pri.Bottom_nth(i)->_scalar.WN_Offset(), 0);
03673 WN_set_pragma_compiler_generated(prag);
03674 }
03675
03676 WN_Set_Linenum(prag, WN_Get_Linenum(_loop));
03677 LWN_Insert_Block_Before(WN_region_pragmas(region), NULL, prag);
03678 }
03679
03680 for (i = 0; i < _use.Elements(); ++i) {
03681 if (Overlap_Local_Array(_use.Bottom_nth(i)->Array(), _use.Bottom_nth(i)->Offset()))
03682 FmtAssert(FALSE,("ARA_LOOP_INFO::Generate_Parallel_Pragma, exposed use overlaps with local array, need renaming"));
03683 prag = WN_CreatePragma(WN_PRAGMA_SHARED,
03684 _use.Bottom_nth(i)->Array().St(),
03685 _use.Bottom_nth(i)->Array().WN_Offset(), 0);
03686 WN_set_pragma_compiler_generated(prag);
03687 WN_Set_Linenum(prag, WN_Get_Linenum(_loop));
03688 LWN_Insert_Block_Before(WN_region_pragmas(region), NULL, prag);
03689 }
03690
03691 for (i = 0; i < _scalar_use.Elements(); ++ i) {
03692 if (Overlap_Local_Scalar(_scalar_use.Bottom_nth(i)->_scalar))
03693 FmtAssert(FALSE,("ARA_LOOP_INFO::Generate_Parallel_Pragma, exposed scalar use overlaps with local scalar, something is wrong"));
03694 if (!Overlap_Reduction_Scalar(_scalar_use.Bottom_nth(i)->_scalar)) {
03695 #ifdef KEY
03696
03697 if (ST_class(_scalar_use.Bottom_nth(i)->_scalar.St()) == CLASS_PREG &&
03698 _scalar_use.Bottom_nth(i)->_scalar.WN_Offset() < 0)
03699 continue;
03700
03701
03702 if (ST_class(_scalar_use.Bottom_nth(i)->_scalar.St()) == CLASS_PREG) {
03703 TYPE_ID rtype = _scalar_use.Bottom_nth(i)->_scalar.Type;
03704 ST * comma_st = Gen_Temp_Symbol (MTYPE_TO_TY_array[rtype], "_ubtmp");
03705 OPCODE ldid_opc = OPCODE_make_op(OPR_LDID,Promote_Type(rtype),rtype);
03706 WN_OFFSET preg_num = _scalar_use.Bottom_nth(i)->_scalar.WN_Offset();
03707 ST * preg_st = _scalar_use.Bottom_nth(i)->_scalar.St();
03708 WN * ldid = WN_CreateLdid(ldid_opc, preg_num, preg_st,
03709 Be_Type_Tbl(rtype));
03710 WN * stid = WN_Stid (rtype, 0, comma_st, WN_ty (ldid), ldid);
03711 WN_Set_Linenum (stid, WN_Get_Linenum(_loop));
03712 LWN_Parentize(stid);
03713 LWN_Insert_Block_Before (parent_block, wn_after_loop, stid);
03714 LWN_Set_Parent(stid, parent_block);
03715 WN *replace = WN_Ldid (rtype, 0, comma_st, WN_ty (ldid));
03716 Replace_Preg_With_Symbol(_loop, replace, stid,
03717 preg_num, preg_st);
03718 prag = WN_CreatePragma(WN_PRAGMA_SHARED,
03719 WN_st(replace),
03720 WN_offset(replace), 0);
03721 WN_set_pragma_compiler_generated(prag);
03722 WN_Set_Linenum(prag, WN_Get_Linenum(_loop));
03723 LWN_Insert_Block_Before(WN_region_pragmas(region), NULL, prag);
03724
03725 DOLOOP_STACK dostack(&ARA_memory_pool);
03726 Build_Doloop_Stack(parent_block, &dostack);
03727 LNO_Build_Access(_loop, &dostack, &LNO_default_pool);
03728 continue;
03729 }
03730 #endif
03731 prag = WN_CreatePragma(WN_PRAGMA_SHARED,
03732 _scalar_use.Bottom_nth(i)->_scalar.St(),
03733 _scalar_use.Bottom_nth(i)->_scalar.WN_Offset(), 0);
03734 WN_set_pragma_compiler_generated(prag);
03735 WN_Set_Linenum(prag, WN_Get_Linenum(_loop));
03736 LWN_Insert_Block_Before(WN_region_pragmas(region), NULL, prag);
03737 }
03738 }
03739
03740 for (i = 0; i < _def.Elements(); ++ i) {
03741 ARA_REF *cur = _def.Bottom_nth(i);
03742 if (!Overlap_Local_Array(cur->Array(), cur->Offset()) &&
03743 !Overlap_Exposed_Array(cur->Array(), cur->Offset())) {
03744 if (cur->Is_Loop_Invariant() && !cur->Is_Unknown_Size()) {
03745 prag = WN_CreatePragma(WN_PRAGMA_LASTLOCAL,
03746 cur->Array().St(), cur->Array().WN_Offset(), 0);
03747 } else {
03748 prag = WN_CreatePragma(WN_PRAGMA_SHARED,
03749 cur->Array().St(), cur->Array().WN_Offset(), 0);
03750 }
03751 WN_set_pragma_compiler_generated(prag);
03752 WN_Set_Linenum(prag, WN_Get_Linenum(_loop));
03753 LWN_Insert_Block_Before(WN_region_pragmas(region), NULL, prag);
03754 }
03755 }
03756
03757 for (i = 0; i < _scalar_def.Elements(); ++ i) {
03758 if (!Overlap_Local_Scalar(_scalar_def.Bottom_nth(i)->_scalar) &&
03759 !Overlap_Exposed_Scalar(_scalar_def.Bottom_nth(i)->_scalar)) {
03760 prag = WN_CreatePragma(WN_PRAGMA_LASTLOCAL,
03761 _scalar_def.Bottom_nth(i)->_scalar.St(),
03762 _scalar_def.Bottom_nth(i)->_scalar.WN_Offset(), 0);
03763 WN_set_pragma_compiler_generated(prag);
03764 WN_Set_Linenum(prag, WN_Get_Linenum(_loop));
03765 LWN_Insert_Block_Before(WN_region_pragmas(region), NULL, prag);
03766 }
03767 }
03768
03769 for (i = 0; i < _scalar_may_def.Elements(); ++ i) {
03770 if (!Overlap_Local_Scalar(_scalar_may_def.Bottom_nth(i)->_scalar) &&
03771 !Overlap_Exposed_Scalar(_scalar_may_def.Bottom_nth(i)->_scalar) &&
03772 !Overlap_Kill_Scalar(_scalar_may_def.Bottom_nth(i)->_scalar) &&
03773 !Overlap_Reduction_Scalar(_scalar_may_def.Bottom_nth(i)->_scalar)) {
03774 prag = WN_CreatePragma(WN_PRAGMA_SHARED,
03775 _scalar_may_def.Bottom_nth(i)->_scalar.St(),
03776 _scalar_may_def.Bottom_nth(i)->_scalar.WN_Offset(), 0);
03777 WN_set_pragma_compiler_generated(prag);
03778 WN_Set_Linenum(prag, WN_Get_Linenum(_loop));
03779 LWN_Insert_Block_Before(WN_region_pragmas(region), NULL, prag);
03780 }
03781 }
03782
03783 for (i = 0; i < _reduction.Elements(); ++i) {
03784 WN* cur_wn = _reduction.Bottom_nth(i);
03785 if (WN_operator(cur_wn) == OPR_ISTORE) {
03786 WN* wn_array = WN_kid1(cur_wn);
03787 prag = WN_CreateXpragma(WN_PRAGMA_REDUCTION, ST_IDX_ZERO, 1);
03788 WN_kid0(prag) = LWN_Copy_Tree(wn_array);
03789 LWN_Copy_Def_Use(wn_array, WN_kid0(prag), Du_Mgr);
03790 WN_set_pragma_compiler_generated(prag);
03791 #ifndef KEY // bug 9112 : WN_prefetch_flag overlaps with WN_st_idx, so is bad
03792 WN_prefetch_flag(prag) = WN_offset(cur_wn);
03793 #else
03794 if (WN_offset(cur_wn)) {
03795 TYPE_ID rtype = WN_rtype(WN_kid0(prag));
03796 WN* wn_ofst = LWN_Make_Icon(rtype, WN_offset(cur_wn));
03797 OPCODE addop = OPCODE_make_op(OPR_ADD, rtype, MTYPE_V);
03798 WN_kid0(prag) = LWN_CreateExp2(addop, WN_kid0(prag), wn_ofst);
03799 }
03800 #endif
03801 Set_Reduction_Array_Base_is_shared_auto(wn_array);
03802 } else {
03803 prag = WN_CreatePragma(WN_PRAGMA_REDUCTION, WN_st(cur_wn),
03804 WN_offset(cur_wn),0);
03805 WN_set_pragma_compiler_generated(prag);
03806 if (WN_sclass(cur_wn) == SCLASS_AUTO)
03807 Set_ST_is_shared_auto(*WN_st(cur_wn));
03808 }
03809 WN_pragma_arg2(prag) = REDUCTION_TYPE_to_OPERATOR(
03810 red_manager->Which_Reduction(cur_wn));
03811 WN_Set_Linenum(prag, WN_Get_Linenum(_loop));
03812 LWN_Insert_Block_Before(WN_region_pragmas(region), NULL, prag);
03813 }
03814
03815 if (dli->Is_Doacross) {
03816 prag = WN_CreatePragma(WN_PRAGMA_SYNC_DOACROSS, ST_IDX_ZERO, 0, 0);
03817 WN_set_pragma_compiler_generated(prag);
03818 WN_Set_Linenum(prag, WN_Get_Linenum(_loop));
03819 LWN_Insert_Block_After(WN_region_pragmas(region),
03820 WN_first(WN_region_pragmas(region)), prag);
03821 }
03822
03823
03824 RID *rid = RID_Create(WN_region_id(region),RID_depth(p_rid)+1,region);
03825
03826 RID_level(rid) = RL_LNO;
03827 RID_TYPE_mp_Set(rid);
03828 WN_MAP_Set(RID_map,region,(void *)rid);
03829
03830 RID_Add_kid(rid, p_rid);
03831
03832
03833 LWN_Parentize(region);
03834 LWN_Insert_Block_Before(parent_block, wn_after_loop, region);
03835
03836 if (dli->Is_Doacross) {
03837 WN* wn_comment=
03838 WN_CreateComment(
03839 "A doacross loop with synchronization is generated for the following loop"
03840 );
03841 LWN_Insert_Block_Before(parent_block, region, wn_comment);
03842 }
03843
03844 DOLOOP_STACK copy_stack(&ARA_memory_pool);
03845 Build_Doloop_Stack(WN_region_pragmas(region), ©_stack);
03846 LNO_Build_Access(WN_region_pragmas(region), ©_stack,
03847 &LNO_default_pool);
03848
03849
03850 Contains_MP = TRUE;
03851 DO_LOOP_INFO * dli = _info;
03852 MP_INFO * mp_info = CXX_NEW(MP_INFO(MP_SCHED_SIMPLE, FALSE),
03853 &LNO_default_pool);
03854 dli->Mp_Info = mp_info;
03855
03856 if (!PU_has_mp(Get_Current_PU()))
03857 Mp_File_Init();
03858 #ifdef _NEW_SYMTAB
03859 Set_PU_has_mp(Get_Current_PU());
03860 Set_PU_has_region(Get_Current_PU());
03861 Set_PU_uplevel(Get_Current_PU());
03862 #else
03863 Set_SYMTAB_has_mp(Current_Symtab);
03864 Set_SYMTAB_has_rgn(Current_Symtab);
03865 Set_SYMTAB_uplevel(Current_Symtab);
03866 #endif
03867
03868 Set_Enclosing_If_Has_Region(region);
03869 if (Index_Variable_Live_At_Exit(_loop)) {
03870 WN* wn_region = LWN_Get_Parent(LWN_Get_Parent(_loop));
03871 WN* wn_first = WN_first(WN_region_pragmas(wn_region));
03872 SYMBOL sym_index(WN_index(_loop));
03873 for (WN* wn = wn_first; wn != NULL; wn = WN_next(wn)) {
03874 if (WN_pragma(wn) == WN_PRAGMA_LOCAL && sym_index.St()
03875 == WN_st(wn) && sym_index.WN_Offset() == WN_pragma_arg1(wn)) {
03876 WN_pragma(wn) = WN_PRAGMA_LASTLOCAL;
03877 WN_set_pragma_compiler_generated(wn);
03878 }
03879 }
03880 }
03881
03882 } else {
03883 if (Is_OK_Parallel())
03884 DevWarn("Heuristic prefers INNER parallel loop to loop %s at %d",
03885 WB_Whirl_Symbol(_loop), (INT) WN_linenum(_loop));
03886 for (INT i = 0; i < _children.Elements(); ++i)
03887 _children.Bottom_nth(i)->Generate_Parallel_Pragma();
03888 }
03889 }
03890
03891
03892
03893
03894
03895
03896
03897
03898
03899
03900
03901
03902
03903
03904
03905
03906
03907
03908
03909
03910
03911
03912 void
03913 ARA_LOOP_INFO::Generate_Copyout_Loop()
03914 {
03915
03916 INT parallel_debug_level = Get_Trace(TP_LNOPT2, TT_LNO_PARALLEL_DEBUG)
03917 ? Parallel_Debug_Level : 0;
03918
03919 WN *if_cond = NULL;
03920 if (LNO_Run_AP==1) {
03921 if_cond = Create_IF_Clause(TRUE);
03922 if (if_cond && WN_operator(if_cond) == OPR_INTCONST) {
03923 if (WN_const_val(if_cond) == 0) {
03924 LWN_Delete_Tree(if_cond);
03925 DO_LOOP_INFO* dli = Get_Do_Loop_Info(_loop);
03926 dli->Suggested_Parallel = FALSE;
03927 dli->Not_Enough_Parallel_Work = TRUE;
03928 dli->Auto_Parallelized = FALSE;
03929 if (LNO_Verbose || parallel_debug_level >= 1) {
03930 Print_Non_Parallel_Loop(stdout, _loop);
03931 Print_Non_Parallel_Loop(TFile, _loop);
03932 }
03933 return;
03934 } else {
03935 LWN_Delete_Tree(if_cond);
03936 if_cond = NULL;
03937 }
03938 }
03939 }
03940
03941 if (_peel_value > 0) {
03942 Last_Value_Peeling_On();
03943 Post_loop_peeling(_loop, _peel_value, TRUE);
03944 Last_Value_Peeling_Off();
03945 }
03946
03947 WN * interleave = NULL;
03948 if (Variable_Load()) {
03949 interleave = WN_CreatePragma(WN_PRAGMA_MPSCHEDTYPE,
03950 ST_IDX_ZERO,
03951 (INT32) WN_PRAGMA_SCHEDTYPE_INTERLEAVE,
03952 0);
03953 WN_set_pragma_compiler_generated(interleave);
03954 }
03955
03956 WN * parent_block = LWN_Get_Parent(_loop);
03957 WN * wn_after_loop = WN_next(_loop);
03958 RID *p_rid = Get_Enclosing_Region_ID(_loop);
03959 FmtAssert(p_rid, ("ARA_LOOP_INFO::Generate_Parallel_Pragma: can't find parent RID"));
03960
03961 WN * do_loop = LWN_Extract_From_Block(_loop);
03962
03963
03964 WN * region = WN_CreateRegion(REGION_KIND_MP,do_loop,NULL,NULL,
03965 RID_CREATE_NEW_ID,
03966 (INITO_IDX) NULL);
03967 if (Prompf_Info != NULL && Prompf_Info->Is_Enabled()) {
03968 INT old_id = WN_MAP32_Get(Prompf_Id_Map, do_loop);
03969 INT new_id = New_Construct_Id();
03970 WN_MAP32_Set(Prompf_Id_Map, region, new_id);
03971 Prompf_Info->Parallel_Region(old_id, new_id);
03972 }
03973 REGION_INFO* rgi = CXX_NEW(REGION_INFO(TRUE), &LNO_default_pool);
03974 WN_MAP_Set(LNO_Info_Map, region, (void *) rgi);
03975
03976
03977 WN *prag = WN_CreatePragma(WN_PRAGMA_PARALLEL_BEGIN, ST_IDX_ZERO, 0, 0);
03978 WN_set_pragma_compiler_generated(prag);
03979 WN_Set_Linenum(prag, WN_Get_Linenum(_loop));
03980 LWN_Insert_Block_Before(WN_region_pragmas(region),NULL,prag);
03981 if (Prompf_Info != NULL && Prompf_Info->Is_Enabled())
03982 WN_MAP32_Set(Prompf_Id_Map, prag, WN_MAP32_Get(Prompf_Id_Map, region));
03983
03984 if (if_cond != NULL) {
03985 prag = WN_CreateXpragma(WN_PRAGMA_IF, ST_IDX_ZERO, 1);
03986 WN_kid0(prag) = if_cond;
03987 LWN_Insert_Block_Before(WN_region_pragmas(region), NULL, prag);
03988 }
03989
03990
03991
03992 INT i;
03993 for (i = 0; i < _pri.Elements(); ++i) {
03994 if (_pri.Bottom_nth(i)->Is_Loop_Invariant() &&
03995 !_pri.Bottom_nth(i)->Is_Unknown_Size()) {
03996 if (_pri.Bottom_nth(i)->Need_Last_Value()) {
03997 prag = WN_CreatePragma(WN_PRAGMA_SHARED,
03998 _pri.Bottom_nth(i)->Array().St(),
03999 _pri.Bottom_nth(i)->Array().WN_Offset(), 0);
04000 } else {
04001 prag = WN_CreatePragma(WN_PRAGMA_LOCAL,
04002 _pri.Bottom_nth(i)->Array().St(),
04003 _pri.Bottom_nth(i)->Array().WN_Offset(), 0);
04004 }
04005 WN_set_pragma_compiler_generated(prag);
04006 WN_Set_Linenum(prag, WN_Get_Linenum(_loop));
04007 LWN_Insert_Block_Before(WN_region_pragmas(region),NULL,prag);
04008 }
04009 }
04010
04011 for (i = 0; i < _scalar_pri.Elements(); ++i) {
04012 if (_scalar_last_value.Bottom_nth(i)) {
04013 prag = WN_CreatePragma(WN_PRAGMA_SHARED,
04014 _scalar_pri.Bottom_nth(i)->_scalar.St(),
04015 _scalar_pri.Bottom_nth(i)->_scalar.WN_Offset(), 0);
04016 } else{
04017 prag = WN_CreatePragma(WN_PRAGMA_LOCAL,
04018 _scalar_pri.Bottom_nth(i)->_scalar.St(),
04019 _scalar_pri.Bottom_nth(i)->_scalar.WN_Offset(), 0);
04020 }
04021 WN_set_pragma_compiler_generated(prag);
04022 WN_Set_Linenum(prag, WN_Get_Linenum(_loop));
04023 LWN_Insert_Block_Before(WN_region_pragmas(region), NULL, prag);
04024 }
04025
04026 for (i = 0; i < _use.Elements(); ++i) {
04027 if (Overlap_Local_Array(_use.Bottom_nth(i)->Array(),
04028 _use.Bottom_nth(i)->Offset()))
04029 FmtAssert(FALSE,("ARA_LOOP_INFO::Generate_Parallel_Pragma, exposed use overlaps with local array, need renaming"));
04030 prag = WN_CreatePragma(WN_PRAGMA_SHARED,
04031 _use.Bottom_nth(i)->Array().St(),
04032 _use.Bottom_nth(i)->Array().WN_Offset(), 0);
04033 WN_set_pragma_compiler_generated(prag);
04034 WN_Set_Linenum(prag, WN_Get_Linenum(_loop));
04035 LWN_Insert_Block_Before(WN_region_pragmas(region), NULL, prag);
04036 }
04037
04038 for (i = 0; i < _scalar_use.Elements(); ++ i) {
04039 if (Overlap_Local_Scalar(_scalar_use.Bottom_nth(i)->_scalar))
04040 FmtAssert(FALSE,("ARA_LOOP_INFO::Generate_Parallel_Pragma, exposed scalar use overlaps with local scalar, something is wrong"));
04041 if (!Overlap_Reduction_Scalar(_scalar_use.Bottom_nth(i)->_scalar)) {
04042 prag = WN_CreatePragma(WN_PRAGMA_SHARED,
04043 _scalar_use.Bottom_nth(i)->_scalar.St(),
04044 _scalar_use.Bottom_nth(i)->_scalar.WN_Offset(), 0);
04045 WN_set_pragma_compiler_generated(prag);
04046 WN_Set_Linenum(prag, WN_Get_Linenum(_loop));
04047 LWN_Insert_Block_Before(WN_region_pragmas(region), NULL, prag);
04048 }
04049 }
04050
04051 for (i = 0; i < _def.Elements(); ++ i) {
04052 prag = WN_CreatePragma(WN_PRAGMA_SHARED,
04053 _def.Bottom_nth(i)->Array().St(),
04054 _def.Bottom_nth(i)->Array().WN_Offset(), 0);
04055 WN_set_pragma_compiler_generated(prag);
04056 WN_Set_Linenum(prag, WN_Get_Linenum(_loop));
04057 LWN_Insert_Block_Before(WN_region_pragmas(region), NULL, prag);
04058 }
04059
04060 for (i = 0; i < _scalar_def.Elements(); ++ i) {
04061 if (!Overlap_Local_Scalar(_scalar_def.Bottom_nth(i)->_scalar) &&
04062 !Overlap_Exposed_Scalar(_scalar_def.Bottom_nth(i)->_scalar) &&
04063 !Overlap_Reduction_Scalar(_scalar_def.Bottom_nth(i)->_scalar)) {
04064 prag = WN_CreatePragma(WN_PRAGMA_SHARED,
04065 _scalar_def.Bottom_nth(i)->_scalar.St(),
04066 _scalar_def.Bottom_nth(i)->_scalar.WN_Offset(), 0);
04067 WN_set_pragma_compiler_generated(prag);
04068 WN_Set_Linenum(prag, WN_Get_Linenum(_loop));
04069 LWN_Insert_Block_Before(WN_region_pragmas(region), NULL, prag);
04070 }
04071 }
04072
04073 for (i = 0; i < _scalar_may_def.Elements(); ++ i) {
04074 if (!Overlap_Local_Scalar(_scalar_may_def.Bottom_nth(i)->_scalar) &&
04075 !Overlap_Exposed_Scalar(_scalar_may_def.Bottom_nth(i)->_scalar) &&
04076 !Overlap_Kill_Scalar(_scalar_may_def.Bottom_nth(i)->_scalar) &&
04077 !Overlap_Reduction_Scalar(_scalar_may_def.Bottom_nth(i)->_scalar)) {
04078 prag = WN_CreatePragma(WN_PRAGMA_SHARED,
04079 _scalar_may_def.Bottom_nth(i)->_scalar.St(),
04080 _scalar_may_def.Bottom_nth(i)->_scalar.WN_Offset(), 0);
04081 WN_set_pragma_compiler_generated(prag);
04082 WN_Set_Linenum(prag, WN_Get_Linenum(_loop));
04083 LWN_Insert_Block_Before(WN_region_pragmas(region), NULL, prag);
04084 }
04085 }
04086
04087
04088
04089
04090 for (i = 0; i < _reduction.Elements(); ++i) {
04091 WN* cur_wn = _reduction.Bottom_nth(i);
04092 if (WN_operator(cur_wn) == OPR_ISTORE) {
04093 WN* wn_array = WN_kid1(cur_wn);
04094 prag = WN_CreatePragma(WN_PRAGMA_SHARED,
04095 Find_Reduction_Array_Base(wn_array), WN_offset(cur_wn), 0);
04096 } else {
04097 prag = WN_CreatePragma(WN_PRAGMA_SHARED, WN_st(cur_wn),
04098 WN_offset(cur_wn),0);
04099 }
04100 WN_set_pragma_compiler_generated(prag);
04101 WN_Set_Linenum(prag, WN_Get_Linenum(_loop));
04102 LWN_Insert_Block_Before(WN_region_pragmas(region), NULL, prag);
04103 }
04104
04105 if (Get_Do_Loop_Info(_loop)->Is_Doacross) {
04106 prag = WN_CreatePragma(WN_PRAGMA_SYNC_DOACROSS, ST_IDX_ZERO, 0, 0);
04107 WN_set_pragma_compiler_generated(prag);
04108 WN_Set_Linenum(prag, WN_Get_Linenum(_loop));
04109 LWN_Insert_Block_After(WN_region_pragmas(region),
04110 WN_first(WN_region_pragmas(region)), prag);
04111 }
04112
04113
04114 RID *rid = RID_Create(WN_region_id(region),RID_depth(p_rid)+1,region);
04115
04116 RID_level(rid) = RL_LNO;
04117 RID_TYPE_mp_Set(rid);
04118 WN_MAP_Set(RID_map,region,(void *)rid);
04119
04120 RID_Add_kid(rid, p_rid);
04121
04122
04123 LWN_Parentize(region);
04124 LWN_Insert_Block_Before(parent_block, wn_after_loop, region);
04125
04126 if (Get_Do_Loop_Info(_loop)->Is_Doacross) {
04127 WN* wn_comment= WN_CreateComment(
04128 "A doacross loop with synchronization is generated for the following loop");
04129 LWN_Insert_Block_Before(parent_block, region, wn_comment);
04130 }
04131
04132
04133 Last_Value_Peeling_On();
04134 Post_loop_peeling(_loop, 1);
04135 Last_Value_Peeling_Off();
04136
04137
04138
04139 parent_block = LWN_Get_Parent(_loop);
04140 wn_after_loop = WN_next(_loop);
04141 p_rid = Get_Enclosing_Region_ID(_loop);
04142 FmtAssert(p_rid, ("ARA_LOOP_INFO::Generate_Parallel_Pragma: can't find parent RID"));
04143
04144 do_loop = LWN_Extract_From_Block(_loop);
04145
04146
04147 region = WN_CreateRegion(REGION_KIND_MP,do_loop,NULL,NULL,
04148 RID_CREATE_NEW_ID,
04149 (INITO_IDX) NULL);
04150 if (Prompf_Info != NULL && Prompf_Info->Is_Enabled()) {
04151 INT loop_id = WN_MAP32_Get(Prompf_Id_Map, do_loop);
04152 WN_MAP32_Set(Prompf_Id_Map, region, loop_id);
04153 }
04154 rgi = CXX_NEW(REGION_INFO(TRUE), &LNO_default_pool);
04155 WN_MAP_Set(LNO_Info_Map, region, (void *) rgi);
04156
04157
04158 prag = WN_CreatePragma(WN_PRAGMA_PDO_BEGIN, ST_IDX_ZERO, 0, 0);
04159 if (Prompf_Info != NULL && Prompf_Info->Is_Enabled()) {
04160 INT loop_id = WN_MAP32_Get(Prompf_Id_Map, do_loop);
04161 WN_MAP32_Set(Prompf_Id_Map, prag, loop_id);
04162 }
04163 WN_set_pragma_compiler_generated(prag);
04164 WN_Set_Linenum(prag, WN_Get_Linenum(_loop));
04165 LWN_Insert_Block_Before(WN_region_pragmas(region),NULL,prag);
04166
04167 if (interleave != NULL) {
04168 LWN_Insert_Block_Before(WN_region_pragmas(region), NULL, interleave);
04169 }
04170
04171 for (i = 0; i < _pri.Elements(); ++i) {
04172 if (_pri.Bottom_nth(i)->Is_Loop_Invariant() &&
04173 !_pri.Bottom_nth(i)->Is_Unknown_Size()) {
04174 prag = WN_CreatePragma(WN_PRAGMA_LOCAL,
04175 _pri.Bottom_nth(i)->Array().St(),
04176 _pri.Bottom_nth(i)->Array().WN_Offset(), 0);
04177 WN_set_pragma_compiler_generated(prag);
04178 WN_Set_Linenum(prag, WN_Get_Linenum(_loop));
04179 LWN_Insert_Block_Before(WN_region_pragmas(region),NULL,prag);
04180 }
04181 }
04182
04183 for (i = 0; i < _def.Elements(); ++ i) {
04184 ARA_REF *cur = _def.Bottom_nth(i);
04185 if (!Overlap_Local_Array(cur->Array(), cur->Offset()) &&
04186 !Overlap_Exposed_Array(cur->Array(),cur->Offset()) &&
04187 cur->Is_Loop_Invariant() && !cur->Is_Unknown_Size()) {
04188 prag = WN_CreatePragma(WN_PRAGMA_LOCAL,
04189 cur->Array().St(), cur->Array().WN_Offset(), 0);
04190 WN_set_pragma_compiler_generated(prag);
04191 WN_Set_Linenum(prag, WN_Get_Linenum(_loop));
04192 LWN_Insert_Block_Before(WN_region_pragmas(region), NULL, prag);
04193 }
04194 }
04195
04196 for (i = 0; i < _scalar_pri.Elements(); ++i) {
04197 if (_scalar_last_value.Bottom_nth(i)) {
04198 prag = WN_CreatePragma(WN_PRAGMA_LOCAL,
04199 _scalar_pri.Bottom_nth(i)->_scalar.St(),
04200 _scalar_pri.Bottom_nth(i)->_scalar.WN_Offset(), 0);
04201 WN_set_pragma_compiler_generated(prag);
04202 WN_Set_Linenum(prag, WN_Get_Linenum(_loop));
04203 LWN_Insert_Block_Before(WN_region_pragmas(region), NULL, prag);
04204 }
04205 }
04206
04207 for (i = 0; i < _reduction.Elements(); ++i) {
04208 WN* cur_wn = _reduction.Bottom_nth(i);
04209 if (WN_operator(cur_wn) == OPR_ISTORE) {
04210 WN* wn_array = WN_kid1(cur_wn);
04211 prag = WN_CreateXpragma(WN_PRAGMA_REDUCTION, ST_IDX_ZERO, 1);
04212 WN_kid0(prag) = LWN_Copy_Tree(wn_array);
04213 LWN_Copy_Def_Use(wn_array, WN_kid0(prag), Du_Mgr);
04214 #ifndef KEY // bug 9112 : WN_prefetch_flag overlaps with WN_st_idx, so is bad
04215 WN_prefetch_flag(prag) = WN_offset(cur_wn);
04216 #else
04217 if (WN_offset(cur_wn)) {
04218 TYPE_ID rtype = WN_rtype(WN_kid0(prag));
04219 WN* wn_ofst = LWN_Make_Icon(rtype, WN_offset(cur_wn));
04220 OPCODE addop = OPCODE_make_op(OPR_ADD, rtype, MTYPE_V);
04221 WN_kid0(prag) = LWN_CreateExp2(addop, WN_kid0(prag), wn_ofst);
04222 }
04223 #endif
04224 Set_Reduction_Array_Base_is_shared_auto(wn_array);
04225 } else {
04226 prag = WN_CreatePragma(WN_PRAGMA_REDUCTION, WN_st(cur_wn),
04227 WN_offset(cur_wn),0);
04228 if (WN_sclass(cur_wn) == SCLASS_AUTO)
04229 Set_ST_is_shared_auto(*WN_st(cur_wn));
04230 }
04231 WN_set_pragma_compiler_generated(prag);
04232 WN_pragma_arg2(prag) = REDUCTION_TYPE_to_OPERATOR(
04233 red_manager->Which_Reduction(cur_wn));
04234 WN_Set_Linenum(prag, WN_Get_Linenum(_loop));
04235 LWN_Insert_Block_Before(WN_region_pragmas(region), NULL, prag);
04236 }
04237
04238
04239 if (!_reduction.Elements() && !Index_Variable_Live_At_Exit(_loop) &&
04240 !Get_Do_Loop_Info(_loop)->Is_Doacross) {
04241 prag = WN_CreatePragma(WN_PRAGMA_NOWAIT, ST_IDX_ZERO, 0,0);
04242 WN_set_pragma_compiler_generated(prag);
04243 WN_Set_Linenum(prag, WN_Get_Linenum(_loop));
04244 LWN_Insert_Block_Before(WN_region_pragmas(region), NULL, prag);
04245 }
04246
04247
04248 rid = RID_Create(WN_region_id(region),RID_depth(p_rid)+1,region);
04249
04250 RID_level(rid) = RL_LNO;
04251 RID_TYPE_mp_Set(rid);
04252 WN_MAP_Set(RID_map,region,(void *)rid);
04253
04254 RID_Add_kid(rid, p_rid);
04255
04256
04257 LWN_Parentize(region);
04258 LWN_Insert_Block_Before(parent_block, wn_after_loop, region);
04259
04260 DOLOOP_STACK copy_stack(&ARA_memory_pool);
04261 Build_Doloop_Stack(WN_region_pragmas(region), ©_stack);
04262 LNO_Build_Access(WN_region_pragmas(region), ©_stack,
04263 &LNO_default_pool);
04264
04265
04266 Contains_MP = TRUE;
04267 DO_LOOP_INFO * dli = _info;
04268 MP_INFO * mp_info = CXX_NEW(MP_INFO(MP_SCHED_SIMPLE, TRUE),
04269 &LNO_default_pool);
04270 dli->Mp_Info = mp_info;
04271 dli->No_Fission = TRUE;
04272 dli->No_Fusion = TRUE;
04273 dli->Cannot_Interchange = TRUE;
04274 dli->Cannot_Block = TRUE;
04275 dli->Required_Unroll = 1;
04276
04277 if (!PU_has_mp(Get_Current_PU()))
04278 Mp_File_Init();
04279 #ifdef _NEW_SYMTAB
04280 Set_PU_has_mp(Get_Current_PU());
04281 Set_PU_has_region(Get_Current_PU());
04282 Set_PU_uplevel(Get_Current_PU());
04283 #else
04284 Set_SYMTAB_has_mp(Current_Symtab);
04285 Set_SYMTAB_has_rgn(Current_Symtab);
04286 Set_SYMTAB_uplevel(Current_Symtab);
04287 #endif
04288 Create_Single_Region(wn_after_loop, NULL);
04289 Set_Enclosing_If_Has_Region(region);
04290 if (Index_Variable_Live_At_Exit(_loop)) {
04291 WN* wn_inner_region = LWN_Get_Parent(LWN_Get_Parent(_loop));
04292 WN* wn_outer_region = LWN_Get_Parent(LWN_Get_Parent(wn_inner_region));
04293 WN* wn_first = WN_first(WN_region_pragmas(wn_outer_region));
04294 SYMBOL sym_index(WN_index(_loop));
04295 for (WN* wn = wn_first; wn != NULL; wn = WN_next(wn)) {
04296 if (WN_pragma(wn) == WN_PRAGMA_LOCAL && sym_index.St()
04297 == WN_st(wn) && sym_index.WN_Offset() == WN_pragma_arg1(wn)) {
04298 WN_pragma(wn) = WN_PRAGMA_SHARED;
04299 Add_Pragma_To_MP_Region(wn_inner_region, WN_st(wn),
04300 WN_pragma_arg1(wn), WN_PRAGMA_LASTLOCAL, TRUE);
04301 }
04302 }
04303 }
04304 }
04305
04306 BOOL
04307 ARA_LOOP_INFO::Is_Covered(WN *wn)
04308 {
04309 SYMBOL symbol(wn);
04310
04311 INT i;
04312 for (i=0; i<_scalar_use.Elements(); ++i) {
04313 if (symbol == _scalar_use.Bottom_nth(i)->_scalar)
04314 return FALSE;
04315 }
04316
04317 for (i=0; i<_scalar_def.Elements(); ++i)
04318 if (symbol == _scalar_def.Bottom_nth(i)->_scalar) {
04319 return TRUE;
04320 }
04321
04322 return FALSE;
04323 }
04324
04325
04326
04327
04328
04329
04330
04331
04332
04333
04334 BOOL
04335 ARA_LOOP_INFO::Is_Problem_Scalar(WN* wn)
04336 {
04337 DU_MANAGER* du = Du_Mgr;
04338 OPERATOR opr = WN_operator(wn);
04339 if (opr != OPR_LDID && opr != OPR_STID)
04340 return FALSE;
04341
04342 REDUCTION_MANAGER* rm = red_manager;
04343 if (rm != NULL && rm->Which_Reduction(wn) != RED_NONE)
04344 return FALSE;
04345
04346 SYMBOL sym(wn);
04347 INT i;
04348 for (i = 0; i < _scalar_may_def.Elements(); i++)
04349 if (_scalar_may_def.Bottom_nth(i)->_scalar == sym)
04350 break;
04351 if (i == _scalar_may_def.Elements())
04352 return FALSE;
04353 for (i = 0; i < _scalar_use.Elements(); i++)
04354 if (_scalar_use.Bottom_nth(i)->_scalar == sym)
04355 break;
04356 if (i < _scalar_use.Elements())
04357 return TRUE;
04358 for (i = 0; i < _scalar_def.Elements(); i++)
04359 if (_scalar_def.Bottom_nth(i)->_scalar == sym)
04360 break;
04361 if (i < _scalar_def.Elements())
04362 return FALSE;
04363 USE_LIST *use_list = du->Du_Get_Use(wn);
04364 if (use_list == NULL)
04365 return FALSE;
04366 if (use_list->Incomplete())
04367 return TRUE;
04368 USE_LIST_ITER iter(use_list);
04369 const DU_NODE* node = NULL;
04370 for (node = iter.First(); !iter.Is_Empty(); node = iter.Next()) {
04371 WN* wn_use = node->Wn();
04372 if (!Wn_Is_Inside(wn_use, _loop))
04373 return TRUE;
04374 }
04375 return FALSE;
04376 }
04377
04378
04379
04380
04381
04382
04383
04384 BOOL ARA_REF::Is_Messy()
04385 {
04386 if (Is_Too_Messy())
04387 return TRUE;
04388 REGION_ITER iter(&Image());
04389 const REGION *first = iter.First();
04390 for (const REGION *node=first; !iter.Is_Empty(); node = iter.Next()) {
04391 if (node->Is_Too_Messy())
04392 return TRUE;
04393 }
04394 return FALSE;
04395 }