C-Breeze
C Compiler Infrastructure

[ Project home page]

location.h

Go to the documentation of this file.
00001 // $Id: location.h,v 1.21 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_LOCATION_H
00039 #define CBZ_LOCATION_H
00040 
00041 #include "allocation.h"
00042 #include "dominators.h"
00043 #include "pointeroptions.h"
00044 
00045 // ------------------------------------------------------------
00046 // Location
00047 // ------------------------------------------------------------
00048 
00049 // Dominance testing : Dominance is tested in much the same way it was
00050 // in the previous version: we have a chain of path components, so we
00051 // move up until the two arguments have a common immediate
00052 // parent. Then we call the type-specific dominance test. The only
00053 // complication is when the two paths turn out to be in a direct
00054 // ancestor/descendant relationship. In this case, we allow each type
00055 // to determine what it does in that situation. The cases are based on
00056 // the following rationale:
00057 
00058 // 1. Assignments to the formal parameters are associated with the
00059 // procLocation, and thus must dominate all other statements inside
00060 // the procedure.
00061 //       => ancestor procLocation always dominates descendant
00062 
00063 // 2. Control-flow merges are associated with the basicblockLocation,
00064 // and thus must dominate all other statements within that block.
00065 //       => ancestor basicblockLocation always dominates descendant
00066 
00067 // 3. The assignment of the return value at a callsite, which is
00068 // associated with the stmtLocation, should be dominated by all
00069 // assignments inside the procedure.
00070 //       => ancestor stmtLocation never dominates descendant
00071 
00072 // The rules for descendants are the mirrors of the above rules for
00073 // ancestors.
00074 
00075 //       => descendant stmtLocation only dominates ancestor stmtLocations
00076 //       => descendant basicblockLocation only dominates ancestor stmtLocations
00077 //       => descendant procLocation only dominates ancestor stmtLocations
00078 
00079 // This divides locations into two categories: stmtLocations and
00080 // non-stmtLocation. So we implement all of this logic with a boolean:
00081 // is_stmt.
00082 
00083 class procLocation;
00084 class basicblockLocation;
00085 class stmtLocation;
00086 
00087 class Location : public PerClassHeap< PointersHeap >
00088 {
00089 public:
00090 
00093   typedef enum { Statement, BasicBlock, Procedure } LocationKind;
00094 
00097 
00098   static unsigned int stmt_count;
00099   static unsigned int block_count;
00100   static unsigned int proc_count;
00101   static unsigned int dom_calls;
00102 
00104 
00105 private:
00106 
00107   Location & operator=(const Location & other)
00108   {
00109     cerr << "ERROR: Cannot assign Location objects" << endl;
00110     return *this;
00111   }
00112 
00113 protected:
00114 
00123   Location * _parent;
00124 
00129   unsigned int _kind:2;
00130 
00131 #ifdef OLD_DOMINATOR_TEST
00132 
00133   unsigned int _depth:9;
00134   unsigned int _dominates_exit:1;
00135   unsigned int _not_basicblock:1;
00136   unsigned int _not_procedure:1;
00137 
00138 #endif
00139 
00151   unsigned int _subtree_id:16;
00152 
00155   static unsigned int current_subtree_id;
00156 
00170   unsigned int _num_children:8;
00171   
00178   Location * _dominator;
00179 
00202 
00203   unsigned int _tree_min;
00204   unsigned int _tree_max;
00205 
00207 
00210   static unsigned int current_tree_number;
00211 
00216   static unsigned int next_tree_number()
00217   { current_tree_number++; return current_tree_number; }
00218 
00219 public:
00220 
00226   Location(Location * parent, LocationKind kind);
00227 
00232 
00233   inline Location * parent() const { return _parent; }
00234   inline LocationKind kind() const { return (LocationKind)_kind; }
00235 
00236 #ifdef OLD_DOMINATOR_TEST
00237 
00238   inline unsigned int depth() const { return _depth; }
00239   inline unsigned int dominates_exit() const { return _dominates_exit; }
00240 
00241 #endif
00242 
00243   inline unsigned int subtree_id() const { return _subtree_id; }
00244 
00245   inline Location * dominator() const { return _dominator; }
00246   void set_dominator(Location * d);
00247   void clear_dominator();
00248 
00249   inline int num_children() const { return _num_children; }
00250   inline void increment_children() { _num_children++; }
00251   inline void decrement_children() { _num_children--; }
00252 
00253   inline unsigned int tree_min() const { return _tree_min; }
00254   inline void set_tree_min(unsigned int m) { _tree_min = m; }
00255 
00256   inline unsigned int tree_max() const { return _tree_max; }
00257   inline void set_tree_max(unsigned int m) { _tree_max = m; }
00258 
00260 
00267   void visit();
00268 
00278   void finish();
00279 
00282   static bool dominates(const Location * dom, const Location * cur);
00283 
00286   static bool strictly_dominates(const Location * dom, const Location * cur);
00287 
00288 #ifdef OLD_DOMINATOR_TEST
00289 
00292   static bool old_strictly_dominates(const Location * dom, const Location * cur);
00293 
00296   static Location * common_parent(Location * one,
00297                                   Location * two);
00298 
00299 #endif
00300 
00303   static procLocation * procedure(Location * where);
00304 
00307   static bool is_prefix(const Location * prefix, const Location * longer);
00308 
00314   virtual void adjust_depth() = 0;
00315  
00316   // Output
00317 
00318   virtual void print(ostream & o) const = 0;
00319   virtual void print_path(ostream & o) const = 0;
00320 
00321   friend ostream & operator<<(ostream & o, const Location & loc) {
00322     loc.print_path(o);
00323     return o;
00324   }
00325 
00326   // Destructor
00327 
00328   virtual ~Location();
00329 
00330   // Stats
00331 
00332   static void stats();
00333 };
00334 
00335 // ------------------------------------------------------------
00336 // stmtLocation
00337 // ------------------------------------------------------------
00338 
00339 class stmtLocation : public Location
00340 {
00341   friend class basicblockLocation;
00342   friend class procLocation;
00343 
00344 private:
00345 
00346   unsigned int _stmt_num;
00347   stmtNode * _stmt;
00348   procLocation * _calls;
00349   map<procNode*,procLocation*> _all_calls;
00350 
00351   inline void stmt_num(unsigned int num) { _stmt_num = num; }
00352   inline void stmt(stmtNode * s) { _stmt = s; }
00353 
00354 public:
00355 
00356   stmtLocation(basicblockLocation * parent);
00357 
00364   void setup_cs_call(procNode * proc);
00365 
00371   procLocation * remove_call();
00372 
00375   inline basicblockLocation * block_location() const
00376   { return (basicblockLocation *) _parent; }
00377 
00383   inline unsigned int stmt_num() const { return _stmt_num; }
00384 
00387   inline stmtNode * stmt() const { return _stmt; }
00388 
00394   inline procLocation * calls() const { return _calls; }
00395 
00400   callNode * callnode();
00401 
00402   // Check for the presence of a function call
00403 
00404   bool is_present(const procNode * proc) const;
00405 
00408   virtual void adjust_depth();
00409 
00410   // Output
00411 
00412   virtual void print(ostream & o) const;
00413   virtual void print_path(ostream & o) const;
00414   void print_callsite(ostream & o) const;
00415 
00416   // Destructor
00417 
00418   virtual ~stmtLocation();
00419 };
00420 
00421 typedef vector< stmtLocation > stmt_location_vec;
00422 typedef stmt_location_vec::iterator stmt_location_vec_p;
00423 
00424 // ------------------------------------------------------------
00425 // basicblockLocation
00426 // ------------------------------------------------------------
00427 
00428 class basicblockLocation : public Location
00429 {
00430   friend class procLocation;
00431 
00432 private:
00433 
00434   basicblockNode * const _block;
00435   stmt_location_vec _statements;
00436 
00437 public:
00438 
00439   basicblockLocation(procLocation * parent,
00440                      basicblockNode * block);
00441 
00442   // Fields
00443 
00444   inline procLocation * proc_location() const { return (procLocation *) _parent; }
00445   inline basicblockNode * block() const { return _block; }
00446   inline stmt_location_vec & statements() { return _statements; }
00447 
00450   stmtLocation * last() { return & _statements.back(); }
00451 
00454   virtual void adjust_depth();
00455 
00456   // Output
00457 
00458   virtual void print(ostream & o) const;
00459   virtual void print_path(ostream & o) const;
00460 
00461   // Destructor
00462 
00463   virtual ~basicblockLocation();
00464 };
00465 
00466 #if defined(__MWERKS__) && !defined(CBZ_HEAPLAYERS)
00467 typedef map< basicblockNode *, basicblockLocation * > basicblock_location_map;
00468 #else
00469 typedef map< basicblockNode *, basicblockLocation *,
00470               less< basicblockNode * >, basicblock_alloc > basicblock_location_map;
00471 #endif  /*      __MWERKS__ && !CBZ_HEAPLAYERS   */
00472 typedef basicblock_location_map::iterator basicblock_location_map_p;
00473 typedef basicblock_location_map::const_iterator basicblock_location_map_cp;
00474 
00475 // ------------------------------------------------------------
00476 // procLocation
00477 // ------------------------------------------------------------
00478 
00479 class procLocation : public Location
00480 {
00481 private:
00482 
00483   procNode * const _proc;
00484   basicblock_location_map _basicblocks;
00485 
00486   static procLocation * Main;
00487 
00488 public:
00489 
00490   procLocation(stmtLocation * parent,
00491                procNode * proc,
00492                bool context_insensitive = false);
00493 
00494   // Fields
00495 
00496   inline stmtLocation * stmt_location() const { return (stmtLocation *) _parent; }
00497   inline procNode * proc() const { return _proc; }
00498   basicblockLocation * lookup_block(basicblockNode * block) const;
00499   procLocation * parent_proc() const;
00500 
00501   static inline procLocation * main() { return Main; }
00502 
00503   // -- Get the last statement in the procedure
00504 
00505   stmtLocation * last();
00506 
00512   void remove_from_tree();
00513 
00516   virtual void adjust_depth();
00517 
00518   // Output
00519 
00520   virtual void print(ostream & o) const;
00521   virtual void print_path(ostream & o) const;
00522 
00523   // Destructor
00524 
00525   virtual ~procLocation();
00526 };
00527 
00528 #endif // CBZ_LOCATION_H

Generated on February 1, 2006
Back to the C-Breeze home page