C-Breeze
C Compiler Infrastructure

[ Project home page]
Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

memoryblock.h

Go to the documentation of this file.
00001 // $Id: memoryblock.h,v 1.30 2003/08/08 15:16:29 toktb Exp $
00002 // ----------------------------------------------------------------------
00003 //
00004 //  C-Breeze
00005 //  C Compiler Framework
00006 // 
00007 //  Copyright (c) 2000 University of Texas at Austin
00008 // 
00009 //  Samuel Z. Guyer
00010 //  Daniel A. Jimenez
00011 //  Calvin Lin
00012 // 
00013 //  Permission is hereby granted, free of charge, to any person
00014 //  obtaining a copy of this software and associated documentation
00015 //  files (the "Software"), to deal in the Software without
00016 //  restriction, including without limitation the rights to use, copy,
00017 //  modify, merge, publish, distribute, sublicense, and/or sell copies
00018 //  of the Software, and to permit persons to whom the Software is
00019 //  furnished to do so, subject to the following conditions:
00020 //  
00021 //  The above copyright notice and this permission notice shall be
00022 //  included in all copies or substantial portions of the Software.
00023 //  
00024 //  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00025 //  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00026 //  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00027 //  NONINFRINGEMENT.  IN NO EVENT SHALL THE UNIVERSITY OF TEXAS AT
00028 //  AUSTIN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
00029 //  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
00030 //  OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00031 //  THE SOFTWARE.
00032 //
00033 //  We acknowledge the C-to-C Translator from MIT Laboratory for
00034 //  Computer Science for inspiring parts of the C-Breeze design.
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 //  Memory block
00051 
00052 // Each object in memory that may be a pointer, or pointed to is
00053 // represented by a memoryBlock. 
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 // -- Keep track of the reaching objects that are combined at a
00068 // context-insensitive procedure call (the self-assignments generated when
00069 // this object is an external input).
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   // TB_unify
00219   int _unify:1;
00220 
00227   int _single_assignment:1;
00228 
00233   int _is_return_value:1;
00234 
00241   procNode * _local_to;
00242 
00248   // string _name;
00249 
00255   stmtLocation * _allocation_site;
00256 
00264   // memoryDef * _initializer_def;
00265 
00273   memoryBlock * _allocation_object;
00274 
00280   // memoryDef * _only_def;
00281 
00287   // memoryUse * _only_use;
00288 
00295   procedureinfo_set _input_to;
00296 
00302   destructive_assignment_map _destructive_assignments;
00303 
00309   complicit_assignment_map _complicit_assignments;
00310 
00312   UnifyType *_unifytype; // TB_unify
00313 
00314 public:
00315 
00316   // --- These two members are just for Broadway
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   // --- Data members
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   // void set_name(const string & new_name) { _name = new_name; }
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     // cout << "SETFS: (0x" << this << ") " << name() << endl;
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   // inline memoryDef * only_def() const { return _only_def; }
00410   // inline memoryUse * only_use() const { return _only_use; }
00411 
00412   inline procedureinfo_set & input_to() { return _input_to; }
00413 
00414   // --- Manage uses and defs
00415 
00422   memoryDef * def_at(Location * where, bool & is_new);
00423 
00430   memoryDef * nearest_def_at(Location * where);
00431 
00437   /*
00438   memoryDef * nearest_def_at(Location * where,
00439                              const procedurecall_stack & callstack);
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   // TB_unify
00680   /* @brief Get all parents. */
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   // --- Prune out unneeded uses and defs
00696 
00697   void prune_defs_uses();
00698 
00699   // --- Manage structure fields
00700 
00701   void dot(const string & field_name,
00702            declNode * field_decl,
00703            memoryModel & Memory,
00704            memoryblock_set & results);
00705 
00706   // --- Handle special array objects
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   // --- Scoping
00719 
00720   bool in_scope(basicblockLocation * where) const;
00721 
00722   // --- Output
00723 
00724   friend ostream& operator<<(ostream & o, const memoryBlock & mb) {
00725     // mb.print(o, Path::always());
00726     return o;
00727   }
00728 
00729   // --- Pass after = true to see the points-to information after the
00730   // given statement has been executed.
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   // --- Update the def-use chains (only performed once at the end of
00742   // analysis by the memoryModel).
00743 
00744   void update_def_use_chains();
00745 
00746   // --- Statistics
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   //  Structure field-name database
00758 
00759   // Since the number of possible field names is small, we keep them in
00760   // a database and then refer to them by number in the memoryBlock class.
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     // --- Get the index for a field name, create if needed
00782 
00783     int get_field(const string & name);
00784 
00785     // --- Reverse search: find the name for a particular index
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   // TB_unify helper functionn.
00797   memoryblock_set top_most_containers(memoryblock_set &visited);
00798 };
00799 
00800 
00801 #endif // CBZ_MEMORYBLOCK_H

Generated on August 27, 2003
Back to the C-Breeze home page