00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 #define __STDC_LIMIT_MACROS
00072 #include <stdint.h>
00073 #ifdef USE_PCH
00074 #include "lno_pch.h"
00075 #endif // USE_PCH
00076 #pragma hdrstop
00077
00078 #include <sys/types.h>
00079 #include <alloca.h>
00080
00081 #include "call_info.h"
00082 #include "defs.h"
00083 #include "config_cache.h"
00084 #include "access_main.h"
00085 #include "access_vector.h"
00086 #include "lnopt_main.h"
00087 #include "stab.h"
00088 #include "lwn_util.h"
00089 #include "opt_du.h"
00090 #include "lnoutils.h"
00091 #include "soe.h"
00092 #include "cond.h"
00093 #include "fb_whirl.h"
00094 #include "move.h"
00095
00096 static INT preg_counter = 0;
00097 extern BOOL Promote_Messy_Bound(WN* wn_loop,
00098 WN* wn_bound,
00099 char name[],
00100 DU_MANAGER* du);
00101 #define MAX_NAME_SIZE 66
00102 extern BOOL Hoist_Lower_Bound(WN* wn_loop,
00103 DOLOOP_STACK* stack,
00104 MEM_POOL* pool)
00105 {
00106 char buffer[MAX_NAME_SIZE];
00107 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn_loop);
00108 WN* wn_load = UBvar(WN_end(wn_loop));
00109 WN* wn_start = WN_kid0(WN_start(wn_loop));
00110 if (wn_load == NULL)
00111 return FALSE;
00112 if (!dli->Step->Is_Const())
00113 return FALSE;
00114 sprintf(buffer, "_lb%d", preg_counter++);
00115 BOOL promoted = Promote_Messy_Bound(wn_loop, wn_start, buffer, Du_Mgr);
00116 FmtAssert(promoted, ("Could not promote lower bound."));
00117 CXX_DELETE(dli->LB, dli->LB->Pool());
00118 INT num_bounds = Num_Lower_Bounds(wn_loop, dli->Step);
00119 dli->LB =
00120 CXX_NEW(ACCESS_ARRAY(num_bounds,stack->Elements(),pool),pool);
00121 dli->LB->Set_LB(WN_kid0(WN_start(wn_loop)), stack, dli->Step->Const_Offset);
00122 return TRUE;
00123 }
00124
00125 extern BOOL Hoist_Upper_Bound(WN* wn_loop,
00126 DOLOOP_STACK* stack,
00127 MEM_POOL* pool)
00128 {
00129 char buffer[MAX_NAME_SIZE];
00130 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn_loop);
00131 WN* wn_load = UBvar(WN_end(wn_loop));
00132 WN* wn_end = UBexp(WN_end(wn_loop));
00133 if (wn_load == NULL || wn_end == NULL)
00134 return FALSE;
00135 if (!dli->Step->Is_Const())
00136 return FALSE;
00137 sprintf(buffer, "_ub%d", preg_counter++);
00138 BOOL promoted = Promote_Messy_Bound(wn_loop, wn_end, buffer, Du_Mgr);
00139 FmtAssert(promoted, ("Could not promote upper bound."));
00140 CXX_DELETE(dli->UB, dli->UB->Pool());
00141 INT num_bounds = Num_Upper_Bounds(wn_loop);
00142 dli->UB = CXX_NEW(ACCESS_ARRAY(num_bounds,stack->Elements(),pool),pool);
00143 dli->UB->Set_UB(WN_end(wn_loop), stack);
00144 return TRUE;
00145 }
00146
00147 static BOOL Expr_Has_Vertex(WN* wn_tree)
00148 {
00149 ARRAY_DIRECTED_GRAPH16* dg = Array_Dependence_Graph;
00150 if (dg->Get_Vertex(wn_tree))
00151 return TRUE;
00152 for (INT i = 0; i < WN_kid_count(wn_tree); i++)
00153 if (Expr_Has_Vertex(WN_kid(wn_tree, i)))
00154 return TRUE;
00155 return FALSE;
00156 }
00157
00158 extern void Hoist_Bounds_One_Level(WN* wn_tree)
00159 {
00160 DOLOOP_STACK shortstack(&LNO_local_pool);
00161 if (WN_operator(wn_tree) == OPR_DO_LOOP) {
00162 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn_tree);
00163 if (Bound_Is_Too_Messy(dli->LB)
00164 || Expr_Has_Vertex(WN_kid0(WN_start(wn_tree)))) {
00165 Build_Doloop_Stack(wn_tree, &shortstack);
00166 Hoist_Lower_Bound(wn_tree, &shortstack, &LNO_default_pool);
00167 shortstack.Clear();
00168 }
00169 WN* wn_var = UBvar(WN_end(wn_tree));
00170 if (wn_var != NULL && (Bound_Is_Too_Messy(dli->UB)
00171 || Expr_Has_Vertex(UBexp(WN_end(wn_tree))))
00172 && WN_operator(wn_var) == OPR_LDID
00173 && SYMBOL(wn_var) == SYMBOL(WN_index(wn_tree))) {
00174 Build_Doloop_Stack(wn_tree, &shortstack);
00175 Hoist_Upper_Bound(wn_tree, &shortstack, &LNO_default_pool);
00176 shortstack.Clear();
00177 }
00178 Hoist_Bounds_One_Level(WN_do_body(wn_tree));
00179 return;
00180 }
00181
00182 if (WN_opcode(wn_tree) == OPC_BLOCK) {
00183 for (WN* wn = WN_first(wn_tree); wn != NULL; wn = WN_next(wn))
00184 Hoist_Bounds_One_Level(wn);
00185 } else {
00186 for (INT i = 0; i < WN_kid_count(wn_tree); i++)
00187 Hoist_Bounds_One_Level(WN_kid(wn_tree, i));
00188 }
00189 }
00190
00191
00192
00193
00194
00195
00196
00197
00198 extern void Hoist_Iload_Ldid_Upper_Bound_One_Level(
00199 WN* loop,
00200 BOOL negative_stride) {
00201 char name[MAX_NAME_SIZE];
00202 DOLOOP_STACK stack(&LNO_local_pool);
00203 if (WN_operator(loop) == OPR_DO_LOOP) {
00204 DO_LOOP_INFO* dli = Get_Do_Loop_Info(loop);
00205 if (!dli->Step->Is_Const())
00206 return;
00207 WN* wn_var = UBvar(WN_end(loop));
00208 WN* wn_exp=NULL;
00209 WN* wn_bound = negative_stride ? WN_kid0(WN_start(loop))
00210 : UBexp(WN_end(loop));
00211 LWN_ITER* itr = LWN_WALK_TreeIter(wn_bound);
00212 for (; itr != NULL; itr = LWN_WALK_TreeNext(itr)) {
00213 wn_exp = itr->wn;
00214 OPERATOR opr = WN_operator(wn_exp);
00215 if (opr == OPR_MPY || opr == OPR_LDID || opr == OPR_ILOAD)
00216 break;
00217 }
00218 if (wn_var == NULL || wn_exp == NULL)
00219 return;
00220 if (WN_operator(wn_exp)==OPR_ILOAD
00221 && WN_operator(WN_kid0(wn_exp))==OPR_LDID
00222 && WN_operator(wn_var) == OPR_LDID
00223 && SYMBOL(wn_var) == SYMBOL(WN_index(loop))) {
00224
00225 WN* dart_ldid=WN_kid0(wn_exp);
00226 WN* dart_stid=Du_Mgr->Ud_Get_Def(dart_ldid)->Head()->Wn();
00227
00228 Build_Doloop_Stack(loop, &stack);
00229
00230 WN* wn_parent = LWN_Get_Parent(wn_exp);
00231 INT i;
00232 for (i = 0; i < WN_kid_count(wn_parent); i++)
00233 if (wn_exp == WN_kid(wn_parent, i))
00234 break;
00235 FmtAssert(i<WN_kid_count(wn_parent), ("Could not find kid for parent."));
00236 INT kid = i;
00237 TYPE_ID type = WN_desc(WN_start(loop));
00238 OPCODE preg_s_opcode = OPCODE_make_op(OPR_STID, MTYPE_V, type);
00239 sprintf(name, "_ub%d", preg_counter++);
00240 WN_OFFSET preg_num = Create_Preg(type, name);
00241 ST* preg_st = MTYPE_To_PREG(type);
00242 WN* wn_stid = LWN_CreateStid(preg_s_opcode, preg_num, preg_st,
00243 Be_Type_Tbl(type), wn_exp);
00244 LWN_Insert_Block_After(LWN_Get_Parent(dart_stid), dart_stid, wn_stid);
00245 WN* wn_ldid = LWN_CreateLdid(WN_opcode(UBvar(WN_end(loop))), wn_stid);
00246 WN_kid(wn_parent, kid) = wn_ldid;
00247 LWN_Set_Parent(wn_ldid, wn_parent);
00248 Du_Mgr->Add_Def_Use(wn_stid, wn_ldid);
00249 INT hoist_level = Hoistable_Statement(wn_stid, Du_Mgr);
00250 if (hoist_level < Loop_Depth(wn_stid))
00251 Hoist_Statement(wn_stid, hoist_level);
00252 CXX_DELETE(dli->UB, dli->UB->Pool());
00253 INT num_bounds = Num_Upper_Bounds(loop);
00254 dli->UB = CXX_NEW(ACCESS_ARRAY(num_bounds,stack.Elements(),
00255 &LNO_default_pool),&LNO_default_pool);
00256 dli->UB->Set_UB(WN_end(loop), &stack);
00257 stack.Clear();
00258 }
00259 }
00260 }
00261
00262
00263
00264 extern void LNO_Build_Access(WN *func_nd,
00265 MEM_POOL *pool,
00266 BOOL Hoist_Bounds)
00267 {
00268 MEM_POOL_Push(&LNO_local_pool);
00269 DOLOOP_STACK *stack = CXX_NEW(DOLOOP_STACK(&LNO_local_pool),&LNO_local_pool);
00270 INDX_RANGE_STACK *irs =
00271 CXX_NEW(INDX_RANGE_STACK(&LNO_local_pool),&LNO_local_pool);
00272 LNO_Build_Access(func_nd,stack,pool,irs,Hoist_Bounds);
00273 CXX_DELETE(stack,&LNO_local_pool);
00274 CXX_DELETE(irs,&LNO_local_pool);
00275 MEM_POOL_Pop(&LNO_local_pool);
00276 }
00277
00278
00279
00280
00281 extern void LNO_Build_Access(WN *wn, DOLOOP_STACK *stack, MEM_POOL *pool,
00282 INDX_RANGE_STACK *irs, BOOL Hoist_Bounds)
00283 {
00284 WN *kid;
00285
00286 Is_True(wn,("Null wn in LNO_Build_Access"));
00287
00288 if (OPCODE_is_leaf(WN_opcode(wn))) return;
00289
00290 if (WN_opcode(wn) == OPC_BLOCK) {
00291 kid = WN_first (wn);
00292 while (kid) {
00293 LNO_Build_Access(kid,stack,pool,irs,Hoist_Bounds);
00294 kid = WN_next(kid);
00295 }
00296 return;
00297 }
00298
00299 if (WN_opcode(wn) == OPC_DO_LOOP) {
00300 LNO_Build_Do_Access(wn,stack,Hoist_Bounds);
00301 stack->Push(wn);
00302 if (irs) irs->Push(INDX_RANGE());
00303 } else if (WN_operator(wn) == OPR_ARRAY) {
00304 LNO_Build_Access_Array(wn,stack,pool,irs);
00305 } else if (WN_opcode(wn) == OPC_IF) {
00306 LNO_Build_If_Access(wn,stack);
00307 }
00308
00309 for (INT kidno=0; kidno<WN_kid_count(wn); kidno++) {
00310 kid = WN_kid(wn,kidno);
00311 LNO_Build_Access(kid,stack,pool,irs,Hoist_Bounds);
00312 }
00313
00314 if (WN_opcode(wn) == OPC_DO_LOOP) {
00315 if (irs) {
00316 INDX_RANGE *ir = &irs->Top_nth(0);
00317 if (ir->Valid) {
00318 DO_LOOP_INFO *dli = (DO_LOOP_INFO *) WN_MAP_Get(LNO_Info_Map,wn);
00319 ACCESS_VECTOR *step = dli->Step;
00320 INT64 new_max = -1;
00321 if (step->Is_Const() && (abs(step->Const_Offset) != 1)) {
00322 new_max = ir->Maxsize()/abs(step->Const_Offset);
00323 } else {
00324 new_max = ir->Maxsize();
00325 }
00326 if (new_max != -1 &&
00327 (dli->Est_Max_Iterations_Index == -1 ||
00328 dli->Est_Max_Iterations_Index > new_max)) {
00329 dli->Est_Max_Iterations_Index = new_max;
00330 }
00331 if (dli->Est_Max_Iterations_Index >= 0 &&
00332 dli->Est_Max_Iterations_Index < dli->Est_Num_Iterations) {
00333 dli->Est_Num_Iterations = dli->Est_Max_Iterations_Index;
00334 dli->Num_Iterations_Symbolic = FALSE;
00335 }
00336 }
00337 irs->Pop();
00338 }
00339 stack->Pop();
00340 }
00341 }
00342
00343 static void LNO_Update_Indx_Range(INDX_RANGE_STACK *irs,
00344 ACCESS_ARRAY *array, WN *wn)
00345 {
00346 if (!array->Too_Messy && (WN_element_size(wn) > 0)) {
00347 INT num_dim = WN_num_dim(wn);
00348 for (INT i = 0; i < num_dim; i++) {
00349 WN* dim_wn = WN_array_dim(wn,i);
00350 if (WN_operator(dim_wn) != OPR_INTCONST)
00351 continue;
00352 INT64 sz = WN_const_val(dim_wn);
00353 if (((sz == 1) || (sz == 0)) && i == 0)
00354 continue;
00355 ACCESS_VECTOR *av = array->Dim(i);
00356 if (av->Too_Messy) continue;
00357 INT coeff = -1;
00358 BOOL seen_two_coeff=FALSE;
00359 for (INT j=0; j<av->Nest_Depth() && !seen_two_coeff; j++) {
00360 if (av->Loop_Coeff(j)) {
00361 if (coeff != -1) {
00362 seen_two_coeff = TRUE;
00363 } else {
00364 coeff = j;
00365 }
00366 }
00367 }
00368
00369 if ((coeff != -1) && !seen_two_coeff) {
00370 if (av->Contains_Non_Lin_Symb() || av->Contains_Lin_Symb()) {
00371 if (av->Non_Const_Loops() <= coeff) {
00372 irs->Bottom_nth(coeff).Union(0,0,av->Loop_Coeff(coeff),sz);
00373 }
00374 } else {
00375 irs->Bottom_nth(coeff).Union(av->Const_Offset,TRUE,
00376 av->Loop_Coeff(coeff),sz);
00377 }
00378 }
00379 }
00380 }
00381 }
00382
00383 extern void LNO_Build_Access_Array(WN *wn, DOLOOP_STACK *stack, MEM_POOL *pool,
00384 INDX_RANGE_STACK *irs)
00385 {
00386 ACCESS_ARRAY *array = CXX_NEW(ACCESS_ARRAY(WN_num_dim(wn),stack->Elements(),
00387 pool),pool);
00388 array->Set_Array(wn,stack);
00389 WN_MAP_Set(LNO_Info_Map,wn,(void *)array);
00390
00391 if (irs) {
00392 LNO_Update_Indx_Range(irs,array,wn);
00393 }
00394 }
00395
00396
00397
00398 extern void LNO_Build_Do_Access(WN *wn,
00399 DOLOOP_STACK *stack,
00400 BOOL Hoist_Bounds)
00401 {
00402
00403 DO_LOOP_INFO *dli = (DO_LOOP_INFO *) WN_MAP_Get(LNO_Info_Map,wn);
00404 FmtAssert(dli,("Unmapped DO loop in LNO_Build_Do_Access"));
00405
00406 MEM_POOL *pool=dli->Pool();
00407 {
00408
00409
00410 ACCESS_VECTOR *step=CXX_NEW(ACCESS_VECTOR(stack->Elements(),pool),pool);
00411
00412 stack->Push(wn);
00413
00414 dli->Step = step;
00415 dli->LB = NULL;
00416 dli->UB = NULL;
00417 WN *s = WN_step(wn);
00418 if (WN_operator(s) != OPR_STID) {
00419 step->Too_Messy = TRUE;
00420 goto return_point;
00421 }
00422 s = WN_kid(s,0);
00423 INT8 sign;
00424 if (WN_operator(s) == OPR_ADD) {
00425 sign = 1;
00426 } else if (WN_operator(s) == OPR_SUB) {
00427 sign = -1;
00428 } else {
00429 step->Too_Messy = TRUE;
00430 goto return_point;
00431 }
00432
00433
00434
00435 BOOL found_step = FALSE;
00436 SYMBOL doloop(WN_index(wn));
00437 if (WN_operator(WN_kid(s,0)) == OPR_LDID) {
00438 WN*kid = WN_kid(s,0);
00439 SYMBOL symbol(kid);
00440 Is_True(symbol.St(),("Null symbol in LNO_Build_Do_Access"));
00441 if (symbol == doloop) {
00442 step->Set(WN_kid(s,1),stack,sign,0);
00443 found_step = TRUE;
00444 }
00445 }
00446
00447 if (!found_step && WN_operator(WN_kid(s,1)) == OPR_LDID) {
00448 SYMBOL symbol(WN_kid(s,1));
00449 if (symbol == doloop) {
00450 step->Set(WN_kid(s,0),stack,sign,0);
00451 found_step = TRUE;
00452 }
00453 }
00454 if (!found_step) {
00455 step->Too_Messy = TRUE;
00456 goto return_point;
00457 }
00458 if (!step->Is_Const()) {
00459 goto return_point;
00460 }
00461
00462
00463
00464
00465 WN *l = WN_start(wn);
00466 Is_True(WN_operator(l) == OPR_STID,
00467 ("LNO_Build_Do_Access::LB of do loop is not a stid"));
00468
00469 INT num_bounds = Num_Lower_Bounds(wn, step);
00470
00471
00472
00473
00474 dli->LB =
00475 CXX_NEW(ACCESS_ARRAY(num_bounds,stack->Elements(),pool),pool);
00476
00477 dli->LB->Set_LB(WN_kid(l,0),stack,step->Const_Offset);
00478 if (Hoist_Bounds && Bound_Is_Too_Messy(dli->LB))
00479 Hoist_Lower_Bound(wn, stack, pool);
00480
00481
00482
00483
00484 WN *u = WN_end(wn);
00485 Is_True(OPCODE_is_compare(WN_opcode(u)),
00486 ("LNO_Build_Do_Access::UB of do loop is not a compare"));
00487 num_bounds = Num_Upper_Bounds(wn);
00488
00489
00490 dli->UB= CXX_NEW(ACCESS_ARRAY(num_bounds,stack->Elements(),pool),pool);
00491 dli->UB->Set_UB(u,stack);
00492 WN* wn_var = UBvar(WN_end(wn));
00493 if (Hoist_Bounds && wn_var != NULL && Bound_Is_Too_Messy(dli->UB)
00494 && WN_operator(wn_var) == OPR_LDID
00495 && SYMBOL(wn_var) == SYMBOL(WN_index(wn)))
00496 Hoist_Upper_Bound(wn, stack, pool);
00497
00498
00499 if (step->Is_Const() && (step->Const_Offset < 0)) {
00500 ACCESS_ARRAY *ub = dli->UB;
00501 dli->UB = dli->LB;
00502 dli->LB = ub;
00503 }
00504
00505
00506
00507 if (step->Is_Const()) {
00508 if ((step->Const_Offset > 0)) {
00509 for (INT i=0; i<dli->UB->Num_Vec(); i++) {
00510 ACCESS_VECTOR *ub = dli->UB->Dim(i);
00511 if (ub->Loop_Coeff(dli->Depth) < 0) {
00512 dli->LB->Too_Messy = TRUE;
00513 dli->UB->Too_Messy = TRUE;
00514 step->Too_Messy = TRUE;
00515 break;
00516 }
00517 }
00518 } else {
00519 for (INT i=0; i<dli->LB->Num_Vec(); i++) {
00520 ACCESS_VECTOR *lb = dli->LB->Dim(i);
00521 if (lb->Loop_Coeff(dli->Depth) > 0) {
00522 dli->LB->Too_Messy = TRUE;
00523 dli->UB->Too_Messy = TRUE;
00524 step->Too_Messy = TRUE;
00525 break;
00526 }
00527 }
00528 }
00529 }
00530 }
00531 return_point:
00532
00533 stack->Pop();
00534
00535 if (!dli->LB) {
00536 ACCESS_ARRAY *lb=
00537 CXX_NEW(ACCESS_ARRAY(1,stack->Elements()+1,pool),pool);
00538 dli->LB = lb;
00539 lb->Too_Messy = TRUE;
00540 }
00541 if (!dli->UB) {
00542 ACCESS_ARRAY *ub=
00543 CXX_NEW(ACCESS_ARRAY(1,stack->Elements()+1,pool),pool);
00544 dli->UB = ub;
00545 ub->Too_Messy = TRUE;
00546 }
00547
00548 if (dli->Est_Num_Iterations == -1) {
00549 dli->Set_Est_Num_Iterations(stack);
00550 if (Cur_PU_Feedback && dli->Num_Iterations_Symbolic) {
00551 #ifndef KEY
00552 INT32 freq_loop_header = WN_MAP32_Get(WN_MAP_FEEDBACK,WN_start(wn));
00553 INT32 freq_loop_body = WN_MAP32_Get(WN_MAP_FEEDBACK,WN_step(wn));
00554 if (LNO_Verbose) {
00555 fprintf(stdout, "Header executed %d\n", freq_loop_header);
00556 fprintf(stdout, "Body executed %d\n", freq_loop_body);
00557 }
00558
00559 if (freq_loop_header > 0) {
00560 dli->Est_Num_Iterations = (INT64) (freq_loop_body/freq_loop_header);
00561 dli->Num_Iterations_Symbolic = FALSE;
00562 dli->Num_Iterations_Profile=TRUE;
00563 if (LNO_Verbose)
00564 fprintf(stdout, "Iteration counts from profile %lld\n", dli->Est_Num_Iterations);
00565 }
00566 #else
00567 const FB_Info_Loop fb_info = Cur_PU_Feedback->Query_loop(wn);
00568
00569 if (!LNO_Ignore_Feedback && fb_info.freq_iterate._value > 0) {
00570
00571
00572 dli->Est_Num_Iterations = (INT64) ( ( fb_info.freq_back._value +
00573 fb_info.freq_out._value ) /
00574 fb_info.freq_positive._value );
00575 dli->Num_Iterations_Symbolic = FALSE;
00576 dli->Num_Iterations_Profile=TRUE;
00577 if (LNO_Verbose)
00578 fprintf(stdout, "Iteration counts from profile %lld\n",
00579 dli->Est_Num_Iterations);
00580 }
00581 #endif
00582 }
00583 }
00584 }
00585
00586
00587 extern void LNO_Build_If_Access(WN *wn, DOLOOP_STACK *stack)
00588 {
00589 Is_True(WN_opcode(wn) == OPC_IF,("Non-if in LNO_Build_If_Access"));
00590 IF_INFO *info = (IF_INFO *) WN_MAP_Get(LNO_Info_Map,wn);
00591 Is_True(info,("Unmapped IF loop in LNO_Build_IF_Access"));
00592
00593 MEM_POOL *pool=info->Pool();
00594
00595 WN *compare = WN_if_test(wn);
00596 BOOL top_level_not;
00597
00598 if (WN_operator(compare) == OPR_LNOT) {
00599 top_level_not = TRUE;
00600 compare = WN_kid0(compare);
00601 } else {
00602 top_level_not = FALSE;
00603 }
00604
00605 if (WN_operator(compare) == OPR_LIOR
00606 || WN_operator(compare) == OPR_CIOR) {
00607 INT num_lors = Num_Liors(compare);
00608 info->Condition =
00609 CXX_NEW(ACCESS_ARRAY(num_lors+1,stack->Elements(),pool),pool);
00610 info->Condition_On_Then = top_level_not;
00611 info->Condition->Set_IF(compare,stack,TRUE,FALSE,0);
00612 } else {
00613 INT num_lands = Num_Lands(compare);
00614 info->Condition =
00615 CXX_NEW(ACCESS_ARRAY(num_lands+1,stack->Elements(),pool),pool);
00616 info->Condition_On_Then = !top_level_not;
00617 info->Condition->Set_IF(compare,stack,FALSE,TRUE,0);
00618 }
00619
00620 if (Cur_PU_Feedback && info->Freq_True<0 && info->Freq_False<0) {
00621 INT32 freq_header = WN_MAP32_Get(WN_MAP_FEEDBACK, wn);
00622 if (freq_header > 0) {
00623 INT32 freq_true = WN_MAP32_Get(WN_MAP_FEEDBACK, WN_then(wn));
00624 info->Freq_True = (float) freq_true / (float) freq_header;
00625
00626 if (LNO_Verbose)
00627 fprintf(stdout, "True branch frequency %f\n", info->Freq_True);
00628
00629 if (!WN_else_is_empty(wn)) {
00630 INT32 freq_false = WN_MAP32_Get(WN_MAP_FEEDBACK, WN_else(wn));
00631 info->Freq_False = (float) freq_false / (float) freq_header;
00632 if (LNO_Verbose)
00633 fprintf(stdout, "False branch frequency %f\n", info->Freq_False);
00634 }
00635 }
00636 }
00637 }
00638
00639
00640
00641 extern void LNO_Print_One_Access(FILE *fp, WN* wn)
00642 {
00643 if (WN_opcode(wn) == OPC_DO_LOOP) {
00644 DO_LOOP_INFO *dli = (DO_LOOP_INFO *) WN_MAP_Get(LNO_Info_Map,wn);
00645 fprintf(fp,"The do loop info is \n");
00646 if (dli != NULL) {
00647 dli->Print(fp);
00648 } else {
00649 fprintf(fp, "Null DO_LOOP_INFO\n");
00650 }
00651 } else if (WN_opcode(wn) == OPC_REGION) {
00652 REGION_INFO* rgi = (REGION_INFO *) WN_MAP_Get(LNO_Info_Map, wn);
00653 if (rgi != NULL) {
00654 fprintf(fp,"The region info is \n");
00655 rgi->Print(fp);
00656 } else {
00657 fprintf(fp, "Null REGION_INFO\n");
00658 }
00659 } else if (WN_opcode(wn) == OPC_IF) {
00660 IF_INFO *info = (IF_INFO *) WN_MAP_Get(LNO_Info_Map,wn);
00661 if (info != NULL) {
00662 fprintf(fp,"The if info is \n"); info->Print(fp);
00663 if (WN_Is_If_MpVersion(wn))
00664 fprintf(fp, "WN_IF_IS_MPVERSION\n");
00665 } else {
00666 fprintf(fp, "Null IF_INFO\n");
00667 }
00668 } else if (WN_operator(wn) == OPR_CALL) {
00669 CALL_INFO *info = (CALL_INFO *) WN_MAP_Get(LNO_Info_Map,wn);
00670 if (info) {
00671 if (info != NULL) {
00672 fprintf(fp,"The call info is \n");
00673 info->Print(fp);
00674 } else {
00675 fprintf(fp, "Null CALL_INFO\n");
00676 }
00677 }
00678 } else if (WN_operator(wn) == OPR_ARRAY) {
00679 ACCESS_ARRAY *array = (ACCESS_ARRAY *) WN_MAP_Get(LNO_Info_Map,wn);
00680 if (array != NULL) {
00681 fprintf(fp,"The access array is \n"); array->Print(fp);
00682 } else {
00683 fprintf(fp,"Null ACCESS_ARRAY\n");
00684 }
00685 }
00686 }
00687
00688
00689 extern void LNO_Print_Access(FILE *fp, WN *wn)
00690 {
00691 WN *kid;
00692
00693 if (!wn) return;
00694
00695 if (OPCODE_is_leaf(WN_opcode(wn))) return;
00696
00697 if (WN_opcode(wn) == OPC_BLOCK) {
00698 kid = WN_first (wn);
00699 while (kid) {
00700 LNO_Print_Access(fp,kid);
00701 kid = WN_next(kid);
00702 }
00703 return;
00704 }
00705
00706 LNO_Print_One_Access(fp, wn);
00707
00708 for (INT kidno=0; kidno<WN_kid_count(wn); kidno++) {
00709 kid = WN_kid(wn,kidno);
00710 LNO_Print_Access(fp,kid);
00711 }
00712
00713 }
00714
00715
00716
00717
00718
00719
00720
00721 static BOOL Exp_Node_Varies_In_Loop(WN* wn_node,
00722 WN* wn_loop)
00723 {
00724 DU_MANAGER* du = Du_Mgr;
00725 ARRAY_DIRECTED_GRAPH16* dg = Array_Dependence_Graph;
00726
00727 if (WN_operator(wn_node) == OPR_LDID) {
00728 LWN_ITER* itr = LWN_WALK_TreeIter(WN_do_body(wn_loop));
00729 for (; itr != NULL; itr = LWN_WALK_TreeNext(itr)) {
00730 WN* wn = itr->wn;
00731 if (OPCODE_is_store(WN_opcode(wn))
00732 && Overlapped_base(Alias_Mgr, wn_node, wn) != NOT_ALIASED)
00733 return TRUE;
00734 if (OPCODE_is_call(WN_opcode(wn))
00735 && Aliased_with_region(Alias_Mgr, wn_node, wn, WRITE) != NOT_ALIASED)
00736 return TRUE;
00737 }
00738 }
00739 if (WN_operator(wn_node) == OPR_ILOAD) {
00740 VINDEX16 v = dg->Get_Vertex(wn_node);
00741 if (v == 0)
00742 return TRUE;
00743 if (Enclosing_Loop(wn_node) == NULL)
00744 return TRUE;
00745 EINDEX16 e = 0;
00746 for (e = dg->Get_Out_Edge(v); e != 0; e = dg->Get_Next_Out_Edge(e)) {
00747 WN* wn_def = dg->Get_Wn(dg->Get_Sink(e));
00748 if (Wn_Is_Inside(wn_def, wn_loop))
00749 return TRUE;
00750 }
00751 }
00752 return FALSE;
00753 }
00754
00755
00756
00757
00758
00759
00760
00761 static BOOL Exp_Varies_In_Loop(WN* wn_exp,
00762 WN* wn_loop)
00763 {
00764 if (Exp_Node_Varies_In_Loop(wn_exp, wn_loop))
00765 return TRUE;
00766
00767 for (INT i = 0; i < WN_kid_count(wn_exp); i++)
00768 if (Exp_Varies_In_Loop(WN_kid(wn_exp, i), wn_loop))
00769 return TRUE;
00770 return FALSE;
00771 }
00772
00773
00774
00775
00776
00777
00778
00779
00780 static void Hoist_Varying_Lower_Bounds_Traverse(WN* wn_tree)
00781 {
00782 DOLOOP_STACK shortstack(&LNO_local_pool);
00783 if (WN_opcode(wn_tree) == OPC_DO_LOOP
00784 && Exp_Varies_In_Loop(WN_kid0(WN_start(wn_tree)), wn_tree)) {
00785 Build_Doloop_Stack(wn_tree, &shortstack);
00786 Hoist_Lower_Bound(wn_tree, &shortstack, &LNO_default_pool);
00787 }
00788
00789 if (WN_opcode(wn_tree) == OPC_BLOCK) {
00790 for (WN* wn = WN_first(wn_tree); wn != NULL; wn = WN_next(wn))
00791 Hoist_Varying_Lower_Bounds_Traverse(wn);
00792 } else {
00793 for (INT i = 0; i < WN_kid_count(wn_tree); i++)
00794 Hoist_Varying_Lower_Bounds_Traverse(WN_kid(wn_tree, i));
00795 }
00796 }
00797
00798
00799
00800
00801
00802
00803
00804 extern void Hoist_Varying_Lower_Bounds(WN* func_nd)
00805 {
00806 Hoist_Varying_Lower_Bounds_Traverse(func_nd);
00807 }