00001
00002 #include <set>
00003 #include <vector>
00004
00005
00006 #include "ProgramUnit.h"
00007 #include "eg_utils.h"
00008 #include "Range/AIRangeDict.h"
00009 #include "utilities/stmt_util.h"
00010 #include "ip_ssa/ip_ssa.h"
00011
00012 static DoStmt* LOOP_ROOT=0;
00013
00014
00015 bool inner(DoStmt* first, DoStmt* second){
00016 if (first==second){
00017 return true;
00018 }
00019 while(first){
00020 if (first==second){
00021 return true;
00022 }
00023 first=(DoStmt*)first->outer_ref();
00024 }
00025 if (first==second){
00026 return true;
00027 }
00028 return false;
00029 }
00030
00031
00032 bool outer(DoStmt* first, DoStmt* second){
00033 return inner(second, first);
00034 }
00035
00036
00037 DoStmt* common_outer(DoStmt* first, DoStmt* second){
00038
00039 if (first==LOOP_ROOT || second==LOOP_ROOT){
00040 return LOOP_ROOT;
00041 }
00042
00043 set<DoStmt*> outer_first;
00044 while(first){
00045 if (first==second){
00046
00047 return first;
00048 }
00049 outer_first.insert(first);
00050 first=(DoStmt*)first->outer_ref();
00051 }
00052 while(second){
00053 if (outer_first.find(second)!=outer_first.end()){
00054
00055 return second;
00056 }
00057 second=(DoStmt*)second->outer_ref();
00058 }
00059
00060 return LOOP_ROOT;
00061 }
00062
00063 DoStmt* common_outer(set<DoStmt*>& loops){
00064 set<DoStmt*>::iterator it=loops.begin();
00065 if (it==loops.end()){
00066 return LOOP_ROOT;
00067 }
00068 DoStmt* toret=*it;
00069 for( ; it!=loops.end(); ++it){
00070 DoStmt* second=*it;
00071 toret=common_outer(toret, second);
00072 if (toret==LOOP_ROOT){
00073 return toret;
00074 }
00075 }
00076 return toret;
00077 }
00078
00079
00080
00081
00082
00083 DoStmt* loop(const Symbol& sym, ProgramUnit& pgm){
00084 DefLoc* defloc=pgm.gsa_deflocs_guarded().find_ref(sym);
00085 if (defloc){
00086 if (defloc->stmt_valid()){
00087 Statement& def=defloc->stmt_guarded();
00088 if (def.stmt_class()==DO_STMT){
00089 return (DoStmt*)&def;
00090 }
00091 if (def.stmt_class()==ASSIGNMENT_STMT){
00092 if (def.rhs().op()==MU_OP){
00093 Statement* ps=&def;
00094 while (ps->stmt_class()!=DO_STMT){
00095 ps=ps->prev_ref();
00096 p_assert(ps, "No DO before MU assignment.");
00097 }
00098 return (DoStmt*)ps;
00099 }
00100 }
00101 }
00102 }
00103 return (DoStmt*)0;
00104 }
00105
00106
00107
00108
00109
00110 DoStmt* def_loop(const Symbol& sym, ProgramUnit& pgm){
00111 DefLoc* defloc=pgm.gsa_deflocs_guarded().find_ref(sym);
00112 if (defloc){
00113 if (defloc->stmt_valid()){
00114 Statement* ps=&defloc->stmt_guarded();
00115 if (ps->stmt_class()==DO_STMT){
00116 return (DoStmt*)ps;
00117 } else {
00118 return (DoStmt*)ps->outer_ref();
00119 }
00120 }
00121 }
00122 return (DoStmt*)0;
00123 }
00124
00125 Expression* iteration_count(DoStmt& loop, ProgramUnit& pgm){
00126 Expression* toret=simplify(div(add(sub(loop.limit().clone(),
00127 loop.init().clone()),
00128 loop.step().clone()),
00129 loop.step().clone()));
00130 if (!pgm.range_dict_valid()){
00131 pgm.range_dict(new AIRangeDict(pgm));
00132 }
00133 RangeAccessor ra(pgm.range_dict_guarded(), *range_stmt(loop));
00134 switch (ra.signz(*toret)){
00135 case POS_EXPR:
00136 return toret;
00137 case ZERO_EXPR:
00138 delete toret;
00139 return constant(0);
00140 case NEG_EXPR:
00141 return simplify(sub(constant(0), toret));
00142 case POS_NEG_EXPR:
00143 default:
00144 {
00145 Symbol *max_sym = pgm.symtab().find_ref("MAX");
00146 p_assert(max_sym, "MAX intrinsic not in symbol table");
00147 toret=intrinsic_call(id(*max_sym), comma(toret, constant(0)));
00148 return toret;
00149 }
00150 }
00151 }
00152
00153
00154 Expression* last_value(DoStmt& loop, ProgramUnit& pgm){
00155 return simplify(add(loop.init().clone(),
00156 mul(sub(iteration_count(loop, pgm),
00157 constant(1)),
00158 loop.step().clone())));
00159 }
00160
00161
00162 void sort_loops_preorder_lr(Statement& first, Statement& last,
00163 DoStmt* outer,
00164 vector<DoStmt*>& sorted){
00165 sorted.push_back(outer);
00166 for(Statement* ps=&first; ps && ps!=&last; ps=ps->next_ref()){
00167 if(ps->stmt_class()==DO_STMT){
00168 sort_loops_preorder_lr(*ps->next_ref(), *ps->follow_ref(),
00169 (DoStmt*)ps, sorted);
00170 ps=ps->follow_ref();
00171 }
00172 }
00173 }
00174
00175 void sort_loops_postorder_lr(Statement& first, Statement& last,
00176 DoStmt* outer,
00177 vector<DoStmt*>& sorted){
00178 for(Statement* ps=&first; ps && ps!=&last; ps=ps->next_ref()){
00179 if(ps->stmt_class()==DO_STMT){
00180 sort_loops_postorder_lr(*ps->next_ref(), *ps->follow_ref(),
00181 (DoStmt*)ps, sorted);
00182 ps=ps->follow_ref();
00183 }
00184 }
00185 sorted.push_back(outer);
00186 }
00187
00188
00189 bool p_less_equal(const Expression& e1, const Expression& e2,
00190 RangeAccessor* ra){
00191 if (e1==e2){
00192 return true;
00193 }
00194 if (ra) {
00195 Relation rel=ra->compare(e1, e2);
00196 if (rel.is_less_equal()){
00197 return true;
00198 }
00199 }
00200 Expression* diff=simplify(sub(e1.clone(), e2.clone()));
00201 if (diff->op()==INTEGER_CONSTANT_OP){
00202 if (diff->value()<=0){
00203 delete diff;
00204 return true;
00205 }
00206 } else {
00207 if (diff->op()==INFINITY_OP){
00208 bool toret=(diff->sign()==-1);
00209 delete diff;
00210 return toret;
00211 }
00212 }
00213 delete diff;
00214
00215
00216 return false;
00217 }
00218
00219 bool p_greater_equal(const Expression& e1, const Expression& e2,
00220 RangeAccessor* ra){
00221 if (e1==e2){
00222 return true;
00223 }
00224 if (ra) {
00225 Relation rel=ra->compare(e1, e2);
00226 if (rel.is_greater_equal()){
00227 return true;
00228 }
00229 }
00230 Expression* diff=simplify(sub(e1.clone(), e2.clone()));
00231 if (diff->op()==INTEGER_CONSTANT_OP){
00232 if (diff->value()>=0){
00233 delete diff;
00234 return true;
00235 }
00236 } else {
00237 if (diff->op()==INFINITY_OP){
00238 bool toret=(diff->sign()==1);
00239 delete diff;
00240 return toret;
00241 }
00242 }
00243 delete diff;
00244
00245
00246 return false;
00247 }
00248
00249 bool p_less_than(const Expression& e1,
00250 const Expression& e2, RangeAccessor* ra){
00251
00252 if (ra) {
00253 Relation rel=ra->compare(e1, e2);
00254 if (rel.is_less_than()){
00255 return true;
00256 }
00257 }
00258 Expression* diff=simplify(sub(e1.clone(), e2.clone()));
00259 if (diff->op()==INTEGER_CONSTANT_OP){
00260 if (diff->value()<0){
00261 delete diff;
00262 return true;
00263 }
00264 } else {
00265 if (diff->op()==INFINITY_OP){
00266 bool toret=(diff->sign()==-1);
00267 delete diff;
00268 return toret;
00269 }
00270 }
00271 delete diff;
00272
00273
00274 return false;
00275 }
00276
00277 bool p_greater_than(const Expression& e1, const Expression& e2,
00278 RangeAccessor* ra){
00279 if (ra) {
00280 Relation rel=ra->compare(e1, e2);
00281 if (rel.is_greater_than()){
00282 return true;
00283 }
00284 }
00285
00286
00287
00288
00289 Expression* diff=simplify(sub(e1.clone(), e2.clone()));
00290 if (diff->op()==INTEGER_CONSTANT_OP){
00291 if (diff->value()>0){
00292 delete diff;
00293 return true;
00294 }
00295 } else {
00296 if (diff->op()==INFINITY_OP){
00297 bool toret=(diff->sign()==1);
00298 delete diff;
00299 return toret;
00300 }
00301 }
00302 delete diff;
00303
00304
00305 return false;
00306 }
00307
00308
00309
00310 void get_phinode_entries(const Expression& phinode,
00311 RefList<Symbol>& entries){
00312 Iterator<Expression> eit=phinode.parameters_guarded().arg_list();
00313 for( ; eit.valid(); ++eit){
00314 switch(eit.current().op()){
00315 case ID_OP:
00316 if (!entries.member(eit.current().symbol())){
00317 entries.ins_last(eit.current().symbol());
00318 }
00319 break;
00320 case MU_OP:
00321 case GAMMA_OP:
00322 case ETA_OP:
00323 case THETA_OP:
00324 get_phinode_entries(eit.current(), entries);
00325 break;
00326 case OMEGA_OP:
00327 for(Iterator<Expression> oit=eit.current().arg_list();
00328 oit.valid(); ++oit){
00329 get_phinode_entries(oit.current(), entries);
00330 }
00331 break;
00332 default:
00333 cerr<<"\nExpression = "<<eit.current().op();
00334 p_abort("Unsupported expression type in a PHI node.");
00335 }
00336 }
00337 }
00338
00339
00340 DoStmt* find_loop_same_level(ProgramUnit& pgm, Symbol& sym, DoStmt& l){
00341 DefLoc* defloc=pgm.gsa_deflocs_guarded().find_ref(sym);
00342 if (defloc){
00343 if (defloc->stmt_valid()){
00344 Statement* ps=&defloc->stmt_guarded();
00345 while (ps){
00346 if (ps->outer_ref()==l.outer_ref()){
00347 break;
00348 }
00349
00350 ps=ps->outer_ref();
00351 }
00352 if (ps){
00353
00354 return (DoStmt*)ps;
00355 }
00356 }
00357 }
00358 return 0;
00359 }
00360
00361
00362
00363
00364
00365
00366 bool loop_variant(Symbol& s, Statement* loop, ProgramUnit& pgm){
00367 if (loop==0){
00368 p_abort("'loop_variant' called with NULL argument.");
00369 } else {
00370 DefLoc* defloc=pgm.gsa_deflocs_guarded().find_ref(s);
00371 if (!defloc){
00372
00373 return false;
00374 }
00375 if (!defloc->stmt_valid()){
00376
00377 return false;
00378 }
00379 Statement* ps=&defloc->stmt_guarded();
00380 while(ps && ps!=loop){
00381 ps=ps->outer_ref();
00382 }
00383 if (ps==loop){
00384
00385 return true;
00386 } else {
00387 return false;
00388 }
00389 }
00390 }