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 #ifndef ipl_analyze_template_INCLUDED
00057 #define ipl_analyze_template_INCLUDED
00058
00059 #ifndef ipl_summarize_util_INCLUDED
00060 #include "ipl_summarize_util.h"
00061 #endif // ipl_summarize_util_INCLUDED
00062
00063 #ifndef opt_base_INCLUDED
00064 #include "opt_base.h"
00065 #endif
00066
00067 #ifndef opt_emit_INCLUDED
00068 #include "opt_emit.h"
00069 #endif // opt_emit_INCLUDED
00070
00071 #ifndef opt_mu_chi_INCLUDED
00072 #include "opt_mu_chi.h"
00073 #endif // opt_mu_chi_INCLUDED
00074
00075 extern "C" {
00076 #ifdef SHARED_BUILD
00077
00078 void _ZN10DU_MANAGER14CD_is_br_takenEj(void) __attribute__ ((weak));
00079 void _ZN10DU_MANAGER15CD_is_fall_thruEj(void) __attribute__((weak));
00080 void _ZNK7CODEREP12Def_at_entryEv(void) __attribute__((weak));
00081 void _ZNK7CODEREP5DefbbEv(void) __attribute__((weak));
00082 void _ZN10DU_MANAGER8DominateEjj(void) __attribute__((weak));
00083 void _ZN10DU_MANAGER6Get_cdEj(void) __attribute__((weak));
00084 void _ZN10DU_MANAGER13Get_last_stmtEj(void) __attribute__((weak));
00085 #endif
00086
00087 void _ZN10DU_MANAGER14CD_is_br_takenEj(void) {}
00088 void _ZN10DU_MANAGER15CD_is_fall_thruEj(void) {}
00089 void _ZNK7CODEREP12Def_at_entryEv(void) {}
00090 void _ZNK7CODEREP5DefbbEv(void) {}
00091 void _ZN10DU_MANAGER8DominateEjj(void) {}
00092 void _ZN10DU_MANAGER6Get_cdEj(void) {}
00093 void _ZN10DU_MANAGER13Get_last_stmtEj(void) {}
00094 }
00095
00096 extern BOOL CXX_Alias_Const;
00097
00098
00099
00100
00101
00102
00103
00104
00105 template <PROGRAM program>
00106 inline void
00107 SUMMARIZE<program>::Restore_from_check_point (const SUMMARY_CHECK_POINT *cp)
00108 {
00109 if (cp->value_idx () == -1)
00110 _value.Resetidx ();
00111 else
00112 _value.Setidx (cp->value_idx ());
00113
00114 if (cp->expr_idx () == -1)
00115 _expr.Resetidx ();
00116 else
00117 _expr.Setidx (cp->expr_idx ());
00118
00119 if (!DoPreopt)
00120 return;
00121
00122 INT i;
00123
00124 PHI_NODE_ARRAY::iterator first_phi =
00125 Hashed_Phis->begin () + cp->hashed_phi_idx();
00126 for (PHI_NODE_ARRAY::iterator last_phi = Hashed_Phis->end () - 1;
00127 last_phi != first_phi; --last_phi)
00128 Phi_To_Idx_Map->erase(*last_phi);
00129 Hashed_Phis->erase (first_phi + 1, Hashed_Phis->end ());
00130
00131 INT phi_idx = cp->phi_idx();
00132 if (phi_idx == -1) {
00133 _phi.Resetidx ();
00134 }
00135 else {
00136 _phi.Setidx (phi_idx);
00137 }
00138
00139 #if Is_True_On
00140 for (first_phi = Hashed_Phis->begin (); first_phi != Hashed_Phis->end ();
00141 ++first_phi) {
00142 PHI_NODE_TO_INT_MAP::const_iterator iter =
00143 Phi_To_Idx_Map->find(*first_phi);
00144 if (iter != Phi_To_Idx_Map->end () && iter->second > phi_idx) {
00145 Fail_FmtAssertion("Incomplete PHI restore: %d > %d is still in the map",
00146 iter->second, phi_idx);
00147 }
00148 }
00149 #endif
00150
00151 CHI_CR_ARRAY::iterator first =
00152 Hashed_Chis->begin () + cp->hashed_chi_idx();
00153 for (CHI_CR_ARRAY::iterator last = Hashed_Chis->end () - 1;
00154 last != first; --last) {
00155 Chi_To_Idx_Map->erase(*last);
00156 }
00157 Hashed_Chis->erase (first + 1, Hashed_Chis->end ());
00158
00159 INT chi_idx = cp->chi_idx();
00160 if (chi_idx == -1) {
00161 _chi.Resetidx ();
00162 }
00163 else {
00164 _chi.Setidx (chi_idx);
00165 }
00166
00167 #if Is_True_On
00168 for (first = Hashed_Chis->begin(); first != Hashed_Chis->end (); ++first) {
00169 CHI_CR_TO_INT_MAP::const_iterator iter = Chi_To_Idx_Map->find (*first);
00170 if (iter != Chi_To_Idx_Map->end () && iter->second > chi_idx)
00171 Fail_FmtAssertion("Incomplete CHI restore: %d > %d is still in the map",
00172 iter->second, chi_idx);
00173 }
00174 #endif
00175
00176 Reset_cd_and_stmt (Summary_Map, cp->cd_idx (), cp->stmt_id ());
00177
00178 }
00179
00180
00181
00182
00183
00184
00185
00186 template <PROGRAM program>
00187 void
00188 SUMMARIZE<program>::Process_constant_jump_function (WN* w, SUMMARY_VALUE *value)
00189 {
00190 const ST* st = WN_st (w);
00191 value->Set_const_st ();
00192 value->Set_const_st_idx (ST_st_idx (st));
00193 TYPE_ID mtype = TY_mtype (ST_type (st));
00194 if (value->Is_addr_of ()) {
00195 value->Set_mtype (Pointer_type);
00196 value->Set_target_mtype (mtype);
00197 } else
00198 value->Set_mtype (mtype);
00199
00200 }
00201
00202
00203 template <PROGRAM program>
00204 void
00205 SUMMARIZE<program>::Process_phi_operand (INT phi_index, WN *orig_wn,
00206 CODEREP *cr, INT kid)
00207 {
00208 WN *wn;
00209
00210 if (cr->Def_at_entry () || cr->Is_flag_set (CF_DEF_BY_PHI) ||
00211 cr->Is_flag_set (CF_DEF_BY_CHI))
00212 wn = orig_wn;
00213 else {
00214 STMTREP *stmt = cr->Defstmt ();
00215 if (stmt == NULL)
00216 return;
00217 else
00218 wn = stmt->Wn ();
00219 }
00220
00221 SUMMARY_DESC desc;
00222 Classify_const_value (desc, wn, cr);
00223
00224 INT idx = Process_jump_function (&desc);
00225
00226 SUMMARY_PHI *phi = Get_phi (phi_index);
00227
00228 phi->Set_node_index (kid, idx);
00229
00230 if (idx == -1)
00231 return;
00232
00233 switch (desc.Get_type ()) {
00234
00235 case VALUE_INT_CONST:
00236 case VALUE_CONST:
00237 case VALUE_FORMAL:
00238 case VALUE_GLOBAL:
00239 phi->Set_value (kid);
00240 break;
00241
00242 case VALUE_EXPR:
00243 phi->Set_expr (kid);
00244 break;
00245
00246 case VALUE_PHI:
00247 phi->Set_phi (kid);
00248 break;
00249
00250 case VALUE_CHI:
00251 phi->Set_chi (kid);
00252 break;
00253
00254 case VALUE_NOT_CONST:
00255 default:
00256 break;
00257 }
00258
00259 }
00260
00261
00262 template <PROGRAM program>
00263 INT
00264 SUMMARIZE<program>::Process_phi_jump_function (WN *orig_wn, PHI_NODE *phi)
00265 {
00266 if (phi->Visited ())
00267 return -1;
00268
00269 phi->Set_visited ();
00270
00271 if (phi->Size () != 2) {
00272 DevWarn ("phi node has more than 2 elements");
00273 return -1;
00274 }
00275
00276 CODEREP *cr0 = phi->OPND (0);
00277 CODEREP *cr1 = phi->OPND (1);
00278 #if 0
00279 CODEREP *res = phi->RESULT ();
00280 printf("sym%dv%d (cr%d) = PHI[sym%dv%d (cr%d), sym%dv%d (cr%d)]\n",
00281 res->Aux_id(), res->Version(), res->Coderep_id(),
00282 cr0->Aux_id(), cr0->Version(), cr0->Coderep_id(),
00283 cr1->Aux_id(), cr1->Version(), cr1->Coderep_id());
00284 fflush(stdout);
00285 #endif
00286 if (cr0->Is_flag_set(CF_IS_ZERO_VERSION) ||
00287 cr1->Is_flag_set(CF_IS_ZERO_VERSION))
00288 return -1;
00289
00290
00291 {
00292 PHI_NODE_TO_INT_MAP::const_iterator result =
00293 Phi_To_Idx_Map->find (phi);
00294 if (result != Phi_To_Idx_Map->end () &&
00295 result->second <= Get_phi_idx ()) {
00296 if (result->second != -1)
00297 phi->Reset_visited ();
00298 return result->second;
00299 }
00300 }
00301
00302 struct DU_MANAGER *du = Get_du_mgr ();
00303
00304 IDTYPE cd0_bb_idx = cr0->Def_at_entry () ?
00305 du->Get_entry_bb () : du->Get_cd (cr0->Defbb()->Id());
00306 IDTYPE cd1_bb_idx = cr1->Def_at_entry () ?
00307 du->Get_entry_bb () : du->Get_cd (cr1->Defbb()->Id());
00308 IDTYPE merged_cd = -1;
00309
00310 if (cd0_bb_idx == 0 || cd1_bb_idx == 0)
00311 return -1;
00312
00313 if (cd0_bb_idx == cd1_bb_idx) {
00314 if (du->CD_is_fall_thru (cr0->Defbb()->Id()) ==
00315 du->CD_is_fall_thru (cr1->Defbb()->Id()))
00316 return -1;
00317 merged_cd = cd0_bb_idx;
00318 } else {
00319 if (du->Dominate (cd0_bb_idx, cd1_bb_idx)) {
00320 if (!du->Dominate (cd1_bb_idx, phi->Bb()->Id()))
00321 return -1;
00322 merged_cd = cd1_bb_idx;
00323 } else if (du->Dominate (cd1_bb_idx, cd0_bb_idx)) {
00324 if (!du->Dominate (cd0_bb_idx, phi->Bb()->Id()))
00325 return -1;
00326 merged_cd = cd0_bb_idx;
00327 }
00328 }
00329
00330 if (merged_cd != -1) {
00331 const SUMMARY_CHECK_POINT chk_pt (this);
00332 INT ctrl_dep_idx = Process_cd_for_phi_node (merged_cd);
00333
00334 if (ctrl_dep_idx == -1) {
00335 Restore_from_check_point (&chk_pt);
00336 Phi_To_Idx_Map->insert (std::make_pair (phi, -1));
00337 return -1;
00338 }
00339
00340 SUMMARY_PHI *phi_node = New_phi ();
00341
00342 phi_node->Set_ctrl_dep_index (0, ctrl_dep_idx);
00343 phi_node->Set_ctrl_dep_index (1, ctrl_dep_idx);
00344
00345 switch (WN_opcode (du->Get_last_stmt (merged_cd))) {
00346 case OPC_FALSEBR:
00347 case OPC_IF:
00348 if (merged_cd == cd0_bb_idx) {
00349 phi_node->Set_branch (0,
00350 du->CD_is_fall_thru(cr0->Defbb()->Id()));
00351 phi_node->Set_branch (1, !phi_node->Get_branch (0));
00352 } else {
00353 phi_node->Set_branch (1,
00354 du->CD_is_fall_thru(cr1->Defbb()->Id()));
00355 phi_node->Set_branch (0, !phi_node->Get_branch (1));
00356 }
00357 break;
00358
00359 case OPC_TRUEBR:
00360 if (merged_cd == cd0_bb_idx) {
00361 phi_node->Set_branch (0,
00362 du->CD_is_br_taken(cr0->Defbb()->Id()));
00363 phi_node->Set_branch (1, !phi_node->Get_branch (0));
00364 } else {
00365 phi_node->Set_branch (1,
00366 du->CD_is_br_taken(cr1->Defbb()->Id()));
00367 phi_node->Set_branch (0, !phi_node->Get_branch (1));
00368 }
00369 break;
00370 }
00371
00372 INT phi_idx = Get_phi_idx ();
00373
00374 Process_phi_operand (phi_idx, orig_wn, cr0, 0);
00375 Process_phi_operand (phi_idx, orig_wn, cr1, 1);
00376
00377 phi_node = Get_phi (phi_idx);
00378 if (phi_node->Get_node_index (0) == -1 &&
00379 phi_node->Get_node_index (1) == -1) {
00380 Restore_from_check_point (&chk_pt);
00381 Phi_To_Idx_Map->insert (std::make_pair (phi, -1));
00382 return -1;
00383 } else {
00384 phi->Reset_visited ();
00385 Phi_To_Idx_Map->insert (std::make_pair (phi, phi_idx));
00386 Hashed_Phis->push_back (phi);
00387 return phi_idx;
00388 }
00389 }
00390
00391 DevWarn ("phi node has 2 different control dep.\n");
00392
00393 return -1;
00394 }
00395
00396
00397 template <PROGRAM program>
00398 INT
00399 SUMMARIZE<program>::Process_chi_jump_function (WN *wn,
00400 const SUMMARY_DESC &desc)
00401 {
00402 #if 0
00403 FmtAssert (! desc.Is_addr_of (),
00404 ("LDA of a symbol cannot have chi node"));
00405 #endif
00406
00407 CODEREP *cr = desc.Get_chi_cr ()->Defchi ()->OPND ();
00408
00409 if (cr->Is_flag_set(CF_IS_ZERO_VERSION))
00410 return -1;
00411
00412 STMTREP *stmt = desc.Get_chi_cr ()->Defstmt ();
00413 if (stmt == NULL)
00414 return -1;
00415
00416 #ifdef KEY
00417
00418
00419
00420
00421 if (WN_st (wn) && ST_sym_class (*WN_st (wn)) == CLASS_CONST)
00422 return -1;
00423 #endif // KEY
00424
00425 #if 0
00426 printf("sym%dv%d (cr%d) = CHI[sym%dv%d (cr%d)]\n",
00427 desc.Get_chi_cr()->Aux_id(),
00428 desc.Get_chi_cr()->Version(),
00429 desc.Get_chi_cr()->Coderep_id(),
00430 cr->Aux_id(),
00431 cr->Version(),
00432 cr->Coderep_id());
00433 fflush(stdout);
00434 #endif
00435
00436
00437 {
00438 CHI_CR_TO_INT_MAP::const_iterator result =
00439 Chi_To_Idx_Map->find (desc.Get_chi_cr ());
00440 if (result != Chi_To_Idx_Map->end () &&
00441 result->second <= Get_chi_idx ())
00442 return result->second;
00443 }
00444
00445 const SUMMARY_CHECK_POINT chk_pt (this);
00446 SUMMARY_CHI *chi_node = New_chi ();
00447
00448 chi_node->Set_symbol_index (Get_symbol_index (WN_st (wn)));
00449
00450 WN *call = stmt->Wn ();
00451 chi_node->Set_call_index (WN_MAP32_Get (Summary_Map, call) - 1);
00452 if (chi_node->Get_call_index () < 0) {
00453 Restore_from_check_point (&chk_pt);
00454 Chi_To_Idx_Map->insert (std::make_pair (desc.Get_chi_cr(), -1));
00455 return -1;
00456 }
00457
00458 INT chi_idx = Get_chi_idx ();
00459
00460 SUMMARY_DESC chi_desc;
00461 Classify_const_value (chi_desc, wn, cr);
00462 INT idx = Process_jump_function (&chi_desc);
00463
00464 if (idx == -1) {
00465 Restore_from_check_point (&chk_pt);
00466 Chi_To_Idx_Map->insert (std::make_pair (desc.Get_chi_cr(), -1));
00467 return -1;
00468 }
00469
00470 chi_node = Get_chi (chi_idx);
00471
00472 chi_node->Set_node_index (idx);
00473
00474 switch (chi_desc.Get_type ()) {
00475 case VALUE_INT_CONST:
00476 case VALUE_CONST:
00477 case VALUE_FORMAL:
00478 case VALUE_GLOBAL:
00479 chi_node->Set_chi_value ();
00480 break;
00481
00482 case VALUE_EXPR:
00483 chi_node->Set_chi_expr ();
00484 break;
00485
00486 case VALUE_PHI:
00487 chi_node->Set_chi_phi ();
00488 break;
00489
00490 case VALUE_CHI:
00491 Is_True (idx != chi_idx,
00492 ("CHI: sym%dv%d (cr%d), OPND: sym%dv%d (cr%d)",
00493 desc.Get_chi_cr()->Aux_id(),
00494 desc.Get_chi_cr()->Version(),
00495 desc.Get_chi_cr()->Coderep_id(),
00496 cr->Aux_id(),
00497 cr->Version(),
00498 cr->Coderep_id()));
00499
00500 chi_node->Set_chi_chi ();
00501 break;
00502
00503 case VALUE_NOT_CONST:
00504 default:
00505 Restore_from_check_point (&chk_pt);
00506 Chi_To_Idx_Map->insert (std::make_pair (desc.Get_chi_cr(), -1));
00507 return -1;
00508 }
00509
00510
00511
00512
00513
00514 Chi_To_Idx_Map->insert (std::make_pair (desc.Get_chi_cr(), chi_idx));
00515 Hashed_Chis->push_back (desc.Get_chi_cr());
00516
00517 return chi_idx;
00518
00519 }
00520
00521
00522 template <PROGRAM program>
00523 void
00524 SUMMARIZE<program>::Process_operand (WN *w, INT kid, INT expr_idx)
00525 {
00526 SUMMARY_DESC desc;
00527
00528 Classify_const_value (desc, w);
00529
00530 INT idx = Process_jump_function (&desc);
00531
00532 SUMMARY_EXPR *expr = Get_expr (expr_idx);
00533
00534 if (idx == -1) {
00535 expr->Set_expr_unknown ();
00536 return;
00537 }
00538
00539 expr->Set_node_index (kid, idx);
00540
00541 switch (desc.Get_type ()) {
00542
00543 case VALUE_INT_CONST:
00544 case VALUE_CONST:
00545 case VALUE_FORMAL:
00546 case VALUE_GLOBAL:
00547 expr->Set_expr_value (kid);
00548 break;
00549
00550 case VALUE_EXPR:
00551 expr->Set_expr_expr (kid);
00552 break;
00553
00554 case VALUE_PHI:
00555 expr->Set_expr_phi (kid);
00556 break;
00557
00558 case VALUE_CHI:
00559 expr->Set_expr_chi (kid);
00560 break;
00561
00562 case VALUE_NOT_CONST:
00563 default:
00564 expr->Set_expr_unknown ();
00565 break;
00566 }
00567 }
00568
00569
00570 template <PROGRAM program>
00571 INT
00572 SUMMARIZE<program>::Process_polynomial_jump_function (WN *w)
00573 {
00574 OPCODE op = WN_opcode (w);
00575
00576 if (!MTYPE_is_integral (OPCODE_rtype (op)))
00577 return -1;
00578
00579 if (!OPCODE_is_expression(op))
00580 return -1;
00581
00582 if (OPCODE_is_load(op))
00583 return -1;
00584
00585 const SUMMARY_CHECK_POINT chk_pt (this);
00586 SUMMARY_EXPR *expr = New_expr ();
00587 expr->Set_expr_unknown ();
00588 INT expr_idx = Get_expr_idx ();
00589
00590 if (OPCODE_nkids(op) == 2) {
00591
00592
00593 expr->Set_mtype (OPCODE_rtype (op));
00594 expr->Set_opcode (op);
00595
00596 if (WN_operator(WN_kid1(w)) == OPR_INTCONST) {
00597 expr->Set_has_const_operand ();
00598 expr->Set_kid (0);
00599 expr->Set_const_value (WN_const_val(WN_kid1(w)));
00600 Process_operand (WN_kid0(w), 0, expr_idx);
00601 } else if (WN_operator (WN_kid0(w)) == OPR_INTCONST) {
00602 expr->Set_has_const_operand ();
00603 expr->Set_kid (1);
00604 expr->Set_const_value (WN_const_val(WN_kid0(w)));
00605 Process_operand (WN_kid1(w), 1, expr_idx);
00606 } else {
00607
00608 expr->Clear_has_const_operand ();
00609 Process_operand (WN_kid0(w), 0, expr_idx);
00610 if (! Get_expr (expr_idx)->Is_expr_unknown ())
00611 Process_operand (WN_kid1(w), 1, expr_idx);
00612 }
00613 } else if (OPCODE_nkids(op) == 1) {
00614
00615
00616
00617
00618
00619
00620
00621
00622 expr->Set_mtype (OPCODE_rtype (op));
00623 expr->Set_opcode (op);
00624 expr->Set_has_const_operand ();
00625 if (OPCODE_operator (op) == OPR_CVTL)
00626 expr->Set_const_value (WN_cvtl_bits (w));
00627 expr->Set_kid (0);
00628 Process_operand (WN_kid0(w), 0, expr_idx);
00629 }
00630
00631 expr = Get_expr (expr_idx);
00632 if (expr->Is_expr_unknown ()) {
00633 Restore_from_check_point (&chk_pt);
00634 expr_idx = -1;
00635 } else {
00636 INT idx = entry_cache->Lookup (SUM_EXPR, expr);
00637 if (idx != -1 && idx < expr_idx) {
00638 Restore_from_check_point (&chk_pt);
00639 return idx;
00640 } else
00641 entry_cache->Insert (SUM_EXPR, expr_idx);
00642 }
00643
00644 return expr_idx;
00645 }
00646
00647
00648 struct LOAD_STORE_ENTRY
00649 {
00650 CODEREP* cr;
00651 ST* st;
00652 INT offset;
00653 TYPE_ID type;
00654 BOOL is_ptr;
00655 BOOL ret_val;
00656
00657 LOAD_STORE_ENTRY(CODEREP* c, ST* s, INT o, TYPE_ID t, BOOL p) :
00658 cr(c), st(s), offset(o), type(t), is_ptr(p) {}
00659
00660 bool operator== (const LOAD_STORE_ENTRY& rhs) {
00661 return (cr == rhs.cr &&
00662 st == rhs.st &&
00663 offset == rhs.offset &&
00664 type == rhs.type &&
00665 is_ptr == rhs.is_ptr);
00666 }
00667 };
00668
00669 template <PROGRAM program>
00670 BOOL
00671 SUMMARIZE<program>::Mismatched_load_store (CODEREP *cr, BOOL is_ptr_var,
00672 ST *st, INT load_offset,
00673 TYPE_ID load_type)
00674 {
00675 if (cr == NULL || cr->Is_flag_set (CF_IS_ZERO_VERSION))
00676 return TRUE;
00677
00678
00679 static vector<LOAD_STORE_ENTRY> depot;
00680 static INT proc_idx = -1;
00681 if (proc_idx != Get_procedure_idx()) {
00682 depot.clear();
00683 proc_idx = Get_procedure_idx();
00684 }
00685
00686
00687 INT idx;
00688 LOAD_STORE_ENTRY ldst(cr, st, load_offset, load_type, is_ptr_var);
00689 for (idx = 0; idx < depot.size(); idx++) {
00690 if (depot[idx] == ldst) {
00691 return depot[idx].ret_val;
00692 }
00693 }
00694 depot.push_back(ldst);
00695
00696 if (cr->Is_flag_set (CF_DEF_BY_CHI)) {
00697 if (cr->Def_at_entry ()) {
00698 depot[idx].ret_val = is_ptr_var;
00699 return is_ptr_var;
00700 }
00701
00702 STMTREP *stmt = cr->Defstmt ();
00703 if (stmt == NULL || WN_operator (stmt->Wn ()) != OPR_CALL) {
00704 depot[idx].ret_val = TRUE;
00705 return TRUE;
00706 }
00707 #ifndef KEY
00708 depot[idx].ret_val =
00709 Mismatched_load_store (cr->Defchi()->OPND(), is_ptr_var,
00710 st, load_offset, load_type);
00711 #else
00712
00713
00714
00715 BOOL r =
00716 Mismatched_load_store (cr->Defchi()->OPND(), is_ptr_var,
00717 st, load_offset, load_type);
00718 depot[idx].ret_val = r;
00719 #endif // !KEY
00720 return depot[idx].ret_val;
00721 }
00722
00723 if (cr->Is_flag_set (CF_DEF_BY_PHI)) {
00724 PHI_NODE *phi = cr->Defphi ();
00725
00726 if (!phi->Live() || phi->Visited ()) {
00727 depot[idx].ret_val = TRUE;
00728 return TRUE;
00729 }
00730 phi->Set_visited ();
00731
00732 for (INT i = 0; i < phi->Size (); i++) {
00733 cr = phi->OPND (i);
00734 if (Mismatched_load_store (cr, is_ptr_var, st, load_offset,
00735 load_type)) {
00736 phi->Reset_visited ();
00737 depot[idx].ret_val = TRUE;
00738 return TRUE;
00739 }
00740 }
00741
00742 phi->Reset_visited ();
00743 depot[idx].ret_val = FALSE;
00744 return FALSE;
00745
00746 } else {
00747 STMTREP *stmt = cr->Defstmt ();
00748
00749 if (stmt == NULL) {
00750 depot[idx].ret_val = FALSE;
00751 return FALSE;
00752 }
00753 WN *def = stmt->Wn ();
00754
00755 if (!is_ptr_var) {
00756 depot[idx].ret_val = !(WN_operator (def) == OPR_STID &&
00757 WN_st (def) == st);
00758 return depot[idx].ret_val;
00759 }
00760 else if (WN_operator (def) == OPR_ISTORE) {
00761 WN *kid1 = WN_kid1(def);
00762 if (!OPCODE_has_sym (WN_opcode (kid1))) {
00763 depot[idx].ret_val = TRUE;
00764 return TRUE;
00765 }
00766 if (WN_st(kid1) != st || load_offset != WN_store_offset(def) ||
00767 load_type != WN_desc(def)) {
00768 depot[idx].ret_val = TRUE;
00769 return TRUE;
00770 }
00771 depot[idx].ret_val = FALSE;
00772 return FALSE;
00773 } else {
00774 depot[idx].ret_val = TRUE;
00775 return TRUE;
00776 }
00777 }
00778 }
00779
00780
00781 template <PROGRAM program>
00782 void
00783 SUMMARIZE<program>::Classify_indirect (SUMMARY_DESC &result, WN *w)
00784 {
00785 Is_True (WN_operator (w) == OPR_ILOAD || WN_operator (w) == OPR_PARM,
00786 ("Invalid opcode"));
00787
00788 WN *parm = w;
00789 w = WN_kid0(parm);
00790 result.Set_wn (w);
00791
00792 BOOL is_ptr_variable = WN_operator (w) != OPR_LDA;
00793
00794 if (!OPCODE_has_sym (WN_opcode (w)))
00795 return;
00796
00797 ST* st = WN_st (w);
00798
00799 BOOL is_iload;
00800 INT load_offset;
00801
00802 if (WN_operator (parm) == OPR_ILOAD) {
00803 is_iload = TRUE;
00804 load_offset = WN_load_offset(parm);
00805 if (is_ptr_variable)
00806 return;
00807 else
00808 result.Set_target_mtype (TY_mtype (ST_type (st)));
00809 } else {
00810 is_iload = FALSE;
00811 load_offset = 0;
00812 if (!is_ptr_variable) {
00813 result.Set_is_addr_of ();
00814 result.Set_target_mtype (TY_mtype (ST_type (st)));
00815 if (ST_level (st) == GLOBAL_SYMTAB) {
00816 switch (ST_sclass (st)) {
00817 case SCLASS_FSTATIC:
00818 case SCLASS_COMMON:
00819 case SCLASS_EXTERN:
00820 case SCLASS_UGLOBAL:
00821 case SCLASS_DGLOBAL:
00822 case SCLASS_TEXT:
00823 result.Set_convertible_to_global ();
00824 }
00825 }
00826 }
00827 }
00828
00829
00830
00831 switch (TY_kind(ST_type(st))) {
00832 case KIND_SCALAR:
00833 #ifdef KEY // bug 6229
00834 case KIND_ARRAY:
00835 #endif
00836 if (ST_class(st) == CLASS_CONST) {
00837
00838 result.Set_type (VALUE_CONST);
00839 return;
00840 }
00841
00842 #ifdef KEY // bug 7718
00843 if (TY_kind(ST_type(st)) == KIND_ARRAY) return;
00844 #endif
00845 break;
00846 case KIND_POINTER:
00847 if (is_ptr_variable)
00848 break;
00849
00850 default:
00851 return;
00852 }
00853
00854
00855 if (!DoPreopt)
00856 return;
00857
00858 CODEREP *cr = (CODEREP *)
00859 WN_MAP_Get (*(Get_emitter ()->Wn_to_cr_map ()), parm);
00860
00861 if (cr == NULL)
00862
00863 return;
00864
00865 cr = cr->Ivar_mu_node ()->OPND ();
00866
00867 if (cr->Kind() != CK_VAR)
00868 return;
00869
00870 if (cr->Is_flag_set (CF_DEF_BY_CHI)) {
00871 if (cr->Def_at_entry ()) {
00872 if (is_ptr_variable)
00873 return;
00874
00875 switch (ST_sclass (st)) {
00876 case SCLASS_FORMAL:
00877 case SCLASS_FORMAL_REF:
00878 if (ST_level (st) == CURRENT_SYMTAB)
00879 result.Set_type (VALUE_FORMAL);
00880 break;
00881 case SCLASS_FSTATIC:
00882 case SCLASS_DGLOBAL:
00883 case SCLASS_UGLOBAL:
00884 case SCLASS_COMMON:
00885 case SCLASS_EXTERN:
00886 result.Set_type (VALUE_GLOBAL);
00887 break;
00888 default:
00889
00890 break;
00891 }
00892 return;
00893 }
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903 STMTREP *stmt = cr->Defstmt ();
00904 if (stmt == NULL ||
00905 WN_operator (stmt->Wn ()) != OPR_CALL)
00906 return;
00907
00908
00909 result.Set_type (VALUE_CHI);
00910 result.Set_chi_cr (cr);
00911 return;
00912 }
00913
00914 if (Mismatched_load_store (cr, is_ptr_variable, st, load_offset,
00915 is_iload ? WN_desc(parm) :
00916 ST_btype(st)))
00917 return;
00918
00919 if (cr->Is_flag_set (CF_DEF_BY_PHI)) {
00920 Classify_const_value (result, w, cr);
00921 return;
00922 }
00923
00924 STMTREP *stmt = cr->Defstmt ();
00925 if (stmt == NULL)
00926 return;
00927
00928 WN *def = stmt->Wn ();
00929 cr = stmt->Rhs ();
00930
00931 if (!is_ptr_variable)
00932 result.Reset_convertible_to_global ();
00933
00934 Classify_const_value (result, WN_kid0(def), cr);
00935
00936 }
00937
00938
00939 template <PROGRAM program>
00940 void
00941 SUMMARIZE<program>::Classify_const_value (SUMMARY_DESC &result, WN *w,
00942 CODEREP *cr)
00943 {
00944 result.Set_wn (w);
00945
00946 if (cr == NULL || cr->Is_flag_set (CF_IS_ZERO_VERSION))
00947 return;
00948
00949 switch (cr->Kind ()) {
00950 case CK_LDA:
00951 if (cr->Offset () == 0) {
00952 ST *st = cr->Lda_base_st ();
00953 result.Set_is_addr_of ();
00954 result.Set_target_mtype (TY_mtype (ST_type (st)));
00955 switch (ST_sclass (st)) {
00956 case SCLASS_TEXT:
00957 if (ST_level (st) != GLOBAL_SYMTAB) {
00958 result.Set_type (VALUE_SYMBOL);
00959 break;
00960 }
00961
00962 case SCLASS_FSTATIC:
00963 case SCLASS_DGLOBAL:
00964 case SCLASS_UGLOBAL:
00965 case SCLASS_COMMON:
00966 case SCLASS_EXTERN:
00967 result.Set_convertible_to_global ();
00968 result.Set_type (VALUE_GLOBAL);
00969 break;
00970 case SCLASS_FORMAL:
00971 case SCLASS_FORMAL_REF:
00972 if (ST_level (st) == CURRENT_SYMTAB)
00973 result.Set_type (VALUE_FORMAL);
00974 break;
00975
00976 case SCLASS_AUTO:
00977 if (ST_level (st) == CURRENT_SYMTAB)
00978 result.Set_type (VALUE_SYMBOL);
00979 break;
00980 }
00981 }
00982 return;
00983
00984 case CK_CONST:
00985 result.Set_type (VALUE_INT_CONST);
00986 return;
00987
00988 case CK_RCONST:
00989 result.Set_type (VALUE_CONST);
00990 return;
00991
00992 case CK_VAR:
00993 break;
00994
00995 case CK_IVAR:
00996 return;
00997
00998 case CK_OP:
00999 result.Set_type (VALUE_EXPR);
01000 return;
01001
01002 default:
01003 return;
01004 }
01005
01006 if (cr->Is_flag_set (CF_DEF_BY_PHI)) {
01007 PHI_NODE *phi = cr->Defphi ();
01008
01009 if (!phi->Live() || phi->Visited ())
01010 return;
01011
01012 phi->Set_visited ();
01013
01014 cr = phi->OPND (0);
01015 BOOL same_phi = TRUE;
01016
01017
01018 for (INT i = 1; i < phi->Size(); i++) {
01019 if (cr != phi->OPND(i)) {
01020 same_phi = FALSE;
01021 break;
01022 }
01023 }
01024
01025 if (!same_phi) {
01026 result.Set_type (VALUE_PHI);
01027 result.Set_phi (phi);
01028 phi->Reset_visited ();
01029 return;
01030 }
01031
01032
01033
01034 Classify_const_value (result, w, cr);
01035 phi->Reset_visited ();
01036 return;
01037 }
01038
01039 if (cr->Is_flag_set (CF_DEF_BY_CHI)) {
01040 if (cr->Def_at_entry ()) {
01041 const ST* st = WN_st (w);
01042 switch (ST_sclass (st)) {
01043 case SCLASS_FSTATIC:
01044 case SCLASS_DGLOBAL:
01045 case SCLASS_UGLOBAL:
01046 case SCLASS_COMMON:
01047 case SCLASS_EXTERN:
01048 result.Set_type (VALUE_GLOBAL);
01049 break;
01050 case SCLASS_FORMAL:
01051 case SCLASS_FORMAL_REF:
01052 if (ST_level (st) == CURRENT_SYMTAB)
01053 result.Set_type (VALUE_FORMAL);
01054 break;
01055 default:
01056 break;
01057 }
01058 return;
01059 }
01060
01061
01062 STMTREP *stmt = cr->Defstmt ();
01063 if (stmt == NULL ||
01064 WN_operator (stmt->Wn ()) != OPR_CALL)
01065 return;
01066
01067
01068 result.Set_type (VALUE_CHI);
01069 result.Set_chi_cr (cr);
01070 return;
01071 }
01072
01073
01074
01075 STMTREP *stmt = cr->Defstmt ();
01076
01077 if (stmt == NULL)
01078 return;
01079
01080 w = stmt->Wn ();
01081 cr = stmt->Rhs ();
01082 if (WN_operator (w) == OPR_STID)
01083 Classify_const_value (result, WN_kid0(w), cr);
01084 }
01085
01086
01087 template <PROGRAM program>
01088 void
01089 SUMMARIZE<program>::Classify_const_value (SUMMARY_DESC &result, WN *w)
01090 {
01091 result.Set_wn (w);
01092 const ST* st;
01093
01094 switch (WN_operator (w)) {
01095 case OPR_ILOAD:
01096 case OPR_PARM:
01097 Classify_indirect (result, w);
01098 return;
01099
01100 case OPR_INTCONST:
01101 result.Set_type (VALUE_INT_CONST);
01102 return;
01103
01104 case OPR_LDA:
01105 if (WN_lda_offset (w) != 0)
01106 return;
01107
01108 st = WN_st (w);
01109 result.Set_is_addr_of ();
01110 result.Set_target_mtype (TY_mtype (ST_type (st)));
01111 switch (ST_sclass (st)) {
01112 case SCLASS_TEXT:
01113 if (ST_level (st) != GLOBAL_SYMTAB) {
01114 result.Set_type (VALUE_SYMBOL);
01115 break;
01116 }
01117
01118 case SCLASS_FSTATIC:
01119 case SCLASS_DGLOBAL:
01120 case SCLASS_UGLOBAL:
01121 case SCLASS_COMMON:
01122 case SCLASS_EXTERN:
01123
01124 result.Set_type (VALUE_GLOBAL);
01125 result.Set_convertible_to_global ();
01126 break;
01127 case SCLASS_FORMAL:
01128 case SCLASS_FORMAL_REF:
01129 if (ST_level (st) == CURRENT_SYMTAB)
01130 result.Set_type (VALUE_FORMAL);
01131 break;
01132
01133 case SCLASS_AUTO:
01134 if (ST_level (st) == CURRENT_SYMTAB)
01135 result.Set_type (VALUE_SYMBOL);
01136 break;
01137 }
01138 return;
01139
01140 default:
01141 if (!OPCODE_has_sym (WN_opcode (w))) {
01142
01143 result.Set_type (VALUE_EXPR);
01144 return;
01145 }
01146 break;
01147 }
01148
01149 st = WN_st (w);
01150 switch (TY_kind(ST_type(st))) {
01151 case KIND_SCALAR:
01152 #ifdef KEY // bug 6229
01153 case KIND_ARRAY:
01154 #endif
01155 case KIND_POINTER:
01156 break;
01157 default:
01158 return;
01159 }
01160
01161 if (ST_class(st) == CLASS_CONST) {
01162
01163 result.Set_type (VALUE_CONST);
01164 return;
01165 }
01166
01167 #ifdef KEY // bug 7718
01168 if (TY_kind(ST_type(st)) == KIND_ARRAY) return;
01169 #endif
01170
01171
01172
01173 switch (ST_sclass(st)) {
01174 case SCLASS_FSTATIC:
01175 case SCLASS_DGLOBAL:
01176 case SCLASS_UGLOBAL:
01177 case SCLASS_COMMON:
01178 case SCLASS_EXTERN:
01179 case SCLASS_FORMAL:
01180 case SCLASS_FORMAL_REF:
01181 case SCLASS_AUTO:
01182 if (!DoPreopt)
01183
01184 break;
01185
01186 CODEREP *cr = (CODEREP *)
01187 WN_MAP_Get (*(Get_emitter()->Wn_to_cr_map ()), w);
01188
01189 Classify_const_value (result, w, cr);
01190 break;
01191 }
01192
01193 return;
01194 }
01195
01196
01197 template <PROGRAM program>
01198 INT
01199 SUMMARIZE<program>::Process_jump_function (SUMMARY_DESC *desc)
01200 {
01201 SUMMARY_VALUE *value = NULL;
01202 SUMMARY_SYMBOL *sym;
01203 INT idx;
01204
01205 WN *w = desc->Get_wn ();
01206
01207 switch (desc->Get_type ()) {
01208
01209 case VALUE_INT_CONST:
01210 if (WN_rtype (w) == MTYPE_I4 &&
01211 (WN_const_val(w) == 0 || WN_const_val(w) == 1))
01212 return WN_const_val(w);
01213
01214 value = New_value ();
01215 value->Set_mtype (WN_rtype (w));
01216 value->Set_int_const ();
01217 value->Set_int_const_value (WN_const_val (w));
01218
01219 break;
01220
01221 case VALUE_EXPR:
01222 return Process_polynomial_jump_function (w);
01223
01224 case VALUE_CONST:
01225 value = New_value ();
01226 Process_constant_jump_function (w, value);
01227 break;
01228
01229 case VALUE_PHI:
01230 return Process_phi_jump_function (w, desc->Get_phi ());
01231
01232 case VALUE_CHI:
01233 idx = Process_chi_jump_function (w, *desc);
01234 if (idx >= 0)
01235 return idx;
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252 switch (ST_sclass (WN_st (w))) {
01253 case SCLASS_FSTATIC:
01254 case SCLASS_DGLOBAL:
01255 case SCLASS_UGLOBAL:
01256 case SCLASS_COMMON:
01257 case SCLASS_EXTERN:
01258 break;
01259
01260 default:
01261 return idx;
01262 }
01263
01264 desc->Set_type (VALUE_GLOBAL);
01265
01266
01267 case VALUE_GLOBAL:
01268 value = New_value ();
01269 if (desc->Is_addr_of ()) {
01270 value->Set_is_addr_of ();
01271 value->Set_target_mtype (desc->Target_mtype ());
01272 if (desc->Is_convertible_to_global ())
01273 value->Set_convertible_to_global ();
01274 }
01275 value->Set_mtype (WN_rtype (w));
01276 value->Set_global ();
01277 {
01278 const ST* st = WN_st (w);
01279 INT32 idx = Get_symbol_index (st);
01280 value->Set_global_index (idx);
01281 if (idx == -1)
01282 {
01283 value->Set_global_st_idx (ST_st_idx (st));
01284 #ifdef KEY
01285 value->Set_is_global_st_idx ();
01286 #endif
01287 }
01288 }
01289 break;
01290
01291 case VALUE_FORMAL:
01292 value = New_value ();
01293 if (desc->Is_addr_of ()) {
01294 value->Set_is_addr_of ();
01295 value->Set_target_mtype (desc->Target_mtype ());
01296 }
01297 value->Set_mtype (WN_rtype (w));
01298 value->Set_formal ();
01299 sym = Get_symbol (Get_symbol_index (WN_st(w)));
01300 value->Set_formal_index (sym->Get_findex ());
01301 break;
01302
01303 case VALUE_SYMBOL:
01304 value = New_value ();
01305 if (desc->Is_addr_of ()) {
01306 value->Set_is_addr_of ();
01307 value->Set_target_mtype (desc->Target_mtype ());
01308 }
01309 value->Set_mtype (WN_rtype (w));
01310 value->Set_symbol ();
01311 value->Set_symbol_index (Get_symbol_index (WN_st(w)));
01312 break;
01313
01314 default:
01315 return -1;
01316 }
01317
01318
01319 Is_True (value != NULL, ("Uninitialized SUMMARY_VALUE pointer\n"));
01320
01321
01322 idx = entry_cache->Lookup (SUM_VALUE, value);
01323 if (idx != -1 && idx < Get_value_idx ())
01324 _value.Decidx ();
01325 else {
01326 idx = Get_value_idx ();
01327 entry_cache->Insert (SUM_VALUE, idx);
01328 }
01329 return idx;
01330
01331 }
01332
01333
01334 template <PROGRAM program>
01335 void
01336 SUMMARIZE<program>::Process_jump_function (WN *w, INT value_idx)
01337 {
01338 INT idx;
01339 SUMMARY_SYMBOL *sym;
01340 SUMMARY_DESC summary_desc;
01341
01342 Classify_const_value (summary_desc, w);
01343
01344 SUMMARY_VALUE *value = Get_value (value_idx);
01345 value->Set_mtype (WN_rtype (w));
01346
01347 if (summary_desc.Is_addr_of ()) {
01348 value->Set_is_addr_of ();
01349 value->Set_target_mtype (summary_desc.Target_mtype ());
01350 if (summary_desc.Is_convertible_to_global ())
01351 value->Set_convertible_to_global ();
01352 }
01353
01354 w = summary_desc.Get_wn ();
01355 switch (summary_desc.Get_type ()) {
01356 case VALUE_INT_CONST:
01357 value->Set_int_const();
01358 value->Set_int_const_value (WN_const_val(w));
01359 break;
01360
01361 case VALUE_EXPR:
01362 value->Set_expr ();
01363
01364 idx = Process_polynomial_jump_function (w);
01365
01366 if (idx == -1)
01367 Get_value (value_idx)->Set_not_const ();
01368 else
01369 Get_value (value_idx)->Set_expr_index (idx);
01370
01371 break;
01372
01373 case VALUE_CONST:
01374 Process_constant_jump_function (w, value);
01375 break;
01376
01377 case VALUE_PHI:
01378 value->Set_phi ();
01379 idx = Process_phi_jump_function (w, summary_desc.Get_phi ());
01380 if (idx == -1)
01381 Get_value (value_idx)->Set_not_const ();
01382 else
01383 Get_value (value_idx)->Set_phi_index (idx);
01384 break;
01385
01386 case VALUE_CHI:
01387 value->Set_chi ();
01388 idx = Process_chi_jump_function (w, summary_desc);
01389 if (idx != -1) {
01390 Get_value (value_idx)->Set_chi_index (idx);
01391 break;
01392 }
01393
01394
01395
01396
01397
01398
01399
01400 switch (ST_sclass (WN_st (w))) {
01401 case SCLASS_FSTATIC:
01402 case SCLASS_DGLOBAL:
01403 case SCLASS_UGLOBAL:
01404 case SCLASS_COMMON:
01405 case SCLASS_EXTERN:
01406 break;
01407
01408 default:
01409 Get_value (value_idx)->Set_not_const ();
01410 return;
01411 }
01412
01413
01414
01415 case VALUE_GLOBAL:
01416 value->Set_global ();
01417 {
01418 const ST* st = WN_st (w);
01419 INT idx = Get_symbol_index (st);
01420 value->Set_global_index (idx);
01421 if (idx == -1)
01422 {
01423 value->Set_global_st_idx (ST_st_idx (st));
01424 #ifdef KEY
01425 value->Set_is_global_st_idx ();
01426 #endif
01427 }
01428 }
01429 break;
01430
01431 case VALUE_FORMAL:
01432 sym = Get_symbol (Get_symbol_index (WN_st(w)));
01433 value->Set_formal ();
01434 value->Set_formal_index (sym->Get_findex ());
01435 break;
01436
01437 case VALUE_SYMBOL:
01438 value->Set_symbol ();
01439 value->Set_symbol_index (Get_symbol_index (WN_st(w)));
01440 break;
01441
01442 case VALUE_NOT_CONST:
01443 default:
01444 value->Set_not_const ();
01445 break;
01446 }
01447
01448 }
01449
01450
01451
01452
01453
01454
01455
01456 template <PROGRAM program>
01457 void
01458 SUMMARIZE<program>:: Record_global_ref (WN* w, ST *s, OPERATOR op, BOOL refcount_only)
01459 {
01460 SUMMARY_GLOBAL *global = NULL;
01461
01462 #ifdef KEY
01463 FmtAssert((WN_operator(w) == OPR_LDID) ||
01464 (WN_operator(w) == OPR_ILOAD) ||
01465 (WN_operator(w) == OPR_LDA) ||
01466 (WN_operator(w) == OPR_PRAGMA),
01467 ("Expecting LDID/ILOAD/LDA/PRAGMA in Record_Global_Ref "));
01468
01469
01470 if ((ST_class(s) == CLASS_CONST) ||
01471 (ST_class(s) == CLASS_PREG)) {
01472 return;
01473 }
01474 #else
01475 FmtAssert((WN_operator(w) == OPR_LDID) ||
01476 (WN_operator(w) == OPR_ILOAD) ||
01477 (WN_operator(w) == OPR_LDA),
01478 ("Expecting OPR_LDID/OPR_ILOAD/OPR_LDA in Record_Global_Ref "));
01479
01480
01481
01482 if ((ST_class(WN_st(w)) == CLASS_CONST) ||
01483 (ST_class(WN_st(w)) == CLASS_PREG)) {
01484 return;
01485 }
01486 #endif
01487
01488 if ( Trace_Modref ) {
01489 fprintf ( TFile, " global %s referenced", ST_name(s) );
01490 }
01491
01492 INT index = Global_hash_table->Find(s);
01493
01494 if (index == 0) {
01495
01496 global = New_global ();
01497 global->Set_symbol_index (Get_symbol_index(s));
01498 Global_hash_table->Enter (s, Get_global_idx() + 1);
01499 } else
01500 global = Get_global (index - 1);
01501
01502 global->Inc_refcount ();
01503
01504 if (refcount_only)
01505 return;
01506
01507 switch (op) {
01508 case OPR_LDID:
01509 global->Set_dref();
01510 break;
01511 case OPR_ILOAD:
01512 #ifdef KEY
01513 if (IPA_Enable_Pure_Call_Opt)
01514 Get_procedure (Get_procedure_idx())->Set_has_side_effect();
01515 #endif
01516 global->Set_iref();
01517 break;
01518 case OPR_LDA:
01519 global->Set_aref();
01520 break;
01521 }
01522 }
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541 template <PROGRAM program>
01542 void
01543 SUMMARIZE<program>:: Record_ref_formal ( WN* w )
01544 {
01545 INT i;
01546 WN* w2;
01547 WN *parent_w;
01548
01549
01550 if (OPCODE_has_sym (WN_opcode (w)) && (ST_class(WN_st(w)) == CLASS_PREG))
01551 return;
01552
01553 switch ( WN_operator(w) ) {
01554
01555 case OPR_ILOAD:
01556 #ifdef KEY
01557 if (IPA_Enable_Pure_Call_Opt)
01558 Get_procedure (Get_procedure_idx())->Set_has_side_effect();
01559 #endif
01560 switch ( WN_operator(WN_kid0(w)) ) {
01561 case OPR_ARRAY:
01562 w2 = WN_array_base(WN_kid0(w));
01563
01564 if (!OPCODE_has_sym(WN_opcode(w2))) {
01565 return;
01566 }
01567
01568 i = Get_symbol_index(WN_st(w2));
01569 Get_symbol (i)->Set_dref ();
01570 if ( Trace_CopyProp )
01571 fprintf ( TFile, "\n formal: %s : set dref",
01572 ST_name(WN_st(w2)) );
01573 break;
01574
01575 default:
01576 w2 = WN_kid0(w);
01577 i = Get_symbol_index(WN_st(w2));
01578 Get_symbol (i)->Set_iref();
01579
01580 if ( Trace_CopyProp )
01581 fprintf ( TFile, "\n formal: %s : set iref\n",
01582 ST_name(WN_st(w2)) );
01583 break;
01584 }
01585 break;
01586
01587 case OPR_LDID:
01588
01589 i = Get_symbol_index(WN_st(w));
01590
01591
01592 parent_w = LWN_Get_Parent(w);
01593
01594 if (IsStidToReturnPreg(parent_w,Get_entry_point()) &&
01595 !(Get_symbol(i)->Is_dref()) && !(Get_symbol(i)->Is_cref()))
01596 {
01597 Get_symbol (i)-> Set_cdref_preg_only();
01598 if ( Trace_CopyProp )
01599 fprintf ( TFile, "\n formal: %s : set cdref_preg_only\n",
01600 ST_name(WN_st(w)));
01601 }
01602
01603
01604
01605 if (ST_sclass(WN_st(w)) == SCLASS_FORMAL_REF ||
01606 WN_operator (parent_w) == OPR_ICALL)
01607 Get_symbol (i)->Set_iref ();
01608 else {
01609 Get_symbol (i)->Set_dref();
01610 if ( Trace_CopyProp )
01611 fprintf ( TFile, "\n formal: %s : set dref\n",
01612 ST_name(WN_st(w)) );
01613 }
01614 break;
01615
01616 case OPR_LDA:
01617
01618 i = Get_symbol_index(WN_st(w));
01619 parent_w = LWN_Get_Parent(w);
01620 OPERATOR opr = parent_w ?
01621 WN_operator(parent_w) : (OPERATOR) 0;
01622 if (opr == OPR_ASM_INPUT) {
01623
01624
01625 if (ST_sclass(WN_st(w)) == SCLASS_FORMAL_REF ||
01626 WN_operator (parent_w) == OPR_ICALL)
01627 Get_symbol (i)->Set_iref ();
01628 else {
01629 Get_symbol (i)->Set_dref();
01630 if ( Trace_CopyProp )
01631 fprintf ( TFile, "\n formal: %s : set dref\n",
01632 ST_name(WN_st(w)) );
01633 }
01634 }
01635 else {
01636 Get_symbol (i)->Set_aref();
01637 if ( Trace_CopyProp )
01638 fprintf ( TFile, "\n formal: %s : set aref\n",
01639 ST_name(WN_st(w)) );
01640 }
01641 break;
01642 }
01643
01644 if ( Trace_Modref ) {
01645 if (WN_operator(w) == OPR_ILOAD)
01646 fprintf ( TFile, " formal %s referenced", ST_name(WN_st(w2)) );
01647 else
01648 fprintf ( TFile, " formal %s referenced", ST_name(WN_st(w)) );
01649 }
01650
01651 }
01652
01653
01654 template <PROGRAM program>
01655 void
01656 SUMMARIZE<program>:: Record_ref_all_formal ( WN* w, BOOL parm_store )
01657 {
01658 INT i,j;
01659 WN* w2;
01660 WN *parent_w;
01661 WN *grandparent_w;
01662 const ST *st;
01663 const ST *st2;
01664 TY *proctype;
01665 TY *arg_type;
01666 TYLIST *argtypes;
01667
01668 if (parm_store) {
01669 WN* parent_w = LWN_Get_Parent(w);
01670 OPERATOR opr = parent_w ?
01671 WN_operator(parent_w) : (OPERATOR) 0;
01672 if (opr == OPR_ISTORE && WN_kid0(parent_w) != w) {
01673 if (WN_operator(w) == OPR_LDID)
01674
01675
01676 return;
01677 }
01678 }
01679
01680 st = WN_st(w);
01681
01682 if (ST_class(st) == CLASS_PREG)
01683 return;
01684
01685 switch ( WN_operator(w) ) {
01686 case OPR_ILOAD:
01687 #ifdef KEY
01688 if (IPA_Enable_Pure_Call_Opt)
01689 Get_procedure (Get_procedure_idx())->Set_has_side_effect();
01690 #endif
01691 switch ( WN_operator(WN_kid0(w)) ) {
01692 case OPR_ARRAY:
01693 w2 = WN_array_base(WN_kid0(w));
01694 st2 = WN_st(w2);
01695 if (!OPCODE_has_sym(WN_opcode(w2))) {
01696 return;
01697 }
01698
01699
01700 i = Get_symbol_index(st2);
01701 Get_symbol (i)->Set_cref ();
01702
01703 if (program == INLINER) {
01704 j = Get_symbol_crefcount_index(i);
01705 Get_symbol_crefcount(j)->Incr_cur_cref_count();
01706 if ( Trace_CopyProp )
01707 fprintf ( TFile, "\n formal: %s : cref count: %d\n",
01708 ST_name(st2),
01709 Get_symbol_crefcount(j)->Get_cur_cref_count());
01710 }
01711
01712 if ( Trace_CopyProp )
01713 fprintf ( TFile, "\n formal: %s : set cref",
01714 ST_name(st2));
01715 break;
01716
01717
01718
01719 default:
01720 w2 = WN_kid0(w);
01721 st2 = WN_st(w2);
01722 if (WN_operator(w2) == OPR_LDID)
01723 return;
01724 else if (OPCODE_has_sym(WN_opcode(w2))) {
01725 i = Get_symbol_index(st2);
01726 Get_symbol (i)->Set_cref ();
01727
01728 if (program == INLINER) {
01729 j = Get_symbol_crefcount_index(i);
01730 Get_symbol_crefcount(j)->Incr_cur_cref_count();
01731 if ( Trace_CopyProp )
01732 fprintf ( TFile, "\n formal: %s : cref count: %d\n",
01733 ST_name(st2),
01734 Get_symbol_crefcount(j)->Get_cur_cref_count());
01735 }
01736
01737 if ( Trace_CopyProp )
01738 fprintf ( TFile, "\n formal: %s : set cref",
01739 ST_name(st2));
01740 }
01741 break;
01742 }
01743 break;
01744
01745 case OPR_LDID:
01746 i = Get_symbol_index(st);
01747
01748 parent_w = LWN_Get_Parent(w);
01749
01750 if (IsStidToReturnPreg(parent_w,Get_entry_point()) &&
01751 !(Get_symbol(i)->Is_cref()))
01752 {
01753 Get_symbol (i)-> Set_cdref_preg_only();
01754 if ( Trace_CopyProp )
01755 fprintf ( TFile, "\n formal: %s : set cdref_preg_only\n",
01756 ST_name(st));
01757 }
01758 Get_symbol (i)->Set_cref ();
01759
01760 if (program == INLINER) {
01761 j = Get_symbol_crefcount_index(i);
01762 Get_symbol_crefcount(j)->Incr_cur_cref_count();
01763 if ( Trace_CopyProp )
01764 fprintf ( TFile, "\n formal: %s : cref count: %d\n",
01765 ST_name(st),
01766 Get_symbol_crefcount(j)->Get_cur_cref_count());
01767 }
01768
01769
01770 if ( Trace_CopyProp )
01771 fprintf ( TFile, "\n formal: %s : set cref", ST_name(st) );
01772 break;
01773
01774 case OPR_LDA:
01775 i = Get_symbol_index(st);
01776 Get_symbol (i)->Set_cref ();
01777
01778 if (program == INLINER) {
01779 j = Get_symbol_crefcount_index(i);
01780 Get_symbol_crefcount(j)->Incr_cur_cref_count();
01781 if ( Trace_CopyProp )
01782 fprintf ( TFile, "\n formal: %s : cref count: %d\n",
01783 ST_name(st),
01784 Get_symbol_crefcount(j)->Get_cur_cref_count());
01785 }
01786
01787 if ( Trace_CopyProp )
01788 fprintf ( TFile, "\n formal: %s : set cref", ST_name(st) );
01789 break;
01790 }
01791 }
01792
01793
01794
01795
01796
01797
01798 template <PROGRAM program>
01799 void
01800 SUMMARIZE<program>:: Check_kid_ref (WN* w)
01801 {
01802 INT i;
01803
01804 for (i = 0; i < WN_kid_count(w); i++) {
01805 WN *wn2;
01806 wn2 = WN_kid(w, i);
01807 Check_kid_ref (wn2);
01808 switch (WN_operator(wn2)) {
01809
01810 case OPR_LDID:
01811 case OPR_LDA:
01812 case OPR_ILOAD:
01813 Record_ref (wn2);
01814 break;
01815 default:
01816 break;
01817 }
01818 }
01819 }
01820
01821
01822 static void
01823 Record_unknown_memory_op (WN* wn)
01824 {
01825 if (WN_operator(wn) == OPR_ARRAY) {
01826 WN* base = WN_array_base(wn);
01827 OPERATOR base_opr = WN_operator(base);
01828 if (OPERATOR_has_sym(base_opr)) {
01829 if (base_opr == OPR_LDA) {
01830 return;
01831 }
01832 ST* base_st = WN_st(base);
01833 switch (ST_sclass(base_st)) {
01834 case SCLASS_FORMAL:
01835 case SCLASS_FORMAL_REF:
01836 case SCLASS_AUTO:
01837 case SCLASS_PSTATIC: {
01838 TY_IDX ty = ST_type(base_st);
01839 if (TY_kind(ty) == KIND_ARRAY ||
01840 (TY_kind(ty) == KIND_POINTER &&
01841 TY_kind(TY_pointed(ty)) == KIND_ARRAY)) {
01842 return;
01843 }
01844 }
01845 }
01846 }
01847 }
01848
01849
01850 Summary->Get_procedure(Summary->Get_procedure_idx())->
01851 Set_has_incomplete_array_info();
01852 }
01853
01854
01855
01856
01857
01858 template <PROGRAM program>
01859 void
01860 SUMMARIZE<program>:: Record_ref (WN *w)
01861 {
01862 ST* s;
01863 WN* w2;
01864 BOOL refcount_only = FALSE;
01865 BOOL Inliner_copy_prop = (program == INLINER && INLINE_Enable_Copy_Prop);
01866
01867 if ( Trace_Modref )
01868 fprintf (TFile, "<mr> Record_Ref -- %s:", OPCODE_name(WN_opcode(w)) );
01869
01870 #ifdef KEY
01871
01872 if (WN_operator (w) == OPR_ILOAD)
01873 if (IPA_Enable_Pure_Call_Opt)
01874 Get_procedure (Get_procedure_idx())->Set_has_side_effect();
01875 #endif // KEY
01876
01877
01878
01879
01880
01881
01882
01883 WN* parent_w = LWN_Get_Parent(w);
01884 OPERATOR opr = parent_w ?
01885 WN_operator(parent_w) : (OPERATOR) 0;
01886 if (opr == OPR_PARM || (opr == OPR_ISTORE && WN_kid0(parent_w) != w)) {
01887 refcount_only = TRUE;
01888 } else if (opr == OPR_ARRAY && WN_kid0(parent_w) == w &&
01889 WN_has_sym(w) && TY_kind(ST_type(WN_st(w))) == KIND_ARRAY) {
01890
01891
01892
01893 WN *grandparent_w = LWN_Get_Parent (parent_w);
01894 opr = grandparent_w ?
01895 WN_operator(grandparent_w) : (OPERATOR) 0;
01896 if ((opr == OPR_ISTORE && WN_kid1(grandparent_w) == parent_w) ||
01897 (opr == OPR_ILOAD && WN_kid0(grandparent_w) == parent_w))
01898 return;
01899 }
01900
01901
01902 if (OPCODE_has_sym (WN_opcode (w))) {
01903 s = WN_st (w);
01904 if (ST_st_idx (s) != ST_base_idx (s) && !ST_is_weak_symbol (s))
01905 s = ST_base (s);
01906 } else
01907 s = NULL;
01908
01909 #ifdef KEY
01910
01911 if (s)
01912 switch (ST_sclass(s))
01913 {
01914 case SCLASS_EXTERN:
01915 case SCLASS_UGLOBAL:
01916 case SCLASS_DGLOBAL:
01917 case SCLASS_FSTATIC:
01918 case SCLASS_COMMON:
01919 if (IPA_Enable_Pure_Call_Opt)
01920 Get_procedure (Get_procedure_idx())->Set_has_side_effect();
01921 break;
01922
01923 default:
01924 break;
01925 }
01926 #endif // KEY
01927
01928 switch (WN_operator(w)) {
01929
01930
01931
01932 case OPR_LDID:
01933
01934 #ifdef KEY
01935 {
01936 TY_IDX st_type = ST_type(s);
01937 TY_IDX wn_type = WN_ty(w);
01938 if (st_type != wn_type &&
01939 TY_kind(st_type) == KIND_POINTER) {
01940
01941 TY_IDX pst_type = TY_pointed(st_type);
01942 if (TY_kind(pst_type) == KIND_STRUCT)
01943 Record_ty_info_for_type (pst_type, TY_NO_SPLIT);
01944
01945 if (TY_kind(wn_type) == KIND_POINTER &&
01946 TY_kind(TY_pointed(wn_type)) == KIND_STRUCT)
01947 Record_ty_info_for_type (TY_pointed(wn_type), TY_NO_SPLIT);
01948 }
01949 }
01950 #endif
01951 parent_w = LWN_Get_Parent(w);
01952
01953
01954 if (parent_w && WN_operator(parent_w) == OPR_ILOAD)
01955 return;
01956
01957
01958 switch(ST_sclass(s)) {
01959
01960 case SCLASS_EXTERN:
01961 case SCLASS_UGLOBAL:
01962 case SCLASS_DGLOBAL:
01963 case SCLASS_FSTATIC:
01964 case SCLASS_COMMON:
01965
01966 if (Inliner_copy_prop)
01967 break;
01968 opr = (WN_operator (parent_w) == OPR_ICALL) ?
01969 OPR_ILOAD : OPR_LDID;
01970 Record_global_ref (w, s, opr, refcount_only);
01971 break;
01972
01973
01974 case SCLASS_FORMAL_REF:
01975 if (Inliner_copy_prop)
01976 break;
01977
01978 case SCLASS_FORMAL:
01979 if ( ! refcount_only )
01980 Record_ref_formal ( w );
01981 Record_ref_all_formal (w, refcount_only);
01982 break;
01983
01984 default:
01985 break;
01986 }
01987 break;
01988
01989 case OPR_LDA:
01990 #ifdef KEY
01991 {
01992 TY_IDX type = WN_type(w);
01993 if (TY_kind(type) == KIND_STRUCT)
01994 Record_ty_info_for_type (type, TY_NO_SPLIT);
01995 }
01996 #endif
01997 if (Inliner_copy_prop)
01998 break;
01999
02000 switch ( ST_sclass(s) ) {
02001 case SCLASS_EXTERN:
02002 case SCLASS_UGLOBAL:
02003 case SCLASS_DGLOBAL:
02004 case SCLASS_FSTATIC:
02005 case SCLASS_COMMON:
02006
02007 Record_global_ref ( w, s, OPR_LDA, refcount_only );
02008 break;
02009
02010
02011 default:
02012 if ( opr == OPR_ASM_INPUT)
02013 Record_ref_formal (w);
02014 break;
02015 }
02016 break;
02017
02018 case OPR_ILOAD:
02019 case OPR_MLOAD:
02020 Record_unknown_memory_op(WN_kid0(w));
02021 switch ( WN_operator(WN_kid0(w)) ) {
02022 case OPR_LDID:
02023 case OPR_ARRAY:
02024 if (WN_operator(WN_kid0(w)) == OPR_LDID) {
02025 w2 = WN_kid0(w);
02026 }
02027 else {
02028 w2 = WN_array_base(WN_kid0(w));
02029 }
02030
02031
02032 if (!OPCODE_has_sym(WN_opcode(w2))) {
02033 return;
02034 }
02035
02036 s = WN_st(w2);
02037 if (ST_st_idx (s) != ST_base_idx (s) && !ST_is_weak_symbol (s))
02038 s = ST_base (s);
02039 switch(ST_sclass(s)) {
02040 case SCLASS_COMMON:
02041 if (Inliner_copy_prop)
02042 break;
02043 Record_global_ref (w2, s, OPR_ILOAD, refcount_only);
02044 break;
02045
02046
02047 case SCLASS_EXTERN:
02048 case SCLASS_UGLOBAL:
02049 case SCLASS_DGLOBAL:
02050 case SCLASS_FSTATIC:
02051 if (Inliner_copy_prop)
02052 break;
02053 Record_global_ref (w2, s, OPR_ILOAD, refcount_only);
02054 break;
02055
02056 case SCLASS_FORMAL_REF:
02057 if (Inliner_copy_prop)
02058 break;
02059
02060 case SCLASS_FORMAL:
02061 if ( ! refcount_only )
02062 Record_ref_formal ( w );
02063 break;
02064
02065 default:
02066 if (Trace_Modref || (Trace_CopyProp && Inliner_copy_prop)) {
02067 fprintf ( TFile, "ignoring ILOAD->LDID/ARRAY\n");
02068 Print_ST ( TFile, WN_st(w2), 0 );
02069 }
02070 break;
02071 }
02072 break;
02073
02074 default:
02075 Check_kid_ref (WN_kid0(w));
02076 break;
02077 }
02078 break;
02079 }
02080
02081 if ( Trace_Modref ) {
02082 fprintf ( TFile, "\n" );
02083 }
02084 }
02085
02086
02087
02088
02089
02090
02091 template <PROGRAM program>
02092 void
02093 SUMMARIZE<program>::Record_global_dmod (const WN* w, const WN *rhs,
02094 const ST *s)
02095 {
02096 SUMMARY_GLOBAL *global = NULL;
02097
02098
02099
02100
02101 if ((ST_class(WN_st(w)) == CLASS_CONST) ||
02102 (ST_class(WN_st(w)) == CLASS_PREG))
02103 return;
02104
02105 if ( Trace_Modref ) {
02106 fprintf ( TFile, " global %s modified", ST_name(WN_st(w)) );
02107 }
02108
02109 #ifdef KEY
02110 if (IPA_Enable_Pure_Call_Opt)
02111 Get_procedure (Get_procedure_idx())->Set_has_side_effect();
02112 #endif
02113
02114 INT index = Global_hash_table->Find (s);
02115
02116 if (index == 0) {
02117
02118 global = New_global ();
02119 global->Set_symbol_index (Get_symbol_index(s));
02120 Global_hash_table->Enter (s, Get_global_idx() + 1);
02121 } else
02122 global = Get_global (index - 1);
02123
02124 global->Set_dmod();
02125 Inc_modcount (global, Get_symbol (global->Get_symbol_index()), rhs);
02126
02127 }
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146 template <PROGRAM program>
02147 void
02148 SUMMARIZE<program>:: Record_mod_formal ( WN* w )
02149 {
02150 INT i;
02151 WN* w2;
02152
02153 #ifdef KEY
02154 if (IPA_Enable_Pure_Call_Opt)
02155 {
02156 ST * tmp_st = WN_st (w);
02157 if (ST_st_idx (tmp_st) != ST_base_idx (tmp_st) &&
02158 !ST_is_weak_symbol (tmp_st))
02159 tmp_st = ST_base (tmp_st);
02160 if (ST_sclass (tmp_st) == SCLASS_FORMAL_REF)
02161 Get_procedure (Get_procedure_idx())->Set_has_side_effect();
02162 }
02163 #endif
02164
02165 switch ( WN_operator(w) ) {
02166
02167 case OPR_ISTORE:
02168 case OPR_MSTORE:
02169 switch ( WN_operator(WN_kid1(w)) ) {
02170 case OPR_ARRAY:
02171
02172
02173
02174 w2 = WN_array_base(WN_kid1(w));
02175
02176 if (!OPCODE_has_sym(WN_opcode(w2))) {
02177 return;
02178 }
02179
02180 switch (WN_operator(w2)) {
02181 case OPR_LDID:
02182
02183 i = Get_symbol_index(WN_st(w2));
02184 Get_symbol (i)->Set_imod ();
02185 if ( Trace_CopyProp )
02186 fprintf ( TFile, "\n formal: %s : set imod\n",
02187 ST_name(WN_st(w2)) );
02188 break;
02189
02190 case OPR_LDA:
02191 i = Get_symbol_index(WN_st(w2));
02192 Get_symbol (i)->Set_dmod ();
02193
02194 if ( Trace_CopyProp )
02195 fprintf ( TFile, "\n formal: %s : set dmod\n",
02196 ST_name(WN_st(w2)) );
02197 break;
02198
02199 default:
02200 Fail_FmtAssertion("unsupported array base address opcode \n");
02201 break;
02202 }
02203 break;
02204
02205 default:
02206
02207 w2 = WN_kid1(w);
02208 if (OPCODE_has_sym(WN_opcode(w2)) && WN_st(w2)) {
02209 i = Get_symbol_index(WN_st(w2));
02210 Get_symbol (i)->Set_imod ();
02211 if ( Trace_CopyProp )
02212 fprintf ( TFile, "\n formal: %s : set imod\n",
02213 ST_name(WN_st(w2)) );
02214 }
02215 break;
02216 }
02217 break;
02218
02219 case OPR_STID:
02220 i = Get_symbol_index(WN_st(w));
02221
02222 if (ST_sclass(WN_st(w)) == SCLASS_FORMAL_REF) {
02223
02224 Get_symbol (i)->Set_imod();
02225 } else {
02226 Get_symbol (i)->Set_dmod ();
02227 if ( Trace_CopyProp )
02228 fprintf ( TFile, "\n formal: %s : set dmod\n",
02229 ST_name(WN_st(w)) );
02230 }
02231 w2 = w;
02232 break;
02233 }
02234
02235 if ( Trace_Modref ) {
02236 fprintf ( TFile, " formal %s modified", ST_name(WN_st(w2)) );
02237 }
02238 }
02239
02240
02241
02242
02243
02244 template <PROGRAM program>
02245 void
02246 SUMMARIZE<program>:: Record_mod_common (WN *w, const ST *st)
02247 {
02248 WN* dest = WN_kid1(w);
02249 if (WN_operator(dest) == OPR_ARRAY) {
02250 dest = WN_array_base(dest);
02251 }
02252 if (!OPERATOR_has_sym(WN_operator(dest))) {
02253 return;
02254 }
02255
02256 #ifdef KEY
02257 if (IPA_Enable_Pure_Call_Opt)
02258 Get_procedure (Get_procedure_idx())->Set_has_side_effect();
02259 #endif
02260
02261 SUMMARY_GLOBAL* global;
02262 INT index = Global_hash_table->Find(st);
02263
02264 if (index == 0) {
02265 global = New_global();
02266 global->Set_symbol_index(Get_symbol_index(st));
02267 Global_hash_table->Enter(st, Get_global_idx() + 1);
02268 }
02269 else {
02270 global = Get_global(index - 1);
02271 }
02272
02273 global->Set_dmod();
02274 global->Inc_modcount();
02275 Get_symbol(global->Get_symbol_index())->Set_modcount();
02276
02277 }
02278
02279
02280
02281 static TY_IDX
02282 get_access_type (WN * w)
02283 {
02284 Is_True (OPERATOR_has_1ty(WN_operator(w)) ||
02285 OPERATOR_has_2ty(WN_operator(w)),
02286 ("get_access_type needs WN with ty_idx information"));
02287 TY_IDX w_type = WN_ty(w);
02288
02289 if (WN_field_id(w) == 0)
02290 return w_type;
02291
02292 UINT cur_field_id = 0;
02293 FLD_HANDLE fld = FLD_get_to_field (w_type, WN_field_id(w), cur_field_id);
02294
02295 return FLD_type(fld);
02296 }
02297
02298
02299
02300
02301
02302
02303
02304 template <PROGRAM program>
02305 void
02306 SUMMARIZE<program>:: Record_mod (WN* w)
02307 {
02308 if ( Trace_Modref ) {
02309 fprintf ( TFile, "<mr> Record_Mod -- %s:", OPCODE_name(WN_opcode(w)) );
02310 }
02311
02312
02313 const ST* st;
02314 const WN* w2;
02315
02316 #ifdef KEY
02317
02318 if (WN_operator (w) == OPR_ISTORE)
02319 if (IPA_Enable_Pure_Call_Opt)
02320 Get_procedure (Get_procedure_idx())->Set_has_side_effect();
02321 #endif // KEY
02322
02323 switch (PU_src_lang (Get_Current_PU ())) {
02324 case PU_C_LANG:
02325 case PU_CXX_LANG:
02326
02327 switch (WN_operator (w)) {
02328 case OPR_ISTORE:
02329 case OPR_MSTORE:
02330 Record_unknown_memory_op(WN_kid1(w));
02331 w2 = get_mod_target (WN_kid1(w));
02332 if (w2 && OPCODE_has_sym(WN_opcode(w2))) {
02333 st = WN_st(w2);
02334 if (ST_base_idx (st) != ST_st_idx (st) &&
02335 !ST_is_weak_symbol (st))
02336 st = ST_base (st);
02337
02338 switch (ST_sclass(st)) {
02339
02340 case SCLASS_COMMON:
02341 case SCLASS_EXTERN:
02342 case SCLASS_UGLOBAL:
02343 case SCLASS_DGLOBAL:
02344 case SCLASS_FSTATIC:
02345 Record_global_dmod (w2, WN_kid0(w), st);
02346 break;
02347 #ifdef KEY
02348 default:
02349 if (IPA_Enable_Pure_Call_Opt)
02350 Get_procedure (Get_procedure_idx())->Set_has_side_effect();
02351 #endif
02352 }
02353 } else {
02354
02355 w2 = WN_kid1(w);
02356 if (OPCODE_has_sym(WN_opcode(w2))) {
02357 if (st = WN_st (w2)) {
02358 INT i = Get_symbol_index(st);
02359 Get_symbol (i)->Set_imod ();
02360 if ( Trace_CopyProp )
02361 fprintf ( TFile, "\n formal: %s : set imod\n",
02362 ST_name(st) );
02363 }
02364 }
02365 }
02366
02367 break;
02368
02369 case OPR_STID:
02370
02371 st = WN_st (w);
02372 if (ST_st_idx (st) != ST_base_idx (st) && !ST_is_weak_symbol (st))
02373 st = ST_base (st);
02374 #ifdef KEY
02375
02376
02377 if (WN_operator(WN_kid0(w)) == OPR_LDID) {
02378
02379 TY_IDX rhs_ty = get_access_type(WN_kid0(w));
02380 TY_IDX w_ty = get_access_type(w);
02381
02382 if (rhs_ty != w_ty) {
02383
02384 if (TY_kind(rhs_ty) == KIND_POINTER &&
02385 TY_kind(TY_pointed(rhs_ty)) == KIND_STRUCT)
02386 Record_ty_info_for_type (TY_pointed(rhs_ty), TY_NO_SPLIT);
02387
02388 if (TY_kind(w_ty) == KIND_POINTER &&
02389 TY_kind(TY_pointed(w_ty)) == KIND_STRUCT)
02390 Record_ty_info_for_type (TY_pointed(w_ty), TY_NO_SPLIT);
02391 }
02392 }
02393 #endif
02394
02395 switch ( ST_sclass(st) ) {
02396 case SCLASS_AUTO:
02397 case SCLASS_FORMAL:
02398 case SCLASS_FORMAL_REF:
02399 Record_mod_formal (w);
02400 break;
02401
02402 case SCLASS_EXTERN:
02403 case SCLASS_UGLOBAL:
02404 case SCLASS_DGLOBAL:
02405 case SCLASS_FSTATIC:
02406 case SCLASS_COMMON:
02407 if (DoPreopt &&
02408 Is_Value_Restored (w, w,
02409 *(Get_emitter ()->Wn_to_cr_map ())))
02410 break;
02411
02412 Record_global_dmod (w, WN_kid0(w), WN_st(w));
02413 break;
02414
02415 }
02416 }
02417 break;
02418
02419 case PU_F77_LANG:
02420 case PU_F90_LANG:
02421 switch ( WN_operator(w) ) {
02422
02423
02424 case OPR_STID:
02425 st = WN_st (w);
02426 if (ST_st_idx (st) != ST_base_idx (st) && !ST_is_weak_symbol (st))
02427 st = ST_base (st);
02428
02429 switch ( ST_sclass(st) ) {
02430 case SCLASS_EXTERN:
02431 case SCLASS_UGLOBAL:
02432 case SCLASS_DGLOBAL:
02433 case SCLASS_FSTATIC:
02434 case SCLASS_COMMON:
02435 Record_global_dmod(w, WN_kid0(w), st);
02436 break;
02437
02438 case SCLASS_FORMAL:
02439 case SCLASS_FORMAL_REF:
02440 Record_mod_formal (w);
02441 break;
02442
02443 default:
02444 break;
02445 }
02446 break;
02447
02448 case OPR_ISTORE:
02449 case OPR_MSTORE:
02450 Record_unknown_memory_op(WN_kid1(w));
02451 switch ( WN_operator(WN_kid1(w)) ) {
02452 case OPR_LDID:
02453 case OPR_ARRAY:
02454 case OPR_LDA:
02455 if (WN_operator(WN_kid1(w)) == OPR_ARRAY)
02456 w2 = WN_array_base(WN_kid1(w));
02457 else
02458 w2 = WN_kid1(w);
02459
02460 if (!OPCODE_has_sym(WN_opcode(w2))) {
02461 return;
02462 }
02463
02464 st = WN_st(w2);
02465
02466 switch(ST_sclass(st)) {
02467 case SCLASS_COMMON:
02468 if (ST_st_idx (st) != ST_base_idx (st) &&
02469 !ST_is_weak_symbol (st))
02470 st = ST_base (st);
02471
02472 Record_mod_common(w, st);
02473 break;
02474
02475 case SCLASS_DGLOBAL:
02476 if (ST_st_idx (st) != ST_base_idx (st) &&
02477 !ST_is_weak_symbol (st)) {
02478
02479 st = ST_base (st);
02480 Record_mod_common(w, st);
02481 }
02482 break;
02483
02484 case SCLASS_EXTERN:
02485 case SCLASS_UGLOBAL:
02486 case SCLASS_FSTATIC:
02487 break;
02488
02489 case SCLASS_FORMAL:
02490 case SCLASS_FORMAL_REF:
02491 Record_mod_formal (w);
02492 break;
02493
02494 default:
02495 if ( Trace_Modref ) {
02496 fprintf ( TFile, " ignoring ISTORE->LDID/ARRAY\n");
02497 Print_ST ( TFile, st, 0 );
02498 }
02499 break;
02500 }
02501 break;
02502
02503 }
02504 }
02505 }
02506
02507 if ( Trace_Modref ) {
02508 fprintf ( TFile, "\n" );
02509 }
02510 }
02511
02512
02513
02514
02515
02516
02517
02518 template <PROGRAM program>
02519 INT
02520 SUMMARIZE<program>::Process_cd_for_phi_node (IDTYPE cd_bb_idx)
02521 {
02522 SUMMARY_CONTROL_DEPENDENCE *cd;
02523 struct DU_MANAGER *du = Get_du_mgr ();
02524
02525 if (cd_bb_idx == du->Get_entry_bb ())
02526 return -1;
02527
02528 WN *cond_stmt = du->Get_last_stmt (cd_bb_idx);
02529
02530 #ifdef KEY
02531
02532
02533
02534 if (!cond_stmt)
02535 return -1;
02536 #endif
02537 switch (WN_opcode (cond_stmt)) {
02538 case OPC_TRUEBR:
02539 case OPC_FALSEBR:
02540 case OPC_IF:
02541 break;
02542
02543 default:
02544 return -1;
02545 }
02546
02547 if (WN_MAP32_Get (Summary_Map, cond_stmt)) {
02548
02549 cd = Get_cd_by_idx (WN_MAP32_Get (Summary_Map, cond_stmt) - 1);
02550 return Get_cd_idx (cd);
02551 }
02552
02553 cd = Get_new_cd ();
02554 INT cd_idx = Get_cd_idx (cd);
02555 cd->Set_if_stmt ();
02556 cd->Set_wn (cond_stmt);
02557 WN_MAP32_Set (Summary_Map, cond_stmt, cd_idx + 1);
02558
02559 INT expr_idx = Process_polynomial_jump_function (WN_kid0(cond_stmt));
02560
02561 cd = Get_cd_by_idx (cd_idx);
02562 cd->Set_expr_index (expr_idx);
02563
02564
02565 if (!Process_control_dependence (cond_stmt, cd_idx))
02566 Set_cd_head_of_chain (cd_idx);
02567
02568 return cd_idx;
02569
02570 }
02571
02572
02573 template <PROGRAM program>
02574 BOOL
02575 SUMMARIZE<program>::Process_control_dependence (WN *w, INT node_index)
02576 {
02577 if (w == Get_entry_point())
02578 return TRUE;
02579
02580 WN* stmt_node = w;
02581 while (stmt_node != NULL &&
02582 WN_opcode(LWN_Get_Parent(stmt_node)) != OPC_BLOCK &&
02583 !OPCODE_is_scf(WN_opcode(stmt_node)))
02584 stmt_node = LWN_Get_Parent (stmt_node);
02585
02586 struct DU_MANAGER *du = Get_du_mgr();
02587 IDTYPE bb_idx = du->Get_bb_id(stmt_node);
02588 FmtAssert(bb_idx != 0,
02589 ("Process_control_dependence: Could not find bb_idx"));
02590
02591 IDTYPE cd_bb_idx = du->Get_cd(bb_idx);
02592 WN* cond_stmt;
02593 BOOL ctrl_dep_on_entry = FALSE;
02594
02595 if (cd_bb_idx == du->Get_entry_bb()) {
02596
02597 ctrl_dep_on_entry = TRUE;
02598 cond_stmt = Get_entry_point();
02599 }
02600 else {
02601 if (cd_bb_idx == 0)
02602 return FALSE;
02603 cond_stmt = du->Get_last_stmt(cd_bb_idx);
02604 #ifdef KEY
02605
02606
02607
02608 if (!cond_stmt)
02609 return FALSE;
02610 #endif
02611 switch (WN_opcode(cond_stmt)) {
02612 case OPC_TRUEBR:
02613 case OPC_FALSEBR:
02614 case OPC_IF:
02615 case OPC_DO_LOOP:
02616 break;
02617 default:
02618 return FALSE;
02619 }
02620 }
02621
02622 SUMMARY_CONTROL_DEPENDENCE* cd;
02623 BOOL new_cd_created = FALSE;
02624 INT cd_idx = WN_MAP32_Get (Summary_Map, cond_stmt) - 1;
02625 if (!(cd_idx >= 0 && cd_idx <= Get_max_cd_idx ())) {
02626 cd = Get_new_cd ();
02627 cd_idx = Get_cd_idx (cd);
02628
02629 WN_MAP32_Set (Summary_Map, cond_stmt, cd_idx + 1);
02630 cd->Set_wn (cond_stmt);
02631
02632 if (ctrl_dep_on_entry)
02633 cd->Set_entry ();
02634 else if (WN_opcode (cond_stmt) != OPC_DO_LOOP) {
02635 cd->Set_if_stmt ();
02636
02637
02638 INT expr_idx = Process_polynomial_jump_function (WN_kid0(cond_stmt));
02639 cd = Get_cd_by_idx (cd_idx);
02640 cd->Set_expr_index (expr_idx);
02641 }
02642 else
02643 cd->Set_do_loop ();
02644
02645 new_cd_created = TRUE;
02646 }
02647
02648 BOOL branch = TRUE;
02649 SUMMARY_STMT* stmt;
02650 switch (WN_opcode (cond_stmt)) {
02651 case OPC_FALSEBR:
02652 case OPC_IF:
02653 branch = du->CD_is_fall_thru(bb_idx);
02654 stmt = Get_new_stmt (cd_idx, branch, stmt_node);
02655 break;
02656 case OPC_TRUEBR:
02657 branch = du->CD_is_br_taken(bb_idx);
02658 stmt = Get_new_stmt (cd_idx, branch, stmt_node);
02659 break;
02660 case OPC_DO_LOOP:
02661 case OPC_FUNC_ENTRY:
02662 stmt = Get_new_stmt (cd_idx, TRUE, stmt_node);
02663 break;
02664 }
02665
02666 if (Do_Par)
02667 WN_MAP32_Set (Stmt_Map, stmt_node, cd_idx + 1);
02668
02669 switch (WN_operator (w)) {
02670 case OPR_CALL:
02671 case OPR_ICALL:
02672 stmt->Set_call_index (node_index);
02673 Inc_cd_call_count (cd_idx, branch);
02674 break;
02675
02676 case OPR_ARRAY: {
02677 WN_MAP_Set_ID (Current_Map_Tab, w);
02678
02679 if (WN_is_istore_or_mstore(w) &&
02680 ST_is_common_element(WN_st(WN_array_base(w)))) {
02681
02682 WN* istore = LWN_Get_Parent(w);
02683
02684 SUMMARY_STID* stid_val = New_global_stid();
02685 stmt->Set_stid_index(Get_global_stid_idx());
02686
02687 ST* array_st = WN_st(WN_array_base(w));
02688 stid_val->Set_symbol_index(Get_symbol_index(array_st));
02689 stid_val->Set_array_assignment();
02690 if (Get_procedure(Get_procedure_idx())->Get_call_count() == 0 &&
02691 Get_cd_by_idx(cd_idx)->Is_entry()) {
02692 stid_val->Set_always_executed();
02693 }
02694 if (TY_kind(ST_type(array_st)) == KIND_ARRAY &&
02695 WN_num_dim(w) == 1 &&
02696 WN_operator(istore) == OPR_ISTORE) {
02697 WN* subscript = WN_array_index(w, 0);
02698 if (WN_operator(subscript) == OPR_INTCONST) {
02699 INT64 const_subscript = WN_const_val(subscript);
02700 if (const_subscript <= UINT32_MAX) {
02701 stid_val->Set_constant_subscript();
02702 stid_val->Set_array_subscript((UINT32)const_subscript);
02703
02704 WN* rhs = WN_kid0(istore);
02705
02706 if (WN_operator(rhs) == OPR_INTCONST) {
02707
02708 SUMMARY_VALUE* value = New_value();
02709 value->Set_int_const();
02710 value->Set_int_const_value(WN_const_val(rhs));
02711 value->Set_mtype(WN_rtype(rhs));
02712
02713 INT val_idx = entry_cache->Lookup(SUM_VALUE, value);
02714 if (val_idx != -1 && val_idx < Get_value_idx()) {
02715 _value.Decidx();
02716 }
02717 else {
02718 val_idx = Get_value_idx();
02719 entry_cache->Insert(SUM_VALUE, val_idx);
02720 }
02721 stid_val->Set_value_index(val_idx);
02722 }
02723 }
02724 }
02725 }
02726 }
02727 break;
02728 }
02729
02730 case OPR_STID: {
02731 SUMMARY_STID* stid_val = New_global_stid();
02732 stmt->Set_stid_index(Get_global_stid_idx());
02733
02734 stid_val->Set_symbol_index(Get_symbol_index(WN_st(w)));
02735 if (Get_procedure(Get_procedure_idx())->Get_call_count() == 0 &&
02736 Get_cd_by_idx(cd_idx)->Is_entry()) {
02737 stid_val->Set_always_executed();
02738 }
02739
02740 const SUMMARY_CHECK_POINT chk_pt(this);
02741 SUMMARY_VALUE* value = New_value();
02742 INT value_idx = Get_value_idx();
02743 value->Set_not_const();
02744
02745 Process_jump_function(WN_kid0(w), value_idx);
02746
02747 if (value->Is_not_const()) {
02748 Restore_from_check_point(&chk_pt);
02749 }
02750 else {
02751 INT tmp_idx = entry_cache->Lookup (SUM_VALUE, value);
02752 if (tmp_idx != -1 && tmp_idx < value_idx) {
02753 Restore_from_check_point(&chk_pt);
02754 stid_val->Set_value_index(tmp_idx);
02755 }
02756 else {
02757 entry_cache->Insert(SUM_VALUE, value_idx);
02758 stid_val->Set_value_index(value_idx);
02759 }
02760 }
02761 }
02762 break;
02763
02764 default:
02765 if (OPCODE_has_sym (WN_opcode (w)))
02766 stmt->Set_var_index (node_index);
02767 else if (OPCODE_is_scf(WN_opcode(w)) || OPCODE_is_non_scf(WN_opcode(w)))
02768 stmt->Set_cond_index (node_index);
02769 else
02770 stmt->Set_expr_index (node_index);
02771 break;
02772 }
02773
02774
02775
02776
02777
02778
02779 if (new_cd_created) {
02780 if (cd->Is_entry ())
02781 Set_cd_head_of_chain (cd_idx);
02782 else if (!Process_control_dependence (cond_stmt, cd_idx))
02783 Set_cd_head_of_chain (cd_idx);
02784 }
02785
02786 return TRUE;
02787 }
02788
02789
02790 template <PROGRAM program>
02791 void
02792 SUMMARIZE<program>::Copy_summary_ctrl_dep (SUMMARY_CONTROL_DEPENDENCE *cd)
02793 {
02794 SUMMARY_STMT *stmts;
02795 SUMMARY_CONTROL_DEPENDENCE *ctrl_dep = New_ctrl_dep ();
02796 INT stmt_idx = Get_stmt_idx ();
02797
02798 *ctrl_dep = *cd;
02799 Set_cd_ctrl_index (cd, Get_ctrl_dep_idx ());
02800 ctrl_dep->Set_map_id (WN_map_id (cd->Get_wn ()));
02801
02802 _stmt.Setidx (cd->Get_true_count () + cd->Get_false_count () + stmt_idx);
02803
02804 if (cd->Get_true_count ()) {
02805 ctrl_dep->Set_true_stmt_index (stmt_idx + 1);
02806 stmts = Get_stmt (ctrl_dep->Get_true_stmt_index ());
02807 bcopy (Get_summary_stmts (cd, TRUE), stmts,
02808 sizeof(SUMMARY_STMT) * cd->Get_true_count ());
02809 }
02810
02811 if (cd->Get_false_count ()) {
02812 ctrl_dep->Set_false_stmt_index (stmt_idx + cd->Get_true_count () + 1);
02813 stmts = Get_stmt (ctrl_dep->Get_false_stmt_index ());
02814 bcopy (Get_summary_stmts (cd, FALSE), stmts,
02815 sizeof(SUMMARY_STMT) * cd->Get_false_count ());
02816 }
02817
02818
02819 INT stmt_lastidx = Get_stmt_idx ();
02820 for (INT i = stmt_idx + 1; i <= stmt_lastidx; i++) {
02821 SUMMARY_STMT *stmt = Get_stmt (i);
02822 if (stmt->Is_cond ()) {
02823 SUMMARY_CONTROL_DEPENDENCE *src_cd =
02824 Get_cd_by_idx (stmt->Get_cond_index ());
02825 Copy_summary_ctrl_dep (src_cd);
02826 Get_stmt (i)->Set_cond_index (Get_cd_real_idx (src_cd));
02827 } else if (stmt->Is_array_ref ()) {
02828 stmt->Set_array_ref_map_id (WN_map_id (stmt->Get_array_ref_wn ()));
02829 }
02830 }
02831 }
02832
02833
02834 template <PROGRAM program>
02835 inline void
02836 SUMMARIZE<program>::Generate_summary_control_dependence (void)
02837 {
02838 SUMMARY_CONTROL_DEPENDENCE *cd;
02839
02840 while (cd = Get_next_cd_chain ())
02841 Copy_summary_ctrl_dep (cd);
02842
02843 }
02844
02845
02846
02847
02848
02849
02850 template <PROGRAM program>
02851 void
02852 SUMMARIZE<program>::Process_IO(WN* w)
02853 {
02854 Is_True(WN_operator(w) == OPR_IO, ("Unexpected operator in Process_IO \n"));
02855
02856 switch (WN_io_statement(w)) {
02857 case IOS_READ:
02858 case IOS_ACCEPT:
02859 case IOS_CR_FRF:
02860 case IOS_CR_FRU:
02861 Set_IO(w, TRUE);
02862 break;
02863
02864 default:
02865 Set_IO(w, FALSE);
02866 break;
02867 }
02868 }
02869
02870
02871
02872
02873 template <PROGRAM program>
02874 void
02875 SUMMARIZE<program>::Set_IO(WN* w, BOOL is_read)
02876 {
02877 OPERATOR opr = WN_operator(w);
02878 if (OPERATOR_has_sym(opr)) {
02879 ST* st = WN_st(w);
02880 if (st && ST_class(st) != CLASS_CONST) {
02881
02882 if (ST_base_idx(st) != ST_st_idx(st) && !ST_is_weak_symbol(st)) {
02883 st = ST_base(st);
02884 }
02885
02886
02887 ST_SCLASS sclass = ST_sclass(st);
02888 if ((sclass == SCLASS_COMMON || sclass == SCLASS_DGLOBAL) &&
02889 TY_kind(ST_type(st)) == KIND_STRUCT) {
02890 if (WN_operator(LWN_Get_Parent(w)) != OPR_ARRAY) {
02891 Get_symbol(Get_symbol_index(st))->Set_common_io_no_pad();
02892 }
02893 if (is_read) {
02894 Get_symbol(Get_symbol_index(st))->Set_common_read_no_cprop();
02895 }
02896 }
02897
02898
02899 if (is_read) {
02900 SUMMARY_SYMBOL* symbol = Get_symbol(Get_symbol_index(st));
02901 symbol->Set_imod();
02902 switch (ST_sclass(st)) {
02903 case SCLASS_COMMON:
02904 case SCLASS_EXTERN:
02905 case SCLASS_UGLOBAL:
02906 case SCLASS_DGLOBAL:
02907 case SCLASS_FSTATIC: {
02908 SUMMARY_GLOBAL* global;
02909 INT index = Global_hash_table->Find(st);
02910 if (index == 0) {
02911 global = New_global();
02912 global->Set_symbol_index(Get_symbol_index(st));
02913 Global_hash_table->Enter(st, Get_global_idx()+1);
02914 }
02915 else {
02916 global = Get_global(index-1);
02917 }
02918 global->Set_dmod();
02919 global->Inc_modcount();
02920 symbol->Set_modcount();
02921 break;
02922 }
02923 }
02924 }
02925 }
02926 }
02927
02928 if (opr == OPR_BLOCK) {
02929 for (WN* wn = WN_first(w); wn; wn = WN_next(wn)) {
02930 Set_IO(wn, is_read);
02931 }
02932 }
02933 else {
02934 for (INT kid = 0; kid < WN_kid_count(w); ++kid) {
02935 Set_IO(WN_kid(w,kid), is_read);
02936 }
02937 }
02938 }
02939
02940 #endif // ipl_analyze_template_INCLUDED