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 #ifndef opt_lftr2_INCLUDED
00052 #define opt_lftr2_INCLUDED "opt_lftr2.h"
00053 #ifdef _KEEP_RCS_ID
00054 static char *opt_lftr2rcs_id = opt_lftr2_INCLUDED"$Revision: 1.5 $";
00055 #endif
00056
00057 #include "defs.h"
00058 #include "errors.h"
00059 #include "erglob.h"
00060 #include "tracing.h"
00061 #include "opt_defs.h"
00062 #include "opt_base.h"
00063 #include "cxx_memory.h"
00064 #include "opt_bb.h"
00065 #include "opt_htable.h"
00066 #include "opt_ssa.h"
00067 #include "opt_sym.h"
00068 #include "opt_etable.h"
00069 #ifndef opt_util_INCLUDED
00070 #include "opt_util.h"
00071 #endif
00072
00073
00074
00075
00076 class LFTR_VAR : public SLIST_NODE {
00077 private:
00078 AUX_ID _aux_id;
00079 EXP_OCCURS *_comp_list;
00080 INT32 _list_size;
00081
00082 LFTR_VAR(void);
00083 LFTR_VAR(const LFTR_VAR&);
00084 LFTR_VAR& operator = (const LFTR_VAR&);
00085
00086 public:
00087 LFTR_VAR(AUX_ID lftr_var)
00088 { _aux_id = lftr_var;
00089 _comp_list = NULL;
00090 _list_size = 0;
00091 }
00092 ~LFTR_VAR(void) { }
00093 void Init(void) { }
00094
00095 DECLARE_SLIST_NODE_CLASS( LFTR_VAR )
00096
00097
00098
00099 void Add_comparison(EXP_OCCURS *);
00100
00101
00102 void Add_comparison(CODEREP *, STMTREP *, INT32, MEM_POOL *, BOOL);
00103
00104
00105 LFTR_VAR *Find_comp_list(AUX_ID);
00106
00107 EXP_OCCURS *Occ_list(void) const { return _comp_list; }
00108 void Set_occ_list(EXP_OCCURS *occ) { _comp_list = occ; }
00109 AUX_ID Lftr_var(void) const { return _aux_id; }
00110 INT32 Size(void) const { return _list_size; }
00111 void Dec_list_size(void) { _list_size--; }
00112 void Inc_list_size(void) { _list_size++; }
00113 void Print(FILE *);
00114 };
00115
00116 class LFTR_VAR_CONTAINER : public SLIST {
00117 private:
00118 LFTR_VAR_CONTAINER(const LFTR_VAR_CONTAINER&);
00119 LFTR_VAR_CONTAINER& operator = (const LFTR_VAR_CONTAINER&);
00120
00121 DECLARE_SLIST_CLASS(LFTR_VAR_CONTAINER, LFTR_VAR)
00122 public:
00123 ~LFTR_VAR_CONTAINER(void) { }
00124 void Init(void) { }
00125 };
00126
00127 class LFTR_VAR_ITER : public SLIST_ITER {
00128 DECLARE_SLIST_ITER_CLASS(LFTR_VAR_ITER, LFTR_VAR, LFTR_VAR_CONTAINER)
00129 public:
00130 void Init(void) { }
00131 };
00132
00133
00134
00135
00136 class LFTR {
00137 private:
00138 BOOL _trace;
00139 BOOL _lftr_on;
00140 INT32 _num_substitutions;
00141 MEM_POOL _mem_pool;
00142 ETABLE *_etable;
00143 CODEMAP *_htable;
00144 CFG *_cfg;
00145 EXP_WORKLST_ITER2 *_exp_iter;
00146
00147 LFTR_VAR **_hash_vec;
00148 INT32 _hash_size;
00149 INT32 _len;
00150
00151 DYN_ARRAY<INT32> _stmt_no;
00152 INT32 _last_stmt;
00153
00154 LFTR(void);
00155 LFTR(const LFTR&);
00156 LFTR& operator = (const LFTR&);
00157
00158
00159 void Set_len(INT32 size) { _len = size; }
00160
00161
00162
00163 BOOL Is_lftr_exp(CODEREP *cr)
00164 { if (Lftr_on()) {
00165 switch(OPCODE_operator(cr->Op())) {
00166 case OPR_ADD:
00167 case OPR_SUB:
00168 case OPR_MPY:
00169 #ifdef TARG_X8664
00170 case OPR_CVT:
00171 #endif
00172 return TRUE;
00173 }
00174 }
00175 return FALSE;
00176 }
00177
00178 CODEREP *Set_lhs_and_rhs(CODEREP *cr, CODEREP **rhs)
00179 { *rhs = (cr->Kid_count() == 2) ? cr->Opnd(1) : NULL;
00180 return cr->Opnd(0);
00181 }
00182
00183
00184 void Add_comparison(CODEREP *cr, AUX_ID lftr_var, STMTREP *stmt,
00185 INT32 stmt_kid_num);
00186
00187
00188 void Remove_comparison(EXP_OCCURS *comp, AUX_ID lftr_var);
00189
00190
00191 void Alloc_hash_vec(INT32);
00192 IDX_32 Hash_lftr_var(AUX_ID aux_id)
00193 { Is_True(aux_id != ILLEGAL_AUX_ID,
00194 ("LFTR::Hash_lftr_var, aux_id out of range"));
00195 return aux_id % _hash_size;
00196 }
00197 LFTR_VAR *Find_comp_list(AUX_ID lftr_var);
00198
00199
00200 CODEREP *Find_lftr_var(CODEREP *);
00201
00202
00203
00204 CODEREP *Find_lftr_var(CODEREP *exp, CODEREP *var);
00205
00206 AUX_ID Find_lftr_var_id(CODEREP *cr)
00207 { CODEREP *ret = Find_lftr_var(cr);
00208 return (ret == NULL) ? ILLEGAL_AUX_ID : ret->Aux_id();
00209 }
00210
00211
00212
00213 CODEREP *Replace_lftr_var(CODEREP *, AUX_ID, CODEREP *);
00214
00215
00216 CODEREP *Find_SR_tempcr(STMTREP *, CODEREP *);
00217
00218 void Lftr_comparison(CODEREP *cr, STMTREP *stmt, INT32 stmt_kid_num);
00219
00220 void Check_for_obsolete_comparison(EXP_OCCURS *);
00221
00222 BOOL Can_only_increase(CODEREP *, AUX_ID);
00223
00224
00225 void Print_occ(FILE *fp, const char *str, EXP_OCCURS *occ)
00226 { fprintf(fp,"%s\n",str);
00227 occ->Print(fp);
00228 occ->Occurrence()->Print(0,fp);
00229 }
00230
00231 public:
00232
00233 LFTR(ETABLE *, CODEMAP *, CFG *, mUINT32);
00234
00235 ~LFTR(void);
00236
00237 BOOL Trace(void) { return _trace; }
00238 BOOL Lftr_on(void) { return _lftr_on; }
00239 INT32 Num_substitutions(void) { return _num_substitutions; }
00240 ETABLE *Etable(void) { return _etable; }
00241 CODEMAP *Htable(void) { return _htable; }
00242 CFG *Cfg(void) { return _cfg; }
00243 IDX_32 Stmt_no(IDX_32 index) { return _stmt_no[index]; }
00244 void Free_hash_vec(void);
00245
00246
00247 EXP_WORKLST_ITER2 *Exp_iter(void) const { return _exp_iter; }
00248 void Set_exp_iter(EXP_WORKLST_ITER2 *exp_iter) { if (Lftr_on())
00249 _exp_iter = exp_iter; }
00250
00251
00252 BOOL Is_comparison(CODEREP *cr)
00253 { if (cr->Kind() == CK_OP) {
00254 switch(OPCODE_operator(cr->Op())) {
00255 case OPR_LNOT:
00256 case OPR_EQ:
00257 case OPR_NE:
00258 case OPR_GT:
00259 case OPR_GE:
00260 case OPR_LT:
00261 case OPR_LE:
00262 return TRUE;
00263 }
00264 }
00265 return FALSE;
00266 }
00267
00268
00269 void Clear_def_occurs(EXP_WORKLST *exp_worklst);
00270
00271
00272 void Insert_comp_occurrence(CODEREP *cr, STMTREP *stmt, INT32 stmt_kid_num)
00273 {
00274 if (Lftr_on() && Is_comparison(cr))
00275 Lftr_comparison(cr, stmt, stmt_kid_num);
00276 }
00277
00278
00279 void Assign_stmt_no(STMTREP *);
00280
00281
00282 EXP_OCCURS_PAIR *Exp_hash(EXP_WORKLST *worklst);
00283
00284 INT32 Len(void) { return _len; }
00285
00286
00287 void Replace_comparison(EXP_OCCURS *comp, BOOL cur_expr_is_sr_candidate);
00288
00289 void Remove_lftr_non_candidates(void);
00290
00291
00292
00293 void Remove_comp_occur(EXP_OCCURS *occur);
00294
00295 void Update_comp_occur_stmt(EXP_OCCURS *occur, STMTREP *stmt);
00296
00297 void Print(FILE *);
00298 };
00299
00300 #endif // opt_lftr_INCLUDED