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
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"
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,
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
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
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
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 };
00696
00697 #endif // CBZ_POINTERS_H