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 #include "defs.h"
00058 #include "config_wopt.h"
00059 #include "opt_defs.h"
00060 #include "mempool.h"
00061 #include "opt_base.h"
00062 #include "opt_htable.h"
00063 #include "opt_mu_chi.h"
00064 #include "opt_fold.h"
00065
00066
00067
00068
00069
00070
00071
00072 static BOOL
00073 Has_overlapping_liverange(INT exam_stmtcnt, CODEREP *cr, STMTREP *stmt)
00074 {
00075 if (stmt == NULL) return FALSE;
00076
00077 for (INT i = 0; i < exam_stmtcnt; i++) {
00078 if (OPERATOR_is_scalar_store (stmt->Opr())) {
00079 if (stmt->Lhs()->Aux_id() == cr->Aux_id() && stmt->Lhs() != cr ) {
00080
00081 return TRUE;
00082 }
00083 } else if (stmt->Has_chi()) {
00084 CHI_LIST_ITER chi_iter;
00085 CHI_NODE *cnode;
00086 FOR_ALL_NODE ( cnode, chi_iter, Init(stmt->Chi_list()) ) {
00087 if (cnode->Aux_id() == cr->Aux_id())
00088 return TRUE;
00089 }
00090 }
00091 stmt = stmt->Next();
00092 if (stmt == NULL)
00093 return FALSE;
00094 }
00095 return TRUE;
00096 }
00097
00098
00099
00100
00101 static CODEREP *
00102 Rehash_tree_rec(CODEREP *newcr,
00103 BOOL prop,
00104 BOOL *changed,
00105 CODEMAP *htable,
00106 BB_NODE *bb,
00107 OPT_STAB *sym)
00108 {
00109 switch (newcr->Kind()) {
00110 case CK_LDA:
00111 case CK_CONST:
00112 case CK_RCONST:
00113 return newcr;
00114
00115 case CK_VAR:
00116 Is_True(!newcr->Is_flag_set(CF_IS_ZERO_VERSION),
00117 ("Rehash_tree_rec: CK_VAR is zero version."));
00118 if (prop &&
00119 !newcr->Is_var_volatile() &&
00120 newcr->Defstmt() != NULL &&
00121 !newcr->Is_flag_set((CR_FLAG)(CF_DEF_BY_PHI|CF_DEF_BY_CHI))) {
00122 CODEREP *rhs = newcr->Defstmt()->Rhs();
00123
00124 BOOL fold_it = FALSE;
00125
00126 if (inCODEKIND( rhs->Kind(), CK_LDA|CK_CONST|CK_RCONST)) fold_it = TRUE;
00127 else if (rhs->Kind() == CK_VAR) {
00128 ST *s = sym->St(rhs->Aux_id());
00129 if ((ST_class(s) == CLASS_PREG && Preg_Is_Dedicated(rhs->Offset())))
00130 return newcr;
00131
00132 STMTREP *defstmt = newcr->Defstmt();
00133 BB_NODE *defbb = defstmt->Bb();
00134 BOOL overlapped = FALSE;
00135 if (defbb == bb) {
00136 fold_it = ! Has_overlapping_liverange
00137 (WOPT_Enable_Ocopy_Lookupstmt+bb->Loopdepth(), rhs, defstmt);
00138 }
00139 else if (defbb == bb->Prev() && bb->Idom() == defbb) {
00140 fold_it = ! Has_overlapping_liverange
00141 (WOPT_Enable_Ocopy_Lookupstmt+bb->Loopdepth(), rhs, bb->First_stmtrep());
00142 if (fold_it)
00143 fold_it = ! Has_overlapping_liverange
00144 (WOPT_Enable_Ocopy_Lookupstmt+bb->Loopdepth(), rhs, defstmt);
00145 if (fold_it) {
00146
00147 PHI_LIST_ITER phi_iter;
00148 PHI_NODE *phi;
00149 AUX_ID aux_id = rhs->Aux_id();
00150 FOR_ALL_ELEM (phi, phi_iter, Init(bb->Phi_list())) {
00151 if (phi->Aux_id() == aux_id)
00152 fold_it = FALSE;
00153 }
00154 }
00155 }
00156 }
00157 if (fold_it) {
00158 Is_Trace(htable->Tracing(), (TFile, " Rehash tree replace:"));
00159 Is_Trace_cmd(htable->Tracing(), newcr->Print(0,TFile));
00160 Is_Trace(htable->Tracing(), (TFile, " with:"));
00161 Is_Trace_cmd(htable->Tracing(), rhs->Print(0,TFile));
00162 *changed = TRUE;
00163 #ifdef KEY // fix bug 2657
00164 rhs = newcr->Convert_type(htable, rhs, FALSE);
00165 #endif
00166 return rhs;
00167 }
00168 }
00169 return newcr;
00170
00171 case CK_IVAR:
00172 {
00173 BOOL kid_changed = FALSE;
00174 CODEREP *ilod_base = newcr->Ilod_base();
00175 CODEREP *istr_base = newcr->Istr_base();
00176 UINT orig_cr_id = newcr->Coderep_id();
00177
00178 if (newcr->Coderep_id() != 0) {
00179
00180
00181
00182 CODEREP *copy_cr;
00183 copy_cr = Alloc_stack_cr(newcr->Extra_ptrs_used());
00184 copy_cr->Copy(*newcr);
00185 newcr = copy_cr;
00186 }
00187 else {
00188
00189
00190 if (newcr->Ivar_mu_node() != NULL)
00191 newcr->Set_ivar_mu_node(CXX_NEW(MU_NODE(*newcr->Ivar_mu_node()),
00192 htable->Sym()->Occ_pool()));
00193 else
00194 newcr->Set_ivar_mu_node(NULL);
00195
00196 if (newcr->Ivar_occ() != NULL)
00197 newcr->Set_ivar_occ(CXX_NEW(OCC_TAB_ENTRY(*newcr->Ivar_occ()),
00198 htable->Sym()->Occ_pool()));
00199 else
00200 newcr->Set_ivar_occ(NULL);
00201
00202 newcr->Set_coderep_id(0);
00203 }
00204
00205
00206
00207
00208
00209 if (ilod_base == istr_base) {
00210 CODEREP *x = Rehash_tree_rec(ilod_base, prop, &kid_changed,
00211 htable, bb, sym);
00212 if (x != ilod_base) {
00213 newcr->Set_ilod_base(x);
00214 newcr->Set_istr_base(x);
00215 }
00216 } else {
00217 if (ilod_base) {
00218 CODEREP *x = Rehash_tree_rec(ilod_base, prop, &kid_changed,
00219 htable, bb, sym);
00220 newcr->Set_ilod_base(x);
00221 }
00222 if (istr_base) {
00223 CODEREP *x = Rehash_tree_rec(istr_base, prop, &kid_changed,
00224 htable, bb, sym);
00225 newcr->Set_istr_base(x);
00226 }
00227 }
00228 CODEREP *cr_after_simp = NULL;
00229 if (kid_changed) {
00230 FOLD ftmp;
00231 cr_after_simp = ftmp.Fold_Expr(newcr);
00232 *changed = TRUE;
00233 }
00234 if (cr_after_simp == NULL) {
00235 newcr = htable->Rehash(newcr);
00236 if (orig_cr_id != 0 &&
00237 orig_cr_id != newcr->Coderep_id())
00238 *changed = TRUE;
00239 } else
00240 newcr = cr_after_simp;
00241
00242 #ifdef KEY // bug 5285
00243 if (newcr->Kind() == CK_CONST)
00244 return newcr;
00245 #endif
00246
00247
00248 Is_True(newcr->Kind()==CK_IVAR || (newcr->Kind()==CK_OP &&
00249 (newcr->Opr()==OPR_CVT ||
00250 newcr->Opr()==OPR_CVTL)),
00251 ("Rehash_tree_rec: illegal CK_IVAR after folding"));
00252
00253 CODEREP *newcr_ivar;
00254 if (newcr->Kind() == CK_IVAR) {
00255 newcr_ivar = newcr;
00256 } else {
00257 newcr_ivar = newcr->Opnd(0);
00258 *changed = TRUE;
00259 }
00260 if (prop &&
00261 !newcr_ivar->Is_var_volatile() &&
00262 newcr_ivar->Ivar_defstmt() != NULL &&
00263 !newcr_ivar->Is_flag_set((CR_FLAG)(CF_DEF_BY_PHI|CF_DEF_BY_CHI)) &&
00264 inCODEKIND( newcr_ivar->Ivar_defstmt()->Rhs()->Kind(), CK_LDA|CK_CONST|CK_RCONST)) {
00265 Is_Trace(htable->Tracing(), (TFile, " Rehash tree replace:"));
00266 Is_Trace_cmd(htable->Tracing(), newcr->Print(0,TFile));
00267 Is_Trace(htable->Tracing(), (TFile, " with:"));
00268 Is_Trace_cmd(htable->Tracing(), newcr_ivar->Ivar_defstmt()->Rhs()->Print(0,TFile));
00269 *changed = TRUE;
00270
00271 if (newcr->Kind() != CK_IVAR) {
00272 newcr->Set_opnd(0, newcr_ivar->Ivar_defstmt()->Rhs());
00273 newcr->Set_coderep_id(0);
00274 return htable->Rehash(newcr);
00275 } else
00276 return newcr->Ivar_defstmt()->Rhs();
00277
00278 } else
00279 return newcr;
00280 }
00281
00282 case CK_OP:
00283 {
00284 if (newcr->Coderep_id() != 0) {
00285 CODEREP *copy_cr = Alloc_stack_cr(newcr->Extra_ptrs_used());
00286 copy_cr->Copy(*newcr);
00287 newcr = copy_cr;
00288 }
00289 for (INT i = 0; i < newcr->Kid_count(); i++) {
00290 BOOL kid_changed = FALSE;
00291 newcr->Set_opnd(i, Rehash_tree_rec(newcr->Opnd(i), prop,
00292 &kid_changed, htable, bb, sym));
00293 *changed |= kid_changed;
00294 }
00295 if (*changed &&
00296 (prop || newcr->Opr() == OPR_CVT || newcr->Opr() == OPR_CVTL)) {
00297 FOLD ftmp;
00298 CODEREP *x = ftmp.Fold_Expr(newcr);
00299 if (x != NULL)
00300 return x;
00301 }
00302
00303 return htable->Rehash(newcr, !OPCODE_is_compare(newcr->Op()));
00304 }
00305
00306 default:
00307 Is_True(FALSE, ("unexpected CK_KIND."));
00308 }
00309 return NULL;
00310 }
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320 CODEREP *
00321 CODEMAP::Rehash_tree(CODEREP *newcr, BOOL prop, BOOL *changed, BB_NODE *bb)
00322 {
00323 BOOL local_changed = FALSE;
00324 CODEREP *retval = Rehash_tree_rec(newcr, prop, &local_changed,
00325 this, bb, Sym());
00326 if (changed != NULL) {
00327 *changed = local_changed;
00328 }
00329 return retval;
00330 }