00001
00002
00003
00004
00005
00006
00007
00008 #include "Traverser.h"
00009 #include <set>
00010 #include <map>
00011 #include <queue>
00012 #include <algorithm>
00013
00014 #include "Symbol/FunctionSymbol.h"
00015 #include "Expression/ArrayRefExpr.h"
00016 #include "Expression/FunctionCallExpr.h"
00017 #include "Range/AIRangeDict.h"
00018 #include "utilities/lambda_util.h"
00019 #include "utilities/stmt_util.h"
00020
00021 #include "prog_info.h"
00022 #include "trans_util.h"
00023 #include "optimize_ssa.h"
00024
00025
00026
00027 Translator::Translator(ProgramUnit& caller, Statement& callsite){
00028 _caller=&caller;
00029 _callsite=&callsite;
00030 _callee=called_pgm(callsite);
00031 p_assert(_callee,
00032 "Cannot build translator for statements that are not call sites.");
00033 }
00034
00035 Translator::~Translator(){
00036 }
00037
00038 Expression* Translator::translate(Symbol& sym){
00039 if (sym.sym_class()==VARIABLE_CLASS) {
00040 return translate_var((VariableSymbol&)sym,
00041 *_callee, *_caller, *_callsite);
00042 } else {
00043 p_abort("Cannot translate symbols that are not variables.");
00044 return 0;
00045 }
00046 }
00047
00048 Expression* Translator::actual(Symbol& sym){
00049 if (sym.sym_class()!=VARIABLE_CLASS){
00050 cerr<<"\n sym: "<<sym.name_ref()
00051 <<" in routine "<<_callee->routine_name_ref();
00052 p_warning("Non-variable symbol cannot be formal.");
00053 return 0;
00054 }
00055 String sbase;
00056 int rank;
00057 gsa_details(sym.name_ref(), sbase, rank);
00058
00059 if (rank!=0) {
00060 cerr<<"\n sym: "<<sym.name_ref()
00061 <<" in routine "<<_callee->routine_name_ref();
00062 p_warning("Can not translate non-entry value.");
00063 return 0;
00064 }
00065 VariableSymbol* base=(VariableSymbol*)&sym;
00066 if (base->is_gsa_symbol()){
00067 base=(VariableSymbol*)&base->gsa_base_symbol();
00068 }
00069 if (sym.formal()){
00070 Statement* entry=_callee->stmts().first_ref();
00071 while (entry->stmt_class()!=ENTRY_STMT) {
00072 entry=entry->next_ref();
00073 p_assert(entry, "Could not find entry to program unit.");
00074 }
00075
00076 List<Expression>& actuals=parameters(*_callsite);
00077 List<Expression>& formals=parameters(*entry);
00078
00079 Iterator<Expression> ait=actuals;
00080 Iterator<Expression> fit=formals;
00081 for ( ; ait.valid() && fit.valid(); ++ait, ++fit){
00082 if (&fit.current().symbol()==base){
00083 if (is_beta(ait.current())){
00084 return ait.current().parameters_guarded().arg_list().last_ref();
00085 } else {
00086 return &ait.current();
00087 }
00088 }
00089 }
00090 } else {
00091
00092
00093
00094 return 0;
00095 }
00096 return 0;
00097 }
00098
00099
00100
00101
00102
00103 void display_translation_error(VariableSymbol& sym,
00104 ProgramUnit& from,
00105 ProgramUnit& to,
00106 Statement& callsite){
00107 cerr<<"\nVariable "<<&sym<<":"<<sym.name_ref()
00108 <<" upon entry to program unit "<<from.routine_name_ref()
00109 <<" when called from program unit "<<to.routine_name_ref()
00110 <<" at the callsite at line "<<callsite.line();
00111 static int dummy=1;
00112 callsite.write(cerr,dummy);
00113 }
00114
00115 void display_translation_error(Expression& e,
00116 ProgramUnit& from,
00117 ProgramUnit& to,
00118 Statement& callsite){
00119 cerr<<"Variable "<<e
00120 <<" upon entry to program unit "<<from.routine_name_ref()
00121 <<" when called from program unit "<<to.routine_name_ref()
00122 <<" at the callsite at line "<<callsite.line();
00123 int dummy=1;
00124 callsite.write(cerr,dummy);
00125 }
00126
00127
00128 ProgramUnit* called_pgm(Statement& stmt){
00129 const char* callee_tag=0;
00130 if (stmt.stmt_class()==CALL_STMT){
00131 callee_tag=stmt.routine_guarded().symbol().tag_ref();
00132 } else {
00133 if (stmt.stmt_class()==ASSIGNMENT_STMT){
00134 if (stmt.rhs().op()==FUNCTION_CALL_OP) {
00135 callee_tag=stmt.rhs().function().symbol().tag_ref();
00136 }
00137 }
00138 }
00139 if (!callee_tag) return 0;
00140 return entry_points().find_ref(callee_tag);
00141 }
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 VariableSymbol* translate_common_var(VariableSymbol& sym,
00155 ProgramUnit& from,
00156 ProgramUnit& to,
00157 Statement& callsite){
00158 if (!sym.common_ref()) return 0;
00159 Database<ProgramUnit*, Database<Statement*, RefDatabase<Symbol*, Symbol> > >*
00160 gmap=&ip_ssa_gmap();
00161 Database<Statement*, RefDatabase<Symbol*, Symbol> >* lmap=
00162 gmap->find_ref(&to);
00163 if (!lmap){
00164 display_translation_error(sym, from, to, callsite);
00165 p_abort("gmap not set.");
00166 }
00167 RefDatabase<Symbol*, Symbol>* smap=lmap->find_ref(&callsite);
00168 if (!smap){
00169 display_translation_error(sym, from, to, callsite);
00170 p_abort("gmap not set.");
00171 }
00172
00173 VariableSymbol* base=&sym;
00174 if (base->is_gsa_symbol()) base=(VariableSymbol*)&base->gsa_base_symbol();
00175 Symbol* trans=to.symtab().find_ref(base->name_ref());
00176 if (trans==0){
00177 display_translation_error(sym, from, to, callsite);
00178 p_abort("Commons must be unified before attempting translations.");
00179 }
00180 VariableSymbol* toret=(VariableSymbol*)smap->find_ref(trans);
00181 if (toret==0){
00182 display_translation_error(sym, from, to, callsite);
00183 p_abort("Could not translate common name properly.");
00184 }
00185 return toret;
00186 }
00187
00188
00189
00190 static Expression* reshape_array(Expression& formal,
00191 VariableSymbol& actual_array_sym,
00192 Translator& translator,
00193 ProgramUnit& from,
00194 ProgramUnit& to,
00195 Statement& callsite){
00196
00197 if (formal.op()!=ARRAY_REF_OP) {
00198 p_abort("Wrong argument to reshape_array");
00199 }
00200
00201 VariableSymbol *formal_symbol=(VariableSymbol *) formal.base_variable_ref();
00202 Expression& subscript_formal=formal.subscript();
00203 Expression* subscript_actual=constant(0);
00204 Expression* stride=constant(1);
00205 for (int i=0; i<formal_symbol->dim().entries(); i++) {
00206
00207 Expression* this_dim=
00208 translate_and_reshape(translator, from, to, callsite,
00209 subscript_formal.arg_list()[i].clone());
00210 this_dim=mul(stride->clone(), this_dim);
00211 ;
00212 subscript_actual=simplify(add(subscript_actual, this_dim));
00213
00214
00215 if (i==formal_symbol->dim().entries()-1) {
00216 break;
00217 }
00218
00219
00220 ArrayBounds & formal_bounds = formal_symbol->dim()[i];
00221 Expression * lower;
00222 Expression * upper;
00223 if (!(formal_bounds.lower_exists())) {
00224 lower = constant(1);
00225 } else {
00226 lower = translate_and_reshape(translator, from, to, callsite,
00227 formal_bounds.lower_guarded().clone());
00228 }
00229 if (!formal_bounds.upper_exists()) {
00230 p_abort("Cannot reshape array because dimensions are not given.");
00231 }
00232 upper=translate_and_reshape(translator, from, to, callsite,
00233 formal_bounds.upper_guarded().clone());
00234 Expression* diff=add(sub(upper, lower), constant(1));
00235 stride=simplify(mul(stride, diff));
00236 }
00237 delete stride;
00238 List<Expression>* new_sub=new List<Expression>;
00239 new_sub->ins_first(subscript_actual);
00240 VariableSymbol& actual_symbol=actual_array_sym;
00241 for (int i=1; i<actual_symbol.dim().entries(); i++) {
00242 new_sub->ins_last(constant(1));
00243 }
00244 CommaExpr* new_subscript=new CommaExpr(new_sub);
00245 return new ArrayRefExpr(formal.array().symbol().type(),
00246 id(actual_array_sym),
00247 new_subscript);
00248 }
00249
00250
00251
00252 bool is_actual_integer_constant(VariableSymbol& sym,
00253 Translator& translator){
00254 Expression* new_const=0;
00255 VariableSymbol* base=0;
00256 if (sym.is_gsa_symbol()){
00257 base=(VariableSymbol*)&sym.gsa_base_symbol();
00258 } else {
00259 base=&sym;
00260 }
00261 new_const=translator.actual(*base);
00262 if (new_const) {
00263 if (new_const->op()==INTEGER_CONSTANT_OP){
00264 return true;
00265 }
00266 }
00267 return false;
00268 }
00269
00270 Symbol* symbol(Expression* e){
00271 if (!e) return 0;
00272 if (e->op()==ID_OP) return &e->symbol();
00273 if (e->op()==ARRAY_REF_OP) return &e->array().symbol();
00274 return 0;
00275 }
00276
00277
00278 RefList<Symbol> untranslate_var(Symbol& sym,
00279 ProgramUnit& callee,
00280 ProgramUnit& caller,
00281 Statement& callsite){
00282 RefList<Symbol> toret;
00283 switch (sym.sym_class()){
00284 case UNDEFINED_CLASS:
00285 p_abort("Cannot translate symbol of undefined type.");
00286 case PROGRAM_CLASS:
00287 p_abort("Cannot have more than one main subprogram in a program.");
00288 case BLOCK_DATA_CLASS:
00289 p_abort("Cannot have more than one block data subprogram in a program.");
00290 case FUNCTION_CLASS:
00291 case SUBROUTINE_CLASS:
00292 case SYMBOLIC_CONSTANT_CLASS:
00293 {
00294 Symbol* found=callee.symtab().find_ref(sym.name_ref());
00295 if (found){
00296
00297 toret.ins_last(*found);
00298 return toret;
00299 } else {
00300 Symbol* callee_sym=sym.clone();
00301 callee.symtab().rename_and_ins(callee_sym);
00302 }
00303 }
00304 case VARIABLE_CLASS:
00305 break;
00306 case NAMELIST_CLASS:
00307 default:
00308 p_abort("Unhandled case in untranslate_var.");
00309 }
00310
00311
00312 if (callsite.stmt_class()==ASSIGNMENT_STMT){
00313 if (callsite.lhs().base_variable_ref()==&sym){
00314 Symbol* fret=callee.symtab().find_ref(callee.routine_name_ref());
00315 p_assert(fret, "Function did not declare return value.");
00316 toret.ins_last(*fret);
00317 return toret;
00318 }
00319 }
00320
00321 Statement& entry=quick_pgm_entry(callee);
00322 List<Expression>& actuals=parameters(callsite);
00323 List<Expression>& formals=parameters(entry);
00324 Iterator<Expression> ait=actuals;
00325 Iterator<Expression> fit=formals;
00326
00327 for ( ; ait.valid() && fit.valid(); ++ait, ++fit){
00328 Expression& expr=ait.current();
00329 Symbol* actual=0;
00330 if (is_beta(ait.current())){
00331
00332 Expression* last_arg=expr.parameters_guarded().arg_list().last_ref();
00333 if (last_arg->op()==ARRAY_REF_OP){
00334 actual=(VariableSymbol*)&last_arg->array().symbol();
00335 } else {
00336 if (last_arg->op()==ID_OP){
00337 actual=(VariableSymbol*)&last_arg->symbol();
00338 } else {
00339 p_abort("Expression not supported as actual.");
00340 }
00341 }
00342 } else {
00343 actual=symbol(&ait.current());
00344 }
00345
00346 if (actual!=&sym) continue;
00347 Symbol* formal=symbol(&fit.current());
00348 p_assert(formal, "Expression not supported as formal.");
00349 toret.ins_last(*formal);
00350 }
00351
00352
00353 if (sym.common_ref()){
00354 Symbol* trans=callee.symtab().find_ref(sym.name_ref());
00355 p_assert(trans, "Commons not unified.");
00356 p_assert(trans->common_ref(), "Commons not unified.");
00357 if (!toret.member(*trans)){
00358 toret.ins_last(*trans);
00359 }
00360 }
00361
00362 return toret;
00363 }
00364
00365
00366 Expression* translate_var(VariableSymbol& sym,
00367 ProgramUnit& from,
00368 ProgramUnit& to,
00369 Statement& callsite){
00370 if (!sym.formal() && !sym.common_ref() && sym.sym_class()!=FUNCTION_CLASS){
00371
00372
00373 return 0;
00374 }
00375
00376
00377
00378 if (sym.intrinsic()){
00379 Symbol* trans=to.symtab().find_ref(sym.name_ref());
00380 if (!trans) {
00381
00382
00383 trans=&to.symtab().ins(new FunctionSymbol(sym.name_ref(),
00384 sym.type(),
00385 NOT_EXTERNAL,
00386 IS_INTRINSIC,
00387 NOT_FORMAL));
00388 } else {
00389
00390 if (!trans->intrinsic()){
00391 display_translation_error(sym, from, to, callsite);
00392 p_abort("This variable has an intrinsic name.");
00393 }
00394 }
00395
00396 return id(*trans);
00397 }
00398
00399 String sbase;
00400 int rank;
00401 gsa_details(sym.name_ref(), sbase, rank);
00402
00403 if (rank!=0) {
00404 display_translation_error(sym, from, to, callsite);
00405 p_warning("Can not translate non-entry value.");
00406 return 0;
00407 }
00408 VariableSymbol* base=0;
00409 if (sym.is_gsa_symbol()){
00410 base=(VariableSymbol*)&sym.gsa_base_symbol();
00411 } else {
00412 base=&sym;
00413 }
00414
00415
00416 if (sym.formal()){
00417
00418 Statement* entry=from.stmts().first_ref();
00419 while (entry->stmt_class()!=ENTRY_STMT) {
00420 entry=entry->next_ref();
00421 if(entry==0) break;
00422 }
00423 p_assert(entry, "Could not find program unit entry.");
00424
00425 List<Expression>& actuals=parameters(callsite);
00426 List<Expression>& formals=parameters(*entry);
00427
00428 Iterator<Expression> ait=actuals;
00429 Iterator<Expression> fit=formals;
00430 for ( ; ait.valid() && fit.valid(); ++ait, ++fit){
00431 KeyIterator<String,ProgramUnit> progiter = program();
00432 if (&fit.current().symbol()==base){
00433 Expression* a=0;
00434 if (is_beta(ait.current())){
00435 a=ait.current().parameters_guarded().arg_list().first_ref();
00436 } else {
00437 a=ait.current().clone();
00438 }
00439 if (a->op()==ALPHA_OP){
00440 return a->parameters_guarded().arg_list()[0].clone();
00441 } else {
00442 return a->clone();
00443 }
00444 }
00445 }
00446 display_translation_error(sym, from, to, callsite);
00447 p_abort("Formal could not be matched to an actual.");
00448 }
00449
00450 if (sym.common_ref()){
00451
00452 VariableSymbol* ct=translate_common_var(sym, from, to, callsite);
00453 if (ct) {
00454 return id(*ct);
00455 } else {
00456 p_abort("Failed to translate common ref.");
00457 }
00458 }
00459
00460 display_translation_error(sym, from, to, callsite);
00461 p_abort("Translation failed: cause unknown.");
00462 return 0;
00463 }
00464
00465
00466
00467
00468 Expression* array_element_count(Symbol& sym){
00469 Expression* stride=constant(1);
00470 for (Iterator<ArrayBounds> abit=sym.dim(); abit.valid(); ++abit){
00471
00472 ArrayBounds& ab=abit.current();
00473 Expression* diff=0;
00474 if (ab.lower_exists()){
00475 if (ab.upper_exists()){
00476 diff=add(constant(1),
00477 sub(ab.upper_guarded().clone(),
00478 ab.lower_guarded().clone()));
00479 } else {
00480 diff=ab.lower_guarded().clone();
00481 }
00482 } else {
00483 if (ab.upper_exists()){
00484 diff=ab.upper_guarded().clone();
00485 } else {
00486 p_abort("Cannot understand array declaration.");
00487 }
00488 }
00489 if (diff==0){
00490 p_abort("'array_element_count' called on assumed size array.");
00491 }
00492 stride=simplify(mul(stride, diff));
00493 }
00494 return stride;
00495 }
00496
00497
00498
00499
00500
00501 Expression* base_offset(Expression* expr){
00502 if (!expr) return 0;
00503 if (expr->op()!=ARRAY_REF_OP) return 0;
00504 VariableSymbol * newsym = (VariableSymbol *) &expr->array().symbol();
00505 Expression* start_offset=constant(0);
00506 int dims=newsym->dim().entries();
00507 int dim=0;
00508 Expression* stride=constant(1);
00509 Iterator<Expression> actit=expr->subscript().arg_list();
00510 for (Iterator<ArrayBounds> abit=newsym->dim();
00511 abit.valid() && dim<dims;
00512 ++abit, ++actit, ++dim){
00513
00514 start_offset=add(start_offset,
00515 mul(sub(actit.current().clone(), constant(1)),
00516 stride->clone()));
00517 if (dim==dims-1) {
00518 delete stride;
00519 break;
00520 }
00521
00522 ArrayBounds& ab=abit.current();
00523 Expression* diff=0;
00524 if (ab.lower_exists()){
00525 if (ab.upper_exists()){
00526 diff=add(constant(1),
00527 sub(ab.upper_guarded().clone(),
00528 ab.lower_guarded().clone()));
00529 } else {
00530 diff=ab.lower_guarded().clone();
00531 }
00532 } else {
00533 if (ab.upper_exists()){
00534 diff=ab.upper_guarded().clone();
00535 } else {
00536 p_abort("Cannot understand array declaration.");
00537 }
00538 }
00539 stride=simplify(mul(stride, diff));
00540 }
00541 start_offset=simplify(start_offset);
00542 return start_offset;
00543 }
00544
00545 Expression* trans_update_expr(Translator& translator, Expression* expr){
00546 if (is_leaf(*expr)) {
00547 Symbol * oldsym = expr->base_variable_ref();
00548 if (oldsym == 0) {
00549 return expr;
00550 } else {
00551 return translator.translate(*oldsym);
00552 }
00553 } else {
00554 Traverser tr(*expr, is_leaf);
00555 for ( ; tr.valid(); ++tr) {
00556 if (tr.current().op() != ID_OP) continue;
00557 Assign<Expression> eas = tr.assign();
00558 Expression * epull = tr.pull();
00559 static LambdaInfo lambda(0, 0, INLINE_CALL);
00560
00561 while (1) {
00562
00563 Expression* changed = trans_update_expr(translator, epull);
00564
00565 if (changed!=epull) {
00566
00567
00568 epull = remove_lambda_calls(changed, lambda);
00569 } else {
00570 break;
00571 }
00572 }
00573 eas = epull;
00574 }
00575 return expr;
00576 }
00577 }
00578
00579 Expression* translate_and_reshape( Translator& translator,
00580 ProgramUnit& from,
00581 ProgramUnit& to,
00582 Statement& callsite,
00583 Expression* expr){
00584 if (!expr) return 0;
00585 if (is_leaf(*expr)){
00586 Expression* new_leaf=0;
00587 if (expr->op()==ID_OP){
00588
00589 if (expr->symbol().intrinsic()){
00590 Symbol* tosym=to.symtab().find_ref(expr->symbol().name_ref());
00591 if(tosym==0){
00592 tosym=&to.symtab().ins_intrinsic(expr->symbol().name_ref());
00593 }
00594 return id(*tosym);
00595 }
00596 VariableSymbol& vs=(VariableSymbol&)expr->symbol();
00597
00598
00599
00600 VariableSymbol* base=(VariableSymbol*)gsa_base(vs);
00601 if (base!=&vs){
00602 cerr<<"\n in routine "<<from.routine_name_ref();
00603 cerr<<"\n expr."<<*expr;
00604 p_abort("Could not translate name in translate_and_reshape.");
00605 }
00606 const Expression* new_const=0;
00607 VariableSymbol* tovar=0;
00608 new_const=translator.actual(*base);
00609 if (!new_const) {
00610
00611 tovar=translate_common_var(*base, from, to, callsite);
00612 if (!tovar){
00613 p_abort("Could not translate name in translate_and_reshape.");
00614 return 0;
00615 } else {
00616 new_leaf=id(*tovar);
00617 }
00618 } else {
00619 new_leaf=new_const->clone();
00620 }
00621 } else {
00622
00623 new_leaf=trans_update_expr(translator, expr);
00624 }
00625 return new_leaf;
00626 }
00627 if (expr->op() == ARRAY_REF_OP) {
00628 Expression& array=expr->array();
00629
00630
00631
00632 VariableSymbol& vs=(VariableSymbol&)array.symbol();
00633 VariableSymbol* base=(VariableSymbol*)gsa_base(vs);
00634 if (base!=&array.symbol()){
00635 cerr<<"\n in routine "<<from.routine_name_ref();
00636 cerr<<"\n expr."<<*expr;
00637 p_abort("Could not translate name in translate_and_reshape.");
00638 }
00639
00640 Expression* new_array=0;
00641 const Expression* new_array_const=0;
00642 new_array_const=translator.actual(*base);
00643 if (!new_array_const) {
00644
00645 VariableSymbol* tovar=translate_common_var(*base, from, to, callsite);
00646 if (!tovar){
00647 p_abort("Could not translate name in translate_and_reshape.");
00648 return 0;
00649 }
00650 new_array=id(*tovar);
00651 } else {
00652 new_array=new_array_const->clone();
00653 }
00654 Expression* new_expr=0;
00655 if (new_array->op()==ARRAY_REF_OP){
00656 new_expr=reshape_array(*expr,
00657 (VariableSymbol&)new_array->array().symbol(),
00658 translator, from, to, callsite);
00659
00660 Expression* start_offset=base_offset(new_array);
00661 Mutator<Expression> mut=new_expr->subscript().arg_list();
00662 Assign<Expression> a = mut.assign();
00663 a=simplify(add(start_offset, mut.pull()));
00664 } else {
00665 if (new_array->op()==ID_OP){
00666 new_expr=reshape_array(*expr,
00667 (VariableSymbol&)new_array->symbol(),
00668 translator, from, to, callsite);
00669 } else {
00670 p_abort("Could not translate array in translate_and_reshape.");
00671 }
00672 }
00673 return new_expr;
00674 } else {
00675 Mutator<Expression> expit = expr->arg_list();
00676 for ( ; expit.valid(); ++expit) {
00677 Assign<Expression> a = expit.assign();
00678 a=translate_and_reshape(translator, from, to, callsite, expit.pull());
00679 }
00680 }
00681 return expr;
00682 }
00683
00684
00685 static bool same_base_name(VariableSymbol& sym1, VariableSymbol& sym2){
00686 Symbol* s1=&sym1;
00687 Symbol* s2=&sym2;
00688 if (sym1.is_gsa_symbol()){
00689 s1=&sym1.gsa_base_symbol();
00690 }
00691 if (sym2.is_gsa_symbol()){
00692 s2=&sym2.gsa_base_symbol();
00693 }
00694 if (s1==s2) {
00695 return true;
00696 }
00697 return false;
00698 }
00699
00700 Symbol* syms_in_expr(RefSet<Symbol>& syms, Expression& expr){
00701 if (expr.op() == ID_OP) {
00702 Iterator<Symbol> sit=syms;
00703 for (sit.reset(); sit.valid(); ++sit){
00704 Symbol& sym=sit.current();
00705 if (same_base_name((VariableSymbol&)expr.symbol(),
00706 (VariableSymbol&)sym)) {
00707 return &sym;
00708 }
00709 }
00710 } else {
00711 Iterator<Expression> expit = expr.arg_list();
00712 for ( ; expit.valid(); ++expit) {
00713 Symbol* variant=syms_in_expr(syms, expit.current());
00714 if (variant) return variant;
00715 }
00716 }
00717 return (Symbol*)0;
00718 }
00719
00720 void referred_symbols(const Expression& expr,
00721 RefList<Symbol>& syms){
00722 if (expr.op() == ID_OP) {
00723 if (expr.symbol().name_ref()!=String("<BETA>")) {
00724 if (expr.symbol().name_ref()!=String("INF")){
00725 if (!syms.member(expr.symbol())){
00726 syms.ins_last(expr.symbol());
00727 }
00728 }
00729 }
00730 } else {
00731 Iterator<Expression> expit = expr.arg_list();
00732 for ( ; expit.valid(); ++expit) {
00733 referred_symbols(expit.current(), syms);
00734 }
00735 }
00736 }
00737
00738 void referred_symbols(const List<AbstractAccess>& lmads,
00739 RefList<Symbol>& syms){
00740 for (Iterator<AbstractAccess> aait=lmads; aait.valid(); ++aait){
00741 AbstractAccess& aa=aait.current();
00742 if ( aa.start_exists() ){
00743 referred_symbols(aa.start_guarded(), syms);
00744 }
00745 Iterator<AccessDimension> adit=aa.iter_dims();
00746 for (adit.reset(); adit.valid(); ++adit){
00747 AccessDimension& ad=adit.current();
00748 if (ad.stride_exists()){
00749 referred_symbols(ad.stride_guarded(), syms);
00750 }
00751 if (ad.span_exists()){
00752 referred_symbols(ad.span_guarded(), syms);
00753 }
00754 }
00755 }
00756 }
00757
00758 void referred_symbols(AbstractAccess& aa,
00759 RefList<Symbol>& syms){
00760 if ( aa.start_exists() ){
00761 referred_symbols(aa.start_guarded(), syms);
00762 }
00763 Iterator<AccessDimension> adit=aa.iter_dims();
00764 for (adit.reset(); adit.valid(); ++adit){
00765 AccessDimension& ad=adit.current();
00766 if (ad.stride_exists()){
00767 referred_symbols(ad.stride_guarded(), syms);
00768 }
00769 if (ad.span_exists()){
00770 referred_symbols(ad.span_guarded(), syms);
00771 }
00772 }
00773 }
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785 bool can_translate(const RefList<Symbol>& given,
00786 RefList<Symbol>& can, RefList<Symbol>& cannot,
00787 Translator& translator,
00788 ProgramUnit& callee, ProgramUnit& caller,
00789 Statement& callsite,
00790 int return_asap){
00791 for (Iterator<Symbol> sit=given; sit.valid(); ++sit){
00792
00793
00794 String name;
00795 int rank;
00796 gsa_details(sit.current().name_ref(), name, rank);
00797 if (rank!=0){
00798 cannot.ins_last(sit.current());
00799 if (return_asap) return false;
00800 }
00801
00802
00803
00804
00805
00806 if (sit.current().intrinsic()){
00807 can.ins_last(sit.current());
00808 continue;
00809 }
00810
00811
00812 bool actual_is_const=
00813 is_actual_integer_constant((VariableSymbol&)sit.current(), translator);
00814 if (actual_is_const){
00815 can.ins_last(sit.current());
00816 continue;
00817 }
00818
00819
00820 String sname=sit.current().name_ref();
00821 if (sname.index_case("DUMMY_J")!=-1){
00822 cannot.ins_last(sit.current());
00823 if (return_asap) {
00824 return false;
00825 } else {
00826 continue;
00827 }
00828 }
00829
00830
00831 Expression* t=translate_var((VariableSymbol&)sit.current(),
00832 callee, caller, callsite);
00833 if (t){
00834 delete t;
00835 can.ins_last(sit.current());
00836 } else {
00837
00838 display_translation_error((VariableSymbol&)sit.current(),
00839 callee, caller, callsite);
00840 p_warning("Uninitialized variable may define memory access.");
00841 cannot.ins_last(sit.current());
00842 if (return_asap) return false;
00843 }
00844 }
00845 if (cannot.entries()==0) {
00846 return true;
00847 } else {
00848 return false;
00849 }
00850 }
00851
00852
00853
00854
00855
00856
00857 List<Expression>& parameters(Statement& stmt){
00858 if (stmt.stmt_class()==CALL_STMT) return stmt.parameters_guarded().arg_list();
00859 if (stmt.stmt_class()==ASSIGNMENT_STMT)
00860 if (stmt.rhs().op()==FUNCTION_CALL_OP)
00861 return stmt.rhs().parameters_guarded().arg_list();
00862 if (stmt.stmt_class()==ENTRY_STMT) return stmt.parameters_guarded().arg_list();
00863 p_abort("Statement has no parameters.");
00864 }
00865
00866
00867
00868 static map<VariableSymbol*, GlobalDefSite> _explicitly_declared_defs;
00869 void add_new_definition(VariableSymbol& sym,
00870 ProgramUnit& pgm,
00871 Statement& stmt){
00872 _explicitly_declared_defs.insert(make_pair(&sym, GlobalDefSite(pgm, stmt)));
00873 }
00874
00875
00876 void find_defs(VariableSymbol& sym,
00877 ProgramUnit& pgm,
00878 List<GlobalDefSite>& defs){
00879
00880
00881 map<VariableSymbol*, GlobalDefSite>::iterator found_def=
00882 _explicitly_declared_defs.find(&sym);
00883 if (found_def!=_explicitly_declared_defs.end()){
00884 defs.ins_last(new GlobalDefSite((*found_def).second));
00885 return;
00886 }
00887
00888
00889 Database<ProgramUnit*, Database<Symbol*, List<GlobalDefSite> > >* dmap=
00890 &ip_ssa_dmap();
00891
00892
00893 if (sym.is_scalar()
00894 || sym.is_array()){
00895 VariableSymbol* base=&sym;
00896 if (sym.is_gsa_symbol()) {
00897 base=(VariableSymbol*)&sym.gsa_base_symbol();
00898 String sbase;
00899 int rank;
00900 gsa_details(sym.name_ref(), sbase, rank);
00901 if (rank>0) {
00902 DefLoc* defloc=pgm.gsa_deflocs_guarded().find_ref(sym);
00903 if (!defloc) {
00904 p_abort("Unknown definition site for GSA symbol.");
00905 }
00906 if (!defloc->stmt_valid()) {
00907 p_abort("Invalid definition site for GSA symbol.");
00908 }
00909 defs.ins_last(new GlobalDefSite(pgm, defloc->stmt_guarded()));
00910 return;
00911 }
00912 }
00913
00914
00915 if (base->common_ref()){
00916 Database<Symbol*, List<GlobalDefSite> >* lmap=dmap->find_ref(&pgm);
00917 if (!lmap) {
00918 cerr<<"\nUndefined global variable "<<sym.name_ref()
00919 <<" in pgm "<<pgm.routine_name_ref();
00920 p_warning("");
00921 return;
00922 }
00923 List<GlobalDefSite>* gdsl=lmap->find_ref(base);
00924 if (!gdsl) {
00925 cerr<<"\nUndefined global variable "<<sym.name_ref()
00926 <<" in pgm "<<pgm.routine_name_ref();
00927 p_warning("");
00928 return;
00929 }
00930 defs=*gdsl;
00931 } else {
00932 if (base->formal()){
00933
00934 return;
00935 } else {
00936 if (base->is_array()){
00937
00938
00939
00940 } else {
00941 cerr<<"\nUndefined local variable "<<sym.name_ref()
00942 <<" in pgm "<<pgm.routine_name_ref();
00943 p_abort("");
00944 }
00945 }
00946 }
00947 }
00948 }
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958 AbstractAccess* compute_top(Symbol& sym){
00959 AbstractAccess* toret=0;
00960 if (sym.is_scalar()) {
00961 List<AccessDimension> dims;
00962 toret=new AbstractAccess(sym, dims, constant(0));
00963 } else {
00964 if (sym.is_array()){
00965 List<AccessDimension> dims;
00966 List<Expression>* factors=new List<Expression>;
00967 Iterator<ArrayBounds> abit=sym.dim();
00968 bool found_all_bounds=true;
00969 for ( ; abit.valid(); ++abit){
00970 ArrayBounds& ab=abit.current();
00971 if (ab.lower_exists()){
00972 if (ab.upper_exists()){
00973 Expression* abup=0;
00974 if (ab.upper_guarded().substituted_valid()){
00975 abup=ab.upper_guarded().substituted_guarded().clone();
00976 } else {
00977 abup=ab.upper_guarded().clone();
00978 }
00979 factors->ins_last(simplify(add(constant(1),
00980 sub(abup,
00981 ab.lower_guarded().clone()))));
00982 } else {
00983 factors->ins_last(ab.lower_guarded().clone());
00984 }
00985 } else {
00986 if (ab.upper_exists()){
00987 Expression* abup=0;
00988 if (ab.upper_guarded().substituted_valid()){
00989 abup=ab.upper_guarded().substituted_guarded().clone();
00990 } else {
00991 abup=ab.upper_guarded().clone();
00992 }
00993 factors->ins_last(abup);
00994 } else {
00995 found_all_bounds=false;
00996 break;
00997 }
00998 }
00999 }
01000 if (found_all_bounds){
01001 AccessDimension* ad=new AccessDimension(constant(1),
01002 simplify(sub(mul(factors),
01003 constant(1))));
01004 dims.ins_first(ad);
01005 toret=new AbstractAccess(sym, dims, constant(0), ACCU_EXACT, AR_READ);
01006 } else {
01007 delete factors;
01008 }
01009 }
01010 }
01011 return toret;
01012 }
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023 void
01024 compute_top_range_from_actuals(Program& prog,
01025 ProgramUnit& pgm,
01026 Statement& callsite,
01027 Database<Symbol*, List<Expression> >& arrays){
01028 ProgramUnit* callee=called_pgm(callsite);
01029 if (!callee) return;
01030 List<Expression>& actuals=parameters(callsite);
01031 Iterator<Expression> ait=actuals;
01032
01033 for (ait=actuals; ait.valid(); ++ait){
01034 VariableSymbol* basesym=0;
01035 Expression* index=0;
01036 Expression& expr=ait.current();
01037
01038 if (expr.op()==ARRAY_REF_OP){
01039 basesym=(VariableSymbol*)&expr.array().symbol();
01040 index=base_offset(&expr);
01041 }
01042
01043 if (expr.op()==ID_OP){
01044 if (expr.symbol().is_array()){
01045 basesym=(VariableSymbol*)&expr.symbol();
01046 index=constant(0);
01047 }
01048 }
01049
01050 if (is_beta(expr)){
01051
01052 Expression* last_arg=expr.parameters_guarded().arg_list().last_ref();
01053 if (last_arg->op()==ARRAY_REF_OP){
01054 basesym=(VariableSymbol*)&last_arg->array().symbol();
01055 index=base_offset(last_arg);
01056 }
01057 if (last_arg->op()==ID_OP){
01058 if (last_arg->symbol().is_array()){
01059 basesym=(VariableSymbol*)&last_arg->symbol();
01060 index=constant(0);
01061 }
01062 }
01063 }
01064 if (!basesym){
01065
01066 continue;
01067 }
01068 if (basesym->is_gsa_symbol()) {
01069 basesym=(VariableSymbol*)&basesym->gsa_base_symbol();
01070 }
01071 List<Expression>* this_array=arrays.find_ref(basesym);
01072 if (!this_array){
01073 this_array=new List<Expression>;
01074 arrays.ins(basesym, this_array);
01075 }
01076
01077 if (!pgm.range_dict_valid()){
01078 cerr<<"\nFor program unit: "<<pgm.routine_name_ref();
01079 p_warning("Range Dictionary is missing or invalid.");
01080 pgm.range_dict(new AIRangeDict(pgm));
01081 }
01082 RangeAccessor range_acc(pgm.range_dict_guarded(),
01083 *(range_stmt(callsite)));
01084 int pos=0;
01085 bool found_pos=false;
01086 if (this_array->entries()==0){
01087 this_array->ins_last(index);
01088 } else {
01089 for (Iterator<Expression> expit=*this_array;
01090 expit.valid(); ++expit, ++pos){
01091 Expression* simple=simplify(expit.current().clone());
01092 Relation comp = range_acc.compare(*index, *simple);
01093 if (comp.is_less_than()){
01094 this_array->ins_before(index, &expit.current());
01095 found_pos=true;
01096 break;
01097 }
01098 }
01099 if (!found_pos){
01100 Expression* simple=simplify(this_array->last_ref()->clone());
01101 Relation comp = range_acc.compare(*index,
01102 *simple);
01103 delete simple;
01104 if (comp.is_greater_equal()){
01105 this_array->ins_last(index);
01106 } else {
01107 this_array->ins_last(index);
01108
01109
01110
01111
01112 }
01113 }
01114 }
01115 }
01116 }
01117
01118
01119
01120 static void _build_call_diamond(ProgramUnit& from, ProgramUnit& to,
01121 set<ProgramUnit*>& pgms){
01122
01123 set<ProgramUnit*> upwards;
01124 RefList<ProgramUnit> q;
01125 q.ins_first(from);
01126 while (q.entries()){
01127 ProgramUnit& pgm=q.grab(0);
01128 upwards.insert(&pgm);
01129 RefSet<ProgramUnit>& callers=pgm.called_by();
01130 for(Iterator<ProgramUnit> pit=callers; pit.valid(); ++pit){
01131 if (upwards.find(&pit.current())!=upwards.end()){
01132
01133 continue;
01134 } else {
01135 q.ins_last(pit.current());
01136 }
01137 }
01138 }
01139
01140
01141 set<ProgramUnit*> downward;
01142 q.ins_first(to);
01143 while (q.entries()){
01144 ProgramUnit& pgm=q.grab(0);
01145 downward.insert(&pgm);
01146 RefSet<ProgramUnit>& callees=pgm.calls();
01147 for(Iterator<ProgramUnit> pit=callees; pit.valid(); ++pit){
01148 if (downward.find(&pit.current())!=downward.end()){
01149
01150 continue;
01151 } else {
01152 q.ins_last(pit.current());
01153 }
01154 }
01155 }
01156
01157
01158 set_intersection(upwards.begin(), upwards.end(),
01159 downward.begin(), downward.end(),
01160 inserter(pgms, pgms.begin()));
01161 }
01162
01163
01164 static void
01165 _find_call_sites(ProgramUnit& callee, set<ProgramUnit*>& all_pgms,
01166 vector<pair<ProgramUnit*, Statement*> >&call_sites){
01167 RefSet<ProgramUnit>& callers=callee.called_by();
01168 for(Iterator<ProgramUnit> pit=callers; pit.valid(); ++pit){
01169 ProgramUnit& pgm=pit.current();
01170 if (all_pgms.find(&pgm)==all_pgms.end()){
01171
01172 continue;
01173 }
01174 Iterator<Statement> stit=pgm.stmts().iterator();
01175 for( ; stit.valid(); ++stit){
01176 Statement& stmt=stit.current();
01177 if (called_pgm(stmt)==&callee){
01178 call_sites.push_back(make_pair(&pgm, &stmt));
01179 }
01180 }
01181 }
01182 }
01183
01184
01185
01186
01187
01188
01189
01190
01191 const Symbol* translate_sym(ProgramUnit& from, ProgramUnit& to,
01192 const Symbol& sym){
01193 set<ProgramUnit*> all_pgms;
01194 _build_call_diamond(from, to, all_pgms);
01195 queue<pair<const Symbol*, ProgramUnit*> > q;
01196 q.push(make_pair(&sym, &from));
01197 const Symbol* target=0;
01198 while (q.size()>0){
01199 pair<const Symbol*, ProgramUnit*> current=q.front();
01200 q.pop();
01201 ProgramUnit& pgm=*current.second;
01202 const Symbol* s=current.first;
01203 if (&pgm==&to){
01204
01205 if (target){
01206
01207
01208 if (target!=s){
01209 p_warning("Two translations found for same symbol.");
01210 return 0;
01211 }
01212 } else {
01213 target=s;
01214 }
01215 } else {
01216
01217
01218
01219 vector<pair<ProgramUnit*, Statement*> > call_sites;
01220 _find_call_sites(pgm, all_pgms, call_sites);
01221
01222 vector<pair<ProgramUnit*, Statement*> >::iterator csit;
01223 for (csit=call_sites.begin(); csit!=call_sites.end(); ++csit){
01224 ProgramUnit& current_to=*(*csit).first;
01225 Statement& call_site=*(*csit).second;
01226 ProgramUnit& current_from=pgm;
01227 Expression* t=translate_var((VariableSymbol&)*s,
01228 current_from, current_to, call_site);
01229 p_assert(t, "Cannot translate input value.");
01230 if (t->op()!=ID_OP){
01231 p_warning("Translation of input values - only simple values for now.");
01232
01233 return 0;
01234 }
01235
01236 q.push(make_pair(&t->symbol(), ¤t_to));
01237 }
01238 }
01239 }
01240 p_assert(target, "Could not find a suitable translation.");
01241 return target;
01242 }
01243
01244
01245 ProgramUnit* find_main_pgm(Program& prog){
01246 for(KeyIterator<String, ProgramUnit> pit=prog; pit.valid(); ++pit){
01247 ProgramUnit& pgm=pit.current_data();
01248 if (pgm.pu_class()==PROGRAM_PU_TYPE){
01249 return &pgm;
01250 }
01251 }
01252 return 0;
01253 }
01254
01255
01256 ProgramUnit* find_pgm(Program& prog,const char * routine_name){
01257 for(KeyIterator<String, ProgramUnit> pit=prog; pit.valid(); ++pit){
01258 ProgramUnit& pgm=pit.current_data();
01259 if (strcmp(pgm.routine_name_ref(),routine_name)==0){
01260 return &pgm;
01261 }
01262 }
01263 return 0;
01264 }
01265
01266
01267
01268
01269
01270
01271 static void postorder(ProgramUnit& source,
01272 vector<ProgramUnit*>& ordered,
01273 set<ProgramUnit*>& processed){
01274
01275 if (processed.find(&source)!=processed.end()){
01276 return;
01277 } else {
01278 for (Iterator<ProgramUnit> pit=source.calls(); pit.valid(); ++pit){
01279 ProgramUnit& pgm=pit.current();
01280 postorder(pgm, ordered, processed);
01281 }
01282 processed.insert(&source);
01283 ordered.push_back(&source);
01284 }
01285 }
01286
01287
01288
01289
01290 void topsort_call_dag(Program& prog, vector<ProgramUnit*>& ordered){
01291 prog.compute_call_lists();
01292 set<ProgramUnit*> processed;
01293 ProgramUnit* main=find_main_pgm(prog);
01294 if (!main){
01295 p_abort("IPA Bottom-up could not find main program.");
01296 }
01297 postorder(*main, ordered, processed);
01298 }
01299
01300
01301 Statement* matching_else(Statement* if_stmt){
01302 Statement* stit;
01303 for (stit=if_stmt; stit!=0 && stit !=if_stmt->matching_endif_ref();
01304 stit=stit->next_ref()){
01305 if (stit->stmt_class()==ELSE_STMT){
01306 if (stit->lead_ref()==if_stmt){
01307 return stit;
01308 }
01309 }
01310 }
01311 return 0;
01312 }
01313
01314
01315 void get_in_out(ProgramUnit& caller, Statement& callsite, Symbol& sym,
01316 Symbol*& incoming, Symbol*& outgoing){
01317 incoming=outgoing=0;
01318
01319 for(Iterator<Expression> eit=callsite.act_refs(); eit.valid(); ++eit){
01320 if (eit.current().op()==ID_OP){
01321 if (gsa_base(eit.current().symbol())==&sym){
01322 outgoing=&eit.current().symbol();
01323 }
01324 }
01325 }
01326 if (outgoing){
01327 for(Iterator<Expression> eit=callsite.in_refs(); eit.valid(); ++eit){
01328 if (eit.current().op()==ID_OP){
01329 if (gsa_base(eit.current().symbol())==&sym){
01330 if (&eit.current().symbol()!=outgoing){
01331 incoming=&eit.current().symbol();
01332 }
01333 }
01334 }
01335 }
01336 if (incoming==0){
01337 display_translation_error((VariableSymbol&)sym,
01338 *called_pgm(callsite), caller, callsite);
01339 p_abort("Could not find IN parameter for a given OUT.");
01340 }
01341 } else {
01342 p_assert(sym.common_ref(),
01343 "Symbol is neither passed as parameter nor in a common.");
01344 Statement* ps=callsite.next_ref();
01345 while (ps){
01346 if (ps->stmt_class()!=ASSIGNMENT_STMT){
01347 break;
01348 }
01349 if (ps->rhs().op()!=THETA_OP){
01350 break;
01351 }
01352 if (gsa_base(ps->lhs().symbol())==&sym){
01353 outgoing=&ps->lhs().symbol();
01354 incoming=&ps->rhs().parameters_guarded().arg_list()[0].symbol();
01355 return;
01356 } else {
01357 ps=ps->next_ref();
01358 }
01359 }
01360 }
01361 }
01362
01363 void get_out(ProgramUnit& caller, Statement& callsite, Symbol& sym,
01364 Symbol*& outgoing){
01365 outgoing=0;
01366
01367 for(Iterator<Expression> eit=callsite.act_refs(); eit.valid(); ++eit){
01368 if (eit.current().op()==ID_OP){
01369 if (gsa_base(eit.current().symbol())==&sym){
01370 outgoing=&eit.current().symbol();
01371 }
01372 }
01373 }
01374 if (outgoing==0){
01375 p_assert(sym.common_ref(),
01376 "Symbol is neither passed as parameter nor in a common.");
01377 Statement* ps=callsite.next_ref();
01378 while (ps){
01379 if (ps->stmt_class()!=ASSIGNMENT_STMT){
01380 break;
01381 }
01382 if (ps->rhs().op()!=THETA_OP){
01383 break;
01384 }
01385 if (gsa_base(ps->lhs().symbol())==&sym){
01386 outgoing=&ps->lhs().symbol();
01387 return;
01388 } else {
01389 ps=ps->next_ref();
01390 }
01391 }
01392 }
01393 }
01394
01395
01396 void get_in(ProgramUnit& caller, Statement& callsite, Symbol& sym,
01397 Symbol*& incoming){
01398 ProgramUnit& callee=*called_pgm(callsite);
01399 incoming=0;
01400
01401 for(Iterator<Expression> eit=callsite.act_refs(); eit.valid(); ++eit){
01402 if (eit.current().op()==ID_OP){
01403 if (gsa_base(eit.current().symbol())==&sym){
01404 incoming=&eit.current().symbol();
01405 }
01406 }
01407 }
01408 if (incoming){
01409 for(Iterator<Expression> eit=callsite.in_refs(); eit.valid(); ++eit){
01410 if (eit.current().op()==ID_OP){
01411 if (gsa_base(eit.current().symbol())==&sym){
01412 if (&eit.current().symbol()!=incoming){
01413 incoming=&eit.current().symbol();
01414 break;
01415 }
01416 }
01417 }
01418 }
01419 if (incoming==0){
01420 display_translation_error((VariableSymbol&)sym,
01421 *called_pgm(callsite), caller, callsite);
01422 p_abort("Could not find IN parameter.");
01423 }
01424 } else {
01425 p_assert(sym.common_ref(),
01426 "Symbol is neither passed as parameter nor in a common.");
01427 Statement* ps=callsite.next_ref();
01428 while (ps){
01429 if (ps->stmt_class()!=ASSIGNMENT_STMT){
01430 break;
01431 }
01432 if (ps->rhs().op()!=THETA_OP){
01433 break;
01434 }
01435 if (gsa_base(ps->lhs().symbol())==&sym){
01436 incoming=&ps->rhs().parameters_guarded().arg_list()[0].symbol();
01437 return;
01438 } else {
01439 ps=ps->next_ref();
01440 }
01441 }
01442
01443 incoming=translate_common_var((VariableSymbol&)sym,
01444 callee, caller, callsite);
01445 }
01446 }
01447
01448
01449
01450 Expression* replace_expression(Expression* given,
01451 Expression& first,
01452 Expression& second){
01453 if (first.op()!=ID_OP && first.op()!=ARRAY_REF_OP){
01454 p_abort("First expression must be ID or ARRAY_REF to perform substitution.");
01455 }
01456 if (!given) return 0;
01457 if (given->op()==ID_OP || given->op()==ARRAY_REF_OP){
01458 if (*given==first){
01459 return second.clone();
01460 } else {
01461 return given;
01462 }
01463 }
01464 Mutator<Expression> expit = given->arg_list();
01465 for ( ; expit.valid(); ++expit) {
01466 Assign<Expression> a = expit.assign();
01467 a=replace_expression(expit.pull(), first, second);
01468 }
01469 return given;
01470 }
01471
01472 void replace_expression(AbstractAccess& aa,
01473 Expression& first, Expression& second){
01474 if ( aa.start_exists() ){
01475 Expression* tmp=simplify(aa.start_guarded().clone());
01476 tmp=replace_expression(tmp, first, second);
01477 aa.start(simplify(tmp));
01478 }
01479 Iterator<AccessDimension> adit=aa.iter_dims();
01480 for (adit.reset(); adit.valid(); ++adit){
01481 AccessDimension& ad=adit.current();
01482 if (ad.stride_exists()){
01483 Expression* tmp=simplify(ad.stride_guarded().clone());
01484 tmp=replace_expression(tmp, first, second);
01485 ad.stride(simplify(tmp));
01486 }
01487 if (ad.span_exists()){
01488 Expression* tmp=simplify(ad.span_guarded().clone());
01489 tmp=replace_expression(tmp, first, second);
01490 ad.span(simplify(tmp));
01491 }
01492 }
01493 }
01494
01495 void replace_expression(List<AbstractAccess>& aalist,
01496 Expression& first, Expression& second){
01497 for (Iterator<AbstractAccess> aait=aalist; aait.valid(); ++aait){
01498 AbstractAccess& aa=aait.current();
01499 replace_expression(aa, first, second);
01500 }
01501 }
01502
01503
01504 void replace_symbol(AbstractAccess& aa,
01505 Symbol& first, Symbol& second){
01506 if ( aa.start_exists() ){
01507 substitute_var(aa.start_guarded(), first, second);
01508 }
01509 Iterator<AccessDimension> adit=aa.iter_dims();
01510 for (adit.reset(); adit.valid(); ++adit){
01511 AccessDimension& ad=adit.current();
01512 if (ad.stride_exists()){
01513 substitute_var(ad.span_guarded(), first, second);
01514 }
01515 if (ad.span_exists()){
01516 substitute_var(ad.stride_guarded(), first, second);
01517 }
01518 }
01519 }
01520
01521 void replace_symbol(AbstractAccess& aa,
01522 Symbol& first, Expression& second){
01523 if ( aa.start_exists() ){
01524 Expression* tmp=aa.start_guarded().clone();
01525 aa.start(simplify(substitute_var(tmp, first, second)));
01526 }
01527 Iterator<AccessDimension> adit=aa.iter_dims();
01528 for (adit.reset(); adit.valid(); ++adit){
01529 AccessDimension& ad=adit.current();
01530 if (ad.stride_exists()){
01531 Expression* tmp=ad.stride_guarded().clone();
01532 ad.stride(simplify(substitute_var(tmp, first, second)));
01533 }
01534 if (ad.span_exists()){
01535 Expression* tmp=ad.span_guarded().clone();
01536 ad.span(simplify(substitute_var(tmp, first, second)));
01537 }
01538 }
01539 }
01540
01541
01542 void simplify_expressions(AbstractAccess& aa){
01543 if ( aa.start_exists() ){
01544 Expression* tmp=aa.start_guarded().clone();
01545 aa.start(simplify(tmp));
01546 }
01547 Iterator<AccessDimension> adit=aa.iter_dims();
01548 for (adit.reset(); adit.valid(); ++adit){
01549 AccessDimension& ad=adit.current();
01550 if (ad.stride_exists()){
01551 Expression* tmp=ad.stride_guarded().clone();
01552 ad.stride(simplify(tmp));
01553 }
01554 if (ad.span_exists()){
01555 Expression* tmp=ad.span_guarded().clone();
01556 ad.span(simplify(tmp));
01557 }
01558 }
01559 }
01560
01561 void replace_symbol(List<AbstractAccess>& aalist,
01562 Symbol& first, Expression& second){
01563 for (Iterator<AbstractAccess> aait=aalist; aait.valid(); ++aait){
01564 AbstractAccess& aa=aait.current();
01565 if ( aa.start_exists() ){
01566 Expression* tmp=aa.start_guarded().clone();
01567 aa.start(simplify(substitute_var(tmp, first, second)));
01568 }
01569 Iterator<AccessDimension> adit=aa.iter_dims();
01570 for (adit.reset(); adit.valid(); ++adit){
01571 AccessDimension& ad=adit.current();
01572 if (ad.stride_exists()){
01573 Expression* tmp=ad.stride_guarded().clone();
01574 ad.stride(simplify(substitute_var(tmp, first, second)));
01575 }
01576 if (ad.span_exists()){
01577 Expression* tmp=ad.span_guarded().clone();
01578 ad.span(simplify(substitute_var(tmp, first, second)));
01579 }
01580 }
01581 }
01582 }
01583
01584 void replace_symbol(List<AbstractAccess>& aalist,
01585 Symbol& first, Symbol& second){
01586 if (&first==&second) return;
01587 for (Iterator<AbstractAccess> aait=aalist; aait.valid(); ++aait){
01588 AbstractAccess& aa=aait.current();
01589 replace_symbol(aa, first, second);
01590 }
01591 }
01592
01593
01594
01595 Expression* at_least_one_iteration(ProgramUnit& pgm, DoStmt& loop,
01596 bool use_range_dict){
01597
01598 if (!use_range_dict){
01599 Expression* toret=or(and(gt(loop.step().clone(),
01600 constant(0)),
01601 ge(loop.limit().clone(),
01602 loop.init().clone())),
01603 and(lt(loop.step().clone(),
01604 constant(0)),
01605 lt(loop.limit().clone(),
01606 loop.init().clone())));
01607 return simplify(toret);
01608 }
01609
01610 if (!pgm.range_dict_valid()){
01611 pgm.range_dict(new AIRangeDict(pgm));
01612 }
01613 RangeAccessor ra(pgm.range_dict_guarded(), loop);
01614 Relation r=ra.compare(loop.limit(), loop.init());
01615 if (ra.signz(loop.step())==POS_EXPR){
01616 if (r.is_greater_equal()){
01617 return constant(".TRUE.");
01618 } else {
01619 if (r.is_less_than()){
01620 return constant(".FALSE.");
01621 } else {
01622 return simplify(ge(loop.limit().clone(),
01623 loop.init().clone()));
01624 }
01625 }
01626 } else {
01627 if (ra.signz(loop.step())==NEG_EXPR){
01628 if (r.is_less_equal()){
01629 return constant(".TRUE.");
01630 } else {
01631 if (r.is_greater_than()){
01632 return constant(".FALSE.");
01633 } else {
01634 return simplify(le(loop.limit().clone(),
01635 loop.init().clone()));
01636 }
01637 }
01638 } else {
01639 if (r.is_greater_equal()){
01640 return simplify(gt(loop.step().clone(), constant(0)));
01641 } else {
01642 if (r.is_less_equal()){
01643 return simplify(lt(loop.step().clone(), constant(0)));
01644 } else {
01645 Expression* toret=or(and(gt(loop.step().clone(),
01646 constant(0)),
01647 ge(loop.limit().clone(),
01648 loop.init().clone())),
01649 and(lt(loop.step().clone(),
01650 constant(0)),
01651 lt(loop.limit().clone(),
01652 loop.init().clone())));
01653 return simplify(toret);
01654 }
01655 }
01656 }
01657 }
01658 }
01659
01660
01661
01662
01663 RefSet<Expression> search_expression(Expression& expr,OP_TYPE o)
01664 {
01665 RefSet<Expression> results;
01666
01667 if(expr.op() == ID_OP)
01668 {
01669 if(o==ID_OP)
01670 {
01671 results.ins(expr);
01672 return results;
01673 }
01674 }
01675 else
01676 {
01677 if(expr.op()==o)
01678 results.ins(expr);
01679
01680 for(Iterator<Expression> iter=expr.arg_list();iter.valid();++iter)
01681 {
01682 Expression& sub_expr=iter.current();
01683 if(o!=BETA_OP)
01684 {
01685 if(sub_expr.op()==o)
01686 results.ins(sub_expr);
01687 }
01688 else
01689 if(is_beta(sub_expr))
01690 results.ins(sub_expr);
01691 RefSet<Expression> sub_results;
01692 sub_results=search_expression(sub_expr,o);
01693 results+=sub_results;
01694 }
01695 }
01696
01697 return results;
01698 }
01699
01700
01701
01702 RefSet<Expression> search_expression(Statement& stmt,OP_TYPE o)
01703 {
01704 RefSet<Expression> results;
01705
01706 Iterator<Expression> iter=stmt.iterate_expressions();
01707 for(;iter.valid();++iter)
01708 {
01709 RefSet<Expression> sub_results;
01710 Expression& sub_expr=iter.current();
01711 sub_results=search_expression(sub_expr,o);
01712 results+=sub_results;
01713 }
01714
01715 return results;
01716 }