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 #define __STDC_LIMIT_MACROS
00049 #include <stdint.h>
00050 #if defined(BUILD_OS_DARWIN)
00051 #include <darwin_elf.h>
00052 #else
00053 #include <elf.h>
00054 #endif
00055 #include <sys/elf_whirl.h>
00056 #include <sys/types.h>
00057
00058 #include "defs.h"
00059 #include "errors.h"
00060 #include "tracing.h"
00061 #include "wn.h"
00062 #include "stab.h"
00063 #include "const.h"
00064 #include "targ_const.h"
00065 #include "pu_info.h"
00066 #include "irbdata.h"
00067 #include "ir_bwrite.h"
00068 #include "ir_bread.h"
00069 #include "ir_bcom.h"
00070 #include "loop_info.h"
00071 #include "if_info.h"
00072 #include "ipl_linex.h"
00073 #include "ipa_section.h"
00074 #include "cxx_hash.h"
00075 #include "wn_util.h"
00076 #include "lwn_util.h"
00077 #include "ipl_summary.h"
00078 #include "ipl_summarize.h"
00079 #include "ipl_summarize_util.h"
00080 #include "ipl_array_bread_write.h"
00081 #include "ipl_tlog.h"
00082 #include "ipl_main.h"
00083 #include "ipl_lno_util.h"
00084 #include "wb_ipl.h"
00085
00086 ARRAY_SUMMARY Array_Summary;
00087
00088 static SUMMARY_PROCEDURE* Current_summary_procedure = NULL;
00089 static CFG_NODE_INFO *Cfg_entry = NULL;
00090 static INT Cfg_entry_idx = -1;
00091
00092
00093
00094
00095
00096 static void
00097 process_scalar_reduc_node(WN* stmt, ST* lhs_st)
00098 {
00099 BOOL branch;
00100 INT loop_idx;
00101 INT stmt_idx;
00102 INT cd_idx;
00103 WN* loop = NULL;
00104 SUMMARY_CONTROL_DEPENDENCE* d = Get_controlling_stmt(stmt);
00105
00106 while (d) {
00107 cd_idx = Get_cd_idx(d);
00108 if (d->Is_do_loop()) {
00109 loop = d->Get_wn();
00110 loop_idx = cd_idx;
00111 d = Get_controlling_stmt(loop);
00112 }
00113 else {
00114 if (loop && d->Is_entry()) {
00115 cd_idx = loop_idx;
00116 }
00117 else if (d->Is_if_stmt()) {
00118 SUMMARY_STMT* summary_stmt =
00119 Search_for_summary_stmt(loop ? loop : stmt, branch, stmt_idx);
00120 Is_True(summary_stmt,("process_scalar_reduc_node: NULL summary stmt"));
00121 }
00122
00123 CFG_NODE_INFO* cfg_node = Array_Summary.Get_cfg_node_array(cd_idx);
00124 if (d->Is_if_stmt() && !branch) {
00125 cfg_node= Array_Summary.Get_cfg_node_array(cfg_node->Get_else_index());
00126 }
00127 cfg_node->Add_scalar_reduc(Summary->Get_symbol_index(lhs_st));
00128 return;
00129 }
00130 }
00131
00132
00133 Cfg_entry->Add_scalar_may_reduc(Summary->Get_symbol_index(lhs_st));
00134 }
00135
00136
00137
00138
00139
00140 static void
00141 process_scalar_def_node(WN* stmt, ST* lhs_st)
00142 {
00143 BOOL branch;
00144 INT loop_idx;
00145 INT stmt_idx;
00146 INT cd_idx;
00147 CFG_NODE_INFO* cfg_node;
00148 WN* loop = NULL;
00149 INT id = Summary->Get_symbol_index(lhs_st);
00150
00151
00152
00153 if (id == -1)
00154 return;
00155
00156 SUMMARY_CONTROL_DEPENDENCE* d = Get_controlling_stmt(stmt);
00157
00158 while (d) {
00159 cd_idx = Get_cd_idx(d);
00160 if (d->Is_do_loop()) {
00161 loop = d->Get_wn();
00162 loop_idx = cd_idx;
00163 d = Get_controlling_stmt(loop);
00164 }
00165 else {
00166
00167
00168 if (loop && d->Is_entry()) {
00169 cd_idx = loop_idx;
00170 cfg_node = Array_Summary.Get_cfg_node_array(cd_idx);
00171 }
00172 else {
00173 if (d->Is_if_stmt()) {
00174 SUMMARY_STMT* summary_stmt =
00175 Search_for_summary_stmt(stmt, branch, stmt_idx);
00176 Is_True(summary_stmt, ("process_scalar_def: NULL summary stmt"));
00177 cd_idx = Get_cd_idx(d);
00178 cfg_node = Array_Summary.Get_cfg_node_array(cd_idx);
00179 if (!branch) {
00180 cd_idx = cfg_node->Get_else_index();
00181 cfg_node = Array_Summary.Get_cfg_node_array(cd_idx);
00182 }
00183 }
00184 else {
00185 cd_idx = Get_cd_idx(d);
00186 cfg_node = Array_Summary.Get_cfg_node_array(cd_idx);
00187 }
00188 }
00189
00190
00191
00192 if (cfg_node->Is_entry()) {
00193 Summary->Get_symbol(id)->Set_dkill();
00194 }
00195
00196
00197 cfg_node->Add_scalar_def(id);
00198 return;
00199 }
00200 }
00201
00202
00203 Cfg_entry->Add_scalar_may_def(id);
00204 }
00205
00206
00207
00208
00209
00210 static void
00211 process_scalar_node(WN* node, IPA_SECTION_TYPE type)
00212 {
00213 ST* s = WN_st(node);
00214 INT id = Summary->Get_symbol_index(s);
00215
00216
00217 if (id == -1) {
00218 return;
00219 }
00220
00221 SUMMARY_STMT* summary_stmt;
00222 CFG_NODE_INFO* cfg_node;
00223 WN* loop = NULL;
00224 BOOL branch = FALSE;
00225 INT loop_idx;
00226 INT stmt_idx;
00227
00228 INT cd_idx = -1;
00229 WN* stmt = IPL_get_stmt_scf(node);
00230 SUMMARY_CONTROL_DEPENDENCE* d = Get_controlling_stmt(stmt);
00231
00232 while (d)
00233 {
00234 cd_idx = Get_cd_idx(d);
00235 if (d->Is_do_loop())
00236 {
00237 loop = d->Get_wn();
00238 loop_idx = cd_idx;
00239 d = Get_controlling_stmt(loop);
00240 }
00241 else
00242 {
00243
00244 if ((loop) && (d->Is_entry()))
00245 cd_idx = loop_idx;
00246
00247 #if 0
00248 if (d->Is_if_stmt() && loop)
00249 {
00250 summary_stmt = Search_for_summary_stmt(loop, branch,
00251 stmt_idx);
00252 FmtAssert(summary_stmt != NULL,("process_scalar_node: NULL summary stmt"));
00253 }
00254 else if (d->Is_if_stmt())
00255 {
00256 summary_stmt = Search_for_summary_stmt(node, branch,
00257 stmt_idx);
00258 FmtAssert(summary_stmt != NULL,("process_scalar_node: NULL summary stmt"));
00259 }
00260 #endif
00261
00262
00263
00264
00265
00266 cfg_node = Array_Summary.Get_cfg_node_array(cd_idx);
00267
00268 if (d->Is_if_stmt() && branch == FALSE)
00269 {
00270 cfg_node =
00271 Array_Summary.Get_cfg_node_array(cfg_node->Get_else_index());
00272 }
00273
00274 switch( type )
00275 {
00276 case IPA_USE: {
00277
00278
00279 SUMMARY_SYMBOL *symbol = Summary->Get_symbol(id);
00280 if (!symbol->Is_dkill())
00281 cfg_node->Add_scalar_use(id);
00282 }
00283 break;
00284
00285 case IPA_DEF:
00286 cfg_node->Add_scalar_def(id);
00287 break;
00288
00289 case IPA_REDUC:
00290 cfg_node->Add_scalar_reduc(id);
00291 break;
00292
00293 default:
00294 Fail_FmtAssertion("unknown scalar type %d \n", id);
00295 break;
00296 }
00297 return;
00298 }
00299 }
00300
00301 if (loop)
00302 {
00303 d = Get_cd_by_idx(cd_idx);
00304 FmtAssert(d != NULL, (" Expecting a cd node \n"));
00305
00306 if (d->Is_if_stmt())
00307 {
00308 summary_stmt = Search_for_summary_stmt(loop, branch, stmt_idx);
00309 FmtAssert(summary_stmt != NULL,("process_scalar_node: NULL summary stmt"));
00310 }
00311
00312 cfg_node = Array_Summary.Get_cfg_node_array(cd_idx);
00313
00314 if (d->Is_if_stmt() && branch == FALSE)
00315 {
00316 cfg_node =
00317 Array_Summary.Get_cfg_node_array(cfg_node->Get_else_index());
00318 }
00319
00320 id = Summary->Get_symbol_index(s);
00321
00322 switch( type )
00323 {
00324 case IPA_USE: {
00325 SUMMARY_SYMBOL *symbol = Summary->Get_symbol(id);
00326 if (!symbol->Is_dkill())
00327 cfg_node->Add_scalar_use(id);
00328 }
00329 break;
00330
00331 case IPA_DEF:
00332 cfg_node->Add_scalar_def(id);
00333 break;
00334
00335 case IPA_REDUC:
00336 cfg_node->Add_scalar_reduc(id);
00337 break;
00338
00339 default:
00340 Fail_FmtAssertion("unknown scalar type %d \n", id);
00341 break;
00342
00343 }
00344 }
00345
00346 else
00347 {
00348 id = Summary->Get_symbol_index(s);
00349 switch( type )
00350 {
00351 case IPA_USE:
00352 Cfg_entry->Add_scalar_may_use(id);
00353 break;
00354
00355 case IPA_DEF:
00356 Cfg_entry->Add_scalar_may_def(id);
00357 break;
00358
00359 case IPA_REDUC:
00360 Cfg_entry->Add_scalar_may_reduc(id);
00361 break;
00362
00363 default:
00364 Fail_FmtAssertion("unknown scalar type %d \n", id);
00365 break;
00366
00367 }
00368 }
00369 }
00370
00371
00372
00373
00374 static INT
00375 get_actual_id(INT callsite_id, INT param_pos, INT start_idx)
00376 {
00377 SUMMARY_CALLSITE* callsite = Summary->Get_callsite(callsite_id);
00378 INT actual_id = callsite->Get_actual_index() + param_pos - start_idx;
00379
00380 if (Get_Trace(TP_IPL, TT_IPL_SECTION)) {
00381 fprintf(TFile, "callsite_id = %d , param_pos = %d , actual_id = %d\n",
00382 callsite_id, param_pos, actual_id);
00383 }
00384
00385 return actual_id;
00386 }
00387
00388
00389
00390
00391 static void
00392 process_actual_array_node(WN* wn,
00393 INT16 callsite_id,
00394 INT16 actual_id)
00395 {
00396 WN* array_base = WN_array_base(wn);
00397 while (array_base && (WN_operator(array_base) == OPR_ARRAY)) {
00398 array_base = WN_array_base(array_base);
00399 }
00400 FmtAssert(array_base != NULL,("NULL array base encountered\n"));
00401 if (!OPCODE_has_sym(WN_opcode(array_base))) {
00402 return;
00403 }
00404 ST* array_st = WN_st(array_base);
00405
00406 if ((ST_sclass(array_st) == SCLASS_FORMAL
00407 || ST_sclass(array_st) == SCLASS_FORMAL_REF)
00408 && ST_level(array_st) != CURRENT_SYMTAB) {
00409 Current_summary_procedure->Set_has_incomplete_array_info();
00410 return;
00411 }
00412
00413 if (ST_sclass(array_st) == SCLASS_AUTO) {
00414 return;
00415 }
00416 TY_IDX array_ty_idx = (ST_sclass(array_st) != SCLASS_FORMAL ?
00417 ST_type(array_st) :
00418 TY_pointed(ST_type(array_st)));
00419
00420
00421 if (TY_kind(array_ty_idx) != KIND_ARRAY) {
00422 return;
00423 }
00424
00425 ACCESS_ARRAY* av = (ACCESS_ARRAY*) WN_MAP_Get(IPL_info_map, wn);
00426 FmtAssert(av != NULL, ("Null access vector encountered \n"));
00427
00428 MEM_POOL* apool = Array_Summary.Get_array_pool();
00429 PROJECTED_REGION* proj_region =
00430 CXX_NEW(PROJECTED_REGION(av, apool, NULL), apool);
00431
00432 CFG_NODE_INFO* cfg_node;
00433
00434
00435 WN* stmt = IPL_get_stmt_scf(wn);
00436
00437
00438 SUMMARY_CONTROL_DEPENDENCE* d = Get_controlling_stmt(stmt);
00439
00440 INT cd_idx = d ? Get_cd_idx(d) : -1;
00441
00442 if (cd_idx != -1) {
00443 cfg_node = Array_Summary.Get_cfg_node_array(cd_idx);
00444 if (d->Is_if_stmt()) {
00445 BOOL branch;
00446 INT stmt_idx;
00447 SUMMARY_STMT* summary_stmt =
00448 Search_for_summary_stmt (stmt, branch, stmt_idx);
00449 FmtAssert (summary_stmt != NULL,
00450 ("process_actual_array_node: NULL summary stmt"));
00451 if (branch == FALSE) {
00452 cfg_node =
00453 Array_Summary.Get_cfg_node_array(cfg_node->Get_else_index());
00454 }
00455 }
00456 }
00457 else {
00458 cfg_node = Cfg_entry;
00459 }
00460
00461
00462
00463 INT element_size = TY_size(TY_etype(array_ty_idx));
00464 INT id = Summary->Get_symbol_index(array_st);
00465 cfg_node->Add_array_param(proj_region, id, element_size,
00466 callsite_id, actual_id);
00467 INT actual_index = get_actual_id(callsite_id, actual_id, 0);
00468 SUMMARY_ACTUAL* actual = Summary->Get_actual(actual_index);
00469 actual->Set_symbol_index(id);
00470 }
00471
00472
00473
00474
00475
00476 static void
00477 process_actual_node(WN* call_stmt, WN* parm_wn, INT callsite_id, INT param_pos)
00478 {
00479 WN* actual = WN_kid0(parm_wn);
00480
00481 if (WN_operator(actual) == OPR_ARRAY) {
00482 process_actual_array_node(actual, callsite_id, param_pos);
00483 }
00484
00485 #if _THIS_SEEMS_USELESS_
00486
00487 if (OPERATOR_has_sym(WN_operator(actual))) {
00488 ST* st = WN_st(actual);
00489 if (ST_sclass(st) == SCLASS_FORMAL_REF || ST_sclass(st) == SCLASS_FORMAL) {
00490 INT id = Summary->Get_symbol_index(st);
00491 SUMMARY_CONTROL_DEPENDENCE* d = Get_controlling_stmt(call_stmt);
00492
00493 if (d) {
00494 BOOL branch;
00495 if (d->Is_if_stmt()) {
00496 INT stmt_idx;
00497 SUMMARY_STMT* summary_stmt =
00498 Search_for_summary_stmt(call_stmt, branch, stmt_idx);
00499 FmtAssert(summary_stmt, ("process_actual_node: NULL summary stmt"));
00500 }
00501 INT cd_idx = Get_cd_idx(d);
00502
00503 CFG_NODE_INFO* cfg_node = Array_Summary.Get_cfg_node_array(cd_idx);
00504 if (d->Is_if_stmt() && branch == FALSE) {
00505 cd_idx = cfg_node->Get_else_index();
00506 cfg_node = Array_Summary.Get_cfg_node_array(cd_idx);
00507 }
00508
00509
00510
00511 INT pid = cfg_node->Add_scalar_ref_passed(id, callsite_id);
00512 INT actual_idx = get_actual_id(callsite_id, param_pos,
00513 Array_Summary.Get_actual_start_idx());
00514
00515 Array_Summary.Set_actual_scalar_info_map(pid+1, cd_idx, actual_idx);
00516 }
00517 else {
00518
00519 INT id = Summary->Get_symbol_index(WN_st(WN_kid0(actual)));
00520 INT pid = Cfg_entry->Add_scalar_ref_may_passed(id, callsite_id);
00521 INT actual_idx = get_actual_id(callsite_id, param_pos,
00522 Array_Summary.Get_actual_start_idx());
00523 Array_Summary.Set_actual_scalar_info_map(pid+1, Cfg_entry_idx,
00524 actual_idx);
00525 }
00526 }
00527 }
00528 #endif // _THIS_SEEMS_USELESS_
00529 }
00530
00531
00532
00533
00534 static void
00535 Min_Max_Fill_Proj_Node (PROJECTED_NODE* pn,
00536 DYN_ARRAY<LOOPINFO*>* loops,
00537 INT bad_loop_count)
00538 {
00539 BOOL substituted_lindex = FALSE;
00540
00541 pn->Fill_Out();
00542
00543 LINEX* lx_lower = pn->Get_lower_linex();
00544 INT j;
00545
00546 for (j = 0; j <= lx_lower->Num_terms(); j++) {
00547 TERM* tm = lx_lower->Get_term(j);
00548 if (tm->Get_type() == LTKIND_LINDEX) {
00549 INT loop_array_index = loops->Lastidx() - tm->Get_desc()
00550 + bad_loop_count;
00551
00552 if (loop_array_index < 0 || loop_array_index > loops->Lastidx()) {
00553 pn->Set_messy_lb();
00554 break;
00555 }
00556
00557 LOOPINFO* l = (*loops)[loop_array_index];
00558 LINEX* lx_substitute = (tm->Get_coeff() < 0)
00559 ? l->Max_value() : l->Min_value();
00560
00561 if (lx_substitute == NULL) {
00562 pn->Set_messy_lb();
00563 break;
00564 }
00565
00566 lx_lower->Substitute_Lindex(tm->Get_desc(), lx_substitute);
00567 substituted_lindex = TRUE;
00568 j = -1;
00569 }
00570 }
00571
00572 LINEX* lx_upper = pn->Get_upper_linex();
00573 for (j = 0; j <= lx_upper->Num_terms(); j++) {
00574 TERM* tm = lx_upper->Get_term(j);
00575 if (tm->Get_type() == LTKIND_LINDEX) {
00576 INT loop_array_index = loops->Lastidx() - tm->Get_desc()
00577 + bad_loop_count;
00578 if (loop_array_index < 0 || loop_array_index > loops->Lastidx()) {
00579 pn->Set_messy_ub();
00580 break;
00581 }
00582 LOOPINFO* l = (*loops)[loop_array_index];
00583 LINEX* lx_substitute = (tm->Get_coeff() < 0)
00584 ? l->Min_value() : l->Max_value();
00585 if (lx_substitute == NULL) {
00586 pn->Set_messy_ub();
00587 break;
00588 }
00589 lx_upper->Substitute_Lindex(tm->Get_desc(), lx_substitute);
00590 substituted_lindex = TRUE;
00591 j = -1;
00592 }
00593 }
00594
00595 if (substituted_lindex) {
00596 LINEX* lx_step = pn->Get_step_linex();
00597 if (lx_step != NULL) {
00598 lx_step->Free_terms();
00599 lx_step->Set_term(LTKIND_CONST, (INT32) 1, CONST_DESC, 0);
00600 }
00601 }
00602 }
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618 static BOOL
00619 Proj_Node_Has_Two_Strides (PROJECTED_NODE* proj_node,
00620 DYN_ARRAY<LOOPINFO*>* loops,
00621 INT bad_loop_count)
00622 {
00623 LOOPINFO* outer_loop = NULL;
00624
00625 if (bad_loop_count != 0)
00626 return FALSE;
00627
00628 INT l_coeff = 0;
00629 INT l_offset = 0;
00630 INT i;
00631 LINEX* lx_lower = proj_node->Get_lower_linex();
00632
00633 for (i = 0; i <= lx_lower->Num_terms(); ++i) {
00634 TERM* tm = lx_lower->Get_term(i);
00635 if (tm->Get_type() == LTKIND_LINDEX) {
00636 if (tm->Get_desc() != 0) {
00637
00638 return FALSE;
00639 }
00640 else {
00641
00642 l_coeff += tm->Get_coeff();
00643 }
00644 }
00645 else if (tm->Get_type() == LTKIND_CONST) {
00646
00647 l_offset += tm->Get_coeff();
00648 }
00649 else {
00650
00651 return FALSE;
00652 }
00653 }
00654
00655 if (l_coeff == 0) {
00656
00657 return FALSE;
00658 }
00659
00660 INT u_coeff = 0;
00661 INT u_offset = 0;
00662 LINEX* lx_upper = proj_node->Get_upper_linex();
00663
00664 for (i = 0; i <= lx_upper->Num_terms(); ++i) {
00665 TERM* tm = lx_upper->Get_term(i);
00666 if (tm->Get_type() == LTKIND_LINDEX) {
00667 if (tm->Get_desc() != 0) {
00668
00669 return FALSE;
00670 }
00671 else {
00672
00673 u_coeff += tm->Get_coeff();
00674 outer_loop = (*loops)[loops->Lastidx()];
00675 }
00676 }
00677 else if (tm->Get_type() == LTKIND_CONST) {
00678
00679 u_offset += tm->Get_coeff();
00680 }
00681 else {
00682
00683 return FALSE;
00684 }
00685 }
00686
00687 if (l_coeff != u_coeff) {
00688
00689 return FALSE;
00690 }
00691
00692 LINEX* lx_step = proj_node->Get_step_linex();
00693 if (lx_step == NULL || !lx_step->Is_const()) {
00694
00695 return FALSE;
00696 }
00697 INT stride = lx_step->Get_constant_term();
00698
00699 LINEX* outer_max = outer_loop->Max_value();
00700 if (outer_max == NULL || !outer_max->Is_const()) {
00701
00702 return FALSE;
00703 }
00704 INT outer_ub = outer_max->Get_constant_term();
00705
00706 LINEX* outer_min = outer_loop->Min_value();
00707 if (!outer_min->Is_const()) {
00708
00709 return FALSE;
00710 }
00711 INT outer_lb = outer_min->Get_constant_term();
00712
00713
00714
00715 if (l_coeff < 0 || stride < 0 || outer_ub < outer_lb) {
00716 return FALSE;
00717 }
00718
00719
00720 if (l_coeff * (outer_ub - outer_lb) < stride) {
00721 #if 0
00722 printf("Double-strided section:\nlb = %d\nub= %d\nstep = %d\nsegment_length = %d\nsegment_stride = %d\n",
00723 l_coeff * outer_lb + l_offset,
00724 u_coeff * outer_ub + u_offset,
00725 (stride % l_coeff == 0) ? l_coeff : 1,
00726 l_coeff * (outer_ub - outer_lb) + 1,
00727 stride);
00728 #endif
00729
00730 proj_node->Set_constant_two_strided_section(l_coeff*outer_lb + l_offset,
00731 l_coeff*outer_ub + u_offset, stride % l_coeff ? 1 : l_coeff,
00732 l_coeff*(outer_ub-outer_lb)+1, stride);
00733 return TRUE;
00734 }
00735
00736 return FALSE;
00737 }
00738
00739
00740
00741
00742 static void
00743 Min_Max_Fill_Region(PROJECTED_REGION* proj_region,
00744 DYN_ARRAY<LOOPINFO*>* loops,
00745 INT bad_loop_count)
00746 {
00747 if (proj_region->Is_messy_region())
00748 return;
00749
00750 PROJECTED_ARRAY* pa = proj_region->Get_projected_array();
00751 if (pa != NULL) {
00752 BOOL is_projected_region = TRUE;
00753
00754 for (INT i = 0; i <= pa->Lastidx(); i++) {
00755 PROJECTED_NODE* pn = &(*pa)[i];
00756 if (!Proj_Node_Has_Two_Strides(pn, loops, bad_loop_count)) {
00757 Min_Max_Fill_Proj_Node(pn, loops, bad_loop_count);
00758 }
00759 if (pn->Is_unprojected()) {
00760 is_projected_region = FALSE;
00761 }
00762 }
00763
00764 if (is_projected_region) {
00765 proj_region->Reset_is_unprojected();
00766 }
00767 else {
00768 proj_region->Set_unprojected();
00769 }
00770 }
00771 }
00772
00773
00774
00775
00776
00777 static void
00778 process_array_node(WN* wn, IPA_SECTION_TYPE type)
00779 {
00780 WN* array_base = WN_array_base(wn);
00781 while (array_base && (WN_operator(array_base) == OPR_ARRAY)) {
00782 array_base = WN_array_base(array_base);
00783 }
00784 Is_True (array_base != NULL, ("process_array_node: NULL array base\n"));
00785
00786 if (!OPERATOR_has_sym(WN_operator(array_base))) {
00787 return;
00788 }
00789 ST* array_st = WN_st(array_base);
00790
00791 if (!array_st || ST_sclass(array_st) == SCLASS_AUTO) {
00792 return;
00793 }
00794 TY_IDX array_ty_idx = (ST_sclass(array_st) != SCLASS_FORMAL ?
00795 ST_type(array_st) :
00796 TY_pointed(ST_type(array_st)));
00797
00798
00799 if (TY_kind(array_ty_idx) != KIND_ARRAY) {
00800 return;
00801 }
00802
00803
00804 if (ST_sclass(array_st) == SCLASS_FORMAL &&
00805 ST_level(array_st) != CURRENT_SYMTAB) {
00806 Current_summary_procedure->Set_has_incomplete_array_info();
00807 return;
00808 }
00809
00810 ACCESS_ARRAY* av = (ACCESS_ARRAY*) WN_MAP_Get(IPL_info_map, wn);
00811 Is_True (av, ("process_array_node: NULL access vector"));
00812
00813 MEM_POOL* apool = Array_Summary.Get_array_pool();
00814 DYN_ARRAY<LOOPINFO*> loops(apool);
00815 PROJECTED_REGION* proj_region = NULL;
00816 INT cd_idx = -1;
00817
00818
00819 WN* stmt = IPL_get_stmt_scf(wn);
00820
00821
00822 SUMMARY_CONTROL_DEPENDENCE* d = Get_controlling_stmt(stmt);
00823
00824
00825 while (d) {
00826 cd_idx = Get_cd_idx(d);
00827 if (d->Is_do_loop()) {
00828 LOOPINFO* l = Array_Summary.Get_cfg_node_array(cd_idx)->Get_loopinfo();
00829 loops.AddElement(l);
00830 if (!proj_region) {
00831 proj_region = CXX_NEW(PROJECTED_REGION(av, apool, l), apool);
00832 if (TY_AR_ndims(array_ty_idx) != av->Num_Vec()) {
00833 proj_region->Set_messy_region();
00834 }
00835 }
00836 proj_region->Project(l->Get_nest_level(), l);
00837 }
00838 d = Get_controlling_stmt(d->Get_wn());
00839 }
00840
00841
00842 INT loop_count = 0;
00843 for (WN* wnn = wn; wnn != NULL; wnn = LWN_Get_Parent(wnn))
00844 if (WN_operator(wnn) == OPR_DO_LOOP)
00845 loop_count++;
00846 INT bad_loop_count = loop_count - (loops.Lastidx() + 1);
00847 if (proj_region) {
00848 Min_Max_Fill_Region(proj_region, &loops, bad_loop_count);
00849 if (proj_region->Get_projected_kernel() &&
00850 proj_region->Get_projected_kernel()->Get_region()) {
00851 Min_Max_Fill_Region(proj_region->Get_projected_kernel()->Get_region(),
00852 &loops, bad_loop_count);
00853 }
00854 }
00855 else {
00856
00857
00858
00859 proj_region = CXX_NEW(PROJECTED_REGION(av, apool, NULL), apool);
00860 if (TY_AR_ndims(array_ty_idx) != av->Num_Vec()) {
00861 proj_region->Set_messy_region();
00862 }
00863 if (!proj_region->Is_messy_region()) {
00864 proj_region->Fill_Out();
00865 }
00866
00867 if (d) {
00868 d = Get_controlling_stmt(stmt);
00869 cd_idx = Get_cd_idx(d);
00870 if (d->Is_if_stmt()) {
00871 BOOL branch;
00872 INT stmt_idx;
00873 SUMMARY_STMT* summary_stmt =
00874 Search_for_summary_stmt(stmt, branch, stmt_idx);
00875 Is_True (summary_stmt, ("process_array_node: NULL summary stmt"));
00876 if (branch == FALSE) {
00877 cd_idx = Array_Summary.Get_cfg_node_array(cd_idx)->Get_else_index();
00878 }
00879 }
00880 }
00881 }
00882
00883 INT element_size = TY_size(TY_etype(array_ty_idx));
00884 INT id = Summary->Get_symbol_index(array_st);
00885
00886 if (cd_idx != -1) {
00887 CFG_NODE_INFO* cfg_node = Array_Summary.Get_cfg_node_array(cd_idx);
00888 switch (type) {
00889 case IPA_DEF:
00890 cfg_node->Add_def_array(proj_region, element_size, id);
00891 break;
00892 case IPA_USE:
00893 cfg_node->Add_use_array(proj_region, element_size, id);
00894 break;
00895 case IPA_REDUC:
00896 cfg_node->Add_array_reduc(id);
00897 break;
00898 }
00899 }
00900 else {
00901 switch (type) {
00902 case IPA_DEF:
00903 Cfg_entry->Add_may_def_array(proj_region, element_size, id);
00904 break;
00905 case IPA_USE:
00906 Cfg_entry->Add_may_use_array(proj_region, element_size, id);
00907 break;
00908 case IPA_REDUC:
00909 Cfg_entry->Add_array_may_reduc(id);
00910 break;
00911 }
00912 }
00913 }
00914
00915
00916
00917
00918 static void
00919 process_node(WN* wn, IPA_SECTION_TYPE type)
00920 {
00921 WN* lhs, *rhs, *parent_wn;
00922 INT32 map;
00923
00924 BOOL save_trace_sections = Trace_Sections;
00925 if (Get_Trace(TP_IPL, TT_IPL_VERBOSE))
00926 Trace_Sections = TRUE;
00927
00928 switch(WN_operator(wn))
00929 {
00930 case OPR_ISTORE:
00931 case OPR_MSTORE:
00932 lhs = WN_kid0(wn);
00933 rhs = WN_kid1(wn);
00934 process_node(lhs, IPA_USE);
00935 map = WN_MAP32_Get(IPL_reduc_map, wn);
00936 if (map > 0 && map < 5)
00937 process_node(rhs, IPA_REDUC);
00938 else
00939 process_node(rhs, IPA_DEF);
00940 break;
00941
00942
00943 case OPR_STID: {
00944
00945
00946 rhs = WN_kid0(wn);
00947 ST* lhs_st = WN_st(wn);
00948 process_node(rhs, IPA_USE);
00949 map = WN_MAP32_Get(IPL_reduc_map, wn);
00950 if (map > 0 && map < 5)
00951 process_scalar_reduc_node(wn, lhs_st);
00952 else
00953 process_scalar_def_node(wn, lhs_st);
00954 }
00955 break;
00956
00957 case OPR_CALL:
00958 case OPR_ICALL:
00959 case OPR_INTRINSIC_CALL: {
00960
00961 if (WN_opcode(wn) == OPC_VCALL && WN_Fake_Call_EH_Region(wn, Parent_Map))
00962 break;
00963
00964
00965 INT call_index = IPL_get_callsite_id(wn);
00966 FmtAssert(call_index != -1, ("Unknown call encountered \n"));
00967 SUMMARY_CALLSITE* c = Summary->Get_callsite(0) + call_index;
00968 for (INT i = 0; i < c->Get_param_count(); ++i) {
00969 process_actual_node(wn, WN_actual(wn ,i), call_index, i);
00970 }
00971 break;
00972 }
00973
00974 case OPR_ARRAY: {
00975 parent_wn = LWN_Get_Parent(wn);
00976 if (WN_operator(parent_wn) == OPR_ILOAD ||
00977 WN_operator(parent_wn) == OPR_MLOAD) {
00978
00979 map = WN_MAP32_Get(IPL_reduc_map, parent_wn);
00980 if (map != RED_NONE)
00981 process_array_node(wn, IPA_REDUC);
00982 process_array_node(wn, IPA_USE);
00983 } else if (WN_operator(parent_wn) == OPR_ISTORE) {
00984 process_array_node(wn, IPA_DEF);
00985 } else {
00986 process_array_node(wn, type);
00987 }
00988
00989 for (INT i = 0; i < WN_num_dim(wn); i++)
00990 process_node(WN_array_index(wn, i), IPA_USE);
00991 }
00992 break;
00993
00994 case OPR_LDID:
00995 parent_wn = LWN_Get_Parent(wn);
00996 if ((WN_operator(parent_wn) == OPR_ARRAY) ||
00997 (WN_operator(parent_wn) == OPR_PARM))
00998 ;
00999 else
01000 {
01001
01002 map = WN_MAP32_Get(IPL_reduc_map, wn);
01003 if (map > 0 && map < 5)
01004 process_scalar_node(wn, IPA_REDUC);
01005 else if (type != IPA_DEF)
01006 process_scalar_node(wn, IPA_USE);
01007 else
01008 process_scalar_node(wn, type);
01009 }
01010 break;
01011
01012
01013
01014 case OPR_MLOAD:
01015 case OPR_ILOAD: {
01016 parent_wn = LWN_Get_Parent(wn);
01017 if ((WN_operator(parent_wn) == OPR_ARRAY) ||
01018 (WN_operator(parent_wn) == OPR_PARM))
01019 ;
01020 else
01021 for (INT i=0; i<WN_kid_count(wn); ++i)
01022 process_node(WN_kid(wn, i), type);
01023 }
01024 break;
01025
01026 case OPR_IO: {
01027 for (INT i=0; i<WN_kid_count(wn); ++i)
01028 process_node(WN_kid(wn, i), type);
01029 }
01030 break;
01031
01032 default: {
01033 if ((OPCODE_is_expression(WN_opcode(wn))))
01034 {
01035 for (INT i=0; i<WN_kid_count(wn); ++i)
01036 process_node(WN_kid(wn, i), type);
01037 }
01038 }
01039 break;
01040 }
01041 Trace_Sections = save_trace_sections;
01042 }
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054 static void
01055 Process_Array_Formals(WN* wn_func,
01056 INT idx_formal_first,
01057 INT formal_count,
01058 MEM_POOL* mem_pool)
01059 {
01060 for (INT i = 0; i < formal_count; i++) {
01061 WN* wn_formal = WN_kid(wn_func, i);
01062 ST* st_formal = WN_st(wn_formal);
01063 FmtAssert(st_formal != NULL,
01064 ("Process_Array_Formals: Expecting non-NULL st_formal"));
01065 TY_IDX ty_idx_formal = ST_type(st_formal);
01066 if (TY_kind(ty_idx_formal) != KIND_POINTER)
01067 continue;
01068 TY_IDX ty_idx_pformal = TY_pointed(ty_idx_formal);
01069 if (TY_kind(ty_idx_pformal) != KIND_ARRAY)
01070 continue;
01071 INT element_size = TY_size(TY_etype(ty_idx_pformal));
01072 PROJECTED_REGION* pr = Projected_Region_From_St(wn_func, st_formal,
01073 mem_pool, FALSE, NULL);
01074 INT idx_st_formal = Summary->Get_symbol_index(st_formal);
01075 Cfg_entry->Add_formal_array(pr, element_size, idx_st_formal,
01076 idx_formal_first + i);
01077 }
01078 }
01079
01080
01081
01082
01083
01084 static void
01085 process_loops()
01086 {
01087 MEM_POOL* apool = Array_Summary.Get_array_pool();
01088 SUMMARY_CONTROL_DEPENDENCE* cd;
01089
01090 while (cd = Get_next_cd ()) {
01091 if (cd->Is_do_loop()) {
01092
01093
01094 DO_LOOP_INFO_BASE* dli =
01095 (DO_LOOP_INFO_BASE*) WN_MAP_Get(IPL_info_map, cd->Get_wn());
01096
01097
01098 INT cd_idx = Get_cd_idx(cd);
01099 LOOPINFO* l = CXX_NEW(LOOPINFO(apool, cd_idx), apool);
01100 l->Map_do_loop_info(dli);
01101
01102
01103 Array_Summary.Get_cfg_node_array(cd_idx)->Set_loopinfo(l);
01104 }
01105 }
01106 }
01107
01108
01109
01110
01111 static void
01112 Record_tlog(TLOG_INFO *tlog)
01113 {
01114 Ipl_record_tlog("LTKIND_CONST", 0, "Count %d", tlog->Get_cterm_count());
01115 Ipl_record_tlog("LTKIND_LINDEX", 0, "Count %d", tlog->Get_lterm_count());
01116 Ipl_record_tlog("LTKIND_IV_GLOBAL", 0,"Count %d",tlog->Get_iv_gterm_count());
01117 Ipl_record_tlog("LTKIND_IV", 0, "Count %d",tlog->Get_iv_term_count());
01118 Ipl_record_tlog("LTKIND_SUBSCR", 0, "Count %d",tlog->Get_sub_term_count());
01119 }
01120
01121
01122
01123
01124
01125
01126
01127 static BOOL Has_Threadprivate_Variable(WN* wn_tree)
01128 {
01129 if (WN_operator(wn_tree) == OPR_BLOCK) {
01130 for (WN* wn = WN_first(wn_tree); wn != NULL; wn = WN_next(wn))
01131 if (Has_Threadprivate_Variable(wn))
01132 return TRUE;
01133 } else {
01134 if (OPERATOR_has_sym(WN_operator(wn_tree)) && WN_st(wn_tree) != NULL
01135 && (ST_base(WN_st(wn_tree)) != WN_st(wn_tree)
01136 && ST_sclass(ST_base(WN_st(wn_tree))) == SCLASS_COMMON
01137 && ST_is_thread_private(ST_base(WN_st(wn_tree)))
01138 || ST_is_thread_private(WN_st(wn_tree)))) {
01139 return TRUE;
01140 }
01141 for (INT i = 0; i < WN_kid_count(wn_tree); i++)
01142 if (Has_Threadprivate_Variable(WN_kid(wn_tree, i)))
01143 return TRUE;
01144 }
01145 return FALSE;
01146 }
01147
01148
01149
01150
01151 void
01152 IPL_Access_Vector_To_Projected_Region(WN* w,
01153 SUMMARY_PROCEDURE* proc,
01154 INT pu_first_formal_idx,
01155 INT pu_last_formal_idx,
01156 INT pu_first_actual_idx,
01157 INT pu_last_actual_idx,
01158 INT pu_first_callsite_idx,
01159 INT pu_last_callsite_idx)
01160 {
01161 WN_ITER *wni;
01162 WN* wn;
01163 INT i;
01164 CFG_NODE_INFO *cfg_node_else = NULL;
01165
01166 FmtAssert((w != NULL),("NULL node in IPL_Access_Vector_To_Proj_Region\n"));
01167 INT max_cd_size = Get_max_cd_idx();
01168
01169 INT pu_formal_count = pu_last_formal_idx - pu_first_formal_idx + 1;
01170 INT pu_actual_count = pu_last_actual_idx - pu_first_actual_idx + 1;
01171 INT pu_callsite_count = pu_last_callsite_idx - pu_first_callsite_idx + 1;
01172
01173 Array_Summary.Init(pu_formal_count, pu_first_formal_idx,
01174 pu_actual_count, pu_first_actual_idx,
01175 pu_callsite_count, pu_first_callsite_idx,
01176 max_cd_size + 1);
01177
01178 WB_IPL_Set_Array_Summary(&Array_Summary);
01179
01180
01181
01182 CFG_NODE_INFO_ARRAY* cfg_nodes = Array_Summary.Get_cfg_node_array();
01183
01184
01185
01186
01187 INT if_count = 0;
01188
01189 for (i = 0; i <= max_cd_size; ++i) {
01190 SUMMARY_CONTROL_DEPENDENCE* cd = Get_cd_by_idx(i);
01191 if (cd->Is_if_stmt()) {
01192 ++if_count;
01193 }
01194 }
01195
01196 if (max_cd_size == -1) {
01197 proc->Set_has_incomplete_array_info();
01198 return;
01199 }
01200
01201
01202 cfg_nodes->Force_Alloc_array(max_cd_size+1+if_count);
01203 cfg_nodes->Setidx(max_cd_size+if_count);
01204
01205
01206 INT* map = Array_Summary.Get_cd_map();
01207
01208 INT if_idx = 0;
01209 for (i=0; i<=max_cd_size; ++i)
01210 {
01211 SUMMARY_CONTROL_DEPENDENCE *d = Get_cd_by_idx(i);
01212 CFG_NODE_INFO *cfg_node = &(*cfg_nodes)[i];
01213 cfg_node->Init(Array_Summary.Get_array_pool());
01214
01215
01216
01217 INT real_idx = Get_cd_real_idx(d);
01218
01219
01220 cfg_node->Set_cd_index(real_idx);
01221
01222
01223 map[real_idx - proc->Get_ctrl_dep_index()] = i;
01224
01225 if (d->Is_if_stmt())
01226 {
01227
01228 cfg_node->Set_type_if();
01229 ++if_idx;
01230 cfg_node->Set_else_index(max_cd_size+if_idx);
01231
01232
01233 cfg_node_else = &(*cfg_nodes)[max_cd_size+if_idx];
01234 cfg_node_else->Init(Array_Summary.Get_array_pool());
01235 cfg_node_else->Set_type_else();
01236 cfg_node_else->Set_if_index(i);
01237 }
01238
01239 else if (d->Is_do_loop())
01240 {
01241 cfg_node->Set_type_do_loop();
01242 }
01243 else
01244 {
01245 cfg_node->Set_type_entry();
01246 Cfg_entry = cfg_node;
01247 Cfg_entry_idx = i;
01248 }
01249
01250
01251 if (cfg_node->Is_if())
01252 {
01253 if (Get_cd_call_count(i, TRUE) > 0)
01254 cfg_node->Set_has_calls();
01255 if (Get_cd_call_count(i, FALSE) > 0)
01256 cfg_node_else->Set_has_calls();
01257 }
01258 else if (Get_cd_call_count(i) > 0)
01259 cfg_node->Set_has_calls();
01260 }
01261
01262 if (Cfg_entry == NULL) {
01263 proc->Set_has_incomplete_array_info();
01264 return;
01265 }
01266
01267 Current_summary_procedure = proc;
01268
01269
01270 MEM_POOL* apool = Array_Summary.Get_array_pool();
01271 IPL_Loopinfo_Map = CXX_NEW(LOOPINFO_TO_DLI_MAP(64,apool),apool);
01272 IPL_Access_Array_Map =
01273 CXX_NEW(PROJ_REGION_TO_ACCESS_ARRAY_MAP(128,apool),apool);
01274
01275
01276 process_loops();
01277
01278
01279 if (Has_Threadprivate_Variable(w)) {
01280 proc->Set_has_incomplete_array_info();
01281 return;
01282 }
01283
01284
01285 for (wni = WN_WALK_StmtIter(w); wni && WN_ITER_wn(wni) != 0;
01286 wni = WN_WALK_StmtNext(wni) ) {
01287 wn = WN_ITER_wn(wni);
01288 process_node(wn, IPA_UNKNOWN);
01289 }
01290
01291
01292 Process_Array_Formals(w, pu_first_formal_idx, pu_formal_count,
01293 Array_Summary.Get_array_pool());
01294
01295 Cfg_entry = NULL;
01296 Cfg_entry_idx = -1;
01297 }
01298
01299
01300
01301
01302 void
01303 IPL_Finalize_Projected_Regions(SUMMARY_PROCEDURE *p)
01304 {
01305 INT term_offset = 0;
01306
01307 if (Get_Trace(TP_PTRACE1, TP_PTRACE1_IPA)) {
01308 term_offset = Array_Summary_Output->Get_term_offset();
01309 }
01310
01311 Map_asections(&Array_Summary, p);
01312
01313 if (Get_Trace(TP_PTRACE1, TP_PTRACE1_IPA)) {
01314 Array_Summary.Record_tlogs(Array_Summary_Output->Get_term_array(),
01315 term_offset+1);
01316 Record_tlog(Array_Summary.Get_tlog_info());
01317 }
01318
01319 Array_Summary.Finalize();
01320 }
01321