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 #ifndef CBZ_MEMORYACCESS_H
00039 #define CBZ_MEMORYACCESS_H
00040
00041 #include <set>
00042 #include "pointeroptions.h"
00043 #include "location.h"
00044
00045
00046 #ifndef _MSC_VER
00047 #include <ext/hash_map>
00048 #include <ext/hash_set>
00049 #endif
00050
00051
00052
00053 class memoryBlock;
00054 class memoryDef;
00055 class memoryUse;
00056 class memorydef_key;
00057
00069 template< class T >
00070 class vector_set : public vector< T >
00071 {
00072 public:
00073
00074 vector_set()
00075 {
00076 reserve(10);
00077 }
00078
00079 inline void insert(T element)
00080 {
00081 int s = size();
00082 for (int i = 0; i < s; i++)
00083 if ((*this)[i] == element)
00084 return;
00085
00086
00087
00088 push_back(element);
00089 }
00090
00091 inline void insert(typename vector< T >::const_iterator b,
00092 typename vector< T >::const_iterator e)
00093 {
00094 for (typename vector< T >::const_iterator p = b;
00095 p != e;
00096 p++)
00097 insert(*p);
00098 }
00099
00100 inline typename vector< T >::const_iterator find(T element) const {
00101 return std::find(begin(), end(), element);
00102 }
00103
00104 inline typename vector< T >::iterator find(T element) {
00105 return std::find(begin(), end(), element);
00106 }
00107 };
00108
00115 typedef vector_set< memoryBlock * > memoryblock_set;
00116 typedef memoryblock_set::iterator memoryblock_set_p;
00117 typedef memoryblock_set::const_iterator memoryblock_set_cp;
00118
00127 typedef vector< memorydef_key > memorydef_list;
00128 typedef memorydef_list::iterator memorydef_list_p;
00129 typedef memorydef_list::const_iterator memorydef_list_cp;
00130
00134 typedef set< memoryDef * > memorydef_set;
00135 typedef memorydef_set::iterator memorydef_set_p;
00136 typedef memorydef_set::const_iterator memorydef_set_cp;
00137
00138 typedef map< Location *, memoryDef * > memorydef_location_map;
00139 typedef memorydef_location_map::iterator memorydef_location_map_p;
00140 typedef memorydef_location_map::const_iterator memorydef_location_map_cp;
00141
00142
00143
00144 typedef vector< memoryUse * > memoryuse_list;
00145 typedef memoryuse_list::iterator memoryuse_list_p;
00146 typedef memoryuse_list::const_iterator memoryuse_list_cp;
00147
00148 typedef set< memoryUse * > memoryuse_set;
00149 typedef memoryuse_set::iterator memoryuse_set_p;
00150 typedef memoryuse_set::const_iterator memoryuse_set_cp;
00151
00152
00153
00154
00155
00158 typedef enum Multiplicity
00159 { Top, Deallocated, Unallocated, Single, Bounded, Unbounded, Error } Multiplicity;
00160
00161
00162
00163 class memoryAccess : public PerClassHeap< PointersHeap >
00164 {
00165 public:
00166
00167 static bool Verbose;
00168 static unsigned int def_count;
00169 static unsigned int use_count;
00170 static unsigned int merge_use_count;
00171
00172 static void stats();
00173
00174 typedef enum { MultipleLHS, HighMultiplicity, Forced } WeakReason;
00175
00176 private:
00177
00180 Location * _where;
00181
00184 int _is_weak:1;
00185
00188 int _multiplicity:8;
00189
00192 int _search_for_def:1;
00193
00196 int _active:1;
00197
00200 memoryBlock * const _owner;
00201
00207
00208
00209 public:
00210
00211
00212
00213 memoryAccess(Location * where, memoryBlock * owner);
00214
00215
00216
00217 inline Location * where() const { return _where; }
00218
00219 inline bool is_weak() const { return _is_weak; }
00220 inline void set_weak(bool is) { _is_weak = is; }
00221
00222
00223
00224 inline Multiplicity multiplicity() const { return (Multiplicity)_multiplicity; }
00225 inline void set_multiplicity(Multiplicity lin) { _multiplicity = lin; }
00226
00227 inline bool search_for_def() const { return _search_for_def; }
00228 inline void search_for_def(bool val) { _search_for_def = val; }
00229
00230 inline bool is_active() const { return _active; }
00231 inline void set_active() { _active = true; }
00232 inline void set_inactive() { _active = false; }
00233
00234
00235
00236
00237
00238
00239 inline memoryBlock * owner() const { return _owner; }
00240
00241
00242
00243
00244
00245 };
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257 class memoryDef : public memoryAccess
00258 {
00259 private:
00260
00263
00264
00267 memoryblock_set _points_to;
00268
00271
00272
00275 const constant * _value;
00276
00284 memoryUse * _self_assign_use;
00285
00286 public:
00287
00288
00289
00290 memoryDef(Location * where, memoryBlock * owner);
00291
00292
00293
00294 ~memoryDef();
00295
00296
00297
00298
00299 inline const memoryblock_set & points_to() const { return _points_to; }
00300
00301
00302
00303
00304 inline const constant * value() const { return _value; }
00305 inline void set_value(const constant * newval) { _value = newval; }
00306
00307
00308
00309 inline memoryUse * self_assign_use() const { return _self_assign_use; }
00310 inline void set_self_assign_use(memoryUse * new_use) { _self_assign_use = new_use; }
00311
00316 void add_pointers(const memoryblock_set & mbs);
00317
00323 void clear_points_to();
00324
00325
00326
00327 void print(ostream & o) const;
00328 };
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340 class memorydef_key
00341 {
00342 public:
00343
00344 memoryDef * def;
00345 Location * location;
00346
00347
00348 memorydef_key(memoryDef * the_def)
00349 : def(the_def),
00350 location(the_def->where())
00351
00352 {}
00353 };
00354
00355 class orderedUses;
00356
00357 class orderedDefs
00358 {
00359 private:
00360
00361 memorydef_list _defs;
00362
00363 memorydef_location_map _quick_lookup;
00364
00365 public:
00366
00367 orderedDefs()
00368 : _defs(),
00369 _quick_lookup()
00370 {}
00371
00372
00373
00374 const memorydef_list & def_list() const { return _defs; }
00375
00376
00377
00378 memoryDef * find_def(Location * where);
00379
00380
00381
00382
00383 memoryDef * find_strictly_dominating_def(Location * where);
00384
00385
00386
00387
00388 memoryDef * find_dominating_def(Location * where);
00389
00390
00391
00392
00393
00394 memoryDef * make_def_at(Location * where, memoryBlock * owner, bool & is_new);
00395
00396
00397
00398 void prune(orderedUses & Uses);
00399
00400
00401
00402 void print(ostream & o) const;
00403
00404
00405
00406 void clear();
00407
00408
00409
00410 void stats(int & total_defs, int & merge_defs, int & weak_defs);
00411
00412 };
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423 class memoryUse : public memoryAccess
00424 {
00425 private:
00426
00427 memoryDef * _reaching_def;
00428
00429 public:
00430
00431
00432
00433 memoryUse(Location * where, memoryBlock * owner);
00434
00435
00436
00437 ~memoryUse();
00438
00439
00440
00441 memoryDef * reaching_def() const { return _reaching_def; }
00442 void reaching_def(memoryDef * def);
00443
00444
00445
00446 void print(ostream & o) const;
00447 };
00448
00449
00450 typedef map< Location *, memoryUse * > memoryuse_map;
00451 typedef memoryuse_map::iterator memoryuse_map_p;
00452 typedef memoryuse_map::const_iterator memoryuse_map_cp;
00453 typedef memoryuse_map::value_type memoryuse_map_pair;
00454
00455 typedef map< basicblockNode *, memoryUse *> pred_use_map;
00456 typedef pred_use_map::iterator pred_use_map_p;
00457 typedef pred_use_map::const_iterator pred_use_map_cp;
00458
00459 typedef map< Location *, pred_use_map > merge_use_map;
00460 typedef merge_use_map::iterator merge_use_map_p;
00461 typedef merge_use_map::const_iterator merge_use_map_cp;
00462
00463
00464
00465
00466
00467 class orderedUses
00468 {
00469 private:
00470
00471 memoryuse_map _uses;
00472 merge_use_map _merge_uses;
00473
00474 public:
00475
00476 orderedUses()
00477 : _uses(),
00478 _merge_uses()
00479 {}
00480
00481
00482
00483
00484 memoryUse * find_use(Location * where) const;
00485
00486
00487
00488 void find_uses_at(Location * where, memoryuse_set & uses);
00489
00490
00491
00492
00493 memoryUse * make_use_at(Location * where, memoryBlock * owner);
00494
00495
00496
00497
00498
00499 const pred_use_map & make_merge_uses_at(basicblockLocation * where,
00500 memoryBlock * owner);
00501
00502
00503
00504
00505 void update_def_use_chains();
00506
00512 void def_uses(memoryDef * def,
00513 memoryuse_list & uses);
00514
00515
00516
00517 void prune(Location * where);
00518
00519
00520
00521 void print(ostream & o) const;
00522
00523
00524
00525 void clear();
00526
00527
00528
00529 void stats(int & total_uses, int & merge_uses);
00530 };
00531
00532
00533
00534
00535
00536 class memoryAssignment : public PerClassHeap< PointersHeap >
00537 {
00538 private:
00539
00544 Location * _where;
00545
00550 memoryuse_set _uses;
00551
00556 memorydef_set _defs;
00557
00558 public:
00559
00562 memoryAssignment(Location * where)
00563 : _where(),
00564 _uses(),
00565 _defs()
00566 {}
00567
00570 inline Location * where() const { return _where; }
00571
00574 inline void add_use(memoryUse * use) { _uses.insert(use); }
00575
00578 inline void add_def(memoryDef * def) { _defs.insert(def); }
00579
00582 inline const memoryuse_set & uses() const { return _uses; }
00583
00586 inline const memorydef_set & defs() const { return _defs; }
00587 };
00588
00589
00590
00591
00592
00593 typedef pair< Location *, memoryBlock *> assignment_key;
00594
00595 typedef map< assignment_key, memoryAssignment * > assignment_map;
00596 typedef assignment_map::iterator assignment_map_p;
00597
00598 class assignmentSet
00599 {
00600 private:
00601
00604 assignment_map _assignments;
00605
00606 public:
00607
00610 assignmentSet()
00611 : _assignments()
00612 {}
00613
00620 memoryAssignment * assignment_at(Location * where, memoryBlock * block,
00621 bool create);
00622 };
00623
00624 #endif // CBZ_MEMORYACCESS_H
00625