00001
00002
00003 #include "expression_util.h"
00004
00005 #include "../Expression/Expression.h"
00006 #include "../Expression/UnaryExpr.h"
00007 #include "../Symbol/Symbol.h"
00008 #include "../Symbol/VariableSymbol.h"
00009 #include "../ArrayDims.h"
00010 #include "../Monotonicity.h"
00011 #include "../Range/StmtRanges.h"
00012 #include "../Range/Relation.h"
00013 #include "../Statement/Statement.h"
00014 #include "../Traverser.h"
00015 #include "../macros.h"
00016
00017
00018
00019
00020
00021
00022
00023 Boolean is_expr_variable(const Expression & e)
00024 {
00025 if (e.op() == ID_OP)
00026 return True;
00027
00028 for (Iterator<Expression> iter = e.arg_list(); iter.valid(); ++iter) {
00029 if (is_expr_variable(iter.current()))
00030 return True;
00031 }
00032
00033 return False;
00034 }
00035
00036
00037
00038
00039
00040
00041 Boolean
00042 is_var_in_expr(const Expression & e, const Symbol & var)
00043 {
00044 if (e.op() == ID_OP)
00045 return (&e.symbol() == &var);
00046
00047 for (Iterator<Expression> iter = e.arg_list(); iter.valid(); ++iter) {
00048 if (is_var_in_expr(iter.current(), var))
00049 return True;
00050 }
00051
00052 return False;
00053 }
00054
00055
00056
00057
00058
00059 Boolean
00060 contains_func_call(const Statement & stmt)
00061 {
00062 Iterator<Expression> iter
00063 = (CASTAWAY(Statement &) stmt).iterate_expressions();
00064
00065 for (; iter.valid(); ++iter)
00066 if (!iter.current().is_side_effect_free())
00067 return True;
00068
00069 return False;
00070 }
00071
00072
00073
00074
00075
00076 Boolean
00077 is_int_scalar(const Symbol & sym)
00078 {
00079 return (sym.sym_class() == VARIABLE_CLASS
00080 && sym.type().data_type() == INTEGER_TYPE
00081 && !sym.is_array());
00082 }
00083
00084
00085
00086
00087
00088
00089
00090 Expression *
00091 replace_parameters(Expression *expr)
00092 {
00093 if (! expr)
00094 return 0;
00095
00096 if (expr->op() == ID_OP) {
00097 if (expr->symbol().sym_class() == SYMBOLIC_CONSTANT_CLASS) {
00098 Expression *old_subst = expr->symbol().expr_ref()->clone();
00099 Expression *new_subst = replace_parameters(old_subst);
00100
00101 delete expr;
00102
00103 return new_subst;
00104 }
00105 }
00106 else {
00107 List<Expression> & args = expr->arg_list();
00108
00109 for (Mutator<Expression> mutr = args; mutr.valid(); ++mutr) {
00110 Assign<Expression> expr_as(mutr.assign());
00111 expr_as = replace_parameters( mutr.pull() );
00112 }
00113 }
00114
00115 return expr;
00116 }
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128 Expression *
00129 extract_stride( Expression * expr, const Expression & index_id )
00130 {
00131 Expression * plus_one = substitute_var( expr->clone(),
00132 *(index_id.base_variable_ref()),
00133 *add( index_id.clone(), constant(1) ) );
00134
00135 return simplify( sub( plus_one, expr->clone() ) );
00136 }
00137
00138
00139
00140
00141
00142
00143 Expression *
00144 linearize_zero_registered( Expression * expr, VariableSymbol & sym )
00145 {
00146
00147
00148
00149 ArrayDims & src_dim = sym.dim();
00150 int src_dims = src_dim.entries();
00151
00152 List<Expression> & src_subs_list = expr->arg_list();
00153
00154
00155
00156 Expression *src_exl;
00157 Expression *src_exu;
00158 Expression *offset;
00159
00160 if (src_dims>1) {
00161 src_exl = src_dim[src_dims - 1].lower_ref();
00162
00163 if (src_exl)
00164 src_exl = src_exl->clone();
00165 else
00166 src_exl = constant(1);
00167
00168
00169
00170 offset = sub(src_subs_list[src_dims - 1].clone(), src_exl);
00171
00172 for (int i = src_dims - 2; i>0; --i) {
00173 src_exl = src_dim[i].lower_ref();
00174
00175 if (src_exl)
00176 src_exl = src_exl->clone();
00177 else
00178 src_exl = constant(1);
00179
00180 src_exu = src_dim[i].upper_ref();
00181
00182 if (src_exu)
00183 src_exu = src_exu->clone();
00184 else
00185 src_exu = constant(1);
00186
00187
00188
00189 offset = add(mul(add(sub(src_exu, src_exl), constant(1)),
00190 offset),
00191 sub(src_subs_list[i].clone(), src_exl->clone()));
00192 }
00193 }
00194 else {
00195 offset = constant(0);
00196 }
00197
00198 src_exl = src_dim[0].lower_ref();
00199
00200 if (src_exl)
00201 src_exl = src_exl->clone();
00202 else
00203 src_exl = constant(1);
00204
00205 src_exu = src_dim[0].upper_ref();
00206
00207 if (src_exu)
00208 src_exu = src_exu->clone();
00209 else
00210 src_exu = constant(1);
00211
00212
00213
00214 offset = add(mul(add(sub(src_exu, src_exl), constant(1)),
00215 offset),
00216 sub(src_subs_list[0].clone(), src_exl->clone()));
00217
00218 return simplify(offset);
00219 }
00220
00221
00222
00223
00224 Expression *
00225 last_element_offset ( VariableSymbol & sym )
00226 {
00227
00228
00229
00230 ArrayDims & src_dim = sym.dim();
00231 int src_dims = src_dim.entries();
00232
00233
00234
00235 Expression *src_exl;
00236 Expression *src_exu;
00237 Expression *offset;
00238
00239 if (src_dims>1) {
00240 src_exu = src_dim[src_dims - 1].upper_ref();
00241
00242
00243
00244
00245 if (src_exu == 0) return omega();
00246
00247 src_exl = src_dim[src_dims - 1].lower_ref();
00248
00249 if (src_exl)
00250 src_exl = src_exl->clone();
00251 else
00252 src_exl = constant(1);
00253
00254
00255
00256 offset = sub(src_exu->clone(), src_exl);
00257
00258 for (int i = src_dims - 2; i>0; --i) {
00259 src_exl = src_dim[i].lower_ref();
00260
00261 if (src_exl)
00262 src_exl = src_exl->clone();
00263 else
00264 src_exl = constant(1);
00265
00266 src_exu = src_dim[i].upper_ref();
00267
00268 if (src_exu)
00269 src_exu = src_exu->clone();
00270 else
00271 src_exu = constant(1);
00272
00273
00274
00275 offset = add(mul(add(sub(src_exu, src_exl), constant(1)),
00276 offset),
00277 sub(src_exu->clone(), src_exl->clone()));
00278 }
00279 }
00280 else {
00281 offset = constant(0);
00282 }
00283
00284 src_exl = src_dim[0].lower_ref();
00285
00286 if (src_exl)
00287 src_exl = src_exl->clone();
00288 else
00289 src_exl = constant(1);
00290
00291 src_exu = src_dim[0].upper_ref();
00292
00293 if (src_exu)
00294 src_exu = src_exu->clone();
00295 else
00296 src_exu = constant(1);
00297
00298
00299
00300 offset = add(mul(add(sub(src_exu, src_exl), constant(1)),
00301 offset),
00302 sub(src_exu->clone(), src_exl->clone()));
00303
00304 return simplify(offset);
00305 }
00306
00307
00308
00309 Expression *
00310 _replace_mul_minus_one (Expression *expr)
00311 {
00312
00313
00314 for (Mutator<Expression> mutexpr = expr->arg_list();
00315 mutexpr.valid();
00316 ++mutexpr) {
00317
00318 if ((mutexpr.current().op() == INTEGER_CONSTANT_OP) &&
00319 (mutexpr.current().value() == -1)) {
00320 mutexpr.del();
00321 }
00322 }
00323
00324
00325
00326
00327 Mutator<Expression> mutexpr2 = expr->arg_list();
00328 Assign<Expression> asexpr2(mutexpr2.assign());
00329 Expression *expr2 = mutexpr2.pull();
00330 Expression *new_expr =
00331 new UnaryExpr(U_MINUS_OP, expr2->type(), expr2);
00332 asexpr2 = new_expr;
00333
00334 return expr;
00335 }
00336
00337
00338
00339
00340 Boolean
00341 _is_mul_minus_one (const Expression & expr)
00342 {
00343 if (expr.op() == MULT_OP) {
00344 for (Iterator<Expression> ex_iter = expr.arg_list();
00345 ex_iter.valid();
00346 ++ex_iter) {
00347
00348 if ((ex_iter.current().op() == INTEGER_CONSTANT_OP) &&
00349 (ex_iter.current().value() == -1)) {
00350
00351
00352
00353 return True;
00354 }
00355 }
00356 return False;
00357 } else {
00358 return False;
00359 }
00360 }
00361
00362
00363
00364 Expression *
00365 replace_mul_minus_one( Expression * expr )
00366 {
00367 Expression * newexpr;
00368
00369 for (Traverser trav(*expr, _is_mul_minus_one);
00370 trav.valid();
00371 ++trav) {
00372
00373
00374
00375 if (!trav.top_level()) {
00376
00377 Assign<Expression> asexpr(trav.assign());
00378 asexpr = _replace_mul_minus_one(trav.pull());
00379
00380 } else {
00381 newexpr = _replace_mul_minus_one(expr);
00382 return replace_mul_minus_one( newexpr );
00383 }
00384 }
00385 return expr;
00386 }
00387
00388 Monotonicity *
00389 test_monotonicity (RangeAccessor & range_acc,
00390 Symbol & index,
00391 Expression * stride,
00392 Expression * expr)
00393 {
00394 Monotonicity * mono = new Monotonicity( );
00395
00396 if (is_var_in_expr( *expr, index )) {
00397 mono->set_varying();
00398
00399
00400
00401
00402 Expression *index_plus_stride = add(id(index),
00403 stride->clone());
00404
00405 Expression * expr_stride = simplify(sub(substitute_var(expr->clone(),
00406 index,
00407 *index_plus_stride),
00408 expr->clone()));
00409
00410
00411
00412 if (expr_stride->op() == INTEGER_CONSTANT_OP) {
00413 int val = expr_stride->value();
00414 if (val < 0) {
00415 mono->set_negative();
00416 } else if (val > 0) {
00417 mono->set_positive();
00418 } else {
00419 mono->set_constant();
00420 }
00421 return mono;
00422 }
00423
00424
00425 Relation rel = range_acc.compare(*expr_stride, *constant(0));
00426
00427 delete index_plus_stride;
00428 delete expr_stride;
00429
00430 if (rel.is_less_than()) {
00431 mono->set_negative();
00432 } else if (rel.is_greater_than()) {
00433 mono->set_positive();
00434 } else {
00435 mono->set_unknown_dir();
00436 }
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555 } else {
00556 mono->set_constant();
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568 }
00569 return mono;
00570 }
00571
00572
00573
00574
00575
00576
00577 AR_CERTAINTY
00578 expr_divides ( Expression & divide_by, Expression & divide_into )
00579 {
00580 bool divi=false;
00581
00582 if (_ar_logging && _ar_logging % 11 == 0) {
00583 arlog << ">>expr_divides-- Does " << divide_by << " DIVIDE " << divide_into << " ??";
00584 }
00585 if (is_integer_one(divide_by)) {
00586 divi = true;
00587 } else {
00588 if (is_integer_constant(divide_by) &&
00589 is_integer_constant(divide_into)) {
00590 if (divide_into.value() % divide_by.value() == 0) {
00591 if (_ar_logging && _ar_logging % 11 == 0) {
00592 arlog << ": YES!" << endl;
00593 }
00594 return AR_YES;
00595 } else {
00596 if (_ar_logging && _ar_logging % 11 == 0) {
00597 arlog << ": NO!" << endl;
00598 }
00599 return AR_NO;
00600 }
00601 } else {
00602 Expression * expr = simplify ( div(divide_into.clone(),
00603 divide_by.clone() ) );
00604 if (expr->op() == INTEGER_CONSTANT_OP) {
00605 divi = (expr->value() != 0);
00606 } else {
00607 if (expr->op() == EXP_OP) {
00608 if ((expr->arg_list()[1].op() == INTEGER_CONSTANT_OP) &&
00609 (expr->arg_list()[1].value() >= 0)) {
00610 divi = true;
00611 } else {
00612 divi = false;
00613 }
00614 } else {
00615 divi = expr->op() != DIV_OP;
00616 }
00617 }
00618
00619 delete expr;
00620 }
00621 }
00622
00623 if (divi) {
00624 if (_ar_logging && _ar_logging % 11 == 0) {
00625 arlog << ": YES!" << endl;
00626 }
00627 return AR_YES;
00628 } else {
00629 if (_ar_logging && _ar_logging % 11 == 0) {
00630 arlog << ": NOT SURE" << endl;
00631 }
00632 return AR_UNSURE;
00633 }
00634 }
00635