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_POINTERS_H
00038 #define CBZ_POINTERS_H
00039
00040 #include "location.h"
00041 #include "memorymodel.h"
00042 #include "memoryblock.h"
00043 #include "proceduredb.h"
00044 #include "linker.h"
00045 #include "ipanalysis.h"
00046 #include "pointervalue.h"
00047
00048 typedef map< Location *, memoryBlock *> heap_map;
00049 typedef heap_map::iterator heap_map_p;
00050
00051 typedef list< memoryblock_set > memoryblock_set_list;
00052 typedef memoryblock_set_list::iterator memoryblock_set_list_p;
00053
00058 class Pointers
00059 {
00060 public:
00061
00062 typedef set< string > string_set;
00063 typedef string_set::iterator string_set_p;
00064
00065 protected:
00066
00072 memoryModel Memory;
00073
00080 heap_map HeapMap;
00081
00084 procNode * Root;
00085
00088 procLocation * root_location;
00089
00096 Linker linker;
00097
00103 procedureDB Procedures;
00104
00107 analysisProblem * Problem;
00108
00116 bool computePointers;
00117
00124 Direction _direction;
00125
00132 int _context_sensitivity_threshold;
00133
00136 bool _debug;
00137
00140 int _procedureCount;
00141
00144 int _skipCount;
00145
00148 bool _show_progress;
00149
00152 string_set _unknown_procedures;
00153
00154 public:
00155
00158 Pointers(procNode * root, unitNode * unit, bool debug = false);
00159
00162 ~Pointers();
00163
00166 void analyze();
00167 void analyze(analysisProblem * problem);
00168
00171 void reanalyze_at(procedureInfo * info, stmtLocation * callsite);
00172
00175 void clear();
00176
00184 void set_context_sensitivity_threshold(int threshold);
00185
00188 void show_progress() { _show_progress = true; }
00189
00192 void hide_progress() { _show_progress = false; }
00193
00196 void analyze_procedure(procLocation * current,
00197 memoryblock_set & external_defs,
00198 memoryuse_set & external_uses,
00199 memoryblock_set & external_changes,
00200 pointerValue & return_val);
00201
00204 virtual void procedure_call(procedureInfo * caller,
00205 stmtLocation * current,
00206 callNode * call,
00207 pointerValue & call_target,
00208 pointervalue_list & arguments,
00209 memoryblock_set & external_defs,
00210 memoryuse_set & external_uses,
00211 memoryblock_set & external_changes,
00212 pointerValue & return_val);
00213
00216 void pass_parameters(procedureInfo * info,
00217 procedureInfo * caller,
00218 procLocation * callee_path,
00219 procNode * callee,
00220 pointervalue_list & arguments,
00221 memoryblock_set & changed_inputs,
00222 pointerValue & return_val);
00223
00226 void process_merge_point(procedureInfo * info,
00227 basicblockLocation * current_block,
00228 pointerValue & result,
00229 memoryblock_set & defs,
00230 memoryuse_set & uses,
00231 memoryblock_set & changes);
00232
00240 void process_changes(procedureInfo * info,
00241 basicblockLocation * current_block,
00242 memoryblock_set & changes,
00243 memoryblock_set & external_changes);
00244
00259 void pass_external_inputs(procedureInfo * info,
00260 memoryuse_set & external_uses,
00261 memoryblock_set & changed_inputs);
00262
00273 void pass_external_outputs(procedureInfo * info,
00274 memoryblock_set & external_defs,
00275 memoryblock_set & external_changes);
00276
00284 void record_external_inputs_and_outputs(procedureInfo * info,
00285 procLocation * current,
00286 memoryblock_set & defs,
00287 memoryblock_set & external_defs,
00288 memoryuse_set & uses,
00289 memoryuse_set & external_uses);
00290
00297 void conservative_procedure_call(procedureInfo * info,
00298 stmtLocation * current,
00299 pointervalue_list & arguments,
00300 memoryblock_set & reachable,
00301 memoryblock_set & external_defs,
00302 memoryuse_set & external_uses,
00303 memoryblock_set & external_changes,
00304 pointerValue & return_val);
00305
00308 void eval(procedureInfo * info,
00309 stmtLocation * current,
00310 exprNode * E,
00311 memoryblock_set & defs,
00312 memoryuse_set & uses,
00313 memoryblock_set & changes,
00314 pointerValue & result,
00315 bool result_is_a_use);
00316
00319 void star_operator(stmtLocation * current,
00320 pointerValue & operand,
00321 memoryuse_set & uses,
00322 pointerValue & result);
00323
00326 void dot_operator(stmtLocation * current,
00327 const string & field_name,
00328 declNode * field_decl,
00329 pointerValue & operand,
00330 memoryuse_set & uses,
00331 pointerValue & result);
00332
00341 void assignment_operator(procedureInfo * info,
00342 Location * current,
00343 pointerValue & left_hand_side,
00344 pointerValue & right_hand_side,
00345 memoryblock_set & defs,
00346 memoryuse_set & uses,
00347 memoryblock_set & changes,
00348 bool additive = false);
00349
00354 void merge_operator(procedureInfo * info,
00355 Location * current,
00356 memoryBlock * block_to_merge,
00357 memoryuse_list & phi_uses,
00358 memoryblock_set & defs,
00359 memoryuse_set & uses,
00360 memoryblock_set & changes);
00361
00364 void call_operator(procedureInfo * caller,
00365 stmtLocation * current,
00366 callNode * call,
00367 memoryblock_set & defs,
00368 memoryuse_set & uses,
00369 memoryblock_set & changes,
00370 pointerValue & result);
00371
00372 void determine_call_targets(procedureInfo * caller,
00373 stmtLocation * current,
00374 callNode * call,
00375 memoryblock_set & defs,
00376 memoryuse_set & uses,
00377 memoryblock_set & changes,
00378 pointerValue & targets);
00379
00386 void generate_uses(procedureInfo * info,
00387 Location * where,
00388 memoryuse_set & uses,
00389 pointerValue & pointer);
00390
00400 memoryDef * nearest_def_at(procedureInfo * info,
00401 memoryBlock * block,
00402 Location * where);
00403
00409 void reachable_blocks(Location * where,
00410 memoryblock_list & worklist,
00411 memoryblock_set & already_seen);
00412
00415 memoryBlock * lookup_memoryblock(Location * location, declNode * decl);
00416
00419 procedureInfo * lookup_procedure(procNode * proc);
00420
00423 bool is_pointer_expression(exprNode * expr);
00424
00427 void stats(ostream & out);
00428
00431 void uses_and_defs();
00432
00433 protected:
00434
00437 memoryBlock * lookup_heap_object(stmtLocation * current);
00438
00439 static bool is_allocation(pointerValue & call_targets);
00440
00441 static bool is_deallocation(pointerValue & call_targets);
00442
00443 memoryBlock * lookup_string_constant(stmtLocation * current,
00444 constant & value);
00445
00448 void setup_va_list_variables(procedureInfo * info,
00449 procLocation * callee_path,
00450 procNode * callee,
00451 memoryBlock * ellipsis,
00452 pointerValue & return_val);
00453
00454 static bool is_va_list(declNode * decl);
00455 static bool is_va_list(exprNode * expr);
00456
00457 static bool is_va_start(pointerValue & call_targets);
00458
00459 static bool is_va_end(pointerValue & call_targets);
00460
00463 static void merge(const memoryblock_set & source,
00464 memoryblock_set & dest);
00465
00466 static void print_memoryblock_set(const string & label,
00467 const memoryblock_set & the_set,
00468 ostream & o);
00469
00470 static void print_memoryblock_def_set(const string & label,
00471 const memoryblock_set & the_set,
00472 ostream & o);
00473
00474 static void print_memorydef_set(const string & label,
00475 const memorydef_set & the_set,
00476 ostream & o);
00477
00480 void progress_meter(procedureInfo * info, bool skipped);
00481 };
00482
00483 #endif // CBZ_POINTERS_H