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 #include "c_breeze.h"
00039 #include "ref_clone_changer.h"
00040 #include "memorymodel.h"
00041 #include "memoryblock.h"
00042
00043
00044
00045
00046
00047 memoryModel::memoryModel()
00048 : _memory_blocks(),
00049 _ci_memory_blocks(),
00050 _string_constants(),
00051 Counter(0),
00052 Null(0),
00053 _string_constant(0),
00054 _unification_based(0)
00055 {
00056
00057
00058 declNode * null_decl = new declNode("null",
00059 declNode::NONE,
00060 (typeNode *)0,
00061 (exprNode *)0,
00062 (exprNode *)0);
00063
00064 Null = new memoryBlock(null_decl, true, (memoryBlock *)0, (procNode *)0);
00065
00066
00067
00068 Null->set_write_protected();
00069
00070 pointerOptions::Unify_objects = 0;
00071 }
00072
00073 memoryModel::~memoryModel()
00074 {
00075
00076
00077 for (proc_memorymodel_map_p q = _memory_blocks.begin();
00078 q != _memory_blocks.end();
00079 ++q)
00080 {
00081 memorymodel_map & mm = (*q).second;
00082
00083 for (memorymodel_map_p p = mm.begin();
00084 p != mm.end();
00085 ++p) {
00086 if(p->second->unifyType()) {
00087 set<procNode*> procs = p->second->unifyType()->procs();
00088 for(set<procNode*>::iterator q=procs.begin(); q!=procs.end(); q++)
00089 if(_unification_based->proctype(*q))
00090 _unification_based->proctype(*q)->block(NULL);
00091 }
00092 delete (*p).second;
00093 }
00094 }
00095
00096 for (ci_memorymodel_map_p p = _ci_memory_blocks.begin();
00097 p != _ci_memory_blocks.end();
00098 ++p) {
00099 if(p->second->unifyType()) {
00100 for(set<procNode*>::iterator q=p->second->unifyType()->procs().begin();
00101 q!=p->second->unifyType()->procs().end(); q++)
00102 if(_unification_based->proctype(*q))
00103 _unification_based->proctype(*q)->block(NULL);
00104 }
00105 delete (*p).second;
00106 }
00107
00108
00109
00110 delete Null;
00111 }
00112
00113 void memoryModel::clear()
00114 {
00115 for (proc_memorymodel_map_p q = _memory_blocks.begin();
00116 q != _memory_blocks.end();
00117 ++q)
00118 {
00119 memorymodel_map & mm = (*q).second;
00120
00121 for (memorymodel_map_p p = mm.begin();
00122 p != mm.end();
00123 ++p)
00124 (*p).second->clear();
00125 }
00126
00127 for (ci_memorymodel_map_p p = _ci_memory_blocks.begin();
00128 p != _ci_memory_blocks.end();
00129 ++p)
00130 (*p).second->clear();
00131
00132 Null->clear();
00133 }
00134
00135 int memoryModel::size()
00136 {
00137 int size = 0;
00138
00139 for (proc_memorymodel_map_p q = _memory_blocks.begin();
00140 q != _memory_blocks.end();
00141 ++q)
00142 {
00143 memorymodel_map & mm = (*q).second;
00144
00145 size += mm.size();
00146 }
00147
00148 return size;
00149 }
00150
00151
00152
00153
00154
00155 memoryBlock * memoryModel::lookup_variable(Location * location,
00156 declNode * decl,
00157 procNode * local_to)
00158 {
00159
00160
00161
00162 procNode * owner = 0;
00163 Location * owner_loc = 0;
00164 bool is_array = false;
00165 bool is_struct_init = false;
00166 typeNode * ty = 0;
00167
00168 if (decl) {
00169
00170
00171
00172
00173 if (((decl->decl_location() == declNode::BLOCK) ||
00174 (decl->decl_location() == declNode::FORMAL)) &&
00175 (decl->storage_class() != declNode::STATIC))
00176 {
00177 owner = local_to;
00178 owner_loc = location;
00179 }
00180
00181 ty = decl->no_tdef_type();
00182 if (ty && (ty->typ() == Array) &&
00183 (decl->decl_location() != declNode::FORMAL))
00184 is_array = true;
00185
00186 if (ty && (ty->typ() == Struct) && decl->init())
00187 is_struct_init = true;
00188 }
00189
00190
00191
00192 memoryBlock * result = 0;
00193
00194 if (pointerOptions::Context_insensitive_memory)
00195 result = lookup((stmtNode *)0, decl);
00196 else
00197 result = lookup(owner_loc, decl);
00198
00199 if (result)
00200 return result;
00201
00202
00203
00204
00205 if (pointerOptions::Context_insensitive_memory)
00206 result = create_memory_object((stmtNode *)0, decl, false,
00207 (memoryBlock *) 0, owner);
00208 else
00209 result = create_memory_object(owner_loc, decl, false,
00210 (memoryBlock *) 0, owner);
00211
00212
00213
00214 if(pointerOptions::Unification || _unification_based)
00215 result->set_unification(pointerOptions::Non_unify_types);
00216
00217
00218
00219 result->set_flow_sensitivity(pointerOptions::Flow_sensitive_objects);
00220
00221
00222
00223
00224
00225 if (is_array)
00226 generate_array_elements_for(result);
00227
00228 if (is_struct_init) {
00229 expr_list inits;
00230 inits.push_back(decl->init());
00231
00232 sueNode * sue = (sueNode *) decl->no_tdef_type();
00233 initialize_struct(result, sue, inits);
00234 }
00235
00236 return result;
00237 }
00238
00239 memoryBlock * memoryModel::lookup_heap_object(const string & name,
00240 stmtLocation * allocation_site,
00241 stmtNode * allocation_stmt,
00242 declNode * decl,
00243 bool synthetic_decl)
00244 {
00245
00246
00247 memoryBlock * result = 0;
00248
00249 if (0)
00250 result = lookup(allocation_stmt, decl);
00251 else
00252 result = lookup(allocation_site, decl);
00253
00254 if (result)
00255 return result;
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275 if (0)
00276 result = create_memory_object(allocation_stmt, decl, synthetic_decl, 0, 0,
00277 true);
00278 else
00279 result = create_memory_object(allocation_site, decl, synthetic_decl, 0, 0,
00280 0, true);
00281
00282
00283
00284 result->set_heap_object(allocation_site);
00285
00286
00287
00288
00289
00290
00291
00292 if(pointerOptions::Unification || _unification_based)
00293 result->set_unification(pointerOptions::Non_unify_types);
00294
00295
00296
00297
00298 result->set_flow_sensitivity(pointerOptions::Flow_sensitive_objects);
00299
00300 return result;
00301 }
00302
00307 memoryBlock * memoryModel::lookup_string_constant(constNode * the_string)
00308 {
00309 memoryBlock * result = 0;
00310
00311 if (pointerOptions::One_string_constant) {
00312
00313 if ( ! _string_constant) {
00314
00315
00316 string fullname("__string_constant");
00317
00318 declNode * the_decl = new declNode(fullname.c_str(),
00319 declNode::NONE,
00320 (typeNode *)0,
00321 (exprNode *)0,
00322 (exprNode *)0);
00323
00324
00325
00326 bool is_synthetic = true;
00327
00328 _string_constant = new memoryBlock(the_decl, is_synthetic,
00329 (memoryBlock *)0, (procNode *)0);
00330
00331
00332
00333 _string_constant->set_write_protected();
00334 _string_constant->set_flow_insensitive();
00335 }
00336
00337 result = _string_constant;
00338 }
00339 else {
00340
00341
00342
00343 string_constant_map_p p = _string_constants.find(the_string);
00344 if (p == _string_constants.end()) {
00345
00346
00347
00348 char buf[50];
00349
00350 sprintf(buf, "_%d", Counter);
00351 Counter++;
00352
00353 string fullname = string("__string_#") + buf;
00354
00355 declNode * the_decl = new declNode(fullname.c_str(),
00356 declNode::NONE,
00357 (typeNode *)0,
00358 (exprNode *)0,
00359 (exprNode *)0);
00360
00361
00362
00363 bool is_synthetic = true;
00364
00365 Unify_ECR *ecr = NULL;
00366 if(pointerOptions::Unification) {
00367 Alpha *alpha = _unification_based->string_alpha(the_string);
00368 if(alpha) {
00369 Unify_ECR *ecr = alpha->tao();
00370 if(ecr) result = ecr->type()->block();
00371 }
00372 }
00373
00374 if(! result) {
00375 result = new memoryBlock(the_decl, is_synthetic,
00376 (memoryBlock *)0, (procNode *)0);
00377 if(ecr) {
00378 ecr->type()->block(result);
00379 result->unifyType(ecr->type());
00380 }
00381 }
00382
00383
00384
00385 _string_constants[the_string] = result;
00386
00387
00388
00389 result->set_write_protected();
00390 result->set_flow_insensitive();
00391 }
00392 else {
00393
00394
00395
00396 result = (*p).second;
00397 }
00398 }
00399
00400 if (result == 0) {
00401 cout << "THIS IS BAD" << endl;
00402 abort();
00403 }
00404
00405 return result;
00406 }
00407
00408 memoryBlock * memoryModel::generate_su_field(const string & field_name,
00409 declNode * field_decl,
00410 memoryBlock * container)
00411 {
00412
00413
00414
00415 string field_obj_name;
00416
00417 if (field_decl)
00418 field_obj_name = field_decl->name();
00419 else
00420 field_obj_name = field_name;
00421
00422
00423
00424
00425 typeNode * type = 0;
00426 if (field_decl)
00427 type = (typeNode *) ref_clone_changer::clone(field_decl->type(), false);
00428
00429 declNode * copy_decl = new declNode(field_obj_name.c_str(),
00430 declNode::NONE,
00431 type,
00432 (exprNode *)0,
00433 (exprNode *)0);
00434
00435 if(field_decl) _copy_decl[copy_decl] = field_decl;
00436
00437
00438
00439 memoryBlock * field = create_memory_object((Location *)0, copy_decl, true,
00440 container, (procNode *)0,
00441 field_decl);
00442
00443
00444
00445 if(pointerOptions::Unification || _unification_based)
00446 field->set_unification(pointerOptions::Non_unify_types);
00447
00448
00449
00450 field->set_flow_sensitivity(pointerOptions::Flow_sensitive_objects);
00451
00452
00453
00454 bool recursive_array = false;
00455
00456
00457
00458
00459 if(_unification_based && !pointerOptions::Unification &&
00460 !container->unifyType() ) {
00461
00462 if(container->container() &&
00463 _copy_decl[container->container()->decl()] == field_decl)
00464 recursive_array = true;
00465 }
00466
00467 if (field_decl &&
00468 field_decl->type() &&
00469 (field_decl->no_tdef_type()->typ() == Array) &&
00470 (! pointerOptions::Unification ||
00471 field_decl->decl_location() != declNode::SU) &&
00472
00473 (!(_unification_based && !pointerOptions::Unification) ||
00474 _unification_based->ecr(field_decl) ||
00475 !container->unifyType() && !recursive_array) ) {
00476
00477
00478
00479
00480
00481
00482 if(! pointerOptions::Unification &&
00483 field_decl->decl_location() == declNode::SU &&
00484 container->unifyType()) {
00485 cout << "field_decl @" << field_decl->coord() << endl;
00486 if(_unification_based->ecr(field_decl))
00487 cout << * _unification_based->ecr(field_decl) << endl;
00488 cout << field << " field " << field->name() << endl;
00489 if(field->unifyType()) cout << * field->unifyType() << endl;
00490 cout << container << " container " << container->name() << endl;
00491 if(container->unifyType()) cout << * container->unifyType() << endl;
00492 pointerOptions::Verbose = true;
00493 }
00494 generate_array_elements_for(field);
00495 if(! pointerOptions::Unification &&
00496 field_decl->decl_location() == declNode::SU &&
00497 container->unifyType()) {
00498 cout << "after generate_array_elemement\n";
00499 exit(1);
00500 }
00501 }
00502
00503 return field;
00504 }
00505
00506
00507
00508
00509
00510 memoryBlock * memoryModel::create_memory_object(Location * location,
00511 declNode * decl,
00512 bool synthetic_decl,
00513 memoryBlock * container,
00514 procNode * local_to,
00515 declNode * org_field_decl,
00516 bool is_alloc,
00517 bool is_array_elt)
00518 {
00519 procNode * owner = 0;
00520
00521 if (!decl)
00522 cout << "WARNING: Creating memoryBlock with no declaration." << endl;
00523
00524
00525
00526 if (container)
00527 owner = container->local_to();
00528 else
00529 owner = local_to;
00530
00531
00532
00533 memoryBlock * result = NULL;
00534 bool brand_new = false;
00535
00536 Unify_ECR *ecr = NULL;
00537 if(_unification_based) {
00538 if(is_alloc) {
00539 stmtNode *site = ((stmtLocation*)location)->stmt();
00540 if(site->typ() == ThreeAddr) {
00541 ecr = _unification_based->ecr((threeAddrNode*) site);
00542 } else {
00543 ecr = _unification_based->ecr(decl);
00544 }
00545 assert(ecr);
00546 } else {
00547 ecr = _unification_based->ecr(decl);
00548 if(!ecr) {
00549 bool field_from_annotation = false;
00550 if(org_field_decl &&
00551 _unification_based->isField(org_field_decl, field_from_annotation)) {
00552
00553
00554
00555
00556
00557
00558 ecr = _unification_based->ecrField(container->unifyType(),
00559 org_field_decl,
00560 field_from_annotation);
00561
00562
00563
00564
00565 } else if(is_array_elt && container->unifyType()) {
00566
00567
00568 assert(container);
00569
00570
00571
00572 ecr = _unification_based->ecrDeref(container->unifyType());
00573
00574
00575 }
00576 }
00577 }
00578
00579 if(ecr) {
00580 bool non_unify;
00581 if(decl &&
00582 (decl->decl_location()==declNode::PROC ||
00583 decl->no_tdef_type() &&
00584 (decl->no_tdef_type()->typ() == Func ||
00585 decl->no_tdef_type()->typ() == Ptr &&
00586 decl->no_tdef_type()->no_tdef_type()->typ()==Func)))
00587 non_unify = true;
00588 else if(!pointerOptions::Unification) {
00589 if(is_alloc) {
00590 assert(location->kind() == Location::Statement);
00591 non_unify = is_in_non_unify_list(pointerOptions::Non_unify_types,
00592 ecr->type());
00593 } else if(container)
00594 non_unify = is_in_non_unify_list(pointerOptions::Non_unify_types,
00595 ecr->type());
00596 else
00597 non_unify = is_in_non_unify_list(pointerOptions::Non_unify_types,
00598 ecr->type());
00599 } else non_unify = false;
00600 if(non_unify) ecr=NULL;
00601 }
00602
00603 if(ecr) {
00604 if(ecr->type()->is_bottom())
00605 _unification_based->ensure_no_bottom(ecr, decl, container ?
00606 container->unifyType() :
00607 NULL);
00608 result = ecr->type()->block();
00609 }
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625 }
00626
00627 if(!result) {
00628 result = new memoryBlock(decl, synthetic_decl, container, owner);
00629 if (pointerOptions::Verbose || pointerOptions::Show_stack) {
00630 cout << "new memoryBlock " << result << " for " << decl->name() << ": "
00631 << result->name() << endl;
00632 if (pointerOptions::Verbose)
00633 if(ecr) cout << " ecr " << *ecr << endl;
00634 }
00635 brand_new = true;
00636 if(ecr) result->unifyType(ecr->type());
00637 }
00638
00639 if(ecr && !ecr->type()->block())
00640 ecr->type()->block(result);
00641
00642
00643
00644 if(brand_new) {
00645 procNode * proc = 0;
00646
00647 if (location)
00648 proc = Location::procedure(location)->proc();
00649 memorymodel_map & mm = _memory_blocks[proc];
00650
00651 memorymodel_key key(location, decl);
00652 mm[key] = result;
00653 }
00654
00655 return result;
00656 }
00657
00658
00659 memoryBlock * memoryModel::create_memory_object(stmtNode * location,
00660 declNode * decl,
00661 bool synthetic_decl,
00662 memoryBlock * container,
00663 procNode * local_to,
00664 bool is_alloc)
00665 {
00666 procNode * owner = 0;
00667
00668 if (!decl)
00669 cout << "WARNING: Creating memoryBlock with no declaration." << endl;
00670
00671
00672
00673 if (container)
00674 owner = container->local_to();
00675 else
00676 owner = local_to;
00677
00678
00679
00680 memoryBlock * result = NULL;
00681 bool brand_new = false;
00682
00683 Unify_ECR *ecr = NULL;
00684 if(_unification_based) {
00685 ecr = _unification_based->ecr(decl);
00686 if(ecr && !pointerOptions::Unification) {
00687 bool non_unify;
00688 assert(! is_alloc);
00689 if(decl &&
00690 (decl->decl_location()==declNode::PROC ||
00691 decl->no_tdef_type() &&
00692 (decl->no_tdef_type()->typ() == Func ||
00693 decl->no_tdef_type()->typ() == Ptr &&
00694 decl->no_tdef_type()->no_tdef_type()->typ()==Func)))
00695 non_unify = true;
00696 else if(container)
00697 non_unify = is_in_non_unify_list(pointerOptions::Non_unify_types,
00698 ecr->type());
00699 else
00700 non_unify = is_in_non_unify_list(pointerOptions::Non_unify_types,
00701 ecr->type());
00702 if(non_unify) ecr=NULL;
00703 }
00704
00705 if(ecr) result = ecr->type()->block();
00706 }
00707
00708 if(!result) {
00709 result = new memoryBlock(decl, synthetic_decl, container, owner);
00710 brand_new = true;
00711 if(ecr) result->unifyType(ecr->type());
00712 }
00713
00714 if(ecr && !ecr->type()->block())
00715 ecr->type()->block(result);
00716
00717
00718
00719 if(brand_new) {
00720 ci_memorymodel_key key(location, decl);
00721 _ci_memory_blocks[key] = result;
00722 }
00723
00724 return result;
00725 }
00726
00744 void memoryModel::generate_array_elements_for(memoryBlock * array_object)
00745 {
00746 declNode * decl = array_object->decl();
00747
00748 if (decl) {
00749 typeNode * curtype = array_object->decl()->no_tdef_type();
00750 memoryBlock * curblock = array_object;
00751 expr_list inits;
00752
00753
00754
00755
00756
00757 if (decl->init() &&
00758 (decl->init()->typ() == Initializer))
00759 {
00760 initializerNode * initializer = (initializerNode *) decl->init();
00761 inits.push_back(initializer);
00762 }
00763
00764 string suffix("[]");
00765
00766
00767
00768 while (curtype && (curtype->typ() == Array)) {
00769
00770
00771
00772
00773 typeNode * type_clone = (typeNode *) ref_clone_changer::clone(curtype->type(), false);
00774
00775 string name = decl->name() + suffix;
00776
00777 declNode * fake_decl = new declNode(name.c_str(),
00778 declNode::NONE,
00779 type_clone,
00780 (exprNode *)0,
00781 (exprNode *)0);
00782
00783 if(decl) _copy_decl[fake_decl] = decl;
00784
00785
00786
00787
00788 memoryBlock * contents = create_memory_object((Location *)0, fake_decl, true,
00789 curblock, (procNode *)0,
00790 0, false, true);
00791
00792 curblock->set_array_element(contents);
00793
00794
00795
00796 contents->set_indexed();
00797
00798
00799
00800 if(pointerOptions::Unification || _unification_based)
00801 contents->set_unification(pointerOptions::Non_unify_types);
00802
00803
00804
00805 contents->set_flow_sensitivity(pointerOptions::Flow_sensitive_objects);
00806
00807
00808
00809
00810 expr_list new_inits;
00811 for (expr_list_p ip = inits.begin();
00812 ip != inits.end();
00813 ++ip)
00814 {
00815 exprNode * expr = (*ip);
00816 if (expr->typ() == Initializer) {
00817 initializerNode * initializer = (initializerNode *) expr;
00818 new_inits.insert(new_inits.end(),
00819 initializer->exprs().begin(),
00820 initializer->exprs().end());
00821 }
00822 }
00823
00824 inits = new_inits;
00825
00826
00827
00828 curtype = curtype->no_tdef_type();
00829 curblock = contents;
00830 suffix = suffix + "[]";
00831 }
00832
00833 if (curtype &&
00834 ( ! inits.empty())) {
00835
00836 if (pointerOptions::Verbose)
00837 cout << "FOUND initializers for " << array_object->name() << endl;
00838
00839 if (curtype->typ() == Struct) {
00840 initialize_struct(curblock, (sueNode *) curtype, inits);
00841 }
00842 else {
00843
00844
00845
00846 for (expr_list_p p = inits.begin();
00847 p != inits.end();
00848 ++p)
00849 {
00850 exprNode * the_init = (*p);
00851 idNode * id = 0;
00852 bool is_addr = false;
00853
00854 if (the_init->typ() == Id)
00855 id = (idNode *) the_init;
00856
00857 if (the_init->typ() == Unary) {
00858 unaryNode * un = (unaryNode *) the_init;
00859 if (un->expr()->typ() == Id)
00860 id = (idNode *) un->expr();
00861 is_addr = (un->op()->id() == Operator::ADDRESS);
00862 }
00863
00864 if (id) {
00865
00866 declNode * decl_init = id->decl();
00867
00868 if (decl_init) {
00869
00870 if(decl_init->type()->typ() == Func)
00871 is_addr = true;
00872
00873 memoryBlock * rhs = lookup_variable((Location *)0,
00874 decl_init,
00875 (procNode *)0);
00876 if (pointerOptions::Verbose)
00877 cout << "Array init: Assign " << curblock->name() << " = " << rhs->name() << endl;
00878
00879 memoryblock_set temp;
00880 if(is_addr)
00881 temp.insert(rhs);
00882 else {
00883 memoryUse * right_use = rhs->current_use();
00884 if ( ! right_use)
00885 right_use = rhs->use_at(procLocation::main());
00886 memoryDef * rd = right_use->reaching_def();
00887 if (rd) {
00888 const memoryblock_set & rd_points_to = rd->points_to();
00889 temp.insert(rd_points_to.begin(), rd_points_to.end());
00890 }
00891
00892
00893 if(pointerOptions::Unification && _unification_based) {
00894 UnifyType *right_type = rhs->unifyType();
00895 if(right_type &&
00896 (right_type->objTyp()==SIMPLE || right_type->objTyp()==OBJECT)) {
00897 Unify_ECR *defer = _unification_based->ecrDeref(right_type);
00898 if(defer && defer->type()->block())
00899 temp.insert( defer->type()->block() );
00900 }
00901 }
00902 }
00903
00904 bool ignore;
00905 memoryDef *def = curblock->def_at(procLocation::main(), ignore);
00906 def->add_pointers(temp);
00907 }
00908 }
00909 }
00910 }
00911 }
00912 }
00913 }
00914
00915
00916
00917 memoryBlock * memoryModel::lookup(Location * location, declNode * decl)
00918 {
00919 procNode * proc = 0;
00920
00921 if (location)
00922 proc = Location::procedure(location)->proc();
00923
00924 memorymodel_map & mm = _memory_blocks[proc];
00925
00926 memorymodel_key key(location, decl);
00927
00928 memorymodel_map_p p = mm.find(key);
00929 if (p != mm.end())
00930 return (*p).second;
00931 else
00932 return 0;
00933 }
00934
00935 memoryBlock * memoryModel::lookup(stmtNode * location, declNode * decl)
00936 {
00937 ci_memorymodel_key key(location, decl);
00938
00939 ci_memorymodel_map_p p = _ci_memory_blocks.find(key);
00940 if (p != _ci_memory_blocks.end())
00941 return (*p).second;
00942 else
00943 return 0;
00944 }
00945
00946 bool memoryModel::is_in_non_unify_list(UnifyTypes & non_unify_types,
00947 UnifyType *obj)
00948 {
00949 assert(obj);
00950 UnifyTypes visited;
00951 return UnificationBasedPtr::reachable(obj, non_unify_types, visited);
00952 }
00953
00954
00955
00956
00957
00958
00959 void memoryModel::update_def_use_chains()
00960 {
00961
00962
00963 for (proc_memorymodel_map_p q = _memory_blocks.begin();
00964 q != _memory_blocks.end();
00965 ++q)
00966 {
00967 memorymodel_map & mm = (*q).second;
00968
00969 for (memorymodel_map_p p = mm.begin();
00970 p != mm.end();
00971 ++p)
00972 ((*p).second)->update_def_use_chains();
00973 }
00974
00975 for (ci_memorymodel_map_p p = _ci_memory_blocks.begin();
00976 p != _ci_memory_blocks.end();
00977 ++p)
00978 ((*p).second)->update_def_use_chains();
00979
00980
00981
00982
00983
00984
00985
00986
00987 }
00988
00989
00990
00991 int num_defs_histogram[200];
00992
00993 void memoryModel::stats(ostream & out)
00994 {
00995 out << "Memory model: " << endl;
00996 int block_count = _memory_blocks.size() + _ci_memory_blocks.size();
00997
00998 out << " memoryBlock : " << block_count << " objects x "
00999 << sizeof(memoryBlock) << " bytes = " << block_count * sizeof(memoryBlock)
01000 << " bytes. " << endl;
01001
01002 long int global_defs = 0;
01003 long int global_merge_defs = 0;
01004 long int global_weak_defs = 0;
01005 long int global_uses = 0;
01006 long int global_merge_uses = 0;
01007
01008 bool first = true;
01009
01010 for (proc_memorymodel_map_p q = _memory_blocks.begin();
01011 q != _memory_blocks.end();
01012 ++q)
01013 {
01014 memorymodel_map & mm = (*q).second;
01015
01016 for (memorymodel_map_cp p = mm.begin();
01017 p != mm.end();
01018 ++p)
01019 {
01020 memoryBlock * block = (*p).second;
01021 if (first) {
01022 block->stats(out, true,
01023 global_defs, global_merge_defs, global_weak_defs,
01024 global_uses, global_merge_uses);
01025 first = false;
01026 }
01027 block->stats(out, false,
01028 global_defs, global_merge_defs, global_weak_defs,
01029 global_uses, global_merge_uses);
01030 }
01031 }
01032
01033 out << "-- Total def/use statistics ---- " << endl;
01034 out << " Total defs: " << global_defs << endl;
01035 out << " Total merge defs: " << global_merge_defs << endl;
01036 out << " Total weak defs: " << global_weak_defs << endl;
01037 out << " Total uses: " << global_uses << endl;
01038 out << " Total merge uses: " << global_merge_uses << endl;
01039
01040 double d_defs = (double) global_defs;
01041 double d_weak = (double) global_weak_defs;
01042 double percent_weak = (d_weak / d_defs) * 100.0;
01043
01044 out << " Percent weak defs: " << percent_weak << endl;
01045 out << "-------------------------------- " << endl;
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067 }
01068
01069 void memoryModel::print(ostream & o) const
01070 {
01071 for (proc_memorymodel_map_cp q = _memory_blocks.begin();
01072 q != _memory_blocks.end();
01073 ++q)
01074 {
01075 const memorymodel_map & mm = (*q).second;
01076
01077 for (memorymodel_map_cp p = mm.begin();
01078 p != mm.end();
01079 ++p)
01080 ((*p).second)->print_def_use(o);
01081 }
01082
01083 for (ci_memorymodel_map_cp p = _ci_memory_blocks.begin();
01084 p != _ci_memory_blocks.end();
01085 ++p)
01086 ((*p).second)->print_def_use(o);
01087 }
01088
01093 void memoryModel::initialize_struct(memoryBlock * struct_object,
01094 sueNode * sue_type,
01095 expr_list & inits)
01096 {
01097 if (pointerOptions::Verbose)
01098 cout << "FOUND initializers for " << struct_object->name() << endl;
01099
01100 suespecNode * spec = sue_type->spec();
01101 decl_list & fields = spec->fields();
01102
01103 for (expr_list_p ip = inits.begin();
01104 ip != inits.end();
01105 ++ip)
01106 {
01107 exprNode * expr = (*ip);
01108 if (expr->typ() == Initializer) {
01109 initializerNode * initializer = (initializerNode *) expr;
01110 expr_list & field_inits = initializer->exprs();
01111
01112
01113
01114 decl_list_p fp = fields.begin();
01115 expr_list_p fip = field_inits.begin();
01116 while ((fp != fields.end()) &&
01117 (fip != field_inits.end()))
01118 {
01119 declNode * field_decl = (*fp);
01120 exprNode * field_init = (*fip);
01121
01122 idNode * id = 0;
01123 bool is_addr = false;
01124
01125 if (field_init->typ() == Id)
01126 id = (idNode *) field_init;
01127
01128 if (field_init->typ() == Unary) {
01129 unaryNode * un = (unaryNode *) field_init;
01130 if (un->expr()->typ() == Id)
01131 id = (idNode *) un->expr();
01132 is_addr = (un->op()->id() == Operator::ADDRESS);
01133 }
01134
01135 if (id) {
01136
01137 declNode * decl_init = id->decl();
01138
01139 if (decl_init) {
01140
01141 if(decl_init->type()->typ() == Func)
01142 is_addr = true;
01143
01144 memoryblock_set results;
01145 struct_object->dot(field_decl->name(),
01146 field_decl,
01147 *this,
01148 results);
01149 memoryBlock * field = * (results.begin());
01150
01151 memoryBlock * rhs = lookup_variable((Location *)0,
01152 decl_init,
01153 (procNode *)0);
01154 if (pointerOptions::Verbose)
01155 cout << "Field init: Assign " << field->name() << " = " << rhs->name() << endl;
01156
01157 memoryblock_set temp;
01158 if(is_addr)
01159 temp.insert(rhs);
01160 else {
01161 memoryUse * right_use = rhs->current_use();
01162 if ( ! right_use)
01163 right_use = rhs->use_at(procLocation::main());
01164 memoryDef * rd = right_use->reaching_def();
01165 if (rd) {
01166 const memoryblock_set & rd_points_to = rd->points_to();
01167 temp.insert(rd_points_to.begin(), rd_points_to.end());
01168 }
01169
01170
01171 if(pointerOptions::Unification && _unification_based) {
01172 UnifyType *right_type = rhs->unifyType();
01173 if(right_type &&
01174 (right_type->objTyp()==SIMPLE || right_type->objTyp()==OBJECT)) {
01175 Unify_ECR *defer = _unification_based->ecrDeref(right_type);
01176 if(defer && defer->type()->block())
01177 temp.insert( defer->type()->block() );
01178 }
01179 }
01180 }
01181
01182 bool ignore;
01183 memoryDef * def = field->def_at(procLocation::main(), ignore);
01184 def->add_pointers(temp);
01185 }
01186 }
01187
01188 fp++;
01189 fip++;
01190 }
01191 }
01192 }
01193 }