00001
00002
00003
00004
00005 #include "../Collection/KeyIterator.h"
00006 #include "../Collection/Iterator.h"
00007 #include "../Collection/Mutator.h"
00008 #include "../Collection/RefSet.h"
00009 #include "../Collection/RefList.h"
00010 #include "../Collection/Map.h"
00011 #include "../Collection/RefMap.h"
00012 #include "../Symbol/Symbol.h"
00013 #include "../Expression/Expression.h"
00014
00015 #include "JumpFunction.h"
00016 #include "AliasSets.h"
00017 #include "IPCPConstants.h"
00018
00019
00020
00021
00022
00023 static void
00024 _simplify_var_mods(Map<Symbol, Expression> &var_mods)
00025 {
00026 RefSet<Symbol> *mod_vars = modified_vars(var_mods);
00027 Iterator<Symbol> mod_var_iter = *mod_vars;
00028
00029 for ( ; mod_var_iter.valid(); ++mod_var_iter) {
00030 Symbol &var = mod_var_iter.current();
00031 Expression *simplified_mod = var_mods.grab(var);
00032 Boolean mod_is_ref = (simplified_mod->base_variable_ref() != 0);
00033 simplified_mod = simplify(simplified_mod);
00034
00035 if (simplified_mod->op() == ID_OP
00036 && &simplified_mod->symbol() == &var)
00037
00038 delete simplified_mod;
00039 else {
00040 if (simplified_mod->base_variable_ref() && ! mod_is_ref)
00041 simplified_mod = paren(simplified_mod);
00042
00043 var_mods.ins(var, simplified_mod);
00044 }
00045 }
00046
00047 delete mod_vars;
00048 }
00049
00050
00051
00052
00053 ReturnJumpFunction::ReturnJumpFunction(const RefList<Symbol> ¶m_list,
00054 const RefSet<Symbol> &used_global_vars,
00055 Map<Symbol, Expression> *old_const_mods,
00056 Map<Symbol, Expression> *new_consts)
00057 {
00058 _param_list = param_list;
00059 _used_global_vars = used_global_vars;
00060 _simplify_var_mods(*new_consts);
00061 _simplify_var_mods(*old_const_mods);
00062 _old_const_mods = old_const_mods;
00063 _new_consts = new_consts;
00064 }
00065
00066 ReturnJumpFunction::ReturnJumpFunction(const ReturnJumpFunction &other)
00067 {
00068 _param_list = other._param_list;
00069 _used_global_vars = other._used_global_vars;
00070 _old_const_mods = new Map<Symbol,Expression>(*other._old_const_mods);
00071 _new_consts = new Map<Symbol,Expression>(*other._new_consts);
00072 }
00073
00074
00075
00076
00077 ReturnJumpFunction::~ReturnJumpFunction()
00078 {
00079 delete _old_const_mods;
00080 delete _new_consts;
00081 }
00082
00083
00084
00085
00086
00087
00088 static Boolean
00089 _are_vars_in_expr(const Expression &e, const RefSet<Symbol> &vars)
00090 {
00091 if (e.op() == ID_OP)
00092 return vars.member(e.symbol());
00093 else {
00094 Iterator<Expression> iter = e.arg_list();
00095
00096 for ( ; iter.valid(); ++iter)
00097 if (_are_vars_in_expr(iter.current(), vars))
00098 return True;
00099 }
00100
00101 return False;
00102 }
00103
00104
00105
00106
00107
00108
00109 static Expression *
00110 _subst_vars_in_expr1(Expression *expr, RefSet<Symbol> &subst_vars,
00111 const Map<Symbol, Expression> &subst_map)
00112 {
00113 p_assert(expr, "_subst_vars_in_expr was given a NULL expression.");
00114
00115 if (expr->op() == ID_OP) {
00116 Symbol &var = expr->symbol();
00117 const Expression *subst_expr = subst_map.find_ref(var);
00118
00119 if (subst_expr) {
00120 delete expr;
00121
00122 if (! subst_vars.member(var)) {
00123 subst_vars.ins(var);
00124 expr = _subst_vars_in_expr1(subst_expr->clone(), subst_vars,
00125 subst_map);
00126 subst_vars.del(var);
00127 }
00128 else
00129 expr = omega();
00130 }
00131 }
00132 else {
00133 Mutator<Expression> arg_iter = expr->arg_list();
00134
00135 for ( ; arg_iter.valid(); ++arg_iter) {
00136 Assign<Expression> eas(arg_iter.assign());
00137 eas = _subst_vars_in_expr1(arg_iter.pull(),
00138 subst_vars, subst_map);
00139
00140 if (arg_iter.current().op() == OMEGA_OP) {
00141 Expression *om = arg_iter.grab();
00142 delete expr;
00143 return om;
00144 }
00145 }
00146 }
00147
00148 return expr;
00149 }
00150
00151 Expression *
00152 subst_vars_in_expr(Expression *expr,
00153 const Map<Symbol, Expression> &subst_map)
00154 {
00155 RefSet<Symbol> subst_vars;
00156 return _subst_vars_in_expr1(expr, subst_vars, subst_map);
00157 }
00158
00159
00160
00161
00162
00163 void
00164 subst_vars_in_map(Map<Symbol, Expression> &var_mods,
00165 const Map<Symbol, Expression> &subst_map)
00166 {
00167 if (subst_map.entries() > 0) {
00168 RefSet<Symbol> *mod_vars = modified_vars(var_mods);
00169 Iterator<Symbol> mod_var_iter = *mod_vars;
00170
00171 for ( ; mod_var_iter.valid(); ++mod_var_iter) {
00172 Symbol &var = mod_var_iter.current();
00173 var_mods.ins(var, subst_vars_in_expr(var_mods.grab(var), subst_map));
00174 }
00175
00176 delete mod_vars;
00177 }
00178 }
00179
00180
00181
00182
00183
00184 RefSet<Symbol> *
00185 ReturnJumpFunction::_modified_aliases(AliasSets &alias_sets) const
00186 {
00187 RefSet<Symbol> *modified_aliases = new RefSet<Symbol>;
00188 KeyIterator<Symbol, Expression> var_mod_iter = *_old_const_mods;
00189
00190 for ( ; var_mod_iter.valid(); ++var_mod_iter) {
00191 RefSet<Symbol> *aliased_vars
00192 = alias_sets.aliases(var_mod_iter.current_key(),
00193 _used_global_vars);
00194
00195 Iterator<Symbol> alias_iter = *aliased_vars;
00196
00197 for ( ; alias_iter.valid(); ++alias_iter)
00198 modified_aliases->ins(alias_iter.current());
00199
00200 delete aliased_vars;
00201 }
00202
00203 return modified_aliases;
00204 }
00205
00206
00207
00208
00209 RefSet<Symbol> *
00210 modified_vars(const Map<Symbol, Expression> &var_mods)
00211 {
00212 RefSet<Symbol> *modified_vars = new RefSet<Symbol>;
00213 KeyIterator<Symbol, Expression> var_mod_iter = var_mods;
00214
00215 for ( ; var_mod_iter.valid(); ++var_mod_iter)
00216 modified_vars->ins(var_mod_iter.current_key());
00217
00218 return modified_vars;
00219 }
00220
00221
00222
00223
00224
00225
00226 void
00227 ReturnJumpFunction::_eliminate_modified_aliases(Map<Symbol, Expression> &var_mods,
00228 AliasSets &alias_sets) const
00229 {
00230 RefSet<Symbol> *modified_aliases = _modified_aliases(alias_sets);
00231
00232 if (modified_aliases->entries()) {
00233
00234
00235
00236 Iterator<Symbol> alias_iter = *modified_aliases;
00237
00238 for ( ; alias_iter.valid(); ++alias_iter)
00239 var_mods.ins(alias_iter.current(), omega());
00240
00241
00242
00243
00244
00245 RefSet<Symbol> *mod_vars = modified_vars(var_mods);
00246 Iterator<Symbol> mod_var_iter = *mod_vars;
00247
00248 for ( ; mod_var_iter.valid(); ++mod_var_iter) {
00249 const Symbol &var = mod_var_iter.current();
00250
00251 if (_are_vars_in_expr(var_mods[var], *modified_aliases))
00252
00253 var_mods.ins(var, omega());
00254 }
00255
00256 delete mod_vars;
00257 }
00258
00259 delete modified_aliases;
00260 }
00261
00262
00263
00264
00265
00266 void
00267 ReturnJumpFunction::_rename_formals(Map<Symbol, Expression> &var_mods,
00268 const List<Expression> ¶m_values) const
00269 {
00270 p_assert(_param_list.entries() == param_values.entries(),
00271 "ReturnJumpFunction::new_values(): The number of formals does not equal the number of actuals.");
00272 Iterator<Symbol> formal_iter = _param_list;
00273 Iterator<Expression> actual_iter = param_values;
00274
00275 for ( ; formal_iter.valid(); ++formal_iter, ++actual_iter) {
00276 Symbol &formal = formal_iter.current();
00277 Expression &actual_expr = actual_iter.current();
00278
00279 if (var_mods.member(formal)) {
00280 const Symbol *actual = actual_expr.base_variable_ref();
00281
00282 if (actual) {
00283 if (actual_expr.op() == ID_OP
00284 && formal.type() == actual->type())
00285
00286 var_mods.ins(*actual, var_mods.grab(formal));
00287 else {
00288 var_mods.del(formal);
00289 var_mods.ins(*actual, omega());
00290 }
00291 }
00292 else
00293 var_mods.del(formal);
00294 }
00295 }
00296 }
00297
00298
00299
00300
00301
00302 Map<Symbol, Expression> *
00303 ReturnJumpFunction::_param_map(const List<Expression> ¶m_values) const
00304 {
00305 p_assert(_param_list.entries() == param_values.entries(),
00306 "ReturnJumpFunction::_param_map(): The number of formals does not equal the number of actuals.");
00307 Map<Symbol, Expression> *param_map = new Map<Symbol, Expression>;
00308 Iterator<Symbol> formal_iter = _param_list;
00309 Iterator<Expression> actual_iter = param_values;
00310
00311 for ( ; formal_iter.valid(); ++formal_iter, ++actual_iter) {
00312 const Symbol &formal = formal_iter.current();
00313 Expression &actual_expr = actual_iter.current();
00314
00315 if (formal.type() == actual_expr.type())
00316 param_map->ins(formal, actual_expr.clone());
00317 else
00318 param_map->ins(formal, omega());
00319 }
00320
00321 return param_map;
00322 }
00323
00324
00325
00326
00327 Map<Symbol, Expression> *
00328 ReturnJumpFunction::const_mods(const List<Expression> ¶m_values,
00329 AliasSets &alias_sets) const
00330 {
00331 Map<Symbol, Expression> *new_const_mods
00332 = new Map<Symbol, Expression>(*_old_const_mods);
00333 _eliminate_modified_aliases(*new_const_mods, alias_sets);
00334 _rename_formals(*new_const_mods, param_values);
00335
00336 Map<Symbol, Expression> *param_map = _param_map(param_values);
00337 subst_vars_in_map(*new_const_mods, *param_map);
00338 delete param_map;
00339
00340 return new_const_mods;
00341 }
00342
00343 Map<Symbol, Expression> *
00344 ReturnJumpFunction::const_mods(const List<Expression> ¶m_values) const
00345 {
00346 AliasSets alias_sets;
00347 alias_sets.alias(_param_list, param_values);
00348 Map<Symbol, Expression> *new_const_mods = const_mods(param_values,
00349 alias_sets);
00350 _simplify_var_mods(*new_const_mods);
00351 return new_const_mods;
00352 }
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362 static void
00363 _filter_out_mod_params(Map<Symbol,Expression> ¶m_map,
00364 const Map<Symbol,Expression> &var_mods)
00365 {
00366 RefSet<Symbol> *mod_vars = modified_vars(param_map);
00367 Iterator<Symbol> mod_var_iter = *mod_vars;
00368
00369 for ( ; mod_var_iter.valid(); ++mod_var_iter) {
00370 const Symbol &var = mod_var_iter.current();
00371
00372 if (var_mods.member(var) && ! param_map[var].base_variable_ref())
00373 param_map.ins(var, omega());
00374 }
00375
00376 delete mod_vars;
00377 }
00378
00379
00380
00381
00382
00383 static void
00384 _delete_non_consts(Map<Symbol, Expression> &var_mods)
00385 {
00386 RefSet<Symbol> *mod_vars = modified_vars(var_mods);
00387 Iterator<Symbol> mod_var_iter = *mod_vars;
00388
00389 for ( ; mod_var_iter.valid(); ++mod_var_iter) {
00390 Symbol &var = mod_var_iter.current();
00391
00392 if (var_mods[var].op() == OMEGA_OP)
00393 var_mods.del(var);
00394 }
00395
00396 delete mod_vars;
00397 }
00398
00399
00400
00401
00402 Map<Symbol, Expression> *
00403 ReturnJumpFunction::new_consts(const List<Expression> ¶m_values,
00404 AliasSets &alias_sets) const
00405 {
00406 Map<Symbol, Expression> *new_consts = new Map<Symbol, Expression>(*_new_consts);
00407 _eliminate_modified_aliases(*new_consts, alias_sets);
00408 _rename_formals(*new_consts, param_values);
00409
00410 Map<Symbol, Expression> *param_map = _param_map(param_values);
00411 _filter_out_mod_params(*param_map, *new_consts);
00412 subst_vars_in_map(*new_consts, *param_map);
00413 delete param_map;
00414 _delete_non_consts(*new_consts);
00415
00416 return new_consts;
00417 }
00418
00419 Map<Symbol, Expression> *
00420 ReturnJumpFunction::new_consts(const List<Expression> ¶m_values) const
00421 {
00422 AliasSets alias_sets;
00423 alias_sets.alias(_param_list, param_values);
00424 Map<Symbol, Expression> *consts = new_consts(param_values, alias_sets);
00425 _simplify_var_mods(*consts);
00426
00427 return consts;
00428 }
00429
00430
00431
00432 Listable *
00433 ReturnJumpFunction::listable_clone() const
00434 {
00435 return new ReturnJumpFunction(*this);
00436 }
00437
00438
00439
00440
00441 void
00442 _print(ostream &o, const Map<Symbol, Expression> &var_mods)
00443 {
00444 KeyIterator<Symbol,Expression> mod_iter = var_mods;
00445
00446 if (mod_iter.valid()) {
00447 o << mod_iter.current_key().name_ref() << "="
00448 << mod_iter.current_data();
00449 ++mod_iter;
00450
00451 for ( ; mod_iter.valid(); ++mod_iter)
00452 o << ", " << mod_iter.current_key().name_ref() << "="
00453 << mod_iter.current_data();
00454 }
00455 }
00456
00457 void
00458 ReturnJumpFunction::print(ostream &o) const
00459 {
00460 o << "[";
00461 o << "param_list=(";
00462
00463 Iterator<Symbol> param_iter = _param_list;
00464
00465 if (param_iter.valid()) {
00466 o << param_iter.current().name_ref();
00467 ++param_iter;
00468
00469 for ( ; param_iter.valid(); ++param_iter)
00470 o << ", " << param_iter.current().name_ref();
00471 }
00472
00473 o << ")";
00474 o << ", old_const_mods={";
00475 _print(o, *_old_const_mods);
00476 o << "}";
00477 o << ", new_consts={";
00478 _print(o, *_new_consts);
00479 o << "}";
00480 o << "]";
00481 }
00482
00483
00484
00485
00486 int
00487 ReturnJumpFunction::structures_OK() const
00488 {
00489 return (_param_list.structures_OK()
00490 && _old_const_mods && _old_const_mods->structures_OK()
00491 && _new_consts && _new_consts->structures_OK());
00492 }
00493
00494
00495
00496
00497 JumpFunction::JumpFunction(const RefList<Symbol> ¶m_list,
00498 const RefSet<Symbol> &used_global_vars,
00499 Map<Symbol, Expression> *old_const_mods,
00500 Map<Symbol, Expression> *new_consts)
00501 : ReturnJumpFunction(param_list, used_global_vars, old_const_mods, new_consts)
00502 {
00503
00504 }
00505
00506 JumpFunction::JumpFunction(const JumpFunction &other)
00507 : ReturnJumpFunction(other)
00508 {
00509
00510 }
00511
00512
00513
00514
00515 JumpFunction::~JumpFunction()
00516 {
00517
00518 }
00519
00520
00521
00522
00523
00524
00525 List<Expression> *
00526 JumpFunction::_const_param_values(const Map<Symbol,Expression> &const_map) const
00527 {
00528 List<Expression> *actuals = new List<Expression>;
00529 Iterator<Symbol> formal_iter = _param_list;
00530
00531 for ( ; formal_iter.valid(); ++formal_iter) {
00532 const Symbol &formal = formal_iter.current();
00533 const Expression *actual_expr = const_map.find_ref(formal);
00534
00535 if (actual_expr && actual_expr->type() == formal.type())
00536 actuals->ins_last(actual_expr->clone());
00537 else
00538 actuals->ins_last(omega());
00539 }
00540
00541 return actuals;
00542 }
00543
00544
00545
00546
00547
00548 static void
00549 _add_map_to_map(Map<Symbol,Expression> &dest_map,
00550 Map<Symbol,Expression> *source_map)
00551 {
00552 RefSet<Symbol> *mod_vars = modified_vars(*source_map);
00553 Iterator<Symbol> mod_var_iter = *mod_vars;
00554
00555 for ( ; mod_var_iter.valid(); ++mod_var_iter) {
00556 Symbol &var = mod_var_iter.current();
00557 dest_map.ins(var, source_map->grab(var));
00558 }
00559
00560 delete mod_vars;
00561 delete source_map;
00562 }
00563
00564
00565
00566
00567
00568
00569 static void
00570 _update_old_consts(Map<Symbol,Expression> &consts,
00571 Map<Symbol,Expression> *var_mods)
00572 {
00573
00574
00575 Map<Symbol,Expression> modified_consts;
00576 KeyIterator<Symbol,Expression> var_mod_iter = *var_mods;
00577
00578 for ( ; var_mod_iter.valid(); ++var_mod_iter) {
00579 const Symbol &var = var_mod_iter.current_key();
00580 const Expression *const_expr = consts.find_ref(var);
00581
00582 if (const_expr)
00583 modified_consts.ins(var, const_expr->clone());
00584 else
00585 modified_consts.ins(var, omega());
00586 }
00587
00588
00589
00590 _add_map_to_map(consts, var_mods);
00591
00592
00593
00594 subst_vars_in_map(consts, modified_consts);
00595
00596
00597
00598 _delete_non_consts(consts);
00599 }
00600
00601
00602
00603
00604 IPCPConstants *
00605 JumpFunction::constants(IPCPConstants &consts,
00606 const List<Expression> ¶m_values) const
00607 {
00608 AliasSets *alias_sets = new AliasSets(consts.alias_sets());
00609 alias_sets->alias(_param_list, param_values);
00610 List<Expression> *const_param_values
00611 = _const_param_values(consts.constants());
00612 Map<Symbol, Expression> *new_const_mods
00613 = const_mods(*const_param_values, *alias_sets);
00614 Map<Symbol, Expression> *updated_consts
00615 = new Map<Symbol,Expression>(consts.constants());
00616 _update_old_consts(*updated_consts, new_const_mods);
00617 Map<Symbol, Expression> *generated_consts
00618 = new_consts(*const_param_values, *alias_sets);
00619 delete const_param_values;
00620 _add_map_to_map(*updated_consts, generated_consts);
00621 _simplify_var_mods(*updated_consts);
00622
00623 return new IPCPConstants(updated_consts, alias_sets);
00624 }
00625
00626
00627
00628
00629 Listable *
00630 JumpFunction::listable_clone() const
00631 {
00632 return new JumpFunction(*this);
00633 }
00634
00635