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_MEMORYBLOCK_H
00039 #define CBZ_MEMORYBLOCK_H
00040
00041 #include "pointeroptions.h"
00042 #include "location.h"
00043 #include "memoryaccess.h"
00044 #include "proceduredb.h"
00045 #include "unification.h"
00046
00047 #include <set>
00048
00049
00050
00051
00052
00053
00054
00055 class memoryBlock;
00056
00057 typedef list< memoryBlock * > memoryblock_list;
00058 typedef memoryblock_list::iterator memoryblock_list_p;
00059
00060 typedef map< int, memoryBlock *, less< int > > component_map;
00061 typedef component_map::iterator component_map_p;
00062 typedef component_map::const_iterator component_map_cp;
00063
00064 typedef vector< memoryBlock * > memoryblock_vector;
00065 typedef memoryblock_vector::iterator memoryblock_vector_p;
00066
00067
00068
00069
00070
00071 typedef map< stmtLocation *, memoryblock_set > callsite_objects_map;
00072 typedef callsite_objects_map::iterator callsite_objects_map_p;
00073 typedef callsite_objects_map::const_iterator callsite_objects_map_cp;
00074
00075 typedef map< procNode *, callsite_objects_map > parameter_assign_map;
00076 typedef parameter_assign_map::iterator parameter_assign_map_p;
00077
00078 class enumPropertyAnn;
00079
00080 class memoryBlock : public PerClassHeap< PointersHeap >
00081 {
00082 public:
00083
00084 typedef enum { Control_flow, Parameter_pass, Weak_update, Additive } DestructiveKind;
00085
00086 typedef map< Location *, DestructiveKind > destructive_assignment_map;
00087 typedef destructive_assignment_map::iterator destructive_assignment_map_p;
00088 typedef destructive_assignment_map::const_iterator destructive_assignment_map_cp;
00089
00090 typedef map< Location *, memoryblock_set > complicit_assignment_map;
00091 typedef complicit_assignment_map::iterator complicit_assignment_map_p;
00092 typedef complicit_assignment_map::const_iterator complicit_assignment_map_cp;
00093
00094 static int memoryblock_count;
00095 static void stats();
00096
00097 private:
00098
00101 REF memoryBlock * _container;
00102
00110
00111 TREE orderedDefs Defs;
00112 TREE orderedUses Uses;
00113
00115
00124 parameter_assign_map _parameter_assignments;
00125
00135 REF memoryUse * _current_use;
00136
00149 REF memoryDef * _current_def;
00150
00153 component_map _components;
00154
00160 declNode * _decl;
00161
00168 int _synthetic_decl:1;
00169
00175 int _write_protected:1;
00176
00181 int _is_array:1;
00182
00188 int _is_array_element:1;
00189
00196 int _is_indexed:1;
00197
00202 int _is_allocation_object:1;
00203
00210 int _flow_sensitive:1;
00211
00212
00219 int _unify:1;
00220
00227 int _single_assignment:1;
00228
00233 int _is_return_value:1;
00234
00241 procNode * _local_to;
00242
00248
00249
00255 stmtLocation * _allocation_site;
00256
00264
00265
00273 memoryBlock * _allocation_object;
00274
00280
00281
00287
00288
00295 procedureinfo_set _input_to;
00296
00302 destructive_assignment_map _destructive_assignments;
00303
00309 complicit_assignment_map _complicit_assignments;
00310
00312 UnifyType *_unifytype;
00313
00314 public:
00315
00316
00317
00324 enumPropertyAnn * property;
00325
00331 memoryblock_vector property_blocks;
00332
00333 private:
00334
00335 friend class memoryModel;
00336
00343 memoryBlock(declNode * decl, bool synthetic,
00344 memoryBlock * container,
00345 procNode * local_to);
00346
00352 ~memoryBlock();
00353
00354 public:
00355
00360 void clear();
00361
00362
00363
00364 declNode * decl() const { return _decl; }
00365 procNode * local_to() const { return _local_to; }
00366
00367 bool is_synthetic_decl() const { return _synthetic_decl; }
00368
00369 bool write_protected() const { return _write_protected; }
00370 void set_write_protected() { _write_protected = true; }
00371
00372 bool is_indexed() const { return _is_indexed; }
00373 void set_indexed() { _is_indexed = true; }
00374
00375
00376
00377 stmtLocation * allocation_site() const { return _allocation_site; }
00378 bool is_heap_object() const { return _allocation_site != 0; }
00379 void set_heap_object(stmtLocation * alloc_site) { _allocation_site = alloc_site; }
00380
00381 bool is_allocation_object() const { return _is_allocation_object; }
00382
00383 memoryUse * current_use() const { return _current_use; }
00384 memoryDef * current_def() const { return _current_def; }
00385
00386 void reset_current_def_use(Location * unused);
00387
00388 void set_current_def_use(Location * where);
00389
00390 inline memoryBlock * container() const { return _container; }
00391
00392 inline bool is_flow_sensitive() const { return _flow_sensitive; }
00393 inline void set_flow_sensitive() {
00394 _flow_sensitive = true;
00395
00396 }
00397 inline void set_flow_insensitive() { _flow_sensitive = false; }
00398
00399 inline bool is_unify() const { return _unify; }
00400 inline void set_unify(bool flag) { _unify = flag; }
00401 inline UnifyType *unifyType() const { return _unifytype; }
00402 inline void unifyType(UnifyType *t) { _unifytype=t; }
00403
00404 inline bool is_single_assignment() const { return _single_assignment; }
00405
00406 inline bool is_return_value() const { return _is_return_value; }
00407 inline bool set_return_value() { _is_return_value = true; }
00408
00409
00410
00411
00412 inline procedureinfo_set & input_to() { return _input_to; }
00413
00414
00415
00422 memoryDef * def_at(Location * where, bool & is_new);
00423
00430 memoryDef * nearest_def_at(Location * where);
00431
00437
00438
00439
00440
00441
00448 memoryUse * use_at(Location * where);
00449
00456 memoryDef * last_def_at(basicblockLocation * block);
00457
00463 memoryDef * find_def_at(Location * where);
00464
00470 memoryUse * find_use_at(Location * where);
00471
00477 void find_uses_at(Location * where, memoryuse_set & uses);
00478
00483 inline const memorydef_list & defs() const { return Defs.def_list(); }
00484
00491 void add_parameter_assignment(procNode * proc, stmtLocation * callsite,
00492 memoryBlock * block);
00493
00500 void add_parameter_assignment(procNode * proc, stmtLocation * callsite,
00501 memoryblock_set & blocks);
00502
00507 const callsite_objects_map & parameter_assignments(procNode * proc)
00508 { return _parameter_assignments[proc]; }
00509
00516 void apply_weak_update(Location * current,
00517 memoryDef * previous_def,
00518 memoryuse_set & uses);
00519
00527 void setup_merge_uses_at(basicblockLocation * merge_location,
00528 memoryDef * reaching_def,
00529 basicblock_set & predecessors);
00530
00540 void merge_uses_at(basicblockLocation * where,
00541 memoryuse_list & uses,
00542 cfg_edge_set & active_edges,
00543 memoryDef * dominating_def,
00544 bool computePointers);
00545
00551 void reachable_blocks(Location * where,
00552 bool has_use_here,
00553 memoryblock_list & worklist,
00554 memoryblock_set & already_seen,
00555 memoryBlock * null);
00556
00563 memoryBlock * get_allocation_object(memoryModel & Memory);
00564
00569 memoryBlock * allocation_object();
00570
00577 Multiplicity at_allocation(Location * current,
00578 memoryDef * reaching_def,
00579 memoryblock_set & defs,
00580 memoryuse_set & uses,
00581 memoryblock_set & changes);
00582
00589 Multiplicity at_deallocation(Location * current,
00590 memoryDef * reaching_def,
00591 memoryblock_set & defs,
00592 memoryuse_set & uses,
00593 memoryblock_set & changes);
00594
00598
00604 void add_destructive_assignment(Location * where, DestructiveKind cause);
00605
00611 void add_complicit_assignment(Location * where, memoryblock_set & objects);
00612
00618 void add_complicit_assignment(Location * where, memoryBlock * object);
00619
00622 const destructive_assignment_map & destructive_assignments() const
00623 { return _destructive_assignments; }
00624
00627 const complicit_assignment_map & complicit_assignments() const
00628 { return _complicit_assignments; }
00629
00638 void add_to_flow_sensitive_list(flow_sensitive_set & flow_sensitive_objects);
00639
00644 bool is_in_flow_sensitive_list(flow_sensitive_set & flow_sensitive_objects);
00645
00652 void set_flow_sensitivity(flow_sensitive_set & flow_sensitive_objects);
00653
00662 void add_to_non_unify_list(UnifyTypes & non_unify_types);
00669 void set_unification(UnifyTypes & unify_types);
00670
00672
00677 memoryBlock * top_most_container();
00678
00679
00680
00681 memoryblock_set containers() const;
00682 memoryblock_set top_most_containers();
00683
00686 static void print_multiplicity(Multiplicity m, ostream & out);
00687
00692 void def_uses(memoryDef * def,
00693 memoryuse_list & uses);
00694
00695
00696
00697 void prune_defs_uses();
00698
00699
00700
00701 void dot(const string & field_name,
00702 declNode * field_decl,
00703 memoryModel & Memory,
00704 memoryblock_set & results);
00705
00706
00707
00708 bool is_array() const { return _is_array; }
00709
00710 bool is_array_element() const { return _is_array_element; }
00711
00712 void set_array_element(memoryBlock * element);
00713
00714 memoryBlock * get_array_element();
00715
00716 memoryDef * setup_array_def();
00717
00718
00719
00720 bool in_scope(basicblockLocation * where) const;
00721
00722
00723
00724 friend ostream& operator<<(ostream & o, const memoryBlock & mb) {
00725
00726 return o;
00727 }
00728
00729
00730
00731
00732 typedef enum { NAME_ONLY, CURRENT_VALUE, AFTER_ASSIGNMENT, ALL_VALUES } Output_mode;
00733
00734 void print(ostream & o, Location * path, Output_mode mode = CURRENT_VALUE) const;
00735 string name() const;
00736
00737 string generate_su_field_name(const string & field) const;
00738
00739 void print_def_use(ostream & o) const;
00740
00741
00742
00743
00744 void update_def_use_chains();
00745
00746
00747
00748 void stats(ostream & out, bool header,
00749 long int & global_defs,
00750 long int & global_merge_defs,
00751 long int & global_weak_defs,
00752 long int & global_uses,
00753 long int & global_merge_uses);
00754
00755 private:
00756
00757
00758
00759
00760
00761
00762 class FieldNameDB
00763 {
00764 private:
00765
00766 typedef map< string, int, less< string > > field_name_map;
00767 typedef field_name_map::iterator field_name_map_p;
00768
00769 field_name_map _fields;
00770 int _count;
00771
00772 public:
00773
00774 static int ArrayField;
00775
00776 FieldNameDB()
00777 : _fields(),
00778 _count(0)
00779 {}
00780
00781
00782
00783 int get_field(const string & name);
00784
00785
00786
00787 string field_name(int index);
00788
00789 void stats() {
00790 cout << " Field names: " << _count << endl;
00791 }
00792 };
00793
00794 static FieldNameDB FieldNames;
00795
00796
00797 memoryblock_set top_most_containers(memoryblock_set &visited);
00798 };
00799
00800
00801 #endif // CBZ_MEMORYBLOCK_H