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 #include "opt_wovp.h"
00028 #include "opt_mu_chi.h"
00029
00030
00031
00032
00033
00034 CODEREP* WOVP::Find_by_id(CODEREP *cr, IDTYPE id)
00035 {
00036 INT i;
00037 CODEREP *retval = NULL;
00038 switch (cr->Kind()) {
00039 case CK_VAR:
00040 if (cr->Aux_id() == id)
00041 return cr;
00042 break;
00043 case CK_OP:
00044 for (i=0; i< cr->Kid_count(); i++) {
00045 retval = Find_by_id(cr->Opnd(i), id);
00046 if (retval)
00047 return retval;
00048 }
00049 break;
00050 case CK_IVAR:
00051 if(cr->Ilod_base())
00052 retval = Find_by_id(cr->Ilod_base(), id);
00053 else
00054 retval = Find_by_id(cr->Istr_base(), id);
00055 if (retval)
00056 return retval;
00057 if (OPCODE_operator(cr->Op()) == OPR_MLOAD)
00058 return Find_by_id(cr->Mload_size(), id);
00059 break;
00060 default:
00061 break;
00062 }
00063 return retval;
00064 }
00065
00066
00067
00068
00069
00070 BOOL WOVP::Write_once_check(IDTYPE id, BB_LIST_CONTAINER *bb_queue)
00071 {
00072 INT bb_num = _cfg->Last_bb_id();
00073 IDTYPE bb_id;
00074 BOOL skip_phi;
00075 BB_NODE *bb, *tmp_bb;
00076 CODEREP *cr;
00077 STMTREP *tmp_stmt, *it_stmt, *def_stmt = NULL;
00078 PHI_NODE *phi;
00079 CHI_NODE *cnode;
00080 BB_LIST_ITER pred_bb_iter;
00081 PHI_LIST_ITER phi_list_iter;
00082 CHI_LIST_ITER chi_iter;
00083
00084 BOOL *bb_not_searched = CXX_NEW_ARRAY(BOOL, bb_num+1, &_pool);
00085 for(INT i = 0; i <= bb_num; i++){
00086 bb_not_searched[i] = TRUE;
00087 }
00088
00089 while((bb = bb_queue->Remove_head(&_pool)) != NULL){
00090 bb_id = bb->Id();
00091 if(bb_not_searched[bb_id]){
00092 bb_not_searched[bb_id] = FALSE;
00093 skip_phi = FALSE;
00094
00095
00096 it_stmt = bb->Stmtlist()->Tail();
00097 for( ; it_stmt != NULL; it_stmt = it_stmt->Prev()){
00098 if(it_stmt->Rhs()){
00099 cr = Find_by_id(it_stmt->Rhs(), id );
00100 if(cr){
00101 if(cr->Is_flag_set(CF_DEF_BY_PHI)){
00102 if(def_stmt != NULL)
00103 return FALSE;
00104 bb = cr->Defphi()->Bb();
00105 bb_not_searched[bb->Id()] = FALSE;
00106 skip_phi = TRUE;
00107 break;
00108 }
00109 else if(cr->Defstmt()){
00110 tmp_stmt = cr->Defstmt();
00111 if(tmp_stmt->Opr() == OPR_OPT_CHI){
00112 skip_phi = TRUE;
00113 break;
00114 }
00115 if(def_stmt != NULL)
00116 return FALSE;
00117 def_stmt = tmp_stmt;
00118 it_stmt = tmp_stmt;
00119 bb = tmp_stmt->Bb();
00120 bb_not_searched[bb->Id()] = FALSE;
00121 continue;
00122 }
00123 }
00124 }
00125 if(it_stmt->Lhs()){
00126 cr = Find_by_id(it_stmt->Lhs(), id );
00127 if(cr){
00128 if(cr->Is_flag_set(CF_DEF_BY_PHI)){
00129 if(def_stmt != NULL)
00130 return FALSE;
00131 bb = cr->Defphi()->Bb();
00132 bb_not_searched[bb->Id()] = FALSE;
00133 skip_phi = TRUE;
00134 break;
00135 }
00136 else if(cr->Defstmt()){
00137 tmp_stmt = cr->Defstmt();
00138 if(tmp_stmt->Opr() == OPR_OPT_CHI){
00139 skip_phi = TRUE;
00140 break;
00141 }
00142 if(def_stmt != NULL)
00143 return FALSE;
00144 def_stmt = tmp_stmt;
00145 it_stmt = tmp_stmt;
00146 bb = tmp_stmt->Bb();
00147 bb_not_searched[bb->Id()] = FALSE;
00148 continue;
00149 }
00150 }
00151 }
00152 if(it_stmt->Has_chi()){
00153 if(it_stmt->Opr() == OPR_OPT_CHI){
00154 skip_phi = TRUE;
00155 break;
00156 }
00157 FOR_ALL_NODE(cnode,chi_iter,Init(it_stmt->Chi_list())){
00158 if(cnode->Aux_id()==id){
00159 if(def_stmt != NULL)
00160 return FALSE;
00161 def_stmt = it_stmt;
00162 }
00163 }
00164 }
00165 }
00166 if(!skip_phi){
00167 FOR_ALL_NODE(phi, phi_list_iter, Init(bb->Phi_list()))
00168 if(phi->Aux_id() == id)
00169 if(def_stmt != NULL)
00170 return FALSE;
00171 }
00172 FOR_ALL_ELEM(tmp_bb, pred_bb_iter, Init(bb->Pred()))
00173 bb_queue->Prepend(tmp_bb, &_pool);
00174 }
00175 }
00176 return TRUE;
00177 }
00178
00179
00180 BOOL WOVP::Is_write_once(IDTYPE id)
00181 {
00182 BB_LIST_CONTAINER bb_queue;
00183
00184 MEM_POOL_Push(&_pool);
00185
00186 if(_cfg->Fake_exit_bb() == NULL)
00187 bb_queue.Append(_cfg->Exit_bb(), &_pool);
00188 else{
00189 BB_NODE *exit_bb;
00190 BB_LIST_ITER pred_bb_iter;
00191 FOR_ALL_ELEM(exit_bb, pred_bb_iter, Init(_cfg->Fake_exit_bb()->Pred()))
00192 if(exit_bb->Kind() == BB_EXIT)
00193 bb_queue.Append(exit_bb, &_pool);
00194 }
00195 if(Write_once_check(id, &bb_queue)){
00196 MEM_POOL_Pop(&_pool);
00197 return TRUE;
00198 }
00199 else{
00200 MEM_POOL_Pop(&_pool);
00201 return FALSE;
00202 }
00203 }
00204
00205
00206 void WOVP::Find_mm_pair()
00207 {
00208 POBB_ITER po_iter(_cfg);
00209 BB_NODE *bb_node;
00210 STMT_LIST *stmt_list;
00211 STMTREP *stmtrep;
00212 CODEREP *rhs, *lhs;
00213 AUX_STAB_ENTRY *aux_stab_entry;
00214
00215 FOR_ALL_ELEM(bb_node, po_iter, Init()){
00216 stmt_list = bb_node->Stmtlist();
00217 STMTREP_ITER stmt_iter(stmt_list);
00218 FOR_ALL_NODE(stmtrep, stmt_iter, Init()){
00219 #ifdef Is_True_On
00220 if(stmtrep->Opr() == OPR_MSTORE){
00221 DevWarn("WOVP doesn't take OPR_MSTORE as candidate!");
00222 }
00223 #endif
00224 if(stmtrep->Opr() == OPR_STID){
00225 lhs=stmtrep->Lhs();
00226 if(lhs->Dsctyp() == MTYPE_M){
00227 aux_stab_entry=_opt_stab->Aux_stab_entry(lhs->Aux_id());
00228 if(ST_sclass(aux_stab_entry->St())==SCLASS_AUTO){
00229 rhs=stmtrep->Rhs();
00230 if(rhs->Dsctyp() == MTYPE_M && rhs->Kind() == CK_VAR){
00231 aux_stab_entry = _opt_stab->Aux_stab_entry(rhs->Aux_id());
00232 if(ST_sclass(aux_stab_entry->St()) == SCLASS_PSTATIC){
00233 Add_wo_loc(lhs->Aux_id(),rhs->Aux_id(),stmtrep);
00234 }
00235 }
00236 }
00237 }
00238 }
00239 }
00240 }
00241 }
00242
00243
00244 void WOVP::Promote(void)
00245 {
00246 AUX_STAB_ENTRY *laux, *raux;
00247 WO_LOC *wo_loc;
00248 vector<WO_LOC*>::iterator it;
00249 for(it=_wovp_loc.begin(); it!=_wovp_loc.end(); ++it){
00250 wo_loc = *it;
00251 if(wo_loc->Get_promote()){
00252 laux = _opt_stab->Aux_stab_entry(wo_loc->Get_lid());
00253 raux = _opt_stab->Aux_stab_entry(wo_loc->Get_rid());
00254 *(laux->St()) = *(raux->St());
00255 }
00256 }
00257 }
00258
00259
00260 void WOVP::Do_wovp()
00261 {
00262 WO_LOC *wo_loc;
00263 STMTREP *stmt;
00264 vector<WO_LOC*>::iterator it;
00265
00266 Find_mm_pair();
00267 for(it=_wovp_loc.begin(); it!=_wovp_loc.end(); ++it){
00268 wo_loc = *it;
00269 if(Is_write_once(wo_loc->Get_lid())&&Is_write_once(wo_loc->Get_rid())){
00270 wo_loc->Set_promote(TRUE);
00271 }
00272 }
00273 if(!_wovp_loc.empty()) {
00274 Promote();
00275
00276
00277 _cfg->Htable()->Verify_hashing();
00278
00279 } if(Get_Trace(TP_WOPT2, WOVP_DUMP_FLAG)){
00280 fprintf(TFile, "%sAfter Write Once Variable Promotion\n%s", DBar, DBar);
00281 Print_wo_loc(Get_Trace_File());
00282 _cfg->Print(Get_Trace_File());
00283 }
00284 return;
00285 }
00286
00287
00288 void WOVP::Print_wo_loc(FILE *fp)
00289 {
00290 WO_LOC *wo_loc;
00291 STMTREP *stmt;
00292 vector<WO_LOC*>::iterator it;
00293
00294 fprintf(fp, "Print_wo_loc\n");
00295 for(it=_wovp_loc.begin(); it!=_wovp_loc.end(); ++it){
00296 wo_loc = *it;
00297 if(wo_loc->Get_promote()){
00298 fprintf(fp, "Left_Opr:%3d ",wo_loc->Get_lid());
00299 fprintf(fp, "Right_Opr:%3d\n",wo_loc->Get_rid());
00300 fprintf(fp, "Stmt:\n");
00301 wo_loc->Get_stmt()->Print(fp);
00302 }
00303 }
00304 }