00001
00002 #include <set>
00003
00004 #include "Statement/AssignmentStmt.h"
00005 #include "Statement/DoStmt.h"
00006 #include "utilities/gsa_util.h"
00007 #include "utilities/program_util.h"
00008 #include "Deadcode/deadcode.h"
00009
00010 #include "simple_maymods.h"
00011 #include "ip_ssa.h"
00012 #include "trans_util.h"
00013 #include "optimize_ssa.h"
00014 #include "Expression/BinaryExpr.h"
00015 #include "Expression/UnaryExpr.h"
00016 #include "Expression/expr_funcs.h"
00017
00018
00019 static Database<ProgramUnit*, Database<Symbol*, RefList<Symbol> > > iomap;
00020
00021
00022
00023
00024
00025 static Database<ProgramUnit*,
00026 Database<Statement*,
00027 RefDatabase<Symbol*,
00028 Symbol> > > _gmap;
00029
00030
00031
00032
00033
00034 static Database<ProgramUnit*,
00035 Database<Symbol*,
00036 List<GlobalDefSite> > > _dmap;
00037
00038 Database<ProgramUnit*,
00039 Database<Statement*,
00040 RefDatabase<Symbol*,
00041 Symbol> > >& ip_ssa_gmap(){
00042 return _gmap;
00043 }
00044
00045 Database<ProgramUnit*,
00046 Database<Symbol*,
00047 List<GlobalDefSite> > >& ip_ssa_dmap(){
00048 return _dmap;
00049 }
00050
00051
00052
00053 static void print_dmap(){
00054 cerr<<"\n\n\nBEGIN DMAP: \n\n";
00055 KeyIterator<ProgramUnit*, Database<Symbol*, List<GlobalDefSite> > > it1=
00056 _dmap;
00057 for (; it1.valid(); ++it1){
00058 cerr<<"\nFor pgm. "<<it1.current_key()->routine_name_ref();
00059 KeyIterator<Symbol*, List<GlobalDefSite> > it2=it1.current_data();
00060 for(; it2.valid(); ++it2){
00061 cerr<<"\n\tFor Sym. "<<it2.current_key()->name_ref()<<
00062 " "<<it2.current_data();
00063 }
00064 }
00065 cerr<<"\n\n\nEND DMAP\n\n\n ";
00066 }
00067
00068
00069 static void print_gmap(ProgramUnit& pgm){
00070 cerr<<"\n\n\nBEGIN GMAP: \n\n";
00071 cerr<<"\nFor pgm. "<<pgm.routine_name_ref();
00072 if (_gmap.find_ref(&pgm)!=0) {
00073 KeyIterator<Statement*, RefDatabase<Symbol*, Symbol> > it2=
00074 *_gmap.find_ref(&pgm);
00075 for(; it2.valid(); ++it2){
00076 cerr<<"\nFor stmt: ";
00077 int w=1;
00078 it2.current_key()->write(cerr, w);
00079 KeyIterator<Symbol*, Symbol> it3=it2.current_data();
00080 for(; it3.valid(); ++it3){
00081 cerr<<"\n"<<it3.current_key();
00082 cerr<<"\n\tFor Sym. "<<it3.current_key()->name_ref()<<
00083 ", mapped is: "<<it3.current_data().name_ref();
00084 }
00085 }
00086 }
00087 cerr<<"\n\n\nEND GMAP\n\n\n ";
00088 }
00089
00090
00091
00092
00093 static void print_in_out_sets(Program& prog){
00094 for (KeyIterator<ProgramUnit*, Database<Symbol*, RefList<Symbol> > > pssit=
00095 iomap; pssit.valid(); ++pssit){
00096 cerr<<"\nIn pgm. "<<pssit.current_key()->routine_name_ref();
00097 for (KeyIterator<Symbol*, RefList<Symbol> > ssit=
00098 pssit.current_data(); ssit.valid(); ++ssit){
00099 cerr<<"\n\tFor output value "<<ssit.current_key()->name_ref()<<"\t:";
00100 for (Iterator<Symbol> sit=
00101 ssit.current_data(); sit.valid(); ++sit){
00102 cerr<<" "<<sit.current().name_ref();
00103 }
00104 }
00105 }
00106 }
00107
00108 void build_in_out_set(Symbol& out, IntraPCodeDomain& domain,
00109 RefList<Symbol>& in,
00110 ProgramUnit& pgm, Program& prog){
00111
00112 RefList<Symbol> q;
00113 q.ins_last(out);
00114 Database<Symbol*, IntElem> seen;
00115
00116 while (q.entries()){
00117 VariableSymbol& current=(VariableSymbol&)q.grab(0);
00118
00119 VariableSymbol* base_current=¤t;
00120 if (base_current->is_gsa_symbol()){
00121 base_current=(VariableSymbol*)&base_current->gsa_base_symbol();
00122 }
00123 if (seen.find_ref(¤t)){
00124 continue;
00125 } else {
00126 seen.ins(¤t, new IntElem(0));
00127 }
00128
00129 if (current.intrinsic()){
00130 continue;
00131 }
00132
00133 String basename;
00134 int rank;
00135 gsa_details(current.name_ref(), basename, rank);
00136 if (rank==0){
00137 bool is_data=false;
00138
00139 for (Iterator<Data> dit=pgm.data(); dit.valid(); ++dit){
00140 for(Iterator<Expression> eit=dit.current().variable_list().arg_list();
00141 eit.valid(); ++eit){
00142 if (eit.current().base_variable_ref()==base_current){
00143
00144 is_data=true;
00145 break;
00146 }
00147 }
00148 if (is_data) break;
00149 }
00150 if (is_data){
00151
00152 } else {
00153
00154 if (!in.member(current)){
00155 in.ins_last(current);
00156 }
00157 }
00158 continue;
00159 }
00160
00161
00162 DefLoc* defloc=pgm.gsa_deflocs_guarded().find_ref(current);
00163 if (!defloc) {
00164 p_abort("Bad DefLoc map.");
00165 }
00166 if (!defloc->stmt_valid()) {
00167 p_abort("Bad DefLoc map.");
00168 }
00169 Statement& def=defloc->stmt_guarded();
00170
00171
00172 if (!domain.contains(def)){
00173 if (!in.member(current)){
00174 in.ins_last(current);
00175 }
00176 continue;
00177 }
00178
00179 Statement* call=0;
00180 ProgramUnit* callee=0;
00181
00182
00183
00184
00185
00186
00187
00188 RefList<Symbol> corresponding_base_syms;
00189 if (def.stmt_class()==ASSIGNMENT_STMT){
00190 if (def.rhs().op()==THETA_OP){
00191 call=&def;
00192 while (call!=0){
00193 if (called_pgm(*call)){
00194 break;
00195 }
00196 call=call->prev_ref();
00197 }
00198 p_assert(call, "Bad THETA placement.");
00199 callee=called_pgm(*call);
00200 Symbol* cbs=0;
00201 cbs=callee->symtab().find_ref(basename);
00202 p_assert(cbs, "Could not map common vars.");
00203 corresponding_base_syms.ins_last(*cbs);
00204 }
00205 }
00206
00207
00208 if (!call){
00209 callee=called_pgm(def);
00210 if (callee){
00211
00212 call=&def;
00213 Translator translator(pgm, def);
00214 corresponding_base_syms=untranslate_var(current,
00215 *callee, pgm, *call);
00216 p_assert(corresponding_base_syms.entries(),
00217 "No suitable un-translation found.");
00218
00219 if (current.common_ref()){
00220 corresponding_base_syms.ins_last(*callee->symtab().find_ref(basename));
00221 }
00222 }
00223 }
00224
00225
00226 if (call){
00227 Translator translator(pgm, *call);
00228
00229 for(Iterator<Symbol> sit=corresponding_base_syms; sit.valid(); ++sit){
00230 Symbol* corresponding_base_sym=&sit.current();
00231 Database<Symbol*, RefList<Symbol> >* local_iomap=iomap.find_ref(callee);
00232 if (local_iomap==0){
00233 cerr<<"\nFor routine: "<<callee->routine_name_ref();
00234 p_abort("Could not find local in-out map.");
00235 }
00236 RefList<Symbol>* callee_iomap=
00237 local_iomap->find_ref(corresponding_base_sym);
00238 if (!callee_iomap){
00239 cerr<<"\nFor routine: "<<callee->routine_name_ref()
00240 <<" and symbol "<<corresponding_base_sym->name_ref();
00241 p_abort( "Could not find in-out map.");
00242 }
00243 for(Iterator<Symbol> csit=*callee_iomap; csit.valid(); ++csit){
00244
00245
00246
00247 Expression* te=translate_var((VariableSymbol&)csit.current(),
00248 *callee, pgm, *call);
00249
00250 if(te==0){
00251
00252
00253
00254
00255
00256
00257 } else {
00258 te=simplify(te);
00259 if (te->op()==INTEGER_CONSTANT_OP ||
00260 te->op()==REAL_CONSTANT_OP ||
00261 te->op()==STRING_CONSTANT_OP ||
00262 te->op()==LOGICAL_CONSTANT_OP ||
00263 te->op()==HOLLERITH_CONSTANT_OP){
00264
00265 } else {
00266 RefList<Symbol> referred;
00267 referred_symbols(*te, referred);
00268
00269 for (Iterator<Symbol> ssit=referred; ssit.valid(); ++ssit){
00270
00271 q.ins_last(ssit.current());
00272 }
00273 }
00274 delete te;
00275 }
00276 }
00277 }
00278 continue;
00279 }
00280
00281
00282 Iterator<Expression> sit=def.in_refs();
00283 for( ; sit.valid(); ++sit){
00284 switch(sit.current().op()){
00285 case ID_OP:
00286
00287 q.ins_last(sit.current().symbol());
00288 break;
00289 case ARRAY_REF_OP:
00290
00291 q.ins_last(sit.current().array().symbol());
00292 }
00293 }
00294 }
00295 }
00296
00297
00298 Symbol* last_gsa_symbol(ProgramUnit& pgm, Symbol& sym){
00299
00300
00301
00302
00303
00304
00305
00306 Symbol* last_def_sym=0;
00307 for(Statement* stit=pgm.stmts().last_ref(); stit!=0; stit=stit->prev_ref()){
00308
00309
00310 if (stit->stmt_class()==ENDDO_STMT){
00311
00312 Statement* dostmt=stit->follow_ref();
00313 Statement* ps=dostmt->next_ref();
00314 while (ps){
00315 if (ps->stmt_class()!=ASSIGNMENT_STMT){
00316 break;
00317 }
00318 if (ps->rhs().op()!=MU_OP){
00319 break;
00320 }
00321 if (gsa_base(ps->lhs().symbol())==&sym){
00322 last_def_sym=&ps->lhs().symbol();
00323 break;
00324 }
00325 ps=ps->next_ref();
00326 }
00327 }
00328 if (last_def_sym) break;
00329
00330 for(Iterator<Expression> sit=stit->out_refs(); sit.valid(); ++sit){
00331 Expression& ce=sit.current();
00332 VariableSymbol* candidate=0;
00333 switch (ce.op()){
00334 case ID_OP:
00335 candidate=(VariableSymbol*)&ce.symbol();
00336 break;
00337 case ARRAY_REF_OP:
00338 candidate=(VariableSymbol*)&ce.array().symbol();
00339 break;
00340 default:
00341 cerr<<"\nIn statement: "<<*stit;
00342 cerr<<"\n "<<sit.current();
00343 p_abort("Out ref. is not variable.");
00344 }
00345
00346
00347
00348 if (candidate->sym_class()==FUNCTION_CLASS){
00349
00350
00351 String basename;
00352 int rank;
00353 gsa_details(candidate->name_ref(), basename, rank);
00354 if (basename==sym.name_ref()){
00355 last_def_sym=candidate;
00356 break;
00357 }
00358 } else {
00359 if (!candidate->is_gsa_symbol()){
00360 if (has_maymod(*stit)){
00361 if (is_var_in_maymod(*candidate, *stit)){
00362 cerr<<"\n "<<candidate->name_ref()
00363 <<"\n in stmt "<<*stit;
00364 p_abort("Definition must refer to nontrivial GSA name.");
00365 } else {
00366
00367 continue;
00368 }
00369 } else {
00370 if (called_pgm(*stit)){
00371
00372
00373 p_warning("Subprogram call statement has no MAYMOD assertions.");
00374 last_def_sym=candidate;
00375 break;
00376 } else {
00377 cerr<<"\n "<<candidate->name_ref()
00378 <<"\n in stmt "<<*stit;
00379
00380 p_abort("Definition must refer to nontrivial GSA name.");
00381 }
00382 }
00383 }
00384
00385 if (&candidate->gsa_base_symbol()==&sym){
00386 last_def_sym=candidate;
00387 break;
00388 }
00389 }
00390 }
00391 if (last_def_sym) {
00392 break;
00393 }
00394 }
00395 return last_def_sym;
00396 }
00397
00398 void build_in_out_sets(Program& prog, ProgramUnit& pgm, Symbol& sym,
00399 Database<Symbol*, RefList<Symbol> >& pgm_iomap){
00400 RefList<Symbol>* in=new RefList<Symbol>;
00401 pgm_iomap.ins(&sym, in);
00402
00403
00404 Symbol* last_def_sym=last_gsa_symbol(pgm, sym);
00405
00406 if (last_def_sym==0){
00407
00408 in->ins_last(sym);
00409 return;
00410 }
00411
00412
00413 IntraPCodeDomain domain(pgm);
00414
00415 build_in_out_set(*last_def_sym, domain, *in, pgm, prog);
00416 }
00417
00418
00419
00420 void build_in_out_sets(Program& prog, ProgramUnit& pgm){
00421 if (!is_code_pu(pgm)){
00422
00423 return;
00424 }
00425 if (iomap.find_ref(&pgm)){
00426
00427 return;
00428 }
00429 Database<Symbol*, RefList<Symbol> >* pgm_iomap=
00430 new Database<Symbol*, RefList<Symbol> >;
00431 iomap.ins(&pgm, pgm_iomap);
00432
00433
00434
00435 for(Iterator<ProgramUnit> pgmit=pgm.calls(); pgmit.valid(); ++pgmit){
00436
00437
00438 build_in_out_sets(prog, pgmit.current());
00439 }
00440
00441
00442
00443
00444
00445
00446
00447
00448 RefList<Symbol> out;
00449 Statement* entry=pgm.stmts().first_ref();
00450 while (entry->stmt_class()!=ENTRY_STMT) {
00451 entry=entry->next_ref();
00452 if(entry==0) break;
00453 }
00454 if(entry==0){
00455 cerr<<"\nProgram without entry: "<<pgm.routine_name_ref();
00456 p_abort("");
00457 }
00458 List<Expression>& formals=parameters(*entry);
00459 for(Iterator<Expression> eit=formals; eit.valid(); ++eit){
00460 if (eit.current().op()!=ID_OP){
00461 cerr<<"Formal not ID_OP: "<<eit.current();
00462 p_abort("");
00463 }
00464 Symbol& sym=eit.current().symbol();
00465 out.ins_last(sym);
00466 }
00467
00468 for(DictionaryIter<CommonBlock> cbit=pgm.common_blocks();
00469 cbit.valid(); ++cbit){
00470 for(Iterator<Symbol> sit=cbit.current().iterator(); sit.valid(); ++sit){
00471 if (!out.member(sit.current())){
00472 out.ins_last(sit.current());
00473 }
00474 }
00475 }
00476
00477 if (pgm.pu_class()==FUNCTION_PU_TYPE){
00478 Symbol* fret=pgm.symtab().find_ref(pgm.routine_name_ref());
00479 p_assert(fret, "Function did not declare return value.");
00480 out.ins_last(*fret);
00481 }
00482
00483
00484
00485
00486
00487 for(Iterator<Symbol> sit=out; sit.valid(); ++sit){
00488 Symbol& sym=sit.current();
00489
00490 build_in_out_sets(prog, pgm, sym, *pgm_iomap);
00491 }
00492 }
00493
00494
00495
00496
00497 void build_in_out_sets(Program& prog){
00498
00499
00500 prog.compute_call_lists();
00501
00502
00503
00504 RefList<ProgramUnit> tops;
00505 for (KeyIterator<String, ProgramUnit> pgmit=prog; pgmit.valid(); ++pgmit){
00506 ProgramUnit& pgm=pgmit.current_data();
00507 if (pgm.called_by().entries()==0){
00508 tops.ins_last(pgm);
00509 }
00510 }
00511
00512 for(Iterator<ProgramUnit> pit=tops; pit.valid(); ++pit){
00513 ProgramUnit& pgm=pit.current();
00514 build_in_out_sets(prog, pgm);
00515 }
00516
00517
00518
00519 }
00520
00521
00522 Expression* theta(Expression *parameters);
00523 Expression* eta(Expression* gate, Expression* parameters);
00524
00525 static bool actual_out_param(Symbol& sym, Statement& stmt){
00526
00527 for(Iterator<Expression> eit=parameters(stmt); eit.valid(); ++eit){
00528
00529 if(eit.current().base_variable_ref()==&sym) return true;
00530 }
00531 return false;
00532 }
00533
00534 static void remove_dummy_assignments(Program& prog){
00535
00536 KeyIterator<String,ProgramUnit> progiter = prog;
00537 for (progiter.reset();
00538 progiter.valid();
00539 ++progiter) {
00540 ProgramUnit& pgm=progiter.current_data();
00541 Statement* ps=pgm.stmts().first_ref();
00542 Statement* next=0;
00543 while (ps){
00544 next=ps->next_ref();
00545 if (ps->stmt_class()==ASSIGNMENT_STMT){
00546 if (ps->lhs()==ps->rhs()){
00547 pgm.stmts().del(*ps);
00548 }
00549 }
00550 ps=next;
00551 }
00552 }
00553 }
00554
00555 static void add_dummy_global_assignments_at_calls(Program& prog){
00556
00557
00558 KeyIterator<String,ProgramUnit> progiter = prog;
00559 for (progiter.reset();
00560 progiter.valid();
00561 ++progiter) {
00562 ProgramUnit& pgm=progiter.current_data();
00563 Statement* ps=pgm.stmts().first_ref();
00564 Statement* next;
00565 while (ps){
00566 next=ps->next_ref();
00567 ProgramUnit* callee=called_pgm(*ps);
00568 if (callee) {
00569 Symbol* callee_sym;
00570 if (ps->stmt_class()==CALL_STMT){
00571 callee_sym=&ps->routine_guarded().symbol();
00572 } else {
00573 callee_sym=&ps->rhs().function().symbol();
00574 }
00575 Iterator<Assertion> asrt_iter = ps->assertions();
00576 for ( ; asrt_iter.valid(); ++asrt_iter) {
00577 if (asrt_iter.current().type() == AS_MAYMOD) {
00578 Iterator<Expression> aexpr_iter =
00579 asrt_iter.current().arg_list_guarded();
00580 for ( ; aexpr_iter.valid(); ++aexpr_iter){
00581 Symbol* sym=aexpr_iter.current().base_variable_ref();
00582 if (sym) {
00583 if (sym->common_ref() &&
00584
00585 !actual_out_param(*sym, *ps)){
00586 if (sym->is_scalar()){
00587
00588 AssignmentStmt* newstmt=
00589 new AssignmentStmt(pgm.stmts().new_tag(),
00590 id(*sym),
00591 theta(comma(id(*sym))));
00592 pgm.stmts().ins_before(newstmt, next);
00593 } else {
00594
00595 AssignmentStmt* newstmt=
00596 new AssignmentStmt(pgm.stmts().new_tag(),
00597 id(*sym),
00598 theta(comma(id(*sym))));
00599 pgm.stmts().ins_before(newstmt, next);
00600
00601 }
00602 }
00603 }
00604 }
00605 }
00606 }
00607 }
00608 ps=next;
00609 }
00610 }
00611 }
00612
00613
00614
00615
00616 static void add_dummy_eta_assignments_after_loops(Program& prog){
00617
00618 KeyIterator<String,ProgramUnit> progiter = prog;
00619 for(progiter.reset();progiter.valid();++progiter)
00620 {
00621 ProgramUnit& pgm=progiter.current_data();
00622 Iterator<Statement> stmt_iter=
00623 pgm.stmts().stmts_of_type(DO_STMT,WHILE_STMT);
00624 for(stmt_iter.reset();stmt_iter.valid();++stmt_iter)
00625 {
00626 Statement& stmt=stmt_iter.current();
00627 Expression * _condition;
00628 Type type(VOID_TYPE);
00629 RefList<Symbol> sym_list;
00630 Iterator<Statement> loop_body_iter;
00631 if(stmt.stmt_class()==DO_STMT)
00632 {
00633 Expression& lmt=stmt.limit();
00634 if(lmt.op()!=INFINITY_OP)
00635 {
00636 _condition=at_least_one_iteration(pgm, (DoStmt&)stmt, false);
00637 }
00638 else
00639 {
00640 Statement * _if_stmt=stmt.next_ref();
00641 if (_if_stmt->stmt_class()==ENDDO_STMT){
00642
00643 _condition=constant(".TRUE.");
00644 } else {
00645 p_assert(_if_stmt->stmt_class()==IF_STMT,
00646 "The next statement to the do statement"
00647 " should be IF statement\n");
00648 Expression& if_condition=_if_stmt->expr();
00649 _condition=simplify(not(if_condition.clone()));
00650 }
00651 };
00652
00653 loop_body_iter=
00654 pgm.stmts().iterate_loop_body(CASTAWAY(Statement *)&stmt);
00655 }
00656 else
00657 {
00658 Expression& while_condition=stmt.expr();
00659 _condition=simplify(not(while_condition.clone()));
00660
00661
00662 p_warning("Incomplete implementation.");
00663 loop_body_iter=
00664 pgm.stmts().iterator((Statement&)stmt,*stmt.follow_ref());
00665 };
00666
00667 for(loop_body_iter.reset();loop_body_iter.valid();++loop_body_iter)
00668 {
00669 Statement& loop_body_stmt=loop_body_iter.current();
00670 if(loop_body_stmt.stmt_class()==DO_STMT)
00671 continue;
00672 RefSet<Expression> out_exprs=loop_body_stmt.out_refs();
00673 while(out_exprs.entries()>0)
00674 {
00675 Expression& out_expr=out_exprs.grab();
00676 if(out_expr.op()==ARRAY_REF_OP||out_expr.op()==ID_OP)
00677 {
00678 Symbol * _out_sym=out_expr.base_variable_ref();
00679 if(!sym_list.member(*_out_sym))
00680 {
00681 sym_list.ins_last(*_out_sym);
00682 }
00683 }
00684 }
00685 };
00686
00687 Iterator<Symbol> sym_iter=sym_list;
00688 Statement * _stmt_ref=stmt.follow_ref();
00689 for(sym_iter.reset();sym_iter.valid();++sym_iter)
00690 {
00691 Symbol& sym=sym_iter.current();
00692 AssignmentStmt* newstmt=
00693 new AssignmentStmt(pgm.stmts().new_tag(), id(sym),
00694 eta(_condition->clone(),
00695 comma(id(sym),id(sym))));
00696 pgm.stmts().ins_after(newstmt,_stmt_ref);
00697 }
00698 delete _condition;
00699 }
00700 }
00701 }
00702
00703 static void modify_dummy_eta_assignments_after_loops(Program& prog){
00704
00705 KeyIterator<String,ProgramUnit> progiter = prog;
00706 for(progiter.reset();progiter.valid();++progiter)
00707 {
00708 ProgramUnit& pgm=progiter.current_data();
00709 Iterator<Statement> stmt_iter=pgm.stmts().stmts_of_type(DO_STMT,WHILE_STMT);
00710 for(stmt_iter.reset();stmt_iter.valid();++stmt_iter)
00711 {
00712 Statement& stmt=stmt_iter.current();
00713 RefMap<Symbol,Statement> mu_assignment;
00714 RefList<Statement> eta_assignment;
00715 bool keep_searching=true;
00716 Statement * _stmt_ptr=stmt.next_ref();
00717 while(keep_searching)
00718 {
00719 if(_stmt_ptr->stmt_class()==ASSIGNMENT_STMT)
00720 {
00721 Expression& mu_expr=_stmt_ptr->rhs();
00722 if(mu_expr.op()==MU_OP)
00723 {
00724 p_assert(_stmt_ptr->lhs().op()==ID_OP,
00725 "The left expression in mu"
00726 " statement should be an id expression\n");
00727 Symbol& mu_sym=_stmt_ptr->lhs().symbol();
00728 mu_assignment.ins(mu_sym,*_stmt_ptr);
00729 }
00730 else
00731 keep_searching=false;
00732 }
00733 else
00734 keep_searching=false;
00735 _stmt_ptr=_stmt_ptr->next_ref();
00736 };
00737
00738 _stmt_ptr=stmt.follow_ref()->next_ref();
00739 keep_searching=true;
00740 while(keep_searching)
00741 {
00742 if(_stmt_ptr->stmt_class()==ASSIGNMENT_STMT)
00743 {
00744 Expression& eta_expr=_stmt_ptr->rhs();
00745 if(eta_expr.op()==ETA_OP)
00746 {
00747 eta_assignment.ins_last(*_stmt_ptr);
00748 }
00749 else
00750 {
00751 keep_searching=false;
00752 }
00753 }
00754 else
00755 {
00756 keep_searching=false;
00757 }
00758 _stmt_ptr=_stmt_ptr->next_ref();
00759 };
00760
00761 Iterator<Statement> eta_iter=eta_assignment;
00762 for(eta_iter.reset();eta_iter.valid();++eta_iter)
00763 {
00764 Statement& eta_stmt=eta_iter.current();
00765 Expression& eta_expr=eta_stmt.rhs();
00766 p_assert(eta_expr.op()==ETA_OP,
00767 "The right expression in eta statement should be an eta expression\n");
00768 Expression& first_eta_expr=eta_expr.parameters_guarded().arg_list()[1];
00769 Symbol& first_sym=first_eta_expr.symbol();
00770
00771
00772 if(mu_assignment.member(first_sym))
00773 {
00774 Statement& mu_stmt=mu_assignment[first_sym];
00775 Expression& mu_expr=mu_stmt.rhs();
00776 Expression& second_mu_expr=mu_expr.parameters_guarded().arg_list()[0];
00777 Symbol& new_sym=second_mu_expr.symbol();
00778 substitute_var(first_eta_expr,first_sym,new_sym);
00779 }
00780 }
00781 }
00782 }
00783 }
00784
00785
00786
00787 static Symbol* def_call_gsa_name(Statement& callsite, Symbol& base){
00788 if (!base.is_scalar() && !base.is_array()){
00789 return 0;
00790 }
00791 p_assert(base.common_ref(), "Argument must be in a common.");
00792 p_assert(!((VariableSymbol&)base).is_gsa_symbol(),
00793 "Argument must NOT be a GSA symbol.");
00794 for (Statement* ps=callsite.next_ref(); ps; ps=ps->next_ref()){
00795 if (ps->stmt_class()!=ASSIGNMENT_STMT) {
00796 break;
00797 }
00798 if (ps->rhs().op()!=THETA_OP){
00799 break;
00800 }
00801
00802 Expression& id=ps->rhs().parameters_guarded().arg_list()[0];
00803 if (id.op()!=ARRAY_REF_OP && id.op()!=ID_OP){
00804 continue;
00805 }
00806 VariableSymbol& sym=(VariableSymbol&)id.symbol();
00807 Symbol* base_sym=&sym;
00808 if (sym.is_gsa_symbol()){
00809 base_sym=&sym.gsa_base_symbol();
00810 }
00811 if (base_sym==&base){
00812 return &sym;
00813 }
00814 }
00815
00816 return 0;
00817 }
00818
00819 static Symbol* use_call_gsa_name(ProgramUnit& pgm,
00820 Statement& callsite,
00821 Symbol& base){
00822 Database<Statement*, RefDatabase<Symbol*, Symbol> >* pgmap=
00823 _gmap.find_ref(&pgm);
00824 p_assert(pgmap, "Cannot find gmap for program unit.");
00825 RefDatabase<Symbol*, Symbol>* spgmap=pgmap->find_ref(&callsite);
00826 p_assert(spgmap, "Cannot find gmap for statement.");
00827 return spgmap->find_ref(&base);
00828 }
00829
00830
00831
00832
00833
00834
00835 void build_def_map(Program& prog, EntryPoints& ep,
00836 ProgramUnit& pgm){
00837 static set<ProgramUnit*> processed;
00838 if (processed.find(&pgm)!=processed.end()){
00839 return;
00840 } else {
00841 processed.insert(&pgm);
00842 }
00843
00844 for (Iterator<Statement> stit=pgm.stmts().iterator();
00845 stit.valid(); ++stit){
00846 Statement& stmt=stit.current();
00847 ProgramUnit* pcallee=called_pgm(stmt);
00848 if (pcallee) {
00849
00850
00851
00852
00853 ProgramUnit& callee=*pcallee;
00854 Statement& call_site=stmt;
00855
00856 Database<Symbol*, List<GlobalDefSite> >* pdmap=_dmap.find_ref(&callee);
00857 if (!pdmap){
00858 pdmap=new Database<Symbol*, List<GlobalDefSite> >;
00859
00860 _dmap.ins(&callee, pdmap);
00861 }
00862
00863 for(DictionaryIter<Symbol> sit=pgm.symtab().iterator();
00864 sit.valid(); ++sit){
00865 Symbol& sym=sit.current();
00866 if (sym.common_ref()){
00867 if (!((VariableSymbol&)sym).is_gsa_symbol()){
00868 Symbol* base=&sym;
00869
00870
00871 Symbol* corresponding_sym=
00872 callee.symtab().find_ref(base->name_ref());
00873 if (corresponding_sym==0){
00874 prog.write(cerr);
00875 cerr<<"\nIn pgm. "<<callee.routine_name_ref();
00876 cerr<<"\nIn common "<<base->common_ref()->name_ref();
00877 cerr<<"\nSymbol "<<base->name_ref();
00878 p_abort("Could not find corresponding symbol in symbol table.");
00879 }
00880 List<GlobalDefSite>* sdmap=pdmap->find_ref(corresponding_sym);
00881 if (!sdmap){
00882 sdmap=new List<GlobalDefSite>;
00883 pdmap->ins(corresponding_sym, sdmap);
00884 }
00885
00886
00887 Symbol* usedname=use_call_gsa_name(pgm, call_site, *base);
00888 p_assert(usedname, "Could not figure out name used at call site.");
00889
00890
00891 DefLoc* defloc=pgm.gsa_deflocs_guarded().find_ref(*usedname);
00892 bool found_def=true;
00893 if (!defloc) {
00894 found_def=false;
00895 } else {
00896 if (!defloc->stmt_valid()) {
00897 found_def=false;
00898 }
00899 }
00900 if (found_def){
00901 sdmap->ins_last(new GlobalDefSite(pgm, defloc->stmt_guarded()));
00902 } else {
00903
00904
00905 Database<Symbol*, List<GlobalDefSite> >* own_pdmap=
00906 _dmap.find_ref(&pgm);
00907 if (own_pdmap==0){
00908 cerr<<"\nFor program unit: "<<pgm.routine_name_ref();
00909 p_abort("Nonexisting dmap object for this pgm.");
00910 }
00911 List<GlobalDefSite>* own_sdmap=
00912 own_pdmap->find_ref(base);
00913
00914 if (own_sdmap){
00915 for(Iterator<GlobalDefSite> gdsit=*own_sdmap;
00916 gdsit.valid(); ++gdsit){
00917 sdmap->ins_last(new GlobalDefSite(gdsit.current()));
00918 }
00919 } else {
00920
00921
00922
00923 }
00924 }
00925 }
00926 }
00927 }
00928
00929 build_def_map(prog, ep, callee);
00930 }
00931 }
00932 }
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942 void build_def_map(Program& prog){
00943
00944
00945
00946 EntryPoints* ep=prog.entry_points();
00947 for(KeyIterator<String, ProgramUnit> kit=prog; kit.valid(); ++kit){
00948 ProgramUnit& pgm=kit.current_data();
00949 if (pgm.pu_class()==PROGRAM_PU_TYPE){
00950
00951 Database<Symbol*, List<GlobalDefSite> >* pdmap=
00952 new Database<Symbol*, List<GlobalDefSite> >;
00953 _dmap.ins(&pgm, pdmap);
00954 for (DictionaryIter<Symbol> sit=pgm.symtab().iterator();
00955 sit.valid(); ++sit){
00956 if (sit.current().common_ref()){
00957 if (sit.current().is_array()){
00958 continue;
00959 }
00960 pdmap->ins(&sit.current(), new List<GlobalDefSite>);
00961 build_def_map(prog, *ep, pgm);
00962 }
00963 }
00964 }
00965 }
00966 delete ep;
00967
00968
00969
00970 }
00971
00972
00973
00974
00975
00976 static bool already_ip_ssa(Program& prog){
00977 ProgramUnit* main_pgm=find_main_pgm(prog);
00978 p_assert(main_pgm, "Could not find main pgm.");
00979 KeyIterator<String,ProgramUnit> myprogiter = prog;
00980 for(myprogiter.reset();myprogiter.valid();++myprogiter){
00981 ProgramUnit& pgm=myprogiter.current_data();
00982 for(DictionaryIter<Symbol> sit=pgm.symtab().iterator();
00983 sit.valid();++sit){
00984 String name=sit.current().name_ref();
00985 if (name.index("@")!=-1){
00986 return true;
00987 }
00988 }
00989 }
00990 return false;
00991 }
00992
00993 void make_ip_ssa(Program& prog){
00994
00995 if (already_ip_ssa(prog)){
00996 return;
00997 }
00998
00999
01000 generate_maymods(prog, true, false);
01001
01002
01003 add_dummy_global_assignments_at_calls(prog);
01004
01005
01006 add_dummy_eta_assignments_after_loops(prog);
01007
01008
01009 KeyIterator<String,ProgramUnit> progiter = prog;
01010 for (progiter.reset();
01011 progiter.valid();
01012 ++progiter) {
01013 ProgramUnit& pgm=progiter.current_data();
01014 if (!is_code_pu(pgm)) continue;
01015 MakeGSA(pgm);
01016 }
01017
01018
01019 modify_dummy_eta_assignments_after_loops(prog);
01020
01021 for (progiter.reset();
01022 progiter.valid();
01023 ++progiter) {
01024 ProgramUnit& pgm=progiter.current_data();
01025 if (!is_code_pu(pgm)) continue;
01026 optimize_ssa(pgm,
01027 SSA_OPT_BETA | SSA_OPT_MU |
01028 SSA_OPT_GAMMA | SSA_OPT_ETA | SSA_OPT_ZERO );
01029 }
01030
01031
01032 build_def_map(prog);
01033
01034
01035 build_in_out_sets(prog);
01036 }
01037
01038
01039 void undo_ip_ssa(Program& prog){
01040 if (!already_ip_ssa(prog)){
01041 return;
01042 }
01043
01044 KeyIterator<String,ProgramUnit> progiter = prog;
01045 for (progiter.reset();
01046 progiter.valid();
01047 ++progiter) {
01048 ProgramUnit& pgm=progiter.current_data();
01049 if (!is_code_pu(pgm)) continue;
01050 DeGSA(pgm);
01051
01052 }
01053 remove_dummy_assignments(prog);
01054 _dmap.clear();
01055 _gmap.clear();
01056 }