00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 #ifdef USE_PCH
00069 #include "opt_pch.h"
00070 #endif // USE_PCH
00071 #pragma hdrstop
00072
00073
00074 #include "opt_points_to.h"
00075 #include "ipo_alias_class.h"
00076 #include "targ_sim.h"
00077
00078 extern "C" {
00079 #include "bitset.h"
00080 }
00081
00082 IP_ALIAS_CLASSIFICATION *Ip_alias_class;
00083 vector<char *> Ip_alias_class_files;
00084
00085
00086
00087
00088
00089 IDTYPE IP_ALIAS_CLASS_REP::_last_id_used;
00090 IP_ACR_SLIST IP_ALIAS_CLASS_REP::_free_list;
00091 UINT32 IP_ALIAS_CLASS_REP::_recycled_acr_nodes;
00092
00093 #if Is_True_On
00094 static const int num_acr_table_entries = 100;
00095 IP_ALIAS_CLASS_REP *acr_table[num_acr_table_entries];
00096
00097 static const int num_acm_table_entries = 100;
00098 IP_ALIAS_CLASS_MEMBER *acm_table[num_acm_table_entries];
00099 static int next_acm_idx = 0;
00100
00101 void print_table(void)
00102 {
00103 UINT i;
00104
00105 for (i = 0;
00106 ((i <= IP_ALIAS_CLASS_REP::_last_id_used) &&
00107 (i < num_acr_table_entries));
00108 ++i) {
00109 if (acr_table[i] != NULL) {
00110 fprintf(TFile, "acr_table[%2u]: ", i);
00111 acr_table[i]->Print(TFile);
00112 }
00113 }
00114
00115 for (i = 0;
00116 ((i < next_acm_idx) && (i < num_acm_table_entries));
00117 ++i) {
00118 fprintf(TFile, "acm_table[%2u]: ", i);
00119 if (acm_table[i] == acm_table[i]->Alias_class()->Representative()) {
00120 fprintf(TFile, "self");
00121 }
00122 else {
00123 acm_table[i]->Print(TFile);
00124 }
00125 fprintf(TFile, " in ");
00126 if (acm_table[i]->Alias_class() == NULL) {
00127 fprintf(TFile, "no class\n");
00128 }
00129 else {
00130 acm_table[i]->Alias_class()->Print(TFile);
00131 }
00132 }
00133 }
00134 #endif
00135
00136 class IP_BASE_ID_MAP_ENTRY {
00137 private:
00138 const ST_IDX _pu_st_idx;
00139 const ST_IDX _base_st_idx;
00140 IP_ALIAS_CLASS_MEMBER _base_member;
00141 public:
00142 IP_BASE_ID_MAP_ENTRY(const ST_IDX pu_st_idx,
00143 const ST_IDX base_st_idx,
00144 IDTYPE base_id) :
00145 _pu_st_idx(pu_st_idx), _base_st_idx(base_st_idx),
00146 _base_member(base_id)
00147 {
00148 #if Is_True_On
00149 if (next_acm_idx < num_acm_table_entries) {
00150 acm_table[next_acm_idx++] = &_base_member;
00151 }
00152 #endif
00153 }
00154
00155 IP_ALIAS_CLASS_MEMBER &Base_member(void)
00156 { return _base_member; }
00157 };
00158
00159
00160 IP_ALIAS_CLASS_REP *
00161 IP_ALIAS_CLASSIFICATION::New_alias_class(const IP_ACR_TYPE_SORT sort,
00162 IP_ALIAS_CLASS_MEMBER &acm) const
00163 {
00164 IP_ALIAS_CLASS_REP *retval;
00165
00166 if (IP_ALIAS_CLASS_REP::_free_list.front() != NULL) {
00167 retval = IP_ALIAS_CLASS_REP::_free_list.pop_front();
00168
00169
00170 retval->~IP_ALIAS_CLASS_REP();
00171 new(retval) IP_ALIAS_CLASS_REP(Pool());
00172 ++IP_ALIAS_CLASS_REP::_recycled_acr_nodes;
00173 }
00174 else {
00175 retval = CXX_NEW(IP_ALIAS_CLASS_REP(Pool()), Pool());
00176 }
00177
00178 #if Is_True_On
00179 if (retval->Id() < num_acr_table_entries) {
00180 acr_table[retval->Id()] = retval;
00181 }
00182 #endif
00183 acm.Put_in_set(retval);
00184 if (Tracing() && _verbose) {
00185 fprintf(TFile, "Creating ");
00186 retval->Print(TFile, Global_data_class());
00187 }
00188
00189 retval->_type_info._sort = sort;
00190
00191 switch (sort) {
00192 case IP_ACR_BOTTOM_TYPE:
00193
00194
00195 break;
00196 case IP_ACR_REF_TYPE:
00197 {
00198 IP_ALIAS_CLASS_MEMBER *acm = New_alias_class_member();
00199 (void) New_alias_class(IP_ACR_BOTTOM_TYPE, *acm);
00200 retval->_type_info._ref.Data_member() = acm;
00201 acm = New_alias_class_member();
00202 (void) New_alias_class(IP_ACR_BOTTOM_TYPE, *acm);
00203 retval->_type_info._ref.Code_member() = acm;
00204 break;
00205 }
00206 case IP_ACR_LAMBDA_TYPE:
00207
00208
00209 retval->_type_info._signature =
00210 CXX_NEW(IP_AC_LAMBDA_TYPE_REP(Pool()), Pool());
00211 break;
00212 case IP_ACR_VALUE_TYPE:
00213 default:
00214 FmtAssert(FALSE, ("New_alias_class: illegal type"));
00215 break;
00216 }
00217 return retval;
00218 }
00219
00220
00221 IP_ALIAS_CLASS_MEMBER *
00222 IP_ALIAS_CLASSIFICATION::New_alias_class_member(void) const
00223 {
00224 IP_ALIAS_CLASS_MEMBER *acm = CXX_NEW(IP_ALIAS_CLASS_MEMBER, Pool());
00225
00226 #if Is_True_On
00227 if (next_acm_idx < num_acm_table_entries) {
00228 acm_table[next_acm_idx++] = acm;
00229 }
00230 #endif
00231
00232 return acm;
00233 }
00234
00235 #if DELETE_ME
00236 IP_ALIAS_CLASS_MEMBER *
00237 IP_ALIAS_CLASSIFICATION::New_alias_class_member(const IDTYPE base_id) const
00238 {
00239 IP_ALIAS_CLASS_MEMBER *acm = CXX_NEW(IP_ALIAS_CLASS_MEMBER(base_id),
00240 Pool());
00241
00242 #if Is_True_On
00243 if (next_acm_idx < num_acm_table_entries) {
00244 acm_table[next_acm_idx++] = acm;
00245 }
00246 #endif
00247
00248 return acm;
00249 }
00250 #endif // DELETE_ME
00251
00252 IP_ALIAS_CLASS_MEMBER *
00253 IP_ALIAS_CLASSIFICATION::New_alias_class_member(const WN *wn) const
00254 {
00255 IP_ALIAS_CLASS_MEMBER *acm = CXX_NEW(IP_ALIAS_CLASS_MEMBER(wn),
00256 Pool());
00257
00258 #if Is_True_On
00259 if (next_acm_idx < num_acm_table_entries) {
00260 acm_table[next_acm_idx++] = acm;
00261 }
00262 #endif
00263
00264 return acm;
00265 }
00266
00267
00268 void
00269 IP_AC_LAMBDA_TYPE_REP::Set_arities(const UINT in_arity,
00270 const UINT out_arity,
00271 const IP_ALIAS_CLASSIFICATION *const ip_ac)
00272 {
00273 arity_established = TRUE;
00274
00275 IP_ALIAS_CLASS_MEMBER *dummy_arg;
00276
00277 for (UINT i = 1; i < in_arity; ++i) {
00278 dummy_arg = ip_ac->New_alias_class_member();
00279 (void) ip_ac->New_alias_class(IP_ACR_REF_TYPE, *dummy_arg);
00280 fixed_args.push_back(dummy_arg);
00281 }
00282
00283 dummy_arg = ip_ac->New_alias_class_member();
00284 (void) ip_ac->New_alias_class(IP_ACR_REF_TYPE, *dummy_arg);
00285 remaining_args = dummy_arg;
00286
00287 if (!returns_new_memory) {
00288 dummy_arg = ip_ac->New_alias_class_member();
00289 (void) ip_ac->New_alias_class(IP_ACR_REF_TYPE, *dummy_arg);
00290 returns = dummy_arg;
00291 }
00292 }
00293
00294 WN *
00295 IP_ALIAS_CLASSIFICATION::Classify_wn_and_kids(WN *const wn)
00296 {
00297 OPCODE opc = WN_opcode(wn);
00298
00299 if (opc == OPC_BLOCK) {
00300 for (WN *wn2 = WN_first(wn); wn2 != NULL; ) {
00301 wn2 = Classify_wn_and_kids(wn2);
00302 }
00303 return NULL;
00304 }
00305 else if (OPCODE_is_store(opc)) {
00306 if (_verbose && Tracing()) {
00307 fprintf(TFile, "cwnk: Handling assignment:\n");
00308 fdump_tree(TFile, wn);
00309 }
00310 return Handle_assignment(wn);
00311 }
00312 else if (WN_operator(wn) == OPR_RETURN_VAL) {
00313 if (_verbose && Tracing()) {
00314 fprintf(TFile, "cwnk: Handling return value:\n");
00315 fdump_tree(TFile, wn);
00316 }
00317 return Handle_return_val(wn);
00318 }
00319 else if (OPCODE_is_call(opc)) {
00320 if (_verbose && Tracing()) {
00321 fprintf(TFile, "cwnk: Handling call:\n");
00322 fdump_tree(TFile, wn);
00323 }
00324 return Handle_call(wn);
00325 }
00326 else if (OPCODE_is_expression(opc)) {
00327
00328
00329 Classify_deref_of_expr(NULL, wn, FALSE);
00330 return NULL;
00331 }
00332 else if (opc == OPC_IO) {
00333 return WN_next(wn);
00334 }
00335 else if (!OPCODE_is_black_box(opc)) {
00336 for (INT i = 0; i < WN_kid_count(wn); i++) {
00337 WN *kid_i = WN_kid(wn, i);
00338 (void) Classify_wn_and_kids(kid_i);
00339 }
00340 return WN_next(wn);
00341 }
00342 else {
00343 return WN_next(wn);
00344 }
00345 }
00346
00347 static BOOL Data_item(const ST *const st)
00348 {
00349 BOOL retval = ST_class(st) != CLASS_FUNC;
00350 Is_True(retval == (ST_sclass(st) == SCLASS_AUTO ||
00351 ST_sclass(st) == SCLASS_FORMAL ||
00352 ST_sclass(st) == SCLASS_FORMAL_REF ||
00353 ST_sclass(st) == SCLASS_REG ||
00354 ST_sclass(st) == SCLASS_PSTATIC ||
00355 ST_sclass(st) == SCLASS_FSTATIC ||
00356 ST_sclass(st) == SCLASS_COMMON ||
00357 ST_sclass(st) == SCLASS_UGLOBAL ||
00358 ST_sclass(st) == SCLASS_DGLOBAL ||
00359 ST_sclass(st) == SCLASS_UNKNOWN ||
00360 ST_sclass(st) == SCLASS_THREAD_PRIVATE_FUNCS ||
00361 ((ST_sclass(st) == SCLASS_EXTERN) &&
00362 (ST_class(st) != CLASS_FUNC))),
00363 ("IP_ALIAS_CLASSIFICATION: Data_item inconsistency"));
00364 return retval;
00365 }
00366
00367 static BOOL Code_item(const ST *const st)
00368 {
00369 return ST_class(st) == CLASS_FUNC;
00370 }
00371
00372 static BOOL Directly_assignable_outside_analyzed_code(const ST *const st)
00373 {
00374 Is_True(Data_item(st),
00375 ("IP_ALIAS_CLASSIFICATION: Data item required"));
00376 Is_True(ST_export(st) != EXPORT_OPTIONAL,
00377 ("IP_ALIAS_CLASSIFICATION: What is EXPORT_OPTIONAL?"));
00378
00379 return (ST_export(st) == EXPORT_PROTECTED ||
00380 ST_export(st) == EXPORT_PREEMPTIBLE ||
00381
00382
00383
00384 ST_export(st) == EXPORT_OPTIONAL);
00385 }
00386
00387 static BOOL Directly_callable_outside_analyzed_code(const ST *const st)
00388 {
00389 Is_True(Code_item(st),
00390 ("IP_ALIAS_CLASSIFICATION: Code item required"));
00391 Is_True(ST_export(st) != EXPORT_OPTIONAL,
00392 ("IP_ALIAS_CLASSIFICATION: What is EXPORT_OPTIONAL?"));
00393
00394 return (ST_export(st) == EXPORT_PROTECTED ||
00395 ST_export(st) == EXPORT_PREEMPTIBLE ||
00396
00397
00398
00399 ST_export(st) == EXPORT_OPTIONAL);
00400 }
00401
00402 IDTYPE
00403 IP_ALIAS_CLASSIFICATION::New_base_id(const ST_IDX pu_st_idx,
00404 const ST_IDX st_idx)
00405 {
00406 BOOL function_class = FALSE;
00407 IDTYPE id = _base_id_map.Newidx();
00408 ST *st = &St_Table[st_idx];
00409
00410 if (Tracing()) {
00411 fprintf(TFile, "Allocating base ID %u\n", id);
00412 }
00413
00414
00415
00416
00417 if (ST_sclass(st) != SCLASS_REG) {
00418 AC_ST_IDENTIFIER st;
00419 st.Set_pu_st_idx(pu_st_idx);
00420 st.Set_base_st_idx(st_idx);
00421 _st_id_to_base_id_map.Insert(st, id);
00422 }
00423
00424 _base_id_map[id] = CXX_NEW(IP_BASE_ID_MAP_ENTRY(pu_st_idx, st_idx, id),
00425 Pool());
00426
00427 if (Tracing()) {
00428 fprintf(TFile, "Base ID %3d is ", id);
00429 }
00430
00431 ST_SCLASS storage_class = ST_sclass(st);
00432
00433
00434
00435 if (Data_item(st)) {
00436
00437 if (Directly_assignable_outside_analyzed_code(st)) {
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454 if (Tracing()) {
00455 fprintf(TFile, "global: ");
00456 }
00457 _base_id_map[id]->Base_member().Put_in_set(Global_data_class());
00458 }
00459 else {
00460
00461
00462
00463 IP_ALIAS_CLASS_REP *ldid_class =
00464 New_alias_class(IP_ACR_REF_TYPE, _base_id_map[id]->Base_member());
00465 if (Tracing()) {
00466 fprintf(TFile, " local: ");
00467 }
00468 }
00469 }
00470 else {
00471 Is_True(Code_item(st),
00472 ("IP_ALIAS_CLASSIFICATION: Referenced ST's must be either "
00473 "code or data"));
00474
00475 BOOL callee_returns_new_memory = Callee_returns_new_memory(st);
00476 BOOL callee_frees_memory = Callee_frees_memory(st);
00477
00478 BOOL require_new_class = (callee_returns_new_memory ||
00479 callee_frees_memory);
00480 if (Directly_callable_outside_analyzed_code(st) &&
00481 !require_new_class) {
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494 _base_id_map[id]->Base_member().Put_in_set(Global_func_class());
00495 }
00496 else {
00497
00498
00499
00500
00501 IP_ALIAS_CLASS_REP *callee_class;
00502 if (callee_returns_new_memory ||
00503 callee_frees_memory) {
00504
00505
00506
00507 callee_class =
00508 New_alias_class(IP_ACR_LAMBDA_TYPE,
00509 _base_id_map[id]->Base_member());
00510 }
00511 else {
00512
00513
00514 callee_class =
00515 New_alias_class(IP_ACR_BOTTOM_TYPE,
00516 _base_id_map[id]->Base_member());
00517 }
00518 if (callee_returns_new_memory) {
00519 callee_class->Signature().returns_new_memory = TRUE;
00520 callee_class->Signature().Set_arities(0, 1, this);
00521 }
00522 if (callee_frees_memory) {
00523 callee_class->Signature().frees_memory = TRUE;
00524 }
00525 }
00526 if (Tracing()) {
00527 fprintf(TFile, " function: ");
00528 function_class = TRUE;
00529 }
00530 }
00531 if (Tracing()) {
00532 Print_ST(TFile, st, _verbose || function_class);
00533 }
00534 return id;
00535 }
00536
00537 IDTYPE
00538 IP_ALIAS_CLASSIFICATION::ST_base_id(const ST_IDX pu_st_idx,
00539 const ST_IDX base_st_idx)
00540 {
00541 Is_True(ST_sclass(St_Table[base_st_idx]) != SCLASS_REG &&
00542 ST_class(St_Table[base_st_idx]) != CLASS_PREG,
00543 ("IP_ALIAS_CLASSIFICATION::St_base_id: wrong mechanism for PREG"));
00544
00545 IDTYPE base_id;
00546
00547 AC_ST_IDENTIFIER st;
00548 st.Set_pu_st_idx(pu_st_idx);
00549 st.Set_base_st_idx(base_st_idx);
00550 base_id = _st_id_to_base_id_map.Lookup(st);
00551
00552 if (base_id == (IDTYPE) 0) {
00553 return New_base_id(pu_st_idx, base_st_idx);
00554 }
00555 else {
00556 return base_id;
00557 }
00558 }
00559
00560 IDTYPE
00561 IP_ALIAS_CLASSIFICATION::Base_id(const ST *const base_st,
00562 const INT64 base_ofst)
00563 {
00564
00565
00566
00567
00568
00569
00570
00571 if (ST_sclass(base_st) == SCLASS_REG) {
00572
00573 ST_IDX base_st_idx = ST_st_idx(base_st);
00574 ST_IDX pu_st_idx =
00575 ST_st_idx(Scope_tab[CURRENT_SYMTAB].st);
00576 AC_PREG_IDENTIFIER preg;
00577 preg.Set_pu_st_idx(pu_st_idx);
00578 preg.Set_preg_num(base_ofst);
00579 IDTYPE base_id = Preg_id_to_base_id_map().Lookup(preg);
00580 if (base_id == 0) {
00581 base_id = New_base_id(pu_st_idx, base_st_idx);
00582 Preg_id_to_base_id_map().Insert(preg, base_id);
00583 }
00584 return base_id;
00585 }
00586 else {
00587 ST_IDX base_st_idx = ST_st_idx(base_st);
00588 ST_IDX pu_st_idx = ST_st_idx(Scope_tab[ST_IDX_level(base_st_idx)].st);
00589 return ST_base_id(pu_st_idx, base_st_idx);
00590 }
00591 }
00592
00593 void
00594 IP_ALIAS_CLASSIFICATION::Find_declared_base_and_offset(ST_IDX st_idx,
00595 ST_IDX &declared_base_idx,
00596 INT64 &declared_offset)
00597 {
00598 ST *st = &St_Table[st_idx];
00599 ST_IDX base_st_idx = ST_base_idx(st);
00600 ST *base_st;
00601
00602
00603 declared_base_idx = st_idx;
00604
00605 while (st_idx != base_st_idx &&
00606 (base_st = &St_Table[base_st_idx], TRUE) &&
00607 (ST_class(base_st) != CLASS_BLOCK ||
00608 !STB_compiler_layout(base_st))) {
00609 declared_offset += ST_ofst(st);
00610 declared_base_idx = ST_base_idx(st);
00611 st = base_st;
00612 st_idx = base_st_idx;
00613 }
00614 }
00615
00616 IDTYPE
00617 IP_ALIAS_CLASSIFICATION::WN_base_id(const WN *wn)
00618 {
00619 ST_IDX declared_base_idx;
00620 INT64 declared_offset;
00621
00622 if (OPCODE_is_call(WN_opcode(wn))) {
00623 declared_offset = (INT64) 0;
00624 }
00625 else {
00626 declared_offset = WN_offset(wn);
00627 }
00628 Find_declared_base_and_offset(WN_st_idx(wn),
00629 declared_base_idx,
00630 declared_offset);
00631 return Base_id(&St_Table[declared_base_idx], declared_offset);
00632 }
00633
00634 static BOOL
00635 Is_LDA_of_variable(const WN *const wn)
00636 {
00637 Is_True(WN_operator(wn) == OPR_LDA,
00638 ("Is_LDA_of_variable: WN must be LDA node"));
00639
00640 ST *st = WN_st(wn);
00641 Is_True(ST_class(st) != CLASS_PREG,
00642 ("Is_LDA_of_variable: CLASS_PREG"));
00643
00644 return (ST_class(st) == CLASS_UNK ||
00645 ST_class(st) == CLASS_VAR ||
00646
00647 ST_class(st) == CLASS_CONST ||
00648 ST_class(st) == CLASS_BLOCK);
00649 }
00650
00651 IP_ALIAS_CLASS_REP *
00652 IP_ALIAS_CLASSIFICATION::Class_of_base_id(const IDTYPE base_id) const
00653 {
00654 return _base_id_map[base_id]->Base_member().Alias_class();
00655 }
00656
00657 #if 0
00658 BOOL
00659 IP_ALIAS_CLASS_REP::In_pending(IP_ALIAS_CLASS_REP *acr)
00660 {
00661 for (PENDING_SET::iterator p_item = Pending().begin();
00662 p_item != Pending().end();
00663 ++p_item) {
00664 if ((*p_item)->Alias_class() == acr) {
00665 return TRUE;
00666 }
00667 }
00668 return FALSE;
00669 }
00670 #endif
00671
00672 void
00673 IP_ALIAS_CLASS_REP::Add_pending(IP_ALIAS_CLASS_REP *item,
00674 BOOL trace)
00675 {
00676 Is_True(item != NULL && item->Representative() != NULL,
00677 ("IP_ALIAS_CLASSIFICATION: Cannot add <NULL> to pending list"));
00678
00679 if (trace) {
00680 fprintf(TFile, "Pending(%d) += %d\n", Id(), item->Id());
00681 }
00682
00683 #if 0
00684 if (!In_pending(acr))
00685 #endif
00686 _pending.push_front(item->Representative());
00687 }
00688
00689 void
00690 IP_ALIAS_CLASS_REP::Process_pending( IP_ALIAS_CLASS_MEMBER *member,
00691 MEM_POOL *pool,
00692 const BOOL trace)
00693 {
00694
00695
00696 if (trace) {
00697 fprintf(TFile, "Process pending of ");
00698 Print(TFile);
00699 fprintf(TFile, " into ");
00700 member->Alias_class()->Print(TFile);
00701 }
00702
00703 for (PENDING_SET::iterator p_item = Pending().begin();
00704 p_item != Pending().end();
00705 ++p_item) {
00706 member->Alias_class()->Join(*((*p_item)->Alias_class()), pool, trace);
00707 }
00708 }
00709
00710 void
00711 IP_ALIAS_CLASS_REP::Settype(const IP_AC_REF_TYPE_REP &new_ref,
00712 MEM_POOL *pool,
00713 const BOOL trace)
00714 {
00715 Is_True(Sort() == IP_ACR_BOTTOM_TYPE,
00716 ("Settype: must be BOTTOM"));
00717 _type_info._sort = IP_ACR_REF_TYPE;
00718 _type_info._ref = new_ref;
00719 Process_pending(Representative(), pool, trace);
00720 }
00721
00722 void
00723 IP_ALIAS_CLASS_REP::Merge_pending( IP_ALIAS_CLASS_REP &that,
00724 const BOOL trace)
00725 {
00726
00727
00728 if (trace) {
00729 fprintf(TFile, "Pending(%d) += Pending(%d)\n", Id(), that.Id());
00730 }
00731
00732 Pending().splice(Pending().begin(), that.Pending());
00733 Is_True(that.Pending().empty(),
00734 ("IP_ALIAS_CLASSIFICATION: Emptied pending container "
00735 "must be empty"));
00736 }
00737
00738 void
00739 IP_ALIAS_CLASS_REP::Free_acr(void)
00740 {
00741 #if Is_True_On
00742 if (Id() < num_acr_table_entries) {
00743 acr_table[Id()] = NULL;
00744 }
00745 #endif
00746 _free_list.push_front(this);
00747 }
00748
00749 void
00750 IP_ALIAS_CLASS_REP::Join( IP_ALIAS_CLASS_REP &that,
00751 MEM_POOL *pool,
00752 const BOOL trace)
00753 {
00754 if (this != &that) {
00755 IP_ALIAS_CLASS_REP *result = (IP_ALIAS_CLASS_REP *) Union(that);
00756 IP_ALIAS_CLASS_REP *non_result = (result == this ? &that : this);
00757 if (trace) {
00758 fprintf(TFile, "%d <-- Join(%d,%d)\n",
00759 result->Id(), Id(), that.Id());
00760 }
00761 if (Sort() == IP_ACR_BOTTOM_TYPE &&
00762 that.Sort() == IP_ACR_BOTTOM_TYPE) {
00763
00764 result->Merge_pending(*non_result, trace);
00765 }
00766 else if (Sort() == IP_ACR_BOTTOM_TYPE) {
00767 if (result == this) {
00768 result->_type_info = that._type_info;
00769 }
00770 Process_pending(result->Representative(), pool, trace);
00771 }
00772 else if (that.Sort() == IP_ACR_BOTTOM_TYPE) {
00773 if (result == &that) {
00774 result->_type_info = _type_info;
00775 }
00776 that.Process_pending(result->Representative(), pool, trace);
00777 }
00778 else {
00779 if (Sort() == IP_ACR_REF_TYPE) {
00780 FmtAssert(that.Sort() == IP_ACR_REF_TYPE,
00781 ("Join: Cannot join REF to another type"));
00782
00783
00784 Data_class_pointed_to()->Join(*that.Data_class_pointed_to(), pool, trace);
00785 Func_class_pointed_to()->Join(*that.Func_class_pointed_to(), pool, trace);
00786 Is_True(Data_class_pointed_to() == that.Data_class_pointed_to(),
00787 ("IP_ACR::Join: Inconsistent join"));
00788 Is_True(Func_class_pointed_to() == that.Func_class_pointed_to(),
00789 ("IP_ACR::Join: Inconsistent join"));
00790 }
00791 else {
00792 FmtAssert(Sort() == IP_ACR_LAMBDA_TYPE &&
00793 that.Sort() == IP_ACR_LAMBDA_TYPE,
00794 ("Join: Cannot join mismatched types"));
00795
00796
00797 Signature().Union_func_args(that.Signature(), pool, trace);
00798 }
00799 }
00800 non_result->Free_acr();
00801 }
00802 }
00803
00804 void
00805 IP_AC_LAMBDA_TYPE_REP::Union_func_args( IP_AC_LAMBDA_TYPE_REP &that,
00806 MEM_POOL *pool,
00807 const BOOL trace)
00808 {
00809 Is_True(arity_established,
00810 ("IP_AC_LAMBDA_TYPE_REP: arity must be established"));
00811 Is_True(that.arity_established,
00812 ("IP_AC_LAMBDA_TYPE_REP: that.arity must be established"));
00813
00814
00815
00816 IP_ALIAS_CLASS_MEMBER **arg;
00817 IP_ALIAS_CLASS_MEMBER **that_arg;
00818 for (arg = &(*fixed_args.begin()),
00819 that_arg = &(*that.fixed_args.begin());
00820 (arg != &(*fixed_args.end()) &&
00821 that_arg != &(*that.fixed_args.end()));
00822 ++arg, ++that_arg)
00823 {
00824 IP_AC_VALUE_TYPE_REP &arg1 = (* arg)->Alias_class()->Ref()._value;
00825 IP_AC_VALUE_TYPE_REP &arg2 = (*that_arg)->Alias_class()->Ref()._value;
00826
00827 IP_ALIAS_CLASS_MEMBER *data_deref_arg1 = arg1.Data_member();
00828 IP_ALIAS_CLASS_MEMBER *data_deref_arg2 = arg2.Data_member();
00829 IP_ALIAS_CLASS_MEMBER *code_deref_arg1 = arg1.Code_member();
00830 IP_ALIAS_CLASS_MEMBER *code_deref_arg2 = arg2.Code_member();
00831 data_deref_arg1->Alias_class()->
00832 Join(*data_deref_arg2->Alias_class(), pool, trace);
00833 code_deref_arg1->Alias_class()->
00834 Join(*code_deref_arg2->Alias_class(), pool, trace);
00835 }
00836
00837
00838
00839 IP_ALIAS_CLASS_MEMBER *vararg_data_representative,
00840 *vararg_code_representative;
00841 IP_ALIAS_CLASS_MEMBER **start, **stop;
00842
00843 if (arg != &(*fixed_args.end()))
00844 {
00845 start = arg;
00846 stop = &(*fixed_args.end());
00847 IP_AC_VALUE_TYPE_REP &vararg_rep =
00848 that.remaining_args->Alias_class()->Ref()._value;
00849 vararg_data_representative = vararg_rep.Data_member();
00850 vararg_code_representative = vararg_rep.Code_member();
00851 }
00852 else {
00853 start = that_arg;
00854 stop = &(*that.fixed_args.end());
00855 IP_AC_VALUE_TYPE_REP &vararg_rep =
00856 remaining_args->Alias_class()->Ref()._value;
00857 vararg_data_representative = vararg_rep.Data_member();
00858 vararg_code_representative = vararg_rep.Code_member();
00859 }
00860 while (start != stop) {
00861 (*start)->Alias_class()->Data_class_pointed_to()->
00862 Join(*vararg_data_representative->Alias_class(), pool, trace);
00863 (*start)->Alias_class()->Func_class_pointed_to()->
00864 Join(*vararg_code_representative->Alias_class(), pool, trace);
00865 ++start;
00866 }
00867
00868 remaining_args->Alias_class()->Data_class_pointed_to()->
00869 Join(*(that.remaining_args->Alias_class()->Data_class_pointed_to()),
00870 pool, trace);
00871 remaining_args->Alias_class()->Func_class_pointed_to()->
00872 Join(*(that.remaining_args->Alias_class()->Func_class_pointed_to()),
00873 pool, trace);
00874
00875 #ifdef KEY // bug 8109
00876 Return_class_member()->Alias_class()->Data_class_pointed_to()->
00877 Join(*(that.Return_class_member()->Alias_class()->Data_class_pointed_to()), pool, trace);
00878 Return_class_member()->Alias_class()->Func_class_pointed_to()->
00879 Join(*(that.Return_class_member()->Alias_class()->Func_class_pointed_to()), pool, trace);
00880 #else
00881 Returns()->Alias_class()->Data_class_pointed_to()->
00882 Join(*(that.Returns()->Alias_class()->Data_class_pointed_to()), pool, trace);
00883 Returns()->Alias_class()->Func_class_pointed_to()->
00884 Join(*(that.Returns()->Alias_class()->Func_class_pointed_to()), pool, trace);
00885 #endif
00886 }
00887
00888 void
00889 IP_ALIAS_CLASSIFICATION::Conditional_join(IP_ALIAS_CLASS_REP *lhs_deref_class,
00890 IP_ALIAS_CLASS_REP *rhs_deref_class)
00891 {
00892 if (lhs_deref_class != rhs_deref_class) {
00893 if (rhs_deref_class->Sort() == IP_ACR_BOTTOM_TYPE) {
00894
00895
00896
00897 rhs_deref_class->Add_pending(lhs_deref_class, Tracing());
00898 }
00899 else {
00900 lhs_deref_class->Join(*rhs_deref_class, Pool(), Tracing());
00901 }
00902 }
00903 }
00904
00905 void
00906 IP_ALIAS_CLASS_REP::Print(FILE *fp,
00907 IP_ALIAS_CLASS_REP *global_class) const
00908 {
00909 fprintf(fp, "class %d ", Id());
00910 FmtAssert(Id() != 0 || global_class == NULL || global_class == this,
00911 ("Class of nonzero ID must not be global"));
00912 if (global_class == this) {
00913 fprintf(fp, "(global)");
00914 }
00915 else {
00916 if (_representative->Null_parent()) {
00917 fprintf(fp, "represented by ");
00918 if (Representative() == NULL) {
00919 fprintf(fp, "<null> ");
00920 }
00921 else {
00922 Representative()->Print(fp);
00923 }
00924 }
00925 else {
00926 fprintf(fp, "[stale] ");
00927 }
00928 }
00929 switch (Sort()) {
00930 case IP_ACR_BOTTOM_TYPE:
00931 fprintf(fp, " bot\n");
00932 break;
00933 case IP_ACR_REF_TYPE:
00934 fprintf(fp, " --> (%d<%p> x %d<%p>)\n",
00935 Data_class_pointed_to()->Id(), Ref().Data_member(),
00936 Func_class_pointed_to()->Id(), Ref().Code_member());
00937 break;
00938 case IP_ACR_LAMBDA_TYPE:
00939 if (Signature().returns_new_memory) {
00940 if (Signature().frees_memory) {
00941 fprintf(fp, " realloc(");
00942 }
00943 else {
00944 fprintf(fp, " alloc(");
00945 }
00946 }
00947 else if (Signature().frees_memory) {
00948 fprintf(fp, " free(");
00949 }
00950 else {
00951 fprintf(fp, " (&%d<%p>) <-- lambda(",
00952 Signature().Return_class()->Id(),
00953 Signature().Returns());
00954 IP_ALIAS_CLASS_MEMBER * const *arg;
00955 for (arg = &(*Signature().fixed_args.begin());
00956 arg != &(*Signature().fixed_args.end());
00957 ++arg)
00958 {
00959 fprintf(fp, "&%d<%p>,",
00960 (*arg)->Alias_class()->Id(), *arg);
00961 }
00962 fprintf(fp, "&%d<%p>",
00963 Signature().remaining_args->Alias_class()->Id(),
00964 Signature().remaining_args);
00965 }
00966 fprintf(fp, ")\n");
00967 break;
00968 case IP_ACR_VALUE_TYPE:
00969 default:
00970 FmtAssert(FALSE, ("Illegal IP_ACR sort in IP_ACR::Print()"));
00971 }
00972 }
00973
00974 void
00975 IP_ALIAS_CLASS_MEMBER::Print(FILE *fp) const
00976 {
00977 if (_kind == ACM_BASE) {
00978 fprintf(fp, "base ID %d", Base_id());
00979 }
00980 else if (_kind == ACM_WN) {
00981 fprintf(fp, "wn");
00982
00983
00984
00985
00986
00987
00988
00989 }
00990 else {
00991 fprintf(fp, "unknown <%p>", this);
00992 }
00993 }
00994
00995 static BOOL
00996 Is_fortran_reference_parm(WN *expr)
00997 {
00998 if (WN_operator(expr) != OPR_PARM) {
00999 return FALSE;
01000 }
01001 return WN_Parm_By_Reference(expr);
01002 }
01003
01004
01005
01006
01007 static BOOL
01008 Opcode_cannot_be_pointer_value(const OPERATOR opr,
01009 const OPCODE opc)
01010 {
01011 switch (opr) {
01012 case OPR_LAND:
01013 case OPR_LIOR:
01014 case OPR_CAND:
01015 case OPR_CIOR:
01016 case OPR_LT:
01017 case OPR_GT:
01018 case OPR_LE:
01019 case OPR_GE:
01020 case OPR_EQ:
01021 case OPR_NE:
01022 return TRUE;
01023 case OPR_MPY:
01024 case OPR_DIV:
01025 case OPR_MOD:
01026 case OPR_ADD:
01027 case OPR_SUB:
01028 case OPR_NEG:
01029 return MTYPE_is_float(OPCODE_rtype(opc));
01030 default:
01031 return FALSE;
01032 }
01033 }
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074 void
01075 IP_ALIAS_CLASSIFICATION::Classify_deref_of_expr(IP_ALIAS_CLASS_MEMBER *lhs_member,
01076 WN *const expr,
01077 BOOL directly_dereferenced)
01078 {
01079 Is_True(lhs_member == NULL ||
01080 lhs_member->Alias_class()->Sort() == IP_ACR_REF_TYPE,
01081 ("Classify_deref_of_expr: lhs must be REF type"));
01082
01083 OPCODE opc = WN_opcode(expr);
01084 OPERATOR opr = OPCODE_operator(opc);
01085
01086 if (_verbose && Tracing()) {
01087 fprintf(TFile, "cdoe: analyzing ");
01088 fdump_wn(TFile, expr);
01089 }
01090 if (OPCODE_is_leaf(opc)) {
01091 if (lhs_member != NULL) {
01092 switch (opr) {
01093 case OPR_LDA:
01094 {
01095 IP_ALIAS_CLASS_REP *acr = Class_of_base_id(WN_base_id(expr));
01096 IP_ALIAS_CLASS_REP *lhs_deref_class;
01097 if (acr->Sort() == IP_ACR_BOTTOM_TYPE) {
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112 Is_True(Code_item(WN_st(expr)),
01113 ("Classify_deref_of_expr: BOTTOM base ID type must "
01114 "be code"));
01115 acr->Add_pending(lhs_member->Alias_class()->Func_class_pointed_to(),
01116 Tracing());
01117 }
01118 else {
01119 if (acr->Sort() == IP_ACR_LAMBDA_TYPE) {
01120 lhs_deref_class = lhs_member->Alias_class()->Func_class_pointed_to();
01121 }
01122 else if (acr->Sort() == IP_ACR_REF_TYPE) {
01123 lhs_deref_class = lhs_member->Alias_class()->Data_class_pointed_to();
01124 }
01125
01126
01127 lhs_deref_class->Join(*acr, Pool(), Tracing());
01128 }
01129 break;
01130 }
01131 case OPR_INTCONST:
01132
01133
01134 if (directly_dereferenced) {
01135
01136
01137
01138
01139 DevWarn("dereference of INTCONST not fully analyzed");
01140 lhs_member->Alias_class()->Join(*Const_addr_class(), Pool(), Tracing());
01141 }
01142 else {
01143
01144
01145 }
01146 break;
01147 case OPR_LDID:
01148 {
01149 IP_ALIAS_CLASS_MEMBER *rhs_member =
01150 Class_of_base_id(WN_base_id(expr))->Representative();
01151 if (rhs_member->Alias_class()->Sort() == IP_ACR_REF_TYPE) {
01152 #ifdef KEY
01153 if (Ty_Table[WN_ty (expr)].kind == KIND_POINTER)
01154 directly_dereferenced = TRUE;
01155 #endif // KEY
01156 if (directly_dereferenced) {
01157
01158
01159
01160 lhs_member->Alias_class()->Data_class_pointed_to()->
01161 Join(*rhs_member->Alias_class()->Data_class_pointed_to(),
01162 Pool(), Tracing());
01163 lhs_member->Alias_class()->Func_class_pointed_to()->
01164 Join(*rhs_member->Alias_class()->Func_class_pointed_to(),
01165 Pool(), Tracing());
01166 }
01167 else {
01168 Conditional_join(lhs_member->Alias_class()->
01169 Data_class_pointed_to(),
01170 rhs_member->Alias_class()->
01171 Data_class_pointed_to());
01172 Conditional_join(lhs_member->Alias_class()->
01173 Func_class_pointed_to(),
01174 rhs_member->Alias_class()->
01175 Func_class_pointed_to());
01176 }
01177 }
01178 else {
01179 Is_True(Code_item(WN_st(expr)),
01180 ("Classify_deref_of_expr: Non-code item must have "
01181 "REF type"));
01182
01183
01184
01185 lhs_member->Alias_class()->Data_class_pointed_to()->
01186 Join(*Class_of_code_misused_as_data(), Pool(), Tracing());
01187 if (_verbose && Tracing()) {
01188 fprintf(TFile, " --- Expression is direct load of code\n");
01189 }
01190 }
01191 if (_verbose && Tracing()) {
01192 fprintf(TFile, " --- After analyzing LDID ");
01193 fdump_wn(TFile, expr);
01194 fprintf(TFile, " lhs is ");
01195 lhs_member->Alias_class()->Print(TFile, Global_data_class());
01196 Print(TFile);
01197 }
01198 break;
01199 }
01200 default:
01201
01202 break;
01203 }
01204 }
01205 }
01206
01207
01208 else if (OPCODE_is_load(opc) ||
01209 Is_fortran_reference_parm(expr)) {
01210
01211
01212
01213
01214
01215
01216
01217
01218 FmtAssert(opr == OPR_ILOAD ||
01219 opr == OPR_MLOAD ||
01220 opr == OPR_PARM,
01221 ("IP_ALIAS_CLASSIFICATION: Indirect load: unexpected opcode"));
01222
01223
01224
01225 IP_ALIAS_CLASS_MEMBER *address_member = New_alias_class_member();
01226 (void) New_alias_class(IP_ACR_REF_TYPE, *address_member);
01227
01228 Classify_deref_of_expr(address_member, WN_kid0(expr), TRUE);
01229
01230 IP_ALIAS_CLASS_REP *address_class = address_member->Alias_class();
01231
01232 IP_ALIAS_CLASS_MEMBER *expr_member = New_alias_class_member(expr);
01233 IP_ALIAS_CLASS_REP *expr_class = address_class->Data_class_pointed_to();
01234
01235 expr_member->Put_in_set(expr_class);
01236
01237 if (expr_class->Sort() == IP_ACR_BOTTOM_TYPE) {
01238 IP_ALIAS_CLASS_REP *expr_deref_data_acr =
01239 New_alias_class(IP_ACR_BOTTOM_TYPE, *New_alias_class_member());
01240 IP_ALIAS_CLASS_REP *expr_deref_code_acr =
01241 New_alias_class(IP_ACR_BOTTOM_TYPE, *New_alias_class_member());
01242
01243 expr_class->
01244 Settype(IP_AC_REF_TYPE_REP(expr_deref_data_acr->Representative(),
01245 expr_deref_code_acr->Representative()),
01246 Pool(), Tracing());
01247 }
01248
01249 if (lhs_member != NULL) {
01250 if (directly_dereferenced) {
01251 Is_True(opr != OPR_PARM, ("Classify_deref_of_expr: Need to "
01252 "add code to handle PARM"));
01253 lhs_member->Alias_class()->Data_class_pointed_to()->
01254 Join(*expr_member->Alias_class()->Data_class_pointed_to(),
01255 Pool(), Tracing());
01256 lhs_member->Alias_class()->Func_class_pointed_to()->
01257 Join(*expr_member->Alias_class()->Func_class_pointed_to(),
01258 Pool(), Tracing());
01259 }
01260 else {
01261 if (opr == OPR_PARM) {
01262
01263 Conditional_join(lhs_member->Alias_class()->Data_class_pointed_to(),
01264 address_member->Alias_class()->Data_class_pointed_to());
01265 Conditional_join(lhs_member->Alias_class()->Func_class_pointed_to(),
01266 address_member->Alias_class()->Func_class_pointed_to());
01267 }
01268 else {
01269
01270
01271 Conditional_join(lhs_member->Alias_class()->Data_class_pointed_to(),
01272 expr_member->Alias_class()->Data_class_pointed_to());
01273 Conditional_join(lhs_member->Alias_class()->Func_class_pointed_to(),
01274 expr_member->Alias_class()->Func_class_pointed_to());
01275 }
01276 }
01277 }
01278
01279 WN_MAP_Set(Indir_classification_map(), expr, (void *) expr_member);
01280
01281 if (_verbose && Tracing()) {
01282 fprintf(TFile, " --- After analyzing expression ");
01283 fdump_wn(TFile, expr);
01284 fprintf(TFile, " expr_class is ");
01285 expr_class->Print(TFile, Global_data_class());
01286 Print(TFile);
01287 #if Is_True_On
01288 print_table();
01289 #endif
01290 }
01291 }
01292 else if (opr == OPR_ARRAY) {
01293 for (INT i = 1; i < WN_kid_count(expr); i++) {
01294 Classify_deref_of_expr(NULL, WN_kid(expr, i), FALSE);
01295 }
01296 if (_verbose && Tracing()) {
01297 fprintf(TFile, " --- After analyzing expression ");
01298 fdump_wn(TFile, expr);
01299 Print(TFile);
01300 }
01301 Classify_deref_of_expr(lhs_member, WN_kid0(expr), directly_dereferenced);
01302 }
01303 else if (opr == OPR_ALLOCA) {
01304 for (INT i = 0; i < WN_kid_count(expr); i++) {
01305 Classify_deref_of_expr(NULL, WN_kid(expr, i), FALSE);
01306 }
01307 if (_verbose && Tracing()) {
01308 fprintf(TFile, " --- After analyzing ALLOCA kids ");
01309 fdump_wn(TFile, expr);
01310 Print(TFile);
01311 }
01312 if (lhs_member != NULL) {
01313
01314
01315 IP_ALIAS_CLASS_REP *lhs_deref_class =
01316 lhs_member->Alias_class()->Data_class_pointed_to();
01317 if (lhs_deref_class->Sort() == IP_ACR_BOTTOM_TYPE) {
01318 IP_ALIAS_CLASS_REP *alloca_mem_data_ptr_acr =
01319 New_alias_class(IP_ACR_BOTTOM_TYPE, *New_alias_class_member());
01320 IP_ALIAS_CLASS_REP *alloca_mem_code_ptr_acr =
01321 New_alias_class(IP_ACR_BOTTOM_TYPE, *New_alias_class_member());
01322 lhs_deref_class->
01323 Settype(IP_AC_REF_TYPE_REP(alloca_mem_data_ptr_acr->Representative(),
01324 alloca_mem_code_ptr_acr->Representative()),
01325 Pool(), Tracing());
01326 }
01327 }
01328 else {
01329 if (Opt_Level >= 2)
01330 Fail_FmtAssertion("Classify_deref_of_expr: Dangling ALLOCA is illegal");
01331 else
01332 DevWarn("Classify_deref_of_expr: Dangling ALLOCA is illegal");
01333 }
01334 }
01335 else {
01336
01337
01338
01339
01340
01341 IP_ALIAS_CLASS_MEMBER *expr_member;
01342
01343
01344
01345 if (Opcode_cannot_be_pointer_value(opr, opc)) {
01346 expr_member = NULL;
01347 }
01348 else {
01349 expr_member = New_alias_class_member(expr);
01350 (void) New_alias_class(IP_ACR_REF_TYPE, *expr_member);
01351 }
01352 for (INT i = 0; i < WN_kid_count(expr); i++) {
01353 Classify_deref_of_expr(expr_member, WN_kid(expr, i), FALSE);
01354 }
01355 if (expr_member != NULL &&
01356 lhs_member != NULL) {
01357 if (directly_dereferenced) {
01358 lhs_member->Alias_class()->Data_class_pointed_to()->
01359 Join(*expr_member->Alias_class()->Data_class_pointed_to(),
01360 Pool(), Tracing());
01361 lhs_member->Alias_class()->Func_class_pointed_to()->
01362 Join(*expr_member->Alias_class()->Func_class_pointed_to(),
01363 Pool(), Tracing());
01364 }
01365 else {
01366 Conditional_join(lhs_member->Alias_class()->Data_class_pointed_to(),
01367 expr_member->Alias_class()->Data_class_pointed_to());
01368 Conditional_join(lhs_member->Alias_class()->Func_class_pointed_to(),
01369 expr_member->Alias_class()->Func_class_pointed_to());
01370 }
01371 }
01372 if (_verbose && Tracing()) {
01373 fprintf(TFile, " --- After analyzing expression ");
01374 fdump_wn(TFile, expr);
01375 fprintf(TFile, " local lhs is ");
01376 if (lhs_member != NULL) {
01377 lhs_member->Alias_class()->Print(TFile, Global_data_class());
01378 }
01379 else {
01380 fprintf(TFile, "<NULL>\n");
01381 }
01382 Print(TFile);
01383 }
01384 }
01385 }
01386
01387 IP_ALIAS_CLASS_MEMBER *
01388 IP_ALIAS_CLASSIFICATION::Classify_lhs_of_store(WN *const stmt_or_idname)
01389 {
01390 OPERATOR opr = WN_operator(stmt_or_idname);
01391
01392 if (opr == OPR_STID || opr == OPR_IDNAME) {
01393 return Class_of_base_id(WN_base_id(stmt_or_idname))->Representative();
01394 }
01395 else if (opr == OPR_ISTORE || opr == OPR_MSTORE) {
01396 IP_ALIAS_CLASS_MEMBER *lhs_address_member =
01397 New_alias_class_member(WN_kid1(stmt_or_idname));
01398 (void) New_alias_class(IP_ACR_REF_TYPE, *lhs_address_member);
01399 Classify_deref_of_expr(lhs_address_member, WN_kid1(stmt_or_idname), TRUE);
01400 IP_ALIAS_CLASS_MEMBER *lhs_member =
01401 lhs_address_member->Alias_class()->Ref().Data_member();
01402 if (Tracing()) {
01403 fprintf(TFile, "Setting ISTORE Indir map to %p\n",
01404 lhs_member->Alias_class());
01405 }
01406 WN_MAP_Set(Indir_classification_map(), stmt_or_idname, lhs_member);
01407
01408
01409 if (lhs_member->Alias_class()->Sort() == IP_ACR_BOTTOM_TYPE) {
01410 IP_ALIAS_CLASS_REP *lhs_deref_data_acr =
01411 New_alias_class(IP_ACR_BOTTOM_TYPE, *New_alias_class_member());
01412 IP_ALIAS_CLASS_REP *lhs_deref_code_acr =
01413 New_alias_class(IP_ACR_BOTTOM_TYPE, *New_alias_class_member());
01414
01415 lhs_member->Alias_class()->
01416 Settype(IP_AC_REF_TYPE_REP(lhs_deref_data_acr->Representative(),
01417 lhs_deref_code_acr->Representative()),
01418 Pool(), Tracing());
01419 }
01420 return lhs_member;
01421 }
01422 else {
01423 FmtAssert(FALSE, ("AC::Classify_lhs_of_store: Other stores "
01424 "not handled"));
01425 return NULL;
01426 }
01427 }
01428
01429 WN *
01430 IP_ALIAS_CLASSIFICATION::Handle_assignment(WN *const stmt)
01431 {
01432 IP_ALIAS_CLASS_MEMBER *lhs_member = Classify_lhs_of_store(stmt);
01433
01434
01435 WN *rhs = WN_kid0(stmt);
01436
01437 Classify_deref_of_expr(lhs_member, rhs, FALSE);
01438
01439 if (WN_operator(stmt) == OPR_MSTORE) {
01440
01441 Classify_deref_of_expr(NULL, WN_kid2(stmt), FALSE);
01442 }
01443
01444
01445
01446
01447 if (Stmt_stores_return_value_to_caller(stmt)) {
01448 ST_IDX pu_st_idx = ST_st_idx(Scope_tab[CURRENT_SYMTAB].st);
01449
01450
01451
01452 Is_True(ST_base_idx(St_Table[pu_st_idx]) == pu_st_idx,
01453 ("Handle_assignment: Current PU must not have based address"));
01454 Is_True(ST_IDX_level(pu_st_idx) == GLOBAL_SYMTAB,
01455 ("Handle_assignment: PU must be global symbol"));
01456 IP_ALIAS_CLASS_REP *current_func_acr =
01457 _base_id_map[Base_id(&St_Table[pu_st_idx],
01458 (INT64) 0)]->Base_member().Alias_class();
01459 Conditional_join(current_func_acr->Signature().Return_class()->
01460 Data_class_pointed_to(),
01461 lhs_member->Alias_class()->Data_class_pointed_to());
01462 Conditional_join(current_func_acr->Signature().Return_class()->
01463 Func_class_pointed_to(),
01464 lhs_member->Alias_class()->Func_class_pointed_to());
01465 }
01466
01467 if (_verbose && Tracing()) {
01468 fprintf(TFile, " after handling assignment:\n");
01469 if (WN_operator(stmt) == OPR_ISTORE ||
01470 WN_operator(stmt) == OPR_MSTORE) {
01471 fprintf(TFile, " (M/I)STORE placed in ");
01472 ((IP_ALIAS_CLASS_MEMBER *) WN_MAP_Get(Indir_classification_map(),
01473 stmt))->
01474 Alias_class()->Print(TFile, Global_data_class());
01475 }
01476 else if (WN_operator(stmt) == OPR_STID) {
01477 fprintf(TFile, " STID placed in ");
01478 Class_of_base_id(WN_base_id(stmt))->Print(TFile, Global_data_class());
01479 }
01480 Print(TFile);
01481 #if Is_True_On
01482 print_table();
01483 #endif
01484 }
01485
01486 return WN_next(stmt);
01487 }
01488
01489 WN *
01490 IP_ALIAS_CLASSIFICATION::Handle_return_val(WN *const stmt)
01491 {
01492 ST *pu_st = Scope_tab[CURRENT_SYMTAB].st;
01493 IP_ALIAS_CLASS_REP *pu_acr =
01494 _base_id_map[Base_id(pu_st, 0ll)]->Base_member().Alias_class();
01495 IP_ALIAS_CLASS_MEMBER *return_ac_member = pu_acr->Signature().Returns();
01496
01497 Classify_deref_of_expr(return_ac_member, WN_kid0(stmt), FALSE);
01498
01499 if (_verbose && Tracing()) {
01500 fprintf(TFile, " after handling return value:\n");
01501 fprintf(TFile, " RETURN_VAL placed in ");
01502 pu_acr->Signature().Return_class()->Print(TFile, Global_data_class());
01503 Print(TFile);
01504 #if Is_True_On
01505 print_table();
01506 #endif
01507 }
01508
01509 return WN_next(stmt);
01510 }
01511
01512 BOOL
01513 IP_ALIAS_CLASSIFICATION::Stmt_stores_return_value_from_callee(const WN *const stmt)
01514 {
01515 WN *rhs = WN_kid0(stmt);
01516
01517 return (OPCODE_is_store(WN_opcode(stmt)) &&
01518 (WN_operator(rhs) == OPR_LDID) &&
01519 (ST_sclass(WN_st(rhs)) == SCLASS_REG) &&
01520 Preg_Is_Dedicated(WN_offset(rhs)));
01521 }
01522
01523 BOOL
01524 IP_ALIAS_CLASSIFICATION::Stmt_stores_return_value_to_caller(const WN *const stmt)
01525 {
01526
01527
01528 return ((WN_operator(stmt) == OPR_STID) &&
01529 (ST_sclass(WN_st(stmt)) == SCLASS_REG) &&
01530 Preg_Is_Dedicated(WN_offset(stmt)));
01531 }
01532
01533
01534 BOOL
01535 IP_ALIAS_CLASSIFICATION::Uses_no_return_value(const WN *const stmt)
01536 {
01537 return TRUE;
01538 }
01539
01540 BOOL
01541 IP_ALIAS_CLASSIFICATION::Callee_saves_no_parms(const WN *const call_wn)
01542 {
01543 if (WN_Call_Never_Return(call_wn)) {
01544 DevWarn("IP_ALIAS_CLASSIFICATION: I see a call that never returns");
01545 return TRUE;
01546 }
01547 else if (Callee_frees_memory(call_wn)) {
01548 return TRUE;
01549 }
01550 else {
01551 return Callee_returns_new_memory(call_wn);
01552 }
01553 }
01554
01555 BOOL
01556 IP_ALIAS_CLASSIFICATION::Callee_returns_new_memory(const WN *const call_wn)
01557 {
01558 #ifndef KEY
01559 return WN_Call_Does_Mem_Alloc(call_wn);
01560 #else
01561 if (WN_Call_Does_Mem_Alloc(call_wn))
01562 return TRUE;
01563 if (WN_operator(call_wn) == OPR_CALL) {
01564 const ST *const st = WN_st(call_wn);
01565
01566
01567
01568 if ((strcmp("malloc", ST_name(st)) == 0) ||
01569 (strcmp("alloca", ST_name(st)) == 0) ||
01570 (strcmp("calloc", ST_name(st)) == 0) ||
01571 (strcmp("_F90_ALLOCATE", ST_name(st)) == 0)) {
01572 return TRUE;
01573 }
01574 }
01575 else if (WN_operator(call_wn) == OPR_INTRINSIC_CALL) {
01576 if ((WN_intrinsic(call_wn) == INTRN_U4I4ALLOCA) ||
01577 (WN_intrinsic(call_wn) == INTRN_U8I8ALLOCA) ||
01578 (WN_intrinsic(call_wn) == INTRN_U4I4MALLOC) ||
01579 (WN_intrinsic(call_wn) == INTRN_U8I8MALLOC)) {
01580 return TRUE;
01581 }
01582 }
01583 return FALSE;
01584 #endif
01585 }
01586
01587
01588 BOOL
01589 IP_ALIAS_CLASSIFICATION::Callee_returns_new_memory(const ST *const st)
01590 {
01591 #ifdef KEY
01592
01593
01594 if ((strcmp("malloc", ST_name(st)) == 0) ||
01595 (strcmp("alloca", ST_name(st)) == 0) ||
01596 (strcmp("calloc", ST_name(st)) == 0) ||
01597 (strcmp("_F90_ALLOCATE", ST_name(st)) == 0)) {
01598 return TRUE;
01599 }
01600 else {
01601 return FALSE;
01602 }
01603 #else
01604 return FALSE;
01605 #endif
01606 }
01607
01608 BOOL
01609 IP_ALIAS_CLASSIFICATION::Callee_frees_memory(const WN *const call_wn)
01610 {
01611 return WN_Call_Does_Mem_Free(call_wn);
01612 }
01613
01614
01615 BOOL
01616 IP_ALIAS_CLASSIFICATION::Callee_frees_memory(const ST *const st)
01617 {
01618 return FALSE;
01619 }
01620
01621 IP_ALIAS_CLASS_MEMBER *
01622 IP_ALIAS_CLASSIFICATION::Incorporate_call_and_parm_flags( IP_ALIAS_CLASS_MEMBER * func_member,
01623 const WN *const call_wn)
01624 {
01625 if (WN_Call_Pure(call_wn)) {
01626
01627
01628
01629
01630
01631 OPERATOR opr = WN_operator(call_wn);
01632 UINT n_parms;
01633
01634 if (opr == OPR_ICALL) {
01635 n_parms = WN_kid_count(call_wn) - 1;
01636 }
01637 else {
01638 n_parms = WN_kid_count(call_wn);
01639 }
01640
01641 func_member = New_alias_class_member(call_wn);
01642 IP_ALIAS_CLASS_REP *pure_func_acr =
01643 New_alias_class(IP_ACR_LAMBDA_TYPE, *func_member);
01644 IP_AC_LAMBDA_TYPE_REP &pure_func_desc = pure_func_acr->Signature();
01645
01646 IP_ALIAS_CLASS_MEMBER *const return_member = New_alias_class_member();
01647 IP_ALIAS_CLASS_REP *const return_class =
01648 New_alias_class(IP_ACR_REF_TYPE, *return_member);
01649 pure_func_desc.Returns() = return_member;
01650
01651 for (UINT i = 1; i < n_parms; ++i) {
01652 IP_ALIAS_CLASS_MEMBER *dummy_arg = New_alias_class_member();
01653 IP_ALIAS_CLASS_REP *arg_class =
01654 New_alias_class(IP_ACR_REF_TYPE, *dummy_arg);
01655 arg_class->Add_pending(return_class, Tracing());
01656 pure_func_desc.fixed_args.push_back(dummy_arg);
01657 }
01658 IP_ALIAS_CLASS_MEMBER *dummy_arg = New_alias_class_member();
01659 IP_ALIAS_CLASS_REP *arg_class =
01660 New_alias_class(IP_ACR_REF_TYPE, *dummy_arg);
01661 arg_class->Add_pending(return_class, Tracing());
01662 pure_func_desc.remaining_args = dummy_arg;
01663 pure_func_desc.arity_established = TRUE;
01664 return func_member;
01665 }
01666 BOOL callee_returns_new_memory = Callee_returns_new_memory(call_wn);
01667 BOOL callee_frees_memory = Callee_frees_memory(call_wn);
01668
01669 BOOL require_new_func_desc = (callee_returns_new_memory ||
01670 callee_frees_memory);
01671 if (require_new_func_desc) {
01672 IP_ALIAS_CLASS_MEMBER *new_func_member = New_alias_class_member(call_wn);
01673 IP_ALIAS_CLASS_REP *func_acr =
01674 New_alias_class(IP_ACR_LAMBDA_TYPE, *new_func_member);
01675 IP_AC_LAMBDA_TYPE_REP &new_func_desc = func_acr->Signature();
01676 if (callee_returns_new_memory) {
01677 new_func_desc.returns_new_memory = TRUE;
01678 new_func_desc.Set_arities(0, 1, this);
01679 }
01680 else {
01681 new_func_desc = func_member->Alias_class()->Signature();
01682 }
01683 if (callee_frees_memory) {
01684 new_func_desc.frees_memory = TRUE;
01685 }
01686 return new_func_member;
01687 }
01688 else {
01689 return func_member;
01690 }
01691 }
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701 WN *
01702 IP_ALIAS_CLASSIFICATION::Handle_call(WN *const call_wn)
01703 {
01704 OPCODE opc = WN_opcode(call_wn);
01705 OPERATOR opr = OPCODE_operator(opc);
01706
01707 IP_ALIAS_CLASS_MEMBER *callee_member;
01708 UINT n_parms;
01709
01710 if (opr == OPR_ICALL) {
01711 n_parms = WN_kid_count(call_wn) - 1;
01712 IP_ALIAS_CLASS_MEMBER *callee_address_member =
01713 New_alias_class_member(WN_kid(call_wn,
01714 WN_kid_count(call_wn) - 1));
01715 (void) New_alias_class(IP_ACR_REF_TYPE, *callee_address_member);
01716 Classify_deref_of_expr(callee_address_member,
01717 WN_kid(call_wn,
01718 WN_kid_count(call_wn) - 1),
01719 TRUE);
01720 callee_member =
01721 callee_address_member->Alias_class()->Ref().Code_member();
01722 }
01723 else {
01724 n_parms = WN_kid_count(call_wn);
01725 if (opr == OPR_CALL) {
01726
01727
01728 ST_IDX callee_st_idx = WN_st_idx(call_wn);
01729 #ifndef KEY // Bug 8433
01730 Is_True(ST_base_idx(St_Table[callee_st_idx]) == callee_st_idx,
01731 ("AC:Handle_call: Called routine must not have based address"));
01732 #endif
01733 callee_member = Class_of_base_id(WN_base_id(call_wn))->Representative();
01734 }
01735 else {
01736 Is_True(opr == OPR_INTRINSIC_CALL,
01737 ("AC::Handle_call: Can handle only calls"));
01738
01739
01740
01741
01742
01743
01744
01745 callee_member = _member_of_global_func_class;
01746 }
01747 }
01748
01749 IP_ALIAS_CLASS_REP *callee_class = callee_member->Alias_class();
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766 Is_True(callee_class->Sort() == IP_ACR_BOTTOM_TYPE ||
01767 callee_class->Sort() == IP_ACR_LAMBDA_TYPE,
01768 ("Handle_call: illegal callee class type"));
01769
01770 if (callee_class->Sort() == IP_ACR_BOTTOM_TYPE) {
01771 callee_class->_type_info._sort = IP_ACR_LAMBDA_TYPE;
01772 callee_class->_type_info._signature =
01773 CXX_NEW(IP_AC_LAMBDA_TYPE_REP(Pool()), Pool());
01774 callee_class->Signature().Set_arities(n_parms, 1, this);
01775 callee_class->Process_pending(callee_member, Pool(), Tracing());
01776 callee_class = callee_member->Alias_class();
01777 }
01778
01779 Is_True(callee_class->Signature().arity_established,
01780 ("Handle_call: Arity must be established at LAMBDA time"));
01781
01782
01783
01784
01785 callee_member =
01786 Incorporate_call_and_parm_flags(callee_member, call_wn);
01787
01788
01789
01790
01791
01792 for (UINT i = 0; i < n_parms; ++i) {
01793 WN *parm_wn = WN_kid(call_wn, i);
01794 Is_True(WN_operator(parm_wn) == OPR_PARM,
01795 ("AC::Handle_call: Can't handle non-PARM parameter"));
01796
01797 IP_ALIAS_CLASS_MEMBER *formal_member;
01798 if (callee_member->Alias_class()->Signature().returns_new_memory ||
01799 callee_member->Alias_class()->Signature().frees_memory) {
01800
01801
01802
01803 formal_member = NULL;
01804 }
01805 else {
01806 formal_member =
01807 callee_member->Alias_class()->Signature().Argument_member(i);
01808 }
01809
01810 Classify_deref_of_expr(formal_member, parm_wn, FALSE);
01811 }
01812
01813 IP_ALIAS_CLASS_MEMBER *return_class_member;
01814 if (callee_member->Alias_class()->Signature().returns_new_memory) {
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826 return_class_member =
01827 callee_member->Alias_class()->
01828 Signature().Memory_allocator_return_class_member(this);
01829 }
01830 else {
01831 return_class_member = callee_member->Alias_class()->Signature().Returns();
01832 }
01833
01834 WN *stmt = WN_next(call_wn);
01835 while (stmt != NULL && Stmt_stores_return_value_from_callee(stmt)) {
01836 if (Tracing()) {
01837 fprintf(TFile, "Store of return value:\n");
01838 fdump_tree(TFile, stmt);
01839 }
01840 IP_ALIAS_CLASS_MEMBER *lhs_member = Classify_lhs_of_store(stmt);;
01841 IP_ALIAS_CLASS_MEMBER *rhs_member = return_class_member;
01842 Conditional_join(lhs_member->Alias_class()->Data_class_pointed_to(),
01843 rhs_member->Alias_class()->Data_class_pointed_to());
01844 Conditional_join(lhs_member->Alias_class()->Func_class_pointed_to(),
01845 rhs_member->Alias_class()->Func_class_pointed_to());
01846 stmt = WN_next(stmt);
01847 }
01848 Is_True(Uses_no_return_value(stmt),
01849 ("IP_ALIAS_CLASSIFICATION: General use of return value illegal"));
01850
01851 if (_verbose && Tracing()) {
01852 fprintf(TFile, " after handling call:\n");
01853 Print(TFile);
01854 #if Is_True_On
01855 print_table();
01856 #endif
01857 }
01858 return stmt;
01859 }
01860
01861 void
01862 IP_ALIAS_CLASSIFICATION::Handle_function_definition(WN *entry_wn)
01863 {
01864 FmtAssert(WN_opcode(entry_wn) == OPC_FUNC_ENTRY,
01865 ("IP_ALIAS_CLASSIFICATION: FUNC_ENTRY expected"));
01866
01867
01868
01869
01870 IP_ALIAS_CLASS_REP *func_class = Class_of_base_id(WN_base_id(entry_wn));
01871
01872 Is_True(func_class->Sort() == IP_ACR_BOTTOM_TYPE ||
01873 func_class->Sort() == IP_ACR_LAMBDA_TYPE,
01874 ("Handle_call: illegal function class type"));
01875
01876 IP_ALIAS_CLASS_MEMBER *func_class_member = func_class->Representative();
01877
01878 if (func_class->Sort() == IP_ACR_BOTTOM_TYPE) {
01879 func_class->_type_info._sort = IP_ACR_LAMBDA_TYPE;
01880 func_class->_type_info._signature =
01881 CXX_NEW(IP_AC_LAMBDA_TYPE_REP(Pool()), Pool());
01882 func_class->Signature().Set_arities(WN_kid_count(entry_wn) - 3,
01883 1, this);
01884 func_class->Process_pending(func_class_member, Pool(), Tracing());
01885 func_class = func_class_member->Alias_class();
01886 }
01887
01888 Is_True(func_class->Signature().arity_established,
01889 ("Handle_function_definition: Arity must be established at "
01890 "LAMBDA time"));
01891
01892 for (UINT i = 0; i < WN_kid_count(entry_wn) - 3; ++i) {
01893 WN *kid_i = WN_kid(entry_wn, i);
01894 FmtAssert(WN_opcode(kid_i) == OPC_IDNAME,
01895 ("IP_ALIAS_CLASSIFICATION: Parameter IDNAME expected"));
01896 IP_ALIAS_CLASS_MEMBER *lhs_member = Classify_lhs_of_store(kid_i);
01897 IP_ALIAS_CLASS_MEMBER *rhs_member =
01898 func_class_member->Alias_class()->Signature().Argument_member(i);
01899 if (ST_sclass(WN_st(kid_i)) == SCLASS_FORMAL_REF) {
01900
01901
01902
01903
01904
01905
01906
01907
01908 Is_True(lhs_member->Alias_class()->Sort() == IP_ACR_REF_TYPE,
01909 ("Handle_func_entry: FORMAL_REF IDNAME kid must have "
01910 "REF type"));
01911 Conditional_join(lhs_member->Alias_class(),
01912 rhs_member->Alias_class()->Data_class_pointed_to());
01913 }
01914 else {
01915
01916
01917
01918
01919 Conditional_join(lhs_member->Alias_class()->Data_class_pointed_to(),
01920 rhs_member->Alias_class()->Data_class_pointed_to());
01921 Conditional_join(lhs_member->Alias_class()->Func_class_pointed_to(),
01922 rhs_member->Alias_class()->Func_class_pointed_to());
01923 }
01924 }
01925
01926 if (Tracing()) {
01927 fprintf(TFile, " after handling function arguments:\n");
01928 Print(TFile);
01929 #if Is_True_On
01930 print_table();
01931 #endif
01932 }
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944 WN *body_wn = WN_kid(entry_wn, WN_kid_count(entry_wn) - 1);
01945 Classify_wn_and_kids(body_wn);
01946 }
01947
01948 void
01949 IP_ALIAS_CLASSIFICATION::Finalize_ac_map_wn(WN *wn)
01950 {
01951 OPCODE opc = WN_opcode(wn);
01952 OPERATOR opr = OPCODE_operator(opc);
01953
01954 if (Tracing()) {
01955 fprintf(TFile, "Finalizing : ");
01956 fdump_wn(TFile, wn);
01957 fflush(TFile);
01958 }
01959
01960 if (OPCODE_is_call(opc)) {
01961
01962 }
01963 else if (OPCODE_is_load(opc) ||
01964 OPCODE_is_store(opc) ||
01965 Is_fortran_reference_parm(wn) ||
01966 (opr == OPR_LDA &&
01967 Is_LDA_of_variable(wn))) {
01968 if (Tracing()) {
01969 fprintf(TFile, " placed in ");
01970 }
01971 if (opr == OPR_LDID || opr == OPR_STID || opr == OPR_LDA
01972 #ifdef KEY
01973 || opr == OPR_LDBITS
01974 #endif
01975 ) {
01976
01977 IDTYPE class_id = Class_of_base_id(WN_base_id(wn))->Id();
01978 WN_MAP32_Set(Memop_classification_map(), wn, class_id);
01979 if (Tracing()) {
01980 Class_of_base_id(WN_base_id(wn))->Print(TFile, Global_data_class());
01981 }
01982 }
01983 else {
01984
01985
01986 IP_ALIAS_CLASS_MEMBER *acm =
01987 (IP_ALIAS_CLASS_MEMBER *) WN_MAP_Get(Indir_classification_map(), wn);
01988 if (Tracing()) {
01989 fprintf(TFile, "Got %p from indir map %u on\n", acm,
01990 Indir_classification_map());
01991 fdump_tree(TFile, wn);
01992 }
01993 IP_ALIAS_CLASS_REP *acr = acm->Alias_class();
01994
01995 if (Tracing()) {
01996 acr->Print(TFile, Global_data_class());
01997 }
01998
01999 WN_MAP32_Set(Memop_classification_map(), wn, acr->Id());
02000 }
02001 }
02002 }
02003
02004 void
02005 IP_ALIAS_CLASSIFICATION::Finalize_ac_map(WN *const wn)
02006 {
02007 OPCODE opc = WN_opcode(wn);
02008 OPERATOR opr = OPCODE_operator(opc);
02009
02010 if (opc == OPC_BLOCK) {
02011 for (WN *wn2 = WN_first(wn); wn2 != NULL; wn2 = WN_next(wn2)) {
02012 Finalize_ac_map(wn2);
02013 }
02014 }
02015 else if (!OPCODE_is_black_box(opc)) {
02016 INT rhs_idx;
02017 if (OPCODE_is_store(opc)) {
02018 rhs_idx = 0;
02019 }
02020 else {
02021 rhs_idx = -1;
02022 }
02023 for (INT i = 0; i < WN_kid_count(wn); i++) {
02024
02025
02026 if (!OPCODE_is_store(opc) ||
02027 !Stmt_stores_return_value_from_callee(wn) ||
02028 i != rhs_idx) {
02029 Finalize_ac_map(WN_kid(wn, i));
02030 }
02031 }
02032 Finalize_ac_map_wn(wn);
02033 }
02034 }
02035
02036 IDTYPE
02037 IP_ALIAS_CLASSIFICATION::Alias_class(IDTYPE base_id) const
02038 {
02039 if (_memops_classified) {
02040 return Class_of_base_id(base_id)->Id();
02041 }
02042 else {
02043 return PESSIMISTIC_AC_ID;
02044 }
02045 }
02046
02047 void
02048 IP_ALIAS_CLASSIFICATION::Merge_initial_value_classes(IDTYPE lhs_base_id,
02049 INITV_IDX val)
02050 {
02051 while (val) {
02052 const INITV &initv = Initv_Table[val];
02053 if (INITV_kind(initv) == INITVKIND_SYMOFF) {
02054 ST_IDX rhs_base_st_idx;
02055 INT64 rhs_base_offset = (INT64) INITV_ofst(initv);
02056 Find_declared_base_and_offset(INITV_st(initv),
02057 rhs_base_st_idx,
02058 rhs_base_offset);
02059 ST *rhs_base_st = &St_Table[rhs_base_st_idx];
02060 IDTYPE rhs_id = Base_id(rhs_base_st, rhs_base_offset);
02061
02062 IP_ALIAS_CLASS_MEMBER *lhs_deref_member;
02063 if (Data_item(rhs_base_st)) {
02064 lhs_deref_member =
02065 Class_of_base_id(lhs_base_id)->Ref().Data_member();
02066 }
02067 else {
02068 Is_True(Code_item(rhs_base_st),
02069 ("Non-data item must be code item"));
02070 lhs_deref_member =
02071 Class_of_base_id(lhs_base_id)->Ref().Code_member();
02072 }
02073 lhs_deref_member->Alias_class()->Join(*Class_of_base_id(rhs_id),
02074 Pool(), Tracing());
02075 }
02076 else if (INITV_kind(initv) == INITVKIND_BLOCK) {
02077 Merge_initial_value_classes(lhs_base_id, INITV_blk(initv));
02078 }
02079 val = INITV_next(initv);
02080 }
02081 }
02082
02083 BOOL
02084 IP_ALIAS_CLASSIFICATION::Can_be_referred_to_by_code(const ST_IDX st_idx)
02085 {
02086 ST *st = &St_Table[st_idx];
02087
02088
02089
02090
02091
02092
02093
02094 return ((ST_sclass(st) != SCLASS_EH_REGION_SUPP) &&
02095 (ST_sclass(st) != SCLASS_CPLINIT));
02096 }
02097
02098 void
02099 IP_ALIAS_CLASSIFICATION::Classify_inito(const INITO *const inito)
02100 {
02101 ST_IDX inito_st_idx = INITO_st_idx(*inito);
02102 if (Can_be_referred_to_by_code(inito_st_idx)) {
02103 ST_IDX base_st_idx;
02104 INT64 base_offset = (INT64) 0;
02105 Find_declared_base_and_offset(inito_st_idx,
02106 base_st_idx,
02107 base_offset);
02108 IDTYPE id = Base_id(&St_Table[base_st_idx], base_offset);
02109
02110 Merge_initial_value_classes(id,
02111 INITO_val(*inito));
02112 }
02113 }
02114
02115 struct CLASSIFY_INITIALIZED_DATA {
02116 IP_ALIAS_CLASSIFICATION *const _ip_alias_classification;
02117
02118 CLASSIFY_INITIALIZED_DATA(IP_ALIAS_CLASSIFICATION *const ip_alias_classification) :
02119 _ip_alias_classification(ip_alias_classification)
02120 { }
02121
02122 void operator() (UINT32, const INITO *const inito) const {
02123 _ip_alias_classification->Classify_inito(inito);
02124 }
02125 };
02126
02127
02128
02129
02130 void
02131 IP_ALIAS_CLASSIFICATION::Init_maps(void)
02132 {
02133 _st_id_to_base_id_map.Init();
02134 Preg_id_to_base_id_map().Init();
02135 _maps_initialized = TRUE;
02136 }
02137
02138 void
02139 IP_ALIAS_CLASSIFICATION::Classify_initialized_data(INITO_TAB *inito_tab)
02140 {
02141 For_all(*inito_tab, CLASSIFY_INITIALIZED_DATA(this));
02142 }
02143
02144 void
02145 IP_ALIAS_CLASSIFICATION::Classify_memops(WN *entry_wn)
02146 {
02147 if (Tracing()) {
02148 fprintf(TFile, "%sBeginning alias classification\n%s",
02149 DBar, DBar);
02150 fdump_tree(TFile, entry_wn);
02151 }
02152
02153 if (Tracing()) {
02154 fprintf(TFile, "----------\nBefore program analysis:\n");
02155 Print(TFile);
02156 fprintf(TFile, "----------\n");
02157 }
02158
02159
02160
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170 if (Tracing()) {
02171 fprintf(TFile, "Current_Map_Tab == %p\n", Current_Map_Tab);
02172 fprintf(TFile, "indir map is %u\n", _indir_classification_map);
02173 }
02174
02175 Handle_function_definition(entry_wn);
02176 }
02177
02178 void
02179 IP_ALIAS_CLASSIFICATION::Finalize_memops(WN *entry_wn)
02180 {
02181 if (Tracing()) {
02182 fprintf(TFile, "----------\nAfter program analysis:\n");
02183 Print(TFile);
02184 fprintf(TFile, "----------\n");
02185 }
02186
02187 Finalize_ac_map(entry_wn);
02188 _memops_classified = TRUE;
02189 }
02190
02191 IDTYPE
02192 IP_ALIAS_CLASSIFICATION::Alias_class(const WN *wn) const
02193 {
02194 Is_True(OPCODE_is_store(WN_opcode(wn)) ||
02195 OPCODE_is_load(WN_opcode(wn)) ||
02196 WN_operator(wn) == OPR_PARM,
02197 ("IP_ALIAS_CLASSIFICATION: WN must be memop"));
02198
02199 if (_memops_classified) {
02200 FmtAssert(_mem_pool_valid,
02201 ("IP_ALIAS_CLASSIFICATION: Our memory is gone."));
02202 return WN_MAP32_Get(Memop_classification_map(), wn);
02203 }
02204 else {
02205 return PESSIMISTIC_AC_ID;
02206 }
02207 }
02208
02209 void
02210 IP_ALIAS_CLASSIFICATION::Release_resources(void)
02211 {
02212 #if 0
02213 if (Tracing()) {
02214 (void) fprintf(TFile,
02215 "Freeing IP alias class resources; "
02216 "recycled %lu ACR's of %lu\n",
02217 IP_ALIAS_CLASS_REP::_recycled_acr_nodes,
02218 IP_ALIAS_CLASS_REP::_last_id_used);
02219 }
02220 #else
02221 DevWarn("Recycled %u of %d ACR's",
02222 IP_ALIAS_CLASS_REP::_recycled_acr_nodes,
02223 IP_ALIAS_CLASS_REP::_last_id_used);
02224 #endif
02225
02226 _base_id_map.Free_array();
02227 if (_maps_initialized) {
02228 (&_preg_id_to_base_id_map)->~ID_MAP();
02229 (&_st_id_to_base_id_map)->~ID_MAP();
02230 }
02231
02232 MEM_POOL_Pop(_pool);
02233 _mem_pool_valid = FALSE;
02234 _pool = NULL;
02235 }
02236
02237 void
02238 IP_ALIAS_CLASSIFICATION::Print(FILE *fp) const
02239 {
02240
02241
02242
02243 fprintf(fp, "Global data class: ");
02244 Global_data_class()->Print(fp);
02245 fprintf(fp, "Global code class: ");
02246 Global_func_class()->Print(fp);
02247 for (INT i = 1; i <= _base_id_map.Lastidx(); i++) {
02248 fprintf(fp, "Class containing base ID %d is ", i);
02249 _base_id_map[i]->Base_member().Alias_class()->Print(fp,
02250 Global_data_class());
02251 }
02252 }