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 #define __STDC_LIMIT_MACROS
00058 #include <stdint.h>
00059 #if defined(BUILD_OS_DARWIN)
00060 #include <darwin_elf.h>
00061 #else
00062 #include <elf.h>
00063 #endif
00064 #include "defs.h"
00065 #include "tracing.h"
00066 #include "loop_info.h"
00067 #include "if_info.h"
00068 #include "soe.h"
00069 #include "opt_alias_interface.h"
00070 #include "ipl_main.h"
00071 #include "ir_reader.h"
00072 #include "cxx_hash.h"
00073 #include "lwn_util.h"
00074 #include "be_util.h"
00075 #include "ipl_summary.h"
00076 #include "ipl_summarize.h"
00077
00078 #ifdef SHARED_BUILD
00079 #pragma weak Aliased
00080 #endif
00081
00082 mINT32
00083 SYSTEM_OF_EQUATIONS::_work[SOE_MAX_WORK_ROWS][SOE_MAX_WORK_COLS];
00084 mINT64
00085 SYSTEM_OF_EQUATIONS::_work_const[SOE_MAX_WORK_ROWS];
00086 struct ALIAS_MANAGER *Ipl_Al_Mgr;
00087 struct DU_MANAGER *Ipl_Du_Mgr;
00088
00089 MEM_POOL IPL_loop_pool;
00090 MEM_POOL IPL_local_pool;
00091 WN_MAP IPL_info_map;
00092 WN_MAP IPL_reduc_map;
00093 static BOOL trace_section = FALSE;
00094
00095 typedef HASH_TABLE<char*, ST*> ST_TBL;
00096 ST_TBL *ST_node_tbl;
00097
00098 static void
00099 Mark_Code(WN* wn, STACK_OF_WN *stack, DLI_BASE_STACK *dlistack,
00100 IF_STACK *if_stack, mUINT8 depth);
00101 static void
00102 IPL_Build_Access_Vectors(WN* wn, DOLOOP_STACK *stack, MEM_POOL *pool);
00103 static WN*
00104
00105 Find_Match(WN *store,OPCODE rhs_opcode, WN *rhs);
00106
00107 static BOOL
00108 Self_Dependent_Store(WN* store);
00109
00110 static void
00111 Check_Reduction(WN* store);
00112
00113 static BOOL
00114 Match(WN *store, WN *value);
00115
00116 static BOOL
00117 Equiv(WN *wn1, WN *wn2);
00118
00119 static void
00120 IPL_Print_One_Access(FILE *fp, WN* wn);
00121
00122 static void
00123 IPL_Print_Access(FILE *fp, WN* wn);
00124
00125
00126
00127
00128 extern void
00129 Mark_formal_summary_symbol(ST* s)
00130 {
00131 if (ST_sclass(s) == SCLASS_FORMAL ||
00132 ST_sclass(s) == SCLASS_FORMAL_REF) {
00133 INT32 idx = Summary->Get_symbol_index(s);
00134 SUMMARY_SYMBOL* sym = Summary->Get_symbol(idx);
00135 sym->Set_used_in_array_section();
00136 }
00137 }
00138
00139
00140
00141
00142 static BOOL
00143 Opcode_Match(OPCODE op1, OPCODE op2)
00144 {
00145 if (op1 == op2) return TRUE;
00146 if (OPCODE_rtype(op1) != OPCODE_rtype(op2)) return FALSE;
00147 if (OPCODE_desc(op1) != OPCODE_desc(op2)) return FALSE;
00148 OPERATOR opr1 = OPCODE_operator(op1);
00149 OPERATOR opr2 = OPCODE_operator(op2);
00150 if ((opr1 == OPR_ADD) && (opr2 == OPR_SUB)) return TRUE;
00151 if ((opr2 == OPR_ADD) && (opr1 == OPR_SUB)) return TRUE;
00152 return FALSE;
00153 }
00154
00155
00156
00157
00158 extern
00159 WN* UBvar(WN* end)
00160 {
00161 WN* wn_index = NULL;
00162 OPERATOR opr = WN_operator(end);
00163 switch (opr) {
00164 case OPR_LE:
00165 case OPR_LT:
00166 wn_index = WN_kid0(end);
00167 break;
00168 case OPR_GE:
00169 case OPR_GT:
00170 wn_index = WN_kid1(end);
00171 break;
00172 default:
00173 return NULL;
00174 }
00175 if (WN_operator(wn_index) != OPR_LDID)
00176 return NULL;
00177 return wn_index;
00178 }
00179
00180 static BOOL
00181 Loop_pool_initialized = FALSE;
00182
00183
00184
00185 extern void
00186 IPL_Initialize_Par_Code()
00187 {
00188 trace_section = Get_Trace(TP_IPL, TT_IPL_SECTION);
00189
00190 IPL_info_map = WN_MAP_Create(&IPL_loop_pool);
00191 IPL_reduc_map = WN_MAP32_Create(&IPL_loop_pool);
00192 if (!Loop_pool_initialized)
00193 {
00194 MEM_POOL_Initialize(&IPL_loop_pool, "ipl loop pool", 0);
00195 MEM_POOL_Initialize(&IPL_local_pool, "ipl local pool", 0);
00196 Loop_pool_initialized = TRUE;
00197 }
00198
00199 MEM_POOL_Push(&IPL_loop_pool);
00200 MEM_POOL_Push(&IPL_local_pool);
00201
00202
00203 ST_node_tbl = (ST_TBL*)CXX_NEW(ST_TBL(12, &IPL_loop_pool), &IPL_loop_pool);
00204
00205 }
00206
00207
00208
00209
00210 extern void
00211 IPL_Finalize_Par_Code()
00212 {
00213 MEM_POOL_Pop(&IPL_local_pool);
00214 MEM_POOL_Pop(&IPL_loop_pool);
00215 WN_MAP_Delete(IPL_info_map);
00216 WN_MAP_Delete(IPL_reduc_map);
00217 }
00218
00219
00220
00221
00222 void
00223 IPL_Mark_Code(WN* func_nd)
00224 {
00225 mUINT8 depth = 0;
00226
00227 DLI_BASE_STACK *dlistack =
00228 CXX_NEW(DLI_BASE_STACK(&IPL_loop_pool),&IPL_loop_pool);
00229
00230 STACK_OF_WN *stack =
00231 CXX_NEW(STACK_OF_WN(&IPL_loop_pool),&IPL_loop_pool);
00232
00233 IF_STACK *if_stack =
00234 CXX_NEW(IF_STACK(&IPL_loop_pool),&IPL_loop_pool);
00235
00236 Mark_Code(func_nd, stack, dlistack, if_stack, depth);
00237
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248 static
00249 void Mark_Code(WN* wn,
00250 STACK_OF_WN* stack,
00251 DLI_BASE_STACK* dlistack,
00252 IF_STACK* if_stack,
00253 mUINT8 depth)
00254 {
00255 FmtAssert (wn, ("NULL node encountered in Mark_Code\n"));
00256
00257 WN* kid;
00258 DO_LOOP_INFO_BASE *dli;
00259 OPERATOR oper = WN_operator(wn);
00260
00261 switch (oper) {
00262
00263 case OPR_BLOCK:
00264 kid = WN_last (wn);
00265 while (kid) {
00266 Mark_Code(kid, stack, dlistack, if_stack, depth);
00267 kid = WN_prev(kid);
00268 }
00269 break;
00270
00271 case OPR_DO_LOOP: {
00272 INT i;
00273
00274 dli = (DO_LOOP_INFO_BASE*) WN_MAP_Get(IPL_info_map, wn);
00275
00276 if (!dli) {
00277 dli = CXX_NEW(DO_LOOP_INFO_BASE(&IPL_loop_pool), &IPL_loop_pool);
00278 dli->Set_depth(depth);
00279 WN_MAP_Set(IPL_info_map,wn,(void *)dli);
00280 }
00281 else {
00282 dli->Set_is_inner_loop();
00283 }
00284
00285 ++depth;
00286
00287
00288 for (i = 0; i < dlistack->Elements(); ++i) {
00289 dlistack->Bottom_nth(i)->Reset_is_inner_loop();
00290 }
00291
00292
00293 for (i = 0; i < if_stack->Elements(); ++i) {
00294 if_stack->Bottom_nth(i)->Contains_Do_Loops = TRUE;
00295 }
00296
00297 stack->Push(wn);
00298 dlistack->Push(dli);
00299 }
00300 break;
00301
00302 case OPR_IF: {
00303 IF_INFO *if_info = (IF_INFO*) WN_MAP_Get(IPL_info_map, wn);
00304 if (!if_info) {
00305 if_info = CXX_NEW(IF_INFO(&IPL_loop_pool, FALSE,FALSE),&IPL_loop_pool);
00306 WN_MAP_Set(IPL_info_map, wn, (void*) if_info);
00307 }
00308 else {
00309 if_info->Contains_Do_Loops = FALSE;
00310 }
00311 if_stack->Push(if_info);
00312 }
00313 break;
00314
00315 case OPR_IO:
00316 case OPR_CALL:
00317 case OPR_FORWARD_BARRIER:
00318 case OPR_BACKWARD_BARRIER: {
00319 for (INT i = 0; i < dlistack->Elements(); ++i) {
00320 dlistack->Bottom_nth(i)->Set_has_calls();
00321 }
00322 }
00323 break;
00324
00325 case OPR_DO_WHILE:
00326 case OPR_WHILE_DO:
00327 case OPR_COMPGOTO: {
00328 for (INT i = 0; i < dlistack->Elements(); i++) {
00329 dlistack->Bottom_nth(i)->Set_has_gotos();
00330 }
00331 }
00332 break;
00333
00334 default: {
00335 if (OPERATOR_is_non_scf(oper)) {
00336 for (INT i = 0; i < dlistack->Elements(); i++) {
00337 dlistack->Bottom_nth(i)->Set_has_gotos();
00338 }
00339 }
00340 if (OPERATOR_is_store(oper)) {
00341 Check_Reduction(wn);
00342 }
00343 }
00344 break;
00345 }
00346
00347 for (INT kidno = 0; kidno < WN_kid_count(wn); kidno++) {
00348 INT64 constval;
00349 kid = WN_kid(wn, kidno);
00350 if (WN_operator(kid) == OPR_LDID && Wn_Is_Intconst(kid, &constval)) {
00351 WN_kid(wn, kidno) = WN_Intconst (WN_rtype(kid), constval);
00352 LWN_Set_Parent (WN_kid(wn, kidno), wn);
00353 IPA_WN_DELETE_Tree (Current_Map_Tab, kid);
00354 }
00355 else {
00356 Mark_Code(kid,stack,dlistack,if_stack,depth);
00357 }
00358 }
00359
00360 if (oper == OPR_DO_LOOP) {
00361 stack->Pop();
00362 dlistack->Pop();
00363 depth--;
00364 }
00365 else if (oper == OPR_IF) {
00366 if_stack->Pop();
00367 }
00368 }
00369
00370
00371
00372
00373 extern void
00374 IPL_Build_Access_Vectors(WN* func_nd)
00375 {
00376
00377
00378 MEM_POOL_Push(&IPL_local_pool);
00379
00380 DOLOOP_STACK *stack =
00381 CXX_NEW(DOLOOP_STACK(&IPL_local_pool),&IPL_local_pool);
00382 IPL_Build_Access_Vectors(func_nd,stack,&IPL_loop_pool);
00383
00384 CXX_DELETE(stack,&IPL_local_pool);
00385
00386 MEM_POOL_Pop(&IPL_local_pool);
00387 if (Get_Trace(TP_IPL, TT_IPL_VERBOSE))
00388 IPL_Print_Access(stderr, func_nd);
00389 }
00390
00391
00392
00393
00394
00395 static void
00396 IPL_Build_Do_Access(WN* wn, DOLOOP_STACK *stack)
00397 {
00398
00399 DO_LOOP_INFO_BASE *dli = (DO_LOOP_INFO_BASE *) WN_MAP_Get(IPL_info_map,wn);
00400
00401 FmtAssert(dli,("Unmapped DO loop in IPL_Build_Do_Access"));
00402
00403 MEM_POOL *pool=dli->Pool();
00404
00405
00406 ACCESS_VECTOR *step =
00407 CXX_NEW(ACCESS_VECTOR(stack->Elements(),pool),pool);
00408
00409 stack->Push(wn);
00410
00411 dli->Set_step(step);
00412 dli->Set_lb(NULL);
00413 dli->Set_ub(NULL);
00414 WN *s = WN_step(wn);
00415 if (WN_operator(s) != OPR_STID) {
00416 step->Too_Messy = TRUE;
00417 goto return_point;
00418 }
00419 {
00420 s = WN_kid(s,0);
00421 INT8 sign;
00422 if (WN_operator(s) == OPR_ADD) {
00423 sign = 1;
00424 } else if (WN_operator(s) == OPR_SUB) {
00425 sign = -1;
00426 } else {
00427 step->Too_Messy = TRUE;
00428 goto return_point;
00429 }
00430
00431
00432
00433 BOOL found_step = FALSE;
00434 SYMBOL doloop(WN_index(wn));
00435 if (WN_operator(WN_kid(s,0)) == OPR_LDID) {
00436 WN*kid = WN_kid(s,0);
00437 SYMBOL symbol(kid);
00438 Is_True(symbol.St(),("Null symbol in IPL_Build_Do_Access"));
00439 if (symbol == doloop) {
00440 step->Set(WN_kid(s,1),stack,sign,0);
00441 found_step = TRUE;
00442 }
00443 }
00444
00445 if (!found_step && WN_operator(WN_kid(s,1)) == OPR_LDID) {
00446 SYMBOL symbol(WN_kid(s,1));
00447 if (symbol == doloop) {
00448 step->Set(WN_kid(s,0),stack,sign,0);
00449 found_step = TRUE;
00450 }
00451 }
00452 if (!found_step) {
00453 step->Too_Messy = TRUE;
00454 goto return_point;
00455 }
00456 if (!step->Is_Const()) {
00457 goto return_point;
00458 }
00459
00460
00461
00462
00463 WN *l = WN_start(wn);
00464
00465 Is_True(WN_operator(l) == OPR_STID,
00466 ("IPL_Build_Do_Access::LB of do loop is not a stid"));
00467
00468 INT num_bounds = Num_Lower_Bounds(wn, step);
00469
00470
00471
00472 ACCESS_ARRAY *lb =
00473 CXX_NEW(ACCESS_ARRAY(num_bounds,stack->Elements(),pool),pool);
00474
00475
00476 dli->Set_lb(lb);
00477
00478
00479 dli->Get_lb()->Set_LB(WN_kid(l,0),stack,step->Const_Offset);
00480
00481
00482
00483 WN *u = WN_end(wn);
00484
00485 Is_True(OPCODE_is_compare(WN_opcode(u)),
00486 ("IPL_Build_Do_Access::UB of do loop is not a compare"));
00487
00488 num_bounds = Num_Upper_Bounds(wn);
00489
00490
00491
00492
00493 ACCESS_ARRAY *ub =
00494 CXX_NEW(ACCESS_ARRAY(num_bounds,stack->Elements(),pool),pool);
00495 dli->Set_ub(ub);
00496 dli->Get_ub()->Set_UB(u,stack);
00497
00498 WN* wn_var = UBvar(WN_end(wn));
00499
00500
00501 if (step->Is_Const() && (step->Const_Offset < 0)) {
00502
00503 ACCESS_ARRAY *ub = dli->Get_ub();
00504 dli->Set_ub(dli->Get_lb());
00505 dli->Set_lb(ub);
00506 }
00507
00508
00509
00510 if (step->Is_Const()) {
00511 if ((step->Const_Offset > 0)) {
00512 for (INT i=0; i<dli->Get_ub()->Num_Vec(); i++) {
00513 ACCESS_VECTOR *ub = dli->Get_ub()->Dim(i);
00514 if (ub->Loop_Coeff(dli->Get_depth()) < 0) {
00515 dli->Get_lb()->Too_Messy = TRUE;
00516 dli->Get_ub()->Too_Messy = TRUE;
00517 step->Too_Messy = TRUE;
00518 break;
00519 }
00520 }
00521 } else {
00522 for (INT i=0; i<dli->Get_lb()->Num_Vec(); i++) {
00523 ACCESS_VECTOR *lb = dli->Get_lb()->Dim(i);
00524 if (lb->Loop_Coeff(dli->Get_depth()) > 0) {
00525 dli->Get_lb()->Too_Messy = TRUE;
00526 dli->Get_ub()->Too_Messy = TRUE;
00527 step->Too_Messy = TRUE;
00528 break;
00529 }
00530 }
00531 }
00532 }
00533 }
00534
00535 return_point:
00536
00537 stack->Pop();
00538
00539 if (!dli->Get_lb()) {
00540 ACCESS_ARRAY *lb=
00541 CXX_NEW(ACCESS_ARRAY(1,stack->Elements()+1,pool),pool);
00542 dli->Set_lb(lb);
00543 lb->Too_Messy = TRUE;
00544 }
00545 if (!dli->Get_ub()) {
00546 ACCESS_ARRAY *ub =
00547 CXX_NEW(ACCESS_ARRAY(1,stack->Elements()+1,pool),pool);
00548 dli->Set_ub(ub);
00549 ub->Too_Messy = TRUE;
00550 }
00551 }
00552
00553
00554
00555
00556 static void
00557 IPL_Build_Access_Array(WN *wn, DOLOOP_STACK *stack, MEM_POOL *pool)
00558 {
00559 ACCESS_ARRAY *array =
00560 CXX_NEW(ACCESS_ARRAY(WN_num_dim(wn),stack->Elements(),
00561 pool),pool);
00562 array->Set_Array(wn,stack);
00563
00564 WN_MAP_Set(IPL_info_map,wn,(void *)array);
00565
00566 if (stack->Elements() == 0 && trace_section)
00567 fprintf(stderr, "NULL elements in the stack, hence NO do loops \n");
00568
00569 }
00570
00571
00572
00573
00574 static void
00575 IPL_Build_If_Access(WN *wn, DOLOOP_STACK *stack)
00576 {
00577
00578 Is_True(WN_opcode(wn) == OPC_IF,("Non-if in IPL_Build_If_Access"));
00579
00580 IF_INFO *info = (IF_INFO *) WN_MAP_Get(IPL_info_map,wn);
00581 Is_True(info,("Unmapped IF loop in IPL_Build_IF_Access"));
00582
00583 MEM_POOL *pool=info->Pool();
00584
00585 WN *compare = WN_if_test(wn);
00586 BOOL top_level_not;
00587
00588 if (WN_operator(compare) == OPR_LNOT) {
00589 top_level_not = TRUE;
00590 compare = WN_kid0(compare);
00591 } else {
00592 top_level_not = FALSE;
00593 }
00594
00595 if (WN_operator(compare) == OPR_LIOR) {
00596 INT num_lors = Num_Liors(compare);
00597 info->Condition =
00598 CXX_NEW(ACCESS_ARRAY(num_lors+1,stack->Elements(),pool),pool);
00599 info->Condition_On_Then = top_level_not;
00600 info->Condition->Set_IF(compare,stack,TRUE,FALSE,0);
00601 } else {
00602 INT num_lands = Num_Lands(compare);
00603 info->Condition =
00604 CXX_NEW(ACCESS_ARRAY(num_lands+1,stack->Elements(),pool),pool);
00605 info->Condition_On_Then = !top_level_not;
00606 info->Condition->Set_IF(compare,stack,FALSE,TRUE,0);
00607 }
00608 }
00609
00610
00611
00612
00613
00614
00615 static void
00616 IPL_Build_Access_Vectors(WN* wn, DOLOOP_STACK *stack, MEM_POOL *pool)
00617 {
00618 WN* kid;
00619
00620 if (WN_opcode(wn) == OPC_BLOCK) {
00621 kid = WN_first (wn);
00622 while (kid) {
00623 IPL_Build_Access_Vectors(kid,stack,pool);
00624 kid = WN_next(kid);
00625 }
00626 return;
00627 }
00628
00629 if (WN_opcode(wn) == OPC_DO_LOOP) {
00630 IPL_Build_Do_Access(wn,stack);
00631 stack->Push(wn);
00632 }
00633 else if (WN_operator(wn) == OPR_ARRAY) {
00634 IPL_Build_Access_Array(wn,stack,pool);
00635 } else if (WN_opcode(wn) == OPC_IF) {
00636 IPL_Build_If_Access(wn,stack);
00637 }
00638
00639 for (INT kidno=0; kidno<WN_kid_count(wn); kidno++) {
00640 kid = WN_kid(wn,kidno);
00641 IPL_Build_Access_Vectors(kid,stack,pool);
00642 }
00643
00644 if (WN_opcode(wn) == OPC_DO_LOOP) {
00645 stack->Pop();
00646 }
00647 }
00648
00649 static void Mark_Formals_In_Tree(WN* wn_tree)
00650 {
00651 if (OPCODE_has_sym(WN_opcode(wn_tree)))
00652 Mark_formal_summary_symbol(WN_st(wn_tree));
00653 for (INT i = 0; i < WN_kid_count(wn_tree); i++)
00654 Mark_Formals_In_Tree(WN_kid(wn_tree, i));
00655 }
00656
00657
00658 static void Mark_Formals_In_Reduction_Increment(WN* wn_stid,
00659 WN* wn_ldid)
00660 {
00661 if (WN_operator(wn_stid) != OPR_STID
00662 && WN_operator(wn_ldid) != OPR_LDID)
00663 return;
00664 WN* wn_redop = WN_kid0(wn_stid);
00665 if (WN_kid_count(wn_redop) != 2)
00666 return;
00667 WN* wn_left = WN_kid0(wn_redop);
00668 WN* wn_right = WN_kid1(wn_redop);
00669 if (wn_left != wn_ldid && wn_right != wn_ldid)
00670 return;
00671 WN* wn_tree = (wn_left == wn_ldid) ? wn_right : wn_left;
00672 Mark_Formals_In_Tree(wn_tree);
00673 }
00674
00675
00676
00677
00678 static void
00679 Check_Reduction(WN* store)
00680 {
00681
00682
00683
00684
00685 if (WN_operator(store) == OPR_STID)
00686 ST_node_tbl->Enter(ST_name(WN_st(store)), WN_st(store));
00687
00688
00689 REDUCTION_TYPE type = RED_NONE;
00690
00691 WN *rhs = WN_kid0(store);
00692 OPERATOR oper = WN_operator(rhs);
00693
00694 switch(oper) {
00695 case OPR_ADD: case OPR_SUB:
00696 type = RED_ADD;
00697 break;
00698 case OPR_MPY:
00699 type = RED_MPY;
00700 break;
00701 case OPR_MAX:
00702 type = RED_MAX;
00703 break;
00704 case OPR_MIN:
00705 type = RED_MIN;
00706 break;
00707 default:
00708 return;
00709 }
00710
00711
00712
00713
00714 WN *match_ld;
00715
00716 match_ld = Find_Match(store,WN_opcode(rhs),rhs);
00717 if ((match_ld) && (WN_operator(store) == OPR_ISTORE))
00718 {
00719 if (!Self_Dependent_Store(store)) {
00720
00721
00722 WN_MAP32_Set(IPL_reduc_map,store,(INT32) type);
00723 WN_MAP32_Set(IPL_reduc_map,match_ld,(INT32) type);
00724 }
00725 }
00726 else if (match_ld)
00727 {
00728
00729
00730 WN* parent_wn = LWN_Get_Parent(store);
00731 if (!(WN_operator(parent_wn) == OPR_DO_LOOP &&
00732 WN_step(parent_wn) == store))
00733 {
00734 WN_MAP32_Set(IPL_reduc_map,store,(INT32) type);
00735 WN_MAP32_Set(IPL_reduc_map,match_ld,(INT32) type);
00736 Mark_Formals_In_Reduction_Increment(store, match_ld);
00737 }
00738 }
00739 }
00740
00741
00742
00743
00744
00745 BOOL Record_scalar_flow(WN* stid)
00746 {
00747 FmtAssert((WN_operator(stid) == OPR_STID),( "expecting OPR_STID \n"));
00748
00749 if (ST_node_tbl->Find(ST_name(WN_st(stid))))
00750 {
00751 return TRUE;
00752 }
00753 return FALSE;
00754 }
00755
00756
00757
00758
00759 static BOOL
00760 Match(WN *store, WN *value)
00761 {
00762 OPERATOR st_oper = WN_operator(store);
00763 OPERATOR value_oper = WN_operator(value);
00764
00765 if (st_oper == OPR_STID) {
00766 return((value_oper == OPR_LDID) &&
00767 (WN_offset(store) == WN_offset(value)) &&
00768 (ST_base(WN_st(store)) == ST_base(WN_st(value))) &&
00769 (ST_ofst(WN_st(store)) == ST_ofst(WN_st(value))));
00770 } else if (st_oper == OPR_ISTORE) {
00771 return((value_oper == OPR_ILOAD) &&
00772 (WN_offset(store) == WN_offset(value)) &&
00773 Equiv(WN_kid1(store),WN_kid0(value)));
00774 } else {
00775 return (FALSE);
00776 }
00777 }
00778
00779
00780
00781
00782
00783 static WN*
00784 Find_Match(WN *store,OPCODE rhs_opcode, WN *rhs) {
00785 WN *kid0 = WN_kid0(rhs);
00786
00787 if (OPCODE_operator(rhs_opcode) == OPR_SUB) {
00788 if (Opcode_Match(WN_opcode(kid0), rhs_opcode)) {
00789 return Find_Match(store,rhs_opcode,kid0);
00790 } else if (Match(store,kid0)) {
00791 return kid0;
00792 } else {
00793 return NULL;
00794 }
00795 } else {
00796 if (Opcode_Match(WN_opcode(kid0), rhs_opcode)) {
00797 WN *result = Find_Match(store,rhs_opcode,kid0);
00798 if (result) {
00799 return result;
00800 }
00801 }
00802 if (Match(store,kid0)) {
00803 return kid0;
00804 }
00805 WN *kid1 = WN_kid1(rhs);
00806 if (Opcode_Match(WN_opcode(kid1), rhs_opcode)) {
00807 WN *result = Find_Match(store,rhs_opcode,kid1);
00808 if (result) {
00809 return result;
00810 }
00811 }
00812 if (Match(store,kid1)) {
00813 return kid1;
00814 }
00815 }
00816 return NULL;
00817 }
00818
00819
00820
00821
00822 static BOOL
00823 Self_Dependent_Store(WN* store)
00824 {
00825 WN* wn1, *wn2;
00826 WN* lhs = WN_kid1(store);
00827 ALIAS_RESULT result;
00828 wn1 = WN_kid1(store);
00829 if (WN_operator(wn1) == OPR_ARRAY)
00830 {
00831 wn2 = WN_array_base(wn1);
00832 if ((!WN_operator(wn1) == OPR_LDID) ||
00833 (!WN_operator(wn1) == OPR_LDA))
00834 {
00835 for (INT kidno=0; kidno<WN_kid_count(wn2); kidno++)
00836 {
00837 WN* wn3 = WN_kid(wn2, kidno);
00838
00839
00840
00841
00842 result = Aliased(Ipl_Al_Mgr, wn1, wn3);
00843
00844 if (!(result == NOT_ALIASED))
00845 return TRUE;
00846 }
00847 return FALSE;
00848 }
00849 }
00850 return FALSE;
00851 }
00852
00853
00854
00855
00856 static BOOL
00857 Equiv(WN *wn1, WN *wn2)
00858 {
00859 if (!WN_Equiv(wn1,wn2)) return(FALSE);
00860 for (INT kidno=0; kidno<WN_kid_count(wn1); kidno++) {
00861 if (!Equiv(WN_kid(wn1,kidno),WN_kid(wn2,kidno))) {
00862 return(FALSE);
00863 }
00864 }
00865 return(TRUE);
00866 }
00867
00868
00869
00870
00871
00872 static void
00873 IPL_Print_Access(FILE *fp, WN* wn)
00874 {
00875 WN *kid;
00876
00877 if (!wn) return;
00878
00879 if (OPCODE_is_leaf(WN_opcode(wn))) return;
00880
00881 if (WN_opcode(wn) == OPC_BLOCK) {
00882 kid = WN_first (wn);
00883 while (kid) {
00884 IPL_Print_Access(fp,kid);
00885 kid = WN_next(kid);
00886 }
00887 return;
00888 }
00889
00890 IPL_Print_One_Access(fp, wn);
00891
00892 for (INT kidno=0; kidno<WN_kid_count(wn); kidno++) {
00893 kid = WN_kid(wn,kidno);
00894 IPL_Print_Access(fp,kid);
00895 }
00896 }
00897
00898
00899
00900
00901 static void
00902 IPL_Print_One_Access(FILE *fp, WN* wn)
00903 {
00904 if (WN_opcode(wn) == OPC_DO_LOOP)
00905 {
00906 DO_LOOP_INFO_BASE *dli = (DO_LOOP_INFO_BASE *)
00907 WN_MAP_Get(IPL_info_map,wn);
00908 fprintf(fp,"The do loop info is \n"); dli->Print(fp);
00909 }
00910 #if 0
00911 else if (WN_opcode(wn) == OPC_IF)
00912 {
00913 IF_INFO *info = (IF_INFO *) WN_MAP_Get(IPL_info_map,wn);
00914 }
00915 #endif
00916 else if (WN_operator(wn) == OPR_ARRAY)
00917 {
00918 ACCESS_ARRAY *array = (ACCESS_ARRAY *) WN_MAP_Get(IPL_info_map,wn);
00919 if (array)
00920 {
00921 if (trace_section)
00922 fprintf(fp,"The array is \n"); array->Print(fp);
00923 }
00924 else
00925 {
00926 if (trace_section)
00927 fprintf(fp,"Null array \n");
00928 }
00929 }
00930 }
00931
00932
00933
00934
00935 void
00936 DO_LOOP_INFO_BASE::Print(FILE *fp, INT indentation)
00937 {
00938 char buf[80];
00939 INT i;
00940
00941 for (i = 0; i < indentation && i < 79; i++)
00942 buf[i] = ' ';
00943 buf[i] = '\0';
00944
00945 if (Has_calls())
00946 fprintf(fp,"%sIt has calls \n", buf);
00947 if (Has_gotos())
00948 fprintf(fp,"%sIt has non-DO or non-IF controlflow\n", buf);
00949 if (Is_inner_loop())
00950 fprintf(fp,"%sIs an inner loop \n", buf);
00951 fprintf(fp, "%sDepth is %d \n", buf, Get_depth());
00952
00953 fprintf(fp,"%sThe lb is ", buf);
00954 if (Get_lb())
00955 Get_lb()->Print(fp,TRUE);
00956 else
00957 fprintf(fp, "<null>\n");
00958
00959 fprintf(fp,"%sThe ub is ", buf);
00960
00961 if (Get_ub())
00962 Get_ub()->Print(fp,TRUE);
00963 else
00964 fprintf(fp, "<null>\n");
00965 fprintf(fp,"%sThe step is ", buf);
00966
00967 if (Get_step()) {
00968 Get_step()->Print(fp);
00969 fprintf(fp,"\n");
00970 }
00971 else
00972 fprintf(fp, "<null>\n");
00973
00974 }
00975
00976
00977
00978
00979
00980
00981
00982
00983 extern "C" void Print_DO_LOOP_INFO_BASE (FILE *fp, DO_LOOP_INFO_BASE *b)
00984 {
00985 b->Print(fp);
00986 }
00987
00988
00989