00001
00002
00003
00004
00005 #include "Program.h"
00006 #include "SSAProgramUnit.h"
00007 #include "Statement/Statement.h"
00008 #include "Symbol/Symbol.h"
00009 #include "Symtab.h"
00010 #include "Expression/Expression.h"
00011 #include "utilities/expression_util.h"
00012 #include "Array.h"
00013 #include "IntSet.h"
00014 #include "Timer.h"
00015 #include "p-assert.h"
00016
00017 #include "SSAFullRangeDict.h"
00018 #include "SSAFullRangeData.h"
00019 #include "RangeExpr.h"
00020 #include "range_util.h"
00021 #include "range_dict_util.h"
00022 #include "stmt_toporder.h"
00023
00024 #include "SSAFullRangeData.cc"
00025
00026 #define min(x,y) ((x) < (y)) ? (x) : (y)
00027
00028 static int _debug_level = 0;
00029
00030
00031
00032 template class Array<SSAFullRangeData *>;
00033
00034
00035
00036
00037 SSAFullRangeDict::SSAFullRangeDict(SSAProgramUnit &pgm, int debug GIV(0))
00038 : RangeDict(pgm.symtab()), _control_ranges(pgm, debug - 20)
00039 {
00040 if (pgm.stmts().entries() == 0)
00041 return;
00042
00043 _debug_level = debug;
00044 _pgm_ref = &pgm;
00045 _num_poisoned_ranges = 0;
00046 _timestamp = 0;
00047 _stmt_toporder = stmt_toporder(pgm.stmts());
00048 remove_min_max_var_conflicts(pgm.symtab());
00049 }
00050
00051
00052
00053
00054 SSAFullRangeDict::~SSAFullRangeDict()
00055 {
00056 delete _stmt_toporder;
00057 }
00058
00059
00060
00061
00062 void
00063 SSAFullRangeDict::touch()
00064 {
00065 data_touch();
00066
00067 Iterator<Statement> stmt_iter = _pgm_ref->stmts().iterator();
00068
00069 for ( ; stmt_iter.valid(); ++stmt_iter) {
00070 const Statement &stmt = stmt_iter.current();
00071 const Statement &rep_stmt = _control_ranges.representative_stmt(stmt);
00072
00073 if (&stmt == &rep_stmt) {
00074 RefSet<Symbol> *vars = _control_ranges.range_vars(stmt);
00075 Iterator<Symbol> def_iter = *vars;
00076
00077 for ( ; def_iter.valid(); ++def_iter)
00078 _get_range_ref(def_iter.current(), stmt);
00079
00080 delete vars;
00081 }
00082 }
00083 }
00084
00085
00086
00087
00088 void
00089 SSAFullRangeDict::control_touch()
00090 {
00091 _control_ranges.touch();
00092 }
00093
00094
00095
00096
00097 void
00098 SSAFullRangeDict::data_touch()
00099 {
00100 KeyIterator<Symbol,Statement> def_iter = _pgm_ref->_def_map;
00101
00102 for ( ; def_iter.valid(); ++def_iter) {
00103 bool is_poisoned;
00104 const Symbol &var = def_iter.current_key();
00105
00106 if (var.type().data_type() == INTEGER_TYPE && ! var.is_array())
00107 _get_data_range_ref(var, is_poisoned);
00108 }
00109 }
00110
00111
00112
00113
00114 int
00115 SSAFullRangeDict::num_data_ranges() const
00116 {
00117 return _data_ranges.entries();
00118 }
00119
00120
00121
00122
00123 int
00124 SSAFullRangeDict::num_poisoned_ranges() const
00125 {
00126 return _num_poisoned_ranges;
00127 }
00128
00129
00130
00131
00132 void
00133 SSAFullRangeDict::_set_range(const Symbol &var,
00134 const Statement &stmt, Expression *range)
00135 {
00136 p_abort("Ranges cannot be modified in a SSAFullRangeDict object.");
00137 }
00138
00139
00140
00141
00142
00143 void
00144 SSAFullRangeDict::_del_range(const Symbol &var, const Statement &stmt)
00145 {
00146 p_abort("Ranges cannot be modified in a SSAFullRangeDict object.");
00147 }
00148
00149
00150
00151
00152
00153
00154 const Expression &
00155 SSAFullRangeDict::_ins_data_range(const Symbol &var,
00156 Expression *range)
00157 {
00158 if (! range)
00159 range = omega();
00160
00161 _data_ranges.ins(var, range);
00162
00163 if (_debug_level >= 10)
00164 cout << "! Inserted data range: " << var.name_ref()
00165 << " = " << *range << endl;
00166
00167 return *range;
00168 }
00169
00170
00171
00172
00173
00174 static bool
00175 _are_all_id_args(const Expression &expr)
00176 {
00177 Iterator<Expression> iter = expr.arg_list();
00178
00179 for ( ; iter.valid(); ++iter)
00180 if (iter.current().op() != ID_OP)
00181 return false;
00182
00183 return true;
00184 }
00185
00186
00187
00188
00189
00190 static void
00191 _init_data_preds(SSAFullRangeData &data)
00192 {
00193 const Statement *flow_join_stmt = &data.stmt();
00194
00195 while (flow_join_stmt
00196 && flow_join_stmt->pred().entries() == 1
00197 && flow_join_stmt->pred().member(*flow_join_stmt->prev_ref()))
00198 flow_join_stmt = flow_join_stmt->prev_ref();
00199
00200 p_assert(flow_join_stmt,
00201 "Couldn't find the control flow join statement for the given phi-statement.");
00202 const List<Expression> &phi_args = data.stmt().rhs().parameters_guarded().arg_list();
00203
00204
00205
00206 if (flow_join_stmt->pred().entries() == 0)
00207 return;
00208
00209 p_assert(flow_join_stmt->pred().entries() == phi_args.entries(),
00210 "There number of phi arguments and the number of flow predecessors differ.");
00211
00212 RefSet<Symbol> multiple_args;
00213 Iterator<Statement> pred_iter = flow_join_stmt->pred();
00214 int arg_num = 0;
00215
00216 for ( ; pred_iter.valid(); ++pred_iter, ++arg_num) {
00217 const Symbol &arg_var = phi_args[arg_num].symbol();
00218
00219 if (! multiple_args.member(CASTAWAY(Symbol &) arg_var))
00220 if (data.arg_preds.member(CASTAWAY(Symbol &) arg_var)) {
00221
00222
00223
00224 data.arg_preds.del(CASTAWAY(Symbol &) arg_var);
00225 multiple_args.ins(CASTAWAY(Symbol &) arg_var);
00226 }
00227 else
00228 data.arg_preds.ins(arg_var, pred_iter.current());
00229 }
00230 }
00231
00232
00233
00234
00235
00236 void
00237 SSAFullRangeDict::_order_args(SSAFullRangeData &data) const
00238 {
00239 RefList<Symbol> unordered_args = data.args;
00240 data.args.clear();
00241 Map<Symbol,IntElem> arg_order;
00242
00243 while (unordered_args.entries()) {
00244 Symbol &arg = unordered_args.grab(0);
00245 const Statement *def = _pgm_ref->_def_map.find_ref(arg);
00246 int order = -1;
00247
00248 if (def) {
00249 const IntElem *order_elem = _stmt_toporder->find_ref(def->tag());
00250
00251 if (order_elem)
00252 order = order_elem->value();
00253 }
00254
00255 Iterator<Symbol> iter = data.args;
00256 for ( ; iter.valid() && order > arg_order[iter.current()]; ++iter);
00257
00258 if (iter.valid())
00259 data.args.ins_before(arg, iter.current());
00260 else
00261 data.args.ins_last(arg);
00262
00263 arg_order.ins(arg, new IntElem(order));
00264 }
00265 }
00266
00267
00268
00269
00270
00271
00272 SSAFullRangeData *
00273 SSAFullRangeDict::_create_data(const Statement &stmt, int &df_num,
00274 RefList<SSAFullRangeData> &scc_node_stack)
00275 {
00276 SSAFullRangeData *data = new SSAFullRangeData(stmt, _timestamp, *this,
00277 _debug_level);
00278
00279
00280
00281 data->union_arg_ranges = true;
00282
00283 if (data->is_phi_stmt
00284 && ! _are_all_id_args(stmt.rhs().parameters_guarded())) {
00285
00286 if (_debug_level >= 20) {
00287 cout << "! Couldn't create SSAFullRangeData object for definition: ";
00288 int zero = 0;
00289 stmt.write(cout, zero);
00290 }
00291
00292 delete data;
00293 return 0;
00294 }
00295
00296 if (data->is_phi_stmt)
00297 _init_data_preds(*data);
00298
00299 _pending_ranges.ins(stmt.lhs().symbol(), data);
00300 ++df_num;
00301 data->df_order = df_num;
00302 data->low_link = df_num;
00303 scc_node_stack.ins_first(*data);
00304
00305
00306
00307
00308 Iterator<Expression> use_iter = stmt.in_refs();
00309
00310 for ( ; use_iter.valid(); ++use_iter) {
00311 const Symbol *var = use_iter.current().base_variable_ref();
00312
00313 if (! data->args.member(* CASTAWAY(Symbol *) var))
00314 data->args.ins_last(* CASTAWAY(Symbol *) var);
00315
00316 SSARangeOrData *link;
00317
00318 if (! var
00319 || var->is_array()
00320 || var->type().data_type() != INTEGER_TYPE)
00321
00322 link = new SSARangeOrData(0);
00323 else
00324 link = new SSARangeOrData(_probe_data_ranges(*var, df_num,
00325 scc_node_stack));
00326
00327 data->arg_ranges_or_data.ins(*var, link);
00328
00329 if (link->is_data() && link->data().timestamp() == _timestamp) {
00330 data->needs_iteration = true;
00331
00332 if (scc_node_stack.member(link->data()))
00333 if (data->df_order < link->data().df_order)
00334 data->low_link = min(data->low_link, link->data().low_link);
00335 else
00336 data->low_link = min(data->low_link, link->data().df_order);
00337 }
00338 }
00339
00340 if (data->needs_iteration) {
00341 if (data->is_phi_stmt)
00342 _order_args(*data);
00343
00344
00345
00346
00347 RefSet<SSAFullRangeData> *succs = data->succs();
00348 Iterator<SSAFullRangeData> succ_iter = *succs;
00349
00350 for ( ; succ_iter.valid(); ++succ_iter)
00351 succ_iter.current().users.ins(*data);
00352 }
00353
00354 return data;
00355 }
00356
00357
00358
00359
00360
00361
00362 void
00363 SSAFullRangeDict::_mark_data_as_computed(SSAFullRangeData &data)
00364 {
00365 const Symbol &var = data.stmt().lhs().symbol();
00366
00367 if (! data.computed) {
00368 p_assert(data.is_poisoned && data.timestamp() != _timestamp,
00369 "Non-poisoned data cannot be marked as computed.");
00370 data.computed = true;
00371 RefSet<SSAFullRangeData> *succs = data.succs();
00372 Iterator<SSAFullRangeData> iter = *succs;
00373
00374 for ( ; iter.valid(); ++iter)
00375 _mark_data_as_computed(iter.current());
00376
00377 delete succs;
00378 }
00379 }
00380
00381
00382
00383
00384
00385
00386
00387 void
00388 SSAFullRangeDict::_commit_data(SSAFullRangeData &data)
00389 {
00390 p_assert(! data.is_poisoned && data.timestamp() == _timestamp,
00391 "Poisoned data cannot be committed.");
00392 const Symbol &var = data.stmt().lhs().symbol();
00393
00394 if (! _data_ranges.member(var)) {
00395 _ins_data_range(var, data.grab_range());
00396 data.computed = true;
00397 RefSet<SSAFullRangeData> *succs = data.succs();
00398 Iterator<SSAFullRangeData> iter = *succs;
00399
00400 for ( ; iter.valid(); ++iter)
00401 _commit_data(iter.current());
00402
00403 delete succs;
00404 }
00405 }
00406
00407
00408
00409
00410
00411 void
00412 SSAFullRangeDict::_delete_data(SSAFullRangeData &data)
00413 {
00414 if (data.timestamp() == _timestamp) {
00415 Symbol & temp = CASTAWAY(Symbol &) data.stmt().lhs().symbol();
00416 SSAFullRangeData *my_data = _pending_ranges.grab(temp);
00417 p_assert(my_data, "Tried to delete an already deleted SSAFullRangeData object.");
00418 KeyIterator<Symbol,SSARangeOrData> iter = data.arg_ranges_or_data;
00419
00420 for ( ; iter.valid(); ++iter)
00421 if (_pending_ranges.member(iter.current_key())
00422 && iter.current_data().is_data())
00423
00424 _delete_data(iter.current_data().data());
00425
00426 delete my_data;
00427 }
00428 }
00429
00430
00431
00432
00433
00434
00435 static void
00436 _add_leaf_nodes_to_set(const Array<SSAFullRangeData *> &iter_order,
00437 IntSet &start_nodes)
00438 {
00439 for (int i = 0; i < iter_order.entries(); ++i) {
00440 const SSAFullRangeData &data = *iter_order[i];
00441 bool smaller_than_args = true;
00442 RefSet<SSAFullRangeData> *succs = data.succs();
00443 Iterator<SSAFullRangeData> succ_iter = *succs;
00444
00445 for ( ; succ_iter.valid() && smaller_than_args; ++succ_iter) {
00446 SSAFullRangeData &succ_data = succ_iter.current();
00447
00448 if (succ_data.needs_iteration
00449 && succ_data.toporder < data.toporder)
00450
00451 smaller_than_args = false;
00452 }
00453
00454 delete succs;
00455
00456 if (smaller_than_args)
00457 start_nodes.ins(data.toporder);
00458 }
00459 }
00460
00461
00462
00463
00464
00465 static void
00466 _add_phi_nodes_to_set(const Array<SSAFullRangeData *> &iter_order,
00467 IntSet &phi_nodes)
00468 {
00469 for (int i = 0; i < iter_order.entries(); ++i) {
00470 const SSAFullRangeData &data = *iter_order[i];
00471
00472 if (data.is_phi_stmt)
00473 phi_nodes.ins(data.toporder);
00474 }
00475 }
00476
00477
00478
00479
00480
00481
00482
00483
00484 void
00485 SSAFullRangeDict::_calc_iter_order1(SSAFullRangeData &data,
00486 RefList<SSAFullRangeData> &iter_order_list)
00487 {
00488 if (data.toporder < 0) {
00489 const IntElem *toporder_elem = _stmt_toporder->find_ref(data.stmt().tag());
00490 p_assert(toporder_elem,
00491 "Statement was not assigned a topological ordering value.");
00492 int to = toporder_elem->value();
00493 p_assert(to >= 0,
00494 "Statement has a negative topological ordering value.");
00495 data.toporder = to;
00496
00497
00498
00499 Iterator<SSAFullRangeData> order_iter = iter_order_list;
00500
00501 for ( ; order_iter.valid() && to > order_iter.current().toporder;
00502 ++order_iter);
00503
00504 p_assert(! order_iter.valid() || to < order_iter.current().toporder,
00505 "Internal error: SSAFullRangeData object was inserted twice in iter_order.");
00506
00507 if (order_iter.valid())
00508 iter_order_list.ins_before(data, order_iter.current());
00509 else
00510 iter_order_list.ins_last(data);
00511
00512
00513
00514 RefSet<SSAFullRangeData> *succs = data.succs();
00515 Iterator<SSAFullRangeData> succ_iter = *succs;
00516
00517 for ( ; succ_iter.valid(); ++succ_iter)
00518 _calc_iter_order1(succ_iter.current(), iter_order_list);
00519 }
00520 }
00521
00522
00523 Array<SSAFullRangeData *> *
00524 SSAFullRangeDict::_calc_iter_order(SSAFullRangeData &root_node)
00525 {
00526 RefList<SSAFullRangeData> iter_order_list;
00527 _calc_iter_order1(root_node, iter_order_list);
00528
00529 Array<SSAFullRangeData *> *iter_order = new Array<SSAFullRangeData *>(iter_order_list.entries());
00530
00531 for (int i = 0; i < iter_order->entries(); ++i) {
00532 (*iter_order)[i] = &iter_order_list.grab(0);
00533 (*iter_order)[i]->toporder = i;
00534 }
00535
00536 p_assert(iter_order_list.entries() == 0,
00537 "Internal Error: not all SSAFullRangeData objects were places in iter_order.");
00538 return iter_order;
00539 }
00540
00541
00542
00543
00544
00545
00546 void
00547 SSAFullRangeDict::_iterate_to_fixed_point_phase(const Array<SSAFullRangeData *> &rtoporder_to_stmt,
00548 const IntSet &start_stmts,
00549 bool widening_phase)
00550 {
00551 IntSet work_list(start_stmts);
00552
00553
00554
00555
00556 while (work_list.entries() > 0) {
00557 for (int data_num = work_list.first();
00558 data_num != -1;
00559 data_num = work_list.next(data_num)) {
00560
00561 SSAFullRangeData &data = *rtoporder_to_stmt[data_num];
00562 work_list.del(data_num);
00563
00564 if (data.update(widening_phase)) {
00565 Iterator<SSAFullRangeData> user_iter = data.users;
00566
00567 for ( ; user_iter.valid(); ++user_iter)
00568 work_list.ins(user_iter.current().toporder);
00569 }
00570 }
00571 }
00572 }
00573
00574
00575
00576
00577
00578
00579 void
00580 SSAFullRangeDict::_iterate_to_fixed_point(SSAFullRangeData &root_node)
00581 {
00582
00583
00584 Array<SSAFullRangeData *> *iter_order = _calc_iter_order(root_node);
00585
00586
00587
00588
00589
00590
00591
00592 if (_debug_level >= 20)
00593 cout << "\nWidening Phase:\n";
00594
00595 IntSet start_nodes(iter_order->entries());
00596 _add_phi_nodes_to_set(*iter_order, start_nodes);
00597
00598
00599 for (int data_num = start_nodes.first();
00600 data_num != -1;
00601 data_num = start_nodes.next(data_num))
00602 (* iter_order)[data_num]->needs_widening = true;
00603
00604 _iterate_to_fixed_point_phase(*iter_order, start_nodes, true);
00605
00606
00607
00608
00609
00610
00611
00612 if (_debug_level >= 20)
00613 cout << "\nNarrowing Phase:\n";
00614
00615 IntSet phi_nodes(iter_order->entries());
00616 _add_phi_nodes_to_set(*iter_order, phi_nodes);
00617
00618 _iterate_to_fixed_point_phase(*iter_order, phi_nodes, false);
00619
00620 delete iter_order;
00621 }
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632 SSARangeOrData
00633 SSAFullRangeDict::_probe_data_ranges(const Symbol &var, int &df_num,
00634 RefList<SSAFullRangeData> &scc_node_stack)
00635 {
00636 const Expression *range = _data_ranges.find_ref(var);
00637
00638 if (range) {
00639
00640
00641 return SSARangeOrData(range);
00642 }
00643 else {
00644 const Statement *def = _pgm_ref->_def_map.find_ref(var);
00645
00646 if (! def
00647 || def->stmt_class() != ASSIGNMENT_STMT
00648 || def->rhs().type().data_type() != INTEGER_TYPE
00649 || contains_func_call(*def)) {
00650
00651
00652
00653
00654 if (_debug_level >= 20) {
00655 if (def) {
00656 cout << "! Unknown statement type for definition: ";
00657 int zero = 0;
00658 def->write(cout, zero);
00659 }
00660 else
00661 cout << "! No definition for variable "
00662 << var.name_ref() << endl;
00663 }
00664
00665 return SSARangeOrData(&_ins_data_range(var, 0));
00666 }
00667 else {
00668
00669
00670
00671
00672 SSAFullRangeData *data = _pending_ranges.find_ref(var);
00673
00674 if (data) {
00675
00676
00677
00678 return SSARangeOrData(*data);
00679 }
00680 else {
00681
00682
00683 data = _create_data(*def, df_num, scc_node_stack);
00684
00685 if (! data)
00686 return SSARangeOrData(&_ins_data_range(var, 0));
00687 else {
00688 if (data->needs_iteration) {
00689
00690
00691
00692 if (data->df_order != data->low_link) {
00693
00694
00695
00696
00697
00698 return SSARangeOrData(*data);
00699 }
00700 else {
00701
00702
00703
00704 _iterate_to_fixed_point(*data);
00705
00706 while (scc_node_stack.entries()
00707 && scc_node_stack[0].df_order >= data->df_order)
00708 scc_node_stack.del(0);
00709
00710 if (data->is_poisoned) {
00711 _mark_data_as_computed(*data);
00712 return SSARangeOrData(*data);
00713 }
00714 else {
00715 _commit_data(*data);
00716 const Expression *range = _data_ranges.find_ref(var);
00717 p_assert(range, "_commit_data() did not commit my range.");
00718 _delete_data(*data);
00719 return SSARangeOrData(range);
00720 }
00721 }
00722 }
00723 else {
00724 data->update();
00725 data->computed = true;
00726 p_assert(scc_node_stack.entries() > 0
00727 && &scc_node_stack[0] == data,
00728 "Some nodes were missed by SCC algorithm.");
00729 scc_node_stack.del(0);
00730
00731 if (data->is_poisoned) {
00732
00733
00734
00735
00736 return SSARangeOrData(*data);
00737 }
00738 else {
00739
00740
00741
00742
00743 SSARangeOrData result(&_ins_data_range(var, data->grab_range()));
00744 Symbol & temp = CASTAWAY(Symbol &)data->stmt().lhs().symbol();
00745 _pending_ranges.del(temp);
00746 return result;
00747 }
00748 }
00749 }
00750 }
00751 }
00752 }
00753 }
00754
00755
00756
00757
00758
00759
00760 const Expression *
00761 SSAFullRangeDict::_get_data_range_ref(const Symbol &var, bool &is_poisoned)
00762 {
00763 is_poisoned = false;
00764
00765 if (var.is_array() || var.type().data_type() != INTEGER_TYPE)
00766 return 0;
00767
00768 ++_timestamp;
00769 int orig_num_pending_ranges = _pending_ranges.entries();
00770 int df_num = 0;
00771 RefList<SSAFullRangeData> scc_node_stack;
00772 SSARangeOrData range_or_data = _probe_data_ranges(var, df_num,
00773 scc_node_stack);
00774 p_assert(scc_node_stack.entries() == 0,
00775 "Some nodes were missed by SCC algorithm.");
00776 const Expression *range;
00777
00778 if (range_or_data.is_range())
00779 range = range_or_data.range_ref();
00780 else {
00781 SSAFullRangeData &data = range_or_data.data();
00782
00783 p_assert(data.is_poisoned || data.timestamp() != _timestamp,
00784 "Unpoisoned SSAFullRangeData object returned by _probe_data_ranges().");
00785
00786 if (data.range_ref()) {
00787 range = &_poisoned_ranges.ins(data.range_ref()->clone());
00788 ++_num_poisoned_ranges;
00789 }
00790 else
00791 range = 0;
00792
00793 is_poisoned = true;
00794
00795 if (_debug_level >= 20) {
00796 cout << "! Computed data range is poisoned: ";
00797 cout << var.name_ref() << " = ";
00798
00799 if (range)
00800 cout << *range;
00801 else
00802 cout << "NULL";
00803
00804 cout << endl;
00805 }
00806
00807 p_assert(_timestamp > 1, "A base data range was poisoned.");
00808
00809 _delete_data(data);
00810 }
00811
00812 p_assert(_pending_ranges.entries() == orig_num_pending_ranges,
00813 "Method SSAFullRangeDict::_get_data_range_ref() did not discard all of its temporary data structures.");
00814 --_timestamp;
00815
00816 return range;
00817 }
00818
00819
00820
00821
00822 const Expression *
00823 SSAFullRangeDict::_get_range_ref(const Symbol &var, const Statement &stmt)
00824 {
00825 if (var.is_array() || var.type().data_type() != INTEGER_TYPE)
00826 return 0;
00827
00828 if (_timestamp == 0)
00829 _num_poisoned_ranges = 0;
00830
00831 const Statement &rep_stmt = _control_ranges.representative_stmt(stmt);
00832 RefMap<Symbol, Expression> *stmt_ranges = _pgm_ranges.find_ref(rep_stmt);
00833 const Expression *range;
00834
00835 if (stmt_ranges)
00836 range = stmt_ranges->find_ref(var);
00837 else
00838 range = 0;
00839
00840 if (! range) {
00841
00842
00843 bool is_poisoned = false;
00844 const Expression *data_range_ref = _get_data_range_ref(var, is_poisoned);
00845 RangeAccessor control_accessor(_control_ranges, rep_stmt);
00846 const Expression *control_range_ref
00847 = control_accessor.get_range_ref(var);
00848
00849 if (data_range_ref && data_range_ref->op() != OMEGA_OP) {
00850 if (control_range_ref && control_range_ref->op() != OMEGA_OP) {
00851 if (! stmt_ranges) {
00852 stmt_ranges = new RefMap<Symbol, Expression>;
00853 _pgm_ranges.ins(rep_stmt, stmt_ranges);
00854 }
00855
00856 stmt_ranges->ins(var, *control_range_ref);
00857 RangeAccessor accessor(*this, rep_stmt);
00858 Expression *new_range = intersect_ranges(data_range_ref,
00859 accessor,
00860 control_range_ref,
00861 accessor);
00862
00863 if (! new_range)
00864 new_range = omega();
00865
00866 if (is_poisoned) {
00867 range = &_poisoned_ranges.ins(new_range);
00868
00869 stmt_ranges->del(CASTAWAY(Symbol &) var);
00870 }
00871 else {
00872 range = &_range_values.ins(new_range);
00873 stmt_ranges->ins(var, *range);
00874 }
00875 }
00876 else
00877 range = data_range_ref;
00878 }
00879 else if (control_range_ref && control_range_ref->op() != OMEGA_OP)
00880 range = control_range_ref;
00881 else
00882 range = 0;
00883 }
00884
00885 if (range && range->op() == OMEGA_OP)
00886 range = 0;
00887
00888 if (_timestamp == 0)
00889 _poisoned_ranges.clear();
00890
00891 return range;
00892 }
00893
00894
00895
00896
00897 void
00898 SSAFullRangeDict::clear()
00899 {
00900 _control_ranges.clear();
00901 _data_ranges.clear();
00902 _pgm_ranges.clear();
00903 _pending_ranges.clear();
00904 _range_values.clear();
00905 _poisoned_ranges.clear();
00906 _timestamp = 0;
00907 _num_poisoned_ranges = 0;
00908 }
00909
00910
00911
00912
00913 void
00914 SSAFullRangeDict::clear_ranges()
00915 {
00916 _control_ranges.clear_ranges();
00917
00918 _data_ranges.clear();
00919 _pgm_ranges.clear();
00920 _pending_ranges.clear();
00921 _range_values.clear();
00922 _poisoned_ranges.clear();
00923 _timestamp = 0;
00924 _num_poisoned_ranges = 0;
00925 }
00926
00927
00928
00929
00930 SSAControlRangeDict &
00931 SSAFullRangeDict::control_range_dict()
00932 {
00933 return _control_ranges;
00934 }
00935
00936
00937
00938
00939 void
00940 SSAFullRangeDict::print(ostream & o) const
00941 {
00942 o << "[";
00943 o << "pgm_ranges={";
00944
00945 KeyIterator<Statement, RefMap<Symbol, Expression> > pgm_range_iter = _pgm_ranges;
00946 bool first_stmt = true;
00947
00948 for ( ; pgm_range_iter.valid(); ++pgm_range_iter) {
00949 if (! first_stmt)
00950 o << ", ";
00951 else
00952 first_stmt = false;
00953
00954 o << pgm_range_iter.current_key().tag() << ": {";
00955
00956 KeyIterator<Symbol, Expression> stmt_range_iter = pgm_range_iter.current_data();
00957 bool first_symbol = true;
00958
00959 for ( ; stmt_range_iter.valid(); ++stmt_range_iter) {
00960 if (! first_symbol)
00961 o << ", ";
00962 else
00963 first_symbol = false;
00964
00965 o << stmt_range_iter.current_key().name_ref()
00966 << ": " << stmt_range_iter.current_data();
00967 }
00968
00969 o << "}";
00970 }
00971
00972 o << "}";
00973
00974 o << ", data_ranges={";
00975
00976 KeyIterator<Symbol, Expression> data_range_iter = _data_ranges;
00977 bool first_symbol = true;
00978
00979 for ( ; data_range_iter.valid(); ++data_range_iter) {
00980 if (! first_symbol)
00981 o << ", ";
00982 else
00983 first_symbol = false;
00984
00985 o << data_range_iter.current_key().name_ref()
00986 << ": " << data_range_iter.current_data();
00987 }
00988
00989 o << "}";
00990 o << ", pending_ranges={";
00991
00992 KeyIterator<Symbol, SSAFullRangeData> pend_iter = _pending_ranges;
00993 first_symbol = true;
00994
00995 for ( ; pend_iter.valid(); ++pend_iter) {
00996 if (! first_symbol)
00997 o << ", ";
00998 else
00999 first_symbol = false;
01000
01001 o << pend_iter.current_key().name_ref()
01002 << ": " << pend_iter.current_data();
01003 }
01004
01005 o << "}";
01006 o << ", timestamp=" << _timestamp;
01007 o << "]";
01008 }
01009
01010
01011
01012
01013 void
01014 SSAFullRangeDict::pretty_print(ostream & o, const Statement &stmt) const
01015 {
01016 o << "[";
01017 o << "control ranges = ";
01018 _control_ranges.pretty_print(o, stmt);
01019 o << ", data ranges = {";
01020
01021 RefList<Symbol> sorted_keys;
01022 KeyIterator<Symbol,Expression> data_iter = _data_ranges;
01023
01024 for ( ; data_iter.valid(); ++data_iter)
01025 sorted_keys.ins_last(data_iter.current_key());
01026
01027 sort_sym_list(sorted_keys);
01028
01029 Iterator<Symbol> key_iter = sorted_keys;
01030 bool first = true;
01031 bool need_comma = true;
01032
01033 for ( ; key_iter.valid(); ++key_iter) {
01034 if (! first && need_comma)
01035 o << ", ";
01036 else
01037 first = false;
01038
01039 const Symbol &var = key_iter.current();
01040 const Expression *value = _data_ranges.find_ref(var);
01041
01042 if (value->op() != OMEGA_OP || _debug_level >= 30) {
01043 pretty_print_range(o, *value, var);
01044 need_comma = true;
01045 }
01046 else
01047 need_comma = false;
01048 }
01049
01050 o << "}";
01051 o << ", merged ranges = {";
01052
01053 const RefMap<Symbol,Expression> *stmt_ranges = _pgm_ranges.find_ref(stmt);
01054
01055 if (stmt_ranges) {
01056 sorted_keys.clear();
01057 KeyIterator<Symbol,Expression> merged_iter = *stmt_ranges;
01058
01059 for ( ; merged_iter.valid(); ++merged_iter)
01060 sorted_keys.ins_last(merged_iter.current_key());
01061
01062 sort_sym_list(sorted_keys);
01063 first = true;
01064 need_comma = true;
01065
01066 for (key_iter.reset(); key_iter.valid(); ++key_iter) {
01067 if (! first && need_comma)
01068 o << ", ";
01069 else
01070 first = false;
01071
01072 const Symbol &var = key_iter.current();
01073 const Expression *value = stmt_ranges->find_ref(var);
01074
01075 if (value->op() != OMEGA_OP || _debug_level >= 30) {
01076 pretty_print_range(o, *value, var);
01077 need_comma = true;
01078 }
01079 else
01080 need_comma = false;
01081 }
01082 }
01083
01084 o << "}";
01085 o << "]";
01086 }
01087
01088
01089
01090
01091 Listable *
01092 SSAFullRangeDict::listable_clone(void) const
01093 {
01094 p_abort("SSAFullRangeDicts cannot be duplicated.");
01095 return 0;
01096 }
01097
01098
01099
01100
01101
01102 int
01103 SSAFullRangeDict::structures_OK() const
01104 {
01105 return 1;
01106 }