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 "memoryaccess.h"
00040
00041
00042
00043
00044
00045
00046
00047
00048 bool memoryAccess::Verbose = false;
00049 unsigned int memoryAccess::def_count = 0;
00050 unsigned int memoryAccess::use_count = 0;
00051 unsigned int memoryAccess::merge_use_count = 0;
00052
00053 memoryAccess::memoryAccess(Location * where, memoryBlock * owner)
00054 : _where(where),
00055 _is_weak(false),
00056 _multiplicity(Unallocated),
00057 _search_for_def(true),
00058 _active(true),
00059 _owner(owner)
00060 {}
00061
00062 void memoryAccess::stats()
00063 {
00064 cout << " memoryDef : " << def_count << " objects x "
00065 << sizeof(memoryDef) << " bytes = " << def_count * sizeof(memoryDef)
00066 << " bytes. " << endl;
00067
00068 cout << " memoryUse : " << use_count << " objects x "
00069 << sizeof(memoryUse) << " bytes = " << use_count * sizeof(memoryUse)
00070 << " bytes. " << endl;
00071 cout << " memoryuse_list : " << sizeof(memoryuse_list) << " bytes" << endl;
00072 cout << " memoryblock_set : " << sizeof(memoryblock_set) << " bytes" << endl;
00073 }
00074
00075
00076
00077
00078
00079 memoryDef::memoryDef(Location * where, memoryBlock * owner)
00080 : memoryAccess(where, owner),
00081
00082 _points_to(),
00083
00084 _value(0),
00085 _self_assign_use(0)
00086 {
00087 memoryAccess::def_count++;
00088 }
00089
00090
00091
00092 memoryDef::~memoryDef()
00093 {
00094 memoryAccess::def_count--;
00095 }
00096
00097
00098
00099 void memoryDef::add_pointers(const memoryblock_set & mbs)
00100 {
00101 _points_to.insert(mbs.begin(), mbs.end());
00102 }
00103
00104 void memoryDef::clear_points_to()
00105 {
00106 _points_to.clear();
00107 }
00108
00109
00110
00111 void memoryDef::print(ostream & o) const
00112 {
00113 o << " Def at " << * where() << endl;
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 }
00125
00126
00127
00128
00129
00130
00131
00132 memoryDef * orderedDefs::find_def(Location * where)
00133 {
00134 memorydef_location_map_cp q = _quick_lookup.find(where);
00135
00136 if (q != _quick_lookup.end())
00137 return (*q).second;
00138 else
00139 return 0;
00140 }
00141
00142
00143
00144 memoryDef * orderedDefs::find_strictly_dominating_def(Location * where)
00145 {
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 bool dominates = false;
00157 memoryDef * dominator = 0;
00158 Location * current = 0;
00159
00160 int looking_for_subtree = where->subtree_id();
00161 unsigned int looking_for_min = where->tree_min();
00162 unsigned int looking_for_max = where->tree_max();
00163
00164
00165
00166 memorydef_list_cp end = _defs.end();
00167 memorydef_list_cp p = _defs.begin();
00168
00169 while (p != end) {
00170 const memorydef_key & key = (*p);
00171
00172 current = key.location;
00173
00174 if (current != where) {
00175
00176
00177
00178 if (current->subtree_id() == looking_for_subtree) {
00179
00180 unsigned int dom_min = current->tree_min();
00181 unsigned int dom_max = current->tree_max();
00182
00183 if ((dom_min < looking_for_min) && (looking_for_max <= dom_max)) {
00184 dominator = key.def;
00185 break;
00186 }
00187 }
00188 }
00189
00190 ++p;
00191 }
00192
00193 return dominator;
00194 }
00195
00196
00197
00198 memoryDef * orderedDefs::find_dominating_def(Location * where)
00199 {
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 bool dominates = false;
00211 memoryDef * dominator = 0;
00212 Location * current = 0;
00213
00214 int looking_for_subtree = where->subtree_id();
00215 unsigned int looking_for_min = where->tree_min();
00216 unsigned int looking_for_max = where->tree_max();
00217
00218
00219
00220
00221
00222 memorydef_list_cp end = _defs.end();
00223 memorydef_list_cp p = _defs.begin();
00224
00225 while (p != end) {
00226 const memorydef_key & key = (*p);
00227
00228 current = key.location;
00229
00230 if (current == where) {
00231 dominator = key.def;
00232 break;
00233 }
00234
00235
00236
00237 if (current->subtree_id() == looking_for_subtree) {
00238
00239 unsigned int dom_min = current->tree_min();
00240 unsigned int dom_max = current->tree_max();
00241
00242
00243
00244 if ((dom_min < looking_for_min) && (looking_for_max <= dom_max)) {
00245 dominator = key.def;
00246 break;
00247 }
00248 }
00249
00250 ++p;
00251 }
00252
00253 return dominator;
00254 }
00255
00256
00257
00258
00259
00260 memoryDef * orderedDefs::make_def_at(Location * where, memoryBlock * owner, bool & is_new)
00261 {
00262
00263
00264 is_new = false;
00265
00266 memorydef_location_map_p q = _quick_lookup.find(where);
00267
00268 if (q != _quick_lookup.end())
00269 return (*q).second;
00270
00271
00272
00273 if (memoryAccess::Verbose)
00274 cout << "make_def_at: dominator for " << * where << endl;
00275
00276
00277
00278 bool dominates = false;
00279 memoryDef * dominator = 0;
00280 Location * current = 0;
00281
00282 int looking_for_subtree = where->subtree_id();
00283 unsigned int looking_for_min = where->tree_min();
00284 unsigned int looking_for_max = where->tree_max();
00285
00286
00287
00288
00289
00290 memorydef_list_p end = _defs.end();
00291 memorydef_list_p p = _defs.begin();
00292
00293 while (p != end) {
00294 const memorydef_key & key = (*p);
00295
00296 current = key.location;
00297
00305
00306
00307 if (current->subtree_id() == looking_for_subtree) {
00308
00309 unsigned int dom_min = current->tree_min();
00310 unsigned int dom_max = current->tree_max();
00311
00312
00313
00314 if ((dom_min < looking_for_min) && (looking_for_max <= dom_max)) {
00315 dominator = key.def;
00316 break;
00317 }
00318 }
00319
00320 ++p;
00321 }
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334 if (memoryAccess::Verbose)
00335 if (p != _defs.end())
00336 cout << " dominated by " << * current << endl;
00337
00338
00339
00340
00341
00342 memoryDef * new_def = new memoryDef(where, owner);
00343
00344 memorydef_key new_entry(new_def);
00345 _defs.insert(p, new_entry);
00346
00347 _quick_lookup[where] = new_def;
00348
00349 is_new = true;
00350
00351
00352
00353 return new_def;
00354 }
00355
00356
00357
00358 void orderedDefs::prune(orderedUses & Uses)
00359 {
00360 memorydef_list_p p = _defs.begin();
00361 memorydef_list_p to_remove;
00362
00363 while (p != _defs.end()) {
00364 memoryDef * cur = (*p).def;
00365
00366 to_remove = p;
00367 ++p;
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381 }
00382 }
00383
00384
00385
00386 void orderedDefs::print(ostream & o) const
00387 {
00388 for (memorydef_list_cp p = _defs.begin();
00389 p != _defs.end();
00390 ++p)
00391 (*p).def->print(o);
00392 }
00393
00394
00395
00396 void orderedDefs::clear()
00397 {
00398 for (memorydef_list_cp p = _defs.begin();
00399 p != _defs.end();
00400 ++p)
00401 delete (*p).def;
00402
00403 _defs.clear();
00404 }
00405
00406
00407
00408 void orderedDefs::stats(int & total_defs, int & merge_defs, int & weak_defs)
00409 {
00410 total_defs = 0;
00411 merge_defs = 0;
00412 weak_defs = 0;
00413
00414 for (memorydef_list_p p = _defs.begin();
00415 p != _defs.end();
00416 ++p)
00417 {
00418 memoryDef * def = (*p).def;
00419
00420 total_defs++;
00421
00422 if (def->where()->kind() == Location::BasicBlock)
00423 merge_defs++;
00424
00425 if (def->is_weak())
00426 weak_defs++;
00427 }
00428 }
00429
00430
00431
00432
00433
00434 memoryUse::memoryUse(Location * where, memoryBlock * owner)
00435 : memoryAccess(where, owner),
00436 _reaching_def(0)
00437 {
00438 memoryAccess::use_count++;
00439 }
00440
00441
00442
00443 memoryUse::~memoryUse()
00444 {
00445 memoryAccess::use_count--;
00446 }
00447
00448 void memoryUse::reaching_def(memoryDef * def)
00449 {
00450 if (memoryAccess::Verbose) {
00451 cout << "-> Use at " << * where();
00452
00453 if (def)
00454 cout << " setting reaching def to " << * def->where();
00455 else
00456 cout << " no reaching def, ";
00457
00458 if (_reaching_def)
00459 cout << " was " << * _reaching_def->where() << endl;
00460 else
00461 cout << " no previous reaching def" << endl;
00462 }
00463
00464 _reaching_def = def;
00465 }
00466
00467
00468
00469 void memoryUse::print(ostream & o) const
00470 {
00471 o << " Use at " << * where() << endl;
00472 o << " ";
00473 if (_reaching_def)
00474 _reaching_def->print(o);
00475 else
00476 o << " (no reaching def)" << endl;
00477 }
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487 memoryUse * orderedUses::find_use(Location * where) const
00488 {
00489 if (where) {
00490 memoryuse_map_cp p = _uses.find(where);
00491 if (p != _uses.end())
00492 return (*p).second;
00493 }
00494
00495 return 0;
00496 }
00497
00498
00499
00500 void orderedUses::find_uses_at(Location * where, memoryuse_set & uses)
00501 {
00502 memoryUse * use;
00503
00504
00505
00506 use = find_use(where);
00507 if (use) {
00508 uses.insert(use);
00509 return;
00510 }
00511
00512
00513
00514 if (where->kind() == Location::BasicBlock) {
00515
00516 basicblockLocation * bb = (basicblockLocation *) where;
00517
00518 merge_use_map_p found = _merge_uses.find(bb);
00519 if (found != _merge_uses.end()) {
00520
00521 pred_use_map & pum = (*found).second;
00522
00523 for (pred_use_map_p p = pum.begin();
00524 p != pum.end();
00525 ++p)
00526 {
00527 uses.insert((*p).second);
00528 }
00529 }
00530 }
00531 }
00532
00533
00534
00535
00536 memoryUse * orderedUses::make_use_at(Location * where, memoryBlock * owner)
00537 {
00538
00539
00540 memoryUse * res = find_use(where);
00541 if ( ! res ) {
00542 res = new memoryUse(where, owner);
00543 _uses.insert(memoryuse_map_pair(where, res));
00544 }
00545
00546 return res;
00547 }
00548
00549
00550
00551
00552 const pred_use_map & orderedUses::make_merge_uses_at(basicblockLocation * where, memoryBlock * owner)
00553 {
00554
00555
00556 merge_use_map_p found = _merge_uses.find(where);
00557 if (found == _merge_uses.end()) {
00558
00559
00560
00561 _merge_uses[where] = pred_use_map();
00562 found = _merge_uses.find(where);
00563 pred_use_map & new_uses = (*found).second;
00564
00565
00566
00567
00568 basicblock_list & preds = where->block()->preds();
00569 for (basicblock_list_p p = preds.begin();
00570 p != preds.end();
00571 ++p) {
00572 memoryUse * use = new memoryUse(where, owner);
00573 new_uses[*p] = use;
00574 }
00575 }
00576
00577 return (*found).second;
00578 }
00579
00580
00581
00582
00583 void orderedUses::update_def_use_chains()
00584 {
00585 memoryUse * use;
00586 memoryDef * def;
00587
00588 for (memoryuse_map_p p = _uses.begin();
00589 p != _uses.end();
00590 ++p)
00591 {
00592 use = (*p).second;
00593 def = use->reaching_def();
00594
00595
00596
00597
00598 }
00599
00600 for (merge_use_map_cp q = _merge_uses.begin();
00601 q != _merge_uses.end();
00602 ++q)
00603 {
00604 const pred_use_map & pred_uses = (*q).second;
00605
00606 for (pred_use_map_cp w = pred_uses.begin();
00607 w != pred_uses.end();
00608 ++w)
00609 {
00610 use = (*w).second;
00611 def = use->reaching_def();
00612
00613
00614
00615
00616 }
00617 }
00618 }
00619
00620 void orderedUses::def_uses(memoryDef * def,
00621 memoryuse_list & uses)
00622 {
00623 for (memoryuse_map_p p = _uses.begin();
00624 p != _uses.end();
00625 ++p)
00626 {
00627 memoryUse * use = (*p).second;
00628 memoryDef * rdef = use->reaching_def();
00629 if (rdef == def)
00630 uses.push_back(use);
00631 }
00632
00633 for (merge_use_map_cp q = _merge_uses.begin();
00634 q != _merge_uses.end();
00635 ++q)
00636 {
00637 const pred_use_map & pred_uses = (*q).second;
00638
00639 for (pred_use_map_cp w = pred_uses.begin();
00640 w != pred_uses.end();
00641 ++w)
00642 {
00643 memoryUse * use = (*w).second;
00644 memoryDef * rdef = use->reaching_def();
00645 if (rdef == def)
00646 uses.push_back(use);
00647 }
00648 }
00649 }
00650
00651
00652
00653 void orderedUses::prune(Location * where)
00654 {
00655
00656
00657 memoryuse_map_p p = _uses.find(where);
00658
00659 if (p != _uses.end()) {
00660
00661
00662
00663 memoryUse * use = (*p).second;
00664 memoryDef * def = use->reaching_def();
00665 if (def) {
00666
00667
00668
00669 memoryuse_list uses;
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681 }
00682
00683
00684
00685 delete use;
00686
00687
00688
00689 _uses.erase(p);
00690 }
00691 }
00692
00693
00694
00695 void orderedUses::print(ostream & o) const
00696 {
00697 for (memoryuse_map_cp p = _uses.begin();
00698 p != _uses.end();
00699 ++p)
00700 (*p).second->print(o);
00701
00702 for (merge_use_map_cp q = _merge_uses.begin();
00703 q != _merge_uses.end();
00704 ++q)
00705 {
00706 const pred_use_map & pred_uses = (*q).second;
00707
00708 for (pred_use_map_cp w = pred_uses.begin();
00709 w != pred_uses.end();
00710 ++w)
00711 (*w).second->print(o);
00712 }
00713 }
00714
00715
00716
00717 void orderedUses::clear()
00718 {
00719 for (memoryuse_map_cp p = _uses.begin();
00720 p != _uses.end();
00721 ++p)
00722 delete (*p).second;
00723
00724 for (merge_use_map_cp q = _merge_uses.begin();
00725 q != _merge_uses.end();
00726 ++q)
00727 {
00728 const pred_use_map & pred_uses = (*q).second;
00729
00730 for (pred_use_map_cp w = pred_uses.begin();
00731 w != pred_uses.end();
00732 ++w)
00733 delete (*w).second;
00734 }
00735
00736 _uses.clear();
00737 _merge_uses.clear();
00738 }
00739
00740
00741
00742 void orderedUses::stats(int & total_uses, int & merge_uses)
00743 {
00744 merge_uses = _merge_uses.size();
00745 total_uses = _uses.size() + merge_uses;
00746 }
00747
00748
00749
00750
00751
00752 memoryAssignment * assignmentSet::assignment_at(Location * where,
00753 memoryBlock * block,
00754 bool create)
00755 {
00756 assignment_key key(where, block);
00757
00758
00759
00760 assignment_map_p p = _assignments.find(key);
00761 if (p != _assignments.end())
00762 return (*p).second;
00763
00764
00765
00766 if (create) {
00767 memoryAssignment * result = new memoryAssignment(where);
00768 _assignments[key] = result;
00769 return result;
00770 }
00771
00772 return 0;
00773 }