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
00069
00070
00071
00072
00073
00074 #ifdef USE_PCH
00075 #include "opt_pch.h"
00076 #endif // USE_PCH
00077 #pragma hdrstop
00078
00079
00080 #define opt_verify_CXX "opt_verify.cxx"
00081
00082 #include "defs.h"
00083 #include "errors.h"
00084 #include "erglob.h"
00085 #include "mempool.h"
00086 #include "tracing.h"
00087 #include "stab.h"
00088 #include "opt_cfg.h"
00089 #include "opt_ssa.h"
00090 #include "opt_sym.h"
00091 #include "opt_mu_chi.h"
00092 #include "opt_util.h"
00093 #include "opt_defs.h"
00094 #include "opt_main.h"
00095 #include "opt_base.h"
00096 #include "opt_htable.h"
00097 #include "opt_rvi.h"
00098 #include "opt_alias_mgr.h"
00099 #include "bb_node_set.h"
00100
00101 #ifdef _LP64
00102 #define UNDEFINED_PTR (void *)0xa5a5a5a5a5a5a5a5LL
00103 #else
00104 #define UNDEFINED_PTR (void *)0xa5a5a5a5
00105 #endif
00106
00107 static BOOL past_ret_reg_def;
00108
00109
00110 BOOL
00111 COMP_UNIT::Verify_IR(CFG *cfg, CODEMAP *htable, INT which)
00112 {
00113 #ifdef Is_True_On
00114 if (WOPT_Enable_Verify < 3)
00115 return TRUE;
00116
00117 if (TFile != stdout)
00118 fprintf(TFile,"%sVerify_IR %d, checking IR\n%s",DBar,which,DBar);
00119
00120 BB_NODE *bb;
00121 CFG_ITER cfg_iter(cfg);
00122
00123
00124 FOR_ALL_ELEM (bb, cfg_iter, Init(cfg)) {
00125 STMTREP_ITER stmt_iter(bb->Stmtlist());
00126 STMTREP *stmt;
00127 FOR_ALL_NODE(stmt, stmt_iter, Init())
00128 switch (stmt->Opr()) {
00129 case OPR_ISTORE:
00130 case OPR_ISTBITS:
00131 case OPR_MSTORE:
00132 if (stmt->Lhs() == NULL || stmt->Lhs() == UNDEFINED_PTR ||
00133 stmt->Lhs()->Istr_base() == NULL ||
00134 stmt->Lhs()->Istr_base() == UNDEFINED_PTR)
00135 fprintf(TFile,"*** Verify_IR %d, BB%d, %s null Istr_base\n",
00136 which,bb->Id(),OPCODE_name(stmt->Op()));
00137 break;
00138 default:
00139 break;
00140 }
00141 }
00142
00143
00144
00145 FOR_ALL_ELEM (bb, cfg_iter, Init(cfg)) {
00146 STMTREP_ITER stmt_iter(bb->Stmtlist());
00147 STMTREP *stmt;
00148 FOR_ALL_NODE(stmt, stmt_iter, Init())
00149 stmt->Verify_IR(cfg,htable,which);
00150 }
00151
00152
00153
00154 CODEREP_ITER cr_iter;
00155 CODEREP *tmpcr, *bucket;
00156 CODEMAP_ITER codemap_iter;
00157 FOR_ALL_ELEM(bucket, codemap_iter, Init(htable)) {
00158 FOR_ALL_NODE(tmpcr, cr_iter, Init(bucket)) {
00159 if (tmpcr->Count_parents(cfg,htable) == 0 && tmpcr->Usecnt() != 0) {
00160 fprintf(TFile,"*** Verify_IR %d, dead code with usecnt = %d\n",
00161 which,tmpcr->Usecnt());
00162 tmpcr->Print(0,TFile);
00163 }
00164 }
00165 }
00166
00167
00168 FOR_ALL_ELEM (bb, cfg_iter, Init(cfg)) {
00169 STMTREP_ITER stmt_iter(bb->Stmtlist());
00170 STMTREP *stmt;
00171 FOR_ALL_NODE(stmt, stmt_iter, Init())
00172 if (stmt->Bb() != bb) {
00173 char str[20];
00174 if (stmt->Bb() != NULL && stmt->Bb() != UNDEFINED_PTR)
00175 sprintf(str,"BB%d",stmt->Bb()->Id());
00176 else
00177 strcpy(str,"<null>");
00178 fprintf(TFile,
00179 "*** Verify_IR %d, BB%d, stmtrep bb pointer is wrong, %s\n",
00180 which,bb->Id(),str);
00181 stmt->Print(TFile);
00182 stmt->Set_bb(bb);
00183 }
00184 }
00185
00186
00187 FOR_ALL_ELEM (bb, cfg_iter, Init(cfg)) {
00188 STMTREP_ITER stmt_iter(bb->Stmtlist());
00189 STMTREP *stmt;
00190 FOR_ALL_NODE(stmt, stmt_iter, Init()) {
00191 if (stmt->Has_chi()) {
00192 CHI_LIST_ITER chi_iter;
00193 CHI_NODE *cnode;
00194 CHI_LIST *chi_list = stmt->Chi_list();
00195 FOR_ALL_NODE( cnode, chi_iter, Init(chi_list)) {
00196 if (cnode->Live()) {
00197
00198
00199 if (cnode->RESULT() == NULL || cnode->RESULT() == UNDEFINED_PTR) {
00200 fprintf(TFile,"*** Verify_IR %d, BB%d, chi RESULT is null\n",
00201 which,bb->Id());
00202 continue;
00203 }
00204 if (cnode->OPND() == NULL || cnode->OPND() == UNDEFINED_PTR) {
00205 fprintf(TFile,"*** Verify_IR %d, BB%d, chi OPND is null\n",
00206 which,bb->Id());
00207 continue;
00208 }
00209
00210
00211 BOOL found_r = FALSE, found_o = FALSE;
00212 FOR_ALL_ELEM(bucket, codemap_iter, Init(htable)) {
00213 FOR_ALL_NODE(tmpcr, cr_iter, Init(bucket)) {
00214 if (tmpcr == cnode->RESULT())
00215 found_r = TRUE;
00216 if (tmpcr == cnode->OPND())
00217 found_o = TRUE;
00218 }
00219 }
00220 if (!found_r)
00221 fprintf(TFile,"*** Verify_IR %d, BB%d, chi RESULT not right\n",
00222 which,bb->Id());
00223 if (!found_o)
00224 fprintf(TFile,"*** Verify_IR %d, BB%d, chi OPND not right\n",
00225 which,bb->Id());
00226
00227
00228 FOR_ALL_ELEM(bucket, codemap_iter, Init(htable)) {
00229 FOR_ALL_NODE(tmpcr, cr_iter, Init(bucket)) {
00230 if (tmpcr->Is_flag_set(CF_DEF_BY_CHI)) {
00231 if (tmpcr->Defchi() == NULL ||
00232 tmpcr->Defchi() == UNDEFINED_PTR){
00233 fprintf(TFile,"*** Verify_IR %d, CR with CF_DEF_BY_CHI ",
00234 which);
00235 fprintf(TFile,"set but no Defchi 0x%p\n",
00236 tmpcr->Defchi());
00237 tmpcr->Print(0,TFile);
00238 }
00239 }
00240 }
00241 }
00242
00243 }
00244 }
00245 }
00246 }
00247 }
00248
00249 if (TFile != stdout) {
00250 fprintf(TFile,"%s",DBar);
00251 htable->Print(TFile);
00252 fprintf(TFile,"%sVerify_IR %d, done checking IR\n%s",DBar,which,DBar);
00253 }
00254 #endif
00255 return TRUE;
00256 }
00257
00258 BOOL
00259 STMTREP::Verify_IR(CFG *cfg, CODEMAP *htable, INT which)
00260 {
00261 #ifdef Is_True_On
00262 if (WOPT_Enable_Verify < 3)
00263 return TRUE;
00264
00265 if (Rhs())
00266 Rhs()->Verify_IR(cfg,htable,TRUE,which);
00267 if (Lhs())
00268 Lhs()->Verify_IR(cfg,htable,FALSE,which);
00269
00270
00271 #endif
00272 return TRUE;
00273 }
00274
00275 BOOL
00276 CODEREP::Verify_IR(CFG *cfg, CODEMAP *htable, BOOL is_rhs, INT which)
00277 {
00278 #ifdef Is_True_On
00279 if (WOPT_Enable_Verify < 3)
00280 return TRUE;
00281
00282 switch (Kind()) {
00283 case CK_OP:
00284 {
00285 if (Kind() == CK_OP) {
00286 for (INT i=0; i<Kid_count(); i++)
00287 Opnd(i)->Verify_IR(cfg,htable,is_rhs,which);
00288 }
00289 }
00290
00291 case CK_CONST:
00292 case CK_RCONST:
00293 case CK_LDA:
00294 case CK_VAR:
00295 case CK_IVAR:
00296 {
00297 INT Nparents = Count_parents(cfg,htable);
00298 if (Nparents != Usecnt()) {
00299 fprintf(TFile,"*** CODEREP::Verify_IR %d, usecnt (%d) and ",
00300 which,Usecnt());
00301 fprintf(TFile,"#parents (%d) don't agree\n",Nparents);
00302 Print(0,TFile);
00303 } else if (Usecnt() <= 0 && is_rhs) {
00304 fprintf(TFile,"*** CODEREP::Verify_IR %d, usecnt should not be zero\n",
00305 which);
00306 Print(0,TFile);
00307 }
00308 }
00309 break;
00310 case CK_DELETED:
00311 default:
00312 fprintf(TFile,"*** CODEREP::Verify_IR %d, unknown kind (0x%x)\n",
00313 which,Kind());
00314 Print(0,TFile);
00315 break;
00316 }
00317 #endif
00318 return TRUE;
00319 }
00320
00321
00322
00323 INT
00324 CODEREP::Count_parents(CFG *cfg, CODEMAP *htable)
00325 {
00326 INT count = 0;
00327
00328 #ifdef Is_True_On
00329
00330 CODEREP_ITER cr_iter;
00331 CODEREP *tmpcr, *bucket;
00332 CODEMAP_ITER codemap_iter;
00333 FOR_ALL_ELEM(bucket, codemap_iter, Init(htable)) {
00334 FOR_ALL_NODE(tmpcr, cr_iter, Init(bucket)) {
00335 switch (tmpcr->Kind()) {
00336 case CK_OP:
00337 {
00338 for (INT i=0; i<tmpcr->Kid_count(); i++)
00339 if (tmpcr->Usecnt() > 0 && tmpcr->Opnd(i) == this)
00340 count++;
00341 }
00342 break;
00343 case CK_IVAR:
00344 {
00345 CODEREP *ctmp;
00346 if (tmpcr->Ilod_base() != NULL &&
00347 tmpcr->Ilod_base() != UNDEFINED_PTR)
00348 ctmp = tmpcr->Ilod_base();
00349 else if (tmpcr->Istr_base() != NULL &&
00350 tmpcr->Istr_base() != UNDEFINED_PTR)
00351 ctmp = tmpcr->Istr_base();
00352 else
00353 FmtAssert(FALSE,("CODEREP::Count_parents, null base for IVAR"));
00354
00355 if (ctmp->Usecnt() > 0 && ctmp == this)
00356 count++;
00357 }
00358 break;
00359 default:
00360 break;
00361 }
00362 }
00363 }
00364
00365
00366 CFG_ITER cfg_iter;
00367 STMTREP *stmt;
00368 BB_NODE *bb;
00369 FOR_ALL_NODE(bb, cfg_iter, Init(cfg)) {
00370 STMTREP_ITER stmt_iter(bb->Stmtlist());
00371 FOR_ALL_NODE(stmt, stmt_iter, Init()) {
00372 if (stmt->Rhs() == this)
00373 count++;
00374
00375 }
00376 }
00377
00378 #endif
00379 return count;
00380 }
00381
00382
00383
00384
00385
00386 BOOL Verify_alias(ALIAS_MANAGER *am, WN *wn)
00387 {
00388 BOOL ret = TRUE;
00389 #ifdef Is_True_On
00390
00391 if (!WOPT_Enable_Verify)
00392 return ret;
00393
00394 if (wn == NULL)
00395 return ret;
00396
00397 OPERATOR opr = WN_operator(wn);
00398
00399 if (opr == OPR_BLOCK) {
00400 if (WN_first(wn) && WN_prev(WN_first(wn))) {
00401 fprintf(TFile, "### Verify_alias, WN_first has prev stmt.");
00402 fdump_tree(TFile,wn);
00403 }
00404 if (WN_last(wn) && WN_next(WN_last(wn))) {
00405 fprintf(TFile, "### Verify_alias, WN_last has next stmt.");
00406 fdump_tree(TFile,wn);
00407 }
00408 for (WN *stmt = WN_first(wn); stmt != NULL; stmt = WN_next(stmt)) {
00409 if (!Verify_alias(am,stmt))
00410 ret = FALSE;
00411 }
00412 } else {
00413 for (INT i = 0; i < WN_kid_count(wn); i++)
00414 if (!Verify_alias(am,WN_kid(wn,i)))
00415 ret = FALSE;
00416 }
00417
00418
00419 if (OPERATOR_is_load(opr) || OPERATOR_is_store(opr)) {
00420 if (Valid_alias(am,wn) == FALSE) {
00421 #ifdef WARN_TODO
00422 Warn_todo("Verify_alias: WN has no alias information");
00423 fprintf(TFile,"Verify_alias: WN has no alias information\n");
00424 fdump_wn_no_st(TFile, wn);
00425 #endif
00426 ret = FALSE;
00427 }
00428 }
00429 #endif
00430 return ret;
00431 }
00432
00433 #ifdef Is_True_On
00434 STMTREP *cur_stmt;
00435 #endif
00436
00437 inline void
00438 Save_cur_stmt(STMTREP *stmt)
00439 {
00440 #ifdef Is_True_On
00441 cur_stmt = stmt;
00442 #endif
00443 }
00444
00445 static BOOL
00446 Cur_stmt_is_entry_chi(void)
00447 {
00448 #ifdef Is_True_On
00449 return (cur_stmt->Opr() == OPR_OPT_CHI);
00450 #endif
00451 }
00452
00453 static void
00454 Reset_find_def_processed(CFG *cfg)
00455 {
00456 BB_NODE *bb;
00457 CFG_ITER cfg_iter(cfg);
00458 FOR_ALL_ELEM (bb, cfg_iter, Init(cfg)) {
00459 PHI_NODE *phi;
00460 PHI_LIST_ITER phi_iter;
00461
00462 FOR_ALL_ELEM (phi, phi_iter, Init(bb->Phi_list())) {
00463 phi->Reset_find_def_processed();
00464 }
00465 }
00466 }
00467
00468
00469 static void
00470 Verify_spre_temp(CODEREP *cr)
00471 {
00472 Is_True(cr->Kind() == CK_VAR, ("Verify_spre_temp: not a CK_VAR."));
00473 Is_True(!cr->Is_flag_set(CF_IS_ZERO_VERSION), ("Verify_spre_temp: spre temp cannot be a zero ver."));
00474 Is_True(!cr->Is_flag_set(CF_DEF_BY_CHI), ("Verify_spre_temp: spre temp cannot be defined by chi."));
00475 if (cr->Is_flag_set(CF_DEF_BY_PHI)) {
00476 if (!cr->Defphi()->Find_def_processed()) {
00477 cr->Defphi()->Set_find_def_processed();
00478 PHI_OPND_ITER phi_opnd_iter(cr->Defphi());
00479 CODEREP *opnd;
00480 FOR_ALL_ELEM(opnd, phi_opnd_iter, Init()) {
00481 Verify_spre_temp(opnd);
00482 }
00483 }
00484 } else {
00485
00486 Is_True(cr->Defstmt() != NULL, ("Verify_spre_temp: null defstmt."));
00487 }
00488 }
00489
00490
00491 void
00492 CODEREP::Verify_CODEMAP(CODEMAP *htable, OPT_STAB *opt_stab, BOOL allow_zero_ver)
00493 {
00494 #ifdef Is_True_On
00495 if (!WOPT_Enable_Verify)
00496 return;
00497
00498 switch (Kind()) {
00499 case CK_LDA:
00500 case CK_CONST:
00501 case CK_RCONST:
00502 return;
00503 case CK_VAR:
00504 FmtAssert(Offset() == opt_stab->St_ofst(Aux_id()) || Dsctyp() == MTYPE_BS,
00505 ("bad offset field in CODEREP."));
00506
00507 if (!Is_flag_set( (CR_FLAG) (CF_DEF_BY_PHI|CF_DEF_BY_CHI)) &&
00508 Defstmt() != NULL) {
00509 FmtAssert(Lod_ty() != 0, ("load ty is NULL."));
00510 }
00511
00512
00513 if (opt_stab->Is_volatile(Aux_id())) {
00514 Is_True( Is_var_volatile(),
00515 ("Volatile variable %d has non-volatile cr%d",Aux_id(), Coderep_id()) );
00516 break;
00517 }
00518 if (Is_var_volatile()) {
00519
00520
00521 Is_True( opt_stab->Is_volatile(Aux_id()),
00522 ("Volatile cr for var %d is not volatile in stab",Aux_id()) );
00523 break;
00524 }
00525
00526 if (!allow_zero_ver) {
00527 FmtAssert(!Is_flag_set(CF_IS_ZERO_VERSION),
00528 ("zero ver not allowed in expr."));
00529 }
00530
00531 if (Is_var_nodef() && !Is_flag_set(CF_IS_ZERO_VERSION))
00532 Is_True(Cur_stmt_is_entry_chi(),
00533 ("corrupted htable: CR loses its definition, but "
00534 "current statement is not entry chi"));
00535
00536 FmtAssert(!Is_var_nodef() || Version() == 0 || Version() == 1 ||
00537 Is_flag_set(CF_IS_ZERO_VERSION),
00538 ("corrupted htable: CR loses its definition."));
00539
00540 if (opt_stab->Aux_stab_entry(Aux_id())->SPRE_temp() &&
00541 !Cur_stmt_is_entry_chi() && !allow_zero_ver) {
00542
00543
00544 Verify_spre_temp(this);
00545 }
00546
00547 break;
00548 case CK_IVAR:
00549 {
00550 Ilod_base()->Verify_CODEMAP(htable, opt_stab, FALSE);
00551 if (Opr() == OPR_MLOAD)
00552 Mload_size()->Verify_CODEMAP(htable, opt_stab, FALSE);
00553 if (Opr() == OPR_ILOADX)
00554 Index()->Verify_CODEMAP(htable, opt_stab, FALSE);
00555 MU_NODE *mnode = Ivar_mu_node();
00556 if (mnode)
00557 FmtAssert(mnode->Aux_id() != opt_stab->Return_vsym(),
00558 ("return vsym cannot be in mu of ivar node"));
00559 if (OPERATOR_is_scalar_iload (Opr()) ||
00560 Opr() == OPR_MLOAD ||
00561 Opr() == OPR_ILOADX) {
00562 if (mnode == NULL)
00563 Warn_todo("ILOAD has no mu node.");
00564 }
00565 if (mnode)
00566 mnode->OPND()->Verify_CODEMAP(htable, opt_stab, TRUE);
00567 }
00568 break;
00569 case CK_OP:
00570 if (Is_isop_flag_set(ISOP_VER_MAP_VISITED))
00571 return;
00572 Set_isop_flag(ISOP_VER_MAP_VISITED);
00573 {
00574 for (INT32 i = 0; i < Kid_count(); i++)
00575 Opnd(i)->Verify_CODEMAP(htable, opt_stab, FALSE);
00576 }
00577 break;
00578 }
00579 #endif
00580 }
00581
00582 void
00583 STMTREP::Verify_CODEMAP(CODEMAP *htable, OPT_STAB *opt_stab)
00584 {
00585 #ifdef Is_True_On
00586 if (!WOPT_Enable_Verify)
00587 return;
00588
00589 Save_cur_stmt(this);
00590 if (OPERATOR_is_call(Opr()))
00591 for (INT32 i = 0; i < Rhs()->Kid_count(); i++) {
00592 Rhs()->Opnd(i)->Verify_CODEMAP(htable, opt_stab, FALSE);
00593 }
00594 else if (Rhs())
00595 Rhs()->Verify_CODEMAP(htable, opt_stab, FALSE);
00596
00597 switch (Opr()) {
00598 case OPR_ISTORE:
00599 case OPR_ISTBITS:
00600 Lhs()->Istr_base()->Verify_CODEMAP(htable, opt_stab, FALSE);
00601 FmtAssert(Opr() == OPR_ISTBITS && Lhs()->Opr() == OPR_ILDBITS ||
00602 Opr() == OPR_ISTORE && Lhs()->Opr() == OPR_ILOAD,
00603 ("STMTREP::Verify_CODEMAP: inconsistent store operator with respect to bitfields"));
00604 break;
00605 case OPR_MSTORE:
00606 Lhs()->Istr_base()->Verify_CODEMAP(htable, opt_stab, FALSE);
00607 Lhs()->Mstore_size()->Verify_CODEMAP(htable, opt_stab, FALSE);
00608 break;
00609 case OPR_STID:
00610 case OPR_STBITS: {
00611
00612 FmtAssert(!Lhs()->Is_var_nodef(),
00613 ("corrupted htable: STMTREP loses its definition."));
00614 FmtAssert(!Lhs()->Is_flag_set(CF_DEF_BY_PHI) &&
00615 !Lhs()->Is_flag_set(CF_DEF_BY_CHI) &&
00616 Lhs()->Defstmt() == this,
00617 ("STMTREP::Verify_CODEMAP: LHS of store must be def by store"));
00618
00619 ST *st = opt_stab->St(Lhs()->Aux_id());
00620
00621
00622 if (st != NULL && ST_sclass(st) != SCLASS_REG) {
00623 BB_NODE_SET_ITER df_iter;
00624 BB_NODE *bb_phi;
00625 FOR_ALL_ELEM (bb_phi, df_iter, Init(Bb()->Dom_frontier())) {
00626 if (htable->Phi_hash_valid() &&
00627 !htable->Lookup_var_phi(bb_phi, Lhs()->Aux_id()))
00628 DevWarn("CODEMAP: STID has no phi.");
00629 }
00630 }
00631
00632 FmtAssert(Opr() == OPR_STBITS && Lhs()->Bit_field_valid() ||
00633 Opr() == OPR_STID && ! Lhs()->Bit_field_valid(),
00634 ("STMTREP::Verify_CODEMAP: inconsistent store operator with respect to bitfields"));
00635 break;
00636 }
00637 default: ;
00638 }
00639 if (Has_mu()) {
00640 MU_LIST_ITER mu_iter;
00641 MU_NODE *mnode;
00642 FOR_ALL_NODE( mnode, mu_iter, Init(Mu_list())) {
00643 if (mnode->OPND())
00644 mnode->OPND()->Verify_CODEMAP(htable,opt_stab, TRUE);
00645 }
00646 }
00647 if (Has_chi()) {
00648 CHI_LIST_ITER chi_iter;
00649 CHI_NODE *cnode;
00650 FOR_ALL_NODE( cnode, chi_iter, Init(Chi_list())) {
00651 if (! cnode->Live()) continue;
00652 if (cnode->RESULT()) {
00653 cnode->RESULT()->Verify_CODEMAP(htable,opt_stab, TRUE);
00654
00655 CODEREP *res = cnode->RESULT();
00656
00657 FmtAssert(res->Is_flag_set(CF_IS_ZERO_VERSION) ||
00658 res->Is_var_nodef() ||
00659 (res->Is_flag_set(CF_DEF_BY_CHI) &&
00660 res->Defchi() == cnode),
00661 ("STMTREP::Verify_CODEMAP: LHS of chi must be def by "
00662 "chi stmt"));
00663
00664 if (!res->Is_flag_set(CF_IS_ZERO_VERSION)) {
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677 cnode->OPND()->Verify_CODEMAP(htable,opt_stab,TRUE);
00678
00679
00680 FmtAssert(res->Is_flag_set(CF_DEF_BY_CHI),
00681 ("corrupted htable: CHI result is not DEF_BY_CHI."));
00682 FmtAssert(!res->Is_var_nodef(),
00683 ("corrupted htable: CHI result loses its definition."));
00684
00685 ST *st = opt_stab->St(res->Aux_id());
00686
00687
00688 if (st != NULL && ST_sclass(st) != SCLASS_REG) {
00689 BB_NODE_SET_ITER df_iter;
00690 BB_NODE *bb_phi;
00691 FOR_ALL_ELEM (bb_phi, df_iter, Init(Bb()->Dom_frontier())) {
00692 if (htable->Phi_hash_valid() &&
00693 !htable->Lookup_var_phi(bb_phi, res->Aux_id()))
00694 DevWarn("CODEMAP: chi result has no phi.");
00695 }
00696 }
00697 }
00698 else {
00699
00700 }
00701 }
00702 }
00703 }
00704 #endif
00705 }
00706
00707
00708
00709
00710
00711
00712 BOOL
00713 COMP_UNIT::Verify_CODEMAP(void)
00714 {
00715 #ifdef Is_True_On
00716 if (!WOPT_Enable_Verify)
00717 return TRUE;
00718
00719 Reset_find_def_processed(Cfg());
00720
00721 BB_NODE *bb;
00722 CFG_ITER cfg_iter(Cfg());
00723
00724 FOR_ALL_ELEM (bb, cfg_iter, Init(Cfg())) {
00725 PHI_LIST_ITER phi_iter;
00726 PHI_NODE *phi;
00727 FOR_ALL_ELEM (phi, phi_iter, Init(bb->Phi_list())) {
00728 if (phi->Live()) {
00729 BB_NODE *pred; BB_LIST_ITER bb_iter;
00730 FOR_ALL_ELEM (pred, bb_iter, Init(bb->Pred())) {
00731 CODEREP *opnd = phi->OPND(bb_iter.Idx());
00732 FmtAssert(opnd, ("NULL phi operand."));
00733 opnd->Verify_CODEMAP(Htable(), Opt_stab(), TRUE);
00734 }
00735 }
00736 }
00737
00738 STMTREP_ITER stmt_iter(bb->Stmtlist());
00739 STMTREP *stmt;
00740 FOR_ALL_NODE(stmt, stmt_iter, Init()) {
00741 stmt->Verify_CODEMAP(Htable(), Opt_stab());
00742 }
00743 }
00744
00745 Reset_find_def_processed(Cfg());
00746
00747 #endif
00748 return TRUE;
00749 }
00750
00751
00752
00753 #ifdef Is_True_On
00754
00755
00756
00757
00758 BOOL
00759 #if defined(TARG_NVISA)
00760 Def_before_use(CODEREP *cr, const BB_NODE *use_bb)
00761 #else
00762 Def_before_use(const CODEREP *cr, const BB_NODE *use_bb)
00763 #endif
00764 {
00765
00766
00767 switch (cr->Kind()) {
00768 case CK_LDA:
00769 case CK_CONST:
00770 case CK_RCONST:
00771 return TRUE;
00772 case CK_VAR:
00773 if (cr->Is_flag_set(CF_IS_ZERO_VERSION) ||
00774 cr->Is_var_volatile()) return TRUE;
00775 FmtAssert(cr->Defbb(), ("Def_before_use: Defbb not defined"));
00776 return cr->Defbb()->Dominates(use_bb);
00777 case CK_IVAR:
00778 if (!Def_before_use(cr->Ilod_base(), use_bb)) {
00779 DevWarn("Def_before_use: ilod_base not def before use.");
00780 return FALSE;
00781 }
00782 if (cr->Ivar_mu_node() != NULL) {
00783 if (!(cr->Ivar_mu_node()->OPND()->Is_flag_set(CF_IS_ZERO_VERSION) ||
00784 Def_before_use(cr->Ivar_mu_node()->OPND(), use_bb))) {
00785 DevWarn("Def_before_use: mu opnd not def before use.");
00786 return FALSE;
00787 }
00788 } else {
00789 FmtAssert(cr->Opr() == OPR_PARM ||
00790 cr->Opr() == OPR_PREFETCH,
00791 ("Def_before_use: CK_IVAR node has null mu-node."));
00792 }
00793 return TRUE;
00794 case CK_OP:
00795 {
00796 #if defined(TARG_NVISA)
00797
00798
00799
00800
00801
00802 if (cr->Is_isop_flag_set(ISOP_DEF_BEFORE_VISITED)
00803 && use_bb == cr->Get_ISOP_def_before_use_cache())
00804 {
00805
00806 return TRUE;
00807 }
00808 else
00809 {
00810
00811
00812
00813
00814
00815 cr->Set_isop_flag(ISOP_DEF_BEFORE_VISITED);
00816 cr->Set_ISOP_def_before_use_cache(use_bb);
00817 }
00818 #endif
00819 for (INT j = 0; j < cr->Kid_count(); j++)
00820 if (!Def_before_use(cr->Opnd(j), use_bb)) {
00821 DevWarn("Def_before_use: inserted use before def (Opnd(%d))", j);
00822 return FALSE;
00823 }
00824 return TRUE;
00825 }
00826 default:
00827 return FALSE;
00828 }
00829 }
00830
00831
00832 static void
00833 Verify_has_zver(STMTREP *stmt)
00834 {
00835 CHI_LIST_ITER chi_iter;
00836 CHI_NODE *chi;
00837 bool has_zver = false;
00838 FOR_ALL_NODE(chi, chi_iter, Init(stmt->Chi_list())) {
00839 if (! chi->Live())
00840 continue;
00841 if (chi->Dse_dead())
00842 continue;
00843 CODEREP *res = chi->RESULT();
00844 if (res->Is_flag_set(CF_IS_ZERO_VERSION)) {
00845 has_zver = true;
00846 break;
00847 }
00848 }
00849 FmtAssert(has_zver == (stmt->Has_zver() != 0),
00850 ("Stmt has_zver is wrong."));
00851 }
00852
00853
00854
00855 static void
00856 Verify_version_CR(CODEREP *cr, OPT_STAB *opt_stab, BB_NODE *bb, INT32 linenum)
00857 {
00858 if (!WOPT_Enable_Verify)
00859 return;
00860
00861 IDTYPE id = cr->Aux_id();
00862
00863 if ( cr->Kind() == CK_VAR && cr->Is_var_nodef() &&
00864 !cr->Is_flag_set(CF_IS_ZERO_VERSION) && !cr->Is_var_volatile())
00865 {
00866
00867
00868
00869 if ( ! opt_stab->Is_volatile(cr->Aux_id()) ) {
00870
00871
00872
00873
00874 Is_True(Cur_stmt_is_entry_chi() ||
00875 (cur_stmt->Op() == OPC_REGION && cur_stmt->Black_box()),
00876 ("Verify_version_CR: Found no-def, but current statement is "
00877 "not entry chi"));
00878 }
00879 }
00880
00881 if (opt_stab->NULL_coderep(id)) {
00882 if (!cr->Is_flag_set(CF_IS_ZERO_VERSION) && !cr->Is_var_volatile()) {
00883 FmtAssert(FALSE, ("sym%dv%d(cr%d) use before def in bb%d line %d",
00884 cr->Aux_id(), cr->Version(), cr->Coderep_id(),
00885 bb->Id(), linenum));
00886 }
00887 else {
00888
00889 return;
00890 }
00891 }
00892
00893 const CODEREP *cur_ver = opt_stab->Top_coderep(id);
00894
00895
00896 if (cr == cur_ver)
00897 return;
00898
00899 if (cr->Is_var_volatile())
00900 return;
00901
00902 if (cur_ver->Is_var_volatile())
00903 return;
00904
00905
00906
00907 if (cr->Is_flag_set(CF_IS_ZERO_VERSION)) {
00908
00909
00910
00911
00912
00913 Is_True(cur_ver->Is_flag_set(CF_INCOMPLETE_USES),
00914 ("Zero version cr at BB%d live-range-overlaps with sym%dv%d(cr%d) not marked CF_INCOMPLETE_USES",
00915 bb->Id(), cur_ver->Aux_id(), cur_ver->Version(),
00916 cur_ver->Coderep_id()));
00917 return;
00918 }
00919
00920 FmtAssert(FALSE, ("sym%dv%d(cr%d) live range overlapped with cur_version sym%dv%d(cr%d) in bb%d line %d",
00921 cr->Aux_id(), cr->Version(), cr->Coderep_id(),
00922 cur_ver->Aux_id(), cur_ver->Version(), cur_ver->Coderep_id(),
00923 bb->Id(), linenum));
00924 }
00925
00926
00927
00928 static void
00929 Verify_version_mu_list(MU_LIST *mu_list, OPT_STAB *opt_stab, BB_NODE *bb, INT32 linenum)
00930 {
00931 if (!WOPT_Enable_Verify)
00932 return;
00933
00934 MU_NODE *mnode;
00935 MU_LIST_ITER mu_iter;
00936 FOR_ALL_NODE(mnode, mu_iter, Init(mu_list)) {
00937 Verify_version_CR(mnode->OPND(), opt_stab, bb, linenum);
00938 }
00939 }
00940
00941
00942 static void
00943 Verify_version_chi_list(CHI_LIST *chi_list, OPT_STAB *opt_stab, BB_NODE *bb, INT32 linenum)
00944 {
00945 if (!WOPT_Enable_Verify)
00946 return;
00947
00948 CHI_NODE *cnode;
00949 CHI_LIST_ITER chi_iter;
00950 FOR_ALL_NODE(cnode, chi_iter, Init(chi_list)) {
00951 if ( cnode->Live() ) {
00952 Verify_version_CR(cnode->OPND(), opt_stab, bb, linenum);
00953 }
00954 }
00955 }
00956
00957
00958
00959 static void
00960 Verify_version_expr(CODEREP *expr, OPT_STAB *opt_stab, BB_NODE *bb, INT32 linenum)
00961 {
00962 if (!WOPT_Enable_Verify)
00963 return;
00964
00965 switch (expr->Kind()) {
00966 case CK_LDA:
00967 case CK_CONST:
00968 case CK_RCONST: return;
00969 case CK_VAR:
00970 {
00971 TY_IDX ty = expr->Lod_ty();
00972 if (ty && TY_is_volatile(ty))
00973 return;
00974 Verify_version_CR(expr, opt_stab, bb, linenum);
00975 return;
00976 }
00977 case CK_IVAR:
00978 if (expr->Ilod_base())
00979 Verify_version_expr(expr->Ilod_base(), opt_stab, bb, linenum);
00980 if (expr->Istr_base())
00981 Verify_version_expr(expr->Istr_base(), opt_stab, bb, linenum);
00982 if (expr->Opr() == OPR_MLOAD)
00983 Verify_version_expr(expr->Mload_size(), opt_stab, bb, linenum);
00984 if (expr->Opr() == OPR_ILOADX)
00985 Verify_version_expr(expr->Index(), opt_stab, bb, linenum);
00986 if (! WOPT_Enable_VN_Full) {
00987 MU_NODE *mnode = expr->Ivar_mu_node();
00988 if (mnode)
00989 Verify_version_CR(mnode->OPND(), opt_stab, bb, linenum);
00990
00991 }
00992
00993 if (expr->Ivar_mu_node() != NULL &&
00994 OPERATOR_is_scalar_iload (expr->Opr())) {
00995 FmtAssert(!expr->Ivar_mu_node()->OPND()->Is_flag_set(CF_IS_ZERO_VERSION),
00996 ("CK_IVAR cr%d has zero version mu operand.", expr->Coderep_id()));
00997 }
00998 return;
00999
01000 case CK_OP:
01001 {
01002 #if defined(TARG_NVISA)
01003
01004
01005
01006
01007
01008
01009
01010 if (expr->Is_isop_flag_set(ISOP_VERIFY_EXPR_VISITED))
01011 return;
01012 else
01013 expr->Set_isop_flag (ISOP_VERIFY_EXPR_VISITED);
01014 #endif
01015 for (INT32 i = 0; i < expr->Kid_count(); i++) {
01016 Verify_version_expr(expr->Opnd(i), opt_stab, bb, linenum);
01017 }
01018
01019 FmtAssert(! past_ret_reg_def || expr->Opr() != OPR_INTRINSIC_OP,
01020 ("cr%d is INTRINSIC_OP appearing after the def of a return register", expr->Coderep_id()));
01021 #ifdef KEY
01022 FmtAssert(! past_ret_reg_def || expr->Opr() != OPR_PURE_CALL_OP,
01023 ("cr%d is PURE_CALL_OP appearing after the def of a return register", expr->Coderep_id()));
01024 #endif
01025 }
01026 return;
01027
01028 default:
01029 return;
01030 }
01031 }
01032
01033
01034
01035
01036
01037 static void
01038 Verify_version_istore(STMTREP *stmt, BB_NODE *bb, CODEMAP *htable, OPT_STAB *opt_stab)
01039 {
01040 CODEREP *lhs = stmt->Lhs();
01041 MU_NODE *mnode = lhs->Ivar_mu_node();
01042 if (mnode == NULL) return;
01043
01044 CHI_LIST_ITER chi_iter;
01045 CHI_NODE *cnode;
01046 FOR_ALL_NODE( cnode, chi_iter, Init(stmt->Chi_list())) {
01047 if (cnode->Aux_id() == lhs->Ivar_occ()->Aux_id()) {
01048 FmtAssert(!cnode->Dse_dead(), ("CK_IVAR has non-null mu-node, but dse-dead chi."));
01049 FmtAssert(cnode->RESULT() == mnode->OPND(), ("CK_IVAR has different mu/chi of vsym."));
01050 return;
01051 }
01052 }
01053 FmtAssert(TRUE, ("CK_IVAR has no chi of vsym."));
01054 }
01055
01056
01057
01058 static void
01059 Verify_version_BB(BB_NODE *bb, CODEMAP *htable, OPT_STAB *opt_stab)
01060 {
01061 if (!WOPT_Enable_Verify)
01062 return;
01063
01064 PHI_NODE *phi; PHI_LIST_ITER phi_iter;
01065
01066
01067 FOR_ALL_ELEM (phi, phi_iter, Init(bb->Phi_list())) {
01068 if (phi->Live())
01069 opt_stab->Push_coderep(phi->RESULT()->Aux_id(), phi->RESULT());
01070 }
01071
01072 past_ret_reg_def = FALSE;
01073
01074
01075 STMTREP_ITER stmt_iter(bb->Stmtlist());
01076 STMTREP *stmt;
01077 FOR_ALL_NODE(stmt, stmt_iter, Init()) {
01078
01079 Save_cur_stmt(stmt);
01080
01081 INT32 linenum = Srcpos_To_Line(stmt->Linenum());
01082 if (stmt->Has_chi()) {
01083 Verify_version_chi_list(stmt->Chi_list(), opt_stab, bb, linenum);
01084 Verify_has_zver(stmt);
01085 }
01086
01087 if (stmt->Has_mu())
01088 Verify_version_mu_list(stmt->Mu_list(), opt_stab, bb, linenum);
01089
01090 if (stmt->Rhs()) {
01091 Verify_version_expr(stmt->Rhs(), opt_stab, bb, linenum);
01092 FmtAssert(Def_before_use(stmt->Rhs(), bb), ("use before def."));
01093 }
01094
01095 if (stmt->Lhs() && stmt->Lhs()->Kind() == CK_IVAR) {
01096 Verify_version_expr(stmt->Lhs()->Istr_base(), opt_stab, bb, linenum);
01097 FmtAssert(Def_before_use(stmt->Lhs()->Istr_base(), bb), ("use before def."));
01098 }
01099
01100 if (OPERATOR_is_scalar_store (stmt->Opr()))
01101 opt_stab->Push_coderep(stmt->Lhs()->Aux_id(), stmt->Lhs());
01102 if (stmt->Has_chi()) {
01103 CHI_LIST_ITER chi_iter;
01104 CHI_NODE *cnode;
01105 CHI_LIST *chi_list = stmt->Chi_list();
01106 FOR_ALL_NODE( cnode, chi_iter, Init(chi_list)) {
01107 if (! cnode->Live()) continue;
01108 CODEREP *res = cnode->RESULT();
01109 if (res)
01110 opt_stab->Push_coderep(res->Aux_id(), res);
01111 }
01112 }
01113
01114 if (OPERATOR_is_scalar_istore (stmt->Opr()))
01115 Verify_version_istore(stmt, bb, htable, opt_stab);
01116
01117 if (OPERATOR_is_scalar_store (stmt->Opr()) &&
01118 opt_stab->Aux_stab_entry(stmt->Lhs()->Aux_id())->Is_dedicated_preg())
01119 past_ret_reg_def = TRUE;
01120 }
01121
01122 if (WOPT_Enable_Verify >= 2) {
01123 BB_LIST_ITER bb_iter;
01124 BB_NODE *succ;
01125 FOR_ALL_ELEM(succ, bb_iter, Init(bb->Succ())) {
01126 INT32 pos = succ->Pred()->Pos(bb);
01127 FOR_ALL_ELEM (phi, phi_iter, Init(succ->Phi_list())) {
01128 if (phi->Live())
01129 Verify_version_CR(phi->OPND(pos), opt_stab, succ, -1);
01130 }
01131 }
01132 }
01133
01134
01135 BB_NODE *dom_bb;
01136 BB_LIST_ITER dom_bb_iter;
01137 FOR_ALL_ELEM(dom_bb, dom_bb_iter, Init(bb->Dom_bbs())) {
01138 Verify_version_BB(dom_bb, htable, opt_stab);
01139 }
01140
01141
01142 FOR_ALL_NODE_REVERSE(stmt, stmt_iter, Init()) {
01143 if (stmt->Has_chi()) {
01144 CHI_LIST_ITER chi_iter;
01145 CHI_NODE *cnode;
01146 CHI_LIST *chi_list = stmt->Chi_list();
01147 FOR_ALL_NODE( cnode, chi_iter, Init(chi_list)) {
01148 if (! cnode->Live()) continue;
01149 CODEREP *res = cnode->RESULT();
01150 if (res)
01151 opt_stab->Pop_coderep(res->Aux_id());
01152 }
01153 }
01154 if (OPERATOR_is_scalar_store (stmt->Opr()))
01155 opt_stab->Pop_coderep(stmt->Lhs()->Aux_id());
01156 }
01157
01158 FOR_ALL_ELEM (phi, phi_iter, Init(bb->Phi_list())) {
01159 if (phi->Live())
01160 opt_stab->Pop_coderep(phi->RESULT()->Aux_id());
01161 }
01162 }
01163 #endif
01164
01165
01166
01167 void
01168 COMP_UNIT::Verify_version(void)
01169 {
01170 #ifdef Is_True_On
01171 if (!WOPT_Enable_Verify)
01172 return;
01173
01174 MEM_POOL verify_pool;
01175 OPT_POOL_Initialize(&verify_pool, "verify pool", FALSE, MEM_DUMP_FLAG+13);
01176 OPT_POOL_Push(&verify_pool, MEM_DUMP_FLAG+13);
01177
01178 Opt_stab()->New_coderep(&verify_pool);
01179 Opt_stab()->Clear_coderep();
01180 Opt_stab()->Check_stack();
01181 Verify_version_BB(Cfg()->Entry_bb(), Htable(), Opt_stab());
01182
01183 OPT_POOL_Pop(&verify_pool, MEM_DUMP_FLAG+13);
01184 OPT_POOL_Delete(&verify_pool, MEM_DUMP_FLAG+13);
01185 #endif
01186 }
01187
01188
01189
01190
01191
01192 void
01193 CODEMAP::Verify_hashing(void)
01194 {
01195 #ifndef KEY // bug 13042: this is found to cause the WHIRL output by wopt to
01196
01197 #ifdef Is_True_On
01198 CODEREP_ITER cr_iter;
01199 CODEREP *cr,*bucket;
01200 CODEMAP_ITER codemap_iter;
01201
01202 FOR_ALL_ELEM(bucket, codemap_iter, Init(this)) {
01203 IDX_32 hash_idx = codemap_iter.Cur();
01204 FOR_ALL_NODE(cr, cr_iter, Init(bucket)) {
01205 switch (cr->Kind()) {
01206 case CK_VAR:
01207 break;
01208 case CK_IVAR:
01209 break;
01210 case CK_OP:
01211 if (OPERATOR_is_call(cr->Opr()))
01212 break;
01213 case CK_LDA:
01214 case CK_CONST:
01215 case CK_RCONST:
01216
01217 if (hash_idx != Hash(cr)) {
01218 #if 0
01219 DevWarn("CODEMAP::Verify_hashing: cr%d does not belong to hash bucket %d, "
01220 "should be in bucket %d.",
01221 cr->Coderep_id(), hash_idx, Hash(cr));
01222 #endif
01223 }
01224 }
01225 }
01226 }
01227 #endif
01228 #endif
01229 }