00001
00002
00003 #include "EvolutionGraph.h"
00004 #include "eg_utils.h"
00005 #include "evolution_graph.h"
00006 #include "affine.h"
00007 #include "BackTrace.h"
00008
00009 #include "ip_ssa/trans_util.h"
00010 #include "ip_ssa/optimize_ssa.h"
00011
00012 #include "guarded_values.h"
00013
00014 EvolutionGraph* _get_eg(ProgramUnit* pgm, Statement* loop);
00015
00016 bool _is_useless(const Evolution<Expression>& ev){
00017 if (ev.min_difference()->op()==INFINITY_OP &&
00018 ev.max_difference()->op()==INFINITY_OP){
00019 if (ev.min_difference()->value()==-1 &&
00020 ev.max_difference()->value()==1){
00021 return true;
00022 }
00023 }
00024 return false;
00025 }
00026
00027 bool _is_useless(const Expression& e){
00028 if (e.op()!=RANGE_OP){
00029 return false;
00030 }
00031 const RangeExpr& ev=(const RangeExpr&)e;
00032 if (ev.lb().op()==INFINITY_OP &&
00033 ev.ub().op()==INFINITY_OP){
00034 if (ev.lb().sign()==-1 &&
00035 ev.ub().sign()==1){
00036 return true;
00037 }
00038 }
00039 return false;
00040 }
00041
00042
00043
00044
00045
00046
00047 Expression* eg_range_from_input(Expression& e,
00048 ProgramUnit& pgm,
00049 Statement* loop){
00050
00051 RefList<Symbol> syms;
00052 referred_symbols(e, syms);
00053 RangeAccessor ra(pgm.range_dict_guarded(), *pgm.stmts().first_ref());
00054 RefSet<Symbol> vars_to_eliminate;
00055 for(Iterator<Symbol> sit=syms; sit.valid(); ++sit){
00056 Expression* r=_get_eg(&pgm, loop)->range_from_input(sit.current());
00057 if (r){
00058 ra.set_range(sit.current(), r);
00059 vars_to_eliminate.ins(sit.current());
00060 }
00061 }
00062
00063 Expression* toret=e.clone();
00064 if (vars_to_eliminate.entries()){
00065 toret=ra.eliminate_vars(toret, &vars_to_eliminate);
00066 }
00067
00068 return toret;
00069 }
00070
00071
00072 bool is_defined(Symbol& sym, Statement& stmt){
00073 if (called_pgm(stmt)){
00074
00075 if (stmt.stmt_class()==ENTRY_STMT){
00076 return false;
00077 }
00078 if (!has_maymod(stmt)){
00079 return true;
00080 }
00081 if (is_var_in_maymod(sym, stmt)){
00082 return true;
00083 }
00084 if (stmt.stmt_class()==ASSIGNMENT_STMT){
00085 if (&sym==gsa_base(*stmt.lhs().base_variable_ref())){
00086 return true;
00087 } else {
00088 return false;
00089 }
00090 } else {
00091 return false;
00092 }
00093 } else {
00094
00095 for(Iterator<Expression> eit=stmt.out_refs(); eit.valid(); ++eit){
00096 if (&sym==gsa_base(*eit.current().base_variable_ref())){
00097 return true;
00098 } else {
00099 return false;
00100 }
00101 }
00102 return false;
00103 }
00104 }
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 bool _find_scalar_sources(ProgramUnit& pgm, Statement* loop,
00115 Expression& expr, List<Expression>& sources){
00116
00117 p_assert(expr.op()==ARRAY_REF_OP, "Not an array.");
00118 if (loop){
00119 p_assert(loop->stmt_class()==DO_STMT, "Not a loop.");
00120 }
00121 Symbol* sym=gsa_base(expr.array().symbol());
00122
00123
00124 if (loop!=0){
00125 for (Statement* ps=pgm.stmts().first_ref(); ps!=loop; ps=ps->next_ref()){
00126 if (is_defined(*sym, *ps)){
00127
00128
00129 return false;
00130 }
00131 }
00132 for (Statement* ps=loop->follow_ref(); ps; ps=ps->next_ref()){
00133 if (is_defined(*sym, *ps)){
00134
00135 if (ps->stmt_class()==ASSIGNMENT_STMT){
00136 if (ps->rhs().op()==ETA_OP){
00137 continue;
00138 }
00139 }
00140
00141
00142 return false;
00143 }
00144 }
00145 }
00146
00147
00148
00149 RefList<Expression> primary_sources;
00150 Statement* begin;
00151 Statement* end;
00152 if (loop){
00153 begin=loop->next_ref();
00154 end=loop->follow_ref();
00155 } else {
00156 begin=pgm.stmts().first_ref();
00157 end=pgm.stmts().last_ref();
00158 }
00159 for (Statement* ps=begin;
00160 ps!=end; ps=ps->next_ref()){
00161 if (is_defined(*sym, *ps)){
00162 if (ps->stmt_class()!=ASSIGNMENT_STMT){
00163
00164 return false;
00165 }
00166 switch (ps->rhs().op()){
00167 case MU_OP:
00168 case GAMMA_OP:
00169 case THETA_OP:
00170 case ETA_OP:
00171 continue;
00172 }
00173
00174 Expression& rhs=ps->rhs().parameters_guarded().arg_list()[1];
00175
00176
00177 if (rhs.op()==FUNCTION_CALL_OP){
00178
00179 return false;
00180 }
00181 RefList<Symbol> syms;
00182 referred_symbols(rhs, syms);
00183 for(Iterator<Symbol> sit=syms; sit.valid(); ++sit){
00184
00185 if (!sit.current().is_scalar()){
00186
00187
00188 return false;
00189 }
00190 }
00191
00192 primary_sources.ins_last(rhs);
00193 }
00194 }
00195
00196
00197
00198
00199
00200 List<Expression> per_iteration;
00201 EvolutionGraph* eg=_get_eg(&pgm, (DoStmt*)loop);
00202 for(Iterator<Expression> eit=primary_sources; eit.valid(); ++eit){
00203 Expression* epi=eit.current().clone();
00204 epi=eg->_global_range_per_iteration(epi, (DoStmt*)loop);
00205 per_iteration.ins_last(epi);
00206 }
00207
00208
00209
00210 p_warning("Incomplete implementation.");
00211 sources=per_iteration;
00212
00213 return true;
00214 }
00215
00216
00217
00218
00219 Expression* eg_range_array_1_to_i(Expression& expr,
00220 ProgramUnit& pgm, Statement* loop){
00221
00222
00223 p_assert(expr.op()==ARRAY_REF_OP, "Not an array.");
00224 Symbol& sym=expr.array().symbol();
00225
00226 List<Expression> sources;
00227 bool found=_find_scalar_sources(pgm, loop, expr, sources);
00228 if (!found){
00229
00230 return new RangeExpr(infinity(-1), infinity(+1));
00231 }
00232 Statement* rs=loop;
00233 if (rs==0){
00234 rs=pgm.stmts().last_ref();
00235 } else {
00236 rs=rs->follow_ref();
00237 }
00238 RangeAccessor ra(pgm.range_dict_guarded(), *rs);
00239 if (sources.entries()==0){
00240
00241 return new RangeExpr(infinity(-1), infinity(+1));
00242 }
00243 Expression* e=sources.grab(0);
00244 ra.set_range(sym, e);
00245 while(sources.entries()){
00246 e=sources.grab(0);
00247 ra.union_range(sym, *e);
00248 delete e;
00249 }
00250 return ra.get_range_ref(sym)->clone();
00251 }
00252
00253
00254
00255
00256
00257 Expression* eg_range(Expression& e, ProgramUnit& pgm, Statement* loop){
00258 Expression* toret=e.clone();
00259 if (loop==0){
00260
00261 RefList<Symbol> syms;
00262 referred_symbols(*toret, syms);
00263 if (!pgm.range_dict_valid()){
00264 pgm.range_dict(new AIRangeDict(pgm));
00265 }
00266
00267 RangeAccessor ra(pgm.range_dict_guarded(), *pgm.stmts().first_ref());
00268 RefSet<Symbol> vars_to_eliminate;
00269 for(Iterator<Symbol> sit=syms; sit.valid(); ++sit){
00270 Expression* r=_get_eg(&pgm, loop)->range_from_input(sit.current());
00271 if (r){
00272 ra.set_range(sit.current(), r);
00273 vars_to_eliminate.ins(sit.current());
00274 }
00275 }
00276 toret=ra.eliminate_vars(toret, &vars_to_eliminate);
00277 if (toret->op()==OMEGA_OP){
00278 delete toret;
00279 toret=new RangeExpr(infinity(-1), infinity());
00280 }
00281 }
00282
00283 if (_is_useless(*toret)){
00284
00285 delete toret;
00286 toret=e.clone();
00287 }
00288
00289 EvolutionGraph* global=_get_eg(&pgm, loop);
00290 toret=global->_global_range(toret, (DoStmt*)loop);
00291
00292 if (toret->op()==OMEGA_OP){
00293 delete toret;
00294
00295 return new RangeExpr(infinity(-1), infinity());
00296 } else {
00297
00298 return toret;
00299 }
00300 }
00301
00302
00303 static RangeAccessor* _get_ra(ProgramUnit& pgm, Statement* domain,
00304 Expression& e1, Expression& e2){
00305 RefList<Symbol> syms;
00306 referred_symbols(e1, syms);
00307 referred_symbols(e2, syms);
00308 RefList<Symbol> vars;
00309 for (Iterator<Symbol> sit=syms; sit.valid(); ++sit){
00310 if (sit.current().sym_class()==VARIABLE_CLASS){
00311 vars.ins_last(sit.current());
00312 }
00313 }
00314
00315 RangeAccessor* ra=0;
00316 switch(vars.entries()){
00317 case 1:
00318 {
00319 DefLoc* defloc=pgm.gsa_deflocs_guarded().find_ref(vars[0]);
00320
00321 if(defloc)
00322 {
00323 if (defloc->stmt_valid()){
00324 Statement* rs=&defloc->stmt_guarded();
00325 ra=new RangeAccessor(pgm.range_dict_guarded(), *rs);
00326 }
00327 }
00328 }
00329 break;
00330 case 2:
00331 {
00332 Statement* rs1=0;
00333 Statement* rs2=0;
00334 DefLoc* defloc=pgm.gsa_deflocs_guarded().find_ref(vars[0]);
00335
00336 if(defloc)
00337 {
00338 if (defloc->stmt_valid()){
00339 rs1=&defloc->stmt_guarded();
00340 }
00341 defloc=pgm.gsa_deflocs_guarded().find_ref(vars[1]);
00342 if(defloc)
00343 {
00344 p_assert(defloc, "Could not find definition for symbol.");
00345 if (defloc->stmt_valid()){
00346 rs2=&defloc->stmt_guarded();
00347 }
00348 if (rs1 && rs2){
00349
00350 ra=new RangeAccessor(pgm.range_dict_guarded(),
00351 *rs1->next_ref(), *rs2->next_ref(), false);
00352 } else {
00353 if (rs1) {
00354
00355 ra=new RangeAccessor(pgm.range_dict_guarded(), *rs1->next_ref());
00356 } else {
00357 if (rs2){
00358
00359 ra=new RangeAccessor(pgm.range_dict_guarded(), *rs2->next_ref());
00360 }
00361 }
00362 }
00363 }
00364 }
00365 }
00366 break;
00367 case 0:
00368 break;
00369 default:
00370 break;
00371 }
00372
00373 if (ra==0){
00374 Statement* rs;
00375 if (domain){
00376
00377 rs=domain->follow_ref();
00378 } else {
00379
00380 rs=pgm.stmts().last_ref();
00381 }
00382 ra=new RangeAccessor(pgm.range_dict_guarded(), *rs);
00383 }
00384 return ra;
00385 }
00386
00387 static Relation _eg_compare(Expression* r1, Expression* r2,
00388 ProgramUnit& pgm, Statement* domain){
00389
00390
00391
00392
00393
00394 if (r1->type().data_type()!=INTEGER_TYPE ||
00395 r2->type().data_type()!=INTEGER_TYPE){
00396 return Relation(false, false, false);
00397 }
00398
00399
00400 Expression* l;
00401 if (r1->op()==RANGE_OP){
00402 l=&((RangeExpr*)r1)->lb();
00403 } else {
00404 l=r1;
00405 }
00406 Expression* u;
00407 if (r2->op()==RANGE_OP){
00408 u=&((RangeExpr*)r2)->ub();
00409 } else {
00410 u=r2;
00411 }
00412
00413
00414 RangeAccessor* ra = _get_ra(pgm, domain, *l, *u);
00415 Relation toret=ra->compare(*l, *u);
00416 delete ra;
00417
00418
00419 if (toret.is_greater_than()){
00420
00421
00422 return toret;
00423 }
00424
00425 if (toret.is_greater_equal()){
00426
00427 return toret;
00428
00429 }
00430
00431
00432 if (r2->op()==RANGE_OP){
00433 l=&((RangeExpr*)r2)->lb();
00434 } else {
00435 l=r2;
00436 }
00437 if (r1->op()==RANGE_OP){
00438 u=&((RangeExpr*)r1)->ub();
00439 } else {
00440 u=r1;
00441 }
00442 ra = _get_ra(pgm, domain, *l, *u);
00443 toret=ra->compare(*l, *u);
00444 delete ra;
00445
00446
00447 if (toret.is_greater_than()){
00448
00449
00450 return Relation(true, false, false);
00451 }
00452 if (toret.is_greater_equal()){
00453
00454
00455 return Relation(true, true, false);
00456 }
00457
00458
00459
00460 return Relation(false, false, false);
00461 }
00462
00463
00464 Relation eg_compare(Expression& e1, Expression& e2, ProgramUnit& pgm){
00465
00466
00467 RefList<Symbol> syms;
00468 referred_symbols(e1, syms);
00469
00470 referred_symbols(e2, syms);
00471
00472 set<DoStmt*> loops;
00473 for(Iterator<Symbol> sit=syms; sit.valid(); ++sit){
00474 loops.insert(def_loop(sit.current(), pgm));
00475 }
00476 DoStmt* domain=common_outer(loops);
00477
00478 Expression* r1=e1.clone();
00479 Expression* r2=e2.clone();
00480
00481
00482
00483
00484
00485 while (1){
00486
00487
00488
00489
00490
00491
00492
00493 EvolutionGraph* eg=_get_eg(&pgm, domain);
00494 r1=eg_forward_substitute(pgm, domain, r1);
00495 r2=eg_forward_substitute(pgm, domain, r2);
00496
00497 r1=eg->_global_range(r1, domain);
00498 r2=eg->_global_range(r2, domain);
00499 if (r1==0 || r2==0){
00500 return Relation();
00501 }
00502
00503
00504 Relation toret=_eg_compare(r1, r2, pgm, domain);
00505 if (!toret.is_unknown()){
00506
00507
00508 delete r1;
00509 delete r2;
00510 return toret;
00511 }
00512 if (domain==0){
00513
00514 delete r1;
00515 delete r2;
00516
00517 if (toret.is_unknown()){
00518
00519
00520 RangeAccessor* ra = _get_ra(pgm, domain, e1, e2);
00521 if (e1.type().data_type()==INTEGER_TYPE &&
00522 e1.type().data_type()==INTEGER_TYPE){
00523 toret=ra->compare(e1, e2);
00524 delete ra;
00525 return toret;
00526 } else {
00527 return Relation();
00528 }
00529 }
00530 return toret;
00531 } else {
00532
00533 domain=(DoStmt*)domain->outer_ref();
00534 }
00535 }
00536 }
00537
00538
00539
00540
00541 Expression* eg_distance(ProgramUnit& pgm, DoStmt& loop,
00542 Symbol& left, Symbol& right){
00543
00544 EvolutionGraph* eg_both=_get_eg(&pgm, &loop);
00545 Expression* toret=eg_both->min_distance(left, right);
00546 return toret;
00547 }
00548
00549
00550
00551
00552
00553 static Expression*
00554 eg_distance_1_dim(ProgramUnit& pgm, DoStmt& loop, RangeAccessor& ra,
00555 vector<vector<Symbol*> >& args_left,
00556 vector<vector<Expression*> >& coeffs_left,
00557 vector<vector<Symbol*> >& args_right,
00558 vector<vector<Expression*> >& coeffs_right){
00559
00560 Expression& model=*coeffs_left[0][0];
00561 unsigned int i,j;
00562 for(i=1; i<args_left.size(); ++i){
00563 if (!(*coeffs_left[i][0]==model)){
00564 return constant(0);
00565 }
00566 }
00567 for(i=0; i<args_right.size(); ++i){
00568 if (!(*coeffs_right[i][0]==model)){
00569 return constant(0);
00570 }
00571 }
00572
00573
00574 Expression* toret=infinity(1);
00575 for(i=0; i<args_left.size(); ++i){
00576 for(j=0; j<args_right.size(); ++j){
00577
00578 Expression* candidate=simplify(sub(coeffs_right[j][1]->clone(),
00579 coeffs_left[i][1]->clone()));
00580
00581 Expression* sym_dist=eg_distance(pgm, loop,
00582 *args_left[i][0], *args_right[j][0]);
00583
00584 candidate=simplify(add(candidate, mul(sym_dist, model.clone())));
00585 if (*candidate==*toret){
00586
00587 delete candidate;
00588 } else {
00589 if (p_less_than(*candidate, *toret, &ra)){
00590
00591 delete toret;
00592 toret=candidate;
00593 } else {
00594 if (p_greater_than(*candidate, *toret, &ra)){
00595
00596 delete candidate;
00597 } else {
00598
00599 Symbol* best_op_sym=pgm.symtab().find_ref("MIN");
00600 p_assert(best_op_sym, "MIN intrinsic not in symbol table");
00601 toret=intrinsic_call(id(*best_op_sym),
00602 comma(toret, candidate));
00603 }
00604 }
00605 }
00606 }
00607 }
00608
00609 if (toret->op()==INFINITY_OP){
00610
00611 delete toret;
00612 return constant(0);
00613 } else {
00614 return toret;
00615 }
00616 }
00617
00618
00619
00620 static void _cleanup_coeffs(vector<vector<Expression*> >& coeffs_left,
00621 vector<vector<Expression*> >& coeffs_right){
00622 unsigned int i,j;
00623 for(i=0; i<coeffs_left.size(); ++i){
00624 for(j=0; j<coeffs_left[i].size(); ++j){
00625 delete coeffs_left[i][j];
00626 }
00627 }
00628 for(i=0; i<coeffs_right.size(); ++i){
00629 for(j=0; j<coeffs_right[i].size(); ++j){
00630 delete coeffs_right[i][j];
00631 }
00632 }
00633 }
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643 Expression* eg_distance(ProgramUnit& pgm, DoStmt& loop,
00644 List<Expression>& left, List<Expression>& right,
00645 set<Symbol*>& variants){
00646
00647
00648
00649
00650
00651
00652
00653
00654 if (left.entries()==0 || right.entries()==0){
00655 return constant(0);
00656 }
00657
00658
00659
00660
00661
00662
00663 vector<vector<Symbol*> > args_left, args_right;
00664 vector<vector<Expression*> > coeffs_left, coeffs_right;
00665
00666 if (!check_scalars_affine(left, pgm, loop, args_left, coeffs_left)){
00667 _cleanup_coeffs(coeffs_left, coeffs_right);
00668 return constant(0);
00669 }
00670 if (!check_scalars_affine(right, pgm, loop, args_right, coeffs_right)){
00671 _cleanup_coeffs(coeffs_left, coeffs_right);
00672 return constant(0);
00673 }
00674 RangeAccessor ra(pgm.range_dict_guarded(), *loop.follow_ref());
00675
00676
00677
00678 unsigned int i,j;
00679 bool all_1_dim=true;
00680 for(i=0; i<args_left.size(); ++i){
00681 if (args_left[i].size()!=1){
00682 all_1_dim=false;
00683 break;
00684 }
00685 }
00686 if (all_1_dim){
00687 for(i=0; i<args_right.size(); ++i){
00688 if (args_right[i].size()!=1){
00689 all_1_dim=false;
00690 break;
00691 }
00692 }
00693 }
00694 if (all_1_dim){
00695 Expression* toret= eg_distance_1_dim(pgm, loop, ra,
00696 args_left, coeffs_left,
00697 args_right, coeffs_right);
00698 _cleanup_coeffs(coeffs_left, coeffs_right);
00699 return toret;
00700 }
00701
00702
00703
00704 map<Symbol*, Expression*> args_coeffs;
00705 vector<Symbol*> args_model=args_left[0];
00706 vector<Expression*> coeffs_model=coeffs_left[0];
00707 args_model=args_left[0];
00708 for(j=0; j<args_model.size(); ++j){
00709 variants.insert(args_model[j]);
00710 args_coeffs[args_model[j]]=coeffs_model[j];
00711 }
00712
00713 for(i=0; i<args_left.size(); ++i){
00714
00715 if (args_left[i].size()!=args_model.size()){
00716 _cleanup_coeffs(coeffs_left, coeffs_right);
00717 return constant(0);
00718 } else {
00719 for(j=0; j<args_left[i].size(); ++j){
00720 map<Symbol*, Expression*>::iterator found=
00721 args_coeffs.find(args_left[i][j]);
00722 if (found==args_coeffs.end()){
00723
00724 _cleanup_coeffs(coeffs_left, coeffs_right);
00725 return constant(0);
00726 } else {
00727 if (!(*(*found).second==*coeffs_left[i][j])){
00728 _cleanup_coeffs(coeffs_left, coeffs_right);
00729 return constant(0);
00730 }
00731 }
00732 }
00733 }
00734 }
00735 for(i=0; i<args_right.size(); ++i){
00736
00737 if (args_right[i].size()!=args_model.size()){
00738 _cleanup_coeffs(coeffs_left, coeffs_right);
00739 return constant(0);
00740 } else {
00741 for(j=0; j<args_right[i].size(); ++j){
00742 map<Symbol*, Expression*>::iterator found=
00743 args_coeffs.find(args_right[i][j]);
00744 if (found==args_coeffs.end()){
00745
00746 _cleanup_coeffs(coeffs_left, coeffs_right);
00747 return constant(0);
00748 } else {
00749 if (!(*(*found).second==*coeffs_right[i][j])){
00750 _cleanup_coeffs(coeffs_left, coeffs_right);
00751 return constant(0);
00752 }
00753 }
00754 }
00755 }
00756 }
00757
00758
00759
00760 Expression* toret=infinity(-1);
00761 for(i=0; i<args_left.size(); ++i){
00762 Expression& candidate=*coeffs_left[i][coeffs_left[i].size()-1];
00763 if (candidate==*toret){
00764
00765 } else {
00766 if (p_greater_than(candidate, *toret, &ra)){
00767
00768 delete toret;
00769 toret=candidate.clone();
00770 } else {
00771 if (p_less_than(candidate, *toret, &ra)){
00772
00773 } else {
00774
00775 Symbol* best_op_sym=pgm.symtab().find_ref("MAX");
00776 p_assert(best_op_sym, "MAX intrinsic not in symbol table");
00777 toret=intrinsic_call(id(*best_op_sym),
00778 comma(toret, candidate.clone()));
00779 }
00780 }
00781 }
00782 }
00783 Expression* max_ftl=toret;
00784
00785
00786
00787 toret=infinity(1);
00788 for(i=0; i<args_right.size(); ++i){
00789 Expression& candidate=*coeffs_right[i][coeffs_right[i].size()-1];
00790 if (candidate==*toret){
00791
00792 } else {
00793 if (p_less_than(candidate, *toret, &ra)){
00794
00795 delete toret;
00796 toret=candidate.clone();
00797 } else {
00798 if (p_greater_than(candidate, *toret, &ra)){
00799
00800 } else {
00801
00802 Symbol* best_op_sym=pgm.symtab().find_ref("MIN");
00803 p_assert(best_op_sym, "MIN intrinsic not in symbol table");
00804 toret=intrinsic_call(id(*best_op_sym),
00805 comma(toret, candidate.clone()));
00806 }
00807 }
00808 }
00809 }
00810 Expression* min_ftr=toret;
00811
00812
00813 toret=simplify(sub(min_ftr, max_ftl));
00814 for(unsigned int i=0; i<args_model.size(); ++i){
00815 Symbol& arg=*args_model[i];
00816 Expression& coeff=*coeffs_model[i];
00817 Expression* sym_dist=eg_distance(pgm, loop, arg, arg);
00818 toret=simplify(add(toret, mul(sym_dist, coeff.clone())));
00819 }
00820
00821
00822 _cleanup_coeffs(coeffs_left, coeffs_right);
00823 if (toret->op()==INFINITY_OP){
00824
00825 delete toret;
00826 return constant(0);
00827 } else {
00828
00829 return toret;
00830 }
00831 }
00832
00833
00834 bool eg_contradictory_gate(Expression& gate, ProgramUnit& pgm){
00835
00836 if (gate.op()==AND_OP){
00837 for(Iterator<Expression> eit=gate.arg_list(); eit.valid(); ++eit){
00838 if (eg_contradictory_gate(eit.current(), pgm)){
00839 return true;
00840 }
00841 }
00842 } else {
00843 switch (gate.op()){
00844 case NE_OP:
00845 case EQ_OP:
00846 case LT_OP:
00847 case GT_OP:
00848 case LE_OP:
00849 case GE_OP:
00850 {
00851
00852
00853 Relation lr=eg_compare(gate.arg_list()[0], gate.arg_list()[1], pgm);
00854
00855 if (lr.is_less_than() && (gate.op()==GT_OP ||
00856 gate.op()==GE_OP ||
00857 gate.op()==EQ_OP )){
00858
00859 return true;
00860 }
00861 if (lr.is_greater_than() && (gate.op()==LT_OP ||
00862 gate.op()==LE_OP ||
00863 gate.op()==EQ_OP )){
00864
00865 return true;
00866 }
00867 if (lr.is_less_equal() && gate.op()==GT_OP){
00868
00869 return true;
00870 }
00871 if (lr.is_greater_equal() && gate.op()==LT_OP){
00872
00873 return true;
00874 }
00875 if (lr.is_equal() && (gate.op()==GT_OP ||
00876 gate.op()==LT_OP ||
00877 gate.op()==NE_OP )){
00878
00879 return true;
00880 }
00881 if (lr.is_not_equal() && gate.op()==EQ_OP){
00882
00883 return true;
00884 }
00885
00886 }
00887 }
00888 }
00889
00890 return false;
00891 }
00892
00893 bool eg_redundant_gate(Expression& gate, ProgramUnit& pgm){
00894 Expression* g=simplify(not(gate.clone()));
00895 bool toret=eg_contradictory_gate(*g, pgm);
00896 delete g;
00897 return toret;
00898 }
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908 void eg_get_ev_summary(ProgramUnit& pgm,
00909 DoStmt* dostmt,
00910 Symbol& sym,
00911 pair<RangeExpr*, bool>& range,
00912 vector<pair<List<Expression>,
00913 pair<RangeExpr*, Expression*> > >& evs,
00914 Symbol*& mu){
00915 EvolutionGraph* eg=_get_eg(&pgm, dostmt);
00916
00917
00918
00919
00920 mu=0;
00921 Symbol* back=0;
00922 if (!eg->find_unique_mu(&sym, mu, back)){
00923
00924 return;
00925 }
00926
00927
00928
00929
00930
00931 map<Symbol*, list<list<Symbol*> > > traces;
00932 eg->traces_from_mu(back, range, traces);
00933
00934
00935 list<list<Symbol*> >& trace=traces[mu];
00936 list<list<Symbol*> >::iterator it;
00937 for(it=trace.begin(); it!=trace.end(); ++it){
00938 evs.push_back(make_pair(List<Expression>(),
00939 make_pair((RangeExpr*)0, (Expression*)0)));
00940 pair<List<Expression>, pair<RangeExpr*, Expression*> >& top=
00941 evs[evs.size()-1];
00942 Evolution<Expression> ev;
00943 eg->get_trace_details(*it, ev, top.second.second, top.first);
00944 top.second.first=new RangeExpr(ev.min_difference()->clone(),
00945 ev.max_difference()->clone());
00946 }
00947 }
00948
00949
00950
00951
00952
00953
00954 bool eg_nondecreasing(ProgramUnit& pgm,
00955 DoStmt& dostmt,
00956 Symbol& sym){
00957 EvolutionGraph* eg=_get_eg(&pgm, &dostmt);
00958 return eg->sequence_type(sym) == EvolutionGraph::ST_NONDECREASING;
00959 }
00960
00961 static void
00962 _find_call_sites(ProgramUnit& callee,
00963 vector<pair<ProgramUnit*, Statement*> >&call_sites){
00964 RefSet<ProgramUnit>& callers=callee.called_by();
00965 for(Iterator<ProgramUnit> pit=callers; pit.valid(); ++pit){
00966 ProgramUnit& pgm=pit.current();
00967 Iterator<Statement> stit=pgm.stmts().iterator();
00968 for( ; stit.valid(); ++stit){
00969 Statement& stmt=stit.current();
00970 if (called_pgm(stmt)==&callee){
00971 call_sites.push_back(make_pair(&pgm, &stmt));
00972 }
00973 }
00974 }
00975 }
00976
00977
00978
00979
00980 RangeExpr* program_wide_range(ProgramUnit& pgm, Expression& expr){
00981
00982
00983 Expression* local_pgm_range=eg_range(expr, pgm, 0);
00984
00985
00986
00987
00988 RefSet<Symbol> vars_to_eliminate;
00989 RangeAccessor ra(pgm.range_dict_guarded(), *pgm.stmts().last_ref());
00990 RefList<Symbol> syms;
00991 referred_symbols(*local_pgm_range, syms);
00992 for(Iterator<Symbol> sit=syms; sit.valid(); ++sit){
00993 Symbol& sym=sit.current();
00994 bool range_is_set= (ra.get_range_ref(sym)!=0);
00995 vars_to_eliminate.ins(sym);
00996 List<RangeExpr> sym_ranges;
00997
00998 map<const Symbol*, Evolution<Expression> > muevs;
00999 list<pair<const Symbol*, Evolution<Expression> > > ievs;
01000 _get_eg(&pgm, 0)->export_evolutions(&sym, muevs, ievs);
01001 map<const Symbol*, Evolution<Expression> >::iterator muit;
01002 list<pair<const Symbol*, Evolution<Expression> > >::iterator iit;
01003 for(muit=muevs.begin(); muit!=muevs.end(); ++muit){
01004
01005
01006 vector<pair<ProgramUnit*, Statement*> > call_sites;
01007 _find_call_sites(pgm, call_sites);
01008 vector<pair<ProgramUnit*, Statement*> >::iterator it;
01009 for(it=call_sites.begin(); it!=call_sites.end(); ++it){
01010 ProgramUnit& caller=*(*it).first;
01011 Statement& callsite=*(*it).second;
01012 Translator trans(caller, callsite);
01013
01014 Expression* t=translate_and_reshape(trans, pgm, caller, callsite,
01015 id(*(*muit).first));
01016
01017
01018 RangeExpr* trange=program_wide_range(caller, *t);
01019
01020 delete t;
01021
01022 RangeExpr* total=
01023 new RangeExpr(simplify(add((*muit).second.min_difference()->clone(),
01024 trange->lb().clone())),
01025 simplify(add((*muit).second.max_difference()->clone(),
01026 trange->ub().clone())));
01027
01028 delete trange;
01029
01030 if (range_is_set){
01031 ra.union_range(sym, *total);
01032 delete total;
01033 } else {
01034 ra.set_range(sym, total);
01035 range_is_set=true;
01036 }
01037 }
01038 }
01039 for(iit=ievs.begin(); iit!=ievs.end(); ++iit){
01040
01041
01042 RangeExpr r((*iit).second.min_difference()->clone(),
01043 (*iit).second.max_difference()->clone());
01044 ra.union_range(sym, r);
01045 }
01046
01047 const Expression* r=ra.get_range_ref(sym);
01048
01049
01050
01051 }
01052
01053
01054 Expression* toret=ra.eliminate_vars(local_pgm_range, &vars_to_eliminate);
01055
01056
01057
01058 if(toret->op()!=RANGE_OP){
01059 return new RangeExpr(toret, toret->clone());
01060 }
01061 return (RangeExpr*)toret;
01062 }
01063
01064