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