C-Breeze
C Compiler Infrastructure

[ Project home page]

pointers.h

Go to the documentation of this file.
00001 // $Id: pointers.h,v 1.37 2003/09/29 13:01:33 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_POINTERS_H
00039 #define CBZ_POINTERS_H
00040 
00041 #include "pointeroptions.h"
00042 #include "location.h"
00043 #include "memorymodel.h"
00044 #include "memoryblock.h"
00045 #include "proceduredb.h"
00046 #include "linker.h"
00047 #include "ipanalysis.h"
00048 #include "pointervalue.h"
00049 #include "constants.h"
00050 #include "unification.h" // TB_unify
00051 
00052 typedef map< stmtNode *, declNode *> heap_map;
00053 typedef heap_map::iterator heap_map_p;
00054 
00055 typedef list< memoryblock_set > memoryblock_set_list;
00056 typedef memoryblock_set_list::iterator memoryblock_set_list_p;
00057 
00062 class Pointers
00063 {
00064 public:
00065 
00066   typedef set< string > string_set;
00067   typedef string_set::iterator string_set_p;
00068 
00069   typedef pair< int, double > count_accuracy_pair;
00070   typedef map< stmtLocation *, count_accuracy_pair > accuracy_map;
00071   typedef accuracy_map::iterator accuracy_map_p;
00072 
00073 protected:
00074 
00080   memoryModel Memory;
00081 
00088   heap_map HeapMap;
00089 
00092   procNode * Root;
00093 
00096   procLocation * root_location;
00097 
00107   Linker & linker;
00108 
00114   procedureDB Procedures;
00115 
00122   constantAnalyzer _constants;
00123 
00126   analysisProblem * Problem;
00127 
00135   bool computePointers;
00136 
00143   Direction _direction;
00144 
00147   int _procedureCount;
00148 
00151   int _skipCount;
00152 
00155   bool _show_progress;
00156 
00159   bool _use_multiplicity;
00160 
00163   string_set _unknown_procedures;
00164 
00169   accuracy_map _def_accuracy;
00170 
00175   accuracy_map _star_accuracy;
00176 
00178   UnificationBasedPtr *_unification_based;
00179 
00180 public:
00181 
00184   Pointers(procNode * root, Linker & l, unitNode * unit);
00185 
00188   virtual ~Pointers();
00189 
00190   inline Linker & getLinker() const { return linker; }
00191 
00193   virtual void run_unification();
00194 
00196   inline UnificationBasedPtr *unification_analyzer() const
00197   { return _unification_based; }
00198 
00199   inline void use_unification_analyzer(UnificationBasedPtr *u)
00200   { Memory.unification(_unification_based = u); }
00201 
00204   void analyze();
00205   void analyze(analysisProblem * problem);
00206 
00212   virtual void initialize() {}
00213 
00219   inline constantAnalyzer & get_constants() { return _constants; }
00220 
00223   void clear();
00224 
00227   void show_progress() { _show_progress = true; }
00228 
00231   void hide_progress() { _show_progress = false; }
00232 
00235   void turn_on_multiplicity() { _use_multiplicity = true; }
00236 
00239   void turn_off_multiplicity() { _use_multiplicity = false; }
00240 
00243   void analyze_procedure(procLocation * current,
00244                          memoryblock_set & defs,
00245                          memoryuse_set & uses,
00246                          memoryblock_set & changes);
00247 
00250   virtual void procedure_call(procedureInfo * caller,
00251                               stmtLocation * current,
00252                               operandNode * call,
00253             operand_list & args,
00254                               pointerValue & call_target,
00255                               memoryBlock * target_mb,
00256                               pointervalue_list & arguments,
00257                               memoryblock_set & external_defs,
00258                               memoryuse_set & external_uses,
00259                               memoryblock_set & external_changes,
00260                               pointerValue & return_val,
00261                               bool & never_returns);
00262 
00269   void analyze_procedure_at(procedureInfo * callee,
00270                             stmtLocation * callsite,
00271                             pointervalue_list & arguments,
00272                             memoryblock_set & external_defs,
00273                             memoryuse_set & external_uses,
00274                             memoryblock_set & external_changes,
00275                             pointerValue & return_val);
00276 
00279   void pass_parameters(procedureInfo * info,
00280                        stmtLocation * callsite,
00281                        pointervalue_list & arguments,
00282                        memoryblock_set & parameters,
00283                        memoryblock_set & changed_inputs);
00284 
00290   void pass_return_value(procedureInfo * info,
00291                          stmtLocation * current_callsite,
00292                          pointerValue & return_val,
00293                          memoryblock_set & changes);
00294 
00297   void process_merge_point(procedureInfo * info,
00298                            basicblockLocation * current_block,
00299                            pointerValue & result,
00300                            memoryblock_set & defs,
00301                            memoryuse_set & uses,
00302                            memoryblock_set & changes);
00303 
00309   void process_local_changes(procedureInfo * info,
00310                              basicblockLocation * current_block,
00311                              memoryblock_set & local_changes,
00312                              memoryblock_set & changes);
00313 
00328   void pass_external_inputs(procedureInfo * info,
00329                             stmtLocation * current_callsite,
00330                             memoryuse_set & external_uses,
00331                             memoryblock_set & changed_inputs);
00332 
00340   void pass_one_external_input(procedureInfo * callee,
00341                                procedureInfo * caller,
00342                                stmtLocation * current_callsite,
00343                                memoryBlock * block_to_pass,
00344                                memoryblock_set & changed_inputs);
00345 
00352   void pass_external_outputs(procedureInfo * info,
00353                              stmtLocation * current_callsite);
00354 
00366   void pass_one_external_output(procedureInfo * info,
00367                                 stmtLocation * current_callsite,
00368                                 memoryBlock * block_to_pass,
00369                                 bool is_return_val);
00370 
00378   void record_external_inputs_and_outputs(procedureInfo * callee,
00379                                           procLocation * current,
00380                                           pointervalue_list & arguments, //TB
00381                                           memoryblock_set & parameters,
00382                                           memoryblock_set & defs,
00383                                           memoryblock_set & external_defs,
00384                                           memoryuse_set & uses,
00385                                           memoryuse_set & external_uses,
00386                                           memoryblock_set & changes,
00387                                           memoryblock_set & external_changes);
00388 
00395   virtual void conservative_procedure_call(procedureInfo * info,
00396                                            stmtLocation * current,
00397                                            pointervalue_list & arguments,
00398                                            memoryblock_set & reachable,
00399                                            memoryblock_set & external_defs,
00400                                            memoryuse_set & external_uses,
00401                                            memoryblock_set & external_changes,
00402                                            pointerValue & return_val);
00403 
00406   void eval(procedureInfo * info,
00407             stmtLocation * current,
00408             exprNode * E,
00409             stmtNode *cur_stmt,
00410             memoryblock_set & defs,
00411             memoryuse_set & uses,
00412             memoryblock_set & changes,
00413             pointerValue & result,
00414             bool & never_returns);
00415 
00416   // TB: new.
00417   void eval(procedureInfo * info,
00418             stmtLocation * current,
00419             threeAddrNode *threeAddr,
00420             memoryblock_set & defs,
00421             memoryuse_set & uses,
00422             memoryblock_set & changes,
00423             pointerValue & result,
00424             bool & never_returns);
00425 
00428   void star_operator(procedureInfo * info,
00429                      Location * current,
00430                      pointerValue & operand,
00431                      memoryblock_set & defs,
00432                      memoryuse_set & uses,
00433                      memoryblock_set & changes,
00434                      pointerValue & result);
00435 
00438   void dot_operator(Location * current,
00439                     const string & field_name,
00440                     declNode * field_decl,
00441                     pointerValue & operand,
00442                     memoryuse_set & uses,
00443                     pointerValue & result);
00444 
00451   void struct_union_assignment(procedureInfo * info,
00452                                stmtLocation * current,
00453                                threeAddrNode *threeaddr,
00454                                sueNode * suetype,
00455                                pointerValue & left_hand_side,
00456                                pointerValue & right_hand_side,
00457                                memoryblock_set & defs,
00458                                memoryuse_set & uses,
00459                                memoryblock_set & changes);
00460 
00469   virtual void assignment_operator(procedureInfo * info,
00470                                    Location * current,
00471                                    stmtLocation * parameter_callsite,
00472                                    pointerValue & left_hand_side,
00473                                    pointerValue & right_hand_side,
00474                                    memoryblock_set & defs,
00475                                    memoryuse_set & uses,
00476                                    memoryblock_set & changes);
00477 
00482   void merge_operator(procedureInfo * info,
00483                       Location * current,
00484                       memoryBlock * block_to_merge,
00485                       memoryuse_list & phi_uses,
00486                       memoryblock_set & defs,
00487                       memoryuse_set & uses,
00488                       memoryblock_set & changes);
00489 
00496   void self_assignment(Location * from,
00497                        Location * to,
00498                        memoryBlock * block,
00499                        memoryblock_set & changes);
00500 
00505   void call_operator(procedureInfo * caller,
00506                      stmtLocation * current,
00507                      operandNode * call,
00508                      operand_list & args,
00509                      memoryblock_set & defs,
00510                      memoryuse_set & uses,
00511                      memoryblock_set & changes,
00512                      pointerValue & result,
00513                      pointerValue & call_targets,
00514                      bool & never_returns);
00515 
00523   void determine_call_targets(procedureInfo * caller,
00524                               stmtLocation * current,
00525                               operandNode * call,
00526                               memoryblock_set & defs,
00527                               memoryuse_set & uses,
00528                               memoryblock_set & changes,
00529                               pointerValue & targets);
00530 
00537   void generate_uses(procedureInfo * info,
00538                      Location * where,
00539                      memoryuse_set & uses,
00540                      pointerValue & pointer);
00541 
00549   memoryDef * nearest_def_at(procedureInfo * info,
00550                              memoryBlock * block,
00551                              Location * where);
00552 
00558   void reachable_blocks(Location * where,
00559                         memoryblock_list & worklist,
00560                         memoryblock_set & already_seen);
00561 
00564   procedureInfo * lookup_procedure(procNode * proc);
00565 
00568   bool is_pointer_expression(operandNode * operand);
00569 
00572   void stats(ostream & out);
00573 
00576   void uses_and_defs();
00577 
00580   void show_accuracy();
00581 
00582 protected:
00583 
00584   // -- Manage the heap
00585 
00593   memoryBlock * at_allocation(const string & name,
00594                               procedureInfo * info,
00595                               stmtLocation * current,
00596                               stmtNode * allocation_stmt,
00597                               declNode * decl,
00598                               memoryblock_set & defs,
00599                               memoryuse_set & uses,
00600                               memoryblock_set & changes,
00601                               pointerValue & result);
00602 
00609   void at_deallocation(procedureInfo * info,
00610                        Location * current,
00611                        pointerValue & to_deallocate,
00612                        memoryblock_set & defs,
00613                        memoryuse_set & uses,
00614                        memoryblock_set & changes);
00615 
00621   Multiplicity current_multiplicity(procedureInfo * info,
00622                                     Location * current,
00623                                     memoryBlock * block,
00624                                     memoryuse_set & uses);
00625 
00626   // memoryBlock * lookup_heap_object(stmtLocation * current);
00627 
00628   static bool is_allocation(pointerValue & call_targets);
00629 
00630   static bool is_deallocation(pointerValue & call_targets);
00631 
00632   static bool is_reallocation(pointerValue & call_targets);
00633 
00642   void mark_as_indexed(memoryblock_set & blocks);
00643 
00646   void setup_va_list_variables(procedureInfo * info,
00647                                procLocation * callee_path, 
00648                                stmtLocation * parameter_callsite,
00649                                procNode * callee,
00650                                memoryBlock * ellipsis);
00651 
00652   static bool is_va_list(declNode * decl);
00653   static bool is_va_list(exprNode * expr);
00654   static bool is_va_arg(pointerValue & call_targets);
00655   static bool is_va_start(pointerValue & call_targets);
00656   static bool is_va_end(pointerValue & call_targets);
00657 
00663   static bool is_exit(pointerValue & call_targets);
00664 
00667 public:
00668 
00669   static void merge(const memoryblock_set & source,
00670                     memoryblock_set & dest);
00671 
00672   static void print_memoryblock_set(const string & label,
00673                                     const memoryblock_set & the_set,
00674                                     ostream & o);
00675   
00676   static void print_memoryblock_def_set(const string & label,
00677                                         const memoryblock_set & the_set,
00678                                         ostream & o);
00679   
00680   static void print_memorydef_set(const string & label,
00681                                         const memorydef_set & the_set,
00682                                         ostream & o);
00683 
00686   void progress_meter(procedureInfo * info, bool skipped);
00687 
00690   static long int call_counter;
00691 
00694   double compute_accuracy(accuracy_map & accuracy_data);
00695 
00697   inline proc_info_map procedures() const { return Procedures.procedures(); }
00698 };
00699 
00700 #endif // CBZ_POINTERS_H

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