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
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 #ifndef opt_points_to_summary_INCLUDED
00063 #define opt_points_to_summary_INCLUDED
00064
00065 #include <vector>
00066 #include "id_map.h"
00067
00068 using idmap::ID_MAP;
00069
00070
00071 class ALIAS_RULE;
00072
00073 typedef enum {
00074 UN_NAMED_GLOBAL,
00075 UN_MALLOC,
00076 UN_ALLOCA,
00077 UN_FORMAL,
00078 UN_CALLER_LOCAL,
00079 UN_RET_VAL,
00080 } UNAME_TYPE;
00081
00082
00083 class SYMBOL_NAME {
00084 public:
00085 union {
00086 ST* sym;
00087 mUINT64 line_num;
00088 INT idx;
00089 };
00090
00091 SYMBOL_NAME (ST* symbol) : sym(symbol) {};
00092
00093
00094 SYMBOL_NAME (mUINT64 ln, BOOL not_used) : line_num(ln) {not_used=not_used;};
00095 SYMBOL_NAME (INT index) : idx(index) {};
00096 SYMBOL_NAME (void) : sym(NULL) {};
00097 };
00098
00099
00100
00101
00102
00103
00104 class UNAME_SPACE;
00105 class UNIFORM_NAME {
00106 friend class UNAME_SPACE;
00107 private:
00108
00109 UNAME_TYPE _type;
00110 INT32 _unique_id;
00111
00112
00113 SYMBOL_NAME _name;
00114 void Set_unique_id (INT32 i) { _unique_id = i; }
00115
00116 public:
00117 UNAME_TYPE Type (void) const { return _type; }
00118 BOOL Is_named_global (void) const { return _type == UN_NAMED_GLOBAL; }
00119 void Set_is_named_global (ST* st) {
00120 _type = UN_NAMED_GLOBAL; _name.sym = st;
00121 }
00122 ST* ST_for_named_global (void) const {
00123 Is_True (Is_named_global(), ("should be named global var"));
00124 return _name.sym;
00125 }
00126
00127 BOOL Is_malloc (void) const { return _type == UN_MALLOC; }
00128 void Set_is_malloc (mUINT64 id) { _type = UN_MALLOC; _name.line_num = id; }
00129 mUINT64 Malloc_id (void) const {
00130 Is_True (Is_malloc (), ("should be a symbol associated with malloc"));
00131 return _name.line_num;
00132 }
00133
00134 BOOL Is_alloca (void) const { return _type == UN_ALLOCA; }
00135 void Set_is_alloca (mUINT64 id) { _type = UN_ALLOCA; _name.line_num = id; }
00136 mUINT64 Alloca_id (void) const {
00137 Is_True (Is_alloca(), ("should be a symbol associated with alloca"));
00138 return _name.line_num;
00139 }
00140
00141 BOOL Is_formal (void) const { return _type == UN_FORMAL; }
00142 void Set_is_formal (INT idx) { _type = UN_FORMAL; _name.idx = idx;}
00143 INT Formal_index (void) const {
00144 Is_True (Is_formal(), ("Should be corresponding to a formal"));
00145 return _name.idx;
00146 }
00147
00148
00149
00150
00151
00152
00153
00154 BOOL Is_caller_local (void) const { return _type == UN_CALLER_LOCAL; }
00155 void Set_is_caller_local (ST* st) {
00156 _type = UN_CALLER_LOCAL;
00157
00158
00159
00160 _name.sym = (ST*)((INTPTR)st ^ 1);
00161 }
00162
00163 ST* Caller_local_st (void) {
00164 Is_True (Is_caller_local(), ("Should be caller's local symbol"));
00165 return _name.sym;
00166 }
00167
00168 INT32 Unique_id (void) const { return _unique_id; }
00169
00170
00171 UNIFORM_NAME (ST* st, UNAME_TYPE type) {
00172 if (type == UN_NAMED_GLOBAL) Set_is_named_global (st);
00173 else if (type == UN_CALLER_LOCAL) Set_is_caller_local (st);
00174 else {
00175 FmtAssert (FALSE, ("Unexpected type %d", (INT)type));
00176 }
00177 }
00178
00179 UNIFORM_NAME (mUINT64 line_num, UNAME_TYPE ty) {
00180 if (ty == UN_MALLOC) Set_is_malloc (line_num);
00181 else if (ty == UN_ALLOCA) Set_is_alloca (line_num);
00182 else {
00183 FmtAssert (FALSE, ("unexpected type %d", (INT)ty));
00184 }
00185 }
00186
00187 void Copy (const UNIFORM_NAME& that) {
00188 *this = that;
00189 }
00190
00191 UNIFORM_NAME (const UNIFORM_NAME& that) {
00192 *this = that;
00193 }
00194
00195 void Print (FILE* f);
00196 };
00197
00198
00199 typedef mempool_allocator<UNIFORM_NAME*> UNAME_ALLOC ;
00200 typedef std::vector<UNIFORM_NAME*, UNAME_ALLOC> UNAME_VECTOR;
00201 typedef UNAME_VECTOR::iterator UNAME_VECTOR_ITER;
00202
00203
00204 class UNAME_SPACE {
00205 private:
00206 MEM_POOL* _mp;
00207 ID_MAP<UNIFORM_NAME*, UINT32> _global_map;
00208 UNAME_VECTOR _all_names;
00209 UNAME_VECTOR _malloc_alloca;
00210 UNAME_VECTOR _formals;
00211 UNAME_VECTOR _caller_locals;
00212 INT32 _next_id;
00213
00214 void Append_new_name (UNIFORM_NAME* name);
00215
00216 public:
00217 UNAME_SPACE (INT32 estimated_sz, MEM_POOL* mp) :
00218 _mp(mp), _global_map(estimated_sz, NULL, mp, FALSE),
00219 _malloc_alloca(mp), _formals(mp), _caller_locals (mp) {
00220
00221 _global_map.Init ();
00222 _next_id = 1;
00223 };
00224 void Copy (UNAME_SPACE& that);
00225
00226 ~UNAME_SPACE (void) {}
00227
00228 UNAME_VECTOR& All_names (void) { return _all_names; }
00229
00230 UNIFORM_NAME* Get_name_by_id (INT32 id) {
00231 return (id > 0 && id <= _all_names.size()) ? _all_names[id-1] : NULL;
00232 }
00233
00234 UNIFORM_NAME* Get_global (ST* st) { return _global_map.Lookup(ST_index(st)); }
00235 UNIFORM_NAME* Get_malloc (mUINT64 mallocid) {
00236 for (UNAME_VECTOR_ITER iter = _malloc_alloca.begin ();
00237 iter != _malloc_alloca.end (); iter++) {
00238 UNIFORM_NAME* n = *iter;
00239 if (n->Is_malloc() && n->Malloc_id() == mallocid) return n;
00240 }
00241 return NULL;
00242 }
00243
00244 UNIFORM_NAME* Get_alloca (mUINT64 allocaid) {
00245 for (UNAME_VECTOR_ITER iter = _malloc_alloca.begin ();
00246 iter != _malloc_alloca.end (); iter++) {
00247 UNIFORM_NAME* n = *iter;
00248 if (n->Is_alloca () && n->Alloca_id() == allocaid) return n;
00249 }
00250 return NULL;
00251 }
00252
00253 UNIFORM_NAME* Get_formal (INT32 idx) {
00254 for (UNAME_VECTOR_ITER iter = _formals.begin ();
00255 iter != _formals.end (); iter++) {
00256 UNIFORM_NAME* n = *iter;
00257 if (n->Is_formal() && n->Formal_index() == idx) return n;
00258 }
00259 return NULL;
00260 }
00261
00262 UNIFORM_NAME* Get_uniform_name (const SYMBOL_NAME& name, UNAME_TYPE ty) {
00263 switch (ty) {
00264 case UN_NAMED_GLOBAL: return Get_global (name.sym);
00265 case UN_MALLOC: return Get_malloc (name.line_num);
00266 case UN_ALLOCA: return Get_alloca (name.line_num);
00267 case UN_FORMAL: return Get_formal (name.idx);
00268 default: Is_True (FALSE, ("ty is unknown %d", ty));
00269 }
00270 return NULL;
00271 }
00272
00273
00274
00275 UNIFORM_NAME* Add_global (ST*);
00276 UNIFORM_NAME* Add_malloc (mUINT64 mallocid);
00277 UNIFORM_NAME* Add_alloca (mUINT64 allocaid);
00278 UNIFORM_NAME* Add_formal (INT idx);
00279 UNIFORM_NAME* Add_caller_local (ST* localst);
00280
00281 INT Cardinality (void) const { return _all_names.size (); }
00282
00283
00284 void Print (FILE*, BOOL verbose=FALSE);
00285 };
00286
00287
00288
00289
00290
00291 typedef enum {
00292 PTC_POSSIBLE = 0,
00293 PTC_DEFINITE = 1,
00294 } PT_CERTAINTY;
00295
00296
00297
00298
00299
00300
00301
00302
00303 typedef enum {
00304 PT_MAY_POINTS_TO = 0,
00305 PT_MUST_POINTS_TO = 1,
00306 } PT_MAY_OR_MUST;
00307
00308 typedef enum {
00309 PTAS_INVALID = 0,
00310 PTAS_UNKNOWN = 1,
00311 PTAS_TEXT = 2,
00312 PTAS_GLOBAL = 4,
00313 PTAS_FSTATIC = 8,
00314 PTAS_LOCAL = 16,
00315 PTAS_INVISIBLE = 32,
00316
00317 } PT_ADDR_SPACE;
00318
00319
00320 typedef mempool_allocator<POINTS_TO*> PT_PTR_ALLOC ;
00321 typedef std::vector<POINTS_TO*, PT_PTR_ALLOC> PT_VECTOR;
00322 typedef PT_VECTOR::iterator PT_VECTOR_ITER;
00323
00324
00325 class PT_SET {
00326 private:
00327 MEM_POOL* _mp;
00328 PT_VECTOR _all_points_to;
00329
00330
00331 PT_ADDR_SPACE _addr_space;
00332 UINT32 _certainty:2;
00333 UINT32 _may_or_must:2;
00334 UINT32 _has_unknown_pt:2;
00335
00336 public:
00337 PT_SET (MEM_POOL* mp) : _mp(mp), _all_points_to(mp) {
00338 _addr_space = PTAS_INVALID;
00339 _certainty = PTC_DEFINITE;
00340 _may_or_must = PT_MUST_POINTS_TO;
00341 _has_unknown_pt = FALSE;
00342 }
00343
00344 PT_SET (PT_SET& pts) {
00345 FmtAssert (FALSE, ("MEMPOOL is not specified"));
00346 }
00347
00348 PT_SET (PT_SET& pts, MEM_POOL* mp);
00349
00350 void Copy (PT_SET& that);
00351
00352 PT_SET& operator = (PT_SET& that)
00353 { Copy (that); return *this; }
00354
00355 PT_VECTOR& Points_to_set (void) { return _all_points_to; }
00356 UINT32 Cardinality (void) const { return _all_points_to.size (); }
00357 void Add_points_to (POINTS_TO* pt, PT_CERTAINTY, PT_MAY_OR_MUST);
00358 PT_ADDR_SPACE Addr_Space (void) const { return _addr_space; }
00359
00360
00361 void Set_addr_space (PT_ADDR_SPACE addr_space) { _addr_space = addr_space; }
00362 PT_ADDR_SPACE Addr_space (void) const { return _addr_space; }
00363
00364 BOOL Has_unknown_pt (void) const { return _has_unknown_pt; }
00365 void Set_has_unkown_pt (void) { _has_unknown_pt = TRUE; }
00366 void Reset_has_unknown_pt (void) { _has_unknown_pt = FALSE; }
00367
00368 PT_CERTAINTY Certainty (void) const { return (PT_CERTAINTY)_certainty; }
00369 void Set_certainty (PT_CERTAINTY certainty) { _certainty = (UINT32)certainty; }
00370
00371
00372 BOOL Aliased (ALIAS_RULE* al, PT_SET* );
00373 BOOL Aliased (ALIAS_RULE* al, POINTS_TO*);
00374
00375
00376 BOOL More_Precise (PT_SET* that);
00377
00378
00379 void Meet (POINTS_TO* pt);
00380
00381 void Print (FILE*);
00382 };
00383
00384 typedef mempool_allocator<PT_SET*> PT_SET_ALLOC ;
00385 typedef std::vector<PT_SET*, PT_SET_ALLOC> PT_SET_VECTOR;
00386 typedef PT_SET_VECTOR::iterator PT_SET_VECTOR_ITER;
00387
00388
00389
00390 class PT_SET_MGR {
00391 private:
00392 MEM_POOL* _mp;
00393 UNAME_SPACE* _name_space;
00394 ID_MAP<PT_SET*, INT32> _nameidx_ptset_map;
00395
00396 public:
00397 PT_SET_MGR (MEM_POOL* mp, UNAME_SPACE* name_space = NULL) :
00398 _mp(mp), _name_space(name_space),
00399 _nameidx_ptset_map ((INT32)(name_space != NULL ?
00400 name_space->Cardinality () : 256),
00401 NULL, mp, FALSE)
00402 {
00403 if (_name_space == NULL) {
00404 _name_space = CXX_NEW (UNAME_SPACE(256, _mp), _mp);
00405 }
00406 _nameidx_ptset_map.Init ();
00407 }
00408
00409 void Copy (PT_SET_MGR& that);
00410
00411 ~PT_SET_MGR (void) {};
00412
00413 MEM_POOL* Mem_pool (void) const { return _mp; }
00414
00415 UNAME_SPACE* Name_space (void) const { return _name_space; }
00416
00417
00418 PT_SET* Points_to_set (UNIFORM_NAME* name) {
00419 Is_True (name == _name_space->Get_name_by_id(name->Unique_id()),
00420 ("name is not belong to the the name space"));
00421 return _nameidx_ptset_map.Lookup (name->Unique_id());
00422 }
00423
00424
00425 void Associate (UNIFORM_NAME* name, PT_SET* pt_set) {
00426 Is_True (name == _name_space->Get_name_by_id(name->Unique_id()),
00427 ("name is not belong to the the name space"));
00428 _nameidx_ptset_map.Insert (name->Unique_id(), pt_set);
00429 }
00430
00431
00432
00433
00434 void Substitute_If_More_Precise (UNIFORM_NAME* name, PT_SET* new_pt_set);
00435
00436 UNIFORM_NAME* Add_global (ST* st) { _name_space->Add_global (st);}
00437 UNIFORM_NAME* Add_malloc (mUINT64 id) { _name_space->Add_malloc(id);}
00438 UNIFORM_NAME* Add_alloca (mUINT64 id) { _name_space->Add_alloca(id);}
00439 UNIFORM_NAME* Add_formal (INT idx){ _name_space->Add_formal(idx);}
00440 UNIFORM_NAME* Add_caller_local (ST* localst) {_name_space->Add_caller_local(localst);}
00441
00442 void Print (FILE* f);
00443 };
00444
00445 class PU_POINTS_TO_SUMMARY {
00446 private:
00447 MEM_POOL* _mp;
00448
00449
00450 PT_SET_MGR _in_set, _out_set;
00451
00452
00453
00454
00455
00456
00457
00458
00459 public:
00460 static BOOL Pt_known_obj (POINTS_TO* pt) {
00461 return pt->Base_is_fixed() && pt->Base() ||
00462 pt->Malloc_id () != 0;
00463 }
00464
00465 PU_POINTS_TO_SUMMARY (MEM_POOL* mp):
00466 _mp(mp), _in_set(mp), _out_set(mp) {}
00467 PU_POINTS_TO_SUMMARY (const PU_POINTS_TO_SUMMARY& summary);
00468
00469 PT_SET_MGR& In_set (void) { return _in_set; }
00470 PT_SET_MGR& Out_set (void) { return _out_set; }
00471
00472 void Print (FILE* f);
00473 };
00474
00475 extern PU_POINTS_TO_SUMMARY* Allocate_PU_Points_To_Summary (ST* pu);
00476
00477
00478 extern PU_POINTS_TO_SUMMARY* Allocate_PU_Points_To_Summary (void);
00479
00480
00481 extern PU_POINTS_TO_SUMMARY* Get_points_to_summary (ST* pu);
00482
00483
00484 extern PU_POINTS_TO_SUMMARY* Get_points_to_summary (void);
00485
00486 #endif