|
||
Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages
proceduredb.hGo to the documentation of this file.00001 // $Id: proceduredb.h,v 1.41 2003/09/29 14:23: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_PROCEDUREDB_H 00039 #define CBZ_PROCEDUREDB_H 00040 00041 class memoryBlock; 00042 00043 #include "pointeroptions.h" 00044 #include "location.h" 00045 #include "dfpreds.h" 00046 #include "memoryaccess.h" 00047 #include "worklist.h" 00048 #include "linker.h" 00049 #include "loops.h" 00050 #include "callgraph.h" 00051 #include "cbztimer.h" 00052 00053 class procedureInfo; 00054 00055 typedef set< procedureInfo * > procedureinfo_set; 00056 typedef procedureinfo_set::iterator procedureinfo_set_p; 00057 typedef procedureinfo_set::const_iterator procedureinfo_set_cp; 00058 00059 typedef pair< basicblockNode *, basicblockNode *> cfg_edge_pair; 00060 typedef set< cfg_edge_pair > cfg_edge_set; 00061 typedef cfg_edge_set::iterator cfg_edge_set_p; 00062 00076 class procedureInfo 00077 { 00078 public: 00079 00080 typedef map< basicblockNode *, int > worklist_order_map; 00081 typedef worklist_order_map::iterator worklist_order_map_p; 00082 00083 // -- This is a map from callsites to the caller 00084 00085 typedef map< stmtLocation *, procedureInfo *> callsite_map; 00086 typedef callsite_map::iterator callsite_map_p; 00087 typedef callsite_map::const_iterator callsite_map_cp; 00088 00089 typedef map< basicblockLocation *, memoryblock_set > mergepoint_map; 00090 typedef mergepoint_map::iterator mergepoint_map_p; 00091 00092 // -- Pending changes 00093 00094 typedef map< stmtLocation *, memoryblock_set> callsite_changes_map; 00095 typedef callsite_changes_map::iterator callsite_changes_map_p; 00096 00097 // -- For use in counting contexts: 00098 00099 typedef map< procedureInfo *, int > proc_int_map; 00100 typedef proc_int_map::iterator proc_int_map_p; 00101 00102 private: 00103 00106 procNode * _proc; 00107 00110 workList _worklist; 00111 00117 worklist_order_map _forward_worklist_order; 00118 00123 vector< basicblockNode * > _forward_basicblock_order; 00124 00130 worklist_order_map _backward_worklist_order; 00131 00136 vector< basicblockNode * > _backward_basicblock_order; 00137 00144 mergepoint_map _merge_points; 00145 00152 DFPreds * _dominance_frontiers; 00153 00160 loopTree * _loops; 00161 00168 callsite_map _callsites; 00169 00175 declNode * _return_variable; 00176 00182 memoryBlock * _return_block; // TB 00183 00188 returnNode * _return_stmt; 00189 00197 bool _never_returns; 00198 00218 callsite_changes_map _pending_changes; 00219 00230 bool _context_insensitive; 00231 00238 bool _prefer_context_sensitive; 00239 00248 TREE procLocation * _only_context; 00249 00260 memoryblock_set _external_inputs; 00261 00271 memoryblock_set _external_outputs; 00272 00274 map<memoryBlock*,memoryblock_set> _input_values; // TB 00275 00276 typedef pair<memoryBlock*,stmtLocation*> block_loc_pair; // TB 00277 00280 map<block_loc_pair,memoryblock_set> _input_site_values; // TB 00281 00287 procedureinfo_set _ancestors, /*TB*/ _decestors; 00288 00294 procedureInfo * _first_caller; 00295 00300 procedureinfo_set _calls; 00301 00306 bool _is_recursive; 00307 00314 basicblock_set _blocks_to_skip; 00315 00320 cfg_edge_set _active_edges; 00321 00327 typedef map< basicblockNode *, basicblockNode * > true_branch_map; 00328 typedef true_branch_map::iterator true_branch_map_p; 00329 00330 true_branch_map _true_branches; 00331 00336 int _analysis_count; 00337 00343 bool _verbose; 00344 00350 cbzTimer _self_timer; 00351 00357 cbzTimer _total_timer; 00358 00360 int _cg_depth_min, _cg_depth_max; // TB 00361 00363 int _cg_height_min, _cg_height_max; // TB 00364 00365 public: 00366 00367 // EDB: Added! 00370 DFPreds * dominance_frontiers() const { return _dominance_frontiers; } 00371 00377 procedureInfo(procNode * the_proc); 00378 00381 ~procedureInfo(); 00382 00389 void add_one_ancestor(procedureInfo *ancestor); 00390 00397 void add_ancestor_set(procedureinfo_set & ancestors); 00398 00405 void setup_call_at(procedureInfo * caller, 00406 stmtLocation * callsite, 00407 bool is_recursive_call, 00408 bool multiple_target_call); 00409 00420 inline procNode * proc() const { return _proc; } 00421 00424 inline string & name() { return proc()->decl()->name(); } 00425 00431 string qualified_name(); 00432 00435 const procedureinfo_set & ancestors() const { return _ancestors; } 00436 00441 inline const procedureinfo_set & calls() const { return _calls; } 00442 00445 inline const callsite_map & callsites() const { return _callsites; } 00446 00449 inline procedureInfo * first_caller() const { return _first_caller; } 00450 00456 inline bool is_recursive() const { return _is_recursive; } 00457 00463 inline void set_recursive() { _is_recursive = true; } 00464 00471 inline declNode * return_variable() const { return _return_variable; } 00472 00477 inline memoryBlock * return_block() const { return _return_block; } 00478 00483 inline void return_block(memoryBlock *r) { _return_block = r; } 00484 00489 inline returnNode * return_stmt() const { return _return_stmt; } 00490 00496 inline bool never_returns() const { return _never_returns; } 00497 00504 inline void set_never_returns() { _never_returns = true; } 00505 00513 void set_pending_changes(stmtLocation * callsite, memoryblock_set & changes); 00514 00521 void get_pending_changes(stmtLocation * callsite, memoryblock_set & changes); 00522 00538 procedureInfo * caller_at(stmtLocation * callsite); 00539 00544 bool is_ancestor(procedureInfo * other); 00545 00552 procLocation * procedure_location(stmtLocation * callsite); 00553 00556 00559 inline bool is_context_insensitive() const { return _context_insensitive; } 00560 00563 inline bool prefer_context_sensitive() const { return _prefer_context_sensitive; } 00564 00567 inline void set_prefer_context_sensitive() { _prefer_context_sensitive = true; } 00568 00573 procLocation * get_context() const { return _only_context; } 00574 00576 00579 00586 void setup_merge_point(memoryBlock * block_to_merge, 00587 basicblockLocation * cur); 00588 00594 memoryblock_set * lookup_merge_point(basicblockLocation * where); 00595 00601 void check_merge_point(memoryBlock * block_to_merge, 00602 basicblockLocation * cur); 00603 00605 00612 00615 const memoryblock_set & external_inputs() const { return _external_inputs; } 00616 00619 const memoryblock_set & external_outputs() const { return _external_outputs; } 00620 00629 bool add_external_input(memoryBlock * block); 00630 00641 bool add_external_output(memoryBlock * block); 00642 // TB 00644 void record_input_to_value(memoryBlock *block, stmtLocation *loc, 00645 memoryblock_set points_to) { 00646 _input_values[block] = points_to; 00647 _input_site_values[block_loc_pair(block,loc)] = points_to; 00648 } 00649 00651 // TB 00652 memoryblock_set input_to_value(memoryBlock *block) const { 00653 if(_input_values.find(block) == _input_values.end()) 00654 return memoryblock_set(); 00655 return _input_values.find(block)->second; 00656 } 00657 00660 // TB 00661 memoryblock_set input_to_value(memoryBlock *block, stmtLocation *loc) const { 00662 block_loc_pair p(block,loc); 00663 if(_input_site_values.find(p) == _input_site_values.end()) 00664 return memoryblock_set(); 00665 return _input_site_values.find(p)->second; 00666 } 00667 00669 00672 00677 basicblockNode * get_next_block(Direction dir); 00678 00684 void add_block(basicblockNode * block, Direction dir); 00685 00691 void add_reachable_blocks(basicblockNode * block, Direction dir); 00692 00697 void add_all_blocks(); 00698 00704 void add_start_block(Direction dir); 00705 00711 bool is_empty() const; 00712 00718 void remove_branch_blocks(basicblockNode * cond, 00719 basicblockNode * branch_taken, 00720 basicblockNode * branch_not_taken); 00721 00726 void update_conditional_worklist(basicblockNode * block, 00727 bool has_truth_value, 00728 bool which_branch); 00729 00734 inline cfg_edge_set & active_edges() { return _active_edges; } 00735 00737 00740 inline int analysis_count() const { return _analysis_count; } 00741 00744 inline void incr_analysis_count() { _analysis_count++; } 00745 00748 inline bool is_verbose() const { return _verbose; } 00749 00754 bool is_library_routine() { return (proc()->decl()->decl_location() == declNode::UNKNOWN); } 00755 00758 void print(ostream & out); 00759 00765 void stats(ostream & out); 00766 00771 int count_calling_contexts(); 00772 00778 int procedure_size(); 00779 00782 void start_self_timer() { _self_timer.start(); } 00783 00786 void stop_self_timer() { _self_timer.stop(); } 00787 00790 double self_timer() { return _self_timer.time(); } 00791 00794 void start_total_timer() { _total_timer.start(); } 00795 00798 void stop_total_timer() { _total_timer.stop(); } 00799 00802 double total_timer() { return _total_timer.time(); } 00803 00804 // TB 00805 void update_cg_statistics_call(procedureInfo *callee); 00806 void update_cg_statistics_return(procedureInfo *callee); 00807 void get_cg_statistics(int &cg_depth_min, int &cg_depth_max, 00808 int &cg_height_min, int &cg_height_max); 00809 00810 private: 00811 00816 int count_calling_contexts_rec(proc_int_map & count, 00817 stmtNode * callsite); 00818 00825 void reverse_post_order(Direction dir, 00826 basicblockNode * cur, 00827 basicblock_set & visited, 00828 basicblock_list & order); 00829 00834 void dfs_dominators(Direction dir, 00835 basicblockNode * cur, 00836 basicblock_set & visited, 00837 basicblock_list & order, 00838 basicblock_list & rpo_order); 00839 00840 int block_position(basicblockNode * block, Direction dir); 00841 00842 basicblockNode * block_at(int position, Direction dir); 00843 00844 void add_reachable_blocks_rec(Direction dir, 00845 basicblockNode * cur, 00846 worklist_set & temp, bool first); 00847 }; 00848 00849 typedef map< procNode *, procedureInfo *> proc_info_map; 00850 typedef proc_info_map::iterator proc_info_map_p; 00851 00852 typedef list< procedureInfo *> proc_info_list; 00853 typedef proc_info_list::iterator proc_info_list_p; 00854 00855 typedef pair< stmtLocation *, procedureInfo * > procedurecall_pair; 00856 00857 typedef list< procedurecall_pair> procedurecall_stack; 00858 typedef procedurecall_stack::iterator procedurecall_stack_p; 00859 typedef procedurecall_stack::const_iterator procedurecall_stack_cp; 00860 typedef procedurecall_stack::reverse_iterator procedurecall_stack_rp; 00861 typedef procedurecall_stack::const_reverse_iterator procedurecall_stack_crp; 00862 00870 class procedureDB : public Walker 00871 { 00872 private: 00873 00878 proc_info_map _procedures; 00879 00882 callGraph * _callgraph; 00883 00891 procedureinfo_set _need_reanalysis; 00892 00895 procedureInfo * _root; 00896 00902 procedurecall_stack _callstack; 00903 00908 proc_info_list _worklist; 00909 00910 public: 00911 00916 procedureDB(); 00917 00920 ~procedureDB(); 00921 00929 void build(procNode * root, Linker & linker); 00930 00935 void clear(); 00936 00939 void add_procedure(procNode * proc); 00940 00944 procedureInfo * lookup(procNode * proc); 00945 00950 inline const procedurecall_stack & callstack() const { return _callstack; } 00951 00957 bool is_recursive_call(procedureInfo * callee, 00958 int & num_instances); 00959 00964 void setup_analysis(); 00965 00970 procedureInfo * next_procedure_on_worklist(); 00971 00976 bool is_procedure_on_worklist(procedureInfo * info); 00977 00981 void add_procedure_to_worklist(procedureInfo * info); 00982 00989 void call_to(stmtLocation * callsite, procedureInfo * callee); 00990 00996 void return_from(); 00997 01003 bool is_visible_to_caller(procedureInfo * info, 01004 memoryBlock * block); 01005 01012 bool is_visible_to(procedureInfo * info, 01013 memoryBlock * block); 01014 01018 inline stmtLocation * current_callsite() { return _callstack.back().first; } 01019 01024 procedureInfo * current_caller(); 01025 01030 void clear_call_stack(); 01031 01034 void print_call_stack(ostream & out); 01035 01038 void progress_meter(ostream & out); 01039 01047 void mark_for_reanalysis(procedureInfo * info, 01048 stmtLocation * callsite, 01049 bool include_self); 01050 01055 void mark_one_for_reanalysis(procedureInfo * info); 01056 01063 bool is_reanalysis_required(procedureInfo * info); 01064 01067 void print_leftovers(); 01068 01076 int times_called(procedureInfo * info); 01077 01080 void stats(ostream & out); 01081 01084 int size() const { return _procedures.size(); } 01085 01090 void number_of_procedures(int & total, int & analyzed, 01091 int & context_insensitive, 01092 int & recursive, 01093 int & unanalyzed, 01094 int & program_size); 01095 01096 01098 inline proc_info_map procedures() const { return _procedures; } 01099 }; 01100 01101 #endif // CBZ_PROCEDUREDB_H |
Generated on February 1, 2006
Back to the C-Breeze home page