00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "c_breeze.h"
00039 #include "location.h"
00040 #include <limits>
00041
00042
00043
00044
00045
00046 unsigned int Location::stmt_count = 0;
00047 unsigned int Location::block_count = 0;
00048 unsigned int Location::proc_count = 0;
00049 unsigned int Location::dom_calls = 0;
00050
00051 unsigned int Location::current_subtree_id = 0;
00052 unsigned int Location::current_tree_number = 0;
00053
00054 Location::Location(Location * parent, LocationKind kind)
00055 : _parent(parent),
00056 _kind(kind),
00057 _num_children(0),
00058 _dominator(0),
00059 _tree_min(0),
00060 _tree_max(numeric_limits<unsigned int>::max())
00061 {
00062
00063 #ifdef OLD_DOMINATOR_TEST
00064
00065 _depth = parent ? parent->depth() + 1 : 0;
00066 _dominates_exit = 0;
00067 _not_basicblock = (kind != BasicBlock);
00068 _not_procedure = (kind != Procedure);
00069
00070 #endif
00071
00072 if (parent)
00073 _subtree_id = parent->subtree_id();
00074 }
00075
00076 void Location::set_dominator(Location * d)
00077 {
00078
00079
00080 _dominator = d;
00081
00082
00083
00084 d->increment_children();
00085 }
00086
00087 void Location::clear_dominator()
00088 {
00089
00090
00091 _dominator->decrement_children();
00092
00093
00094
00095 _dominator = 0;
00096 }
00097
00098
00099
00100
00101 bool Location::strictly_dominates(const Location * dom, const Location * cur)
00102 {
00103
00104
00105 if (dom == cur)
00106 return false;
00107
00108
00109
00110
00111 if (dom->subtree_id() != cur->subtree_id())
00112 return false;
00113
00114 #ifdef OLD_DOMINATOR_TEST
00115
00116 bool old_dominates = old_strictly_dominates(dom, cur);
00117
00118 #endif
00119
00120 dom_calls++;
00121
00122 bool new_dominates = false;
00123
00124 unsigned int dom_min = dom->tree_min();
00125 unsigned int cur_min = cur->tree_min();
00126 unsigned int dom_max = dom->tree_max();
00127 unsigned int cur_max = cur->tree_max();
00128
00129
00130
00131
00132 if ((dom_min < cur_min) && (cur_max <= dom_max))
00133 new_dominates = true;
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 #ifdef OLD_DOMINATOR_TEST
00148
00149 if (new_dominates != old_dominates) {
00150 cout << "TEST FAILED for "
00151 << * dom << "(" << dom->tree_min() << " - " << dom->tree_max() << ")" << endl;
00152
00153 if (old_dominates)
00154 cout << " DOM " << endl;
00155 else
00156 cout << " NOT DOM " << endl;
00157
00158 cout << " " << * cur << "(" << cur->tree_min() << " - " << cur->tree_max() << ")" << endl;
00159 }
00160
00161 #endif
00162
00163 return new_dominates;
00164 }
00165
00166 #ifdef OLD_DOMINATOR_TEST
00167
00168 bool Location::old_strictly_dominates(const Location * dom, const Location * cur)
00169 {
00170
00171
00172 if (dom == cur)
00173 return false;
00174
00175
00176
00177
00178 if (dom->subtree_id() != cur->subtree_id())
00179 return false;
00180
00181
00182
00183 if (dom == procLocation::main())
00184 return true;
00185
00186 if (cur == procLocation::main())
00187 return false;
00188
00189 dom_calls++;
00190
00191
00192
00193
00194 const Location * dom_p = dom;
00195 const Location * cur_p = cur;
00196
00197 unsigned int depth_dom = dom_p->depth();
00198 unsigned int depth_cur = cur_p->depth();
00199 unsigned int max_depth = (depth_dom > depth_cur) ? depth_dom : depth_cur;
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 unsigned int dom_exit = 1;
00218 unsigned int local_dom_exit = 0;
00219 unsigned int not_procedure_boundary = 1;
00220
00221 while ((depth_dom > depth_cur) & dom_exit) {
00222
00223
00224
00225 local_dom_exit &= dom_p->_not_basicblock;
00226
00227
00228
00229
00230
00231 local_dom_exit |= dom_p->dominates_exit();
00232
00233
00234
00235
00236
00237
00238 not_procedure_boundary &= dom_p->_not_procedure;
00239
00240
00241
00242
00243
00244 dom_exit &= (local_dom_exit | not_procedure_boundary );
00245
00246
00247
00248 dom_p = dom_p->parent();
00249 depth_dom--;
00250 }
00251
00252
00253
00254
00255
00256 if ( ! dom_exit )
00257 return false;
00258
00259 while (depth_cur > depth_dom) {
00260 cur_p = cur_p->parent();
00261 depth_cur--;
00262 }
00263
00264
00265
00266
00267 if (dom_p == cur_p) {
00268 if (dom->depth() > cur->depth()) {
00269
00270
00271
00272 return (cur->kind() == Statement);
00273 }
00274 else {
00275
00276
00277
00278 return (dom->kind() != Statement);
00279 }
00280 }
00281
00282
00283
00284 const Location * dom_next = dom_p->parent();
00285 const Location * cur_next = cur_p->parent();
00286
00287 while ((dom_next != cur_next) & dom_exit) {
00288
00289
00290
00291
00292 local_dom_exit &= dom_p->_not_basicblock;
00293 local_dom_exit |= dom_p->dominates_exit();
00294 not_procedure_boundary &= dom_p->_not_procedure;
00295 dom_exit &= (local_dom_exit | not_procedure_boundary );
00296
00297
00298
00299 dom_p = dom_next;
00300 dom_next = dom_p->parent();
00301
00302 cur_p = cur_next;
00303 cur_next = cur_p->parent();
00304 }
00305
00306
00307
00308 if ( ! dom_exit )
00309 return false;
00310
00311
00312
00313 if (dom_p->kind() == Statement) {
00314 stmtLocation * dom_s = (stmtLocation *) dom_p;
00315 stmtLocation * cur_s = (stmtLocation *) cur_p;
00316
00317 return (dom_s->stmt_num() < cur_s->stmt_num());
00318 }
00319
00320 if (dom_p->kind() == BasicBlock) {
00321 basicblockLocation * dom_b = (basicblockLocation *) dom_p;
00322 basicblockLocation * cur_b = (basicblockLocation *) cur_p;
00323
00324 return Dominators::dominates(dom_b->block(), cur_b->block());
00325 }
00326
00327
00328
00329
00330
00331 return false;
00332
00333 cerr << "ERROR: Cannot determine path dominance." << endl;
00334 cerr << " Dom : " << *dom << " depth = " << dom->depth() << endl;
00335 if (dom_p)
00336 cerr << " DomP : " << *dom_p << " depth = " << dom_p->depth() << endl;
00337 cerr << " Cur : " << *cur << " depth = " << cur->depth() << endl;
00338 if (cur_p)
00339 cerr << " CurP : " << *cur_p << " depth = " << cur_p->depth() << endl;
00340
00341 return false;
00342 }
00343
00344 Location * Location::common_parent(Location * one,
00345 Location * two)
00346 {
00347 if (one == two)
00348 return one;
00349
00350
00351
00352
00353 Location * one_p = one;
00354 Location * two_p = two;
00355
00356 unsigned int depth_one = one_p->depth();
00357 unsigned int depth_two = two_p->depth();
00358 unsigned int max_depth = (depth_one > depth_two) ? depth_one : depth_two;
00359
00360 while (depth_one > depth_two) {
00361 one_p = one_p->parent();
00362 depth_one--;
00363 }
00364
00365 while (depth_two > depth_one) {
00366 two_p = two_p->parent();
00367 depth_two--;
00368 }
00369
00370
00371
00372 if (one_p == two_p)
00373 return one_p;
00374
00375
00376
00377 Location * one_next = one_p->parent();
00378 Location * two_next = two_p->parent();
00379
00380 while (one_next != two_next) {
00381
00382 one_p = one_next;
00383 one_next = one_p->parent();
00384
00385 two_p = two_next;
00386 two_next = two_p->parent();
00387 }
00388
00389 return one_p;
00390 }
00391
00392 #endif
00393
00394
00395 procLocation * Location::procedure(Location * where)
00396 {
00397 if (where->kind() == Procedure)
00398 return (procLocation *) where;
00399
00400 if (where->kind() == Statement) {
00401 stmtLocation * stmt = (stmtLocation *) where;
00402 return stmt->block_location()->proc_location();
00403 }
00404
00405 if (where->kind() == BasicBlock) {
00406 basicblockLocation * block = (basicblockLocation *) where;
00407 return block->proc_location();
00408 }
00409
00410 return 0;
00411 }
00412
00413 bool Location::is_prefix(const Location * prefix, const Location * longer)
00414 {
00415 while (longer) {
00416 if (longer == prefix)
00417 return true;
00418 longer = longer->parent();
00419 }
00420
00421 return false;
00422 }
00423
00424 void Location::stats()
00425 {
00426 cout << " stmtLocation : " << stmt_count << " objects x "
00427 << sizeof(stmtLocation) << " bytes = " << stmt_count * sizeof(stmtLocation)
00428 << " bytes. " << endl;
00429
00430 cout << " basicblockLocation : " << block_count << " objects x "
00431 << sizeof(basicblockLocation) << " bytes = " << block_count * sizeof(basicblockLocation)
00432 << " bytes. " << endl;
00433
00434 cout << " procLocation : " << proc_count << " objects x "
00435 << sizeof(procLocation) << " bytes = " << proc_count * sizeof(procLocation)
00436 << " bytes. " << endl;
00437
00438 }
00439
00440
00441 bool Location::dominates(const Location * dom, const Location * cur)
00442 {
00443 if (dom == cur)
00444 return true;
00445
00446 return strictly_dominates(dom, cur);
00447 }
00448
00449 Location::~Location()
00450 {
00451 }
00452
00453
00454
00455
00456
00457 void Location::visit()
00458 {
00459 if (tree_min() == 0) {
00460
00461 set_tree_min(next_tree_number());
00462
00463
00464
00465
00466
00467
00468
00469
00470 }
00471 }
00472
00473
00474 void Location::finish()
00475 {
00476 if ((tree_max() == numeric_limits<unsigned int>::max()) &&
00477 (num_children() == 0))
00478 {
00479
00480
00481 unsigned int cur_max = tree_min();
00482 Location * cur_node = this;
00483 Location * cur_dom;
00484
00485 do {
00486 cur_node->set_tree_max(next_tree_number());
00487 cur_dom = cur_node->dominator();
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497 cur_node = cur_dom;
00498
00499 if (cur_node)
00500 cur_node->decrement_children();
00501
00502 } while (cur_node &&
00503 (cur_node->num_children() == 0));
00504 }
00505 }
00506
00507
00508
00509
00510
00511 stmtLocation::stmtLocation(basicblockLocation * parent)
00512 : Location(parent, Statement),
00513 _stmt_num(0),
00514 _calls(0)
00515 {
00516 Location::stmt_count++;
00517 }
00518
00519
00520
00521
00522 void stmtLocation::setup_cs_call(procNode * proc)
00523 {
00524 if(_calls && _calls->proc() != proc) {
00525 _calls = _all_calls[proc];
00526 }
00527
00528 if (! _calls) {
00529 _calls = _all_calls[proc] = new procLocation(this, proc, false);
00530
00531
00532
00533 _calls->visit();
00534
00535
00536
00537
00538 _calls->set_dominator(dominator());
00539 clear_dominator();
00540
00541
00542
00543 set_tree_min(0);
00544
00545
00546
00547
00548
00549
00550 set_dominator(_calls->last());
00551 }
00552 }
00553
00559 procLocation * stmtLocation::remove_call()
00560 {
00561 procLocation * out = 0;
00562
00563 if (_calls) {
00564
00565
00566
00567 out = _calls;
00568 out->remove_from_tree();
00569 _calls = 0;
00570
00571
00572
00573 set_dominator(out->dominator());
00574 out->clear_dominator();
00575
00576
00577
00578
00579 visit();
00580 }
00581
00582 return out;
00583 }
00584
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616 bool stmtLocation::is_present(const procNode * proc) const
00617 {
00618 const procLocation * procl = block_location()->proc_location();
00619 if (procl->proc() == proc)
00620 return true;
00621
00622 if (procl->stmt_location())
00623 return procl->stmt_location()->is_present(proc);
00624
00625 return false;
00626 }
00627
00628 void stmtLocation::adjust_depth()
00629 {
00630 #ifdef OLD_DOMINATOR_TEST
00631
00632
00633
00634 _depth = _parent->depth() + 1;
00635
00636 #endif
00637
00638
00639
00640 _subtree_id = _parent->subtree_id();
00641
00642
00643
00644 if (_calls)
00645 _calls->adjust_depth();
00646 }
00647
00648
00649
00650 void stmtLocation::print(ostream & o) const
00651 {
00652
00653 }
00654
00655 void stmtLocation::print_path(ostream & o) const
00656 {
00657 block_location()->print_path(o);
00658 o << ':' << _stmt_num << '(' << _stmt->coord() << ')';
00659 }
00660
00661 void stmtLocation::print_callsite(ostream & o) const
00662 {
00663 basicblockLocation * bb = block_location();
00664 procLocation * p = bb->proc_location();
00665
00666 o << p->proc()->decl()->name()
00667 << ':' << bb->block()->dfn()
00668 << ':' << _stmt_num;
00669 }
00670
00671
00672
00673 stmtLocation::~stmtLocation()
00674 {
00675
00676
00677 if (_calls)
00678 delete _calls;
00679
00680 Location::stmt_count--;
00681 }
00682
00683
00684
00685
00686
00687 basicblockLocation::basicblockLocation(procLocation * parent,
00688 basicblockNode * block)
00689 : Location(parent, BasicBlock),
00690 _block(block),
00691 _statements(block->stmts().size(), stmtLocation(this))
00692 {
00693 basicblockNode * exit = parent->proc()->exit();
00694
00695 #ifdef OLD_DOMINATOR_TEST
00696
00697
00698
00699 _dominates_exit = Dominators::dominates(block , exit);
00700
00701 #endif
00702
00703
00704
00705 Location * cur_dom = this;
00706
00707
00708
00709 stmt_list & stmts = block->stmts();
00710 unsigned int num = 0;
00711
00712 for (stmt_list_p p = stmts.begin();
00713 p != stmts.end();
00714 ++p)
00715 {
00716 stmtLocation * cur_stmt = & _statements[num];
00717 cur_stmt->stmt_num(num);
00718 cur_stmt->stmt(*p);
00719 num++;
00720
00721
00722
00723
00724 cur_stmt->set_dominator(cur_dom);
00725 cur_dom = cur_stmt;
00726 }
00727
00728 Location::block_count++;
00729 Location::stmt_count += block->stmts().size();
00730 }
00731
00732 void basicblockLocation::adjust_depth()
00733 {
00734
00735 #ifdef OLD_DOMINATOR_TEST
00736
00737
00738
00739 _depth = _parent->depth() + 1;
00740
00741 #endif
00742
00743
00744
00745 _subtree_id = _parent->subtree_id();
00746
00747
00748
00749 unsigned int size = _statements.size();
00750
00751 for (unsigned int i = 0; i < size ; i++)
00752 _statements[i].adjust_depth();
00753 }
00754
00755
00756
00757 void basicblockLocation::print(ostream & o) const
00758 {
00759
00760 }
00761
00762 void basicblockLocation::print_path(ostream & o) const
00763 {
00764 proc_location()->print_path(o);
00765 o << ':' << block()->dfn();
00766 }
00767
00768
00769
00770 basicblockLocation::~basicblockLocation()
00771 {
00772 Location::block_count--;
00773
00774 }
00775
00776
00777
00778
00779
00780 procLocation * procLocation::Main = 0;
00781
00782 static unsigned int progress_counter = 0;
00783
00784 procLocation::procLocation(stmtLocation * parent,
00785 procNode * proc,
00786 bool context_insensitive)
00787 : Location(parent, Procedure),
00788 _proc(proc),
00789 _basicblocks()
00790 {
00791 Location::proc_count++;
00792
00793 if (! parent) {
00794
00795
00796
00797 Main = this;
00798
00799 current_subtree_id = 0;
00800 _subtree_id = current_subtree_id;
00801
00802
00803
00804 current_tree_number = 0;
00805 set_tree_min(next_tree_number());
00806 }
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819 stmt_list & stmts = proc->body()->stmts();
00820 for (stmt_list_p p = stmts.begin();
00821 p != stmts.end();
00822 ++p)
00823 {
00824 basicblockNode * block = (basicblockNode *) *p;
00825
00826
00827
00828 basicblockLocation * block_loc = new basicblockLocation(this, block);
00829
00830
00831
00832 _basicblocks[block] = block_loc;
00833 }
00834
00835 progress_counter++;
00836
00837
00838
00839
00840
00841
00842
00843 for (basicblock_location_map_p p = _basicblocks.begin();
00844 p != _basicblocks.end();
00845 ++p)
00846 {
00847 basicblockNode * bb = (*p).first;
00848 basicblockLocation * block_loc = (*p).second;
00849
00850
00851
00852 if (bb == proc->entry())
00853 block_loc->set_dominator(this);
00854 else {
00855
00856
00857
00858
00859 basicblockNode * dom = bb->parent();
00860 basicblockLocation * dom_loc = lookup_block(dom);
00861 block_loc->set_dominator(dom_loc->last());
00862 }
00863 }
00864
00865
00866
00867
00868 if (context_insensitive)
00869 remove_from_tree();
00870 }
00871
00872
00873
00874
00875
00876
00877
00878
00879 basicblockLocation * procLocation::lookup_block(basicblockNode * block) const
00880 {
00881 basicblock_location_map_cp p = _basicblocks.find(block);
00882 return (*p).second;
00883 }
00884
00885 procLocation * procLocation::parent_proc() const
00886 {
00887 if (_parent) {
00888 stmtLocation * parent2 = (stmtLocation *) _parent;
00889 return parent2->block_location()->proc_location();
00890 }
00891 else
00892 return 0;
00893 }
00894
00895
00896
00897 stmtLocation * procLocation::last()
00898 {
00899 basicblockNode * the_exit = _proc->exit();
00900 basicblockLocation * the_exit_location = lookup_block(the_exit);
00901 return the_exit_location->last();
00902 }
00903
00909 void procLocation::remove_from_tree()
00910 {
00911
00912
00913 _parent = 0;
00914
00915
00916
00917 current_subtree_id++;
00918 _subtree_id = current_subtree_id;
00919
00920
00921
00922 adjust_depth();
00923 }
00924
00925 void procLocation::adjust_depth()
00926 {
00927
00928 #ifdef OLD_DOMINATOR_TEST
00929
00930
00931
00932 if (_parent)
00933 _depth = _parent->depth() + 1;
00934 else
00935 _depth = 0;
00936
00937 #endif
00938
00939
00940 if (_parent) {
00941
00942
00943
00944 _subtree_id = _parent->subtree_id();
00945 }
00946
00947
00948
00949 for (basicblock_location_map_p p = _basicblocks.begin();
00950 p != _basicblocks.end();
00951 ++p)
00952 (*p).second->adjust_depth();
00953 }
00954
00955
00956
00957 void procLocation::print(ostream & o) const
00958 {
00959
00960 }
00961
00962 void procLocation::print_path(ostream & o) const
00963 {
00964 if (stmt_location()) {
00965 stmt_location()->print_path(o);
00966 o << '/';
00967 }
00968 o << _proc->decl()->name();
00969 }
00970
00971
00972
00973 procLocation::~procLocation()
00974 {
00975
00976
00977 for (basicblock_location_map_p p = _basicblocks.begin();
00978 p != _basicblocks.end();
00979 ++p)
00980 delete (*p).second;
00981
00982 progress_counter--;
00983
00984
00985
00986 if (this == Main)
00987 Main = 0;
00988
00989 Location::proc_count--;
00990 }