Polaris: gsa_util.cc Source File

gsa_util.cc

Go to the documentation of this file.
00001 ///
00002 #include "../ProgramUnit.h"
00003 #include "../HeapStats.h"
00004 #include "../Timer.h"
00005 #include "../TranslateObject.h"
00006 #include "../Traverser.h"
00007 #include "../Expression/expr_funcs.h"
00008 #include "../Expression/IDExpr.h"
00009 #include "../Statement/AssignmentStmt.h"
00010 #include "../Symbol/FunctionSymbol.h"
00011 #include "../Symbol/SymbolicConstantSymbol.h"
00012 #include "../Symbol/VariableSymbol.h"
00013 #include "../GSAPathExpr.h"
00014 #include "../GSAPathMap.h"
00015 #include "../GSAWorkSpace.h"
00016 #include "../PhiPlaceDef.h"
00017 
00018 #include "ip_ssa/trans_util.h"
00019 #include "ip_ssa/ip_ssa.h"
00020 
00021 #include "dominator_util.h"
00022 #include "lambda_util.h"
00023 #include "stmt_util.h"
00024 #include "switches_util.h"
00025 #include "gsa_util.h"
00026 
00027 
00028 inline void
00029 avoid_arrays_substitute_var(Expression &e, const Symbol & var, const Symbol & new_var){
00030 ///   if (var.is_array()) return;
00031   substitute_var(e,var,new_var);
00032 }
00033 
00034 
00035 static Statement      *
00036 make_phi_function(ProgramUnit & pgm, Symbol & v, int fan_in, OP_TYPE op)
00037 {
00038 
00039     p_assert(fan_in > 1, "GSA fail due to only one incoming variable");
00040 
00041     List<Expression> *list = new List<Expression>;
00042 
00043     for (int i = 1; i <= fan_in; ++i)
00044         list->ins_last(id(v));
00045 
00046     Expression * rhs_expr = NULL;
00047     switch(op) {
00048     case GAMMA_OP:
00049       rhs_expr = gamma(NULL, comma(list));
00050       break;
00051     case MU_OP:
00052       rhs_expr = mu(comma(list));
00053       break;
00054     default:
00055       p_abort("Illegal expression op passed to make_phi_function");
00056     }
00057 
00058     return new AssignmentStmt(pgm.stmts().new_tag(),
00059                               id(v), rhs_expr);
00060 }
00061 
00062 static Statement      *
00063 make_phi_function(ProgramUnit & pgm, Symbol & v, Expression &ex)
00064 {
00065     return new AssignmentStmt(pgm.stmts().new_tag(),
00066                               id(v),
00067                               ex.clone());
00068 }
00069 
00070 /// COMPRESS, EVAL and LINK for building dominator tree
00071 
00072 static void 
00073 COMPRESS_S(Statement & v, unsigned int pass)
00074 {
00075     GSAWorkSpace & v_ws 
00076         = *(GSAWorkSpace *) v.work_stack().top_ref(pass);
00077 
00078     GSAWorkSpace & anc_v_ws 
00079         = *(GSAWorkSpace *) v_ws.ancestor->work_stack().top_ref(pass);
00080 
00081     if (anc_v_ws.ancestor) {
00082         COMPRESS_S(*v_ws.ancestor, pass);
00083 
00084         GSAWorkSpace & label_anc_v_ws 
00085             = *(GSAWorkSpace *)anc_v_ws.label->work_stack().top_ref(pass);
00086 
00087         GSAWorkSpace & label_v_ws 
00088             = *(GSAWorkSpace *) v_ws.label->work_stack().top_ref(pass);
00089 
00090         if (label_anc_v_ws.semi<label_v_ws.semi)
00091             v_ws.label = anc_v_ws.label;
00092 
00093         /// ...  Link the definition information from the root down.
00094     GSAWorkSpace & anc_anc_v_ws 
00095             = *(GSAWorkSpace *) anc_v_ws.ancestor->work_stack().top_ref(pass);
00096 
00097     *anc_v_ws._b_label_def |=  *anc_anc_v_ws._b_label_def;
00098 
00099         v_ws.ancestor = anc_v_ws.ancestor;
00100     }
00101 
00102     /// ...  Link the definition information from its ancestor.
00103     *v_ws._b_label_def |= *anc_v_ws._b_label_def;
00104 
00105 }
00106 
00107 static Statement & 
00108 EVAL_S(Statement & stmt, unsigned int pass, IntSet & EVALDEF)
00109 {
00110 /// Check to see if statement has work space (unreachable code
00111 /// does not)
00112 
00113   GSAWorkSpace * stmt_ws_ptr
00114     = (GSAWorkSpace *) stmt.work_stack().top_ref(pass);
00115 
00116   if (!stmt_ws_ptr || !stmt_ws_ptr->ancestor) {
00117     EVALDEF.clear();
00118     return stmt;
00119   }
00120 
00121   COMPRESS_S(stmt, pass);
00122   if (stmt_ws_ptr->_b_label_def)
00123     EVALDEF = *(stmt_ws_ptr->_b_label_def);
00124 
00125   return *stmt_ws_ptr->label;
00126 }
00127 
00128 static void 
00129 LINK_S(Statement * v, Statement & w, unsigned int pass)
00130 {
00131     GSAWorkSpace & w_ws 
00132         = *(GSAWorkSpace *) w.work_stack().top_ref(pass);
00133 
00134     /// ...  Update w's label_def to include its sdef and def
00135     /// ...  since it is no longer the root in the forest.
00136 
00137     *w_ws._b_label_def |= *w_ws._b_sdef;
00138     if (w_ws._i_b_def >= 0) 
00139         w_ws._b_label_def->ins(w_ws._i_b_def);
00140     else 
00141         *w_ws._b_label_def |= *w_ws._b_def;
00142 
00143     w_ws.ancestor = v;
00144 }
00145 
00146 static void
00147 DFS_S(Statement & first_stmt, Array<Statement *> &vertex, 
00148       unsigned int pass, Dictionary<PhiPlaceDef> *V,
00149       const Map<Symbol,IntElem> &candidates, int size)
00150 {
00151 /// Originally, first statement is on top of stack
00152   Statement * stack_stmt_ptr = &first_stmt;
00153   GSAWorkSpace * stack_stmt_ws_ptr = 0;
00154 /// Initialize vertex array pointer
00155   int array_index = -1;
00156 /// First statement has no parent
00157   Statement * parent_stmt_ptr = 0;
00158 /// Loop until stack is empty
00159   while (1) {
00160     /// ...  Check to see if our object is on workspace stack
00161     if (!stack_stmt_ws_ptr) {
00162       /// ...  No, this must be a newly pushed item
00163       /// ...  Allocate workspace for top of stack
00164       stack_stmt_ws_ptr = new GSAWorkSpace(pass, size);
00165       /// ...  Put top of stack into vertex array
00166       vertex[++array_index] = stack_stmt_ptr;
00167       /// ...  Put workspace onto top of stack
00168       stack_stmt_ptr->work_stack().push(stack_stmt_ws_ptr);
00169       /// ...  Set semi field
00170       stack_stmt_ws_ptr->semi = array_index + 1;
00171       /// ...  Set parent pointer to parent
00172       stack_stmt_ws_ptr->parent = parent_stmt_ptr;
00173       /// ...  initialize the def(s)
00174       stack_stmt_ws_ptr->_b_sdef = new IntSet(size);
00175       stack_stmt_ws_ptr->_b_idef = new IntSet(size);
00176       stack_stmt_ws_ptr->_b_label_def = new IntSet(size);
00177     
00178       if (stack_stmt_ptr->stmt_class() == ASSIGNMENT_STMT){
00179     Expression &d = stack_stmt_ptr->lhs();
00180 
00181     if (d.op() == ID_OP || d.op() == ARRAY_REF_OP || d.op() == SUBSTRING_OP) {
00182 
00183       Symbol *sym = d.base_variable_ref();
00184       stack_stmt_ws_ptr->_i_b_def = *candidates.find_ref(*sym);
00185 
00186       PhiPlaceDef *v = V->find_ref(sym->name_ref());
00187       v->involved = 1;
00188     }
00189       } else {
00190     stack_stmt_ws_ptr->_b_def = new IntSet(size);
00191     for (Iterator<Expression> def = stack_stmt_ptr->out_refs(); def.valid(); ++def) {
00192       Expression &d = def.current();
00193 
00194       if (d.op() == ID_OP || d.op() == ARRAY_REF_OP || d.op() == SUBSTRING_OP) {
00195 
00196         Symbol *sym = d.base_variable_ref();
00197         if (sym->sym_class() != SYMBOLIC_CONSTANT_CLASS)
00198           stack_stmt_ws_ptr->_b_def->ins(*candidates.find_ref(*sym));
00199 
00200         PhiPlaceDef *v = V->find_ref(sym->name_ref());
00201         v->involved = 1;
00202       }
00203     }
00204       }
00205     }
00206     /// ...  Indicate that no push has occurred
00207     parent_stmt_ptr = 0;
00208     /// ...  Examine each successor which has not been seen before
00209     if (!stack_stmt_ws_ptr->label) {
00210       Iterator<Statement> succ_iter(stack_stmt_ptr->succ(),
00211                     stack_stmt_ws_ptr->ancestor,
00212                     0);
00213       while (succ_iter.valid()) {
00214     /// ...  Get reference to successor
00215     Statement & succ_stmt = succ_iter.current();
00216     /// ...  Increment iterator now, so we can resume at next successor
00217     ++succ_iter;
00218     /// ...  Process successor next if it does not have our workspace
00219     GSAWorkSpace * succ_stmt_ws_ptr =
00220       (GSAWorkSpace *) succ_stmt.work_stack().top_ref(pass);
00221     if (!succ_stmt_ws_ptr) {
00222       // Check for continuation
00223       if (succ_iter.valid()) {
00224       // Continue processing with next successor
00225         stack_stmt_ws_ptr->ancestor = &succ_iter.current();
00226       }
00227       else {
00228         /// ...  Set label field to signal no more successor processing
00229         stack_stmt_ws_ptr->label = stack_stmt_ptr;
00230       }
00231       // Push successor onto top of stack
00232       parent_stmt_ptr = stack_stmt_ptr;
00233       stack_stmt_ptr = &succ_stmt;
00234       stack_stmt_ws_ptr = 0;
00235       break;
00236     }
00237       }
00238       /// ...  Skip cleanup processing if push
00239       if (parent_stmt_ptr)
00240     continue;
00241       /// ...  Set label field to signal no more successor processing
00242       stack_stmt_ws_ptr->label = stack_stmt_ptr;
00243     }
00244     /// ...  Clean up ancestor pointer
00245     stack_stmt_ws_ptr->ancestor = 0;
00246     /// ...  Pop statement off stack and point to new top of stack
00247     stack_stmt_ptr = stack_stmt_ws_ptr->parent;
00248     /// ...  If stack is empty, no more processing
00249     if (!stack_stmt_ptr)
00250       break;
00251     /// ...  Look up workspace pointer
00252     stack_stmt_ws_ptr =
00253       (GSAWorkSpace *) stack_stmt_ptr->work_stack().top_ref(pass);
00254   }
00255 
00256 /// If we skipped over unreachable code, resize array
00257   if (array_index + 1< vertex.entries())
00258     vertex.resize(array_index+1);
00259 }
00260 
00261 static void 
00262 Dominator_S(ProgramUnit & pgm, Array<Statement *> & vertex, 
00263             unsigned int pass, Dictionary<PhiPlaceDef> *V,
00264             const Map<Symbol,IntElem> &candidates,
00265             const Array<Symbol *> & NOTUSED(tag_to_candidate), 
00266             int size)
00267 {
00268 
00269   DFS_S(*pgm.stmts().first_ref(), vertex, pass, V, candidates, size);
00270 
00271   IntSet EVALDEF(size);
00272   int i;
00273   for (i = vertex.entries() - 1; i > 0; i--) {
00274     Statement & w = *vertex[i];
00275     GSAWorkSpace & w_ws 
00276       = *(GSAWorkSpace *) w.work_stack().top_ref(pass);
00277 
00278     {
00279       for (Iterator<Statement>v = w.pred(); v.valid(); ++v) {
00280     Statement & u = EVAL_S(v.current(), pass, EVALDEF);
00281 
00282     GSAWorkSpace * u_ws_ptr 
00283       = (GSAWorkSpace *) u.work_stack().top_ref(pass);
00284 
00285     if (u_ws_ptr) {
00286       if (u_ws_ptr->semi<w_ws.semi)
00287         w_ws.semi = u_ws_ptr->semi;
00288       *w_ws._b_sdef |= EVALDEF;
00289     }
00290       }
00291 
00292       Statement & t = *vertex[w_ws.semi - 1];
00293       /* Debugging statement
00294      cout << "Statement: " << w.tag() << 
00295      ", Bucket Statement: " << t.tag() << '\n';
00296      */
00297 
00298       GSAWorkSpace & ws_t 
00299     = *(GSAWorkSpace *) t.work_stack().top_ref(pass);
00300 
00301       ws_t.bucket.ins_last(w);
00302 
00303       LINK_S(w_ws.parent, w, pass);
00304     }
00305 
00306     {
00307       GSAWorkSpace & p_ws 
00308     = *(GSAWorkSpace *) w_ws.parent->work_stack().top_ref(pass);
00309       /* Debugging statement
00310      cout << "Statement: " << w.tag() << 
00311      ", Parent Statement: " << w_ws.parent->tag() << '\n';
00312      */
00313 
00314       for (Mutator<Statement> v = p_ws.bucket; v.valid(); ++v) {
00315     Statement & vc = v.current();
00316     /* Debugging statement
00317        cout << "Bucket Statement: " << vc.tag() << '\n';
00318        */
00319     Statement & u = EVAL_S(vc, pass, EVALDEF);
00320 
00321     GSAWorkSpace & u_ws 
00322       = *(GSAWorkSpace *) u.work_stack().top_ref(pass);
00323 
00324     GSAWorkSpace & v_ws 
00325       = *(GSAWorkSpace *) 
00326         vc.work_stack().top_ref(pass);
00327 
00328     v_ws.idom = ((u_ws.semi < v_ws.semi) ? &u : w_ws.parent);
00329 
00330     EVAL_S(*v_ws.parent, pass, EVALDEF);
00331 
00332     /* Debugging statement
00333        cout << "Before or statements: " << *v_ws._b_idef << '\n';
00334        */
00335     *v_ws._b_idef |= *v_ws._b_sdef;
00336     /* Debugging statement
00337        cout << "After 1st or statement: " << *v_ws._b_idef << '\n';
00338        */
00339     *v_ws._b_idef |= EVALDEF;
00340     /* Debugging statement
00341        cout << "After 2nd or statement: " << *v_ws._b_idef << '\n';
00342        */
00343     v.del();
00344       }
00345     }
00346     EVALDEF.clear();
00347   }
00348 
00349   for (i = 1; i < vertex.entries(); ++i) {
00350     Statement & w = *vertex[i];
00351     /* Debugging statement
00352        cout << "Statement: " << w.tag() << '\n';
00353        */
00354 
00355     GSAWorkSpace & w_ws 
00356       = *(GSAWorkSpace *) w.work_stack().top_ref(pass);
00357 
00358     if (w_ws.idom && w_ws.idom != vertex[w_ws.semi - 1]) {
00359       GSAWorkSpace & d_ws 
00360     = *(GSAWorkSpace *) w_ws.idom->work_stack().top_ref(pass);
00361 
00362       w_ws.idom = d_ws.idom;
00363 
00364       /* Debugging statement
00365      cout << "Before or statement: " << *w_ws._b_idef << '\n';
00366      */
00367       *w_ws._b_idef |= *d_ws._b_idef;
00368       /* Debugging statement
00369      cout << "After or statement: " << *w_ws._b_idef << '\n';
00370      */
00371     }
00372   }
00373 
00374   for (i = 1; i < vertex.entries(); ++i) {
00375     Statement & w = *vertex[i];
00376 
00377     GSAWorkSpace & w_ws
00378       = *(GSAWorkSpace *) w.work_stack().top_ref(pass);
00379 
00380     w_ws.ancestor = NULL;
00381     Statement & p = *w_ws.idom;
00382 
00383     GSAWorkSpace & p_ws
00384       = *(GSAWorkSpace *) p.work_stack().top_ref(pass);
00385 
00386     p_ws.bucket.ins_last(w);
00387 
00388   }
00389 
00390   if (switch_value("gsa_prt_dom") == 1)
00391     write_idom(vertex, cout, pass);
00392 }
00393 
00394 static Dictionary<PhiPlaceDef> *
00395 Variable_set_new(const ProgramUnit & pgm,
00396          Map<Symbol,IntElem> &candidates,
00397          Array<Symbol *> &tag_to_candidate,
00398                  int &tag)
00399 {
00400     Dictionary<PhiPlaceDef> *V = new Dictionary<PhiPlaceDef>;
00401 
00402     tag_to_candidate.resize(pgm.symtab().entries());
00403 
00404     for (DictionaryIter<Symbol> sym = pgm.symtab().iterator();
00405                                 sym.valid(); ++sym) {
00406         Symbol &sb = sym.current();
00407         if (sb.sym_class() == VARIABLE_CLASS ||
00408             sb.sym_class() == FUNCTION_CLASS ||
00409             sb.sym_class() == SYMBOLIC_CONSTANT_CLASS){
00410             V->ins(new PhiPlaceDef(sb));
00411         tag_to_candidate[tag] = &sb;
00412         candidates.ins(sb, new IntElem(tag++));
00413         }
00414     }
00415 
00416     tag_to_candidate.resize(tag);
00417 
00418     return V;
00419 }
00420 
00421 static void
00422 insert_pseudo_assignment_stmts(ProgramUnit &pgm, 
00423                    Array<Statement *> &vertex,
00424                    Array<Symbol *> &tag_to_candidate,
00425                    unsigned int pass)
00426 {
00427   for (int i = 0; i < vertex.entries(); i++) {
00428     Statement &w = *vertex[i];
00429     GSAWorkSpace &ws = *(GSAWorkSpace *) w.work_stack().top_ref(pass);
00430 
00431     switch (w.stmt_class()) {
00432     case DO_STMT:    
00433 
00434       {
00435     for (int elem = ws._b_idef->first(); 
00436          elem != -1; elem = ws._b_idef->next(elem)){
00437       Symbol *sym = tag_to_candidate[elem];
00438                     
00439       if (sym != w.index().base_variable_ref()){
00440         ws.PHI_name.ins_last(*sym);
00441 
00442 #if 0           
00443         if (ws.path_star && ws.path_star->expr)
00444           ws.PHI->ins_last(make_phi_function(pgm, *sym, *(ws.path_star->expr)));
00445         else
00446           ws.PHI->ins_last(make_phi_function(pgm, *sym, w.pred().entries(), MU_OP));
00447 #endif
00448 
00449         ws.PHI->ins_last(make_phi_function(pgm, *sym, w.pred().entries(), MU_OP));
00450       }
00451     }
00452       }
00453       break;
00454             
00455     default:
00456 
00457       for (int elem = ws._b_idef->first();
00458        elem != -1; elem = ws._b_idef->next(elem)){
00459     Symbol *sym = tag_to_candidate[elem];
00460     ws.PHI_name.ins_last(*sym);
00461     ws.PHI->ins_last(make_phi_function(pgm, *sym, w.pred().entries(), GAMMA_OP));
00462 
00463       }
00464     }
00465     delete ws._b_def;
00466     ws._b_def = NULL;
00467     delete ws._b_label_def;
00468     ws._b_label_def = NULL;
00469     delete ws._b_idef;
00470     ws._b_idef = NULL;
00471     delete ws._b_sdef;
00472     ws._b_sdef = NULL;
00473   }
00474 }
00475 
00476 static void 
00477 array_in_subscript(RefSet<Symbol>&all, List<Expression>&args)
00478 {
00479     for (Iterator<Expression>iter = args; iter.valid(); ++iter) {
00480         if (iter.current().op() == ARRAY_REF_OP)
00481             all.ins(*iter.current().base_variable_ref());
00482         else if (iter.current().arg_list().entries())
00483             array_in_subscript(all, iter.current().arg_list());
00484     }
00485 }
00486 
00487 static String 
00488 integer_to_string(int i)
00489 {
00490     String          result;
00491     char            number[] = "0123456789";
00492     String          t = " ";
00493 
00494     do {
00495         t[0] = number[i % 10];
00496         result = t + result;
00497         i = i / 10;
00498     } while (i > 0);
00499 
00500     return result;
00501 }
00502 
00503 static void
00504 InitializeGSAStack(TranslateObject & trans_obj,
00505            Dictionary<PhiPlaceDef>*V)
00506 {
00507     ProgramUnit & pgm = trans_obj.pgm_main();
00508     for (DictionaryIter<PhiPlaceDef> v = *V; v.valid(); ++v) {
00509 
00510         if (v.current().involved) {
00511         Symbol & old_var = *v.current().var;
00512             String          var(old_var.name_ref());
00513 
00514             var += "@";
00515             var += integer_to_string(0);
00516 
00517             Symbol *t;
00518         if (old_var.sym_class() == VARIABLE_CLASS){
00519                 t = new VariableSymbol(var, old_var.type(), 
00520                                        old_var.formal(),
00521                                        old_var.saved() );
00522                 t->dim() = old_var.dim();
00523                 t->shared_dim() = old_var.shared_dim();
00524         VariableSymbol & new_var = (VariableSymbol &)pgm.symtab().ins(t);
00525         new_var.gsa_base_symbol( old_var );
00526 
00527             }
00528             else if (old_var.sym_class() == FUNCTION_CLASS) {
00529                 t = new FunctionSymbol(var, old_var.type(), 
00530                                        old_var.external(),
00531                                        old_var.intrinsic(),
00532                                        old_var.formal(),
00533                                        old_var.entry_ref() );
00534         pgm.symtab().ins(t);
00535         }
00536         else { /// ... SYMBOLIC_CONSTANT_CLASS 
00537                 t = new SymbolicConstantSymbol(var, old_var.expr_ref()->clone());
00538         pgm.symtab().ins(t);
00539         }
00540             
00541             v.current().syms.push(*t);
00542         trans_obj.GSA_mapping(*t,old_var);
00543         }
00544     }
00545 }
00546 
00547 static int
00548 occurs(Expression &expr, int pos)
00549 {
00550   if (is_pseudo_function(expr)) {
00551         Mutator<Expression> iter = expr.parameters_guarded().arg_list();
00552         for ( ; iter.valid(); ++iter)
00553             if (occurs(iter.current(), pos)) return 1;
00554 
00555         return 0;
00556 
00557     } else if (expr.op() == INTEGER_CONSTANT_OP && expr.value() == pos)
00558         return 1;
00559 
00560     return 0;
00561 }
00562 
00563 static Expression *
00564 substitute_argument(Expression *expr, int pos, Expression &subs)
00565 {
00566   if (is_pseudo_function(*expr)) {
00567     Mutator<Expression> iter = expr->parameters_guarded().arg_list();
00568 
00569     for ( ; iter.valid(); ++iter) {
00570       Assign<Expression> eas(iter.assign());
00571       eas = substitute_argument(iter.pull(), pos, subs);
00572     }
00573 
00574     return expr;
00575 
00576   } else if (((pos<0) && (expr->op()==OMEGA_OP)) ||
00577          ((expr->op() == INTEGER_CONSTANT_OP) && (expr->value() == pos))) {
00578     delete expr;
00579     return subs.clone();
00580   } else
00581     return expr;
00582 }
00583 
00584 static void 
00585 get_variable_clone(Expression & expr, List<Expression>*l)
00586 {
00587     if (expr.op() == ID_OP || 
00588     expr.op() == ARRAY_REF_OP || 
00589     expr.op() == SUBSTRING_OP)
00590         l->ins_last(expr.clone());
00591     else if (expr.op() == FUNCTION_CALL_OP)
00592         get_variable_clone(expr.parameters_guarded(), l);
00593     else {
00594         for (Iterator<Expression>iter = expr.arg_list(); iter.valid(); ++iter) {
00595             if (iter.current().op() == FUNCTION_CALL_OP)
00596                 get_variable_clone(iter.current(), l);
00597         }
00598     }
00599 }
00600 
00601 static void fix_substituted(Expression& expr, Symbol& n, Symbol& s){
00602 ///   cerr<<"\nNow in expr "<<expr;
00603   if (expr.op()==ID_OP){
00604     if (expr.symbol().is_array() || expr.symbol().is_scalar()){
00605 ///     cerr<<"\nIt is ID.";
00606       IDExpr& idexpr=(IDExpr&)expr;
00607       if (idexpr.substituted_valid()){
00608 ///       cerr<<"\nBefore substitution: "<<idexpr.substituted_guarded();
00609     avoid_arrays_substitute_var(idexpr.substituted_guarded(), n, s);
00610 ///       cerr<<"\nAfter substitution: "<<idexpr.substituted_guarded();
00611       }
00612     }
00613   } else {
00614 ///     cerr<<"\nIt is NOT ID.";
00615     Iterator<Expression> expit=expr.arg_list();
00616     for ( expit.reset() ; expit.valid(); ++expit){
00617       fix_substituted(expit.current(), n, s);
00618     }
00619   }  
00620 }
00621 
00622 static void find_id_exprs(Expression& expr, RefList<Symbol>& all){
00623   if (expr.op()==ID_OP){
00624     if (expr.symbol().is_array() || expr.symbol().is_scalar()){
00625       all.ins_first(expr.symbol());
00626     }
00627   } else {
00628     Iterator<Expression> expit=expr.arg_list();
00629     for ( expit.reset() ; expit.valid(); ++expit){
00630       find_id_exprs(expit.current(), all);
00631     }
00632   }  
00633 }
00634 
00635 static void find_substituted_id_exprs(Expression& expr, RefList<Symbol>& all){
00636   if (expr.op()==ID_OP){
00637     IDExpr& idexpr=(IDExpr&)expr;
00638     if (idexpr.substituted_valid()){
00639       find_id_exprs(idexpr.substituted_guarded(), all);
00640     }
00641   } else {
00642     Iterator<Expression> expit=expr.arg_list();
00643     for ( expit.reset() ; expit.valid(); ++expit){
00644       find_substituted_id_exprs(expit.current(), all);      
00645     }
00646   }  
00647 }
00648 
00649 static void print_substituted(Expression& expr){
00650   if (expr.op()==ID_OP){
00651     cerr<<"\nOriginal expression: "<<expr
00652     <<"\tsubstituted: ";
00653     if (expr.substituted_valid()){
00654       cerr<<expr.substituted_guarded();
00655     } else {
00656       cerr<<"NULL";
00657     }
00658   } else {
00659     Iterator<Expression> expit=expr.arg_list();
00660     for ( expit.reset() ; expit.valid(); ++expit){
00661       print_substituted(expit.current());
00662     }
00663   }
00664 }
00665 
00666 
00667 static void 
00668 SEARCH(TranslateObject & trans_obj, Statement & X, 
00669        Dictionary<PhiPlaceDef>&V, unsigned int pass,
00670        Symbol * beta)
00671 {
00672 #if 0
00673     cout << X << "\n";
00674 #endif
00675 
00676     ProgramUnit & pgm = trans_obj.pgm_main();
00677 
00678     RefStack<Symbol> oldLHS;
00679     RefList<Symbol>  old_name;
00680     RefList<Symbol> subst;
00681 
00682 #if 0
00683     X.in_refs().print(cout);
00684     cout << "\n";
00685 #endif
00686 
00687     for (Iterator<Expression> use = X.in_refs(); use.valid(); ++use) {
00688         PhiPlaceDef   *v 
00689             = V.find_ref(use.current().base_variable_ref()->name_ref());
00690 
00691         if (v->involved && !old_name.member(*v->var)) {
00692             old_name.ins_last(*v->var);
00693             subst.ins_last(v->syms.top_guarded());
00694         }
00695     }
00696 
00697     /// ...  Get the variables for each of the parameter;
00698 
00699     List<Expression> new_p;
00700 
00701     if (X.stmt_class() == CALL_STMT) {
00702         for (Iterator<Expression> iter = X.parameters_guarded().arg_list();
00703                                   iter.valid(); ++iter) {
00704 
00705             List<Expression> *t = new List<Expression>;
00706 
00707             get_variable_clone(iter.current(), t);
00708 
00709             new_p.ins_last(comma(t));
00710         }
00711     }
00712 
00713     Iterator<Symbol>     iter_n = old_name;
00714     Iterator<Symbol>     iter_s = subst; 
00715 
00716     Mutator<Expression>  iter_e = X.iterate_expressions();
00717 
00718 
00719 #if 0
00720     /// ...  Replace the names in the INDUCTION assertion with the GSA version
00721 
00722     for (Iterator<Assertion> a_iter2 = X.assertions(); 
00723      a_iter2.valid(); 
00724      ++a_iter2) {
00725         if (a_iter2.current().type() == AS_INDUCTION) {
00726         if (a_iter2.current().arg_list_valid()) {
00727         for (Mutator<Expression> ex_iter = a_iter2.current().arg_list_guarded();
00728              ex_iter.valid();
00729              ++ex_iter) {
00730           Expression & assert_expr = ex_iter.current();
00731           for (iter_n.reset(),iter_s.reset(); iter_s.valid(); ++iter_s, ++iter_n)
00732             avoid_arrays_substitute_var(assert_expr, iter_n.current(), iter_s.current());
00733         }
00734         }
00735     }
00736     }
00737 #endif      
00738     
00739     switch (X.stmt_class()) {
00740     case ASSIGNMENT_STMT:
00741         {
00742             ++iter_e;
00743             Expression &rhs_t = iter_e.current();
00744             for (iter_n.reset(),iter_s.reset(); iter_s.valid(); ++iter_s, ++iter_n) 
00745                 avoid_arrays_substitute_var(rhs_t, iter_n.current(), iter_s.current());
00746 
00747             break;
00748         }
00749 
00750     case READ_STMT:
00751     case WRITE_STMT:
00752         break;
00753 
00754     default:
00755         {  
00756             for ( ; iter_e.valid(); ++iter_e) {
00757                 Expression &rhs_t = iter_e.current();
00758                 for (iter_n.reset(),iter_s.reset(); iter_s.valid(); ++iter_s, ++iter_n) 
00759                     avoid_arrays_substitute_var(rhs_t,iter_n.current(),iter_s.current());
00760             }
00761             break;
00762         }
00763     }
00764 
00765     
00766 
00767 
00768     /// ...  Make BETA assignment to subroutine call parameters
00769 
00770     if (X.stmt_class() == CALL_STMT) {
00771         Mutator<Expression> iter_1 = new_p;
00772 
00773         for (Mutator<Expression> iter = X.parameters_guarded().arg_list();
00774                             iter.valid() && iter_1.valid(); ++iter, ++iter_1) {
00775 
00776             Expression     *t = iter_1.grab();
00777 
00778             if (t->arg_list().entries()) {
00779                 t->arg_list().ins_first(alpha(comma(iter.current().clone())));
00780                 iter.modify(function_call(id(*beta), t));
00781             }
00782             else {
00783                 delete t;
00784             }
00785         }
00786 
00787     }
00788 
00789     /// ...  Make a PHI assignment for an array assignment
00790 
00791     if (X.stmt_class() == ASSIGNMENT_STMT && 
00792     (X.lhs().op() == ARRAY_REF_OP || X.lhs().op() == SUBSTRING_OP)) {
00793         PhiPlaceDef   *v 
00794             = V.find_ref(X.lhs().base_variable_ref()->name_ref());
00795 
00796         if (v->involved) {
00797         iter_e.set_to_last();
00798       
00799         Assign<Expression> eas(iter_e.assign());
00800         eas = alpha(comma(id(v->syms.top_guarded()),
00801                   iter_e.pull()));
00802         }
00803 
00804     }
00805 
00806     X.build_refs();
00807 
00808 
00809 
00810 
00811 
00812 #if 0
00813     cout << X << "\n";
00814     X.out_refs().print(cout);
00815     cout << "\n";
00816 #endif
00817 
00818     {
00819         RefList<Symbol>   old_name;
00820         RefList<Symbol>   subst;
00821 
00822         for (Iterator<Expression> def = X.out_refs(); def.valid(); ++def) {
00823         Expression &dc = def.current();
00824 
00825             PhiPlaceDef   *v 
00826                 = V.find_ref(dc.base_variable_ref()->name_ref());
00827 
00828             if (v && v->involved && (!old_name.member(*v->var))) {
00829             Symbol & old_var = *v->var;
00830                 oldLHS.push(*dc.base_variable_ref());
00831                 v->C += 1;
00832                 int             i = v->C;
00833                 String          var_i(old_var.name_ref());
00834 
00835                 var_i += "@";
00836                 var_i += integer_to_string(i);
00837 
00838                 Symbol *t;
00839                 if (old_var.sym_class() == VARIABLE_CLASS){
00840                     t = new VariableSymbol(var_i, old_var.type(), 
00841                                            old_var.formal(),
00842                                            old_var.saved() );
00843                     t->dim() = old_var.dim();
00844                     t->shared_dim() = old_var.shared_dim();
00845             VariableSymbol & new_var = (VariableSymbol &)pgm.symtab().ins(t);
00846             new_var.gsa_base_symbol( old_var );
00847 
00848                 } else if (old_var.sym_class() == FUNCTION_CLASS) {
00849                     t = new FunctionSymbol(var_i, old_var.type(), 
00850                                            old_var.external(),
00851                                            old_var.intrinsic(),
00852                                            old_var.formal(),
00853                                            old_var.entry_ref() );
00854             pgm.symtab().ins(t);
00855         }
00856                 else { /// ...  SYMBOLIC_CONSTANT_CLASS
00857                     t = new SymbolicConstantSymbol(var_i,old_var.expr_ref()->clone());
00858             pgm.symtab().ins(t);
00859         }
00860 
00861                 v->syms.push(*t);
00862         trans_obj.GSA_mapping(*t,old_var);
00863 
00864                 old_name.ins_last(old_var);
00865                 subst.ins_last(*t);
00866             }
00867         }
00868 
00869         Iterator<Symbol>     iter_n = old_name;
00870         Iterator<Symbol>     iter_s = subst;
00871 
00872     Mutator<Expression>  iter_e = X.iterate_expressions();
00873 
00874     switch (X.stmt_class()) {
00875     case ASSIGNMENT_STMT:
00876         case DO_STMT:
00877             {
00878                 Expression &lhs_t = iter_e.current();
00879                 for ( ; iter_s.valid(); ++iter_s, ++iter_n) 
00880                     avoid_arrays_substitute_var(lhs_t, iter_n.current(), iter_s.current());
00881                 
00882                 break;
00883             }
00884 
00885         default:
00886             {  
00887                 for ( ; iter_e.valid(); ++iter_e) {
00888                     Expression &lhs_t = iter_e.current();
00889                     for (iter_n.reset(),iter_s.reset(); iter_s.valid(); ++iter_s, ++iter_n) 
00890                         avoid_arrays_substitute_var(lhs_t,iter_n.current(),iter_s.current());
00891                 }
00892                 break;
00893             }
00894         }
00895 
00896         old_name.clear();
00897         subst.clear();
00898     }
00899 
00900     /// ...  Replace variable uses on the left hand side of the assignment
00901 
00902     iter_e.reset();
00903 
00904     switch (X.stmt_class()) {
00905     case ASSIGNMENT_STMT:
00906         {
00907             Expression &lhs_t = iter_e.current();
00908 
00909             for ( iter_n.reset(),iter_s.reset(); iter_s.valid(); ++iter_s, ++iter_n) 
00910                avoid_arrays_substitute_var(lhs_t, iter_n.current(), iter_s.current());
00911 
00912             break;
00913         }
00914 
00915     case READ_STMT:
00916     case WRITE_STMT:
00917 
00918         {  
00919             for ( ; iter_e.valid(); ++iter_e) {
00920                 Expression &rhs_t = iter_e.current();
00921                 for (iter_n.reset(),iter_s.reset(); iter_s.valid(); ++iter_s, ++iter_n) 
00922                     avoid_arrays_substitute_var(rhs_t,iter_n.current(),iter_s.current());
00923             }
00924         }
00925     default: break;
00926     }
00927 
00928     old_name.clear();
00929     subst.clear();
00930 
00931     /// ...  Handle PHI function assignment statements
00932 
00933     GSAWorkSpace & X_ws 
00934         = *(GSAWorkSpace *) X.work_stack().top_ref(pass);
00935 
00936     Iterator<Statement>   p_stmt = *X_ws.PHI;
00937     Iterator<Symbol>      p_name = X_ws.PHI_name; 
00938 
00939     for ( ; p_name.valid(); ++p_name, ++p_stmt) {
00940         Symbol &pn = p_name.current();
00941 
00942         oldLHS.push(pn);
00943 
00944         PhiPlaceDef   *v = V.find_ref(pn.name_ref());
00945     Symbol & old_var = *v->var;
00946         v->C += 1;
00947         int             i = v->C;
00948         String          var_i(old_var.name_ref());
00949 
00950         var_i += "@";
00951         var_i += integer_to_string(i);
00952 
00953         Symbol *t;
00954         if (old_var.sym_class() == VARIABLE_CLASS){
00955             t = new VariableSymbol(var_i, old_var.type(), 
00956                                    old_var.formal(),
00957                                    old_var.saved() );
00958             t->dim() = old_var.dim();
00959             t->shared_dim() = old_var.shared_dim();
00960         VariableSymbol & new_var = (VariableSymbol &)pgm.symtab().ins(t);
00961         new_var.gsa_base_symbol( old_var );
00962 
00963         }
00964         else if (old_var.sym_class() == FUNCTION_CLASS) {
00965             t = new FunctionSymbol(var_i, old_var.type(), 
00966                                    old_var.external(),
00967                                    old_var.intrinsic(),
00968                                    old_var.formal(),
00969                                    old_var.entry_ref() );
00970         pgm.symtab().ins(t);
00971     }
00972         else {   /// ...  SYMBOLIC_CONSTANT_CLASS
00973             t = new SymbolicConstantSymbol(var_i,old_var.expr_ref()->clone());
00974         pgm.symtab().ins(t);
00975     }
00976 
00977         v->syms.push(*t);
00978     trans_obj.GSA_mapping(*t,old_var);
00979 
00980         Expression     &lhs_t = p_stmt.current().lhs();
00981 
00982         avoid_arrays_substitute_var(lhs_t, old_var, *t);
00983     }
00984 
00985     for (Iterator<Statement> Y = X.succ(); Y.valid(); ++Y) {
00986         GSAWorkSpace & Y_ws 
00987             = *(GSAWorkSpace *) Y.current().work_stack().top_ref(pass);
00988 
00989         int i ;
00990     if (Y.current().stmt_class() == DO_STMT){
00991             if (Y.current().follow_ref() == &X)
00992                 i = 1;
00993             else
00994                 i = 0;
00995         }
00996         else
00997             i = Y.current().pred()._member(X);
00998 
00999         p_assert(i >= 0, "X is not a predecessor of Y");
01000     
01001     Iterator<Symbol> p_n = Y_ws.PHI_name;
01002     Iterator<Statement> phi = *Y_ws.PHI;
01003         for ( ; phi.valid(); ++phi, ++p_n) {
01004             PhiPlaceDef   *v 
01005                 = V.find_ref(p_n.current().name_ref());
01006 
01007         avoid_arrays_substitute_var(phi.current().rhs().parameters_guarded().arg_list()[i],
01008                    p_n.current(), v->syms.top_guarded());
01009         }
01010     }
01011 
01012 
01013     /// ...  Silvius
01014     /// ...  Replace the names in the 'substituted' fields
01015     /// ...  First collect all ids that need to be replaced with their gsa names
01016     RefList<Symbol> id_exprs_in_subst;
01017     Iterator<Expression> expit=X.iterate_expressions();
01018     for ( ; expit.valid(); ++expit){
01019       find_substituted_id_exprs(expit.current(), id_exprs_in_subst);
01020     }
01021     RefList<Symbol>  s_old_name;
01022     RefList<Symbol> s_new_name;
01023     
01024     for (Iterator<Symbol> use = id_exprs_in_subst; use.valid(); ++use) {
01025       PhiPlaceDef   *v 
01026     = V.find_ref(use.current().name_ref());
01027       
01028       if (v->involved && !old_name.member(*v->var)) {
01029     s_old_name.ins_last(*v->var);
01030     s_new_name.ins_last(v->syms.top_guarded());
01031       }
01032     }
01033     Iterator<Symbol> in=s_old_name;
01034     Iterator<Symbol> is=s_new_name;
01035     /// ...  Now go through the 'substituted' and update them
01036     for ( ; is.valid(); ++is, ++in) {
01037       for (expit=X.iterate_expressions(); expit.valid(); ++expit){
01038     fix_substituted(expit.current(), in.current(), is.current());
01039       }
01040     }
01041 
01042 
01043     // Silvius: gmap is part of the interprocedural ssa pass (base/ip_ssa)
01044     /// ...  Build database containing common variables values at call sites.
01045     if (called_pgm(X)){
01046       /// ...  This is a call site.
01047       Database<Statement*, RefDatabase<Symbol*, Symbol> >* lmap=
01048     ip_ssa_gmap().find_ref(&pgm);
01049       if (!lmap) {
01050     lmap=new Database<Statement*, RefDatabase<Symbol*, Symbol> >;
01051     ip_ssa_gmap().ins(&pgm, lmap);
01052       }
01053       RefDatabase<Symbol*, Symbol>* smap=lmap->find_ref(&X);
01054       if (!smap) {
01055     smap=new RefDatabase<Symbol*, Symbol>;
01056     lmap->ins(&X, smap);
01057       }
01058       
01059       for (DictionaryIter<Symbol> sit=pgm.symtab().iterator();
01060        sit.valid(); ++sit){
01061     Symbol& sym=sit.current();
01062     if (sym.common_ref()){
01063       PhiPlaceDef   *v 
01064         = V.find_ref(sym.name_ref());
01065       p_assert(v, "Could not find ref in GSA::SEARCH.");
01066       if (v->involved){
01067         if (v->var){
01068           smap->ins(v->var, v->syms.top_guarded());
01069         }
01070       } else {
01071         if (v->var){
01072           smap->ins(v->var, *v->var);
01073         }
01074       }
01075     }
01076       }
01077     }
01078 
01079 
01080     {
01081         for (Iterator<Statement> Y = X_ws.bucket; Y.valid(); ++Y)
01082             SEARCH(trans_obj, Y.current(), V, pass, beta);
01083     }
01084 
01085     while (oldLHS.entries()) {
01086         Symbol         &top = oldLHS.pop();
01087         PhiPlaceDef   *v = V.find_ref(top.name_ref());
01088 
01089         v->syms.pop();
01090 
01091     }
01092 
01093     X.build_refs();
01094 }
01095 
01096 static void 
01097 InsertPhiStmt(ProgramUnit & pgm, 
01098               Array<Statement *> &vertex, 
01099               unsigned int pass, 
01100               int GSA)
01101 {
01102     if (GSA) {
01103         /// ...  Fill the gating functions
01104 
01105         for (int i = 0; i<vertex.entries(); ++i) {
01106             Statement & w = *vertex[i];
01107             GSAWorkSpace & w_ws
01108                 = *(GSAWorkSpace *) w.work_stack().top_ref(pass);
01109             
01110             if (w_ws.PHI->entries() && w.stmt_class() != FLOW_EXIT_STMT) {
01111 
01112                 w_ws.path_idom->fill_expr();
01113 
01114                 if (w_ws.path_star) {
01115             if (w.pred().entries()>2){
01116                         if (w.stmt_class()==DO_STMT)
01117                             w_ws.path_star->fill_expr(w_ws.path_idom->expr);
01118                         else
01119                             w_ws.path_star->fill_expr(w_ws.path_idom->expr);
01120                     } else {
01121                         delete w_ws.path_idom->expr;
01122                         if (w.stmt_class()==DO_STMT)
01123                             w_ws.path_star->fill_expr(NULL);
01124                         else
01125                             w_ws.path_star->fill_expr(NULL);
01126                     }
01127                     w_ws.path_idom->expr = NULL;
01128                 }
01129                 
01130                 for (Iterator<Statement> iter = *w_ws.PHI; iter.valid(); ++iter) {
01131                     Statement &s = iter.current();
01132                     Expression &rhs = s.rhs();
01133                     Expression *rhs_new;
01134                     if (w_ws.path_star && w_ws.path_star->expr){
01135                         rhs_new = w_ws.path_star->expr->clone();
01136                     } else {
01137                         rhs_new = w_ws.path_idom->expr->clone();
01138                     }
01139                     
01140                     int i = 0;
01141                     for (Iterator<Expression> subs(rhs.parameters_guarded().arg_list());
01142                          subs.valid(); ++subs, ++i) {
01143                     
01144                         if (occurs(*rhs_new,i))
01145                             rhs_new = substitute_argument(rhs_new, i, subs.current());
01146                         else
01147                             rhs_new = substitute_argument(rhs_new, -1, subs.current());
01148                     }
01149                     
01150                     s.rhs(rhs_new);
01151                 }
01152 
01153                 if (w_ws.path_idom) delete w_ws.path_idom;
01154                 if (w_ws.path_label) delete w_ws.path_label;
01155                 if (w_ws.path_star) delete w_ws.path_star;
01156                 w_ws.path_idom = w_ws.path_star = w_ws.path_label = NULL;
01157 
01158             }
01159         }
01160     }
01161 
01162 
01163     for (int i = 0; i<vertex.entries(); ++i) {
01164         Statement & w = *vertex[i];
01165 
01166         GSAWorkSpace & w_ws 
01167             = *(GSAWorkSpace *) w.work_stack().top_ref(pass);
01168 
01169         if (w_ws.PHI->entries()) {
01170 
01171       // Fix the Idom and Dominance Frontier for the list of the Phi
01172       // assignments
01173 
01174             Statement      *idom = &w;
01175 
01176             for (Iterator<Statement>iter = *w_ws.PHI; iter.valid(); ++iter) {
01177                 Statement & u = iter.current();
01178         
01179                 GSAWorkSpace * u_ws = new GSAWorkSpace(pass);
01180                 u_ws->DF = w_ws.DF;
01181                 u_ws->idom = idom;
01182                 idom = &u;
01183                 
01184                 u.work_stack().push(u_ws);
01185             }
01186 
01187             /// ...  Fix the idom for the children of w in the dominator tree
01188 
01189             for (Iterator<Statement>iter1 = w_ws.bucket; iter1.valid(); ++iter1) {
01190                 Statement & v = iter1.current();
01191 
01192                 GSAWorkSpace & v_ws 
01193                     = *(GSAWorkSpace *) v.work_stack().top_ref(pass);
01194 
01195                 v_ws.idom = idom;
01196             }
01197 
01198             /// ...  Now, the ins_after will do the hard work to fix the control
01199             /// ...  flow graph
01200 
01201             if (w.stmt_class() == FLOW_EXIT_STMT && w_ws.PHI->entries()) {
01202 
01203                 /// ...  Some redundant PHI assignments could be created at the
01204                 /// ...  FLOW EXIT statement because all the RETURN statements
01205                 /// ...  artificially have the FLOW EXIT statement as their successor.
01206                 /// ...  The PHI assignments will never be executed since the subroutine
01207                 /// ...  already returned.  They may still be useful for interprocedural
01208                 /// ...  analysis as a summary for the subroutine.  That requires us to
01209                 /// ...  change all the RETURN statements to GOTO statements to the
01210                 /// ...  FLOW EXIT and the FLOW EXIT to its sole RETURN.
01211                 /// ...  For now, we just ignore the PHI assignments.
01212 
01213                 /// ...  for (Iterator<Statement> iter = *w_ws.PHI; iter.valid(); --iter)
01214                 /// ...      pgm.stmts().ins_before(iter.grab(), &w);
01215 
01216                 delete w_ws.PHI;
01217                 w_ws.PHI = NULL;
01218             }
01219             else {
01220 
01221                 pgm.stmts().ins_after(w_ws.PHI, &w);
01222                 w_ws.PHI = NULL;
01223 
01224                 /// ...             Iterator<Statement> iter = w_ws.PHI;
01225                 /// ...             for (iter.set_to_last(); iter.valid(); --iter) 
01226                 /// ...                 pgm.stmts().ins_after(iter.grab(), &w);
01227                 
01228             }
01229         }
01230     }
01231 }
01232 
01233 static unsigned int
01234 build_pidom(ProgramUnit & pgm)
01235 {
01236     unsigned int   pass = create_pass_tag();
01237 
01238     Array<Statement *> vertex(pgm.stmts().entries());
01239 
01240     /// ...  build post-dominator tree using Tarjan's algorithm
01241 
01242     pDominator(pgm, vertex, new pDominatorWorkSpace(pass),
01243            (switch_value("gsa_prt_pdom") == 1));
01244     return pass;
01245 }
01246 
01247 static void 
01248 get_all_variable_clone(Expression & expr, RefList<Symbol>*l)
01249 {
01250     if (expr.op() == ID_OP)
01251         l->ins_last(*expr.base_variable_ref());
01252     else if (expr.op() == ARRAY_REF_OP) {
01253         l->ins_last(*expr.base_variable_ref());
01254     get_all_variable_clone(expr.subscript(), l);
01255     }
01256     else if (expr.op() == SUBSTRING_OP){
01257         l->ins_last(*expr.base_variable_ref());
01258     get_all_variable_clone(expr.bound(), l);
01259     }
01260     else if (expr.op() == FUNCTION_CALL_OP)
01261         get_all_variable_clone(expr.parameters_guarded(), l);
01262     else 
01263         for (Iterator<Expression>iter = expr.arg_list(); iter.valid(); ++iter) 
01264             get_all_variable_clone(iter.current(), l);
01265 }
01266 
01267 void 
01268 DeGSA(ProgramUnit & pgm)
01269 {
01270   if (pgm.pu_class() == BLOCK_DATA_PU_TYPE) return;
01271   p_assert(pgm.gsa_valid(),
01272        "DeGSA called for a non-GSA ProgramUnit");
01273   pgm.gsa_names_guarded().translate_GSA_symbol_refs();
01274   pgm.gsa_names(0);
01275   pgm.gsa_deflocs(0);
01276 }
01277 
01278 /// COMPRESS_PATH, EVAL_PATH and LINK_PATH for building path expr.
01279 
01280 static void 
01281 COMPRESS_PATH(Statement & v, Statement &tail, unsigned int pass)
01282 {
01283     GSAWorkSpace & v_ws 
01284         = *(GSAWorkSpace *) v.work_stack().top_ref(pass);
01285 
01286     GSAWorkSpace & anc_v_ws 
01287         = *(GSAWorkSpace *) v_ws.ancestor->work_stack().top_ref(pass);
01288 
01289     if (anc_v_ws.ancestor) {
01290 
01291         COMPRESS_PATH(*v_ws.ancestor, tail, pass);
01292 
01293         /// ...  Link the path expression from the root down.
01294     GSAWorkSpace & anc_anc_v_ws 
01295             = *(GSAWorkSpace *) anc_v_ws.ancestor->work_stack().top_ref(pass);
01296 
01297     if (anc_anc_v_ws.path_label)
01298             *anc_v_ws.path_label /= *anc_anc_v_ws.path_label;
01299 
01300         v_ws.ancestor = anc_v_ws.ancestor;
01301 
01302     } else 
01303         anc_v_ws.tails.ins_last(tail);
01304 
01305     /// ...  Link the path expression from its ancestor.
01306     if (anc_v_ws.path_label) *v_ws.path_label /= *anc_v_ws.path_label;
01307 
01308 }
01309 
01310 static GSAPathExpr *
01311 EVAL_PATH(Statement &v, Statement & tail, unsigned int pass)
01312 {
01313     GSAWorkSpace &v_ws 
01314         = *(GSAWorkSpace *) v.work_stack().top_ref(pass);
01315 
01316     if (!v_ws.ancestor){
01317         v_ws.tails.ins_last(tail); 
01318         return NULL;
01319     }
01320 
01321     COMPRESS_PATH(v, tail, pass);
01322     
01323     return v_ws.path_label->clone();
01324 }
01325 
01326 static void 
01327 LINK_PATH(Statement * v, Statement & w, unsigned int pass, unsigned int pidom_pass)
01328 {
01329     GSAWorkSpace & w_ws 
01330         = *(GSAWorkSpace *) w.work_stack().top_ref(pass);
01331     w_ws.ancestor = v;
01332 
01333     pDominatorWorkSpace & v_ws
01334         = *(pDominatorWorkSpace *) v->work_stack().find_ref(pidom_pass);
01335     if (v_ws.idom == &w)
01336         w_ws.path_label =  new GSAPathExpr(*v,w);
01337     else
01338         w_ws.path_label = w_ws.path_idom->clone();
01339 }
01340 
01341 /// This algorithm is a modification of Tarjan's fast algorithms in
01342 /// "Fast Algorithms for Solving Path Problems", Journal of ACM, Vol 28,
01343 /// No. 3, July 1981, 594-614.  
01344 /// Let idom(v) = u.  The algorithm finds all the paths from u to v
01345 /// containing only proper descendants of u as intermediate vertices.
01346 /// We use it to construct the gating functions.
01347 
01348 static void 
01349 gating(ProgramUnit & NOTUSED(pgm), Array<Statement *> & vertex, 
01350        unsigned int pass,
01351        unsigned int pidom_pass)
01352 {
01353     for (int i = vertex.entries() - 1; i >= 0; --i) {
01354         Statement & u = *vertex[i];
01355         GSAWorkSpace & u_ws 
01356             = *(GSAWorkSpace *) u.work_stack().top_ref(pass);
01357 
01358     /// ...  u is a branch st.
01359     RefList<Statement> top_sorted;
01360 
01361     {
01362             for (Iterator<Statement> children = u_ws.bucket; 
01363                  children.valid(); ++children) {
01364                 Statement & v = children.current();
01365                 GSAWorkSpace & v_ws 
01366                     = *(GSAWorkSpace *) v.work_stack().top_ref(pass);
01367 
01368                 /// ...  Compute every path starting from a sibling s of v containing only
01369                 /// ...  the proper descendants of s.
01370                 for (Iterator<Statement> edges = v.pred(); edges.valid(); ++edges) {
01371                     Statement &e = edges.current();
01372 
01373                     /* Exclude edges originating from an unreachable node
01374                        by checking if it is in the dominator tree (extending
01375                        the original check, which only handled one 
01376                        Polaris-generated case of this: an IMPLIED_GOTO_STMT
01377                        with no predecessors) */
01378 
01379             if (!e.work_stack().top_ref(pass))
01380               continue;
01381             if (&e != &u) {
01382               GSAPathExpr *P = EVAL_PATH(e,v,pass);
01383               if (P==NULL) {
01384             int b = e.succ()._member(v);
01385             p_assert(b >= 0, "v is not a successor of e");
01386             v_ws.path.ins_last(new GSAPathExpr(e,v,b));
01387             ++v_ws.number_of_predecessors;
01388               } else if (P->head == &v) {
01389             /// ...  a loop with v as its entrance
01390             int b = e.succ()._member(v);
01391             p_assert(b >= 0, "v is not a successor of e");
01392             *P *= GSAPathExpr(e,v,b);
01393             if (v_ws.path_star) {
01394               *v_ws.path_star |= *P;
01395               delete P;
01396             } else {
01397               v_ws.path_star = P;
01398             }
01399               } else {
01400             /// ...  an ordinary path from a sibling
01401             int b = e.succ()._member(v);
01402             p_assert(b >= 0, "v is not a successor of e");
01403             *P *= GSAPathExpr(e,v,b);
01404             v_ws.path.ins_last(P);
01405             ++v_ws.number_of_predecessors;
01406               }
01407             } else {
01408               /// ...  Compute the path from u to v
01409               int b = u.succ()._member(v);
01410               p_assert(b >= 0, "v is not a successor of u");
01411               if (v_ws.path_idom) 
01412             v_ws.path_idom->add_edge(u,v,b);
01413               else
01414             v_ws.path_idom = new GSAPathExpr(u,v,b);
01415             }
01416           }
01417 
01418                 if (v_ws.number_of_predecessors == 0)
01419                     top_sorted.ins_last(v);
01420             }
01421         }
01422     
01423         {
01424             int done = 0;
01425             Iterator<Statement> siblings = top_sorted;
01426 
01427             do {
01428                 for ( ; siblings.valid(); ++siblings) {
01429                     Statement & v = siblings.current();
01430                     GSAWorkSpace & v_ws 
01431                         = *(GSAWorkSpace *) v.work_stack().top_ref(pass);
01432 
01433                     if (v_ws.path.entries()) 
01434                         for (Iterator<GSAPathExpr> iter=v_ws.path; iter.valid(); ++iter) {
01435                             GSAPathExpr &path = iter.current();
01436                             Statement * w  = path.head;
01437                             GSAWorkSpace & w_ws 
01438                                 = *(GSAWorkSpace *) w->work_stack().top_ref(pass);
01439                 if (w_ws.path_idom) {
01440                                 path /= *w_ws.path_idom;
01441                         
01442                                 /// ...  UPDATE(v): set the v_ws.pathall be all the paths from u to v
01443                                 /// ...  containing only the proper descendants of u
01444                                 if (v_ws.path_idom)
01445                                     *v_ws.path_idom |= path;
01446                                 else
01447                                     v_ws.path_idom = path.clone();
01448                             }
01449                         }
01450 #if 0
01451                     if (v.pred().entries()>1) v_ws.path_idom->fill_expr()
01452                     if (v_ws.path_star) {
01453                         if (v.stmt_class()==DO_STMT)
01454                             v_ws.path_star->fill_expr(v_ws.path_idom->expr);
01455                         else
01456                             v_ws.path_star->fill_expr(v_ws.path_idom->expr);
01457                         v_ws.path_idom->expr = NULL;
01458                     }
01459 #endif 
01460                     LINK_PATH(&u,v,pass,pidom_pass);
01461                 
01462                     for (Iterator<Statement> iter1 = v_ws.tails; iter1.valid(); ++iter1) {
01463                         Statement &v1 = iter1.current();
01464                         /// ...  if it is not a self cycle
01465                         if (&v1 != &v){ 
01466                             GSAWorkSpace & t_ws 
01467                                 = *(GSAWorkSpace *) v1.work_stack().top_ref(pass);
01468                             --t_ws.number_of_predecessors;
01469                             if (t_ws.number_of_predecessors==0) top_sorted.ins_last(v1);
01470                         }
01471                     }
01472         }
01473 
01474                 if (top_sorted.entries() != u_ws.bucket.entries()) {
01475                     cout << "Irreducible flow graph encounted!" << endl;
01476                     for (Iterator<Statement> iter = u_ws.bucket; iter.valid(); ++iter) {
01477                         Statement &v1 = iter.current();
01478                         if (!top_sorted.member(v1)) {
01479                             top_sorted.ins_last(v1);
01480                             GSAWorkSpace & t_ws
01481                                 = *(GSAWorkSpace *) v1.work_stack().top_ref(pass);
01482                             t_ws.number_of_predecessors = 0;
01483                 siblings.set_to_last();
01484                             break;
01485                         }
01486                     }
01487                 } else
01488                     done = 1;
01489 
01490             } while (!done);
01491         }
01492     }
01493 }
01494 
01495 /// MakeDefMap must be externally visible because it is a friend of
01496 /// DefLoc and DefLocMap... it should NOT be called from other source files
01497 
01498 DefLocMap *
01499 MakeDefMap(ProgramUnit & pgm)
01500 {
01501     DefLocMap *V = new DefLocMap;
01502 
01503     for (DictionaryIter<Symbol> sym = pgm.symtab().iterator();
01504                                 sym.valid(); ++sym) {
01505 ///        cout << sym.current() << endl;
01506         if (sym.current().sym_class() == VARIABLE_CLASS ||
01507         sym.current().sym_class() == FUNCTION_CLASS ||
01508         sym.current().sym_class() == SYMBOLIC_CONSTANT_CLASS) {
01509       // The following is a PRIVATE member access
01510       V->_map.ins(sym.current(),new DefLoc());
01511     }
01512     }
01513 
01514     for (Iterator<Statement> iter = pgm.stmts().iterator(); 
01515                              iter.valid(); ++iter) {
01516         Statement & s = iter.current();
01517 
01518         if (s.stmt_class() == ASSIGNMENT_STMT ||
01519             s.stmt_class() == DO_STMT ||
01520             s.stmt_class() == CALL_STMT ||
01521         s.stmt_class() == READ_STMT ||
01522         s.stmt_class() == WRITE_STMT) {
01523 
01524             for (Iterator<Expression> def_iter = s.out_refs(); 
01525                                       def_iter.valid(); ++def_iter) {
01526                 Expression & def = def_iter.current();
01527 
01528                 DefLoc *v = V->find_ref(*def.base_variable_ref());
01529 
01530         if (v == 0) {
01531                     cerr << "warning: DefDict: base variable not found" 
01532                       << def << endl;
01533                 }
01534         /// ...  The following is a PRIVATE member access
01535                 else if (!v->_st.valid()) {
01536           /// ...  The following is a PRIVATE member access
01537           v->_st = s;
01538                 }
01539                 else if (s.stmt_class() == ASSIGNMENT_STMT &&
01540              s.lhs().base_variable_ref() == def.base_variable_ref()) {
01541             /// ...  The following is a PRIVATE member access
01542             Statement &t = *v->_st;
01543                     if (!(t.stmt_class() == ASSIGNMENT_STMT &&
01544                           t.lhs().base_variable_ref() == def.base_variable_ref())) {
01545             /// ...  The following is a PRIVATE member access
01546               v->_st = s;
01547             }
01548                     else {
01549                         cout << def << "\n";
01550             /// ...  The following is a PRIVATE member access
01551                         cout << *v->_st << "\n" << s << "\n";
01552                         p_abort("More than one definition for a GSA variable");
01553                     }
01554                 }
01555             }
01556         }
01557     }
01558 
01559     return V;
01560 }
01561 
01562 void
01563 MakeGSA(ProgramUnit & pgm)
01564 {
01565     if (pgm.pu_class() == BLOCK_DATA_PU_TYPE) return;
01566     p_assert(!pgm.gsa_valid(),
01567          "MakeGSA called for a GSA ProgramUnit");
01568     pgm.gsa_names(new TranslateObject(pgm));
01569     TranslateObject & trans_obj = pgm.gsa_names_guarded();
01570 
01571     /// ...  The following function is used to avoid irreduciable flow graph
01572     remove_assigned_goto_stmts(pgm);
01573 
01574     /// ...  Find the post dominator
01575     unsigned int   pidom_pass = build_pidom(pgm);
01576 
01577     Timer time;
01578     Map<Symbol,IntElem> candidates;
01579     Array<Symbol *> tag_to_candidate;
01580     int tag = 0;
01581     int gsa_debug = switch_value("gsa_debug");
01582 
01583     Dictionary<PhiPlaceDef> *V = Variable_set_new(pgm,candidates,tag_to_candidate,tag);
01584     
01585     unsigned int   pass = create_pass_tag();
01586 
01587     Array<Statement *> vertex(pgm.stmts().entries());
01588     Dominator_S(pgm, vertex, pass, V, candidates, tag_to_candidate, tag);
01589 
01590     if (gsa_debug) 
01591     cerr << "Time for placement: " << time << endl;
01592 
01593     time.reset();
01594 
01595     /// ...  Declare BETA pseudo function (others are now integrated in base)
01596 
01597     Symbol *beta = new FunctionSymbol("<BETA>", UNKNOWN_TYPE, NOT_EXTERNAL,
01598                                        NOT_INTRINSIC, NOT_FORMAL);
01599 
01600     pgm.symtab().ins(beta);
01601     trans_obj.GSA_mapping(*beta);
01602 
01603     gating(pgm, vertex, pass, pidom_pass);
01604 
01605     if (gsa_debug)
01606     cerr << "Time for gating: " << time << endl;
01607 
01608     /// ...  Insert pseudo assignment statements into the program
01609     time.reset();
01610     insert_pseudo_assignment_stmts(pgm, vertex, tag_to_candidate, pass);
01611 
01612     InitializeGSAStack(trans_obj, V);
01613 
01614     if (gsa_debug)
01615     cerr << "Time for GSA stack: " << time << endl;
01616 
01617     time.reset();
01618     SEARCH(trans_obj, *pgm.stmts().first_ref(), *V, pass, beta);
01619 
01620     if (gsa_debug)
01621     cerr << "Time for renaming: " << time << endl;
01622 
01623     time.reset();
01624     delete V;
01625 
01626     if (gsa_debug)
01627     cerr << "Time for deleting GSA stack: " << time << endl;
01628 
01629     time.reset();
01630     InsertPhiStmt(pgm, vertex, pass, 1);
01631 
01632     if (gsa_debug)
01633     cerr << "Time for inserting PHIs: " << time << endl;
01634 
01635     pgm.clean_workspace(pass);
01636     pgm.clean_workspace(pidom_pass);
01637     pgm.gsa_deflocs(MakeDefMap(pgm));
01638 }
01639 
01640 void
01641 MakeGSA_test(TranslateObject & trans_obj)
01642 {
01643     ProgramUnit & pgm = trans_obj.pgm_main();
01644     if (pgm.pu_class() == BLOCK_DATA_PU_TYPE) return;
01645 
01646     /// ...  The following function is used to avoid irreduciable flow graph
01647     remove_assigned_goto_stmts(pgm);
01648 
01649     /// ...  Find the post dominator
01650     unsigned int   pidom_pass = build_pidom(pgm);
01651 
01652     Map<Symbol,IntElem> candidates;
01653     Array<Symbol *> tag_to_candidate;
01654     int tag = 0;
01655 
01656     Dictionary<PhiPlaceDef> *V = Variable_set_new(pgm,candidates,tag_to_candidate,tag);
01657     
01658     unsigned int   pass = create_pass_tag();
01659 
01660     Array<Statement *> vertex(pgm.stmts().entries());
01661     Dominator_S(pgm, vertex, pass, V, candidates, tag_to_candidate, tag);
01662 
01663     /// ...  Declare BETA pseudo function (all others integrated into base)
01664 
01665     Symbol *beta = new FunctionSymbol("<BETA>", UNKNOWN_TYPE, NOT_EXTERNAL,
01666                                        NOT_INTRINSIC, NOT_FORMAL);
01667 
01668     pgm.symtab().ins(beta);
01669     trans_obj.GSA_mapping(*beta);
01670 
01671 ///    gating(pgm, vertex, pass, pidom_pass);
01672 
01673 
01674     /// ...  Insert pseudo assignment statements into the program
01675     insert_pseudo_assignment_stmts(pgm, vertex, tag_to_candidate,
01676                    pass);
01677 
01678     InitializeGSAStack(trans_obj, V);
01679 
01680     SEARCH(trans_obj, *pgm.stmts().first_ref(), *V, pass, beta);
01681 
01682     delete V;
01683 
01684     InsertPhiStmt(pgm, vertex, pass, 0);
01685 
01686     pgm.clean_workspace(pass);
01687     pgm.clean_workspace(pidom_pass);
01688 }
01689 Expression * 
01690 trans_update_expr(InlineObject * tobj, Expression * expr)
01691 {
01692     Expression * return_expr = expr;
01693 
01694     extern Boolean is_leaf(const Expression & expr);
01695 
01696     if (is_leaf(*expr)) {
01697     Symbol * oldsym = expr->base_variable_ref();
01698     if (oldsym == 0) return expr;
01699 
01700     Expression * xlate = tobj->translate_GSA_refs_expr(expr);  
01701     Symbol * xlatesym = xlate->base_variable_ref();
01702     if (oldsym == xlatesym) {
01703         if (oldsym->sym_class() != VARIABLE_CLASS) {
01704         return_expr = xlate;
01705         } else {
01706         Symbol & newsym = trans_update_symbol(tobj, *(VariableSymbol *) oldsym);
01707         xlate->symbol(newsym);
01708         return_expr = xlate;
01709         }
01710     } else {
01711         return_expr = xlate;
01712     }
01713     } else {
01714     Traverser tr(*expr, is_leaf);
01715 
01716     for ( ; tr.valid(); ++tr) {
01717 
01718         if (tr.current().op() != ID_OP) continue;
01719 
01720         Assign<Expression> eas = tr.assign();
01721         Expression * epull = tr.pull();
01722         static LambdaInfo lambda(0, 0, INLINE_CALL);
01723         tobj->remap_expr(&epull, lambda, IN_REF_EXPR);
01724         eas = epull;
01725     }
01726     return_expr = expr;
01727     }
01728     return return_expr;
01729 }
01730 Symbol &
01731 trans_update_symbol( TranslateObject * tobj, VariableSymbol & sym)
01732 {
01733     VariableSymbol * trans_sym = (VariableSymbol *)(&sym);
01734     if (trans_sym->is_gsa_symbol()) {
01735     trans_sym = (VariableSymbol *) (&(trans_sym->gsa_base_symbol()));
01736     }
01737     Symbol * symclone = trans_sym->clone();
01738     Symbol & newsym = tobj->pgm_main().symtab().rename_and_ins(symclone);
01739     tobj->GSA_mapping(sym, newsym);
01740 
01741     return newsym;
01742 }
01743 
01744 
01745 /*
01746  * Guobin: Make a new gsa variable whose index is C
01747 */
01748 VariableSymbol* make_gsa_var(ProgramUnit& pgm, VariableSymbol& old_var, int C) {
01749   TranslateObject & trans_obj = pgm.gsa_names_guarded();
01750   int             i = C;
01751   String          var_i(old_var.name_ref());
01752 
01753   var_i += "@";
01754   var_i += integer_to_string(i);
01755 
01756   VariableSymbol* _t = new VariableSymbol(var_i, old_var.type(), 
01757                                                old_var.formal(),
01758                                               old_var.saved() );
01759   _t->dim() = old_var.dim();
01760   _t->shared_dim() = old_var.shared_dim();
01761   VariableSymbol & new_var = (VariableSymbol &)pgm.symtab().ins(_t);
01762   new_var.gsa_base_symbol( old_var );
01763 
01764   trans_obj.GSA_mapping(*_t,old_var);
01765   return &new_var;
01766 }
01767 
01768 VariableSymbol* get_gsa_var(ProgramUnit& pgm, VariableSymbol& base_var, int C) {
01769   Symtab& st=pgm.symtab();
01770   String var_c(base_var.name_ref());
01771   var_c+="@";
01772   var_c+=integer_to_string(C);
01773   Symbol* _new_sym=st.find_ref(var_c);
01774   return (VariableSymbol*)_new_sym;
01775 }
 © 1995-2005 University of Illinois, Urbana-Champaign. All rights reserved.  Fri Mar 25 23:05:53 2005