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 #ifdef USE_PCH
00052 #include "opt_pch.h"
00053 #endif // USE_PCH
00054 #pragma hdrstop
00055
00056
00057 #ifdef _KEEP_RCS_ID
00058 #define opt_mu_chi_CXX "opt_mu_chi.cxx"
00059 static char *rcs_id = opt_mu_chi_CXX"$Revision$";
00060 #endif
00061
00062 #include "defs.h"
00063 #include "opt_alias_class.h"
00064 #include "opt_defs.h"
00065 #include "opt_config.h"
00066 #include "opt_base.h"
00067 #include "opt_mu_chi.h"
00068 #include "opt_htable.h"
00069 #include "opt_ssa.h"
00070 #include "opt_bb.h"
00071 #include "pf_cg.h"
00072
00073
00074 OCC_TAB_ENTRY *
00075 #ifdef KEY
00076 OPT_STAB::Enter_occ_tab(WN *wn, AUX_ID aux_id, POINTS_TO *pt)
00077 #else
00078 OPT_STAB::Enter_occ_tab(WN *wn, AUX_ID aux_id)
00079 #endif
00080 {
00081 OCC_TAB_ENTRY *occ = CXX_NEW(OCC_TAB_ENTRY, Occ_pool());
00082 occ->Set_aux_id(aux_id);
00083 occ->Set_wn(wn);
00084 occ->Set_lno_dep_vertex_load(0);
00085 occ->Set_lno_dep_vertex_store(0);
00086
00087
00088
00089
00090
00091 if (occ->Is_stmt()) {
00092 occ->Set_stmt_mu_list( CXX_NEW(MU_LIST, Occ_pool()));
00093 occ->Set_stmt_chi_list( CXX_NEW(CHI_LIST, Occ_pool()));
00094 occ->Set_pf_list(NULL);
00095 occ->Set_pt_list(NULL);
00096 } else {
00097 #ifdef KEY
00098 if (WOPT_Enable_New_Vsym_Allocation && pt ) {
00099 occ->Points_to()->Copy_fully (pt);
00100 } else
00101 #endif
00102 {
00103 occ->Points_to()->Init();
00104
00105 if (WN_operator(wn) == OPR_PARM && aux_id == _default_vsym)
00106 occ->Points_to()->Set_expr_kind(EXPR_IS_ANY);
00107 occ->Points_to()->Set_base_kind(BASE_IS_UNKNOWN);
00108 occ->Points_to()->Set_ofst_kind(OFST_IS_INVALID);
00109 }
00110
00111 if (occ->Is_load()) {
00112 occ->Set_mem_mu_node(NULL);
00113 INT32 vertex = WN_get_dep_graph_vertex(wn);
00114 WN_detach_wn_from_dep_graph(vertex);
00115 occ->Set_lno_dep_vertex_load(vertex);
00116 } else {
00117 occ->Set_mem_chi_list( CXX_NEW(CHI_LIST, Occ_pool()));
00118 INT32 vertex = WN_get_dep_graph_vertex(wn);
00119 WN_detach_wn_from_dep_graph(vertex);
00120 occ->Set_lno_dep_vertex_store(vertex);
00121 }
00122 if (! OPERATOR_is_scalar_store (WN_operator(wn)))
00123 Set_virtual_var(aux_id);
00124 PF_POINTER *pf_pointer = WN_get_pf_pointer(wn);
00125 occ->Set_pf_pointer(pf_pointer);
00126
00127
00128 if ((occ->Is_load() || occ->Is_store()) &&
00129 WN_MEMOP_ANNOT_MGR::WN_mem_annot_mgr()) {
00130 MEMOP_ANNOT* annot = WN_MEMOP_ANNOT_MGR::WN_mem_annot_mgr()->Get_annot(wn);
00131 if (annot) {
00132 MEMOP_ANNOT* t = Cr_sr_annot_mgr()->Import_annot (annot);
00133 occ->Points_to()->Mem_annot().Set_annots (t);
00134 }
00135 }
00136 }
00137
00138 WN_MAP_Set(WN_sym_map(), wn, occ);
00139
00140 return occ;
00141 }
00142
00143
00144
00145
00146
00147
00148 void
00149 OPT_STAB::Update_pf_list(WN *pref_wn, STMTREP *srep)
00150 {
00151 PF_LIST *pf_list = Get_occ(pref_wn)->Pf_list();
00152 PF_POINTER *p;
00153 PF_NODE *pf_node;
00154 PF_LIST_ITER pf_iter;
00155 FOR_ALL_NODE(pf_node, pf_iter, Init(pf_list)) {
00156 p = pf_node->Pf_pointer();
00157 if (PF_PTR_wn_pref_1L(p) == pref_wn)
00158 PF_PTR_wn_pref_1L(p) = (WN *) srep;
00159 if (PF_PTR_wn_pref_2L(p) == pref_wn)
00160 PF_PTR_wn_pref_2L(p) = (WN *) srep;
00161 }
00162 }
00163
00164
00165
00166 OCC_TAB_ENTRY *
00167 OPT_STAB::Get_occ(const WN *wn) const
00168 {
00169 OCC_TAB_ENTRY *occ = (OCC_TAB_ENTRY *) WN_MAP_Get(WN_sym_map(), wn);
00170 return occ;
00171 }
00172
00173 CHI_LIST *
00174 OPT_STAB::Get_mem_chi_list(const WN *wn) const
00175 {
00176 OCC_TAB_ENTRY *occ = (OCC_TAB_ENTRY *) WN_MAP_Get(WN_sym_map(), wn);
00177 return (occ == NULL) ? NULL : occ->Mem_chi_list();
00178 }
00179
00180 CHI_LIST *
00181 OPT_STAB::Get_stmt_chi_list(const WN *wn) const
00182 {
00183 OCC_TAB_ENTRY *occ = (OCC_TAB_ENTRY *) WN_MAP_Get(WN_sym_map(), wn);
00184 return (occ == NULL) ? NULL : occ->Stmt_chi_list();
00185 }
00186
00187
00188 CHI_LIST *
00189 OPT_STAB::Get_generic_chi_list(const WN *wn) const
00190 {
00191 OCC_TAB_ENTRY *occ = (OCC_TAB_ENTRY *) WN_MAP_Get(WN_sym_map(), wn);
00192 if (occ == NULL) return NULL;
00193 return occ->Is_stmt() ? occ->Stmt_chi_list() : occ->Mem_chi_list();
00194 }
00195
00196
00197 MU_NODE *
00198 OPT_STAB::Get_mem_mu_node(const WN *wn) const
00199 {
00200 OCC_TAB_ENTRY *occ = (OCC_TAB_ENTRY *) WN_MAP_Get(WN_sym_map(), wn);
00201 if (occ == NULL) return NULL;
00202 Is_True(occ->Wn() == wn,
00203 ("OPT_STAB::Get_mem_mu_node: occ gets attached to wrong wn"));
00204 return occ->Mem_mu_node();
00205 }
00206
00207
00208 MU_LIST *
00209 OPT_STAB::Get_stmt_mu_list(const WN *wn) const
00210 {
00211 OCC_TAB_ENTRY *occ = (OCC_TAB_ENTRY *) WN_MAP_Get(WN_sym_map(), wn);
00212 if (occ == NULL) return NULL;
00213 Is_True(occ->Wn() == wn,
00214 ("OPT_STAB::Get_stmt_mu_list: occ gets attached to wrong wn"));
00215 return occ->Stmt_mu_list();
00216 }
00217
00218
00219 void
00220 OPT_STAB::Update_iload_vsym(OCC_TAB_ENTRY *occ)
00221 {
00222 BOOL trace = Get_Trace(TP_GLOBOPT, ALIAS_DUMP_FLAG);
00223
00224 if (occ->Points_to()->Base_kind() != BASE_IS_FIXED)
00225 return;
00226 if (occ->Points_to()->Unique_pt() ||
00227 occ->Points_to()->Restricted())
00228 return;
00229
00230 Is_True(occ->Points_to()->Base_kind() == BASE_IS_FIXED, ("base is not fixed."));
00231 ST *st = occ->Points_to()->Base();
00232 AUX_ID vsym_id;
00233 if (occ->Points_to()->Ofst_kind() == OFST_IS_FIXED) {
00234 INT64 byte_ofst = occ->Points_to()->Byte_Ofst();
00235 INT64 byte_size = occ->Points_to()->Byte_Size();
00236 UINT8 bit_ofst = occ->Points_to()->Bit_Ofst();
00237 UINT8 bit_size = occ->Points_to()->Bit_Size();
00238 vsym_id = Find_vsym_with_base_ofst_and_size(st, byte_ofst, byte_size,
00239 bit_ofst, bit_size);
00240 } else
00241 vsym_id = Find_vsym_with_base_ofst_and_size(st, 0, 0, 0, 0);
00242 if (vsym_id == 0) return;
00243
00244
00245 if (aux_stab[vsym_id].Aux_id_list() == NULL)
00246 Update_aux_id_list(vsym_id);
00247
00248
00249 POINTS_TO *pt = aux_stab[vsym_id].Points_to();
00250 pt->Meet(occ->Points_to(), NULL);
00251 Is_True(vsym_id == Default_vsym() || pt->Base_is_fixed() || pt->Based_sym()
00252 || aux_stab[vsym_id].Unique_vsym(), ("base is disrupted."));
00253
00254 MU_NODE *mu = occ->Mem_mu_node();
00255 VER_ID ver = mu->Opnd();
00256 while (1) {
00257 INT32 vtype = Ver_stab_entry(ver)->Type();
00258 switch (vtype) {
00259 case ENTRY_STMT:
00260
00261 return;
00262 case WHIRL_STMT:
00263 case CHI_STMT:
00264 {
00265 WN *wn;
00266 if (vtype == WHIRL_STMT) {
00267 wn = Ver_stab_entry(ver)->Wn();
00268 }
00269 else {
00270 wn = Ver_stab_entry(ver)->Chi_wn();
00271 if (OPERATOR_is_scalar_store ( WN_operator(wn) )) {
00272 if ( Du_aux_id(WN_ver(wn)) == vsym_id ) {
00273 occ->Set_aux_id(vsym_id);
00274 mu->Set_aux_id(vsym_id);
00275 mu->Set_opnd(WN_ver(wn));
00276 return;
00277 }
00278 }
00279 }
00280
00281 CHI_LIST *chi_list = Get_generic_chi_list(wn);
00282 Is_True(chi_list, ("chi list is null."));
00283 CHI_LIST_ITER chi_iter;
00284 CHI_NODE *cnode;
00285 FOR_ALL_NODE( cnode, chi_iter, Init(chi_list)) {
00286 if (cnode->Aux_id() == vsym_id) {
00287 occ->Set_aux_id(vsym_id);
00288 mu->Set_aux_id(vsym_id);
00289 mu->Set_opnd(cnode->Result());
00290 cnode->Set_live(TRUE);
00291 if (trace) {
00292 fprintf(TFile, "Update_iload_vsym: set aux_id %d chi live.\n",
00293 cnode->Aux_id());
00294 }
00295
00296 return;
00297 }
00298 }
00299
00300 ver = Ver_stab_entry(ver)->Chi()->Opnd();
00301 }
00302 break;
00303 case PHI_STMT:
00304 {
00305 BB_NODE *bb = Ver_stab_entry(ver)->Bb();
00306 PHI_LIST_ITER phi_iter;
00307 PHI_NODE *phi;
00308 FOR_ALL_ELEM (phi, phi_iter, Init(bb->Phi_list())) {
00309 if (phi->Aux_id() == vsym_id) {
00310 occ->Set_aux_id(vsym_id);
00311 mu->Set_aux_id(vsym_id);
00312 mu->Set_opnd(phi->Result());
00313 phi->Set_live();
00314 if (trace) {
00315 fprintf(TFile, "Update_iload_vsym: set aux_id %d phi at BB%d to live.\n",
00316 phi->Aux_id(), bb->Id());
00317 }
00318
00319 return;
00320 }
00321 }
00322
00323 phi = Ver_stab_entry(ver)->Phi();
00324
00325
00326 BB_NODE *pred;
00327 BB_LIST_ITER bb_iter;
00328 ver = (VER_ID) -1;
00329 INT32 i = -1;
00330 FOR_ALL_ELEM(pred, bb_iter, Init(bb->Pred())) {
00331 i++;
00332 if (bb->Dominates(pred)) continue;
00333 if (ver != -1) return;
00334 ver = phi->Opnd(i);
00335 }
00336
00337 }
00338 }
00339 }
00340 }
00341
00342
00343 void
00344 OPT_STAB::Update_istore_vsym(OCC_TAB_ENTRY *occ)
00345 {
00346 if (occ->Points_to()->Base_kind() != BASE_IS_FIXED)
00347 return;
00348 if (occ->Points_to()->Unique_pt() ||
00349 occ->Points_to()->Restricted())
00350 return;
00351
00352 Is_True(occ->Points_to()->Base_kind() == BASE_IS_FIXED, ("base is not fixed."));
00353 ST *st = occ->Points_to()->Base();
00354 AUX_ID vsym_id;
00355 if (occ->Points_to()->Ofst_kind() == OFST_IS_FIXED) {
00356 INT64 byte_ofst = occ->Points_to()->Byte_Ofst();
00357 INT64 byte_size = occ->Points_to()->Byte_Size();
00358 UINT8 bit_ofst = occ->Points_to()->Bit_Ofst();
00359 UINT8 bit_size = occ->Points_to()->Bit_Size();
00360 vsym_id = Find_vsym_with_base_ofst_and_size(st, byte_ofst, byte_size,
00361 bit_ofst, bit_size);
00362 } else
00363 vsym_id = Find_vsym_with_base_ofst_and_size(st, 0, 0, 0, 0);
00364 if (vsym_id == 0) return;
00365 occ->Set_aux_id(vsym_id);
00366
00367
00368 if (aux_stab[vsym_id].Aux_id_list() == NULL)
00369 Update_aux_id_list(vsym_id);
00370
00371
00372 POINTS_TO *pt = aux_stab[vsym_id].Points_to();
00373 pt->Meet(occ->Points_to(), NULL);
00374 Is_True(vsym_id == Default_vsym() || pt->Base_is_fixed() || pt->Based_sym()
00375 || aux_stab[vsym_id].Unique_vsym(), ("base is disrupted."));
00376
00377 }
00378
00379
00380 void
00381 OCC_TAB_ENTRY::Print(FILE *fp)
00382 {
00383 fprintf(fp, "auxid %d\n", Aux_id());
00384 fdump_tree_no_st(fp, Wn());
00385 if (Is_mem())
00386 Points_to()->Print(fp);
00387 else
00388 fprintf(fp, "\n");
00389 }
00390
00391 BOOL
00392 MU_LIST::Contains(AUX_ID var)
00393 {
00394 MU_LIST_ITER mu_iter;
00395 MU_NODE *mnode;
00396 FOR_ALL_NODE(mnode, mu_iter, Init(this)) {
00397 if ( mnode->Aux_id() == var )
00398 return TRUE;
00399 }
00400 return FALSE;
00401 }
00402
00403 void
00404 MU_LIST::Delete_def_at_entry_mus(OPT_STAB *opt_stab)
00405 {
00406 VER_STAB_ENTRY *vse;
00407 MU_NODE *prev = NULL;
00408 MU_NODE *cur;
00409
00410 cur = Head();
00411 while (cur != NULL) {
00412 vse = opt_stab->Ver_stab_entry(cur->Opnd());
00413 if (vse->Zero_vers() ||
00414 vse->Type() == ENTRY_STMT ||
00415 vse->Type() == CHI_STMT && WN_operator(vse->Chi_wn()) == OPR_OPT_CHI) {
00416 Remove(prev, cur);
00417 if (prev != NULL)
00418 cur = prev->Next();
00419 else cur = Head();
00420 }
00421 else {
00422 prev = cur;
00423 cur = cur->Next();
00424 }
00425 }
00426 }
00427
00428
00429 void
00430 OCC_TAB_ENTRY::Clone(OCC_TAB_ENTRY *occ, MEM_POOL *pool)
00431 {
00432 Set_aux_id(occ->Aux_id());
00433 Set_wn(occ->Wn());
00434 if (occ->Is_stmt()) {
00435 _u1._is_stmt = occ->_u1._is_stmt;
00436 Set_stmt_mu_list(NULL);
00437 Set_stmt_chi_list(NULL);
00438 } else {
00439 _u1._is_mem = occ->_u1._is_mem;
00440 Set_lno_dep_vertex_load(0);
00441 Set_lno_dep_vertex_store(0);
00442 Set_pf_pointer(NULL);
00443 if (Is_load())
00444 Set_mem_mu_node(NULL);
00445 else
00446 Set_mem_chi_list(NULL);
00447 }
00448 _points_to.Copy_fully(&(occ->_points_to));
00449 }