Polaris: eg_utils.cc Source File

eg_utils.cc

Go to the documentation of this file.
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 /// first contained in second.
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 /// first contains second.
00032 bool outer(DoStmt* first, DoStmt* second){
00033   return inner(second, first);
00034 }
00035 
00036 
00037 DoStmt* common_outer(DoStmt* first, DoStmt* second){
00038 /// Quick test.
00039   if (first==LOOP_ROOT || second==LOOP_ROOT){
00040     return LOOP_ROOT;
00041   }
00042 /// Store all loops outer to 'first'.
00043   set<DoStmt*> outer_first;
00044   while(first){
00045     if (first==second){
00046       /// ...  Second is outer to first.
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       /// ...  One of 'first's parents is a parent of second.
00055       return second;
00056     }
00057     second=(DoStmt*)second->outer_ref();
00058   }
00059 /// Both are first level loops.
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   \brief Returns loop header if the given symbol appears in the LHS of a MU.
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   \brief Returns header of innermost loop where this symbol is defined.
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 /// Be conservative.
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 /// Be conservative.
00246   return false;
00247 }
00248 
00249 bool p_less_than(const Expression& e1, 
00250          const Expression& e2, RangeAccessor* ra){
00251 ///   cerr<<"\n"<<e1.op()<<" "<<e2.op();
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 /// Be conservative.
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 ///   if (!(e1.type().data_type()==e2.type().data_type())){
00286 ///     cerr<<"\ne1 = "<<e1<<"\ne2 = "<<e2;
00287 ///     cerr<<"\ne1.op = "<<e1.op();
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 /// Be conservative.
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     /// ...  Get out.
00350     ps=ps->outer_ref();
00351       }
00352       if (ps){
00353     /// ...  Found it.
00354     return (DoStmt*)ps;
00355       }
00356     }
00357   }
00358   return 0;
00359 }
00360 
00361 
00362 
00363 /// If loop is a DoStmt, return whether the given symbol is loop variant.
00364 /// If loop is a null pointer, return whether the given symbol is a 
00365 /// modified variable (SSA number > 0).
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       /// ...  Predefined.
00373       return false;
00374     }
00375     if (!defloc->stmt_valid()){
00376       /// ...  Predefined.
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       /// ...  Definition inside _loop.
00385       return true;
00386     } else {
00387       return false;
00388     }
00389   }
00390 }
 © 1995-2005 University of Illinois, Urbana-Champaign. All rights reserved.  Fri Mar 25 23:05:45 2005