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 #ifdef USE_PCH
00030 #include "be_com_pch.h"
00031 #endif
00032
00033 #include "defs.h"
00034 #include "config.h"
00035 #include "errors.h"
00036
00037 #include <vector>
00038 using namespace std;
00039
00040 #include "wn.h"
00041 #include "wn_map.h"
00042 #include "cxx_memory.h"
00043 #include "tracing.h"
00044
00045 #include "be_memop_annot.h"
00046
00047 WN_MEMOP_ANNOT_MGR* WN_MEMOP_ANNOT_MGR::_unique_instance = NULL;
00048 MEMOP_ANNOT_MGR* MEMOP_ANNOT_MGR::active_mgr = NULL;
00049
00050 BOOL
00051 MEMOP_ANNOT_ITEM::operator == (const MEMOP_ANNOT_ITEM& that) const {
00052 BOOL equ = FALSE;
00053 if (Kind() == that.Kind()) {
00054 switch (Kind()) {
00055 case MEM_ANNOT_INVALID: break;
00056 case MEM_ANNOT_MALLOC_ID:
00057 equ = (Malloc_id () == that.Malloc_id());
00058 break;
00059 case MEM_ANNOT_LMV_ALIAS_GROUP:
00060 equ = (LMV_alias_group () == that.LMV_alias_group ());
00061 break;
00062
00063 default:
00064 FmtAssert (FALSE, ("Unknown kind %d", Kind()));
00065 }
00066 }
00067 return equ;
00068 }
00069
00071
00072
00073
00075
00076
00077
00078
00079 BOOL
00080 MEMOP_ANNOT::Lookup (MEM_ANNOT_KIND kind, MEMOP_ANNOT_ITEM& res) const {
00081
00082 if (_kinds & kind) {
00083 for (MEMOP_ANNOT_ITEM_CITER iter = _vect.begin ();
00084 iter != _vect.end (); iter++) {
00085 if ((*iter).Kind() == kind) {
00086 res = *iter;
00087 return TRUE;
00088 }
00089 }
00090 Is_True (FALSE, ("Fail to find the annotation of kind %d", kind));
00091 }
00092
00093 return FALSE;
00094 }
00095
00096 void
00097 MEMOP_ANNOT::Remove (MEM_ANNOT_KIND kind) {
00098
00099 if (_kinds & kind) {
00100 for (MEMOP_ANNOT_ITEM_ITER iter = _vect.begin ();
00101 iter != _vect.end (); iter++) {
00102 if ((*iter).Kind() == kind) {
00103 *iter = _vect.back ();
00104 _vect.pop_back ();
00105 Remove_kind (kind);
00106 return;
00107 }
00108 }
00109 Is_True (FALSE, ("Fail to kind the annotation of kind %d", kind));
00110 }
00111 }
00112
00113 void
00114 MEMOP_ANNOT::Replace_or_add (const MEMOP_ANNOT_ITEM& annot) {
00115
00116 if (annot.Kind() == MEM_ANNOT_INVALID &&
00117 annot.Kind() > MEM_ANNOT_LAST_KIND) {
00118 DevWarn ("Add a invalid item") ;
00119 return;
00120 }
00121
00122 MEM_ANNOT_KIND kind = annot.Kind ();
00123 if (_kinds & kind) {
00124 for (MEMOP_ANNOT_ITEM_ITER iter = _vect.begin ();
00125 iter != _vect.end (); iter++) {
00126 if ((*iter).Kind() == kind) {
00127 *iter = annot;
00128 }
00129 return;
00130 }
00131 Is_True (FALSE, ("Fail to kind the annotation of kind %d", kind));
00132 }
00133 _vect.push_back (annot);
00134 _kinds = MEM_ANNOT_KIND(UINT(_kinds) | UINT(annot.Kind()));
00135 }
00136
00137 void
00138 MEMOP_ANNOT::Meet (const MEMOP_ANNOT_ITEM* that) {
00139
00140 MEMOP_ANNOT_ITEM match;
00141 BOOL find_match = Lookup (that->Kind(), match) && match == (*that);
00142 Remove_all ();
00143
00144 if (find_match) {
00145 _vect.push_back (match);
00146 _kinds = that->Kind();
00147 }
00148 }
00149
00151
00152
00153
00154
00155
00157
00158 void
00159 MEMOP_ANNOT::Meet (const MEMOP_ANNOT* that) {
00160
00161 BOOL change = FALSE;
00162
00163 for (MEMOP_ANNOT_ITEM_ITER iter = _vect.begin ();
00164 iter != _vect.end (); iter++) {
00165 MEMOP_ANNOT_ITEM& item = *iter;
00166 MEMOP_ANNOT_ITEM item2;
00167 if (!Lookup (item.Kind(), item2) || item == item2) {
00168
00169 item.Set_kind (MEM_ANNOT_INVALID);
00170 change = TRUE;
00171 }
00172 }
00173
00174 if (change) {
00175 MEMOP_ANNOT_ITEM_VECT t;
00176 Clear_kinds ();
00177
00178 for (MEMOP_ANNOT_ITEM_ITER iter = _vect.begin (); iter != _vect.end (); iter++) {
00179
00180 if ((*iter).Kind () != MEM_ANNOT_INVALID) {
00181 t.push_back (*iter);
00182 Add_kind ((*iter).Kind());
00183 }
00184 }
00185 _vect = t;
00186 }
00187 }
00188
00189 void
00190 MEMOP_ANNOT::Union (const MEMOP_ANNOT* that) {
00191
00192 if (that == NULL) return;
00193 const MEMOP_ANNOT_ITEM_VECT* vect = &that->_vect;
00194 for (MEMOP_ANNOT_ITEM_CITER iter = vect->begin ();
00195 iter != vect->end (); iter++) {
00196
00197 const MEMOP_ANNOT_ITEM& item = *iter;
00198 MEMOP_ANNOT_ITEM item2;
00199 if (!Lookup (item.Kind(), item2)) {
00200 _vect.push_back (item2);
00201 Add_kind (item2.Kind());
00202 } else if (item != item2) {
00203 DevWarn ("memory annotations of kind %d does not agree", item2.Kind());
00204 };
00205 }
00206 }
00207
00209
00210
00211
00213
00214 MEMOP_ANNOT_MGR::MEMOP_ANNOT_MGR (MEM_POOL* mp):
00215 _mp(mp), _all_annot(mp), _recycled_annot (mp) {
00216
00217 _all_annot.push_back (NULL);
00218 _last_id = 0;
00219
00220
00221
00222 _all_annot.reserve (512 * sizeof (MEMOP_ANNOT*));
00223 _recycled_annot.reserve (512 * sizeof(MEMOP_ANNOT*));
00224 }
00225
00226 void
00227 MEMOP_ANNOT_MGR::Init (void) {
00228
00229 for (MOA_VECT_ITER iter = _all_annot.begin ();
00230 iter != _all_annot.end (); iter++) {
00231 if (*iter != NULL)
00232 _recycled_annot.push_back (*iter);
00233 }
00234 _all_annot.clear ();
00235 _all_annot.push_back (NULL);
00236 _last_id = 0;
00237 }
00238
00239 MEMOP_ANNOT*
00240 MEMOP_ANNOT_MGR::Alloc_annot (void) {
00241 MEMOP_ANNOT* t;
00242 if (_recycled_annot.empty()) {
00243 t = CXX_NEW (MEMOP_ANNOT(_mp, ++_last_id), _mp);
00244 } else {
00245 t = _recycled_annot.back ();
00246 _recycled_annot.pop_back ();
00247 t->Recycle(++_last_id);
00248 }
00249 _all_annot.push_back (t);
00250 Is_True (_all_annot[_last_id] == t && t->Id() == _last_id,
00251 ("Inconsistent status"));
00252
00253 return t;
00254 }
00255
00257
00258
00259
00261 void
00262 WN_MEMOP_ANNOT_MGR::Init (void) {
00263
00264 MEMOP_ANNOT_MGR::Init ();
00265 if (_wn_map != WN_MAP_UNDEFINED) { WN_MAP_Delete (_wn_map);}
00266 _wn_map = WN_MAP_Create (_mp);
00267 }
00268
00269 WN_MEMOP_ANNOT_MGR::WN_MEMOP_ANNOT_MGR (MEM_POOL* mp):
00270 MEMOP_ANNOT_MGR(mp) {
00271
00272 Is_True (_unique_instance == NULL,
00273 ("WN_MEMOP_ANNOT_MGR disallow more than one instance"));
00274
00275 _unique_instance = this;
00276 _wn_map = WN_MAP_UNDEFINED;
00277 }
00278
00279 WN_MEMOP_ANNOT_MGR::~WN_MEMOP_ANNOT_MGR (void) {
00280 _unique_instance = NULL;
00281 if (_wn_map != WN_MAP_UNDEFINED) { WN_MAP_Delete (_wn_map);}
00282 }
00283
00285
00286
00287
00289
00290 void
00291 PT_MEM_ANNOT::Remove_annot (MEM_ANNOT_KIND kind) {
00292 if (_flags == USE_INLINE_ITEM) {
00293 if (kind == _inlined_annot.Kind()) {
00294 _flags = (PT_MEM_ANNOT_SELECTOR)0;
00295 }
00296 return;
00297 } else if (_flags == USE_ANNOT_PTR) {
00298 _annot_ptr->Remove (kind);
00299 }
00300 }
00301
00302 void
00303 PT_MEM_ANNOT::Replace_or_add_annot (const MEMOP_ANNOT_ITEM& item) {
00304
00305 if (item.Kind() == MEM_ANNOT_INVALID) return;
00306
00307
00308 if (item.Is_invalid()) {
00309 Remove_annot (item.Kind());
00310 return;
00311 }
00312
00313 if (!_flags ||
00314 _flags == USE_INLINE_ITEM && item.Kind() == _inlined_annot.Kind()) {
00315
00316 _inlined_annot = item;
00317 _flags = USE_INLINE_ITEM;
00318 return;
00319 }
00320
00321 if (_flags == USE_ANNOT_PTR) {
00322
00323 _annot_ptr->Replace_or_add (item);
00324 return;
00325 }
00326
00327 Is_True (_flags == USE_INLINE_ITEM, ("Incorrect selector"));
00328
00329
00330 MEMOP_ANNOT_MGR* p = MEMOP_ANNOT_MGR::Active_mgr ();
00331 if (p) {
00332 _annot_ptr = p->Alloc_annot_v ();
00333 _annot_ptr->Replace_or_add (item);
00334 _annot_ptr->Replace_or_add (_inlined_annot);
00335 _flags = USE_ANNOT_PTR;
00336 } else {
00337 DevWarn ("fail to add annotations because no active annotation manager");
00338 }
00339 }
00340
00341 void
00342 PT_MEM_ANNOT::Replace_or_add_annots (MEMOP_ANNOT* annots) {
00343
00344
00345 Is_True (MEMOP_ANNOT_MGR::Active_mgr()->Alloc_by_this_class (annots),
00346 ("Annotation should be allocated by current active annotation manager"));
00347
00348 if (_flags == USE_INLINE_ITEM) {
00349 if (!_inlined_annot.Is_invalid()) {
00350 annots->Replace_or_add (_inlined_annot);
00351 }
00352 } else {
00353 Is_True (!_flags || _flags == USE_ANNOT_PTR, ("Incorrect flags"));
00354 if (_flags == USE_ANNOT_PTR)
00355 annots->Union (_annot_ptr);
00356 }
00357
00358 _flags = USE_ANNOT_PTR;
00359 _annot_ptr = annots;
00360 }
00361
00362 void
00363 PT_MEM_ANNOT::Set_malloc_id (UINT64 id) {
00364 if (id != INVALID_ITEM_VALUE) {
00365 MEMOP_ANNOT_ITEM t;
00366 t.Set_malloc_id (id);
00367 Replace_or_add_annot (t);
00368 } else {
00369 Remove_annot (MEM_ANNOT_MALLOC_ID);
00370 }
00371 }
00372
00373 void
00374 PT_MEM_ANNOT::Set_LMV_alias_group (LMV_ALIAS_GROUP grp_id) {
00375
00376 if (grp_id != INVALID_ITEM_VALUE) {
00377 MEMOP_ANNOT_ITEM t;
00378 t.Set_LMV_alias_group (grp_id);
00379 Replace_or_add_annot (t);
00380 } else {
00381 Remove_annot (MEM_ANNOT_LMV_ALIAS_GROUP);
00382 }
00383 }
00384
00385 BOOL
00386 PT_MEM_ANNOT::Lookup (MEM_ANNOT_KIND kind, MEMOP_ANNOT_ITEM& t) const {
00387 if (!_flags) return FALSE;
00388 if (_flags == USE_INLINE_ITEM) {
00389 t = _inlined_annot;
00390 return !t.Is_invalid () && t.Kind() == kind;
00391 } else {
00392 Is_True (_flags == USE_ANNOT_PTR, ("Incorrect flags"));
00393 return _annot_ptr->Lookup (kind, t);
00394 }
00395 }
00396
00397 void
00398 PT_MEM_ANNOT::Meet (const PT_MEM_ANNOT& that) {
00399 if (!Has_annotation ()) return;
00400
00401 if (!that.Has_annotation ()) {
00402 Invalidate (); return;
00403 }
00404
00405 if (Item_is_inlined ()) {
00406
00407 const MEMOP_ANNOT_ITEM& i1 = Get_inlined_item();
00408 if (that.Item_is_inlined()) {
00409 const MEMOP_ANNOT_ITEM& i2 = that.Get_inlined_item();
00410 if (i1 != i2) {
00411 Invalidate ();
00412 }
00413 } else {
00414 MEMOP_ANNOT_ITEM t;
00415 if (!that.Get_annots_ptr()->Lookup (i1.Kind(), t) || i1 != t) {
00416 Invalidate ();
00417 }
00418 }
00419 } else {
00420 if (that.Item_is_inlined())
00421 Get_annots_ptr()->Meet (&that.Get_inlined_item());
00422 else {
00423 Get_annots_ptr()->Meet (that.Get_annots_ptr());
00424 }
00425 }
00426 }
00427
00429
00430
00431
00433
00434 void
00435 MEMOP_ANNOT_ITEM::Print (FILE* f) const {
00436 switch (Kind()) {
00437 case MEM_ANNOT_INVALID:
00438 fprintf (f, "Invalid");
00439 break;
00440
00441 case MEM_ANNOT_MALLOC_ID:
00442 fprintf (f, "malloc:%#llx", (unsigned long long)Malloc_id ());
00443 break;
00444
00445 case MEM_ANNOT_LMV_ALIAS_GROUP:
00446 fprintf (f, "alias-grp:%#llx", (unsigned long long)LMV_alias_group ());
00447 break;
00448
00449 default:
00450 FmtAssert (FALSE, ("Invalid kind %d", Kind()));
00451 };
00452 }
00453
00454 void
00455 MEMOP_ANNOT::Print (FILE* f) const {
00456
00457 fprintf (f, "id:%d,", _id);
00458
00459 for (MEMOP_ANNOT_ITEM_CITER iter = _vect.begin (); iter != _vect.end(); iter++) {
00460 const MEMOP_ANNOT_ITEM& item = *iter;
00461 (*iter).Print (f);
00462 fprintf (TFile, ",");
00463 }
00464
00465
00466 }
00467
00468 void
00469 PT_MEM_ANNOT::Print (FILE* f, BOOL verbose) const {
00470 if (_flags) {
00471 if (Item_is_inlined ()) {
00472 _inlined_annot.Print (f);
00473 } else if (!verbose) {
00474 fprintf (f, "annot:%d", _annot_ptr->Id());
00475 } else {
00476 _annot_ptr->Print (f);
00477 }
00478 }
00479 }