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 #define __STDC_LIMIT_MACROS
00060 #include <stdint.h>
00061 #include <alloca.h>
00062
00063 #include "be_symtab.h"
00064 #include "ipa_cg.h"
00065 #include "ipa_option.h"
00066 #include "ipa_preopt.h"
00067 #include "ipa_summary.h"
00068 #include "ipa_section_annot.h"
00069 #include "ipa_section_main.h"
00070 #include "ipa_section_prop.h"
00071 #include "ipaa.h"
00072 #include "config_ipa.h"
00073 #include "ipa_lno_util.h"
00074 #include "ipa_cost.h"
00075
00076 MEM_POOL IPA_array_prop_pool;
00077 BOOL Trace_IPA_Sections = FALSE;
00078
00079 static BOOL IPA_array_prop_pool_initialized = FALSE;
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100 static BOOL
00101 Is_formal_modified (const IPA_NODE* node,
00102 const SUMMARY_FORMAL& formal)
00103 {
00104 if (IPA_Enable_Simple_Alias) {
00105 IPAA_NODE_INFO* ipaa = node->Mod_Ref_Info();
00106 Is_True(ipaa, ("NULL ipaa info in is_mod\n"));
00107 INT position = formal.Get_position();
00108 return (ipaa->Is_formal_dmod_elmt(position) ||
00109 ipaa->Is_formal_imod_elmt(position));
00110 }
00111 return TRUE;
00112 }
00113
00114 static BOOL
00115 Is_global_modified (const IPA_NODE* node,
00116 ST_IDX base_st_idx)
00117 {
00118 if (IPA_Enable_Simple_Alias) {
00119 IPAA_NODE_INFO* ipaa = node->Mod_Ref_Info();
00120 Is_True(ipaa, ("NULL ipaa info in is_mod\n"));
00121 return (ipaa->Is_def_elmt(ST_IDX_index(base_st_idx)));
00122 }
00123 return TRUE;
00124 }
00125
00126
00127
00128
00129
00130 static BOOL
00131 Is_constant_val(SUMMARY_VALUE* summary_val, INT64* val)
00132 {
00133 if (summary_val->Is_const_st()) {
00134 TCON_IDX tcon_idx = ST_tcon(ST_ptr(summary_val->Get_const_st_idx()));
00135 return Targ_Is_Integral(Tcon_Table[tcon_idx], val);
00136 }
00137
00138 if (summary_val->Is_int_const()) {
00139 *val = summary_val->Get_int_const_value();
00140 return TRUE;
00141 }
00142
00143 return FALSE;
00144 }
00145
00146
00147
00148
00149 static BOOL
00150 Is_constant_global(const IPA_NODE* n,
00151 INT64* val,
00152 ST_IDX base_st_idx,
00153 INT64 offset,
00154 TYPE_ID mtype)
00155 {
00156
00157 TCON tcon;
00158
00159 if (ST_is_const_initialized_scalar(ST_ptr(base_st_idx), offset, tcon)) {
00160 return Targ_Is_Integral(tcon, val);
00161 }
00162
00163
00164 GLOBAL_ANNOT* gannot = n->Global_Annot();
00165 if (gannot) {
00166 const GLOBAL_VALUE* gval =
00167 gannot->Find(GLOBAL_ANNOT::Index(base_st_idx), offset, 0);
00168 if (gval) {
00169 SUMMARY_VALUE* summary_value = gval->Value();
00170 if (summary_value &&
00171 summary_value->Get_mtype() == mtype &&
00172 Is_constant_val(summary_value, val)) {
00173 return TRUE;
00174 }
00175 }
00176 }
00177
00178 return FALSE;
00179 }
00180
00181
00182
00183
00184 static void
00185 Update_term_with_formal_constant (const IPA_NODE* node,
00186 const SUMMARY_FORMAL& formal,
00187 TERM* t)
00188 {
00189
00190 VALUE_DYN_ARRAY* cprop_annot = node->Cprop_Annot();
00191 if (cprop_annot && cprop_annot != (void*)-1) {
00192 SUMMARY_VALUE* annot_node = &(*cprop_annot)[formal.Get_position()];
00193 INT64 val;
00194 if (Is_constant_val(annot_node, &val)) {
00195 new (t) TERM(LTKIND_CONST, (COEFF)val*t->Get_coeff(), CONST_DESC, 0);
00196 }
00197 }
00198 }
00199
00200
00201
00202
00203 static void
00204 Update_term_with_global_constant (const IPA_NODE* node,
00205 ST_IDX base_st_idx,
00206 INT64 offset,
00207 TYPE_ID mtype,
00208 TERM* t)
00209 {
00210
00211 INT64 val;
00212 if (Is_constant_global(node, &val, base_st_idx, offset, mtype)) {
00213 new (t) TERM(LTKIND_CONST, (COEFF)val*t->Get_coeff(), CONST_DESC, 0);
00214 }
00215 }
00216
00217
00218
00219
00220
00221 static LINEX*
00222 update_linex_with_constant_mod(IPA_NODE* node, LINEX* linex, BOOL* modified)
00223 {
00224 INT32 size;
00225 IVAR* ipa_ivar = IPA_get_ivar_array(node, size);
00226 SUMMARY_SYMBOL* ipa_symbol = IPA_get_symbol_array(node);
00227 SUMMARY_FORMAL* ipa_formal = IPA_get_formal_array(node);
00228 SUMMARY_PROCEDURE* ipa_proc = node->Summary_Proc();
00229
00230 *modified = FALSE;
00231
00232 for (INT i = 0; i <= linex->Num_terms(); ++i) {
00233
00234 TERM* term = linex->Get_term(i);
00235 switch(term->Get_type()) {
00236
00237 case LTKIND_CONST:
00238 case LTKIND_LINDEX:
00239 case LTKIND_SUBSCR:
00240 break;
00241
00242 case LTKIND_IV: {
00243 const IVAR& ivar = ipa_ivar[term->Get_desc()];
00244 if (ivar.Is_Formal()) {
00245 INT32 idx = ipa_proc->Get_formal_index() + ivar.Formal_Position();
00246 const SUMMARY_FORMAL& formal = ipa_formal[idx];
00247 *modified |= Is_formal_modified(node, formal);
00248 if (ivar.Offset() == 0) {
00249 Update_term_with_formal_constant(node, formal, term);
00250 }
00251 }
00252 else {
00253 ST* st = ST_ptr(ivar.St_Idx());
00254 ST_IDX base_st = ST_base_idx(st);
00255 INT64 offset = ST_ofst(st) + ivar.Offset();
00256 TYPE_ID mtype = ivar.Mtype();
00257 Update_term_with_global_constant(node, base_st, offset, mtype, term);
00258 *modified |= Is_global_modified(node, base_st);
00259 }
00260 break;
00261 }
00262
00263 default:
00264 Fail_FmtAssertion("update_linex_with_constant_mod: LTKIND_NONE");
00265 break;
00266 }
00267 }
00268
00269 IPA_NODE_SECTION_INFO *section = node->Section_Annot();
00270 linex->Simplify();
00271
00272 return linex;
00273 }
00274
00275
00276
00277
00278 static void
00279 update_loop_info(IPA_NODE* node, LOOPINFO* loop_info)
00280 {
00281 BOOL is_mod;
00282
00283 loop_info->Create_linex(IPA_get_term_array(node));
00284
00285 LINEX* upper_linex = loop_info->Get_upper_linex();
00286 if (upper_linex && !loop_info->Is_messy_ub()) {
00287 LINEX* result = update_linex_with_constant_mod(node, upper_linex, &is_mod);
00288 result->Copy(upper_linex);
00289 }
00290
00291 LINEX* lower_linex = loop_info->Get_lower_linex();
00292 if (lower_linex && !loop_info->Is_messy_lb()) {
00293 LINEX* result = update_linex_with_constant_mod(node, lower_linex, &is_mod);
00294 result->Copy(lower_linex);
00295 }
00296
00297 LINEX* step_linex = loop_info->Get_step_linex();
00298 if (step_linex && !loop_info->Is_messy_step()) {
00299 LINEX* result = update_linex_with_constant_mod(node, step_linex, &is_mod);
00300 result->Copy(step_linex);
00301 }
00302 }
00303
00304
00305
00306
00307 static void
00308 update_projected_region(IPA_NODE* node, PROJECTED_REGION* p)
00309 {
00310 INT start_idx = p->Get_id();
00311 INT count = p->Get_num_dims();
00312 INT i;
00313
00314
00315
00316 PROJECTED_NODE* copy_pn = (PROJECTED_NODE*)
00317 MEM_POOL_Alloc(&IPA_array_prop_pool, count * sizeof(PROJECTED_NODE));
00318 bcopy(IPA_get_projected_node_array(node) + start_idx,
00319 copy_pn,
00320 count * sizeof(PROJECTED_NODE));
00321 for (i = 0; i < count; i++) {
00322 copy_pn[i].Set_Mem_Pool(&IPA_array_prop_pool);
00323 }
00324 start_idx = 0;
00325
00326 for (i = start_idx; i < start_idx + count; ++i) {
00327
00328 BOOL has_mod;
00329 LINEX* l;
00330
00331
00332 PROJECTED_NODE* pnode = ©_pn[i];
00333 pnode->Create_linex(IPA_get_term_array(node));
00334
00335 LINEX* upper_linex = pnode->Get_upper_linex();
00336 if (upper_linex) {
00337 l = update_linex_with_constant_mod(node, upper_linex, &has_mod);
00338 pnode->Set_upper_linex(l);
00339 if (has_mod) {
00340 p->Set_messy_region();
00341 }
00342 }
00343
00344 LINEX* lower_linex = pnode->Get_lower_linex();
00345 if (lower_linex) {
00346 l = update_linex_with_constant_mod(node, lower_linex, &has_mod);
00347 pnode->Set_lower_linex(l);
00348 if (has_mod) {
00349 p->Set_messy_region();
00350 }
00351 }
00352
00353 LINEX* step_linex = pnode->Get_step_linex();
00354 if (step_linex) {
00355 l = update_linex_with_constant_mod(node, step_linex, &has_mod);
00356 pnode->Set_step_linex(l);
00357 if (has_mod) {
00358 p->Set_messy_region();
00359 }
00360 }
00361
00362 LINEX* segment_length_linex = pnode->Get_segment_length_linex();
00363 if (segment_length_linex) {
00364 l = update_linex_with_constant_mod(node, segment_length_linex, &has_mod);
00365 pnode->Set_segment_length_linex(l);
00366 if (has_mod) {
00367 p->Set_messy_region();
00368 }
00369 }
00370
00371 LINEX* segment_stride_linex = pnode->Get_segment_stride_linex();
00372 if (segment_stride_linex) {
00373 l = update_linex_with_constant_mod(node, segment_stride_linex, &has_mod);
00374 pnode->Set_segment_stride_linex(l);
00375 if (has_mod) {
00376 p->Set_messy_region();
00377 }
00378 }
00379 }
00380
00381 IPA_NODE_SECTION_INFO* info = node->Section_Annot();
00382 PROJECTED_ARRAY* parray = CXX_NEW(PROJECTED_ARRAY(info->Mem_Pool()),
00383 info->Mem_Pool());
00384 p->Set_projected_array(parray);
00385 for (i = start_idx; i < start_idx + count; ++i) {
00386 p->Set_projected_node(©_pn[i]);
00387 }
00388 }
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398 static void
00399 update_region(IPA_NODE* node, REGION_ARRAYS* r)
00400 {
00401 INT32 start_idx = r->Get_idx();
00402 INT32 count = r->Get_count();
00403 INT i;
00404
00405
00406
00407 PROJECTED_REGION* copy_pr = (PROJECTED_REGION*)
00408 MEM_POOL_Alloc(&IPA_array_prop_pool, sizeof(PROJECTED_REGION) * count);
00409 bcopy(IPA_get_proj_region_array(node) + start_idx,
00410 copy_pr,
00411 count * sizeof(PROJECTED_REGION));
00412 for (i = 0; i < count; i++) {
00413 copy_pr[i].Set_Mem_Pool(&IPA_array_prop_pool);
00414 }
00415 start_idx = 0;
00416
00417 IPA_NODE_SECTION_INFO* info = node->Section_Annot();
00418 SUMMARY_SYMBOL* sym = IPA_get_symbol_array(node) + r->Get_sym_id();
00419 BOOL is_formal = FALSE;
00420 BOOL is_global = FALSE;
00421 INT position;
00422
00423 if (sym->Is_formal()) {
00424
00425 position = IPA_get_formal_array(node)[sym->Get_findex()].Get_position();
00426 is_formal = TRUE;
00427 }
00428 else if (ST_IDX_level(sym->St_idx()) == GLOBAL_SYMTAB) {
00429 is_global = TRUE;
00430 }
00431
00432 for (i = start_idx; i < start_idx + count; ++i) {
00433
00434 PROJECTED_REGION* pr;
00435 PROJECTED_REGION* p = ©_pr[i - start_idx];
00436 if (!p->Is_messy_region()) {
00437 update_projected_region(node, p);
00438 }
00439
00440
00441 if (is_formal) {
00442 if (r->Is_def()) {
00443 if (pr = info->Get_formal_mod_region(position))
00444 pr->May_Union(*p, Trace_IPA_Sections);
00445 else
00446 info->Set_formal_mod_region(position, p);
00447 }
00448 if (r->Is_use()) {
00449 if (pr = info->Get_formal_ref_region(position))
00450 pr->May_Union(*p, Trace_IPA_Sections);
00451 else
00452 info->Set_formal_ref_region(position, p);
00453 }
00454 if (r->Is_formal()) {
00455 if (pr = info->Get_formal_dcl_region(position))
00456 pr->May_Union(*p, Trace_IPA_Sections);
00457 else
00458 info->Set_formal_dcl_region(position, p);
00459 }
00460 }
00461 else if (is_global) {
00462 BOOL is_messy;
00463 if (r->Is_def() || r->Is_may_def()) {
00464 if (pr = info->Global_Array_Region(sym, &is_messy, p, TRUE))
00465 if (pr != p)
00466 pr->May_Union(*p, Trace_IPA_Sections);
00467 }
00468 if (r->Is_use() || r->Is_may_use()) {
00469 if (pr = info->Global_Array_Region(sym, &is_messy, p, FALSE))
00470 if (pr != p)
00471 pr->May_Union(*p, Trace_IPA_Sections);
00472 }
00473 }
00474 }
00475 }
00476
00477
00478
00479
00480
00481
00482
00483 static void
00484 update_mod_const_sections(IPA_NODE *node)
00485 {
00486
00487 Init_IPA_Print_Arrays (node);
00488
00489 CFG_NODE_INFO* ipa_cfg = IPA_get_cfg_node_array (node);
00490 REGION_ARRAYS* ipa_regions_array = IPA_get_region_array (node);
00491 LOOPINFO* ipa_loopinfo = IPA_get_loopinfo_array (node);
00492 SUMMARY_PROCEDURE* ipa_proc = node->Summary_Proc();
00493
00494 if (ipa_proc->Has_incomplete_array_info())
00495 return;
00496
00497
00498 INT start_idx = ipa_proc->Get_array_section_index();
00499 INT end_idx = ipa_proc->Get_array_section_count() + start_idx;
00500 INT i;
00501 for (i = start_idx; i < end_idx; ++ i) {
00502
00503
00504 CFG_NODE_INFO* cfg_info = &ipa_cfg[i];
00505 INT start_region_idx = cfg_info->Get_def_index();
00506 INT end_region_idx = cfg_info->Get_def_count() + start_region_idx;
00507 INT j;
00508
00509 for (j = start_region_idx; j < end_region_idx; ++j) {
00510 update_region(node, &ipa_regions_array[j]);
00511 }
00512
00513
00514 start_region_idx = cfg_info->Get_use_index();
00515 end_region_idx = cfg_info->Get_use_count() + start_region_idx;
00516 for (j = start_region_idx; j < end_region_idx; ++j) {
00517 update_region(node, &ipa_regions_array[j]);
00518 }
00519
00520
00521 start_region_idx = cfg_info->Get_param_index();
00522 end_region_idx = cfg_info->Get_param_count() + start_region_idx;
00523 for (j = start_region_idx; j < end_region_idx; ++j) {
00524 update_region(node, &ipa_regions_array[j]);
00525 }
00526
00527
00528 start_region_idx = cfg_info->Get_formal_index();
00529 end_region_idx = cfg_info->Get_formal_count() + start_region_idx;
00530 for (j = start_region_idx; j < end_region_idx; ++j) {
00531 update_region(node, &ipa_regions_array[j]);
00532 }
00533
00534
00535 if (cfg_info->Is_do_loop()) {
00536
00537
00538 if (ipa_loopinfo != NULL) {
00539 LOOPINFO* l = &ipa_loopinfo[cfg_info->Get_loop_index()-1];
00540 LOOPINFO* copy_li = (LOOPINFO*)
00541 MEM_POOL_Alloc(&IPA_array_prop_pool, sizeof(LOOPINFO));
00542 bcopy(l, copy_li, sizeof(LOOPINFO));
00543 copy_li->Set_Mem_Pool(&IPA_array_prop_pool);
00544 update_loop_info(node, copy_li);
00545 }
00546 }
00547 }
00548 }
00549
00550
00551
00552
00553 static void
00554 init_node_section_annot (IPA_NODE* node)
00555 {
00556 if (node->Section_Annot() == NULL) {
00557
00558
00559
00560 if (IPA_Enable_Preopt &&
00561 node->Has_Propagated_Const() &&
00562 (node->Summary_Proc()->Has_messy_regions() ||
00563 (IPA_Max_Node_Clones_Set && IPA_Max_Node_Clones != 0))) {
00564 IPA_Preoptimize(node);
00565 }
00566
00567 SUMMARY_PROCEDURE* ipa_proc = node->Summary_Proc();
00568
00569 IPA_NODE_SECTION_INFO* asection =
00570 CXX_NEW(IPA_NODE_SECTION_INFO(&IPA_array_prop_pool),
00571 &IPA_array_prop_pool);
00572 node->Set_Section_Annot(asection);
00573
00574 INT count = node->Num_Formals();
00575 if (count > 0) {
00576
00577 STATE_ARRAY* state =
00578 CXX_NEW(STATE_ARRAY(&IPA_array_prop_pool), &IPA_array_prop_pool);
00579 state->Force_Alloc_array(count);
00580 state->Setidx(count-1);
00581 asection->Set_formals(state);
00582
00583 SUMMARY_FORMAL* formal =
00584 IPA_get_formal_array(node) + ipa_proc->Get_formal_index();
00585 for (INT j = 0; j < count; ++j, ++formal) {
00586 (*state)[j].Init();
00587 if (TY_kind(formal->Get_ty()) != KIND_POINTER ||
00588 TY_kind(TY_pointed(formal->Get_ty())) != KIND_ARRAY) {
00589 (*state)[j].Set_is_scalar();
00590 }
00591 }
00592 }
00593
00594 CFG_NODE_INFO* ipa_cfg = IPA_get_cfg_node_array (node);
00595 if (ipa_cfg) {
00596 if (ipa_proc->Get_array_section_count() != 0) {
00597 asection->Set_cfg_node(&ipa_cfg[ipa_proc->Get_array_section_index()]);
00598 }
00599 }
00600
00601 update_mod_const_sections(node);
00602
00603 Update_Execution_Cost(node, &IPA_array_prop_pool);
00604 }
00605 }
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615 IPA_ARRAY_DF_FLOW::IPA_ARRAY_DF_FLOW(IPA_CALL_GRAPH*,
00616 DF_DIRECTION ddf,
00617 MEM_POOL *m)
00618 : IPA_DATA_FLOW(ddf,m)
00619 {
00620
00621 if (!IPA_array_prop_pool_initialized) {
00622 MEM_POOL_Initialize(&IPA_array_prop_pool, "ipa_array_prop_pool", 0);
00623 IPA_array_prop_pool_initialized = TRUE;
00624 }
00625
00626 Trace_IPA_Sections = Get_Trace(TP_IPA, IPA_TRACE_SECTIONS);
00627 }
00628
00629
00630
00631
00632
00633
00634 void
00635 IPA_ARRAY_DF_FLOW::InitializeNode(void* n)
00636 {
00637
00638 IPA_NODE* node = (IPA_NODE*) n;
00639 IP_FILE_HDR& file_hdr = node->File_Header();
00640 if (IP_FILE_HDR_section_annot(file_hdr) == NULL) {
00641 INT32 size;
00642 IVAR* ivar = IPA_get_ivar_array(node, size);
00643 SECTION_FILE_ANNOT* section_annot =
00644 CXX_NEW(SECTION_FILE_ANNOT(ivar, &IPA_array_prop_pool),
00645 &IPA_array_prop_pool);
00646 Set_IP_FILE_HDR_section_annot(file_hdr, section_annot);
00647 }
00648
00649 init_node_section_annot(node);
00650 }
00651
00652
00653
00654
00655 void*
00656 IPA_ARRAY_DF_FLOW::Meet(void*, void*, INT*)
00657 {
00658 return 0;
00659 }
00660
00661
00662
00663
00664
00665 void
00666 IPA_ARRAY_DF_FLOW::PostProcessIO(void* n)
00667 {
00668 if (!n) {
00669 return;
00670 }
00671 IPA_NODE* node = (IPA_NODE*) n;
00672
00673
00674 if (node->Has_Must_Inline_Attrib()) {
00675 return;
00676 }
00677
00678
00679 if (node->Summary_Proc()->Has_incomplete_array_info()) {
00680 return;
00681 }
00682
00683 IPA_NODE_SECTION_INFO* section = node->Section_Annot();
00684 IPAA_NODE_INFO* modref = node->Mod_Ref_Info();
00685
00686 if (!section || !modref) {
00687 return;
00688 }
00689
00690
00691
00692 UINT32 num_formals = node->Num_Formals();
00693 for (UINT32 pos = 0; pos < num_formals; ++pos) {
00694 STATE* formal = section->Get_formal(pos);
00695 if (formal->Is_scalar()) {
00696 if ((modref->Is_formal_dmod_elmt(pos) ||
00697 modref->Is_formal_imod_elmt(pos)) &&
00698 (modref->Is_formal_dref_elmt(pos) ||
00699 modref->Is_formal_iref_elmt(pos))) {
00700 return;
00701 }
00702 }
00703 else {
00704 PROJECTED_REGION* mod = formal->Get_projected_mod_region();
00705 PROJECTED_REGION* ref = formal->Get_projected_ref_region();
00706 if (mod && (mod->Is_messy_region() || (ref && ref->Is_messy_region()))) {
00707 return;
00708 }
00709 }
00710 }
00711
00712 SUMMARY_SYMBOL* symbols = IPA_get_symbol_array(node);
00713 SUMMARY_ACTUAL* actuals = IPA_get_actual_array(node);
00714
00715
00716 ST_IDX st_idx;
00717 GLOBAL_ARRAY_LIST* ga_list;
00718 GLOBAL_ARRAY_TABLE* ga_table = section->Global_Array_Table();
00719 GLOBAL_ARRAY_TABLE_ITER ga_table_iter(ga_table);
00720 while (ga_table_iter.Step(&st_idx, &ga_list)) {
00721 if (ga_list->Is_messy()) {
00722 return;
00723 }
00724 GLOBAL_ARRAY_LIST_ITER ga_list_iter(ga_list);
00725 for (ga_list_iter.First(); !ga_list_iter.Is_Empty(); ga_list_iter.Next()) {
00726 GLOBAL_ARRAY_INFO* ga_info = ga_list_iter.Cur();
00727 PROJECTED_REGION* mod = ga_info->Get_projected_mod_region();
00728 PROJECTED_REGION* ref = ga_info->Get_projected_ref_region();
00729 if (mod && (mod->Is_messy_region() || (ref && ref->Is_messy_region()))) {
00730 return;
00731 }
00732 }
00733 }
00734
00735
00736
00737
00738 IPA_SUCC_ITER edge_iter(IPA_Call_Graph, node);
00739 for (edge_iter.First(); !edge_iter.Is_Empty(); edge_iter.Next()) {
00740 IPA_EDGE* e = edge_iter.Current_Edge();
00741 if (!e) {
00742 continue;
00743 }
00744 IPA_NODE* callee = IPA_Call_Graph->Callee(e);
00745 IPA_NODE_SECTION_INFO* section = callee->Section_Annot();
00746 IPAA_NODE_INFO* modref = node->Mod_Ref_Info();
00747 if (!section || !modref) {
00748 node->Set_Noinline_Attrib();
00749 return;
00750 }
00751
00752 INT32 actual_index = e->Summary_Callsite()->Get_actual_index();
00753 UINT32 num_formals = callee->Num_Formals();
00754 for (UINT32 pos = 0; pos < num_formals; ++pos) {
00755 STATE* formal = section->Get_formal(pos);
00756 if (formal->Is_scalar()) {
00757 if ((modref->Is_formal_dmod_elmt(pos) ||
00758 modref->Is_formal_imod_elmt(pos)) &&
00759 (modref->Is_formal_dref_elmt(pos) ||
00760 modref->Is_formal_iref_elmt(pos))) {
00761 INT32 symbol_index = actuals[actual_index+pos].Get_symbol_index();
00762 if (symbol_index != -1 &&
00763 ST_IDX_level(symbols[symbol_index].St_idx()) != GLOBAL_SYMTAB) {
00764 node->Set_Noinline_Attrib();
00765 return;
00766 }
00767 }
00768 }
00769 else {
00770 PROJECTED_REGION* mod = formal->Get_projected_mod_region();
00771 PROJECTED_REGION* ref = formal->Get_projected_ref_region();
00772
00773
00774
00775 if (mod && (mod->Is_messy_region() || ref)) {
00776 INT32 symbol_index = actuals[actual_index+pos].Get_symbol_index();
00777 if (symbol_index != -1 &&
00778 ST_IDX_level(symbols[symbol_index].St_idx()) != GLOBAL_SYMTAB) {
00779 node->Set_Noinline_Attrib();
00780 return;
00781 }
00782 }
00783 }
00784 }
00785 }
00786 }
00787
00788
00789
00790
00791
00792 void*
00793 IPA_ARRAY_DF_FLOW::Trans(void*, void*, void* vertex, INT* change)
00794 {
00795 *change |= Merge_Section((IPA_NODE*)vertex);
00796 return 0;
00797 }
00798
00799
00800
00801
00802 void
00803 IPA_ARRAY_DF_FLOW::Print_entry(FILE* fp, void*, void* n)
00804 {
00805 IPA_NODE* node = (IPA_NODE*)n;
00806 node->Print(fp);
00807 if (node->Section_Annot()) {
00808 node->Section_Annot()->Print(fp);
00809 }
00810 }
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823 IPA_FORMALS_IN_ARRAY_SECTION_DF::
00824 IPA_FORMALS_IN_ARRAY_SECTION_DF(IPA_CALL_GRAPH*,
00825 DF_DIRECTION ddf,
00826 MEM_POOL* m)
00827 : IPA_DATA_FLOW(ddf,m)
00828 {}
00829
00830
00831
00832
00833 void*
00834 IPA_FORMALS_IN_ARRAY_SECTION_DF::Meet(void*, void*, INT*)
00835 {
00836 return 0;
00837 }
00838
00839
00840
00841
00842
00843 static SUMMARY_EXPR* expressions;
00844 static SUMMARY_VALUE* values;
00845 static SUMMARY_FORMAL* formals;
00846
00847 static BOOL
00848 Value_has_only_formals(SUMMARY_VALUE* value,
00849 mBOOL* formals_used);
00850
00851
00852
00853
00854
00855 static BOOL
00856 Expr_has_only_formals(SUMMARY_EXPR* expr,
00857 mBOOL* formals_used)
00858 {
00859 if (expr->Is_expr_unknown()) {
00860 return FALSE;
00861 }
00862 if (expr->Has_const_operand()) {
00863 INT32 kid = expr->Get_kid();
00864 INT32 non_const_idx = expr->Get_node_index(kid);
00865 if (expr->Is_expr_value(kid)) {
00866 return Value_has_only_formals(values + non_const_idx, formals_used);
00867 }
00868 else if (expr->Is_expr_expr(kid)) {
00869 return Expr_has_only_formals(expressions + non_const_idx, formals_used);
00870 }
00871 else {
00872 return FALSE;
00873 }
00874 }
00875 else {
00876 INT32 kid0_idx = expr->Get_node_index(0);
00877 INT32 kid1_idx = expr->Get_node_index(1);
00878 if (((expr->Is_expr_value(0) &&
00879 Value_has_only_formals(values + kid0_idx, formals_used)) ||
00880 (expr->Is_expr_expr(0) &&
00881 Expr_has_only_formals(expressions + kid0_idx, formals_used))) &&
00882 ((expr->Is_expr_value(1) &&
00883 Value_has_only_formals(values + kid1_idx, formals_used)) ||
00884 (expr->Is_expr_expr(1) &&
00885 Expr_has_only_formals(expressions + kid1_idx, formals_used)))) {
00886 return TRUE;
00887 }
00888 else {
00889 return FALSE;
00890 }
00891 }
00892 }
00893
00894
00895
00896
00897 static BOOL
00898 Value_has_only_formals(SUMMARY_VALUE* value,
00899 mBOOL* formals_used)
00900 {
00901 if (value->Is_formal()) {
00902 formals_used[formals[value->Get_formal_index()].Get_position()] = TRUE;
00903 return TRUE;
00904 }
00905 else if (value->Is_expr()) {
00906 SUMMARY_EXPR* expr = expressions + value->Get_expr_index();
00907 return Expr_has_only_formals(expr, formals_used);
00908 }
00909 else if (value->Is_int_const() || value->Is_const_st()) {
00910 return TRUE;
00911 }
00912 else {
00913 return FALSE;
00914 }
00915 }
00916
00917
00918
00919
00920
00921 void*
00922 IPA_FORMALS_IN_ARRAY_SECTION_DF::Trans(void*,
00923 void*,
00924 void* vertex,
00925 INT* change)
00926 {
00927 IPA_NODE* node = (IPA_NODE*)vertex;
00928 UINT32 num_formals = node->Num_Formals();
00929 if (num_formals == 0) return 0;
00930
00931
00932 mBOOL* formals_used = (mBOOL*) alloca(num_formals * sizeof(mBOOL));
00933
00934
00935 expressions = IPA_get_expr_array (node);
00936 values = IPA_get_value_array (node);
00937 formals = IPA_get_formal_array (node);
00938
00939 SUMMARY_FORMAL* caller_formals = formals
00940 + node->Summary_Proc()->Get_formal_index();
00941 SUMMARY_ACTUAL* actuals = IPA_get_actual_array(node);
00942 SUMMARY_SYMBOL* symbols = IPA_get_symbol_array(node);
00943
00944
00945 IPA_SUCC_ITER edge_iter(IPA_Call_Graph, node);
00946 for (edge_iter.First(); !edge_iter.Is_Empty(); edge_iter.Next()) {
00947 IPA_EDGE* e = edge_iter.Current_Edge();
00948 if (e) {
00949 SUMMARY_CALLSITE* callsite = e->Summary_Callsite();
00950 SUMMARY_ACTUAL* call_actuals = actuals + callsite->Get_actual_index();
00951 IPA_NODE* callee = IPA_Call_Graph->Callee(e);
00952 SUMMARY_PROCEDURE* callee_proc = callee->Summary_Proc();
00953 SUMMARY_SYMBOL* callee_symbols = IPA_get_symbol_array(callee);
00954 SUMMARY_FORMAL* callee_formals = IPA_get_formal_array(callee)
00955 + callee_proc->Get_formal_index();
00956 UINT32 count = callee->Num_Formals();
00957 if (count > callsite->Get_param_count()) {
00958 count = callsite->Get_param_count();
00959 }
00960
00961 for (INT32 i = 0; i < count; ++i) {
00962 INT32 callee_formal_sym_idx = callee_formals[i].Get_symbol_index();
00963 if (callee_symbols[callee_formal_sym_idx].Used_in_array_section()) {
00964
00965 INT32 actual_value_idx = call_actuals[i].Get_value_index();
00966 if (actual_value_idx != -1) {
00967 bzero(formals_used, num_formals * sizeof(mBOOL));
00968 SUMMARY_VALUE* actual_value = values + actual_value_idx;
00969 if (Value_has_only_formals(actual_value, formals_used)) {
00970
00971 for (INT32 j = 0; j < num_formals; ++j) {
00972 if (formals_used[j]) {
00973 INT32 formal_sym_idx = caller_formals[j].Get_symbol_index();
00974 if (!symbols[formal_sym_idx].Used_in_array_section()) {
00975 symbols[formal_sym_idx].Set_used_in_array_section();
00976 *change = TRUE;
00977 }
00978 }
00979 }
00980 }
00981 }
00982 }
00983 }
00984 }
00985 }
00986 return 0;
00987 }
00988
00989
00990
00991
00992 void
00993 IPA_FORMALS_IN_ARRAY_SECTION_DF::Print_entry(FILE* fp,
00994 void*,
00995 void* vertex)
00996 {
00997 IPA_NODE* node = (IPA_NODE*)vertex;
00998 UINT32 num_formals = node->Num_Formals();
00999 if (num_formals == 0) return;
01000
01001 SUMMARY_SYMBOL* symbols = IPA_get_symbol_array(node);
01002 SUMMARY_FORMAL* formals = IPA_get_formal_array(node)
01003 + node->Summary_Proc()->Get_formal_index();
01004
01005 fprintf(fp,"PU %s should be cloned", node->Name());
01006 BOOL should_clone = FALSE;
01007
01008 for (INT32 i = 0; i < num_formals; ++i) {
01009 SUMMARY_SYMBOL* s = symbols + formals[i].Get_symbol_index();
01010 if (s->Used_in_array_section()) {
01011 fprintf(fp, "\n if formal [%d] can be exposed as constant", i);
01012 should_clone = TRUE;
01013 }
01014 }
01015
01016 if (!should_clone) {
01017 fprintf(fp, " - NOT!");
01018 }
01019 fprintf(fp, "\n");
01020 }
01021