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 #ifndef CBZ_PROCEDUREDB_H
00038 #define CBZ_PROCEDUREDB_H
00039
00040 #include "pointers_common.h"
00041 #include "location.h"
00042 #include "dfpreds.h"
00043 #include "memoryaccess.h"
00044 #include "memoryblock.h"
00045 #include "worklist.h"
00046 #include "linker.h"
00047 #include "loops.h"
00048 #include "callgraph.h"
00049
00063 class procedureInfo
00064 {
00065 public:
00066
00067 typedef map< basicblockNode *, int > worklist_order_map;
00068 typedef worklist_order_map::iterator worklist_order_map_p;
00069
00070
00071
00072 typedef map< stmtLocation *, procedureInfo *> callsite_map;
00073 typedef callsite_map::iterator callsite_map_p;
00074 typedef callsite_map::const_iterator callsite_map_cp;
00075
00076 typedef map< basicblockLocation *, memoryblock_set > mergepoint_map;
00077 typedef mergepoint_map::iterator mergepoint_map_p;
00078
00079 typedef set< procedureInfo * > procedure_set;
00080 typedef procedure_set::iterator procedure_set_p;
00081 typedef procedure_set::const_iterator procedure_set_cp;
00082
00083 private:
00084
00087 procNode * _proc;
00088
00091 workList _worklist;
00092
00098 worklist_order_map _forward_worklist_order;
00099
00104 vector< basicblockNode * > _forward_basicblock_order;
00105
00111 worklist_order_map _backward_worklist_order;
00112
00117 vector< basicblockNode * > _backward_basicblock_order;
00118
00125 mergepoint_map _merge_points;
00126
00133 DFPreds * _dominance_frontiers;
00134
00141 loopTree * _loops;
00142
00149 callsite_map _callsites;
00150
00155 stmtLocation * _current_callsite;
00156
00161 bool _context_insensitive;
00162
00171 TREE procLocation * _only_context;
00172
00183 memoryblock_set _external_inputs;
00184
00194 memoryblock_set _external_outputs;
00195
00201 procedure_set _ancestors;
00202
00207 procedure_set _calls;
00208
00213 bool _is_recursive;
00214
00215 public:
00216
00217
00220 DFPreds * dominance_frontiers() const { return _dominance_frontiers; }
00221
00227 procedureInfo(procNode * the_proc);
00228
00231 ~procedureInfo();
00232
00239 void add_ancestor_set(procedure_set & ancestors);
00240
00246 void setup_call_at(procedureInfo * caller, stmtLocation * callsite);
00247
00253 void return_from();
00254
00257 inline procNode * proc() const { return _proc; }
00258
00261 inline string & name() { return proc()->decl()->name(); }
00262
00265 const procedure_set & ancestors() const { return _ancestors; }
00266
00271 inline const procedure_set & calls() const { return _calls; }
00272
00275 inline const callsite_map & callsites() const { return _callsites; }
00276
00279 inline stmtLocation * current_callsite() const { return _current_callsite; }
00280
00285 procedureInfo * current_caller();
00286
00291 procedureInfo * caller_at(stmtLocation * callsite);
00292
00297 bool is_current_call_recursive(procedureInfo * caller);
00298
00305 procLocation * current_procedure_location();
00306
00309
00315 void make_context_insensitive();
00316
00319 inline bool is_context_insensitive() const { return _context_insensitive; }
00320
00325 procLocation * get_context() const { return _only_context; }
00326
00331 basicblockLocation * external_inputs_mergepoint();
00332
00334
00337
00344 void setup_merge_point(memoryBlock * block_to_merge,
00345 basicblockLocation * cur);
00346
00352 memoryblock_set * lookup_merge_point(basicblockLocation * where);
00353
00355
00362
00365 const memoryblock_set & external_inputs() const { return _external_inputs; }
00366
00369 const memoryblock_set & external_outputs() const { return _external_outputs; }
00370
00379 bool add_external_input(memoryBlock * block);
00380
00391 bool add_external_output(memoryBlock * block);
00392
00394
00397
00402 basicblockNode * get_next_block(Direction dir);
00403
00409 void add_block(basicblockNode * block, Direction dir);
00410
00416 void add_reachable_blocks(basicblockNode * block, Direction dir);
00417
00422 void add_all_blocks();
00423
00429 void add_start_block(Direction dir);
00430
00436 bool is_empty() const;
00437
00439
00442 void print_call_stack(ostream & out);
00443
00446 void progress_meter(ostream & out);
00447
00450 void print(ostream & out);
00451
00457 void stats(ostream & out);
00458
00459 private:
00460
00467 void reverse_post_order(Direction dir,
00468 basicblockNode * cur,
00469 basicblock_set & visited,
00470 basicblock_list & order);
00471
00472
00473 int block_position(basicblockNode * block, Direction dir);
00474
00475 basicblockNode * block_at(int position, Direction dir);
00476
00477 void add_reachable_blocks_rec(Direction dir,
00478 basicblockNode * cur,
00479 worklist_set & temp, bool first);
00480 };
00481
00482 typedef map< procNode *, procedureInfo *> proc_info_map;
00483 typedef proc_info_map::iterator proc_info_map_p;
00484
00485 typedef list< procedureInfo *> proc_info_list;
00486 typedef proc_info_list::iterator proc_info_list_p;
00487
00495 class procedureDB : public Walker
00496 {
00497 public:
00498
00499 static bool _debug;
00500
00501 private:
00502
00507 proc_info_map _procedures;
00508
00511 callGraph * _callgraph;
00512
00520 procedureInfo::procedure_set _need_reanalysis;
00521
00522 public:
00523
00528 procedureDB();
00529
00532 ~procedureDB();
00533
00541 void build(procNode * root, Linker & linker);
00542
00547 void clear();
00548
00551 void add_procedure(procNode * proc);
00552
00556 procedureInfo * lookup(procNode * proc);
00557
00562 void setup_analysis();
00563
00570 bool is_in_scope(procedureInfo * info,
00571 memoryBlock * block);
00572
00579 void mark_for_reanalysis(procedureInfo * info);
00580
00587 bool is_reanalysis_required(procedureInfo * info);
00588
00596 int times_called(procedureInfo * info);
00597
00600 void stats(ostream & out);
00601
00604 int size() const { return _procedures.size(); }
00605
00606 };
00607
00608 #endif // CBZ_PROCEDUREDB_H