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
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
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
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
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
00111
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
00135
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
00152 Statement * stack_stmt_ptr = &first_stmt;
00153 GSAWorkSpace * stack_stmt_ws_ptr = 0;
00154
00155 int array_index = -1;
00156
00157 Statement * parent_stmt_ptr = 0;
00158
00159 while (1) {
00160
00161 if (!stack_stmt_ws_ptr) {
00162
00163
00164 stack_stmt_ws_ptr = new GSAWorkSpace(pass, size);
00165
00166 vertex[++array_index] = stack_stmt_ptr;
00167
00168 stack_stmt_ptr->work_stack().push(stack_stmt_ws_ptr);
00169
00170 stack_stmt_ws_ptr->semi = array_index + 1;
00171
00172 stack_stmt_ws_ptr->parent = parent_stmt_ptr;
00173
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
00207 parent_stmt_ptr = 0;
00208
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
00215 Statement & succ_stmt = succ_iter.current();
00216
00217 ++succ_iter;
00218
00219 GSAWorkSpace * succ_stmt_ws_ptr =
00220 (GSAWorkSpace *) succ_stmt.work_stack().top_ref(pass);
00221 if (!succ_stmt_ws_ptr) {
00222
00223 if (succ_iter.valid()) {
00224
00225 stack_stmt_ws_ptr->ancestor = &succ_iter.current();
00226 }
00227 else {
00228
00229 stack_stmt_ws_ptr->label = stack_stmt_ptr;
00230 }
00231
00232 parent_stmt_ptr = stack_stmt_ptr;
00233 stack_stmt_ptr = &succ_stmt;
00234 stack_stmt_ws_ptr = 0;
00235 break;
00236 }
00237 }
00238
00239 if (parent_stmt_ptr)
00240 continue;
00241
00242 stack_stmt_ws_ptr->label = stack_stmt_ptr;
00243 }
00244
00245 stack_stmt_ws_ptr->ancestor = 0;
00246
00247 stack_stmt_ptr = stack_stmt_ws_ptr->parent;
00248
00249 if (!stack_stmt_ptr)
00250 break;
00251
00252 stack_stmt_ws_ptr =
00253 (GSAWorkSpace *) stack_stmt_ptr->work_stack().top_ref(pass);
00254 }
00255
00256
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
00294
00295
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
00310
00311
00312
00313
00314 for (Mutator<Statement> v = p_ws.bucket; v.valid(); ++v) {
00315 Statement & vc = v.current();
00316
00317
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
00333
00334
00335 *v_ws._b_idef |= *v_ws._b_sdef;
00336
00337
00338
00339 *v_ws._b_idef |= EVALDEF;
00340
00341
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
00352
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
00365
00366
00367 *w_ws._b_idef |= *d_ws._b_idef;
00368
00369
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 {
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
00603 if (expr.op()==ID_OP){
00604 if (expr.symbol().is_array() || expr.symbol().is_scalar()){
00605
00606 IDExpr& idexpr=(IDExpr&)expr;
00607 if (idexpr.substituted_valid()){
00608
00609 avoid_arrays_substitute_var(idexpr.substituted_guarded(), n, s);
00610
00611 }
00612 }
00613 } else {
00614
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
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
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
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
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 {
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
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
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 {
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
01014
01015
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
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
01044
01045 if (called_pgm(X)){
01046
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
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
01172
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
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
01199
01200
01201 if (w.stmt_class() == FLOW_EXIT_STMT && w_ws.PHI->entries()) {
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
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
01225
01226
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
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
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
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
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
01342
01343
01344
01345
01346
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
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
01369
01370 for (Iterator<Statement> edges = v.pred(); edges.valid(); ++edges) {
01371 Statement &e = edges.current();
01372
01373
01374
01375
01376
01377
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
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
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
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
01443
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
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
01496
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
01506 if (sym.current().sym_class() == VARIABLE_CLASS ||
01507 sym.current().sym_class() == FUNCTION_CLASS ||
01508 sym.current().sym_class() == SYMBOLIC_CONSTANT_CLASS) {
01509
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
01535 else if (!v->_st.valid()) {
01536
01537 v->_st = s;
01538 }
01539 else if (s.stmt_class() == ASSIGNMENT_STMT &&
01540 s.lhs().base_variable_ref() == def.base_variable_ref()) {
01541
01542 Statement &t = *v->_st;
01543 if (!(t.stmt_class() == ASSIGNMENT_STMT &&
01544 t.lhs().base_variable_ref() == def.base_variable_ref())) {
01545
01546 v->_st = s;
01547 }
01548 else {
01549 cout << def << "\n";
01550
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
01572 remove_assigned_goto_stmts(pgm);
01573
01574
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
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
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
01647 remove_assigned_goto_stmts(pgm);
01648
01649
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
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
01672
01673
01674
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
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 }