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 #ifndef ipl_summarize_template_INCLUDED
00059 #define ipl_summarize_template_INCLUDED
00060
00061 #ifndef wn_tree_util_INCLUDED
00062 #include "wn_tree_util.h"
00063 #endif
00064
00065 #ifndef ipl_summarize_util_INCLUDED
00066 #include "ipl_summarize_util.h"
00067 #endif // ipl_summarize_util_INCLUDED
00068
00069 #ifndef loop_info_INCLUDED
00070 #include "loop_info.h"
00071 #endif // loop_info_INCLUDED
00072
00073 #ifndef ipl_linex_INCLUDED
00074 #include "ipl_linex.h"
00075 #endif
00076
00077 #ifndef ipl_reorder_INCLUDED // for Ptr_to_ty_vector, local_cands
00078 #include "ipl_reorder.h"
00079 #endif
00080
00081 #include "region_util.h"
00082 #include "wn_mp.h"
00083 #include "ipl_lno_util.h"
00084 #include "wb_ipl.h"
00085
00086 extern BOOL DoPreopt;
00087 extern BOOL Do_Par;
00088 extern BOOL Do_Common_Const;
00089 extern ALIAS_MANAGER* Ipl_Al_Mgr;
00090 extern DU_MANAGER *Ipl_Du_Mgr;
00091 extern DYN_ARRAY<char*>* Ipl_Symbol_Names;
00092 extern DYN_ARRAY<char*>* Ipl_Function_Names;
00093
00094 extern void Init_Chi_Phi_Hash_Tables(MEM_POOL*);
00095 extern void IPL_Mark_Code(WN* func_nd);
00096 extern void IPL_Build_Access_Vectors(WN* func_nd);
00097 extern void Initialize_Access_Vals (DU_MANAGER*, FILE*);
00098 extern void Finalize_Access_Vals();
00099 extern void IPL_Initialize_Par_Code();
00100 extern void IPL_Finalize_Par_Code();
00101 extern void IPL_Finalize_Projected_Regions(SUMMARY_PROCEDURE *p);
00102 extern DYN_ARRAY<char*>* Ipl_Symbol_Names;
00103 extern DYN_ARRAY<char*>* Ipl_Function_Names;
00104
00105 #ifdef KEY
00106 static BOOL proc_has_pstatics = FALSE;
00107 #endif
00108
00109
00110 static inline BOOL
00111 ST_is_formal(const ST* s)
00112 {
00113 return (ST_sclass(s) == SCLASS_FORMAL || ST_sclass(s) == SCLASS_FORMAL_REF);
00114 }
00115
00116 static inline BOOL
00117 ST_is_common_block (const ST* st)
00118 {
00119 return
00120 ( ST_class(st) == CLASS_VAR &&
00121 ST_base(st) == st &&
00122 (ST_sclass(st) == SCLASS_COMMON || ST_sclass(st) == SCLASS_DGLOBAL) &&
00123 TY_kind(ST_type(st)) == KIND_STRUCT );
00124 }
00125
00126 static inline BOOL
00127 ST_is_common_element (const ST* st)
00128 {
00129 return ( ST_class(st) == CLASS_VAR &&
00130 ST_base(st) != st &&
00131 ST_is_common_block(ST_base(st)) );
00132 }
00133
00134
00135 enum ADDR_TAKEN_ACTION
00136 {
00137 RECORD_PASSED,
00138 RECORD_SAVED,
00139 RECORD_EXTERN
00140
00141
00142 };
00143
00144 template <PROGRAM program>
00145 static void
00146 set_addr_taken_expr (const WN* expr, SUMMARIZE<program>* sum,
00147 ADDR_TAKEN_ACTION action, BOOL is_iload)
00148 {
00149 Is_True (OPERATOR_is_expression (WN_operator (expr)),
00150 ("Expecting an expression node"));
00151
00152 WN_TREE_ITER<PRE_ORDER, const WN*> iter (expr);
00153
00154 while (iter.Wn () != NULL) {
00155 const WN* wn = iter.Wn ();
00156 OPERATOR opr = WN_operator (wn);
00157
00158 if (program == INLINER && ! OPERATOR_is_expression (opr)) {
00159 Set_Addr_Taken_Attrib (wn, sum);
00160 iter.WN_TREE_next_skip ();
00161 continue;
00162 }
00163
00164 if (OPERATOR_is_load (opr) && !OPERATOR_is_leaf (opr)) {
00165
00166 if (program == INLINER) {
00167 set_addr_taken_expr(WN_kid0 (wn), sum, action, TRUE);
00168 iter.WN_TREE_next_skip ();
00169 continue;
00170 }
00171 else {
00172 iter.WN_TREE_next_skip ();
00173 continue;
00174 }
00175 }
00176
00177 if (!is_iload && opr == OPR_LDA) {
00178 ST* st = WN_st (wn);
00179 if (ST_class(st) == CLASS_VAR || ST_class(st) == CLASS_FUNC) {
00180 IPL_ST_INFO& st_info = Aux_Symbol(st);
00181 switch (action) {
00182 case RECORD_SAVED:
00183
00184
00185
00186
00187
00188
00189 if (st_info.addr_saved_reset || ST_addr_saved (st)) {
00190 st_info.addr_saved = TRUE;
00191 Set_ST_addr_saved (st);
00192 if (st_info.summary_symbol_idx > -1) {
00193 sum->Get_symbol(st_info.summary_symbol_idx)->Set_addr_saved();
00194 }
00195
00196
00197 if (ST_is_common_element(st)) {
00198 ST* base_st = ST_base(st);
00199 IPL_ST_INFO& st_info = Aux_Symbol(base_st);
00200 st_info.addr_saved = TRUE;
00201 Set_ST_addr_saved(base_st);
00202 if (st_info.summary_symbol_idx > -1) {
00203 sum->Get_symbol(st_info.summary_symbol_idx)->Set_addr_saved();
00204 }
00205 }
00206 }
00207 break;
00208
00209 case RECORD_EXTERN:
00210 if (ST_level (st) == CURRENT_SYMTAB)
00211 break;
00212
00213
00214 case RECORD_PASSED:
00215 st_info.addr_passed = TRUE;
00216 if (st_info.summary_symbol_idx > -1) {
00217 sum->Get_symbol(st_info.summary_symbol_idx)->Set_addr_passed();
00218 }
00219
00220
00221 if (ST_is_common_element(st)) {
00222 ST* base_st = ST_base(st);
00223 IPL_ST_INFO& st_info = Aux_Symbol(base_st);
00224 st_info.addr_passed = TRUE;
00225 Set_ST_addr_passed(base_st);
00226 if (st_info.summary_symbol_idx > -1) {
00227 sum->Get_symbol(st_info.summary_symbol_idx)->Set_addr_passed();
00228 }
00229 }
00230 break;
00231 }
00232 }
00233 }
00234
00235 ++iter;
00236 }
00237 }
00238
00239
00240
00241 template <PROGRAM program>
00242 static void
00243 Set_Addr_Taken_Attrib (const WN *proc_entry, SUMMARIZE<program>* sum)
00244 {
00245 WN_TREE_ITER<PRE_ORDER, const WN*> iter (proc_entry);
00246
00247 while (iter.Wn () != NULL) {
00248 const WN* wn = iter.Wn ();
00249 OPERATOR opr = WN_operator (wn);
00250
00251 if (OPERATOR_is_store (opr) || (opr == OPR_RETURN_VAL)) {
00252
00253
00254 set_addr_taken_expr (WN_kid0 (wn), sum, RECORD_SAVED, FALSE);
00255 if (program == INLINER)
00256 set_addr_taken_expr (WN_kid0 (wn), sum, RECORD_PASSED, FALSE);
00257 iter.WN_TREE_next_skip ();
00258
00259 } else {
00260 INT i;
00261 switch (opr) {
00262 #ifdef TODO
00263 case OPR_ICALL:
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 #endif // TODO
00277
00278 case OPR_IO_ITEM:
00279 for (i = 0; i < WN_kid_count (wn); ++i)
00280 if (OPERATOR_is_expression (WN_operator (WN_kid (wn, i))))
00281 set_addr_taken_expr (WN_kid (wn, i), sum,
00282 RECORD_PASSED, FALSE);
00283 iter.WN_TREE_next_skip ();
00284 break;
00285
00286 case OPR_PARM:
00287 set_addr_taken_expr (WN_kid0 (wn), sum, RECORD_PASSED, FALSE);
00288 iter.WN_TREE_next_skip ();
00289 break;
00290
00291 case OPR_LDA:
00292 if (ST_level (WN_st (wn)) != CURRENT_SYMTAB)
00293 set_addr_taken_expr (wn, sum, RECORD_EXTERN, FALSE);
00294 ++iter;
00295 break;
00296
00297 default:
00298 ++iter;
00299 }
00300 }
00301 }
00302 }
00303
00304
00305 struct update_symtab
00306 {
00307 #ifdef Is_True_On
00308 BOOL trace;
00309
00310 update_symtab () : trace (Get_Trace (TP_IPL, TT_IPL_VERBOSE)) {}
00311
00312 #endif
00313 void operator() (UINT32, ST* st) const {
00314 IPL_ST_INFO& st_info = Aux_Symbol (st);
00315 if (st_info.addr_saved)
00316 Set_ST_addr_saved (st);
00317 else if (ST_addr_saved (st) && !ST_has_nested_ref (st)) {
00318 Clear_ST_addr_saved (st);
00319 st_info.addr_saved_reset = TRUE;
00320 #ifdef Is_True_On
00321 if (trace)
00322 fprintf (TFile, "Clearing addr_saved for %s\n", ST_name (st));
00323 #endif
00324
00325 }
00326
00327 if (st_info.addr_passed)
00328 Set_ST_addr_passed (st);
00329 else if (ST_addr_passed (st) && !ST_has_nested_ref (st)) {
00330 Clear_ST_addr_passed (st);
00331 #ifdef Is_True_On
00332 if (trace)
00333 fprintf (TFile, "Clearing addr_passed for %s\n", ST_name (st));
00334 #endif
00335 }
00336 #ifdef KEY // bug 11801
00337 if (ST_sclass(st) == SCLASS_PSTATIC)
00338 proc_has_pstatics = TRUE;
00339 #endif
00340 }
00341
00342 };
00343
00344
00345
00346
00347
00348 static void
00349 search_for_symoff_initv (INITV_IDX initv_idx)
00350 {
00351 while (initv_idx) {
00352 const INITV& initv = Initv_Table[initv_idx];
00353 if (INITV_kind (initv) == INITVKIND_SYMOFF
00354 #ifdef TARG_IA64
00355 || INITV_kind (initv) == INITVKIND_SYMIPLT
00356 #endif
00357 ) {
00358 ST_IDX st_idx = INITV_st (initv);
00359 Aux_Symbol[st_idx].addr_saved = TRUE;
00360 } else if (INITV_kind (initv) == INITVKIND_BLOCK)
00361 search_for_symoff_initv (INITV_blk (initv));
00362 initv_idx = INITV_next (initv);
00363 }
00364 }
00365
00366
00367 struct search_for_static_initialization
00368 {
00369 void operator() (UINT32, const INITO* inito) const {
00370 search_for_symoff_initv (INITO_val (*inito));
00371 }
00372 };
00373
00374
00375
00376
00377 template <PROGRAM program>
00378 void
00379 Recompute_Addr_Taken (const WN *proc_entry, SUMMARIZE<program>* sum)
00380 {
00381
00382
00383 if (program == IPL) {
00384 for (SYMTAB_IDX i = GLOBAL_SYMTAB; i <= CURRENT_SYMTAB; ++i) {
00385 if (ST_Table_Size (i) > Aux_Symbol_Info[i].size ()) {
00386 vector<IPL_ST_INFO>& aux_st = Aux_Symbol_Info[i];
00387 aux_st.insert (aux_st.end(),
00388 ST_Table_Size (i) - aux_st.size (),
00389 IPL_ST_INFO ());
00390 }
00391 }
00392 }
00393
00394
00395 Set_Addr_Taken_Attrib (proc_entry, sum);
00396
00397
00398 if (Scope_tab[CURRENT_SYMTAB].inito_tab->Size () > 1)
00399 For_all (Inito_Table, CURRENT_SYMTAB,
00400 search_for_static_initialization ());
00401
00402
00403
00404
00405
00406
00407
00408
00409 For_all (St_Table, CURRENT_SYMTAB, update_symtab ());
00410 }
00411
00412 static MEM_POOL Temp_pool;
00413
00414 template <PROGRAM program>
00415 void
00416 SUMMARIZE<program>::Summarize (WN *w)
00417 {
00418 static BOOL Temp_pool_initialized = FALSE;
00419 WN_MAP save_parent_map = Parent_Map;
00420
00421 if (!Temp_pool_initialized) {
00422 Temp_pool_initialized = TRUE;
00423 MEM_POOL_Initialize(&Temp_pool, "temp pool", 0);
00424 }
00425
00426 MEM_POOL_Popper pool (&Temp_pool);
00427
00428 Init_Aux_Symbol_Info (CURRENT_SYMTAB);
00429
00430 #ifdef KEY
00431 proc_has_pstatics = FALSE;
00432 #endif
00433
00434 Recompute_Addr_Taken (w, this);
00435
00436 if (!Has_alt_entry ()) {
00437 Parent_Map = WN_MAP_Create(&Temp_pool);
00438 LWN_Parentize(w);
00439
00440
00441 Global_hash_table = CXX_NEW(GLOBAL_HASH_TABLE(113,&Temp_pool),&Temp_pool);
00442 entry_cache = CXX_NEW(SUMMARY_ENTRY_CACHE(&Temp_pool), &Temp_pool);
00443
00444
00445 Chi_To_Idx_Map =
00446 CXX_NEW (CHI_CR_TO_INT_MAP (113, ptr_hash<CODEREP> (),
00447 std::equal_to<CODEREP*> (), &Temp_pool),
00448 &Temp_pool);
00449 Phi_To_Idx_Map =
00450 CXX_NEW (PHI_NODE_TO_INT_MAP (113, ptr_hash<PHI_NODE> (),
00451 std::equal_to<PHI_NODE*> (), &Temp_pool),
00452 &Temp_pool);
00453 Hashed_Chis = CXX_NEW(CHI_CR_ARRAY(&Temp_pool), &Temp_pool);
00454 Hashed_Phis = CXX_NEW(PHI_NODE_ARRAY(&Temp_pool), &Temp_pool);
00455 Num_Chis_On_PU_Start = Get_chi_idx()+1;
00456 Num_Phis_On_PU_Start = Get_phi_idx()+1;
00457
00458
00459 Summary_Map = WN_MAP32_Create (&Temp_pool);
00460
00461 if (DoPreopt) {
00462 Init_cdg (&Temp_pool);
00463 if (Do_Par)
00464
00465 Stmt_Map = WN_MAP32_Create (&Temp_pool);
00466 }
00467
00468 }
00469
00470 Set_entry_point (w);
00471 Process_procedure (w);
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483 if ( Has_alt_entry () ) {
00484
00485 for (INT i = 0; i <= Get_alt_entry_idx(); i++) {
00486 ALT_ENTRY *alt_entry = Get_alt_entry (i);
00487 w = alt_entry->Get_wn ();
00488 if ( Trace_IPA || Show_Progress) {
00489
00490 fprintf (TFile, "Summarizing alternate entry point %s \n",
00491 ST_name(WN_st(w)));
00492 }
00493
00494 INT position = alt_entry->Get_position();
00495 INT formal_count = alt_entry->Get_formal_count();
00496 Summary->Process_alt_procedure (w, position, formal_count);
00497 }
00498 _alt_entry.Free_array();
00499 _alt_entry.Resetidx();
00500 }
00501
00502 #ifdef KEY
00503 if (Get_Trace (TP_IPL, TT_IPL_SUMMARY))
00504 Trace (TFile);
00505 #endif
00506
00507
00508 if (!Has_alt_entry()) {
00509 WN_MAP_Delete(Parent_Map);
00510 Parent_Map = save_parent_map;
00511 WN_MAP_Delete(Summary_Map);
00512 if (DoPreopt && Do_Par) {
00513 WN_MAP_Delete(Stmt_Map);
00514 }
00515 }
00516
00517 }
00518
00519
00520
00521
00522
00523
00524 template <PROGRAM program>
00525 struct process_compile_time_addr_saved
00526 {
00527 SUMMARIZE<program>* const sum;
00528 vector<IPL_ST_INFO>& aux_st_info;
00529
00530 process_compile_time_addr_saved (SUMMARIZE<program>* const s) :
00531 sum (s), aux_st_info (Aux_Symbol_Info[GLOBAL_SYMTAB]) {}
00532
00533 void operator() (UINT32, const INITV* initv) const {
00534 if (INITV_kind (*initv) != INITVKIND_SYMOFF
00535 #ifdef TARG_IA64
00536 && INITV_kind (*initv) != INITVKIND_SYMIPLT
00537 #endif
00538 )
00539 return;
00540 ST_IDX st_idx = INITV_st (*initv);
00541 if (ST_IDX_level (st_idx) != GLOBAL_SYMTAB)
00542 return;
00543 const ST& st = St_Table[st_idx];
00544 if (ST_sym_class (st) != CLASS_VAR &&
00545 ST_sym_class (st) != CLASS_FUNC)
00546 return;
00547
00548 IPL_ST_INFO& st_info = aux_st_info[ST_IDX_index (st_idx)];
00549 st_info.addr_saved = TRUE;
00550 }
00551 };
00552
00553 #ifdef KEY
00554
00555 #include <sys/param.h>
00556 #include <unistd.h>
00557 static unsigned int
00558 hash_of_full_path_name (int index)
00559 {
00560 bool malloced = false;
00561
00562
00563 char *cwd = getcwd((char *) NULL, MAXPATHLEN);
00564 if (cwd == NULL)
00565 {
00566 cwd = getenv("PWD");
00567 if (cwd == NULL)
00568 {
00569
00570 cwd = const_cast<char*>(".");
00571 }
00572 }
00573 else malloced = true;
00574
00575 char fullname[10 + strlen(cwd) + strlen(Src_File_Name) + 1 + 1];
00576 sprintf (fullname, "%d%s/%s", index, cwd, Src_File_Name);
00577 __gnu_cxx::hash<char*> hfn;
00578
00579 if (malloced) free (cwd);
00580
00581 return (unsigned int) hfn (fullname);
00582 }
00583
00584
00585 template <PROGRAM program>
00586 struct set_local_static_to_global
00587 {
00588 SUMMARIZE<program>* const sum;
00589 const vector<IPL_ST_INFO>& aux_st_info;
00590
00591 set_local_static_to_global (SUMMARIZE<program>* const s) :
00592 sum (s),
00593 aux_st_info (Aux_Symbol_Info[GLOBAL_SYMTAB]) {}
00594
00595 void operator() (UINT32 idx, ST* st) const {
00596
00597 if (ST_class (st) != CLASS_VAR ||
00598 ST_sclass (st) != SCLASS_FSTATIC ||
00599 !ST_initv_in_other_st(st))
00600 return;
00601
00602 if (!ST_is_initialized (st))
00603 Set_ST_sclass(st, SCLASS_COMMON);
00604 else if (ST_init_value_zero(st))
00605 Set_ST_sclass(st, SCLASS_UGLOBAL);
00606 else
00607 Set_ST_sclass(st, SCLASS_DGLOBAL);
00608
00609 Set_ST_export(st, EXPORT_PREEMPTIBLE);
00610
00611 char idname[30];
00612
00613 sprintf(idname, "_%d_%u", ST_index(st), hash_of_full_path_name(ST_index(st)));
00614 int newname = Save_Str2(ST_name(st), idname);
00615 Set_ST_name (st, newname);
00616 }
00617 };
00618 #endif
00619
00620 template <PROGRAM program>
00621 struct set_global_addr_taken_attrib
00622 {
00623 #ifdef Is_True_On
00624 BOOL trace;
00625 #endif
00626 SUMMARIZE<program>* const sum;
00627 const vector<IPL_ST_INFO>& aux_st_info;
00628
00629 set_global_addr_taken_attrib (SUMMARIZE<program>* const s) :
00630 sum (s),
00631 #ifdef Is_True_On
00632 trace (Get_Trace (TP_IPL, TT_IPL_VERBOSE)),
00633 #endif
00634 aux_st_info (Aux_Symbol_Info[GLOBAL_SYMTAB]) {}
00635
00636 void operator() (UINT32 idx, ST* st) const {
00637
00638 #ifdef _LIGHTWEIGHT_INLINER
00639 if (INLINE_Inlined_Pu_Call_Graph && (idx >= aux_st_info.size()))
00640 return;
00641 #endif
00642
00643 if (ST_class (st) == CLASS_NAME)
00644 return;
00645
00646 const IPL_ST_INFO& st_info = aux_st_info[idx];
00647
00648
00649 if (st_info.addr_saved)
00650 Set_ST_addr_saved (st);
00651 #ifdef _LIGHTWEIGHT_INLINER
00652 else if (!INLINE_Inlined_Pu_Call_Graph && ST_addr_saved (st)) {
00653 #else // _LIGHTWEIGHT_INLINER
00654 else if (ST_addr_saved (st)) {
00655 #endif // _LIGHTWEIGHT_INLINER
00656 Clear_ST_addr_saved (st);
00657 #ifdef Is_True_On
00658 if (trace)
00659 fprintf (TFile, "Clearing addr_saved for %s\n", ST_name (st));
00660 #endif
00661 }
00662
00663 if (st_info.addr_passed)
00664 Set_ST_addr_passed (st);
00665 else
00666 Clear_ST_addr_passed (st);
00667
00668
00669
00670 if (ST_class (st) == CLASS_CONST)
00671 return;
00672
00673
00674
00675 if (st_info.addr_saved || st_info.addr_passed) {
00676 UINT sym_idx = st_info.summary_symbol_idx;
00677
00678 Is_True (ST_class (st) == CLASS_VAR ||
00679 ST_class (st) == CLASS_FUNC,
00680 ("symbol is neither variable nor function"));
00681
00682 if (sym_idx == (UINT32) -1)
00683 sym_idx = sum->Get_symbol_index(st);
00684
00685 SUMMARY_SYMBOL *symbol = sum->Get_symbol (sym_idx);
00686
00687
00688 if (st_info.addr_saved)
00689 symbol->Set_addr_saved ();
00690
00691 if (st_info.addr_passed)
00692 symbol->Set_addr_passed();
00693 }
00694 }
00695 };
00696
00697 template <PROGRAM program>
00698 void
00699 SUMMARIZE<program>::Set_global_addr_taken_attrib (void)
00700 {
00701
00702
00703 For_all (Initv_Table, process_compile_time_addr_saved<program> (this));
00704
00705
00706
00707 For_all (St_Table, GLOBAL_SYMTAB,
00708 set_global_addr_taken_attrib<program> (this));
00709 #ifdef KEY
00710 if (program == IPL)
00711 For_all (St_Table, GLOBAL_SYMTAB, set_local_static_to_global<program> (this));
00712 #endif
00713 }
00714
00715
00716
00717
00718
00719 template <PROGRAM program>
00720 void
00721 SUMMARIZE<program>::Update_Addr_Passed_Count (WN* opr_parm)
00722 {
00723 WN_ITER *wni;
00724 INT i;
00725 const ST* s = NULL;
00726
00727
00728 for ( wni = WN_WALK_TreeIter(opr_parm); wni && WN_ITER_wn(wni) != 0;
00729 wni = WN_WALK_TreeNext(wni) ) {
00730
00731 WN* w = WN_ITER_wn(wni);
00732 SUMMARY_SYMBOL *symbol;
00733
00734
00735
00736 if ((program == INLINER) &&
00737 (WN_operator(w) == OPR_CALL))
00738 {
00739 WN_WALK_Abort(wni);
00740 return;
00741 }
00742 if (WN_operator(w) != OPR_LDA)
00743 continue;
00744
00745 s = WN_st(w);
00746
00747 if (ST_class(s) == CLASS_CONST)
00748 continue;
00749
00750 symbol = Get_symbol (Get_symbol_index (s));
00751
00752
00753
00754 if (symbol->Is_local () && !symbol->Is_common())
00755 symbol->Incr_addr_count ();
00756
00757 if ( Trace_CopyProp )
00758 fprintf ( TFile, "\n Addr passed count for %s updated to %d\n",
00759 ST_name(s), symbol->Get_addr_count ());
00760
00761
00762
00763 if (ST_st_idx (s) == ST_base_idx (s) && ST_sclass (s) != SCLASS_COMMON)
00764 continue;
00765
00766 if (ST_st_idx (s) != ST_base_idx (s)) {
00767 const ST* st = ST_base (s);
00768 if (ST_sclass (st) == SCLASS_COMMON) {
00769
00770
00771
00772
00773
00774 WN* parent_w = LWN_Get_Parent(w);
00775
00776 OPERATOR opc = WN_operator(parent_w);
00777
00778 if (opc == OPR_PARM || opc == OPR_ARRAY) {
00779 if (TY_kind (ST_type (s)) == KIND_ARRAY &&
00780 TY_kind (ST_type (st)) == KIND_STRUCT) {
00781 const TY& array_type = Ty_Table[ST_type (s)];
00782 if (ARB_dimension (TY_arb (array_type)) == 1) {
00783 WN_WALK_Abort (wni);
00784 return;
00785 }
00786 }
00787 }
00788
00789 s = st;
00790 }
00791 }
00792
00793
00794 i = Get_symbol_index (s);
00795 Get_symbol (i)->Set_parm ();
00796 }
00797 }
00798
00799
00800
00801
00802
00803 template <PROGRAM program>
00804 inline void
00805 SUMMARIZE<program>::Set_local_addr_taken_attrib ()
00806 {
00807 typedef vector<IPL_ST_INFO> AUX_INFO;
00808 const AUX_INFO& aux_info = Aux_Symbol_Info[CURRENT_SYMTAB];
00809
00810 for (AUX_INFO::const_iterator first = aux_info.begin ();
00811 first != aux_info.end (); ++first) {
00812
00813 const IPL_ST_INFO& st_info = *first;
00814
00815 if (st_info.summary_symbol_idx == -1)
00816 continue;
00817
00818 if (st_info.addr_saved || st_info.addr_passed) {
00819 SUMMARY_SYMBOL* symbol = Get_symbol (st_info.summary_symbol_idx);
00820 if (st_info.addr_saved)
00821 symbol->Set_addr_saved ();
00822 if (st_info.addr_passed)
00823 symbol->Set_addr_passed ();
00824 }
00825 }
00826 }
00827
00828
00829
00830
00831
00832
00833
00834 template <PROGRAM program>
00835 INT
00836 SUMMARIZE<program>::Get_symbol_crefcount_index(INT idx)
00837 {
00838 FmtAssert(program == INLINER,
00839 ("Get_symbol_crefcount_index can be called only from INLINER"));
00840
00841
00842 INT maxidx;
00843 SUMMARY_CREF_SYMBOL *sym;
00844
00845 if (Has_symbol_crefcount_entry ()) {
00846 INT i = 0;
00847 maxidx = Get_symbol_crefcount_idx ();
00848 while (i <= maxidx) {
00849 if (Get_symbol_crefcount(i)->Get_symbol_index() == idx)
00850 return i;
00851 else
00852 i++;
00853 }
00854 }
00855
00856
00857
00858 sym = New_symbol_crefcount();
00859 sym->Set_symbol_index(idx);
00860 return Get_symbol_crefcount_idx ();
00861 }
00862
00863
00864
00865
00866
00867
00868
00869 template <PROGRAM program>
00870 INT
00871 SUMMARIZE<program>::Find_symbol_crefcount_index(INT idx)
00872 {
00873 FmtAssert(program == INLINER,
00874 ("Find_symbol_crefcount_index can be called only from INLINER"));
00875
00876
00877 INT i = 0;
00878 INT maxidx;
00879 if (Has_symbol_crefcount_entry ()) {
00880 maxidx = Get_symbol_crefcount_idx ();
00881 while (i <= maxidx) {
00882 if (Get_symbol_crefcount(i)->Get_symbol_index() == idx)
00883 return i;
00884 else
00885 i++;
00886 }
00887 }
00888 return -1;
00889 }
00890
00891
00892
00893
00894
00895
00896
00897 template <PROGRAM program>
00898 INT
00899 SUMMARIZE<program>::Find_proc_info_index(INT32 idx)
00900 {
00901 FmtAssert(program == INLINER,
00902 ("Find_proc_info_index can be called only from INLINER"));
00903
00904 INT i = 0;
00905 INT maxidx;
00906 if (Has_proc_info_entry ()) {
00907 maxidx = Get_proc_info_idx ();
00908 while (i <= maxidx) {
00909 if (Get_proc_info(i)->Get_symbol_index() == idx)
00910 return i;
00911 else
00912 i++;
00913 }
00914 }
00915 return -1;
00916 }
00917
00918
00919
00920
00921 static inline BOOL
00922 WN_is_istore_or_mstore (WN* w)
00923 {
00924 WN* parent = LWN_Get_Parent(w);
00925 return (parent &&
00926 (WN_operator(parent) == OPR_ISTORE ||
00927 WN_operator(parent) == OPR_MSTORE) &&
00928 WN_kid1(parent) == w);
00929 }
00930
00931 static BOOL
00932 WN_is_in_pragma (WN* wn_node)
00933 {
00934 for (WN* wn = wn_node; wn != NULL; wn = LWN_Get_Parent(wn))
00935 if (WN_operator(wn) == OPR_PRAGMA || WN_operator(wn) == OPR_XPRAGMA)
00936 return TRUE;
00937 return FALSE;
00938 }
00939
00940
00941 static inline BOOL
00942 Last_Node (WN_TREE_ITER<PRE_ORDER, WN*> i)
00943 {
00944 i.Skip ();
00945 return i.Wn () == NULL;
00946 }
00947
00948 #ifdef KEY
00949
00950
00951 template <PROGRAM program>
00952 void
00953 SUMMARIZE<program>::Process_eh_globals (void)
00954 {
00955 if (!(PU_src_lang (Get_Current_PU()) & PU_CXX_LANG) ||
00956 !PU_misc_info (Get_Current_PU()))
00957 return;
00958
00959 INITV_IDX i = INITV_next (INITV_next (INITO_val (PU_misc_info (Get_Current_PU()))));
00960
00961 INITO_IDX idx = TCON_uval (INITV_tc_val(i));
00962 if (idx)
00963 {
00964 INITO* ino = &Inito_Table[idx];
00965 INITV_IDX blk = INITO_val (*ino);
00966 do
00967 {
00968 INITV_IDX st_entry = INITV_blk (blk);
00969 ST_IDX st_idx = 0;
00970 if (INITV_kind (st_entry) != INITVKIND_ZERO)
00971 {
00972 st_idx = TCON_uval (INITV_tc_val (st_entry));
00973 FmtAssert (st_idx != 0, ("Invalid st idx"));
00974 }
00975 if (st_idx <= 0)
00976 {
00977 blk = INITV_next (blk);
00978 continue;
00979 }
00980 INT32 index = Get_symbol_index (&St_Table [st_idx]);
00981 INITV_IDX filter = INITV_next (st_entry);
00982 FmtAssert (index >= 0, ("Unexpected summary id for eh symbol"));
00983 INITV_Set_VAL (Initv_Table[st_entry], Enter_tcon (
00984 Host_To_Targ (MTYPE_U4, index)), 1);
00985 Set_INITV_next (st_entry, filter);
00986 blk = INITV_next (blk);
00987 } while (blk);
00988 }
00989
00990 i = INITV_next (i);
00991 idx = TCON_uval (INITV_tc_val (i));
00992 if (idx)
00993 {
00994 INITO* ino = &Inito_Table[idx];
00995 INITV_IDX st_entry = INITV_blk (INITO_val (*ino));
00996 do
00997 {
00998 ST_IDX st_idx = 0;
00999 if (INITV_kind (st_entry) != INITVKIND_ZERO)
01000 {
01001 st_idx = TCON_uval (INITV_tc_val (st_entry));
01002 FmtAssert (st_idx > 0, ("Invalid eh-spec entry"));
01003 }
01004 if (st_idx == 0)
01005 {
01006 st_entry = INITV_next (st_entry);
01007 continue;
01008 }
01009 INT32 index = Get_symbol_index (&St_Table[st_idx]);
01010 INITV_IDX next = INITV_next (st_entry);
01011 FmtAssert (index >= 0, ("Unexpected summary id for eh symbol"));
01012 INITV_Set_VAL (Initv_Table[st_entry], Enter_tcon (
01013 Host_To_Targ (MTYPE_U4, index)), 1);
01014 Set_INITV_next (st_entry, next);
01015 st_entry = INITV_next (st_entry);
01016 } while (st_entry);
01017 }
01018 }
01019
01020 template <PROGRAM program>
01021 void
01022 SUMMARIZE<program>::Process_eh_region (WN * wn)
01023 {
01024
01025 if (!WN_ereg_supp (wn) || !WN_block_empty (WN_region_pragmas (wn)))
01026 return;
01027 FmtAssert (INITO_val (WN_ereg_supp (wn)) &&
01028 INITV_blk (INITO_val (WN_ereg_supp (wn))) &&
01029 INITV_next (INITV_blk (INITO_val (WN_ereg_supp (wn)))),
01030 ("No exception info attached to EH region"));
01031 INITV_IDX blk = INITO_val (WN_ereg_supp (wn));
01032
01033
01034 if (INITV_flags (Initv_Table[blk]) == INITVFLAGS_SUMMARIZED)
01035 return;
01036
01037 Set_INITV_flags (blk, INITVFLAGS_SUMMARIZED);
01038
01039 INITV_IDX types = INITV_next (INITV_blk (blk));
01040 for (; types; types = INITV_next (types))
01041 {
01042 int sym = 0;
01043 if (INITV_kind (types) != INITVKIND_ZERO)
01044 sym = TCON_uval (INITV_tc_val (types));
01045 if (sym > 0)
01046 {
01047 INT32 index = Get_symbol_index (&St_Table[sym]);
01048 INITV_IDX next = INITV_next (types);
01049
01050
01051 FmtAssert (index > 0, ("Unexpected summary id for eh symbol"));
01052 INITV_Set_VAL (Initv_Table[types], Enter_tcon (
01053 Host_To_Targ (MTYPE_U4, index)), 1);
01054 Set_INITV_next (types, next);
01055 }
01056 }
01057 }
01058
01059 #include <ext/hash_map>
01060
01061 namespace Local
01062 {
01063 struct hashfn
01064 {
01065 size_t operator() (const WN * w) const
01066 {
01067 return reinterpret_cast<size_t>(w);
01068 }
01069 };
01070
01071 struct eqnode
01072 {
01073 bool operator()(WN * w1, WN * w2) const
01074 {
01075 return w1 == w2;
01076 }
01077 };
01078 };
01079
01080 struct branch_dir
01081 {
01082 float taken, not_taken;
01083 };
01084 hash_map<WN*, branch_dir, Local::hashfn, Local::eqnode> if_map;
01085
01086 inline void get_parent_if ( WN ** p, WN ** b )
01087 {
01088 WN * parent = *p;
01089 WN * block;
01090 while ( parent && WN_operator (parent) != OPR_IF )
01091 {
01092 if ( WN_operator ( parent ) == OPR_BLOCK )
01093 block = parent;
01094 parent = LWN_Get_Parent ( parent );
01095 }
01096 *p = parent;
01097 *b = block;
01098 }
01099
01100
01101
01102 static inline INT get_loopnest (WN * w)
01103 {
01104 WN * parent = LWN_Get_Parent (w);
01105 INT loopnest = 0;
01106
01107 while (parent)
01108 {
01109 switch (WN_operator (parent))
01110 {
01111 case OPR_DO_LOOP:
01112 #if !defined(_STANDALONE_INLINER) && !defined(_LIGHTWEIGHT_INLINER)
01113 {
01114 if (IPL_Ignore_Small_Loops)
01115 {
01116 WN * loop_info = WN_do_loop_info(parent);
01117 if (loop_info)
01118 {
01119
01120
01121 WN * trip = WN_loop_trip(loop_info);
01122 if (trip && WN_operator(trip) == OPR_INTCONST)
01123 {
01124 INT64 tripcount = WN_const_val(trip);
01125 Is_True (tripcount >= 0,
01126 ("get_loopnest: negative loop trip count"));
01127 if (tripcount <= IPL_Ignore_Small_Loops)
01128 break;
01129 }
01130 }
01131 }
01132 }
01133 #endif // !_STANDALONE_INLINER && !_LIGHTWEIGHT_INLINER
01134 case OPR_WHILE_DO:
01135 case OPR_DO_WHILE:
01136 loopnest++;
01137 break;
01138 default:
01139 break;
01140 }
01141 parent = LWN_Get_Parent (parent);
01142 }
01143
01144 return loopnest;
01145 }
01146 #endif
01147
01148 static BOOL
01149 is_variable_dim_array(TY_IDX ty)
01150 {
01151 if (TY_kind(ty) == KIND_POINTER)
01152 ty = TY_pointed(ty);
01153
01154 if (TY_kind(ty) == KIND_ARRAY) {
01155 ARB_ITER arb_iter = Make_arb_iter (ARB_HANDLE (TY_arb(ty)));
01156 UINT dim = ARB_dimension (arb_iter);
01157 for (UINT i = 0; i < dim; ++i) {
01158 ARB_HANDLE arb (arb_iter);
01159 if (!(ARB_const_lbnd(arb) && ARB_const_stride(arb)))
01160 return TRUE;
01161 else if (!ARB_const_ubnd(arb)) {
01162 if (ARB_ubnd_var(arb) != 0)
01163 return TRUE;
01164 }
01165 ++arb_iter;
01166 }
01167 return is_variable_dim_array(TY_etype(ty));
01168 }
01169
01170 return FALSE;
01171 }
01172
01173 #ifdef KEY
01174
01175
01176
01177 static void
01178 Count_WN (WN * wn, INT32& bbs, INT32& stmts, INT32& calls)
01179 {
01180 OPERATOR opr = WN_operator (wn);
01181 TYPE_ID rtype = WN_rtype (wn);
01182
01183
01184 if (OPERATOR_is_non_scf(opr)) {
01185 if (opr != OPR_RETURN && opr != OPR_RETURN_VAL)
01186 ++bbs;
01187 } else if (OPERATOR_is_stmt(opr)) {
01188 if (OPERATOR_is_call(opr)) {
01189 ++bbs;
01190 ++calls;
01191 } else if (opr == OPR_IO) {
01192
01193
01194 ++bbs;
01195 ++calls;
01196 } else if (! OPERATOR_is_not_executable(opr)) {
01197 ++stmts;
01198 if (MTYPE_is_complex(rtype) && OPERATOR_is_store(opr)) {
01199 ++stmts;
01200 }
01201 }
01202 } else if (OPERATOR_is_scf(opr)) {
01203 if (opr != OPR_BLOCK && opr != OPR_FUNC_ENTRY) {
01204
01205 ++bbs;
01206 }
01207
01208
01209 } else if ((rtype == MTYPE_FQ || rtype == MTYPE_CQ) &&
01210 OPERATOR_is_expression(opr) &&
01211 !OPERATOR_is_load(opr) &&
01212 !OPERATOR_is_leaf(opr) ) {
01213
01214 ++bbs;
01215 ++calls;
01216 } else if (opr == OPR_CAND || opr == OPR_CIOR) {
01217
01218
01219
01220 ++bbs;
01221 }
01222 }
01223
01224
01225 class label_wn
01226 {
01227 public:
01228 WN * wn;
01229 BOOL seen;
01230 label_wn () : wn (NULL), seen (FALSE) {}
01231 };
01232 #include <ext/hash_map>
01233
01234
01235 struct eq_oper
01236 {
01237 bool operator() (INT i, INT j) const
01238 {
01239 return i == j;
01240 }
01241 };
01242
01243
01244 typedef hash_map<INT, label_wn, __gnu_cxx::hash<INT>, eq_oper> LABEL_WN_MAP;
01245 #endif
01246
01247
01248
01249
01250
01251 template <PROGRAM program>
01252 void
01253 SUMMARIZE<program>::Process_procedure (WN* w)
01254 {
01255 SUMMARY_PROCEDURE *proc = New_procedure ();
01256 WN* w2, *alt_wn;
01257 ST *st = WN_st (w);
01258 #ifndef KEY
01259 INT loopnest = 0;
01260 #endif // !KEY
01261 INT pu_first_formal_idx = 0;
01262 INT pu_last_formal_idx = 0;
01263 INT pu_first_actual_idx = 0;
01264 INT pu_first_callsite_idx = 0;
01265 BOOL Do_Altentry = Has_alt_entry ();
01266 BOOL Do_parallel_stuff = Do_Par && !Do_Altentry && DoPreopt ;
01267 BOOL Do_common_const = Do_Common_Const && !Do_Altentry && DoPreopt;
01268 BOOL Has_return_already = FALSE;
01269 BOOL Has_pdo_pragma = FALSE;
01270 BOOL Has_local_pragma = FALSE;
01271 #ifdef KEY
01272 BOOL Do_reorder=!Do_Altentry && Cur_PU_Feedback;
01273 #if defined(VENDOR_PSC)
01274 Do_reorder = FALSE;
01275 #endif
01276 LABEL_WN_MAP label_use_map;
01277 UINT64 PU_invoke_count = 0;
01278 #else
01279 BOOL Do_reorder=!Do_Altentry && Cur_PU_Feedback&& IPA_Enable_Reorder;
01280 #endif // KEY
01281
01282 UINT fld_id,i, pop_loops;
01283 BOOL cur_pu_is_reorder_cand=FALSE;
01284 UINT64 loop_count;
01285 UINT stack_size;
01286 WN* wn_tmp;
01287 UINT num_struct_access;
01288
01289 #ifdef KEY
01290
01291 Initialize_PU_Stats();
01292
01293
01294 if (proc_has_pstatics)
01295 proc->Set_has_pstatic ();
01296 #endif
01297
01298 Trace_Modref = Get_Trace ( TP_IPL, TT_IPL_MODREF );
01299
01300 BOOL Direct_Mod_Ref = FALSE;
01301 if (!Do_parallel_stuff)
01302 proc->Set_has_incomplete_array_info();
01303
01304 if (!WHIRL_Return_Val_On)
01305 proc->Set_use_lowered_return_preg ();
01306
01307
01308 if (Do_parallel_stuff) {
01309 pu_first_formal_idx = Get_formal_idx() + 1;
01310 pu_first_actual_idx = Get_actual_idx() + 1;
01311 pu_first_callsite_idx = Get_callsite_idx() + 1;
01312 }
01313
01314 if (WN_operator(w) == OPR_FUNC_ENTRY)
01315 Process_pragmas (w);
01316
01317
01318 if ((WN_operator(w) == OPR_FUNC_ENTRY) &&
01319 WN_num_formals(w) )
01320 Process_formal (w, WN_num_formals(w), proc);
01321
01322 if (Do_parallel_stuff) {
01323 pu_last_formal_idx = Get_formal_idx();
01324 }
01325
01326 const PU& pu = Get_Current_PU ();
01327 if (PU_mp_needs_lno (pu))
01328 proc->Set_has_mp_needs_lno ();
01329
01330
01331 proc->Set_symbol_index (Get_symbol_index(st));
01332
01333 if (Cur_PU_Feedback) {
01334 FB_FREQ freq = (Cur_PU_Feedback->Query_invoke(w)).freq_invoke;
01335
01336 #ifdef KEY
01337 SUMMARY_FEEDBACK *fb = New_feedback ();
01338 proc->Set_feedback_index (Get_feedback_idx ());
01339 #endif
01340
01341 if (freq.Known()) {
01342 proc->Set_has_PU_freq ();
01343 #ifdef KEY
01344 PU_invoke_count = (UINT64) freq.Value();
01345 #else
01346 SUMMARY_FEEDBACK *fb = New_feedback ();
01347 proc->Set_feedback_index (Get_feedback_idx ());
01348 #endif
01349 fb->Set_frequency_count (freq);
01350 }
01351 else {
01352
01353 DevWarn ("Unknown invoke frequency found in %s so no feedback info in this procedure will be considered", ST_name(WN_st(w)));
01354 }
01355 #ifdef KEY
01356
01357 fb->Set_func_runtime_addr (Cur_PU_Feedback->Get_Runtime_Func_Addr());
01358 #endif
01359 }
01360 else
01361 {
01362 if(Feedback_Enabled[PROFILE_PHASE_BEFORE_VHO])
01363 {
01364 proc->Set_Never_Invoked ();
01365 }
01366 }
01367
01368
01369 Set_lang (proc);
01370
01371 if (PU_is_inline_function (pu))
01372 proc->Set_may_inline();
01373
01374 if (PU_no_inline (pu) )
01375 proc->Set_no_inline();
01376
01377 if (PU_no_delete (pu) )
01378 proc->Set_no_delete();
01379
01380 if (TY_is_varargs (Ty_Table[ST_pu_type (st)]))
01381 proc->Set_is_varargs();
01382
01383
01384
01385 proc->Set_global_index (Get_global_idx () + 1);
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395 if (Do_parallel_stuff) {
01396 Ipl_Al_Mgr = Get_alias_mgr();
01397 Ipl_Du_Mgr = Get_du_mgr();
01398 IPL_Initialize_Par_Code();
01399 IPL_Mark_Code(w);
01400 WB_IPL_Set_Reduction_Map(IPL_reduc_map);
01401 Initialize_Access_Vals(Get_du_mgr(), TFile);
01402 IPL_Build_Access_Vectors(w);
01403 WB_IPL_Set_Access_Array_Map(IPL_info_map);
01404 }
01405 if(Do_reorder)
01406 Start_PU_process_struct_access();
01407
01408
01409
01410 if ( Do_Altentry ) {
01411 alt_wn = w;
01412 w = Get_entry_point ();
01413 }
01414
01415 BOOL phi_index;
01416
01417 if (DoPreopt)
01418 phi_index = Get_phi_idx ();
01419
01420 #ifdef KEY
01421 Process_eh_globals ();
01422 #endif
01423
01424 BOOL found = FALSE;
01425
01426
01427 for (WN_TREE_ITER<PRE_ORDER, WN*> iter (w); iter.Wn () != NULL; ++iter) {
01428
01429
01430
01431
01432 while ( (Do_Altentry) && (!found) ) {
01433 if ( iter.Wn () == alt_wn ) {
01434 found = TRUE;
01435 } else {
01436 ++iter;
01437 }
01438 }
01439
01440 w2 = iter.Wn ();
01441 st = OPERATOR_has_sym(WN_operator(w2)) ? WN_st(w2) : NULL;
01442
01443
01444
01445 if (st && (Do_Common_Const || Do_parallel_stuff)) {
01446 if (ST_is_common_element(st)) {
01447 Get_symbol_index(ST_base(st));
01448 Get_symbol_index(st);
01449 }
01450 else if (ST_is_common_block(st)) {
01451 Get_symbol_index(st);
01452 }
01453 }
01454
01455 if (st && (is_variable_dim_array(ST_type(st))))
01456 proc->Set_has_var_dim_array();
01457
01458 #ifdef KEY
01459
01460 Count_WN (w2, PU_WN_BB_Cnt, PU_WN_Stmt_Cnt, PU_WN_Call_Cnt);
01461 #endif // KEY
01462
01463 switch ( WN_operator(w2) ) {
01464 case OPR_DO_LOOP:
01465 #ifdef KEY
01466 {
01467
01468 WN * index = WN_index(w2);
01469 Is_True (WN_operator(index) == OPR_IDNAME,
01470 ("Process_procedure: Invalid do-loop index"));
01471
01472 ST * id = WN_st (index);
01473 INT formal_id;
01474
01475
01476 if (ST_sclass (id) == SCLASS_FORMAL_REF)
01477 for (INT i = 0, formal_id = proc->Get_formal_index();
01478 i < proc->Get_formal_count();
01479 i++, formal_id++)
01480 {
01481 SUMMARY_FORMAL * formal = Get_formal(formal_id);
01482 if (Get_symbol_index(id) == formal->Get_symbol_index())
01483 {
01484 formal->Set_is_loop_index();
01485 break;
01486 }
01487 }
01488 }
01489 #endif
01490 case OPR_WHILE_DO:
01491 case OPR_DO_WHILE:
01492 #ifndef KEY // disable buggy loopnest computation
01493 loopnest++;
01494 #endif // !KEY
01495 if(Do_reorder){
01496 FB_Info_Loop fb_info=Cur_PU_Feedback->Query_loop( w2);
01497 loop_count=(UINT64) fb_info.freq_iterate.Value();
01498 loop_count_stack->Push(loop_count);
01499 stack_size=loop_count_stack->Elements();
01500 }
01501
01502 break;
01503
01504 #ifdef KEY
01505 case OPR_IF:
01506 {
01507
01508 if ( ! IPA_Enable_Branch_Heuristic || ! Cur_PU_Feedback ) break;
01509
01510 FB_Info_Branch info = Cur_PU_Feedback->Query_branch ( w2 );
01511 if (!info.freq_taken.Known() || !info.freq_not_taken.Known())
01512 {
01513 if_map[w2].taken = if_map[w2].not_taken = -1;
01514 break;
01515 }
01516 float taken = info.freq_taken.Value() / info.Total().Value();
01517 float not_taken = info.freq_not_taken.Value() / info.Total().Value();
01518
01519
01520 if ( !if_map.empty() )
01521 {
01522 WN * block;
01523 WN * parent = LWN_Get_Parent ( w2 );
01524
01525 get_parent_if ( &parent, &block );
01526
01527 if ( parent )
01528 {
01529 Is_True (block && WN_operator (block) == OPR_BLOCK, ("kid of if stmt wrong"));
01530
01531 if ( WN_kid1 (parent) == block )
01532 {
01533 taken *= if_map[parent].taken;
01534 not_taken *= if_map[parent].taken;
01535 }
01536 else
01537 {
01538 Is_True ( WN_kid2 (parent) == block, ("kid of if stmt wrong"));
01539 taken *= if_map[parent].not_taken;
01540 not_taken *= if_map[parent].not_taken;
01541 }
01542 }
01543 }
01544
01545 if_map[w2].taken = taken;
01546 if_map[w2].not_taken = not_taken;
01547 }
01548 break;
01549 #endif
01550 case OPR_ICALL:
01551 case OPR_CALL: {
01552
01553 if ((WN_opcode(w2) == OPC_VCALL) &&
01554 (WN_Fake_Call_EH_Region(w2, Parent_Map)))
01555 break;
01556
01557 #ifdef KEY
01558 float probability = -1;
01559
01560 if ( IPA_Enable_Branch_Heuristic && Cur_PU_Feedback &&
01561 WN_operator (w2) == OPR_CALL )
01562 {
01563 WN * block, * parent = LWN_Get_Parent ( w2 );
01564
01565 get_parent_if ( &parent, &block );
01566
01567 if (parent)
01568 {
01569 Is_True (block && WN_operator (block) == OPR_BLOCK, ("kid of if stmt wrong"));
01570 if ( WN_kid1 (parent) == block )
01571 probability = if_map[parent].taken;
01572 else
01573 probability = if_map[parent].not_taken;
01574 }
01575 }
01576 INT loopnest = get_loopnest (w2);
01577
01578 #if defined(KEY) && !defined(_STANDALONE_INLINER) && !defined(_LIGHTWEIGHT_INLINER)
01579
01580 if (Cur_PU_Feedback && WN_operator(w2) == OPR_ICALL)
01581 Process_icall (proc, w2, loopnest, probability);
01582 #endif
01583 #endif // KEY
01584
01585 proc->Incr_call_count ();
01586 #ifdef KEY
01587 Process_callsite (w2, proc->Get_callsite_count (), loopnest, probability);
01588 #else
01589 Process_callsite (w2, proc->Get_callsite_count (), loopnest);
01590 Direct_Mod_Ref = TRUE;
01591 #endif
01592 proc->Incr_callsite_count ();
01593
01594
01595 if (Do_common_const &&
01596 !Process_control_dependence (w2, Get_callsite_idx())) {
01597 proc->Set_has_unstructured_cflow();
01598 }
01599 break;
01600 }
01601
01602 case OPR_INTRINSIC_CALL:
01603 #ifdef KEY
01604 Process_callsite (w2, proc->Get_callsite_count (), get_loopnest (w2));
01605 #else
01606 Process_callsite (w2, proc->Get_callsite_count (), loopnest);
01607 Direct_Mod_Ref = TRUE;
01608 #endif
01609 proc->Incr_callsite_count ();
01610 break;
01611
01612 case OPR_ARRAY: {
01613 WN* base = WN_array_base(w2);
01614 if (OPERATOR_has_sym(WN_operator(base))) {
01615
01616
01617
01618 if (Do_common_const &&
01619 WN_is_istore_or_mstore(w2) &&
01620 ST_is_common_element(WN_st(base))) {
01621 if (!Process_control_dependence(w2, 0)) {
01622 proc->Set_has_unstructured_cflow();
01623 }
01624 }
01625
01626 else if (Do_parallel_stuff &&
01627 !WN_is_in_pragma(w2) &&
01628 (ST_level(WN_st(base)) == GLOBAL_SYMTAB ||
01629 ST_is_formal(WN_st(base)))) {
01630 if (!Process_control_dependence(w2, 0)) {
01631 proc->Set_has_unstructured_cflow();
01632 }
01633 }
01634 }
01635 break;
01636 }
01637
01638 case OPR_LDA:
01639 case OPR_LDID:
01640 case OPR_ILOAD:
01641 #ifndef KEY
01642 Direct_Mod_Ref = TRUE;
01643 #endif
01644 Record_ref (w2);
01645 #ifdef KEY
01646 if (Do_reorder) {
01647 loop_count = PU_invoke_count;
01648 if (!loop_count_stack->Is_Empty())
01649 loop_count *= loop_count_stack->Top();
01650 if (loop_count)
01651 Record_struct_access(w2,loop_count);
01652 }
01653 #else
01654 if(Do_reorder && !loop_count_stack->Is_Empty() ){
01655 loop_count=loop_count_stack->Top();
01656 Record_struct_access(w2,loop_count);
01657 }
01658 #endif
01659 break;
01660
01661 case OPR_STID:
01662 if (Do_common_const && ST_is_common_element(st)) {
01663 if (!Process_control_dependence(w2, 0)) {
01664 proc->Set_has_unstructured_cflow();
01665 }
01666 }
01667
01668
01669
01670 case OPR_ISTORE:
01671 case OPR_MSTORE:
01672 Direct_Mod_Ref = TRUE;
01673 Record_mod (w2);
01674 #ifdef KEY
01675 if (Do_reorder) {
01676 loop_count = PU_invoke_count;
01677 if (!loop_count_stack->Is_Empty())
01678 loop_count *= loop_count_stack->Top();
01679 if (loop_count)
01680 Record_struct_access(w2,loop_count);
01681 }
01682 #else
01683 if(Do_reorder && !loop_count_stack->Is_Empty() ) {
01684 loop_count=loop_count_stack->Top();
01685 Record_struct_access(w2,loop_count);
01686 }
01687 #endif
01688 break;
01689
01690 case OPR_IO:
01691 #ifdef KEY
01692
01693
01694 Direct_Mod_Ref = TRUE;
01695 proc->Set_has_side_effect ();
01696 #endif
01697 Process_IO(w2);
01698 break;
01699 case OPR_ILDA:
01700 case OPR_MLOAD:
01701 #ifdef KEY
01702 if (Do_reorder) {
01703 loop_count = PU_invoke_count;
01704 if (!loop_count_stack->Is_Empty())
01705 loop_count *= loop_count_stack->Top();
01706 if (loop_count)
01707 Record_struct_access(w2,loop_count);
01708 }
01709 #else
01710 if(Do_reorder && !loop_count_stack->Is_Empty() ) {
01711 loop_count=loop_count_stack->Top();
01712 Record_struct_access(w2,loop_count);
01713 }
01714 #endif
01715 break;
01716
01717
01718 case OPR_EXC_SCOPE_BEGIN:
01719 case OPR_EXC_SCOPE_END:
01720 Fail_FmtAssertion ("Invalid opcode from old style Exception Processing\n");
01721 break;
01722
01723 case OPR_REGION:
01724 if (WN_region_is_EH(w2))
01725 {
01726 #ifdef KEY
01727 Process_eh_region (w2);
01728 #endif
01729 proc->Set_exc_inline();
01730 }
01731 if (WN_region_kind(w2)== REGION_KIND_TRY)
01732 proc->Set_exc_try();
01733 break;
01734
01735 case OPR_PRAGMA:
01736 if (st) {
01737 if (ST_is_formal(st) && !ST_is_value_parm(st))
01738 proc->Set_has_formal_pragma();
01739
01740 if (PU_has_alloca (Get_Current_PU ()) &&
01741 is_variable_dim_array(ST_type(st)))
01742
01743 proc->Set_has_formal_pragma();
01744
01745 if (ST_sclass(st) == SCLASS_FORMAL ||
01746 PU_has_alloca (Get_Current_PU ())
01747 ) {
01748 switch (WN_pragma(w2)) {
01749 case WN_PRAGMA_DISTRIBUTE:
01750 case WN_PRAGMA_DISTRIBUTE_RESHAPE:
01751 case WN_PRAGMA_DYNAMIC:
01752 case WN_PRAGMA_REDISTRIBUTE:
01753 case WN_PRAGMA_AFFINITY:
01754 case WN_PRAGMA_DATA_AFFINITY:
01755 case WN_PRAGMA_THREAD_AFFINITY:
01756 case WN_PRAGMA_PAGE_PLACE:
01757 proc->Set_has_formal_pragma();
01758 break;
01759
01760 default:
01761 break;
01762 }
01763 }
01764
01765 if (TY_is_non_pod(ST_type(st))) {
01766 switch (WN_pragma(w2)) {
01767 case WN_PRAGMA_LOCAL:
01768 case WN_PRAGMA_LASTLOCAL:
01769 case WN_PRAGMA_FIRSTPRIVATE:
01770 Has_local_pragma = TRUE;
01771 break;
01772
01773 default:
01774 break;
01775 }
01776 }
01777 }
01778
01779
01780 if ((WN_pragma(w2) == WN_PRAGMA_DOACROSS) ||
01781 (WN_pragma(w2) == WN_PRAGMA_PARALLEL_DO)) {
01782 proc->Set_has_parallel_pragma();
01783 }
01784
01785
01786 if (WN_pragma(w2) == WN_PRAGMA_PARALLEL_BEGIN) {
01787 proc->Set_has_parallel_region_pragma();
01788 }
01789
01790 if ((WN_pragma(w2) == WN_PRAGMA_DOACROSS) ||
01791 (WN_pragma(w2) == WN_PRAGMA_PARALLEL_DO) ||
01792 (WN_pragma(w2) == WN_PRAGMA_PARALLEL_BEGIN) ||
01793 #ifdef KEY
01794
01795 (WN_pragma(w2) == WN_PRAGMA_THREADPRIVATE) ||
01796 #endif
01797 (WN_pragma(w2) == WN_PRAGMA_PARALLEL_SECTIONS))
01798 proc->Set_has_noinline_parallel_pragma();
01799
01800 if ((WN_pragma(w2) == WN_PRAGMA_PDO_BEGIN) ||
01801 (WN_pragma(w2) == WN_PRAGMA_PSECTION_BEGIN) ||
01802 (WN_pragma(w2) == WN_PRAGMA_SINGLE_PROCESS_BEGIN))
01803 Has_pdo_pragma = TRUE;
01804
01805 if (WN_has_pragma_with_side_effect(w2))
01806 #ifdef KEY
01807 proc->Set_has_pragma_side_effect();
01808 #else
01809 proc->Set_has_side_effect();
01810 #endif
01811
01812 #ifdef KEY
01813 if (WN_pragma(w2) == WN_PRAGMA_THREADPRIVATE)
01814 {
01815 ST * thdprv_st = ST_ptr (WN_pragma_arg2(w2));
01816 Get_symbol_index (thdprv_st);
01817 Record_global_ref (w2, thdprv_st, OPR_PRAGMA, TRUE);
01818
01819
01820 INT index = Global_hash_table->Find (thdprv_st);
01821 Is_True (index > 0, ("Invalid global symbol index"));
01822 SUMMARY_GLOBAL * global = Get_global (index - 1);
01823 global->Set_dmod ();
01824 global->Inc_modcount ();
01825 Get_symbol (global->Get_symbol_index ())->Set_modcount ();
01826 }
01827
01828
01829 if (st &&
01830 ST_level (st) == GLOBAL_SYMTAB &&
01831 ST_class (st) == CLASS_VAR)
01832 {
01833
01834
01835 Record_global_ref (w2, st, OPR_PRAGMA, TRUE);
01836 }
01837 #endif
01838
01839
01840 Process_pragma_node (w2);
01841 break;
01842
01843
01844
01845
01846
01847
01848 case OPR_PARM:
01849 Update_Addr_Passed_Count(w2);
01850 break;
01851
01852 case OPR_ALTENTRY:
01853 proc->Incr_altentry_count();
01854
01855 if ( Do_Altentry ) {
01856
01857
01858
01859 proc->Set_alt_entry();
01860 } else {
01861
01862
01863 proc->Set_has_alt_entry();
01864 }
01865
01866 proc->Set_no_inline();
01867
01868
01869
01870
01871
01872 if (!Do_Altentry)
01873 Process_alt_entry (w2);
01874 break;
01875
01876 case OPR_RETURN_VAL:
01877 Direct_Mod_Ref = TRUE;
01878
01879 case OPR_RETURN:
01880 if (!proc->Has_early_returns ()) {
01881 if (!Last_Node (iter))
01882 proc->Set_has_early_returns ();
01883 }
01884 break;
01885
01886 #ifdef KEY
01887
01888 case OPR_LABEL:
01889 {
01890 Is_True (Do_Altentry || !WN_Label_Is_Not_Used (w2),
01891 ("Label should not be marked yet"));
01892 label_wn &label = label_use_map [WN_label_number (w2)];
01893 Is_True (label.wn == NULL, ("Process_procedure: Duplicate labels?"));
01894 label.wn = w2;
01895 Is_True (label.wn != NULL, ("Process_procedure: Undefined label?"));
01896 break;
01897 }
01898
01899
01900 case OPR_GOTO_OUTER_BLOCK:
01901 Is_True (FALSE, ("Did not expect GOTO_OUTER_BLOCK"));
01902 case OPR_REGION_EXIT:
01903 {
01904 WN *region_exits = LWN_Get_Parent(w2);
01905 if(region_exits != NULL && WN_operator(region_exits) == OPR_BLOCK) {
01906 WN *region = LWN_Get_Parent(region_exits);
01907 if(region != NULL && WN_operator(region) == OPR_REGION
01908 && WN_kid0(region) == region_exits) {
01909
01910 break;
01911 }
01912 }
01913 }
01914
01915 case OPR_TRUEBR:
01916 case OPR_FALSEBR:
01917 case OPR_GOTO:
01918 case OPR_CASEGOTO:
01919 label_use_map [WN_label_number (w2)].seen = TRUE;
01920 break;
01921
01922
01923 case OPR_ASM_STMT:
01924 Direct_Mod_Ref = TRUE;
01925 break;
01926 #endif
01927 }
01928
01929 if (WN_next(w2) == NULL) {
01930
01931 WN *parent = LWN_Get_Parent (w2);
01932 if (parent && WN_opcode(parent) == OPC_BLOCK) {
01933 parent = LWN_Get_Parent (parent);
01934 if (parent) {
01935 switch (WN_opcode(parent)) {
01936 case OPC_DO_LOOP:
01937 case OPC_WHILE_DO:
01938 case OPC_DO_WHILE:
01939 #ifndef KEY // disable buggy loopnest computation
01940 loopnest--;
01941 #endif // !KEY
01942 if(Do_reorder){
01943 loop_count_stack->Pop();
01944 }
01945
01946 }
01947 }
01948 }
01949 }
01950
01951
01952
01953 if (OPCODE_has_sym(WN_opcode(w2)) && WN_st_idx(w2) != 0) {
01954 ST* st2 = ST_st_idx (st) == ST_base_idx (st) ? st : ST_base (st);
01955 if (ST_level (st2) == CURRENT_SYMTAB) {
01956
01957 if (ST_sclass (st2) == SCLASS_PSTATIC) {
01958
01959 Is_True (proc->Has_pstatic(),
01960 ("Has_pstatic should already be set"));
01961 proc->Set_has_pstatic ();
01962 }
01963 } else if (ST_sclass (st2) == SCLASS_FSTATIC &&
01964 !ST_class (st2) == CLASS_CONST)
01965 proc->Set_has_fstatic ();
01966 }
01967
01968 }
01969
01970 #ifdef KEY
01971 {
01972
01973 proc->Set_bb_count (PU_WN_BB_Cnt);
01974 proc->Set_stmt_count (PU_WN_Stmt_Cnt);
01975
01976
01977
01978 LABEL_WN_MAP::iterator i;
01979 INT unused_labels = 0;
01980
01981
01982 for (i = label_use_map.begin(); i != label_use_map.end(); i++)
01983 {
01984 Is_True ((*i).second.wn, ("Process_procedure: Undefined label?"));
01985 if (!(*i).second.seen)
01986 {
01987 unused_labels++;
01988 WN_Set_Label_Is_Not_Used ((*i).second.wn);
01989 }
01990 }
01991
01992
01993 if (unused_labels)
01994 {
01995 UINT16 bbs = proc->Get_bb_count();
01996 Is_True (bbs >= unused_labels,
01997 ("Expected all labels to be included in bb count"));
01998 proc->Set_bb_count (bbs - unused_labels);
01999 }
02000 }
02001 if_map.clear ();
02002 #endif // KEY
02003
02004
02005 if (proc->Get_callsite_count () > 0)
02006 proc->Set_callsite_index (Get_callsite_idx () -
02007 proc->Get_callsite_count () + 1);
02008
02009 proc->Set_global_count (Get_global_idx () + 1 - proc->Get_global_index ());
02010
02011
02012 if (!Do_Altentry) {
02013 if (Cur_PU_Feedback) {
02014 INT bb_count = 0;
02015 INT stmt_count = 0;
02016 #ifdef KEY
02017 FB_FREQ cycle_count(0.0);
02018 #else
02019 FB_FREQ cycle_count(0);
02020 #endif
02021 UINT16 WN_Count = 0;
02022 #ifdef KEY
02023 FB_FREQ Cycle_Count2(0.0);
02024 #else
02025 FB_FREQ Cycle_Count2(0);
02026 #endif
02027 SUMMARY_FEEDBACK *fb = Get_feedback (proc->Get_feedback_index ());
02028 FB_FREQ freq_count = fb->Get_frequency_count();
02029
02030 Count_tree_size_tuning (*Cur_PU_Feedback, Get_entry_point (), bb_count, stmt_count, cycle_count, freq_count, WN_Count, Cycle_Count2);
02031
02032 if (!cycle_count.Known()) {
02033 proc->Clear_has_PU_freq();
02034 DevWarn("%s has unknown frequencies so no feedback info in this procedure will be considered", ST_name(WN_st(w)));
02035
02036 }
02037 else
02038 {
02039 fb->Set_cycle_count (cycle_count);
02040 fb->Set_cycle_count_2(Cycle_Count2);
02041 }
02042 fb->Set_effective_bb_count (bb_count);
02043 fb->Set_effective_stmt_count (stmt_count);
02044 fb->Set_wn_count(WN_Count);
02045 }
02046
02047 if (DoPreopt) {
02048
02049 proc->Set_ctrl_dep_index (Get_ctrl_dep_idx () + 1);
02050 Generate_summary_control_dependence ();
02051 proc->Set_ctrl_dep_count (Get_ctrl_dep_idx () -
02052 proc->Get_ctrl_dep_index () + 1);
02053 if (Get_phi_idx () > phi_index)
02054 Fix_phi_node_ctrl_dep_index (Get_phi (phi_index + 1),
02055 Get_phi_idx () - phi_index);
02056 }
02057 if (Do_Par)
02058 IPL_Execution_Cost(w, proc, &Temp_pool, FALSE);
02059 if (Do_parallel_stuff) {
02060 IPL_Access_Vector_To_Projected_Region(w,
02061 proc,
02062 pu_first_formal_idx,
02063 pu_last_formal_idx,
02064 pu_first_actual_idx,
02065 Get_actual_idx(),
02066 pu_first_callsite_idx,
02067 Get_callsite_idx());
02068 Finalize_Access_Vals();
02069 IPL_Finalize_Projected_Regions(proc);
02070 IPL_Finalize_Par_Code();
02071 }
02072 if(Do_reorder)
02073 num_struct_access=Finish_PU_process_struct_access();
02074
02075 Set_local_addr_taken_attrib ();
02076 } else {
02077 if (Do_Par)
02078 IPL_Execution_Cost(w, proc, &Temp_pool, TRUE);
02079 }
02080
02081 if ( Direct_Mod_Ref )
02082 proc->Set_direct_mod_ref();
02083
02084 if ( Has_local_pragma && Has_pdo_pragma)
02085 proc->Set_has_pdo_pragma();
02086
02087 }
02088
02089
02090
02091
02092
02093
02094
02095
02096 template <PROGRAM program>
02097 void
02098 SUMMARIZE<program>::Update_call_pragmas (SUMMARY_CALLSITE *callsite)
02099 {
02100 INT name_index;
02101 char* func_name;
02102
02103 func_name = ST_name (Get_symbol (callsite->Get_symbol_index())->St_idx ());
02104
02105
02106 for (INT i = Get_inline_attr_idx(); i >= 0; i--) {
02107 INLINE_ATTR *pragma = Get_inline_attr (i);
02108 char *name = pragma->Get_name ();
02109 BOOL is_f77 = PU_f77_lang (Get_Current_PU ());
02110 if (is_f77) {
02111 if (Fortran_string_compare (name, func_name)) {
02112 if (pragma->Is_file_inline())
02113 callsite->Set_must_inline();
02114 if (pragma->Is_no_file_inline())
02115 callsite->Set_no_inline();
02116 return;
02117 }
02118 } else {
02119 if (func_name[0] == name[0] && strcmp (func_name, name) == 0) {
02120 if (pragma->Is_file_inline())
02121 callsite->Set_must_inline();
02122 if (pragma->Is_no_file_inline())
02123 callsite->Set_no_inline();
02124 return;
02125 }
02126 }
02127 }
02128 }
02129
02130 #if defined(KEY) && !defined(_STANDALONE_INLINER) && !defined(_LIGHTWEIGHT_INLINER)
02131
02132
02133
02134 template <PROGRAM program>
02135 void
02136 SUMMARIZE<program>::Process_icall (SUMMARY_PROCEDURE * proc, WN * wn,
02137 INT loopnest, float probability)
02138 {
02139 Is_True (WN_operator (wn) == OPR_ICALL, ("Process_icall: ICALL expected"));
02140
02141
02142 const int freq_threshold = IPA_Icall_Min_Freq;
02143
02144 const FB_Info_Call& info_call = Cur_PU_Feedback->Query_call(wn);
02145 if (!info_call.freq_entry.Known())
02146 return;
02147 if (info_call.freq_entry.Value() < freq_threshold)
02148 return;
02149
02150 FB_Info_Icall info_icall = Cur_PU_Feedback->Query_icall(wn);
02151 if (info_icall.Is_uninit())
02152 return;
02153
02154 if (info_icall.tnv._exec_counter < info_call.freq_entry.Value())
02155 {
02156 const UINT64 gap = (UINT64)info_call.freq_entry.Value() -
02157 info_icall.tnv._exec_counter;
02158 info_icall.tnv._exec_counter += gap;
02159 info_icall.tnv._counters[0] += gap;
02160 Cur_PU_Feedback->Annot_icall (wn, info_icall);
02161 }
02162
02163 const UINT64 exec_counter = info_icall.tnv._exec_counter;
02164 const UINT64 callee_counter = info_icall.tnv._counters[0];
02165 const UINT64 callee_addr = info_icall.tnv._values[0];
02166
02167 if (exec_counter == 0 || callee_counter == 0)
02168 return;
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179 SUMMARY_CALLSITE * cs = New_callsite();
02180 cs->Set_callsite_id (proc->Get_callsite_count());
02181 cs->Set_loopnest (loopnest);
02182 cs->Set_probability (probability);
02183 cs->Set_param_count (WN_num_actuals (wn));
02184 cs->Set_return_type (WN_rtype (wn));
02185
02186
02187 static ST * st = NULL;
02188
02189 if (! st)
02190 {
02191 PU_IDX pu_idx;
02192 PU& pu = New_PU (pu_idx);
02193
02194
02195 PU_Init (pu, MTYPE_TO_TY_array[MTYPE_V], GLOBAL_SYMTAB+1);
02196
02197 st = New_ST (GLOBAL_SYMTAB);
02198 ST_Init (st, Save_Str ("__dummy_icall_target"),
02199 CLASS_FUNC, SCLASS_EXTERN, EXPORT_PREEMPTIBLE,
02200 TY_IDX (pu_idx));
02201 vector<IPL_ST_INFO>& aux_st = Aux_Symbol_Info[GLOBAL_SYMTAB];
02202 aux_st.insert (aux_st.end(), 1, IPL_ST_INFO ());
02203 }
02204 cs->Set_symbol_index (Get_symbol_index (st));
02205
02206 FB_FREQ freq ((float) callee_counter, FB_FREQ_TYPE_EXACT);
02207 cs->Set_callsite_freq ();
02208 cs->Set_frequency_count (freq);
02209 cs->Set_icall_target ();
02210 cs->Set_targ_runtime_addr (callee_addr);
02211
02212
02213
02214 for (INT i = 0; i < cs->Get_param_count (); i++)
02215 Process_actual (WN_actual (wn, i));
02216
02217 if (cs->Get_param_count () > 0)
02218 cs->Set_actual_index (Get_actual_idx () - cs->Get_param_count () + 1);
02219
02220 proc->Incr_callsite_count ();
02221 proc->Incr_call_count ();
02222 }
02223 #endif // KEY && !(_STANDALONE_INLINER) && !(_LIGHTWEIGHT_INLINER)
02224
02225
02226
02227
02228 template <PROGRAM program>
02229 void
02230 SUMMARIZE<program>::Process_callsite (WN *w, INT id, INT loopnest, float probability)
02231 {
02232 INT count;
02233 SUMMARY_CALLSITE *callsite = New_callsite ();
02234
02235 if (program == IPL)
02236 WN_MAP32_Set (Summary_Map, w, Get_callsite_idx () + 1);
02237
02238 callsite->Set_callsite_id (id);
02239 callsite->Set_loopnest (loopnest);
02240 #ifdef KEY
02241 callsite->Set_probability (probability);
02242 #endif
02243 callsite->Set_param_count (WN_num_actuals(w));
02244 callsite->Set_return_type (WN_rtype(w));
02245
02246 if (program == INLINER) {
02247 callsite->Set_symbol_index (Get_symbol_index(WN_st(w)));
02248
02249 WN_MAP_Set_ID (Current_Map_Tab, w);
02250
02251 if (File_Pragmas)
02252 Update_call_pragmas(callsite);
02253
02254 switch (WN_operator(w)) {
02255
02256 case OPR_CALL:
02257
02258
02259
02260
02261
02262 if (WN_Call_Inline(w) && WN_Call_Dont_Inline(w)) {
02263 if (Trace_IPA || Trace_Perf)
02264 fprintf (TFile, "\t user specified inconsistent inline"
02265 " pragmas at callsite\n");
02266 } else if (WN_Call_Dont_Inline(w)) {
02267
02268 callsite->Set_no_inline();
02269 } else if (WN_Call_Inline(w)) {
02270
02271 callsite->Set_must_inline();
02272 } else {
02273 WN* parent_block = LWN_Get_Parent(w);
02274 Is_True(parent_block, ("Cannot get parent node of call\n"));
02275
02276
02277
02278
02279 if (WN_operator (parent_block) != OPR_BLOCK) {
02280
02281 callsite->Set_no_inline();
02282 } else if (WN_operator (parent_block) == OPR_IO_ITEM) {
02283
02284
02285 callsite->Set_no_inline();
02286 }
02287 }
02288
02289 break;
02290 default:
02291 break;
02292 }
02293
02294 #if 0
02295 if (!INLINE_Enable_Copy_Prop)
02296 return;
02297 #endif
02298 } else {
02299
02300
02301 switch (WN_operator(w)) {
02302
02303 case OPR_ICALL:
02304 callsite->Set_func_ptr ();
02305 count = WN_kid_count(w) - 1;
02306
02307 if (OPCODE_has_sym(WN_opcode(WN_kid(w, count)))) {
02308
02309 const SUMMARY_CHECK_POINT chk_pt (this);
02310
02311 SUMMARY_VALUE *value = New_value ();
02312 INT value_idx = Get_value_idx ();
02313 value->Set_not_const ();
02314
02315 Process_jump_function (WN_kid(w, count), value_idx);
02316
02317 value = Get_value (value_idx);
02318 INT tmp_idx = entry_cache->Lookup (SUM_VALUE, value);
02319 if (tmp_idx != -1 && tmp_idx < value_idx) {
02320 Restore_from_check_point(&chk_pt);
02321 callsite->Set_value_index (tmp_idx);
02322 } else {
02323 entry_cache->Insert (SUM_VALUE, value_idx);
02324 callsite->Set_value_index (value_idx);
02325 }
02326 }
02327
02328 WN_MAP_Set_ID(Current_Map_Tab, w);
02329 callsite->Set_map_id (WN_map_id(w));
02330
02331
02332 if (WN_Call_Is_Virtual(w)) {
02333 callsite->Set_is_virtual_call();
02334 WN *last = WN_kid(w, WN_kid_count(w)-1);
02335 #ifdef TARG_IA64
02336 if (WN_operator_is(last, OPR_ADD)) {
02337 FmtAssert(WN_kid_count(last) == 2, ("Incorrect virtual call site."));
02338 WN *addr = WN_kid0(last);
02339 WN *ofst = WN_kid1(last);
02340 FmtAssert(WN_operator_is(addr, OPR_ILOAD) || WN_operator_is(addr, OPR_LDID),
02341 ("Virtual function call does not use ILOAD or LDID."));
02342 FmtAssert(WN_operator_is(ofst, OPR_INTCONST),
02343 ("Virtual table offset is not INTCONST."));
02344 callsite->Set_virtual_class(WN_ty(addr));
02345 callsite->Set_vtable_offset(WN_const_val(ofst));
02346 callsite->Set_vptr_offset(WN_load_offset(addr));
02347 }
02348 else {
02349
02350
02351 FmtAssert(WN_operator_is(last, OPR_ILOAD) || WN_operator_is(last, OPR_LDID),
02352 ("Virtual function call does not use ILOAD or LDID."));
02353 callsite->Set_vptr_offset(WN_load_offset(last));
02354 callsite->Set_virtual_class(WN_ty(last));
02355 callsite->Set_vtable_offset(0);
02356 }
02357 #endif
02358 #ifdef TARG_X8664
02359 FmtAssert(WN_operator_is(last, OPR_ILOAD),
02360 ("Virtual function call does node use ILOAD."));
02361 callsite->Set_vtable_offset(WN_load_offset(last));
02362 WN *vptr = WN_kid0(last);
02363 FmtAssert(WN_operator_is(vptr, OPR_ILOAD) || WN_operator_is(vptr, OPR_LDID),
02364 ("Virtual function call does not use ILOAD or LDID."));
02365 callsite->Set_virtual_class(WN_ty(vptr));
02366 callsite->Set_vptr_offset(WN_load_offset(vptr));
02367 #endif
02368 }
02369
02370 break;
02371
02372 case OPR_CALL:
02373 callsite->Set_symbol_index (Get_symbol_index (WN_st(w)));
02374 WN_MAP_Set_ID(Current_Map_Tab, w);
02375 callsite->Set_map_id (WN_map_id(w));
02376
02377 if (Cur_PU_Feedback) {
02378 FB_FREQ freq = Cur_PU_Feedback->Query(w, FB_EDGE_CALL_INCOMING);
02379 if (freq.Known()) {
02380 callsite->Set_callsite_freq ();
02381 callsite->Set_frequency_count (freq);
02382 }
02383 else {
02384 SUMMARY_PROCEDURE *proc = Get_procedure (Get_procedure_idx());
02385 proc->Clear_has_PU_freq();
02386 DevWarn("%s has unknown frequencies so no feedback info in this procedure will be considered", ST_name(WN_st(w)));
02387
02388 }
02389 }
02390
02391
02392 if (File_Pragmas) {
02393 Update_call_pragmas (callsite);
02394 }
02395
02396
02397
02398
02399
02400
02401 if (WN_Call_Inline(w) && WN_Call_Dont_Inline(w)) {
02402 if (Trace_IPA || Trace_Perf)
02403 fprintf (TFile, "\t user specified inconsistent inline"
02404 " pragmas at callsite\n");
02405 } else if (WN_Call_Dont_Inline(w)) {
02406
02407 callsite->Set_no_inline();
02408 } else if (WN_Call_Inline(w)) {
02409
02410 callsite->Set_must_inline();
02411 } else {
02412 WN* parent_block = LWN_Get_Parent(w);
02413 Is_True(parent_block, ("Cannot get parent node of call\n"));
02414 if (WN_operator (parent_block) != OPR_BLOCK) {
02415
02416 callsite->Set_no_inline();
02417 }
02418 }
02419
02420 break;
02421
02422 case OPR_INTRINSIC_CALL:
02423
02424 callsite->Set_intrinsic();
02425 WN_MAP_Set_ID(Current_Map_Tab, w);
02426 callsite->Set_map_id (WN_map_id(w));
02427 break;
02428
02429 case OPR_INTRINSIC_OP:
02430 callsite->Set_intrinsic();
02431 callsite->Set_map_id (-1);
02432 break;
02433
02434 default:
02435 Fail_FmtAssertion ("Unsupported OPCODE %s \n",
02436 OPCODE_name(WN_opcode(w)));
02437 break;
02438 }
02439 }
02440
02441
02442
02443
02444 for (INT i = 0; i < callsite->Get_param_count (); i++)
02445 Process_actual (WN_actual (w, i));
02446
02447 if (callsite->Get_param_count () > 0)
02448 callsite->Set_actual_index (Get_actual_idx () -
02449 callsite->Get_param_count () + 1);
02450
02451 }
02452
02453
02454
02455 template <PROGRAM program>
02456 void
02457 SUMMARIZE<program>::Process_formal (WN *w, INT num_formals, SUMMARY_PROCEDURE *proc)
02458 {
02459 for (INT i = 0; i < num_formals; i++) {
02460 SUMMARY_FORMAL *formal = New_formal ();
02461 BZERO (formal, sizeof(SUMMARY_FORMAL));
02462 const ST* formal_st = WN_st (WN_formal (w, i));
02463 INT sym_idx = Get_symbol_index (formal_st);
02464 formal->Set_symbol_index (sym_idx);
02465 Get_symbol (sym_idx)->Set_findex (Get_formal_idx());
02466 if (ST_sclass (formal_st) == SCLASS_FORMAL_REF)
02467 formal->Set_is_ref_parm ();
02468 formal->Set_position (i);
02469 formal->Set_region_index (-1);
02470 formal->Set_machine_type(Machine_Type(WN_formal(w, i)));
02471 formal->Set_ty(Promoted_Parm_Type(formal_st));
02472 if (is_variable_dim_array(formal->Get_ty())) {
02473 formal->Set_is_var_dim_array();
02474 proc->Set_has_var_dim_array();
02475 }
02476 }
02477
02478 INT position = Get_formal_idx () - num_formals + 1;
02479 proc->Set_formal_index (position);
02480 proc->Set_formal_count (num_formals);
02481 }
02482
02483
02484 template <PROGRAM program>
02485 void
02486 SUMMARIZE<program>::Process_formal_alt (WN *w, INT kid_count)
02487 {
02488 for (INT i = 0; i < kid_count; i++) {
02489 SUMMARY_FORMAL *formal = New_formal ();
02490 BZERO (formal, sizeof(SUMMARY_FORMAL));
02491 const ST* formal_st = WN_st(WN_kid(w, i));
02492 INT sym_idx = Get_symbol_index (formal_st);
02493 formal->Set_symbol_index (sym_idx);
02494 Get_symbol (sym_idx)->Set_findex (Get_formal_idx());
02495 if (ST_sclass (formal_st) == SCLASS_FORMAL_REF)
02496 formal->Set_is_ref_parm ();
02497 formal->Set_position (i);
02498 formal->Set_region_index (-1);
02499 formal->Set_machine_type(Machine_Type(WN_formal(w, i)));
02500 formal->Set_ty (ST_type(formal_st));
02501 if (is_variable_dim_array(formal->Get_ty())) {
02502 formal->Set_is_var_dim_array();
02503 }
02504 }
02505 }
02506
02507
02508 static inline BOOL
02509 Parm_Type_Equal_To_Etype(TY_IDX parm_ty, WN* array_wn)
02510 {
02511 Is_True(WN_operator(array_wn) == OPR_ARRAY,
02512 ("Parm_Type_Equal_To_Etype: expected an array node"));
02513
02514 WN* base_wn = WN_array_base(array_wn);
02515 if (OPERATOR_has_sym(WN_operator(base_wn))) {
02516 ST* array_st = WN_st(base_wn);
02517 TY_IDX array_ty = ST_type(array_st);
02518 if (TY_kind(array_ty) == KIND_POINTER) {
02519 array_ty = TY_pointed(array_ty);
02520 }
02521 return (TY_kind(array_ty) == KIND_ARRAY && TY_etype(array_ty) == parm_ty);
02522 }
02523
02524 return FALSE;
02525 }
02526
02527 #ifdef KEY
02528
02529
02530
02531
02532
02533
02534
02535
02536
02537 static WN * traverse_actual (WN * w)
02538 {
02539
02540 if (!OPERATOR_is_expression (WN_operator (w)))
02541 return NULL;
02542
02543 if (WN_operator (w) == OPR_LDA) return w;
02544
02545 for (INT i = 0; i < WN_kid_count (w); i++)
02546 {
02547 WN * lda = traverse_actual (WN_kid (w, i));
02548 if (lda) return lda;
02549 }
02550 return NULL;
02551 }
02552 #endif
02553
02554 template <PROGRAM program>
02555 void
02556 SUMMARIZE<program>::Process_actual (WN* w)
02557 {
02558 SUMMARY_ACTUAL* actual = New_actual ();
02559 #ifdef KEY
02560
02561 const WN * param = w;
02562 #endif
02563
02564 OPERATOR opr = WN_operator(w);
02565 if (opr == OPR_PARM) {
02566
02567 WN* kid = WN_kid0(w);
02568 opr = WN_operator(kid);
02569
02570 if (WN_Parm_By_Reference(w)) {
02571
02572 if (opr == OPR_INTCONST && WN_const_val(kid) == 0) {
02573
02574 actual->Set_ty(0);
02575 }
02576 else if (opr == OPR_ARRAYEXP || opr == OPR_ARRSECTION) {
02577
02578
02579 actual->Set_ty(0);
02580 }
02581 else {
02582 TY_IDX parm_ty = WN_ty(w);
02583 if (opr == OPR_ARRAY &&
02584 TY_kind(parm_ty) == KIND_POINTER &&
02585 Parm_Type_Equal_To_Etype(TY_pointed(parm_ty), kid)) {
02586
02587 ST* array_st = WN_st(WN_array_base(kid));
02588 actual->Set_symbol_index(Get_symbol_index(array_st));
02589 actual->Set_ty(ST_type(array_st));
02590 }
02591 else {
02592 actual->Set_ty(parm_ty);
02593 if (OPERATOR_has_sym(opr)) {
02594 actual->Set_symbol_index(Get_symbol_index(WN_st(kid)));
02595 }
02596 }
02597 }
02598 }
02599 else {
02600 if (WN_Parm_By_Value(w)) {
02601 actual->Set_is_value_parm();
02602 }
02603 actual->Set_ty(WN_ty(w));
02604 w = WN_kid0(w);
02605 if (OPERATOR_has_sym(opr)) {
02606 actual->Set_symbol_index(Get_symbol_index(WN_st(w)));
02607 }
02608 #ifdef KEY
02609 else {
02610
02611 WN * lda = traverse_actual (w);
02612 if (lda) {
02613 actual->Set_symbol_index(Get_symbol_index (WN_st (lda)));
02614 opr = WN_operator (lda);
02615 }
02616 }
02617 #endif
02618 }
02619 }
02620
02621 if (program == INLINER)
02622 return;
02623
02624 SUMMARY_VALUE *value;
02625
02626 switch (opr) {
02627
02628 case OPR_INTCONST: {
02629
02630 if (WN_operator (w) == OPR_PARM)
02631 w = WN_kid0(w);
02632 if (WN_rtype(w) == MTYPE_I4 &&
02633 (WN_const_val(w) == 0 || WN_const_val(w) == 1)) {
02634
02635 actual->Set_value_index (WN_const_val (w));
02636 return;
02637 }
02638
02639 value = New_value ();
02640 value->Set_int_const ();
02641 value->Set_int_const_value (WN_const_val (w));
02642 value->Set_mtype (WN_rtype (w));
02643
02644 INT idx = entry_cache->Lookup (SUM_VALUE, value);
02645 if (idx != -1 && idx < Get_value_idx()) {
02646 actual->Set_value_index (idx);
02647 _value.Decidx ();
02648 }
02649 else {
02650 entry_cache->Insert (SUM_VALUE, Get_value_idx ());
02651 actual->Set_value_index (Get_value_idx ());
02652 }
02653 return;
02654 }
02655
02656 case OPR_LDID:
02657 actual->Set_pass_type(PASS_LDID);
02658 break;
02659
02660 case OPR_ILOAD:
02661 actual->Set_pass_type(PASS_LOAD);
02662 break;
02663
02664 case OPR_MLOAD:
02665 actual->Set_pass_type(PASS_MLOAD);
02666 break;
02667
02668 case OPR_LDA:
02669 actual->Set_pass_type(PASS_LDA);
02670 break;
02671
02672 #ifdef KEY
02673 case OPR_ARRAY:
02674 if (WN_Parm_By_Reference(param))
02675 actual->Set_pass_type(PASS_ARRAY);
02676 break;
02677 #endif
02678
02679 default:
02680 actual->Set_pass_type(PASS_UNKNOWN);
02681 break;
02682 }
02683
02684 const SUMMARY_CHECK_POINT chk_pt(this);
02685
02686 value = New_value ();
02687 value->Set_not_const ();
02688 actual->Set_value_index (Get_value_idx ());
02689
02690 Process_jump_function (w, Get_value_idx ());
02691
02692 value = Get_value (actual->Get_value_index ());
02693
02694 if (value->Is_not_const ()) {
02695 Restore_from_check_point (&chk_pt);
02696 actual->Set_value_index (-1);
02697 }
02698 else {
02699 INT tmp_idx = entry_cache->Lookup (SUM_VALUE, value);
02700 if (tmp_idx != -1 && tmp_idx < actual->Get_value_index()) {
02701 Restore_from_check_point (&chk_pt);
02702 actual->Set_value_index (tmp_idx);
02703 }
02704 else {
02705 entry_cache->Insert (SUM_VALUE, actual->Get_value_index ());
02706 }
02707 }
02708
02709 }
02710
02711
02712
02713
02714
02715 template <PROGRAM program>
02716 BOOL
02717 SUMMARIZE<program>::Has_global_symbol_index(const ST* st)
02718 {
02719 INT idx;
02720 SUMMARY_SYMBOL *sym;
02721
02722 if (ST_class(st) == CLASS_CONST)
02723 return -1;
02724
02725
02726 if (ST_level (st) == GLOBAL_SYMTAB) {
02727
02728 idx = ST_index (st);
02729
02730 if (idx <= Global_index->Lastidx() && (*Global_index)[idx])
02731 return TRUE;
02732 }
02733 return FALSE;
02734 }
02735
02736
02737
02738
02739
02740
02741
02742 static void Save_Symbol_Name(const ST* st)
02743 {
02744 static BOOL Ipl_Symbol_Function_Names_Inited = FALSE;
02745 if (!Ipl_Symbol_Function_Names_Inited) {
02746 Ipl_Symbol_Function_Names_Inited = TRUE;
02747 Ipl_Symbol_Names = CXX_NEW(DYN_ARRAY<char*>(Malloc_Mem_Pool),
02748 Malloc_Mem_Pool);
02749 Ipl_Function_Names = CXX_NEW(DYN_ARRAY<char*>(Malloc_Mem_Pool),
02750 Malloc_Mem_Pool);
02751 }
02752 INT idx_symbol = Ipl_Symbol_Names->Newidx();
02753 INT idx_function = Ipl_Function_Names->Newidx();
02754 char** symbol_name = &((*Ipl_Symbol_Names)[idx_symbol]);
02755 char** function_name = &((*Ipl_Function_Names)[idx_symbol]);
02756 const char* original_symbol_name = ST_name(st);
02757 const char* original_function_name = Scope_tab[CURRENT_SYMTAB].st == NULL
02758 ? "?" : ST_name(ST_st_idx(Scope_tab[CURRENT_SYMTAB].st));
02759 *symbol_name = CXX_NEW_ARRAY(char, strlen(original_symbol_name) + 1,
02760 Malloc_Mem_Pool);
02761 *function_name = CXX_NEW_ARRAY(char,
02762 strlen(original_function_name) + 1, Malloc_Mem_Pool);
02763 strcpy(*symbol_name, original_symbol_name);
02764 strcpy(*function_name, original_function_name);
02765 }
02766
02767
02768
02769
02770
02771
02772 template <PROGRAM program>
02773 INT32
02774 SUMMARIZE<program>::Get_symbol_index (const ST *st)
02775 {
02776 if (ST_class(st) == CLASS_CONST) {
02777 return -1;
02778 }
02779
02780 UINT32& index = Aux_Symbol(st).summary_symbol_idx;
02781
02782 if (index != (UINT32) -1) {
02783 return index;
02784 }
02785
02786 SUMMARY_SYMBOL* sym = New_symbol();
02787
02788 if (Get_Trace(TKIND_IR, TP_IPL)) {
02789 Save_Symbol_Name(st);
02790 }
02791
02792 sym->Set_st_idx (ST_st_idx(st));
02793 sym->Set_st_idx_func(ST_st_idx(Scope_tab[CURRENT_SYMTAB].st));
02794
02795 if (ST_sclass(st) == SCLASS_PSTATIC || ST_sclass(st) == SCLASS_FSTATIC) {
02796 sym->Set_static();
02797 }
02798
02799 if (ST_is_export_local(st)) {
02800 sym->Set_local();
02801 }
02802
02803 if (ST_is_formal(st)) {
02804 sym->Set_formal();
02805 if (ST_is_optional_argument(st)) {
02806 sym->Set_optional();
02807 }
02808 }
02809
02810 if (ST_class(st) == CLASS_FUNC) {
02811 sym->Set_function();
02812 }
02813 else if (ST_is_common_block(st)) {
02814 sym->Set_common_block();
02815 }
02816 else if (ST_is_common_element(st)) {
02817 sym->Set_common();
02818 }
02819
02820 if (ST_class(st) == CLASS_FUNC || ST_class(st) == CLASS_BLOCK) {
02821 sym->Set_btype(MTYPE_UNKNOWN);
02822 }
02823 else {
02824 sym->Set_btype(TY_mtype(ST_type(st)));
02825 }
02826
02827 if (ST_class(st) != CLASS_FUNC) {
02828
02829 if (TY_kind(ST_type(st)) == KIND_POINTER) {
02830 if (TY_kind(TY_pointed(ST_type(st))) == KIND_ARRAY)
02831 sym->Set_array();
02832 } else {
02833 if (TY_kind(ST_type(st)) == KIND_ARRAY)
02834 sym->Set_array();
02835 }
02836 }
02837
02838 if (ST_is_f90_target (st))
02839 sym->Set_addr_f90_target ();
02840
02841 index = Get_symbol_idx();
02842
02843 return index;
02844
02845 }
02846
02847
02848 template <PROGRAM program>
02849 void
02850 SUMMARIZE<program>::Process_alt_entry (WN *w)
02851 {
02852 ALT_ENTRY *alt = New_alt_entry ();
02853
02854 alt->Set_wn (w);
02855
02856 Process_formal_alt (w, WN_kid_count(w));
02857
02858 INT position = Get_formal_idx () - WN_kid_count(w) + 1;
02859 alt->Set_position (position);
02860 alt->Set_formal_count (WN_kid_count(w));
02861
02862 }
02863
02864
02865 template <PROGRAM program>
02866 void
02867 SUMMARIZE<program>::Process_inline_attr (WN *pragma_node)
02868 {
02869 INLINE_ATTR *inline_attr;
02870 TCON tc;
02871
02872 switch (WN_pragma(pragma_node)) {
02873
02874 case WN_PRAGMA_KAP_OPTION_INLINE:
02875 inline_attr = New_inline_attr ();
02876 tc = STC_val(WN_st(pragma_node));
02877 inline_attr->Set_name (Targ_String_Address(tc));
02878 inline_attr->Set_file_inline();
02879 break;
02880
02881 case WN_PRAGMA_KAP_OPTION_NOINLINE:
02882 inline_attr = New_inline_attr ();
02883 tc = STC_val(WN_st(pragma_node));
02884 inline_attr->Set_name (Targ_String_Address(tc));
02885 inline_attr->Set_no_file_inline();
02886 break;
02887
02888 default:
02889 break;
02890 }
02891 }
02892
02893
02894
02895
02896 template <PROGRAM program>
02897 void
02898 SUMMARIZE<program>::Process_pragma_node (WN* w)
02899 {
02900 switch (WN_pragma(w)) {
02901
02902 case WN_PRAGMA_KAP_OPTION_INLINE:
02903 case WN_PRAGMA_KAP_OPTION_NOINLINE:
02904 Process_inline_attr (w);
02905 File_Pragmas = TRUE;
02906 break;
02907
02908 default:
02909 break;
02910 }
02911 }
02912
02913
02914
02915
02916
02917 template <PROGRAM program>
02918 void
02919 SUMMARIZE<program>::Process_pragmas (WN *w)
02920 {
02921 WN* pragmas = WN_func_pragmas(w);
02922
02923 if (pragmas)
02924 pragmas = WN_first(pragmas);
02925
02926 while (pragmas != NULL) {
02927 Process_pragma_node (pragmas);
02928 pragmas = WN_next(pragmas);
02929 }
02930 }
02931
02932
02933
02934
02935
02936
02937 template <PROGRAM program>
02938 void
02939 SUMMARIZE<program>::Trace(FILE* fp)
02940 {
02941 if (Has_symbol_entry()) {
02942 Ipl_Summary_Symbol = Get_symbol(0);
02943 Ipl_Summary_Symbol->Print_array(fp, Get_symbol_idx()+1);
02944 }
02945
02946 if (Has_procedure_entry())
02947 Get_procedure(0)->Print_array(fp, Get_procedure_idx()+1);
02948
02949 if (Has_callsite_entry())
02950 Get_callsite(0)->Print_array(fp, Get_callsite_idx()+1);
02951
02952 if (Has_feedback_entry())
02953 Get_feedback(0)->Print_array(fp, Get_feedback_idx()+1);
02954
02955 if (Has_actual_entry())
02956 Get_actual(0)->Print_array(fp, Get_actual_idx()+1);
02957
02958 if (Has_value_entry())
02959 Get_value(0)->Print_array(fp, Get_value_idx()+1);
02960
02961 if (Has_expr_entry())
02962 Get_expr(0)->Print_array(fp, Get_expr_idx()+1);
02963
02964 if (Has_phi_entry())
02965 Get_phi(0)->Print_array(fp, Get_phi_idx()+1);
02966
02967 if (Has_chi_entry())
02968 Get_chi(0)->Print_array(fp, Get_chi_idx()+1);
02969
02970 if (Has_stmt_entry())
02971 Get_stmt(0)->Print_array(fp, Get_stmt_idx()+1);
02972
02973 if (Has_ctrl_dep_entry())
02974 Get_ctrl_dep(0)->Print_array(fp, Get_ctrl_dep_idx()+1);
02975
02976 if (Has_formal_entry())
02977 Get_formal(0)->Print_array(fp, Get_formal_idx()+1);
02978
02979 if (Has_global_entry())
02980 Get_global(0)->Print_array(fp, Get_global_idx()+1);
02981
02982 if (Has_global_stid_entry())
02983 Get_global_stid(0)->Print_array(fp, Get_global_stid_idx()+1);
02984
02985 if (Has_common_entry())
02986 Get_common(0)->Print_array(fp, Get_common_idx()+1);
02987
02988 if (Has_common_shape_entry())
02989 Get_common_shape(0)->Print_array(fp, Get_common_shape_idx()+1);
02990 if (Has_struct_access_entry())
02991 Get_struct_access(0)->Print_array(fp, Get_struct_access_idx()+1);
02992 #ifdef KEY
02993 if (Has_ty_info_entry())
02994 Get_ty_info(0)->Print_array(fp, Get_ty_info_idx()+1);
02995 #endif
02996 }
02997
02998 template <PROGRAM program>
02999 void
03000 SUMMARIZE<program>:: Record_struct_access(WN *wn, mUINT64 loop_count)
03001 {
03002
03003
03004
03005 mUINT32 fld_id,flatten_flds,summary_idx;
03006 UINT struct_index, index=WN_ty(wn)>>8;
03007 TY_IDX point_idx;
03008 TY_TO_FLDNUM_MAP::const_iterator iter;
03009 TY_TO_ACCESS_MAP::const_iterator iter1;
03010 PTR_TO_TY_VECTOR::iterator ptr_iter;
03011 mUINT32 cur_summary_idx = UINT32_MAX;
03012 SUMMARY_STRUCT_ACCESS * cur_summary;
03013 BOOL is_pointer=FALSE;
03014 fld_id=WN_field_id(wn);
03015 if(fld_id<=0) return;
03016 if(WN_operator(wn)==OPR_ISTORE|| WN_operator(wn)==OPR_MSTORE
03017 ||WN_operator(wn)==OPR_MLOAD||WN_operator(wn)==OPR_LDA
03018 ||WN_operator(wn)==OPR_ILDA){
03019 point_idx=TY_pointed(Ty_tab[index]);
03020 struct_index=point_idx>>8;
03021 }
03022 else {
03023 struct_index=index;
03024 }
03025
03026
03027
03028
03029
03030 iter1=Ty_to_access_map->find(struct_index);
03031 if (iter1!=Ty_to_access_map->end ()){
03032 cur_summary_idx=iter1->second;
03033 }
03034 else {
03035 iter=local_cands->find(struct_index);
03036 if (iter==local_cands->end ())
03037 return;
03038 else
03039 flatten_flds=iter->second;
03040
03041
03042
03043
03044 FmtAssert(flatten_flds!=0,
03045 ("in Record_struct_access(), flatten_flds!=0!\n"));
03046 FmtAssert(Ty_tab[struct_index].kind==KIND_STRUCT,
03047 ("the wn's ty_idx operated must be STRUCT"));
03048 iter1=Ty_to_access_map->find(struct_index);
03049 if (iter1!=Ty_to_access_map->end ())
03050 cur_summary_idx=iter1->second;
03051 else{
03052 cur_summary_idx=New_struct_access(struct_index,flatten_flds);
03053 #ifdef KEY
03054 Ty_to_access_map->insert(std::make_pair(struct_index,cur_summary_idx));
03055 #else
03056 Ty_to_access_map->insert(make_pair(struct_index,cur_summary_idx));
03057 #endif // KEY
03058 for(ptr_iter=Ptr_to_ty_vector->begin();
03059 ptr_iter!=Ptr_to_ty_vector->end();
03060 ptr_iter++){
03061 if(ptr_iter->pt_index==struct_index)
03062 #ifdef KEY
03063 Ty_to_access_map->insert(std::make_pair(ptr_iter->ty_index,cur_summary_idx));
03064 #else
03065 Ty_to_access_map->insert(make_pair(ptr_iter->ty_index,cur_summary_idx));
03066 #endif // KEY
03067 }
03068 }
03069 }
03070
03071 Is_True(cur_summary_idx != UINT32_MAX,
03072 ("cur_summary_idx is not initialized."));
03073 cur_summary = Get_struct_access(cur_summary_idx);
03074 Is_True(cur_summary != NULL,
03075 ("cur_summary is NULL"));
03076
03077 #ifdef KEY
03078 Is_True(fld_id <= cur_summary->Get_flatten_flds(),
03079 ("Record_struct_access: illegal field ID"));
03080 #endif
03081
03082
03083 cur_summary->Inc_fld_count(fld_id, loop_count);
03084 return;
03085 }
03086
03087 #ifdef KEY
03088 template <PROGRAM program>
03089 void
03090 SUMMARIZE<program>::Record_ty_info_for_type (TY_IDX ty, TY_FLAGS flags)
03091 {
03092 SUMMARY_TY_INFO * ty_info;
03093 UINT32 ty_index = TY_IDX_index(ty);
03094
03095 Is_True (TY_kind(ty) == KIND_STRUCT,
03096 ("Record_ty_info_for_type expects STRUCT ty"));
03097
03098 INT index = Ty_info_hash_table->Find(ty_index);
03099
03100 if (index == 0)
03101 {
03102 ty_info = New_ty_info();
03103 ty_info->Set_ty(ty);
03104 Ty_info_hash_table->Enter(ty_index, Get_ty_info_idx() + 1);
03105 }
03106 else
03107 ty_info = Get_ty_info(index - 1);
03108
03109 if (flags & TY_NO_SPLIT)
03110 ty_info->Set_ty_no_split();
03111 }
03112 #endif
03113
03114 #endif // ipl_summarize_template_INCLUDED
03115
03116 template <PROGRAM program>
03117 void
03118 SUMMARIZE<program>::Process_alt_procedure(WN *w, INT formal_index, INT
03119 formal_count)
03120 {
03121 Process_procedure (w);
03122 SUMMARY_PROCEDURE *proc = Get_procedure (Get_procedure_idx());
03123 proc->Set_formal_index (formal_index);
03124 proc->Set_formal_count (formal_count);
03125 }
03126
03127