00001
00002 #include "unification.h"
00003 #include "linker.h"
00004 #include "memoryblock.h"
00005 #include "memorymodel.h"
00006 #include "location.h"
00007
00008 static bool debug = false;
00009
00010
00011
00012 #ifdef cx_vt
00013 int vt = 0, vt_e = 0;
00014 #endif
00015
00016 int UnificationBasedPtr::unify_points_to_max = 0;
00017
00018 void Unify_Pendings::insert(Unify_Pending *p, bool is_new) {
00019 #define delete_and_return { \
00020 if(is_new) delete p; \
00021 return; \
00022 }
00023
00024
00025 if(!is_new && _set.find(p) != _set.end()) return;
00026
00027 if(p->typ() == Unify_Pending::cjoin) {
00028 Unify_ECR *e1 = (Unify_ECR*) p->arg2(),
00029 *e2 = (Unify_ECR*) p->arg3();
00030 if( e1->root() == e2->root() ) delete_and_return;
00031
00032
00033 if( e1->type()->objTyp()==OBJECT &&
00034 e2->type()->objTyp()==OBJECT &&
00035 e1->type()->object()->alpha->tao()->type() ==
00036 e2->type()->object()->alpha->tao()->type() ) {
00037
00038
00039
00040 delete_and_return;
00041 }
00042
00043 } else if(p->typ() == Unify_Pending::join_ECR) {
00044 Unify_ECR *e1 = (Unify_ECR*) p->arg1(),
00045 *e2 = (Unify_ECR*) p->arg2();
00046 if( e1->root() == e2->root() ) delete_and_return;
00047 }
00048
00049 cleanup();
00050
00051 std::set<Unify_Pending*> temp_set = _set;
00052 for(Pendings_p s=temp_set.begin(); s!=temp_set.end(); s++)
00053 if((*s)->typ() == p->typ()) {
00054 bool d1 = (*s)->arg1() != p->arg1(),
00055 d2 = (*s)->arg2() != p->arg2(),
00056 d3 = (*s)->arg3() != p->arg3();
00057 switch(p->typ()) {
00058 case Unify_Pending::cjoin:
00059 if(d1) {
00060 Unify_Size *s1 = (Unify_Size*) (*s)->arg1(),
00061 *s2 = (Unify_Size*) p->arg1();
00062 if(s1->is_top()==s2->is_top() && s1->size()==s2->size())
00063 d1 = false;
00064 }
00065
00066 if(d2 && ((Unify_ECR*)(*s)->arg2())->root()
00067 == ((Unify_ECR*)p->arg2())->root())
00068 d2 = false;
00069 if(d3 && ((Unify_ECR*)(*s)->arg3())->root()
00070 == ((Unify_ECR*)p->arg3())->root())
00071 d3 = false;
00072
00073 if(!d1 && !d2 && !d3) {
00074
00075
00076 _set.insert(p);
00077 Unify_ECR *es = (Unify_ECR*) (*s)->arg2(),
00078 *ep = (Unify_ECR*) p->arg2();
00079 if(es != ep) {
00080 std::set<Unify_Pending*> S = ep->pending().set();
00081 for(Pendings_p q=S.begin(); q!=S.end(); q++)
00082 if(& es->pending()!=this && *q!=p)
00083 es->pending().insert(*q,false);
00084 }
00085 es = (Unify_ECR*) (*s)->arg3();
00086 ep = (Unify_ECR*) p->arg3();
00087 if(es != ep) {
00088 std::set<Unify_Pending*> S = ep->pending().set();
00089 for(Pendings_p q=S.begin(); q!=S.end(); q++)
00090 if(& es->pending()!=this && *q!=p)
00091 es->pending().insert(*q,false);
00092 }
00093 _set.erase(p);
00094 }
00095 break;
00096
00097 case Unify_Pending::join_ECR:
00098 if(d1) {
00099 Unify_ECR *es = (Unify_ECR*) (*s)->arg1(),
00100 *ep = (Unify_ECR*) p->arg1();
00101 if(es->root() == ep->root() &&
00102 es->pending().set() == ep->pending().set())
00103 d1 = false;
00104 }
00105 if(d2) {
00106 Unify_ECR *es = (Unify_ECR*) (*s)->arg2(),
00107 *ep = (Unify_ECR*) p->arg2();
00108 if(es->root() == ep->root() &&
00109 es->pending().set() == ep->pending().set())
00110 d2 = false;
00111 }
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 break;
00134 case Unify_Pending::join_Lambda:
00135 if(d1 && ((Lambda*)(*s)->arg1()) == (Lambda*)p->arg1())
00136 d1 = false;
00137 if(d2 && ((Lambda*)(*s)->arg2()) == (Lambda*)p->arg2())
00138 d2 = false;
00139 if(!d1 && !d2) {
00140 _set.insert(p);
00141 Lambda *ls = (Lambda*) (*s)->arg1(),
00142 *lp = (Lambda*) p->arg1();
00143 if(ls != lp) {
00144 std::set<Unify_Pending*> S = lp->pending().set();
00145 for(Pendings_p q=S.begin(); q!=S.end(); q++)
00146 if(& ls->pending()!=this && *q!=p)
00147 ls->pending().insert(*q,false);
00148 }
00149 ls = (Lambda*) (*s)->arg2();
00150 lp = (Lambda*) p->arg2();
00151 if(ls != lp) {
00152 std::set<Unify_Pending*> S = lp->pending().set();
00153 for(Pendings_p q=S.begin(); q!=S.end(); q++)
00154 if(& ls->pending()!=this && *q!=p)
00155 ls->pending().insert(*q,false);
00156 }
00157 _set.erase(p);
00158 }
00159 break;
00160 case Unify_Pending::collapse:
00161 if(d1 && ((Unify_ECR*)(*s)->arg1())->root()
00162 == ((Unify_ECR*)p->arg1())->root()) {
00163 d1 = false;
00164 _set.insert(p);
00165 Unify_ECR *es = (Unify_ECR*) (*s)->arg1(),
00166 *ep = (Unify_ECR*) p->arg1();
00167 if(es != ep) {
00168 std::set<Unify_Pending*> S = ep->pending().set();
00169 for(Pendings_p q=S.begin(); q!=S.end(); q++)
00170 if(& es->pending()!=this && *q!=p)
00171 es->pending().insert(*q,false);
00172 }
00173 _set.erase(p);
00174 }
00175 break;
00176 case Unify_Pending::makeunknown:
00177 if(d1) {
00178 Unify_Offset *os = (Unify_Offset*) (*s)->arg1(),
00179 *op = (Unify_Offset*) p->arg1();
00180 if(os->value()==op->value()) {
00181 d1 = false;
00182 _set.insert(p);
00183 std::set<Unify_Pending*> S = op->pending().set();
00184 for(Pendings_p q=S.begin(); q!=S.end(); q++)
00185 if(& os->pending() != this && *q!=p)
00186 os->pending().insert(*q,false);
00187 _set.erase(p);
00188 }
00189 }
00190 }
00191 if(!d1 && !d2 && !d3) delete_and_return;
00192 }
00193
00194 _set.insert(p);
00195 cleaned = false;
00196 }
00197
00198
00199 void Unify_Pendings::cleanup() {
00200 if(cleaned) return;
00201 std::set<Unify_Pending*> temp_set = _set;
00202 for(Pendings_p s=temp_set.begin(); s!=temp_set.end(); s++)
00203 switch((*s)->typ()) {
00204 case Unify_Pending::cjoin: {
00205 Unify_ECR *e1 = (Unify_ECR*) (*s)->arg2(),
00206 *e2 = (Unify_ECR*) (*s)->arg3();
00207
00208
00209 if( e1->type()->objTyp()==OBJECT &&
00210 e2->type()->objTyp()==OBJECT &&
00211 e1->type()->object()->alpha->tao()->type() ==
00212 e2->type()->object()->alpha->tao()->type() ) {
00213
00214
00215
00216 _set.erase(*s);
00217 } else if( e1->root() == e2->root())
00218 _set.erase(*s);
00219 break;
00220 }
00221 case Unify_Pending::join_ECR:
00222 if( ((Unify_ECR*) (*s)->arg1())->root() ==
00223 ((Unify_ECR*) (*s)->arg2())->root())
00224 _set.erase(*s);
00225 break;
00226 }
00227 cleaned = true;
00228 }
00229
00230
00231 void Unify_Pending::print() const {
00232 switch(_typ) {
00233 case makeunknown:
00234 cout << "make_unknown(" << _arg1 << ")"; break;
00235 case join_ECR:
00236 cout << "join_ECR(" << ((Unify_ECR*)_arg1)->type()->id()
00237 << "," << ((Unify_ECR*)_arg2)->type()->id() << ")";
00238 break;
00239 case join_Lambda:
00240 cout << "join_Lambda(" << ((Lambda*)_arg1)->id() << ","
00241 << ((Lambda*)_arg2)->id() << ")";
00242 break;
00243 case cjoin:
00244 cout << "cjoin(" << ((Unify_Size*)_arg1)->str() << ","
00245 << ((Unify_ECR*)_arg2)->type()->id() << ","
00246 << ((Unify_ECR*)_arg3)->type()->id() << ")";
00247 break;
00248 case collapse:
00249 cout << "collapse(," << ((Unify_ECR*)_arg1)->type()->id() << ")";
00250 }
00251 }
00252
00253
00254
00255 Alpha::Alpha() : _tao(T_bottom->ecr()),
00256 _offset(new Unify_Offset(Unify_Offset::zero)) {}
00257
00258
00259 bool Alpha::leq(Alpha *o, Unify_Size s) const {
00260 return _tao->type()->is_bottom() || _tao->type()->leq(o->_tao->type(),s)
00261 && _offset->leq(o->_offset);
00262 }
00263
00264 void Alpha::print() const {
00265 cout << "(" << _tao->type()->id() << "," << *_offset << ")";
00266 }
00267
00268 int Lambda::id_count=0;
00269
00270 Lambda *Lambda::bottom() {
00271 Lambda *_bottom = new Lambda();
00272 return _bottom;
00273 }
00274
00275
00276 void Lambda::settype(int n, int m, Unify_ECR **t, Unify_ECR *r, bool ellipsis) {
00277 assert(_is_bottom);
00278 _is_bottom=false; _n=n; _m=m; _ellipsis=ellipsis; _taos=t; _taoR=r;
00279 }
00280
00281
00282 void Lambda::addArg(int n) {
00283 if(n <= 0 || _ellipsis) return;
00284 Unify_ECR **new_taos = (Unify_ECR**) malloc((n+_n) * sizeof(Unify_ECR*));
00285 for(int i=0; i<_n; i++) new_taos[i] = _taos[i];
00286 for(int i=_n; i<n+_n; i++) new_taos[i] = T_bottom->ecr();
00287 free(_taos);
00288 _taos = new_taos;
00289 _n += n;
00290 }
00291
00292
00293 bool Lambda::equal(Lambda *o) const {
00294 if(is_bottom() && o->is_bottom()) return true;
00295 if(is_bottom() || o->is_bottom()) return false;
00296 if(n()!=o->n() || m()!=o->m()) return false;
00297 for(int i=0; i<n(); i++)
00298 if(tao(i)->type() != o->tao(i)->type()) return false;
00299 if(m())
00300 if(taoR()->type() != o->taoR()->type()) return false;
00301 return true;
00302 }
00303
00304 void Lambda::print() const {
00305 cout << id();
00306 if(is_bottom()) {
00307 cout << "-L_bot";
00308 return;
00309 }
00310 cout << "-lambda(" << _n << ":";
00311 for(int i=0; i<n(); i++)
00312 cout << tao(i)->type()->id() << ",";
00313 if(_ellipsis) cout << "...";
00314 if(_m) cout <<" + "<< taoR()->type()->id();
00315 cout << ")";
00316 }
00317
00318 int Unify_Size::sizeOf(typeNode *ty) {
00319 assert(ty);
00320 switch(ty->typ()) {
00321 case Prim: {
00322 basic_type bt = ((primNode*)ty)->basic();
00323 if(bt == basic_type::Void || bt == basic_type::Ellipsis)
00324 return -1;
00325 return bt.size();
00326 }
00327 case Ptr: return sizeof(int*);
00328 case Array: {
00329 arrayNode *a = (arrayNode*) ty;
00330 if(a->dim() && a->dim()->typ()==Const) {
00331 int dim = ((constNode*)a->dim())->value().Integer();
00332 return sizeOf(a->type()) * dim;
00333 }
00334 return sizeof(int*);
00335 }
00336 case Enum: return sizeof(unsigned int);
00337 case Struct:
00338 case Union:
00339 case sueSpec: {
00340 suespecNode *spec = (ty->typ()==sueSpec) ? (suespecNode*) ty
00341 : ((sueNode*)ty)->spec();
00342 decl_list fields = spec->fields();
00343 int r = 0;
00344 for(decl_list_p d=fields.begin(); d!=fields.end(); d++) {
00345 int f = sizeOf((*d)->type());
00346 if(ty->typ()==Struct) r += f;
00347 else if(r>f) r=f;
00348 }
00349 return r;
00350 }
00351 case Func: {
00352 long p1 = sizeof(&sizeOf),
00353 p2 = sizeof(&sizeOfAssign);
00354 assert(p1 == p2);
00355 return p1;
00356 }
00357 case Tdef: return sizeOf(((tdefNode*)ty)->def());
00358 default: cout << ty->typ() << endl; assert(false);
00359 }
00360 }
00361
00362
00363 int Unify_Size::sizeOfAssign(threeAddrNode *t, Linker &linker,
00364 UnificationBasedPtr *analyzer) {
00365 if(!t || !t->lhs()) return 0;
00366
00367 #define size_operand(x,value) \
00368
00369 \
00370 if(x->cast()) \
00371 value = Unify_Size::sizeOf(x->cast()); \
00372 else if(x->var()->typ() == Const) { \
00373 assert(!x->addr() && !x->star() && x->fields().empty()); \
00374 typeNode *ty = ((constNode*)x->var())->type(); \
00375 if(! x->index()) \
00376 value = Unify_Size::sizeOf(ty); \
00377 else { \
00378 assert(ty->typ() == Array); \
00379 value = Unify_Size::sizeOf(ty->type()); \
00380 } \
00381 } else { \
00382 \
00383 typeNode *ty = ((idNode*)x->var())->decl()->type(); \
00384 int defers = 0; \
00385 if(x->star()) defers++; \
00386 if(! x->fields().empty()) { \
00387 assert(x->fields().back()->decl()); \
00388 ty = x->fields().back()->decl()->type(); \
00389 assert(ty); \
00390 defers=0; \
00391 } \
00392 if(x->index()) defers++; \
00393 if(x->addr()) defers--; \
00394 if(defers<0) value = sizeof(int*); \
00395 else { \
00396 while(defers-->0) { \
00397 if(ty->typ()==Tdef) ty = ((tdefNode*)ty)->def(); \
00398 ty=ty->type(); \
00399 } \
00400 value = Unify_Size::sizeOf(ty); \
00401 } \
00402 }
00403
00404 if(t->rhs1()->cast())
00405 return sizeOf(t->rhs1()->cast());
00406 if(t->op() && t->op()->id()==Operator::FUNC_CALL) {
00407 if(t->rhs1()->star()) {
00408
00409 int lhs;
00410 size_operand(t->lhs(), lhs)
00411 return lhs;
00412 } else {
00413 declNode *call = ((idNode*) t->rhs1()->var())->decl();
00414 procNode *proc = linker.lookup_procedure(call);
00415 if(!proc) proc = analyzer->synthetic_proc(call);
00416 if(! proc) {
00417 declNode *callee = ((idNode*)t->rhs1()->var())->decl();
00418 if(callee) {
00419 typeNode *type = callee->type()->follow_tdefs();
00420 if( type->typ() == Ptr ) {
00421
00422 int lhs;
00423 size_operand(t->lhs(), lhs)
00424 return lhs;
00425 }
00426 }
00427 }
00428 if(! proc) return -1;
00429 return sizeOf( ((funcNode*)proc->decl()->type())->returns() );
00430 }
00431
00432 } else if(! t->sizeof_type()) {
00433 int rhs;
00434 size_operand(t->rhs1(), rhs)
00435 if(t->rhs2()) {
00436 assert(t->op());
00437 if(t->op()->is_comparison())
00438 rhs = sizeof(bool);
00439 else {
00440 assert(t->op()->is_arithmetic());
00441 int rhs2;
00442 size_operand(t->rhs2(), rhs2)
00443 if(rhs2 > rhs) rhs=rhs2;
00444 }
00445 }
00446 return rhs;
00447 }
00448 }
00449
00450
00451 string Unify_Size::str() const {
00452 if(_is_top) return "_top_";
00453 ostringstream ost; ost << _size;
00454 return ost.str();
00455 }
00456
00457 string Unify_Parents::str() const {
00458 if(_is_top) return "_top_";
00459 ostringstream ost; ost << "{";
00460 for(set<Unify_ECR*>::const_iterator p=_parents.begin(); p!=_parents.end();
00461 p++) {
00462 if(p != _parents.begin()) ost << ",";
00463 ost << (*p)->type()->id();
00464 }
00465 ost << "}";
00466 return ost.str();
00467 }
00468
00469
00470 Unify_Structure::Unify_Structure(suespecNode *sue, EltMap _m, Unify_Size _s,
00471 Unify_Parents _p)
00472 : m(_m), s(_s), p(_p) {
00473 decl_list fields = sue->fields();
00474 assert(! fields.empty());
00475 if(sue->owner() == Struct) {
00476 for(decl_list_p f=fields.begin(); f!=fields.end(); f++) {
00477 declSet ds; ds.insert(*f);
00478 fo.push_back(ds);
00479 fto.push_back((*f)->type());
00480 }
00481 } else {
00482 declSet ds;
00483 typeNode *type = NULL;
00484 for(decl_list_p d=fields.begin(); d!=fields.end(); d++) {
00485 ds.insert(*d);
00486 if(d==fields.begin())
00487 type = (*d)->type();
00488 else if(! UnificationBasedPtr::compatible_type((*d)->type(), type))
00489 type = NULL;
00490 }
00491 fo.push_back(ds);
00492 fto.push_back(type);
00493 }
00494 }
00495
00496
00497 Unify_ECR *Unify_Structure::get(declNode *field, Unify_ECR *container) {
00498 #define new_field_ECR(X, type, container) {\
00499 set<Unify_ECR*> ps; ps.insert(container->root()); \
00500 Unify_Parents p(ps); \
00501 if(type) { \
00502 Unify_Size size(Unify_Size::sizeOf(type)); \
00503 X = (new UnifyType( new Unify_Blank(size,p)))->ecr(); \
00504 } else { \
00505 Unify_Size size; \
00506 X = (new UnifyType( new Unify_Blank(size,p)))->ecr(); \
00507 }}
00508
00509 for(FieldOrder::iterator f=fo.begin(); f!=fo.end(); f++)
00510 if((*f).find(field) != (*f).end()) {
00511 if(! m[*f])
00512 new_field_ECR(m[*f], field->type(), container)
00513 return m[*f];
00514 }
00515 return NULL;
00516 }
00517
00518 string Unify_Structure::map_str() {
00519 ostringstream ost;
00520 ost << "map: ";
00521 for(map<declSet,Unify_ECR*>::iterator p=m.begin(); p!=m.end(); p++) {
00522 assert(! p->first.empty());
00523 ost << "\n <";
00524 if(p->first.size() > 10) {
00525 declNode *first = * p->first.begin();
00526 ost << first->name() << "-" << first->coord() << ",etc...";
00527 } else
00528 for(set<declNode*>::iterator d=p->first.begin(); d!=p->first.end(); d++)
00529 ost << (*d)->name() << ",";
00530 ost << ">|->";
00531 if(p->second) ost << p->second->type()->id();
00532 else ost << "NULL";
00533 }
00534 ost << endl;
00535 return ost.str();
00536 }
00537
00538
00539 string Unify_Structure::all_str() {
00540 ostringstream ost;
00541 ost << "FO: ";
00542 for(FieldOrder::iterator p=fo.begin(); p!=fo.end(); p++) {
00543 assert(! (*p).empty());
00544 ost << "\n <";
00545 if(p->size() > 10) {
00546 declNode *first = * p->begin();
00547 ost << first->name() << "-" << first->coord() << ",etc...";
00548 } else
00549 for(set<declNode*>::iterator d=p->begin(); d!=p->end(); d++)
00550 ost << (*d)->name() << "-" << *d << "-" << (*d)->coord() << ",";
00551 ost << ">,";
00552 }
00553 ost << endl;
00554 return ost.str() + map_str();
00555 }
00556
00557
00558
00559 int Unify_ECR::id_count=0;
00560 set<Unify_ECR*> Unify_ECR::all_ECR;
00561
00562 Unify_ECR::Unify_ECR(declNode *v, procNode *p)
00563 : _var(v), _proc(p), _parent(0), _root(this), _ndecestors(0), _id(id_count++) {
00564 all_ECR.insert(this);
00565
00566 Unify_Size size(Unify_Size::sizeOf(v->type()));
00567 if(v->type()->typ() == Array && v->init() && v->init()->typ()==Initializer)
00568 size = Unify_Size( ((initializerNode*)v->init())->exprs().size() *
00569 Unify_Size::sizeOf(v->type()->type()) );
00570 Unify_Parents par(false);
00571 _type = new UnifyType( new Unify_Blank(size,par), this );
00572 _type->ecr(this);
00573 }
00574
00575 Unify_ECR::Unify_ECR(UnifyType *t)
00576 : _var(NULL), _proc(NULL), _parent(0), _root(this), _ndecestors(0),
00577 _id(id_count++), _type(t) {
00578 all_ECR.insert(this);
00579 }
00580
00581 UnifyType *Unify_ECR::type() { if(_parent) return root()->type(); return _type;}
00582
00583 void Unify_ECR::type(UnifyType *t) {
00584 assert(t);
00585 if(_parent) { root()->type(t); return; }
00586 _type = t;
00587 assert(!_root || _root==this);
00588 _root = Union(t->ecr());
00589 assert(_root == this);
00590 }
00591
00592 Unify_ECR * Unify_ECR::root() {
00593 if(! _parent) return this;
00594 if(! _root->_parent) return _root;
00595 return _root = _root->root();
00596 }
00597
00598 Unify_ECR * Unify_ECR::Union(Unify_ECR *other) {
00599 if(!other) return root();
00600 Unify_ECR *r1 = root(),
00601 *r2 = other->root();
00602 if(r1 == r2) return r1;
00603 if( r1->_ndecestors < r2->_ndecestors ) {
00604
00605 r1->_parent = r1->_root = r2;
00606 r2->_children.insert(r1);
00607 r2->_ndecestors += r1->_ndecestors;
00608 return r2;
00609 } else {
00610 r2->_parent = r2->_root = r1;
00611 r1->_children.insert(r2);
00612 r1->_ndecestors += r2->_ndecestors;
00613 return r1;
00614 }
00615 }
00616
00617
00618 decl_list Unify_ECR::all_decls() const {
00619 decl_list ds;
00620 if(_var) ds.push_back(_var);
00621 for(set<Unify_ECR*>::const_iterator c=_children.begin(); c!=_children.end();
00622 c++) {
00623 decl_list more = (*c)->all_decls();
00624 ds.merge(more);
00625 }
00626 return ds;
00627 }
00628
00629 #define huge_pending 1400
00630
00631 #ifdef cx_vt
00632 bool check_28920 = false;
00633 #define parentsOf(t) \
00634 ((t->objTyp()==OBJECT) ? t->object()->p.parents() : \
00635 (t->objTyp()==SIMPLE) ? t->simple()->p.parents() : \
00636 (t->objTyp()==STRUCTURE) ? t->structure()->p.parents() : \
00637 (t->objTyp()==BLANK) ? t->blank()->p.parents() : set<Unify_ECR*>() );
00638 #endif
00639
00640 void Unify_ECR::print() {
00641 #ifdef cx_vt
00642 if(check_28920) {
00643 cout << id() << "/" << *_type << " ";
00644 set<Unify_ECR*> P = parentsOf(_type);
00645 bool contain_25976 = false;
00646 for(set<Unify_ECR*>::iterator p=P.begin(); p!=P.end(); p++)
00647 if((*p)->type()->id() == vt) { contain_25976 = true; break; }
00648 cout << vt << " " << contain_25976 << endl;
00649 if(_parent) _parent->print();
00650 return;
00651 }
00652 #endif
00653
00654 cout << id() << " r=" << root()->id() << "/" << *type();
00655 if(! _pending.empty())
00656 cout << " " << _pending.size() << " pendings";
00657 set<Unify_Pending*> P = _pending.set();
00658 if(!P.empty() && P.size() <= 30) {
00659 cout << " {";
00660 for(Pendings_p p=P.begin(); p!=P.end(); p++) {
00661 if(p!=P.begin()) cout << " ";
00662 if((*p)->is_served()) cout << "s-";
00663 cout << **p;
00664 }
00665 cout << "} ";
00666 }
00667 if(P.size() >= huge_pending) {
00668 for(Pendings_p p=P.begin(); p!=P.end(); p++) {
00669 cout << " {" << **p << "} " << endl;
00670 if((*p)->typ() == Unify_Pending::cjoin)
00671 cout << " " << * (Unify_ECR*) (*p)->arg3() << endl;
00672 }
00673 cout << "end huge " << P.size() << " pendings\n";
00674 exit(1);
00675 }
00676 }
00677
00678
00679
00680 int UnifyType::id_count=0;
00681
00682 Unify_Size UnifyType::size() const {
00683 switch(obj_typ) {
00684 case BOTTOM: return Unify_Size(0);
00685 case SIMPLE: return simple()->s;
00686 case STRUCTURE: return structure()->s;
00687 case OBJECT: return object()->s;
00688 case BLANK: return blank()->s;
00689 }
00690 }
00691
00692
00693 void UnifyType::print() const {
00694 if(is_bottom()) {
00695 cout << id() << ":T_bot";
00696 goto remaining;
00697 }
00698 cout << id() << ":tao";
00699 switch(obj_typ) {
00700 case SIMPLE: {
00701 Unify_Simple *s = _tao.simple;
00702 cout << "(simple " << * s->alpha << ",";
00703 cout << * s->lambda << "," << s->s.str() <<","<< s->p.str() <<")";
00704 break;
00705 }
00706 case OBJECT: {
00707 Unify_Object *o = _tao.object;
00708 cout << "(object " << *o->alpha << ",";
00709 cout << * o->lambda << "," << o->s.str() <<","<< o->p.str();
00710 cout <<")";
00711 break;
00712 }
00713 case STRUCTURE: {
00714 Unify_Structure *s = _tao.structure;
00715 cout << "(struct {";
00716 for(EltMap::iterator m=s->m.begin(); m!=s->m.end(); m++)
00717 if(m->second) {
00718 cout << "<";
00719 declSet decls = m->first;
00720 for(declSet::iterator d=decls.begin(); d!=decls.end(); d++) {
00721 if(d!=decls.begin()) cout << ",";
00722 cout << (*d)->name();
00723 }
00724 cout << "->" << m->second->type()->id() << ">,";
00725 }
00726 cout << "}," << s->s.str() << "," + s->p.str() << ")";
00727 break;
00728 }
00729 case BLANK: {
00730 Unify_Blank *b = _tao.blank;
00731 cout << "(blank " << b->s.str() << "," + b->p.str() << ")";
00732 }
00733 }
00734
00735 remaining:
00736 if(block()) cout << " block=" << block();
00737 if(! _procs.empty()) {
00738 cout << " " << _procs.size() << " procs";
00739 cout << "(";
00740 for(set<procNode*>::iterator p=_procs.begin(); p!=_procs.end(); p++)
00741 cout << (*p)->decl()->name() << ",";
00742 cout << ")";
00743 }
00744 }
00745
00746
00747 class UnificationBasedPtr::findVarAssign : public Walker {
00748
00749
00750 public:
00751 map<declNode*,int> &_assignments;
00752 map<declNode*,bool> &_uses;
00753
00754 findVarAssign(map<declNode*,int> &assignments, map<declNode*,bool> &uses)
00755 : _assignments(assignments), _uses(uses), Walker(Preorder,Subtree) {}
00756
00757 void at_threeAddr(threeAddrNode *ta, Order) {
00758 if(ta->rhs1() && ta->rhs1()->var()->typ()==Id)
00759 _uses[((idNode*) ta->rhs1()->var())->decl()] = true;
00760 if(ta->rhs2() && ta->rhs2()->var()->typ()==Id)
00761 _uses[((idNode*) ta->rhs2()->var())->decl()] = true;
00762 for(operand_list_p a=ta->arg_list().begin(); a!=ta->arg_list().end(); a++)
00763 if((*a)->var()->typ() == Id)
00764 _uses[((idNode*)(*a)->var())->decl()] = true;
00765
00766 if(!ta->lhs() || ta->lhs()->var()->typ() != Id) return;
00767 if(ta->lhs()->star() || ta->lhs()->index() || !ta->lhs()->fields().empty()){
00768 _uses[ ((idNode*)ta->lhs()->var())->decl() ] = true;
00769 return;
00770 }
00771 declNode *lhs = ((idNode*) ta->lhs()->var())->decl();
00772
00773 bool rhs1_is_func = false;
00774 if(ta->rhs1() && ta->rhs1()->var()->typ()==Id) {
00775 operandNode *rhs1 = ta->rhs1();
00776 if(! rhs1->addr() && !rhs1->star() && !rhs1->index() &&
00777 rhs1->fields().empty() &&
00778 ((idNode*)rhs1->var())->decl()->no_tdef_type()->typ() == Func &&
00779
00780 (!rhs1->cast() || rhs1->cast()->follow_tdefs()->typ()==Func))
00781 rhs1_is_func = true;
00782 }
00783
00784 if(!ta->rhs1() || ta->rhs2() || ta->op() || ta->rhs1()->addr() ||
00785 ta->rhs1()->var()->typ() == Const || rhs1_is_func ||
00786 lhs->decl_location() != declNode::BLOCK ||
00787 lhs->storage_class() != declNode::NONE)
00788 _assignments[ lhs ] = 2;
00789 else
00790 _assignments[ lhs ] ++;
00791 }
00792 void at_operand(operandNode *opr, Order) {
00793 if(opr->var()->typ() != Id) return;
00794 if(opr->addr() && !opr->index() && !opr->star() && opr->fields().empty())
00795 _assignments[ ((idNode*)opr->var())->decl() ] = 2;
00796 }
00797 void at_conditiongoto(conditiongotoNode *c, Order) {
00798 if(c->left() && c->left()->typ()==Id)
00799 _uses[((idNode*) c->left())->decl()] = true;
00800 if(c->right() && c->right()->typ()==Id)
00801 _uses[((idNode*) c->right())->decl()] = true;
00802 }
00803 };
00804
00805
00806
00807
00808 void UnificationBasedPtr::at_suespec(suespecNode *sue, Order ord) {
00809 if(ord==Postorder ) return;
00810 if(_visited_sue.find(sue) != _visited_sue.end()) return;
00811 _visited_sue.insert(sue);
00812
00813
00814
00815
00816 for(set<suespecNode*>::iterator s=_unique_sue.begin(); s!=_unique_sue.end();
00817 s++)
00818 if((*s)->owner() == sue->owner() &&
00819 (*s)->coord().to_string() == sue->coord().to_string() &&
00820 (*s)->fields().size() == sue->fields().size()) {
00821
00822
00823 decl_list fields1 = (*s)->fields(),
00824 fields2 = sue->fields();
00825 bool all_same = true;
00826 for(decl_list_p f1=fields1.begin(), f2=fields2.begin();
00827 all_same && f1!=fields1.end(); f1++, f2++)
00828
00829 if((*f1)->name()!=(*f2)->name() ||
00830 (*f1)->coord().to_string()!=(*f2)->coord().to_string())
00831 all_same = false;
00832 if(all_same) {
00833 for(decl_list_p f1=fields1.begin(), f2=fields2.begin();
00834 f1!=fields1.end(); f1++, f2++) {
00835 assert((*f1)->name() == (*f2)->name() &&
00836 (*f1)->coord().to_string() == (*f2)->coord().to_string());
00837 _unique_field_defn[*f2] = *f1;
00838 }
00839 return;
00840 }
00841 }
00842 _unique_sue.insert(sue);
00843
00844 bool is_struct = (sue->owner() == Struct);
00845 decl_list pos;
00846 for(decl_list_p d=sue->fields().begin(); d!=sue->fields().end(); d++) {
00847 _unique_field_defn[*d] = *d;
00848 _field2sue[*d] = sue;
00849 if(! is_struct) pos.clear();
00850 pos.push_back(*d);
00851 _fieldpos[*d] = pos;
00852 }
00853 }
00854
00855
00856 void UnificationBasedPtr::at_proc(procNode *p, Order ord) {
00857 if(ord==Postorder) { cur_proc = NULL; return; }
00858 _analyzed_proc.insert(p);
00859
00860 findVarAssign fva(_assignments, _uses);
00861 p->walk(fva);
00862 _assignments[ p->return_decl() ] = 2;
00863 _uses[ p->return_decl() ] = true;
00864
00865 declNode *decl = p->decl();
00866
00867
00868 procNode *actual_p = linker.lookup_procedure(decl);
00869 if(actual_p && p != actual_p)
00870 return;
00871
00872 cur_proc = p;
00873 if(_ecr[decl]) return;
00874
00875
00876 Unify_ECR *tao0 = _ecr[decl] = new Unify_ECR(decl, cur_proc);
00877 Unify_Size s(Unify_Size::sizeOf(decl->type()));
00878
00879 funcNode *func = (funcNode*) decl->type();
00880 bool returns = ! func->returns()->is_void();
00881 decl_list formals = func->args();
00882 int n=formals.size(), m=returns?1:0;
00883 bool contain_ellipsis = false;
00884
00885 if(n==1 && formals.front()->type()->is_void()) n=0;
00886 else if(n>0 && (formals.back()->type()->is_ellipsis() ||
00887 is_va_list(formals.back()))) {
00888 contain_ellipsis = true;
00889 }
00890
00891 ensure_sim_obj(tao0, s);
00892
00893
00894
00895
00896
00897
00898
00899 _proctype[p] = tao0->type();
00900 _ecr[decl] = tao0->root();
00901 tao0->type()->ecr( tao0->root() );
00902
00903 UnifyType *taoT = tao0->type();
00904 is_Sim_Obj(taoT);
00905 Unify_Size s0 = Sim_Obj_Size(taoT);
00906 Lambda *lambda0 = Sim_Obj_Lambda(taoT);
00907 taoT->procs().insert(p);
00908
00909 if(! s.leq(s0)) expand(tao0);
00910
00911 if(lambda0->is_bottom()) {
00912 Unify_ECR **ecrs = (Unify_ECR**) malloc(n * sizeof(Unify_ECR*));
00913 for(int i=0; i<n; i++)
00914 ecrs[i] = T_bottom->ecr();
00915 settype(lambda0,n,m,ecrs, returns ? T_bottom->ecr() : NULL,
00916 contain_ellipsis);
00917 } else
00918 assert(lambda0->ellipsis() == contain_ellipsis);
00919
00920 decl_list_p f=formals.begin();
00921 Unify_ECR *last = NULL;
00922 Unify_Size last_size;
00923 for(int i=0; i<n; i++, f++) {
00924 _uses[*f] = true;
00925 assert(! _ecr[*f]);
00926 if(i==n-1 && contain_ellipsis) {
00927 assert((*f)->type()->is_ellipsis() || is_va_list(*f));
00928 if(last) {
00929 assert(last->type()->objTyp()==BLANK);
00930 Unify_Blank *b = last->type()->blank();
00931 _ecr[*f] = (new UnifyType(new Unify_Blank(b->s,b->p)))->ecr();
00932 } else {
00933 _ecr[*f] = (new UnifyType(
00934 new Unify_Blank(Unify_Size(),Unify_Parents(true))))->ecr();
00935 }
00936 _ecr[*f]->var(*f);
00937 _ecr[*f]->proc(cur_proc);
00938 } else {
00939 last_size = Unify_Size(Unify_Size::sizeOf((*f)->type()));
00940 _ecr[*f] = last = new Unify_ECR(*f, cur_proc);
00941 }
00942 cjoin(last_size, lambda0->tao(i), _ecr[*f]);
00943 }
00944
00945 if(returns) {
00946 declNode *ret = cur_proc->return_decl();
00947 assert(ret);
00948 typeNode *ret_type = ret->no_tdef_type();
00949 Unify_Size ret_size = Unify_Size(Unify_Size::sizeOf(ret_type));
00950 assert(! _ecr[ret]);
00951 Unify_ECR *ret_tao = _ecr[ret] = new Unify_ECR(ret, cur_proc);
00952 if(ret_type->typ() != Prim || annotation_returns_object(cur_proc))
00953
00954 ensure_sim_obj(ret_tao, ret_size);
00955 cjoin(ret_size, ret_tao, lambda0->taoR());
00956 }
00957 }
00958
00959 #define is_dismantler_tmp(name) ((name).find("__T") == 0)
00960
00961
00962 void UnificationBasedPtr::at_decl(declNode *decl, Order ord) {
00963 if(ord==Preorder || inside_call_func)
00964 return;
00965
00966
00967 declNode::Decl_location loc = decl->decl_location();
00968 if(loc == declNode::FORMAL) return;
00969
00970
00971
00972 if(_ecr.find(decl) != _ecr.end()) return;
00973
00974 if(loc == declNode::ENUM) {
00975 _uses[decl] = true;
00976 assert(_unique_field_defn[decl]);
00977 if(decl != _unique_field_defn[decl]) {
00978 declNode *unique = _unique_field_defn[decl];
00979 at_decl(unique, Postorder);
00980 assert(_ecr[unique]);
00981 _ecr[decl] = _ecr[unique];
00982 return;
00983 }
00984 }
00985
00986 bool is_synthetic;
00987 declNode *real = linker.lookup_symbol(cur_unit, decl->name(),is_synthetic);
00988
00989
00990 if(real && real!=decl && decl->type()->typ() == real->type()->typ() &&
00991 (loc == real->decl_location() || real->decl_location()==declNode::PROC) ||
00992
00993 decl->storage_class() == declNode::EXTERN ||
00994 decl->type()->typ()==Func && (!cur_proc || loc==declNode::BLOCK)) {
00995
00996 if(real && real!=decl && decl->type()->typ() == real->type()->typ() &&
00997 (loc == real->decl_location() || real->decl_location()==declNode::PROC)){
00998 at_decl(real, Postorder);
00999 if(_ecr.find(real) != _ecr.end()) {
01000 _ecr[decl] = _ecr[real];
01001 }
01002 return;
01003 } else if(decl->type()->typ() == Func) {
01004
01005 procNode *new_proc = create_synthetic_proc(decl);
01006 procNode *old_cur_proc = cur_proc;
01007 at_proc(new_proc, Preorder);
01008 cur_proc = old_cur_proc;
01009 return;
01010 }
01011 }
01012
01013 if(loc == declNode::TOP) _uses[decl] = true;
01014
01015 if ((loc == declNode::BLOCK ||
01016 loc == declNode::ENUM ||
01017 loc == declNode::TOP ) &&
01018 decl->storage_class() != declNode::TYPEDEF
01019
01020
01021 ) {
01022
01023 if( _assignments[decl] != 1 && _uses[decl] ) {
01024
01025
01026
01027 assert(decl->name() != "");
01028 _ecr[decl] = new Unify_ECR(decl,cur_proc);
01029
01030 if(is_dismantler_tmp(decl->name())) _dismantler_tmp++;
01031
01032 if(decl->no_tdef_type()->typ() == Array &&
01033 decl->decl_location() != declNode::SU) {
01034
01035 Unify_Size s(Unify_Size::sizeOf(decl->type()));
01036 ensure_sim_obj(_ecr[decl], s);
01037 }
01038
01039 if(loc==declNode::BLOCK && is_va_list(decl)) {
01040
01041 assert(cur_proc);
01042 decl_list formals = ((funcNode*)cur_proc->decl()->type())->args();
01043 assert(formals.size()>=1);
01044 declNode *last_arg = formals.back();
01045 assert(last_arg->type()->is_ellipsis() || is_va_list(last_arg));
01046 assert(_ecr[last_arg]);
01047
01048 Unify_Size s(Unify_Size::sizeOf(decl->type()));
01049 ensure_sim_obj(_ecr[decl], s);
01050 join(Sim_Obj_Alpha(_ecr[decl]->type())->tao(), _ecr[last_arg]);
01051 }
01052
01053 if(decl->init() && decl->init()->typ() == Initializer)
01054 at_initializer((initializerNode*) decl->init(),
01055 decl->no_tdef_type(),
01056 _ecr[decl]);
01057
01058 else if(decl->no_tdef_type()->typ() == Array) {
01059 #define ensure_parent_child(child, parent, child_type) { \
01060 switch(child->type()->objTyp()) { \
01061 case BOTTOM: { \
01062 Unify_Size child_size(Unify_Size::sizeOf(child_type)); \
01063 settype(child, new UnifyType(new Unify_Blank(child_size, \
01064 Unify_Parents(false))));\
01065 \
01066 } \
01067 case BLANK: child->type()->blank()->p.parents().insert(parent); break; \
01068 case SIMPLE: child->type()->simple()->p.parents().insert(parent); break; \
01069 case STRUCTURE: child->type()->structure()->p.parents().insert(parent); \
01070 break; \
01071 case OBJECT: child->type()->object()->p.parents().insert(parent); \
01072 } }
01073
01074 typeNode *curtype = decl->no_tdef_type();
01075 Unify_ECR *tao = _ecr[decl];
01076 while (curtype && (curtype->typ() == Array)) {
01077 exprNode *size = ((arrayNode*)curtype)->dim();
01078 curtype = curtype->no_tdef_type();
01079 Unify_Size array_size;
01080 if(size && size->typ()==Const)
01081 array_size = Unify_Size(((constNode*)size)->value().Integer()
01082 * Unify_Size::sizeOf(curtype));
01083 ensure_sim_obj(tao, array_size);
01084 Unify_ECR *child_tao = Sim_Obj_Alpha(tao->type())->tao();
01085 ensure_parent_child(child_tao, tao, curtype)
01086
01087 if(curtype && curtype->typ() == Array)
01088 tao = child_tao;
01089 }
01090 }
01091
01092 if(loc == declNode::TOP) annotation_init_global(decl);
01093 #ifdef cx_vt
01094 if(decl->name() == "switches") {
01095 cout << "at_decl " << decl->name() << " " << *_ecr[decl] << endl;
01096 debug = true;
01097 vt = _ecr[decl]->type()->id();
01098 vt_e = Sim_Obj_Alpha(_ecr[decl]->type())->tao()->type()->id();
01099 }
01100 #endif
01101 }
01102 }
01103 }
01104
01105
01106 void UnificationBasedPtr::at_threeAddr(threeAddrNode *ta, Order ord) {
01107 if(ord==Postorder) {
01108 inside_call_func = false;
01109 return;
01110 }
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125 if(ta->op() && ta->op()->id() == Operator::FUNC_CALL) {
01126 Unify_Size s = Unify_Size(Unify_Size::sizeOfAssign(ta, linker, this));
01127 operandNode *call = ta->rhs1();
01128 assert(call->var()->typ() == Id);
01129 string call_name = ((idNode*)call->var())->name();
01130 if(! call->star() && (call_name=="malloc" || call_name=="calloc"))
01131 at_allocation(ta,s);
01132 else
01133 at_call(ta,s);
01134 inside_call_func = true;
01135
01136 } else if(! ta->sizeof_type()) {
01137 Unify_Size s = Unify_Size(Unify_Size::sizeOfAssign(ta, linker, this));
01138 assert(ta->lhs());
01139 if(ta->rhs1())
01140 mergeOperand(ta->lhs(), ta->rhs1(), s);
01141 if(ta->rhs2()) {
01142 mergeOperand(ta->lhs(), ta->rhs2(), s);
01143
01144 Unify_ECR *tao = ecr(ta->lhs(), s);
01145 if(tao) {
01146 ensure_sim_obj(tao, s);
01147 UnifyType *t = tao->type();
01148 is_Sim_Obj(t);
01149 Alpha *alpha = Sim_Obj_Alpha(t);
01150 if(alpha->offset()->value() == Unify_Offset::zero)
01151 make_unknown(alpha->offset());
01152 }
01153 }
01154 }
01155
01156 }
01157
01158
01159
01160 void UnificationBasedPtr::mergeOperand(operandNode *lhs, operandNode *rhs,
01161 Unify_Size s) {
01162 bool rhs_is_str = false;
01163 if(rhs->var()->typ() == Const) {
01164 return;
01165 rhs_is_str = ((constNode*)rhs->var())->value().is_str();
01166 }
01167 assert(! lhs->addr());
01168
01169 Unify_ECR *lhs_ecr = NULL;
01170 if(!lhs->index() && !lhs->star() && lhs->fields().empty()) {
01171
01172 declNode *lhs_decl = ((idNode*) lhs->var())->decl();
01173 if(! _uses[lhs_decl]) return;
01174 if(_assignments[lhs_decl] == 1) {
01175 assert(lhs_decl->decl_location() == declNode::BLOCK);
01176 assert(_ecr.find(lhs_decl) == _ecr.end());
01177 assert(! rhs->addr());
01178 assert(rhs->var()->typ() == Id || rhs_is_str);
01179 _ecr[lhs_decl] = ecr(rhs, s);
01180 if(_ecr[lhs_decl]) {
01181 if(! _ecr[lhs_decl]->var() ||
01182 is_dismantler_tmp(_ecr[lhs_decl]->var()->name())) {
01183 _ecr[lhs_decl]->var( lhs_decl );
01184 if(! _ecr[lhs_decl]->proc() &&
01185 lhs_decl->decl_location()==declNode::BLOCK)
01186 _ecr[lhs_decl]->proc( cur_proc );
01187 }
01188 } else
01189 _ecr.erase(lhs_decl);
01190 return;
01191 } else
01192 lhs_ecr = ecr(lhs, s);
01193 } else
01194 lhs_ecr = ecr(lhs, s);
01195 assert(lhs_ecr);
01196
01197 if(rhs->var()->typ() != Id && !rhs_is_str) return;
01198
01199 bool rhs_is_func = false;
01200 if(! rhs->addr() && !rhs->star() && !rhs->index() && rhs->fields().empty() &&
01201 ((idNode*)rhs->var())->decl()->no_tdef_type()->typ() == Func &&
01202
01203
01204
01205
01206 (!rhs->cast() || rhs->cast()->follow_tdefs()->typ()==Func))
01207 rhs_is_func = true;
01208
01209 if(rhs->addr() || rhs_is_str || rhs_is_func) {
01210
01211 ensure_sim_obj(lhs_ecr, s);
01212 if(rhs_is_func) rhs->addr(true);
01213 Alpha *rhs_alpha = alpha(rhs, s);
01214 if(rhs_is_func) rhs->addr(false);
01215 Unify_Size s1 = Sim_Obj_Size(lhs_ecr->type());
01216 if(! s.leq(s1)) expand(lhs_ecr);
01217 join(rhs_alpha, Sim_Obj_Alpha(lhs_ecr->type()));
01218
01219 } else {
01220
01221 Unify_ECR *rhs_ecr = ecr(rhs, s);
01222 cjoin(s, rhs_ecr, lhs_ecr);
01223 }
01224 }
01225
01226
01227 Unify_ECR *UnificationBasedPtr::ecr(operandNode *opr, Unify_Size s,
01228 Unify_Offset **offset) {
01229 if(!opr || opr->var()->typ() != Id) return NULL;
01230 assert(! opr->addr());
01231 declNode *d = ((idNode*)opr->var())->decl();
01232
01233
01234
01235
01236 Unify_ECR *E = ecr1(d);
01237 if(!E) return NULL;
01238
01239 \
01240
01241 if(opr->star() && opr->fields().empty()) {
01242
01243
01244 if(!opr->index())
01245 ensure_sim_obj(E, s);
01246 else {
01247 idNode *id = (idNode*) opr->var();
01248 Unify_Size s1(Unify_Size::sizeOf(id->decl()->type()->type()));
01249 ensure_sim_obj(E, s1);
01250 }
01251 is_Sim_Obj(E->type());
01252 Alpha *alpha2 = Sim_Obj_Alpha(E->type());
01253 unless_zero(alpha2->offset(), alpha2->tao());
01254 E = alpha2->tao();
01255 if(offset) *offset = alpha2->offset();
01256 }
01257
01258
01259 if(! opr->fields().empty()) {
01260 indexNode *index = opr->index();
01261 opr->index(NULL);
01262 id_list fields = opr->fields();
01263 opr->fields().clear();
01264 typeNode *cast = opr->cast();
01265 opr->cast(NULL);
01266
01267 int base_size;
01268 size_operand(opr, base_size)
01269 Unify_Offset *offset2 = NULL;
01270 Unify_ECR *base = ecr(opr, base_size, &offset2);
01271 if(!offset2) offset2 = new Unify_Offset(Unify_Offset::zero);
01272 opr->fields() = fields;
01273 opr->cast(cast);
01274
01275
01276 for(id_list_p f=fields.begin(); f!=fields.end(); f++) {
01277
01278
01279
01280
01281
01282
01283 Unify_ECR *tao2 = base;
01284
01285
01286 Unify_ECR *next_tao2 = NULL;
01287 Unify_Offset *next_offset2 = NULL;
01288 suespecNode *sue = field2sue((*f)->decl());
01289 assert(sue);
01290 if(offset2->value() == Unify_Offset::unknown) {
01291 collapse(tao2);
01292 next_tao2 = tao2->type()->object()->alpha->tao();
01293 if(! next_tao2)
01294 new_field_ECR( next_tao2, 0, tao2 )
01295 if(next_tao2 == tao2) break;
01296 next_offset2 = new Unify_Offset(Unify_Offset::unknown);
01297 } else {
01298 declSet F; F.insert((*f)->decl());
01299 unless_zero(offset2, tao2);
01300 if(tao2->type()->is_bottom() ||
01301 tao2->type()->objTyp() == BLANK) {
01302 ensure_struct_obj(tao2, sue);
01303
01304
01305
01306
01307
01308
01309
01310 }
01311 if(tao2->type()->objTyp() == STRUCTURE) {
01312 Unify_Structure *st = tao2->type()->structure();
01313 make_compatible(F, st, tao2, true);
01314
01315 next_tao2 = st->get(unique_field_defn((*f)->decl()), tao2);
01316 assert(next_tao2);
01317 next_offset2 = new Unify_Offset(Unify_Offset::zero);
01318 } else {
01319 ensure_struct_obj(tao2, sue);
01320 Unify_Size struct_size(Unify_Size::sizeOf(sue));
01321 promote(tao2, struct_size);
01322
01323 next_tao2 = tao2->type()->object()->alpha->tao();
01324 if(! next_tao2)
01325 new_field_ECR( next_tao2, 0, tao2)
01326 if(next_tao2 == tao2) break;
01327 next_offset2 = new Unify_Offset(Unify_Offset::unknown);
01328 }
01329 }
01330 if(next_tao2) {
01331 base = next_tao2;
01332 offset2 = next_offset2;
01333 }
01334 base_size = Unify_Size::sizeOf((*f)->decl()->type());
01335 }
01336
01337 opr->index(index);
01338 E = base;
01339 }
01340
01341 if(opr->index()) {
01342
01343 ensure_sim_obj(E, s);
01344 is_Sim_Obj(E->type());
01345 Alpha *alpha2 = Sim_Obj_Alpha(E->type());
01346 unless_zero(alpha2->offset(), alpha2->tao());
01347 if(offset && (*offset)->value() != Unify_Offset::unknown) {
01348
01349
01350
01351
01352
01353 if(alpha2->offset()->value() == Unify_Offset::unknown ||
01354 opr->index()->typ()!=Const ||
01355 ((constNode*)opr->index())->value().Integer() != 0)
01356 (*offset)->value(Unify_Offset::unknown);
01357 }
01358 E = alpha2->tao();
01359 }
01360
01361
01362
01363
01364
01365 return E;
01366 }
01367
01368
01369 Unify_ECR *UnificationBasedPtr::ecr1(declNode *d) {
01370 Unify_ECR *E = _ecr[d];
01371 if(!E) {
01372 _ecr.erase(d);
01373
01374 if(d->type()->typ() == Func) {
01375 procNode *proc = linker.lookup_procedure(d);
01376 assert(proc);
01377 procNode *old_cur_proc = cur_proc;
01378 at_proc(proc, Preorder);
01379 cur_proc = old_cur_proc;
01380 } else if(_assignments[d] == 1 || !_uses[d])
01381 return NULL;
01382 else {
01383 assert(d->decl_location() == declNode::TOP ||
01384 d->decl_location() == declNode::ENUM);
01385 at_decl(d, Postorder);
01386 }
01387 E = _ecr[d];
01388 assert(E);
01389 }
01390 return E->root();
01391 }
01392
01393
01394 Alpha *UnificationBasedPtr::alpha(operandNode *opr, Unify_Size s) {
01395
01396 if(opr->var()->typ() == Const) {
01397 return NULL;
01398 constNode *con = (constNode*) opr->var();
01399 assert(con->value().is_str());
01400 if(! _string_alpha[con]) {
01401 int len = strlen(con->value().Str());
01402 Unify_ECR *E = (new UnifyType( new Unify_Blank(Unify_Size(len),
01403 Unify_Parents(false))))->ecr();
01404 _string_alpha[con] = new Alpha(E, new Unify_Offset(Unify_Offset::zero));
01405 }
01406 return _string_alpha[con];
01407 }
01408
01409 assert(opr->var()->typ() == Id);
01410 assert(opr->addr());
01411 opr->addr(false);
01412
01413 Unify_Offset * offset = new Unify_Offset(Unify_Offset::zero);
01414 Unify_ECR *E = ecr(opr, s, &offset);
01415 Alpha *alpha = new Alpha(E, offset);
01416
01417 opr->addr(true);
01418
01419
01420 return alpha;
01421 }
01422
01423
01424 void UnificationBasedPtr::at_allocation(threeAddrNode *ta, Unify_Size s) {
01425 if(_alloc[ta]) return;
01426 operandNode *lhs = ta->lhs();
01427 assert(lhs && lhs->var()->typ()==Id);
01428 declNode *lhs_decl = ((idNode*)lhs->var())->decl();
01429 Unify_ECR *x = _ecr[lhs_decl];
01430 if(! x) {
01431
01432 _uses[lhs_decl] = true;
01433 _assignments[lhs_decl] = 2;
01434 bool i = inside_call_func;
01435 inside_call_func = false;
01436 _ecr.erase(lhs_decl);
01437 at_decl(lhs_decl, Postorder);
01438 x = _ecr[lhs_decl];
01439 assert(x);
01440 inside_call_func = i;
01441 }
01442 ensure_sim_obj(x,s);
01443 UnifyType *t = x->type();
01444 is_Sim_Obj(t);
01445 Unify_Size s1 = Sim_Obj_Size(t);
01446 if(! s.leq(s1)) expand(x);
01447 Alpha *alpha1 = Sim_Obj_Alpha(t);
01448 if(alpha1->tao()->type()->is_bottom())
01449 settype(alpha1->tao(),
01450 new UnifyType(new Unify_Blank(Unify_Size(), Unify_Parents(false))));
01451 _alloc[ta] = alpha1->tao();
01452 }
01453
01454
01455 void UnificationBasedPtr::at_call(threeAddrNode *ta, Unify_Size s_m) {
01456 operandNode *call = ta->rhs1();
01457 assert(call->var()->typ() == Id);
01458 typeNode *call_expr_type = call->type()->follow_tdefs();
01459 bool is_func_ptr =
01460 call->star() || !call->fields().empty() || call->index() ||
01461 ((idNode*)call->var())->decl()->type()->follow_tdefs()->typ() == Ptr;
01462 declNode *callee = NULL;
01463
01464 Unify_ECR *tao0;
01465
01466 if(!is_func_ptr) {
01467 assert(call_expr_type->typ() == Func);
01468 Unify_Size s_c(Unify_Size::sizeOf(call_expr_type));
01469 tao0 = ecr(call, s_c);
01470 callee = ((idNode*)call->var())->decl();
01471 ensure_sim_obj(tao0, s_c);
01472 } else {
01473 Unify_Size s_c(Unify_Size::sizeOf(call_expr_type));
01474 tao0 = ecr(call, s_c);
01475
01476
01477 if(call_expr_type->typ() == Ptr) {
01478 call_expr_type = call_expr_type->type()->follow_tdefs();
01479 ensure_sim_obj(tao0, s_c);
01480 tao0 = Sim_Obj_Alpha(tao0->type())->tao();
01481 }
01482 assert(call_expr_type->typ() == Func);
01483 Unify_Size s_c1(Unify_Size::sizeOf(call_expr_type));
01484 ensure_sim_obj(tao0, s_c1);
01485 }
01486
01487 UnifyType *taoT = tao0->type();
01488 is_Sim_Obj(taoT);
01489 Unify_Size s0 = Sim_Obj_Size(taoT);
01490 Lambda *lambda0 = Sim_Obj_Lambda(taoT);
01491
01492 operand_list args = ta->arg_list();
01493 bool returns = ta->lhs();
01494 int n=args.size(), m=returns?1:0;
01495
01496 bool is_synthetic_callee = false;
01497 procNode *proc = NULL;
01498 if(callee) {
01499 proc = linker.lookup_procedure(callee);
01500 if(!proc) {
01501 proc = _synthetic_proc[callee];
01502 assert(proc);
01503 is_synthetic_callee = true;
01504
01505 }
01506 }
01507
01508 if(!proc && lambda0->is_bottom()) {
01509
01510
01511
01512
01513
01514
01515 _ptr_call[ta] = taoT;
01516 return;
01517 }
01518 if(!proc) _ptr_call[ta] = taoT;
01519
01520 if(lambda0->is_bottom()) {
01521 assert(proc);
01522 funcNode *func = (funcNode*) proc->decl()->type();
01523 decl_list formals = func->args();
01524 int n=formals.size(), m=func->returns()->is_void()?0:1;
01525 Unify_ECR **ecrs = (Unify_ECR**) malloc(n * sizeof(Unify_ECR*));
01526 for(int i=0; i<n; i++)
01527 ecrs[i] = T_bottom->ecr();
01528 bool contain_ellipsis =
01529 !formals.empty() &&
01530 (is_va_list(formals.back()) || formals.back()->type()->is_ellipsis());
01531 settype(lambda0,n,m,ecrs, returns ? T_bottom->ecr() : NULL,
01532 contain_ellipsis);
01533 }
01534
01535 if(is_func_ptr) {
01536
01537 set<procNode*> procs = taoT->procs();
01538 for(set<procNode*>::iterator p=procs.begin(); p!=procs.end(); p++)
01539 if((*p)->decl()->name()=="malloc" || (*p)->decl()->name()=="calloc") {
01540 at_allocation(ta, s_m);
01541 break;
01542 }
01543 }
01544
01545
01546 if(is_synthetic_callee) {
01547
01548 if(n>1) {
01549
01550
01551
01552
01553 }
01554 if(lambda0->n() < n)
01555
01556 lambda0->addArg(n - lambda0->n());
01557 }
01558
01559 if(n == lambda0->n() || n+1>=lambda0->n() && lambda0->ellipsis() ||
01560 taoT->procs().size()>1) ;
01561 else {
01562 cout << "Warning: more argument at callsite at " << ta->coord()
01563 << " than callee";
01564 if(callee) cout << " definition at " << callee->coord();
01565 cout << endl;
01566 }
01567
01568 int i=0;
01569 for(operand_list_p arg=args.begin(); arg!=args.end(); arg++) {
01570 bool arg_is_str = false,
01571 arg_is_func = false;
01572 if((*arg)->var()->typ() == Const)
01573 ;
01574 else if(! (*arg)->addr()) {
01575
01576 typeNode *cast = (*arg)->cast();
01577 (*arg)->cast(NULL);
01578 typeNode *arg_type = (*arg)->type()->follow_tdefs();
01579 (*arg)->cast(cast);
01580
01581
01582
01583
01584
01585
01586
01587 if(arg_type->typ() == Func &&
01588
01589
01590
01591
01592 (!(*arg)->cast() ||
01593 (*arg)->cast()->follow_tdefs()->typ()==Ptr &&
01594 (*arg)->cast()->follow_tdefs()->no_tdef_type()->typ()==Func))
01595 arg_is_func = true;
01596 }
01597
01598 if(i<lambda0->n() && ((*arg)->var()->typ() == Id || arg_is_str)) {
01599 Unify_Size s_i = Unify_Size(Unify_Size::sizeOf((*arg)->type()));
01600 Unify_ECR *lambda_tao = NULL;
01601 lambda_tao = lambda0->tao(i);
01602
01603 if((*arg)->addr() || arg_is_str || arg_is_func) {
01604 if(arg_is_func) (*arg)->addr(true);
01605
01606 Alpha *arg_alpha = alpha(*arg, s_i);
01607 if(lambda_tao) {
01608 ensure_sim_obj(lambda_tao, s_i);
01609 Unify_Size s1 = Sim_Obj_Size(lambda_tao->type());
01610 if(! s_i.leq(s1)) expand(lambda_tao);
01611 join(arg_alpha, Sim_Obj_Alpha(lambda_tao->type()));
01612 }
01613 annotation_call_arg(proc, i, (*arg)->type(), arg_alpha);
01614
01615 } else {
01616
01617 Unify_ECR *arg_ecr = ecr(*arg, s_i);
01618 if(arg_ecr && lambda_tao) {
01619 cjoin(s_i, arg_ecr, lambda_tao);
01620 }
01621 annotation_call_arg(proc, i, (*arg)->type(), arg_ecr);
01622 }
01623 }
01624 if(arg_is_func) (*arg)->addr(false);
01625
01626 if(i+1 < lambda0->n()) i++;
01627 else if(! lambda0->ellipsis()) break;
01628 }
01629
01630 if(returns) {
01631 if(lambda0->m()==0) {
01632 cout << "Warning: callsite at " << ta->coord() << " expecting return "
01633 << "value (due to cfg?) when callee has no return value";
01634 if(proc) cout << "(definition at " << proc->coord() << ")";
01635 cout << ".\n";
01636
01637 } else {
01638 assert(ta->lhs()->var()->typ() == Id);
01639 declNode *ret = ((idNode*)ta->lhs()->var())->decl();
01640 Unify_ECR *ret_tao = NULL;
01641 if(_ecr.find(ret) != _ecr.end())
01642 ret_tao = _ecr[ret];
01643 if(ret->no_tdef_type()->typ() != Prim ||
01644 proc && annotation_returns_object(proc) ||
01645 !lambda0->taoR()->type()->is_bottom() &&
01646 lambda0->taoR()->type()->objTyp()!=BLANK) {
01647
01648 Unify_Size ret_size =
01649 Unify_Size(Unify_Size::sizeOf(ret->no_tdef_type()));
01650 if(ret_tao)
01651 ensure_sim_obj(ret_tao, ret_size);
01652 annotation_ret_val(proc, lambda0->taoR(), cur_unit);
01653 }
01654 Unify_Size s_m = Unify_Size(Unify_Size::sizeOfAssign(ta, linker, this));
01655 if(ret_tao)
01656 cjoin(s_m, lambda0->taoR(), ret_tao);
01657 }
01658 }
01659 }
01660
01661
01662 void UnificationBasedPtr::at_initializer(initializerNode *init,
01663 typeNode *init_type,
01664 Unify_ECR *init_ecr) {
01665
01666 typeNode * curtype = init_type->follow_tdefs();
01667 NodeType typ = curtype->typ();
01668 if(typ!=Struct && typ!=Union && typ!=Array) return;
01669 Unify_ECR *tao = init_ecr;
01670 assert(tao);
01671 expr_list inits;
01672 inits.push_back(init);
01673
01674
01675 while (curtype && (curtype->typ() == Array)) {
01676
01677
01678
01679 expr_list new_inits;
01680 for (expr_list_p ip = inits.begin(); ip != inits.end(); ++ip) {
01681 exprNode * expr = (*ip);
01682 if (expr->typ() == Initializer) {
01683 initializerNode * initializer = (initializerNode *) expr;
01684 new_inits.insert(new_inits.end(), initializer->exprs().begin(),
01685 initializer->exprs().end());
01686 }
01687 }
01688
01689 inits = new_inits;
01690 curtype = curtype->no_tdef_type();
01691 Unify_Size array_size(inits.size() * Unify_Size::sizeOf(curtype));
01692 ensure_sim_obj(tao, array_size);
01693 Unify_ECR *child_tao = Sim_Obj_Alpha(tao->type())->tao();
01694 ensure_parent_child(child_tao, tao, curtype)
01695
01696 if(curtype && curtype->typ() == Array)
01697 tao = child_tao;
01698 }
01699
01700 if (curtype && ! inits.empty()) {
01701
01702 if (curtype->typ() == Struct || curtype->typ() == Union) {
01703
01704
01705
01706
01707 Unify_ECR *tao2;
01708 if(curtype == init_type)
01709 tao2 = init_ecr;
01710
01711 else {
01712 Alpha *alpha2 = Sim_Obj_Alpha(tao->type());
01713 tao2 = alpha2->tao();
01714 Unify_Offset *offset2 = alpha2->offset();
01715 unless_zero(offset2, tao2);
01716 }
01717
01718 suespecNode * spec = ((sueNode*)curtype)->spec();
01719 at_suespec(spec, Preorder);
01720 decl_list & fields = spec->fields();
01721
01722
01723 map<declNode*,Unify_ECR*> rhs_unique;
01724
01725 for (expr_list_p ip = inits.begin(); ip != inits.end(); ++ip) {
01726 exprNode * expr = (*ip);
01727 if (expr->typ() != Initializer) continue;
01728 initializerNode * initializer = (initializerNode *) expr;
01729 expr_list & field_inits = initializer->exprs();
01730
01731
01732 decl_list_p fp = fields.begin();
01733 expr_list_p fip = field_inits.begin();
01734 while((fp != fields.end()) && (fip != field_inits.end())) {
01735 declNode * field_decl = (*fp);
01736 exprNode * field_init = (*fip);
01737
01738
01739
01740
01741
01742 idNode * id = 0;
01743 Unify_ECR *rhs_ecr = NULL;
01744 bool rhs_addr = false;
01745 if (field_init->typ() == Id)
01746 id = (idNode *) field_init;
01747 else if (field_init->typ() == Unary) {
01748 unaryNode * un = (unaryNode *) field_init;
01749 if (un->expr()->typ() == Id)
01750 id = (idNode *) un->expr();
01751 rhs_addr = (un->op()->id() == Operator::ADDRESS);
01752 } else if(field_init->typ() == Const && 0 &&
01753 ((constNode*)field_init)->value().is_str()) {
01754 constNode *con = (constNode*) field_init;
01755 if(! _string_alpha[con]) {
01756 int len = strlen(con->value().Str());
01757 Unify_ECR *E = (new UnifyType( new Unify_Blank(Unify_Size(len),
01758 Unify_Parents(false))))->ecr();
01759 _string_alpha[con] = new Alpha(E,
01760 new Unify_Offset(Unify_Offset::zero));
01761 }
01762 rhs_ecr = _string_alpha[con]->tao();
01763 rhs_addr = true;
01764 }
01765 if(id && id->decl()
01766 ) {
01767 typeNode *field_type = field_decl->type();
01768 if(field_type->typ() == Struct ||
01769 field_type->typ() == Union ||
01770 field_type->typ() == Enum)
01771 at_suespec(((sueNode*)field_type)->spec(), Preorder);
01772 rhs_ecr = ecr1(id->decl());
01773 if(id->decl()->type()->typ() == Func)
01774 rhs_addr = true;
01775 }
01776
01777 if(rhs_ecr) {
01778 declSet F; F.insert(field_decl);
01779 Unify_Structure *st;
01780 if(tao2->type()->is_bottom() ||
01781 tao2->type()->objTyp() == BLANK) {
01782 suespecNode *sue = field2sue(field_decl);
01783 assert(sue);
01784 ensure_struct_obj(tao2, sue);
01785
01786 }
01787 if(tao2->type()->objTyp() == STRUCTURE) {
01788 st = tao2->type()->structure();
01789 make_compatible(F, st, tao2, true);
01790 } else assert(false);
01791 Unify_ECR *field_ecr = st->get(unique_field_defn(field_decl),
01792 tao2);
01793 assert(field_ecr);
01794
01795 if(! rhs_addr) {
01796 Unify_Size rhs_size(Unify_Size::sizeOf(id->type()));
01797 cjoin(rhs_size, rhs_ecr, field_ecr);
01798
01799 if(!rhs_unique[field_decl]) rhs_unique[field_decl] = rhs_ecr;
01800 else join(rhs_unique[field_decl], rhs_ecr);
01801 } else {
01802 Unify_Size size(sizeof(int*));
01803 ensure_sim_obj(field_ecr, size);
01804 UnifyType *field_t = field_ecr->type();
01805 if(! size.leq(Sim_Obj_Size(field_t)))
01806 expand(field_ecr);
01807 Alpha *rhs_alpha = new Alpha(rhs_ecr, new Unify_Offset(
01808 Unify_Offset::zero));
01809 join(rhs_alpha, Sim_Obj_Alpha(field_ecr->type()));
01810 delete rhs_alpha;
01811 }
01812
01813 } else if(tao2->type()->is_bottom() ||
01814 tao2->type()->objTyp() == BLANK) {
01815
01816 suespecNode *sue = field2sue(field_decl);
01817 assert(sue);
01818 ensure_struct_obj(tao2, sue);
01819 }
01820
01821 fp++;
01822 fip++;
01823 }
01824 }
01825
01826 } else {
01827
01828
01829 Alpha *alpha3 = Sim_Obj_Alpha(tao->type());
01830 Unify_ECR *tao3 = alpha3->tao();
01831 unless_zero(alpha3->offset(), tao3);
01832
01833 Unify_ECR *rhs_unique=NULL;
01834
01835 for (expr_list_p p = inits.begin(); p != inits.end(); ++p) {
01836 exprNode * the_init = (*p);
01837 idNode * id = 0;
01838 Unify_ECR *rhs_ecr = NULL;
01839 bool rhs_addr = false;
01840
01841 if (the_init->typ() == Id) id = (idNode *) the_init;
01842 else if (the_init->typ() == Unary) {
01843 unaryNode * un = (unaryNode *) the_init;
01844 if (un->expr()->typ() == Id)
01845 id = (idNode *) un->expr();
01846 rhs_addr = (un->op()->id() == Operator::ADDRESS);
01847 } else if(the_init->typ() == Const && 0 &&
01848 ((constNode*)the_init)->value().is_str()) {
01849 constNode *con = (constNode*) the_init;
01850 if(! _string_alpha[con]) {
01851 int len = strlen(con->value().Str());
01852 Unify_ECR *E = (new UnifyType( new Unify_Blank(Unify_Size(len),
01853 Unify_Parents(false))))->ecr();
01854 _string_alpha[con] = new Alpha(E,
01855 new Unify_Offset(Unify_Offset::zero));
01856 }
01857 rhs_ecr = _string_alpha[con]->tao();
01858 rhs_addr = true;
01859 }
01860 if (id && id->decl()
01861 ) {
01862 rhs_ecr = ecr1(id->decl());
01863 if(id->decl()->type()->typ() == Func)
01864 rhs_addr = true;
01865 }
01866
01867 if (rhs_ecr) {
01868 if(! rhs_addr) {
01869 Unify_Size rhs_size(Unify_Size::sizeOf(id->type()));
01870 cjoin(rhs_size, rhs_ecr, tao3);
01871 if(!rhs_unique) rhs_unique = rhs_ecr;
01872 else join(rhs_unique, rhs_ecr);
01873 } else {
01874 Unify_Size size(sizeof(int*));
01875 ensure_sim_obj(tao3, size);
01876 UnifyType *tao3_t = tao3->type();
01877 if(! size.leq(Sim_Obj_Size(tao3_t)))
01878 expand(tao3);
01879 Alpha *rhs_alpha = new Alpha(rhs_ecr, new Unify_Offset(
01880 Unify_Offset::zero));
01881 join(rhs_alpha, Sim_Obj_Alpha(tao3->type()));
01882 delete rhs_alpha;
01883 }
01884
01885 } else if(curtype->follow_tdefs()->typ() == Ptr &&
01886 tao3->type()->is_bottom()) {
01887
01888
01889 Unify_Size size(sizeof(int*));
01890 ensure_sim_obj(tao3, size);
01891 Unify_ECR *child = Sim_Obj_Alpha(tao3->type())->tao();
01892 ensure_parent_child(child, tao3, curtype)
01893 }
01894 }
01895 }
01896 }
01897 }
01898
01899
01900
01901
01902 void UnificationBasedPtr::settype(Unify_ECR *e, UnifyType *t) {
01903 if(e->type() == t) return;
01904 if(e->type()->block()) {
01905 UnifyType *old_type = e->type();
01906 assert(! t->block() || old_type->block() == t->block());
01907 t->block(old_type->block());
01908 old_type->block(NULL);
01909 t->block()->unifyType(t);
01910 }
01911 e->type(t);
01912
01913 set<Unify_Pending*> pending = e->pending().set();
01914
01915 bool big = pending.size() > huge_pending;
01916 if(big) cout << "settype " << pending.size() << " pendings\n";
01917 int not_served = 0;
01918 for(Pendings_p a=pending.begin(); a!=pending.end(); a++) {
01919 if((*a)->is_served()) continue;
01920 not_served++;
01921 if(finalizing) (*a)->served();
01922 switch((*a)->typ()) {
01923 case Unify_Pending::join_ECR:
01924 if(big)
01925 cout<< "join_ECR "<< *(Unify_ECR*) (*a)->arg1() <<"+"<< * (Unify_ECR*) (*a)->arg2() <<endl;
01926 join((Unify_ECR*) (*a)->arg1(), (Unify_ECR*) (*a)->arg2());
01927 break;
01928 case Unify_Pending::join_Lambda:
01929 if(big)
01930 cout << "join_Lambda " << *(Lambda*) (*a)->arg1() <<"+"
01931 << *(Lambda*) (*a)->arg2() << endl;
01932 join((Lambda*) (*a)->arg1(), (Lambda*) (*a)->arg2());
01933 break;
01934 case Unify_Pending::cjoin:
01935 if(big)
01936 cout << "cjoin " << ((Unify_Size*)(*a)->arg1())->size() << " "
01937 << *(Unify_ECR*) (*a)->arg2() <<"+"<< *(Unify_ECR*) (*a)->arg3() << endl;
01938 cjoin(* (Unify_Size*) (*a)->arg1(), (Unify_ECR*) (*a)->arg2(),
01939 (Unify_ECR*) (*a)->arg3());
01940 break;
01941 default: cout << (*a)->typ() << endl; assert(false);
01942 }
01943 }
01944 if(big) {
01945 cout << "not_served = " << not_served << endl;
01946 assert(false);
01947 }
01948 }
01949
01950
01951 void UnificationBasedPtr::settype(Lambda *l, int n, int m, Unify_ECR **t,
01952 Unify_ECR *r, bool ellipsis) {
01953 l->settype(n,m,t,r,ellipsis);
01954 set<Unify_Pending*> pendings = l->pending().set();
01955
01956 for(Pendings_p p=pendings.begin(); p!=pendings.end(); p++) {
01957 switch((*p)->typ()) {
01958 case Unify_Pending::join_Lambda:
01959 join((Lambda*) (*p)->arg1(), (Lambda*) (*p)->arg2());
01960 break;
01961 default: assert(false);
01962 }
01963 }
01964 }
01965
01966
01967 void UnificationBasedPtr::join(Alpha *a1, Alpha *a2, bool *recursion_detected) {
01968 if(a1 == a2) return;
01969 if(a1->offset()->value() == Unify_Offset::zero) {
01970 if(new_pending) {
01971 a1->offset()->pending() = a2->offset()->pending();
01972 a1->offset()->pending().insert( new Unify_Pending(a2->offset()),true );
01973 }
01974 } else if(a2->offset()->value() == Unify_Offset::zero)
01975 make_unknown(a2->offset());
01976 join(a1->tao(), a2->tao(), recursion_detected);
01977 }
01978
01979
01980 void UnificationBasedPtr::join(Unify_ECR *e1, Unify_ECR *e2,
01981 bool *recursion_detected) {
01982 assert(e1); assert(e2);
01983 if(e1 == e2) return;
01984
01985 if(e1->root()==e2->root()) {
01986 if(!finalizing) return;
01987
01988
01989
01990
01991 }
01992
01993
01994 static set<pair<UnifyType*,UnifyType*> > stack;
01995 pair<UnifyType*,UnifyType*> ee(e1->type(),e2->type());
01996 if(stack.find(ee) != stack.end()) {
01997
01998 if(recursion_detected) *recursion_detected = true;
01999 return;
02000 }
02001 stack.insert(ee);
02002 if(recursion_detected) *recursion_detected = false;
02003
02004 static int ID = 0;
02005 int _id = ID++;
02006
02007
02008
02009
02010 bool force_no_pending = false;
02011 if(new_pending && finalizing)
02012
02013
02014
02015 force_no_pending = e1->type()->is_bottom() && e2->type()->is_bottom();
02016
02017 if(new_pending && e1->type()->is_bottom() && !force_no_pending) {
02018 e1->pending().insert( new Unify_Pending(e1,e2),true );
02019 } else {
02020 set<procNode*> e1_procs = e1->type()->procs(),
02021 e2_procs = e2->type()->procs();
02022 UnifyType *e1_type = e1->type(),
02023 *e2_type = e2->type(),
02024 *new_type = unify(e1_type,e2_type);
02025 if(new_type == NULL) return;
02026 if(e1->type() != e1_type || e2->type() != e2_type) {
02027
02028
02029 join(e1, e2);
02030 return;
02031 }
02032
02033 bool e1_changed = new_type!=e1->type(),
02034 e2_changed = new_type!=e2->type();
02035 e1->root()->pending().cleanup();
02036 if(e1->root() != e2->root()) e2->root()->pending().cleanup();
02037 set<Unify_Pending*> e1_pendings = e1->root()->pending().set(),
02038 e2_pendings = e2->root()->pending().set();
02039 Unify_ECR *e = e1->Union(e2);
02040
02041 set<Unify_Pending*> new_pendings;
02042 if(e==e1) new_pendings = e2_pendings;
02043 else if(e==e2) new_pendings = e1_pendings;
02044 else {
02045 new_pendings = e1_pendings;
02046 new_pendings.insert(e2_pendings.begin(), e2_pendings.end());
02047 }
02048 for(Pendings_p p=new_pendings.begin(); p!=new_pendings.end(); p++)
02049 e->pending().insert(*p,false);
02050
02051 if(serve_again) {
02052
02053
02054 if(e1_changed)
02055 for(Pendings_p p=e1_pendings.begin(); p!=e1_pendings.end(); p++)
02056 if((*p)->is_served()) {
02057 (*p)->un_served();
02058 more_pending.insert(*p);
02059 }
02060 if(e2_changed)
02061 for(Pendings_p p=e2_pendings.begin(); p!=e2_pendings.end(); p++)
02062 if((*p)->is_served()) {
02063 (*p)->un_served();
02064 more_pending.insert(*p);
02065 }
02066 }
02067
02068
02069 settype(e, new_type);
02070 set<procNode*> e_procs = e->type()->procs();
02071 for(set<procNode*>::iterator p=e1_procs.begin(); p!=e1_procs.end(); p++)
02072 if(e_procs.find(*p) == e_procs.end()) {
02073 cout << _id << " ";
02074 cout << (*p)->decl()->name() << endl;
02075 cout << *e1 << "\n + " << *e2 << "\n -> " << *e << endl;
02076 cout << "new_type " << *new_type << endl;
02077 assert(false);
02078 }
02079 for(set<procNode*>::iterator p=e2_procs.begin(); p!=e2_procs.end(); p++)
02080 if(e_procs.find(*p) == e_procs.end()) {
02081 cout << _id << " ";
02082 cout << (*p)->decl()->name() << endl;
02083 cout << *e1 << "\n + " << *e2 << "\n -> " << *e << endl;
02084 cout << "new_type " << *new_type << endl;
02085 assert(false);
02086 }
02087
02088
02089
02090
02091
02092 }
02093 stack.erase(ee);
02094 }
02095
02096
02097 void UnificationBasedPtr::join(Lambda *l1, Lambda *l2) {
02098 assert(l1 && l2);
02099 if(l1 == l2) return;
02100
02101 if(l1->is_bottom() && new_pending) {
02102 l1->pending().insert( new Unify_Pending(l1,l2),true );
02103 } else if(l2->is_bottom() && new_pending) {
02104 l2->pending().insert( new Unify_Pending(l1,l2),true );
02105 } else if(!l1->is_bottom() && !l2->is_bottom()) {
02106
02107
02108
02109
02110
02111
02112 l2->addArg(l1->n() - l2->n());
02113 l1->addArg(l2->n() - l1->n());
02114 int t = l1->n() < l2->n() ? l1->n() : l2->n();
02115 for(int i=0; i<t; i++) {
02116 Unify_ECR *e1 = l1->tao(i),
02117 *e2 = l2->tao(i);
02118 if(! e1->type()->is_bottom())
02119 join(e1, e2);
02120 else if(! e2->type()->is_bottom())
02121 join(e2, e1);
02122 else {
02123 join(e1, e2);
02124
02125
02126
02127
02128 e2->pending().insert( new Unify_Pending(e2,e1),true );
02129 }
02130 l1->tao(i,e1->root()); l2->tao(i,e1->root());
02131 }
02132
02133 if(l1->m()>0 && l2->m()>0) {
02134 Unify_ECR *e1 = l1->taoR(),
02135 *e2 = l2->taoR();
02136 if(! e1->type()->is_bottom())
02137 join(e1, e2);
02138 else if(! e2->type()->is_bottom())
02139 join(e2, e1);
02140 else {
02141 join(e1, e2);
02142 e2->pending().insert( new Unify_Pending(e2,e1),true );
02143 }
02144 l1->taoR(e1->root()); l2->taoR(e1->root());
02145 }
02146
02147 if(finalizing) {
02148 set<Unify_Pending*> pendings = l1->pending().set(),
02149 more = l2->pending().set();
02150 pendings.insert(more.begin(), more.end());
02151 for(Pendings_p p=pendings.begin(); p!=pendings.end(); p++) {
02152 if((*p)->is_served()) continue;
02153 (*p)->served();
02154 switch((*p)->typ()) {
02155 case Unify_Pending::join_Lambda:
02156 join((Lambda*) (*p)->arg1(), (Lambda*) (*p)->arg2());
02157 break;
02158 default: assert(false);
02159 }
02160 }
02161 }
02162
02163 } else if(!l1->is_bottom() || !l2->is_bottom()) {
02164 assert(! new_pending);
02165 Lambda *bot, *non_bot;
02166 if( l1->is_bottom() ) { bot = l1; non_bot = l2; }
02167 else { bot = l2; non_bot = l1; }
02168 Unify_ECR **taos = (Unify_ECR**) malloc(non_bot->n() * sizeof(Unify_ECR*));
02169 for(int i=0; i<non_bot->n(); i++) taos[i] = non_bot->tao(i);
02170 settype(bot, non_bot->n(), non_bot->m(), taos,
02171 non_bot->m()>0 ? non_bot->taoR() : NULL, non_bot->ellipsis());
02172 }
02173
02174 }
02175
02176
02177 void UnificationBasedPtr::ensure_sim_obj(Unify_ECR *tao, Unify_Size &s) {
02178 if(tao->type()->is_bottom()) {
02179 Unify_Parents par(false);
02180 settype(tao, new UnifyType(new Unify_Simple(new Alpha(), L_bottom,
02181 s, par)));
02182 return;
02183 }
02184 switch(tao->type()->objTyp()) {
02185 case BLANK: {
02186 Unify_Blank *b = tao->type()->blank();
02187 settype(tao, new UnifyType(new Unify_Simple(new Alpha(), L_bottom,
02188 b->s, b->p)));
02189 if(! s.leq(b->s)) expand(tao);
02190 break;
02191 }
02192 case SIMPLE: {
02193 Unify_Simple *si = tao->type()->simple();
02194 if(! s.leq(si->s)) expand(tao);
02195 break;
02196 }
02197 case STRUCTURE: {
02198 Unify_Structure *st = tao->type()->structure();
02199 promote(tao, st->s);
02200 }
02201
02202 }
02203 }
02204
02205
02206 void UnificationBasedPtr::ensure_no_bottom(Unify_ECR *tao, declNode *decl,
02207 UnifyType *parent) {
02208 if(! tao->type()->is_bottom()) return;
02209
02210 Unify_Size s;
02211 if(decl && decl->type()) s = Unify_Size(Unify_Size::sizeOf(decl->type()));
02212 Unify_Parents p(false);
02213 if(parent) p.parents().insert(parent->ecr());
02214 settype(tao, new UnifyType(new Unify_Blank(s, p)));
02215 }
02216
02217
02218 Unify_Structure *UnificationBasedPtr::ensure_struct_obj(Unify_ECR *tao,
02219 suespecNode *sue,
02220 bool redo_pending) {
02221 assert(sue);
02222 Object_Typ typ = tao->type()->objTyp();
02223 if(typ == STRUCTURE) return tao->type()->structure();
02224 if(tao->type()->is_bottom() || typ == BLANK) {
02225 Unify_Structure *st;
02226 if(tao->type()->is_bottom()) {
02227 Unify_Size struct_size(Unify_Size::sizeOf(sue));
02228 st = new Unify_Structure(sue, EltMap(), struct_size,
02229 Unify_Parents(false));
02230 } else {
02231 Unify_Blank *blank = tao->type()->blank();
02232 st = new Unify_Structure(sue, EltMap(), blank->s, blank->p);
02233 }
02234 UnifyType *tao_type = tao->type();
02235 UnifyType *st_type = new UnifyType(st);
02236
02237 if(redo_pending) {
02238 typeNode *c_type = NULL;
02239 memoryBlock *m = tao->type()->block();
02240 if(m && m->decl())
02241 c_type = m->decl()->type();
02242 Unify_Size size;
02243 if(c_type) size = Unify_Size(Unify_Size::sizeOf(c_type));
02244
02245
02246 set<Unify_Pending*> pending = tao->pending().set();
02247 for(Pendings_p a=pending.begin(); a!=pending.end(); a++) {
02248 (*a)->un_served();
02249 if((*a)->typ() == Unify_Pending::cjoin &&
02250 ! ((Unify_Size*) (*a)->arg1())->leq(size)) {
02251
02252
02253 size = Unify_Size();
02254 if(tao->type()->objTyp() == BLANK)
02255
02256 tao->type()->blank()->s= size;
02257 }
02258 }
02259 }
02260
02261 if(tao->type() != tao_type)
02262 return ensure_struct_obj(tao, sue, redo_pending);
02263 settype(tao, st_type);
02264 return st;
02265 } else {
02266 Unify_Size struct_size(Unify_Size::sizeOf(sue));
02267 promote(tao, struct_size);
02268 return NULL;
02269 }
02270 }
02271
02272
02273 void UnificationBasedPtr::expand(Unify_ECR *e) {
02274
02275
02276 UnifyType *T = e->type(),
02277 *U = unify(T, new UnifyType(new Unify_Blank(Unify_Size(),
02278 Unify_Parents(false))));
02279 while(T != e->type())
02280 U = unify(T = e->type(), U);
02281 settype(e, U);
02282 }
02283
02284
02285 void UnificationBasedPtr::promote(Unify_ECR *e, Unify_Size &s) {
02286 if(e->type()->objTyp() == OBJECT && s.leq(e->type()->object()->s))
02287 return;
02288
02289
02290
02291
02292 UnifyType *T = e->type(),
02293 *U = unify(T, new UnifyType(new Unify_Object(new Alpha(), L_bottom,
02294 s, Unify_Parents(false))));
02295 while(T != e->type())
02296 U = unify(T = e->type(), U);
02297 settype(e, U);
02298 }
02299
02300
02301 void UnificationBasedPtr::collapse(Unify_ECR *e) {
02302 if(e->type()->objTyp() == OBJECT) {
02303 Unify_Size s;
02304 if(s.leq(e->type()->object()->s)) return;
02305 }
02306
02307
02308
02309
02310
02311 UnifyType *T = e->type(),
02312 *U = unify(T, new UnifyType(new Unify_Object(new Alpha(), L_bottom,
02313 Unify_Size(),
02314 Unify_Parents(true))));
02315 while(T != e->type())
02316 U = unify(T = e->type(), U);
02317 settype(e, U);
02318 }
02319
02320
02321 void UnificationBasedPtr::make_unknown(Unify_Offset *o) {
02322 if(o->value() == Unify_Offset::zero) return;
02323 o->value(Unify_Offset::unknown);
02324 set<Unify_Pending*> pending = o->pending().set();
02325
02326 for(Pendings_p a=pending.begin(); a!=pending.end(); a++) {
02327 if((*a)->is_served()) continue;
02328 if(finalizing) (*a)->served();
02329 switch((*a)->typ()) {
02330 case Unify_Pending::collapse:
02331 collapse((Unify_ECR*) (*a)->arg1());
02332 break;
02333 case Unify_Pending::makeunknown:
02334 if((Unify_Offset*) (*a)->arg1() != o)
02335 make_unknown((Unify_Offset*) (*a)->arg1());
02336 break;
02337 }
02338 }
02339 }
02340
02341 void UnificationBasedPtr::unless_zero(Unify_Offset *o, Unify_ECR *tao) {
02342 if(o->value() == Unify_Offset::zero) {
02343 if(new_pending)
02344 o->pending().insert( new Unify_Pending(tao),true );
02345 } else
02346 collapse(tao);
02347 }
02348
02349 void UnificationBasedPtr::cjoin(Unify_Size &s, Unify_ECR *e1, Unify_ECR *e2) {
02350 if(!e1 || !e2) return;
02351 if(e1 == e2 || e1->root()==e2->root()) return;
02352
02353
02354 static set<pair<UnifyType*,UnifyType*> > stack;
02355 pair<UnifyType*,UnifyType*> ee(e1->type(),e2->type());
02356 if(stack.find(ee) != stack.end()) {
02357
02358 return;
02359 }
02360 stack.insert(ee);
02361
02362
02363
02364 bool force_no_pending = e1->type()->objTyp()==OBJECT &&
02365 e2->type()->objTyp()==OBJECT &&
02366 e1->type()->object()->alpha->tao()->type() ==
02367 e2->type()->object()->alpha->tao()->type();
02368
02369 if(new_pending && !force_no_pending)
02370 e1->pending().insert( new Unify_Pending(s,e1,e2),true );
02371
02372 if(e1->type()->is_bottom()) {
02373 stack.erase(ee);
02374 return;
02375 }
02376
02377
02378
02379 Object_Typ e2_typ = e2->type()->objTyp();
02380
02381 switch(e1->type()->objTyp()) {
02382 case BLANK: {
02383 Unify_Blank *b1 = e1->type()->blank();
02384 if(! s.leq(b1->s))
02385 expand(e1);
02386 else if(e2->type()->is_bottom())
02387 settype(e2, new UnifyType(new Unify_Blank(s, Unify_Parents(false))));
02388 else if(! s.leq(e2->type()->size()))
02389 expand(e2);
02390 break;
02391 }
02392
02393 case SIMPLE: {
02394 Unify_Simple *sim1 = e1->type()->simple();
02395 if(! s.leq(sim1->s))
02396 expand(e1);
02397 else if(e2->type()->is_bottom())
02398 settype(e2, new UnifyType(new Unify_Simple(sim1->alpha, sim1->lambda,
02399 s, Unify_Parents(false))));
02400 else {
02401 switch(e2->type()->objTyp()) {
02402 case BLANK: {
02403 Unify_Blank *b2 = e2->type()->blank();
02404 settype(e2, new UnifyType(new Unify_Simple(sim1->alpha,sim1->lambda,
02405 b2->s, b2->p)));
02406 if(! s.leq(b2->s))
02407 expand(e2);
02408 break;
02409 }
02410 case SIMPLE: {
02411 Unify_Simple *sim2 = e2->type()->simple();
02412 join(sim1->alpha, sim2->alpha);
02413 join(sim1->lambda, sim2->lambda);
02414 if(! s.leq(sim2->s))
02415 expand(e2);
02416 break;
02417 }
02418 case STRUCTURE:
02419 promote(e2, e2->type()->structure()->s);
02420 if(!finalizing && !serve_again) break;
02421 case OBJECT: {
02422 Unify_Object *o = e2->type()->object();
02423
02424 join(sim1->alpha, o->alpha);
02425 join(sim1->lambda, o->lambda);
02426 }
02427 }
02428 }
02429 break;
02430 }
02431
02432 case STRUCTURE: {
02433 Unify_Structure *st1 = e1->type()->structure();
02434 if(! s.leq(st1->s))
02435 expand(e1);
02436 else if(e2->type()->is_bottom())
02437 settype(e2, new UnifyType(
02438 new Unify_Structure(st1->fo, st1->fto, st1->m, s,
02439 Unify_Parents(false))));
02440 else {
02441 switch(e2->type()->objTyp()) {
02442 case BLANK: {
02443 Unify_Blank *b2 = e2->type()->blank();
02444 settype(e2, new UnifyType(
02445 new Unify_Structure(st1->fo, st1->fto, st1->m, b2->s,
02446 b2->p)));
02447 if(! s.leq(b2->s))
02448 expand(e2);
02449 break;
02450 }
02451 case SIMPLE:
02452 promote(e2, e2->type()->simple()->s);
02453 if(finalizing || serve_again) goto STRUCTURE_OBJECT;
02454 break;
02455 case STRUCTURE: {
02456 Unify_Structure *st2 = e2->type()->structure();
02457 bool all_compatible = true;
02458 if(s.leq(st2->s)) {
02459
02460 for(EltMap::iterator x=st1->m.begin(); x!=st1->m.end(); x++)
02461 if(! make_compatible(x->first, st2, e2))
02462 { all_compatible = false; break; }
02463 } else all_compatible = false;
02464 if(all_compatible)
02465 for(EltMap::iterator x=st1->m.begin(); x!=st1->m.end(); x++) {
02466 declNode *one_field = unique_field_defn(* x->first.begin());
02467 Unify_Size s_x(Unify_Size::sizeOf(one_field->type()));
02468 cjoin(s_x, x->second, st2->get(one_field, e2));
02469 }
02470 else
02471 expand(e2);
02472 break;
02473 }
02474 case OBJECT: {
02475 STRUCTURE_OBJECT:
02476
02477 for(EltMap::iterator x=st1->m.begin(); x!=st1->m.end(); x++) {
02478 Unify_Size s_x(Unify_Size::sizeOf((*x->first.begin())->type()));
02479 cjoin(s_x, x->second, e2);
02480 }
02481 }
02482 }
02483 }
02484 break;
02485 }
02486
02487 case OBJECT: {
02488 Unify_Object *o1 = e1->type()->object();
02489 if(! s.leq(o1->s)) expand(e1);
02490
02491
02492 if(finalizing || serve_again)
02493 promote(e2,s);
02494
02495 Unify_Object *o2 = NULL;
02496 if(e2->type()->objTyp()==OBJECT) {
02497 o2 = e2->type()->object();
02498
02499 }
02500 if( o2 ) {
02501 bool f = finalizing;
02502 finalizing = false;
02503 if(! s.leq(o2->s)) expand(e2);
02504 join(o1->alpha, o2->alpha);
02505 join(o1->lambda, o2->lambda);
02506 finalizing = f;
02507
02508 }
02509
02510
02511 else
02512 promote(e2,s);
02513
02514
02515
02516
02517 }
02518 }
02519
02520 if(serve_again && e2_typ != e2->type()->objTyp()) {
02521
02522
02523 set<Unify_Pending*> pending = e2->root()->pending().set();
02524 for(Pendings_p p=pending.begin(); p!=pending.end(); p++)
02525 if((*p)->is_served()) {
02526 (*p)->un_served();
02527 more_pending.insert(*p);
02528 }
02529 }
02530
02531
02532
02533 stack.erase(ee);
02534 }
02535
02536
02537 UnifyType *UnificationBasedPtr::unify(UnifyType *t1, UnifyType *t2) {
02538 if(t1 == t2) return t1;
02539
02540 #define return_unify(t) { \
02541 UnifyType *T = (t)->ecr()->type();
02542 \
02543 memoryBlock *block = t1->block() ? t1->block() : t2->block(); \
02544 if(! T->block()) T->block(block); \
02545 else assert(T->block()==block); \
02546 \
02547 if(t1 != T) T->procs().insert(t1->procs().begin(), t1->procs().end()); \
02548 if(t2 != T) T->procs().insert(t2->procs().begin(), t2->procs().end()); \
02549 \
02550 return T; \
02551 }
02552
02553 if(t1->block() && t2->block()) {
02554 cout << "cannot unify " << *t1 << " + " << *t2 << endl;
02555 cout << " " << *t1->ecr() << " + " << *t2->ecr() << endl;
02556 cout << " " << t1->block()->name() << " + " << t2->block()->name() << endl;
02557 assert(false);
02558 return NULL;
02559 }
02560
02561 Object_Typ ty1 = t1->objTyp(),
02562 ty2 = t2->objTyp(),
02563 result_ty;
02564 if(ty1 == BOTTOM) return_unify( t2 )
02565 if(ty2 == BOTTOM) return_unify( t1 )
02566
02567 #define max_Lambda(t1, ty1, t2, ty2, l) \
02568 if(t1->is_bottom() || ty1==STRUCTURE || ty1==BLANK) { \
02569 is_Sim_Obj(t2); \
02570 l = Sim_Obj_Lambda(t2); \
02571 } else if(t2->is_bottom() || ty2==STRUCTURE || ty2==BLANK) { \
02572 is_Sim_Obj(t1); \
02573 l = Sim_Obj_Lambda(t1); \
02574 } else { \
02575 l = Sim_Obj_Lambda(t1); \
02576 Lambda *l2 = Sim_Obj_Lambda(t2); \
02577 if(l->leq(l2)) l=l2; \
02578 else if(l2->leq(l)) ; \
02579 else join(l,l2); \
02580 }
02581
02582 #define sizeOfType(t,ty) \
02583 ((ty==OBJECT) ? t->object()->s : \
02584 (ty==SIMPLE) ? t->simple()->s : \
02585 (ty==STRUCTURE) ? t->structure()->s : \
02586 (ty==BLANK) ? t->blank()->s : Unify_Size())
02587
02588 #define max_Size(t1, ty1, t2, ty2, s) \
02589 if(t1->is_bottom()) \
02590 s = sizeOfType(t2,ty2); \
02591 else if(t2->is_bottom()) \
02592 s = sizeOfType(t1,ty1); \
02593 else { \
02594 s = sizeOfType(t1,ty1); \
02595 Unify_Size s2 = sizeOfType(t2,ty2); \
02596 if(s.is_top()) ; \
02597 else if(s2.is_top()) s=s2; \
02598 else if( s.size() < s2.size() ) s=s2; \
02599 }
02600
02601 #define parentsOfType(t,ty) \
02602 ((ty==OBJECT) ? t->object()->p : \
02603 (ty==SIMPLE) ? t->simple()->p : \
02604 (ty==STRUCTURE) ? t->structure()->p : \
02605 (ty==BLANK) ? t->blank()->p : Unify_Parents(true))
02606
02607 #define max_Parents(t1, ty1, t2, ty2, p) \
02608 if(t1->is_bottom()) \
02609 p = parentsOfType(t2,ty2); \
02610 else if(t2->is_bottom()) \
02611 p = parentsOfType(t1,ty1); \
02612 else { \
02613 Unify_Parents p1 = parentsOfType(t1,ty1), \
02614 p2 = parentsOfType(t2,ty2); \
02615 for(set<Unify_ECR*>::iterator P=p1.parents().begin(); \
02616 P!=p1.parents().end(); P++)\
02617 p.parents().insert((*P)->root()); \
02618 for(set<Unify_ECR*>::iterator P=p2.parents().begin(); \
02619 P!=p2.parents().end(); P++)\
02620 p.parents().insert((*P)->root()); \
02621 if(!p1.is_top() || ! p2.is_top()) p.top(false); \
02622 }
02623
02624 if(ty1==OBJECT || ty2==OBJECT || ty1==STRUCTURE && ty2==SIMPLE ||
02625 ty2==STRUCTURE && ty1==SIMPLE)
02626 result_ty = OBJECT;
02627 else if(ty1==SIMPLE || ty2==SIMPLE)
02628 result_ty = SIMPLE;
02629 else if(ty1==STRUCTURE || ty2==STRUCTURE)
02630 result_ty = STRUCTURE;
02631 else if(ty1==BLANK || ty2==BLANK)
02632 result_ty = BLANK;
02633 else result_ty = BOTTOM;
02634
02635
02636
02637
02638
02639
02640
02641 if(result_ty==SIMPLE || result_ty==OBJECT) {
02642 Unify_Size s;
02643 max_Size(t1,ty1,t2,ty2,s)
02644 Alpha *alpha;
02645 bool recursion_detected;
02646 if(ty1!=SIMPLE && ty1!=OBJECT)
02647 alpha = Sim_Obj_Alpha(t2);
02648 else if(ty2!=SIMPLE && ty2!=OBJECT)
02649 alpha = Sim_Obj_Alpha(t1);
02650 else {
02651 Alpha *a1 = Sim_Obj_Alpha(t1),
02652 *a2 = Sim_Obj_Alpha(t2);
02653 if(a2->offset()->value() == Unify_Offset::unknown)
02654 join(a2,a1,&recursion_detected);
02655 else
02656 join(a1,a2,&recursion_detected);
02657
02658
02659
02660 if(a1->tao()->root() == a1->tao()) alpha = a1;
02661 else if(a2->tao()->root() == a2->tao()) alpha = a2;
02662 else alpha = new Alpha(a1->tao()->root(), a1->offset());
02663 }
02664 Lambda *lambda;
02665 max_Lambda(t1,ty1,t2,ty2,lambda)
02666 Unify_Parents p(true);
02667 max_Parents(t1,ty1,t2,ty2,p);
02668
02669 if(result_ty==SIMPLE) {
02670 if(ty1==SIMPLE) {
02671 Unify_Simple *s1 = t1->simple();
02672 if((s1->alpha->equal(alpha) || s1->alpha->tao()->type()->is_bottom()) &&
02673 s1->lambda->equal(lambda) && s1->s.equal(s) && s1->p.equal(p))
02674 return_unify( t1 )
02675 }
02676 if(ty2==SIMPLE) {
02677 Unify_Simple *s2 = t2->simple();
02678 if((s2->alpha->equal(alpha) || s2->alpha->tao()->type()->is_bottom()) &&
02679 s2->lambda->equal(lambda) && s2->s.equal(s) && s2->p.equal(p))
02680 return_unify( t2 )
02681 }
02682 if(ty1==SIMPLE && ty2==SIMPLE && recursion_detected) {
02683
02684
02685
02686 t1->simple()->p = p;
02687 return_unify( t1 )
02688 }
02689 if(ty1==SIMPLE && !recursion_detected) {
02690 Unify_Simple *s1 = t1->simple();
02691 s1->lambda = lambda;
02692 s1->s = s;
02693 s1->p = p;
02694 return_unify( t1 )
02695 } else if(ty2==SIMPLE && !recursion_detected) {
02696 Unify_Simple *s2 = t2->simple();
02697 s2->lambda = lambda;
02698 s2->s = s;
02699 s2->p = p;
02700 return_unify( t2 )
02701 }
02702 Unify_Simple *sim = new Unify_Simple(alpha, lambda, s, p);
02703 return_unify( new UnifyType(sim) )
02704
02705 } else {
02706 Unify_ECR *field = NULL;
02707 #define consolidate_struct_fields(struc,result) {\
02708 EltMap map = struc->m; \
02709 for(EltMap::iterator m=map.begin(); m!=map.end(); m++) \
02710 if(m->second) { \
02711 if(result) join(result, m->second); \
02712 else result = m->second; \
02713 } \
02714 }
02715
02716 #define consolidate_sim_obj_fields(alpha,result) {\
02717 if(result) join(result,alpha->tao()); \
02718 else result = alpha->tao(); \
02719 }
02720
02721 if(ty1==STRUCTURE) consolidate_struct_fields(t1->structure(), field)
02722 else if(ty1==SIMPLE || ty1==OBJECT)
02723 consolidate_sim_obj_fields(Sim_Obj_Alpha(t1), field)
02724 if(ty2==STRUCTURE) consolidate_struct_fields(t2->structure(), field)
02725 else if(ty2==SIMPLE || ty2==OBJECT)
02726 consolidate_sim_obj_fields(Sim_Obj_Alpha(t2), field)
02727
02728 if(ty1==OBJECT) {
02729 Unify_Object *o1 = t1->object();
02730 if((o1->alpha->equal(alpha) || o1->alpha->tao()->type()->is_bottom()) &&
02731 o1->lambda->equal(lambda) && o1->s.equal(s) && o1->p.equal(p))
02732 return_unify( t1 )
02733 }
02734 if(ty2==OBJECT) {
02735 Unify_Object *o2 = t2->object();
02736 if((o2->alpha->equal(alpha) || o2->alpha->tao()->type()->is_bottom()) &&
02737 o2->lambda->equal(lambda) && o2->s.equal(s) && o2->p.equal(p))
02738 return_unify( t2 )
02739 }
02740 if(ty1==OBJECT && ty2==OBJECT && recursion_detected) {
02741
02742
02743
02744 t1->object()->p = p;
02745 return_unify( t1 )
02746 }
02747 if(ty1==OBJECT && !recursion_detected) {
02748 Unify_Object *o1 = t1->object();
02749 o1->lambda = lambda;
02750 o1->s = s;
02751 o1->p = p;
02752 return_unify( t1 )
02753 } else if(ty2==OBJECT && !recursion_detected) {
02754 Unify_Object *o2 = t2->object();
02755 o2->lambda = lambda;
02756 o2->s = s;
02757 o2->p = p;
02758 return_unify( t2 )
02759 }
02760 Unify_Object *obj = new Unify_Object(alpha, lambda, s, p);
02761 return_unify( new UnifyType(obj) )
02762 }
02763
02764 } else if(result_ty==STRUCTURE) {
02765 Unify_Size s;
02766 max_Size(t1,ty1,t2,ty2,s)
02767 Unify_Parents p(true);
02768 max_Parents(t1,ty1,t2,ty2,p);
02769
02770 EltMap m;
02771 FieldOrder fo;
02772 FieldTypeOrder fto;
02773 if(ty1!=STRUCTURE) {
02774 t2->structure()->s = s;
02775 t2->structure()->p = p;
02776 return_unify( t2 )
02777 } else if(ty2!=STRUCTURE) {
02778 t1->structure()->s = s;
02779 t1->structure()->p = p;
02780 return_unify( t1 )
02781 } else {
02782 Unify_Structure *s = new Unify_Structure(FieldOrder(), FieldTypeOrder(),
02783 EltMap(), Unify_Size(), p);
02784 merge_EltMap(t1, t2, s);
02785 return_unify( new UnifyType(s) )
02786 }
02787
02788
02789 } else if(result_ty==BLANK) {
02790 Unify_Size s;
02791 max_Size(t1,ty1,t2,ty2,s)
02792 Unify_Parents p(true);
02793 max_Parents(t1,ty1,t2,ty2,p);
02794 if(ty1==BLANK) {
02795 Unify_Blank *b1 = t1->blank();
02796 if(b1->s.equal(s) && b1->p.equal(p)) return_unify( t1 )
02797 }
02798 if(ty2==BLANK) {
02799 Unify_Blank *b2 = t2->blank();
02800 if(b2->s.equal(s) && b2->p.equal(p)) return_unify( t2 )
02801 }
02802 if(ty1==BLANK) {
02803 Unify_Blank *b1 = t1->blank();
02804 b1->s = s;
02805 b1->p = p;
02806 return_unify( t1 )
02807 } else {
02808 Unify_Blank *b2 = t2->blank();
02809 b2->s = s;
02810 b2->p = p;
02811 return_unify( t2 )
02812 }
02813
02814 } else
02815 return_unify( t1 )
02816 }
02817
02818
02819 void UnificationBasedPtr::merge_EltMap(UnifyType *t1, UnifyType *t2,
02820 Unify_Structure *s) {
02821
02822
02823
02824
02825
02826
02827
02828
02829
02830
02831
02832 assert(t1->objTyp()==STRUCTURE && t2->objTyp()==STRUCTURE);
02833 EltMap m1 = t1->structure()->m,
02834 m2 = t2->structure()->m;
02835 FieldOrder fo1 = t1->structure()->fo,
02836 fo2 = t2->structure()->fo;
02837
02838 for(FieldOrder::iterator f1=fo1.begin(); f1!=fo1.end(); f1++) {
02839 make_compatible(*f1,s,t1->ecr(),true);
02840 if(! m1[*f1]) continue;
02841 declNode *one_field = * f1->begin();
02842 FieldOrder::iterator fo=s->fo.begin();
02843 while(fo!=s->fo.end() && fo->find(one_field)==fo->end())
02844 fo++;
02845 assert(fo!=s->fo.end());
02846 join(m1[*f1], s->m[*fo]);
02847 }
02848
02849 for(FieldOrder::iterator f2=fo2.begin(); f2!=fo2.end(); f2++) {
02850 make_compatible(*f2,s,t2->ecr(),true);
02851 if(! m2[*f2]) continue;
02852 declNode *one_field = * f2->begin();
02853 FieldOrder::iterator fo=s->fo.begin();
02854 while(fo!=s->fo.end() && fo->find(one_field)==fo->end())
02855 fo++;
02856 assert(fo!=s->fo.end());
02857 join(m2[*f2], s->m[*fo]);
02858 }
02859 }
02860
02861
02862 bool UnificationBasedPtr::make_compatible(declSet n, Unify_Structure *s,
02863 Unify_ECR *container, bool force) {
02864 {
02865 declSet n1 = n;
02866 for(declSet::iterator d=n1.begin(); d!=n1.end(); d++)
02867 if(_unique_field_defn[*d] != *d) {
02868 n.erase(*d);
02869 n.insert(_unique_field_defn[*d]);
02870 }
02871 }
02872
02873 if(find(s->fo.begin(), s->fo.end(), n) != s->fo.end()) return true;
02874 container = container->root();
02875
02876
02877
02878
02879
02880
02881 assert(! n.empty());
02882
02883 if(s->fo.empty()) {
02884 suespecNode *sue = _field2sue[* n.begin()];
02885 decl_list fields = sue->fields();
02886 assert(! fields.empty());
02887 if(sue->owner() == Struct) {
02888 for(decl_list_p d=fields.begin(); d!=fields.end(); d++) {
02889 declSet ds; ds.insert(*d);
02890 s->fo.push_back(ds);
02891 s->fto.push_back((*d)->type());
02892 assert(! s->m[ds]);
02893 new_field_ECR(s->m[ds], (*d)->type(), container)
02894 }
02895 } else {
02896 declSet ds;
02897 typeNode *type = NULL;
02898 for(decl_list_p d=fields.begin(); d!=fields.end(); d++) {
02899 ds.insert(*d);
02900 if(d==fields.begin()) type = (*d)->type();
02901 else if(! compatible_type((*d)->type(), type)) type = NULL;
02902 }
02903 s->fo.push_back(ds);
02904 s->fto.push_back(type);
02905 assert(s->m.empty());
02906 new_field_ECR(s->m[ds], type, container);
02907 }
02908 return true;
02909 }
02910
02911 decl_list n_pos;
02912 for(declSet::iterator d=n.begin(); d!=n.end(); d++) {
02913
02914 if(d==n.begin()) n_pos = _fieldpos[*d];
02915
02916
02917
02918
02919
02920
02921
02922
02923
02924
02925
02926
02927
02928
02929
02930
02931
02932
02933
02934
02935
02936
02937
02938
02939 else if(_fieldpos[*d].size() < n_pos.size())
02940 n_pos = _fieldpos[*d];
02941 }
02942
02943
02944
02945
02946
02947
02948
02949
02950
02951
02952
02953
02954
02955
02956 assert(s->fo.size() == s->fto.size());
02957 FieldOrder::iterator fo=s->fo.begin();
02958 FieldTypeOrder::iterator to=s->fto.begin();
02959 Unify_ECR *previously_merged = NULL;
02960
02961
02962 for(decl_list_p n1=n_pos.begin(); n1!=n_pos.end(); n1++) {
02963
02964
02965
02966
02967
02968 #define insert_into_set(set, Dp) { \
02969 if(Dp == n_pos.back()) set->insert(n.begin(), n.end()); \
02970 else set->insert(Dp); \
02971 if(Dp != n_pos.front()) { \
02972 \
02973 for(declSet::iterator N=n.begin(); N!=n.end(); N++) { \
02974 decl_list all_fields = _field2sue[*N]->fields(); \
02975 FieldOrder::iterator fo1 = s->fo.begin(); \
02976 for(decl_list_p f=all_fields.begin(); f!=all_fields.end(); f++) { \
02977 if(_fieldpos[*f].size() >= _fieldpos[Dp].size()) break; \
02978 else { \
02979 Unify_ECR *E = s->m[*fo1]; \
02980 s->m.erase(*fo1); \
02981 fo1->insert(*f); \
02982 s->m[*fo1] = E; \
02983 break; \
02984 } \
02985 if(++fo1==s->fo.end()) break; \
02986 } \
02987 } \
02988 } \
02989 }
02990
02991 bool merge = false;
02992 typeNode *field_type = (to==s->fto.end()) ? NULL : *to;
02993
02994 if(field_type == NULL || !compatible_type((*n1)->type(), field_type)) {
02995
02996 if(!force) return false;
02997
02998 declSet * ds;
02999 if(to!=s->fto.end()) {
03000 *to = NULL;
03001 ds = &(*fo);
03002 } else {
03003 s->fto.back() = NULL;
03004 ds = & s->fo.back();
03005 }
03006 if(s->m.find(*ds) != s->m.end()) {
03007 Unify_ECR *E = s->m[*ds];
03008 s->m.erase(*ds);
03009 insert_into_set(ds,*n1)
03010 s->m[*ds] = E;
03011 } else
03012 insert_into_set(ds,*n1)
03013 if(previously_merged) {
03014 if(s->m[*ds])
03015 join(s->m[*ds], previously_merged);
03016 else
03017 s->m[*ds] = previously_merged;
03018 } else if(! s->m[*ds])
03019 new_field_ECR(s->m[*ds], field_type, container)
03020 previously_merged = s->m[*ds];
03021 } else {
03022 if(s->m.find(*fo) == s->m.end()) {
03023 insert_into_set(fo,*n1)
03024 new_field_ECR(s->m[*fo], field_type, container)
03025 } else {
03026 Unify_ECR *E = s->m[*fo];
03027 s->m.erase(*fo);
03028 insert_into_set(fo,*n1)
03029 s->m[*fo] = E;
03030 }
03031 }
03032
03033 if(*n1 == n_pos.back() && ! previously_merged && fo!=s->fo.end()) {
03034
03035
03036
03037 bool n_in_later_fo = false;
03038 FieldOrder::iterator fo1 = fo; fo1++;
03039 while(!n_in_later_fo && fo1!=s->fo.end()) {
03040 for(declSet::iterator d=n.begin(); d!=n.end(); d++)
03041 if(fo1->find(*d) != fo1->end()) { n_in_later_fo=true; break; }
03042 fo1++;
03043 }
03044 if(n_in_later_fo)
03045 previously_merged = s->m[*fo];
03046 }
03047
03048 if(!previously_merged && fo != s->fo.end()) { fo++; to++; }
03049
03050
03051
03052
03053
03054
03055
03056
03057
03058
03059
03060
03061 }
03062
03063
03064 if(previously_merged) {
03065 if(fo != s->fo.end()) {
03066
03067 while(s->fo.back() != *fo) {
03068 declSet back = s->fo.back();
03069 s->m.erase(*fo);
03070 if(s->m.find(back) != s->m.end()) {
03071 Unify_ECR *E2 = s->m[back];
03072 s->m.erase(back);
03073 join(previously_merged, E2);
03074 previously_merged = previously_merged->root();
03075 }
03076 (*fo).insert(back.begin(), back.end());
03077 s->m[*fo] = previously_merged;
03078 s->fo.pop_back();
03079 s->fto.pop_back();
03080 }
03081 }
03082
03083
03084 for(declSet::iterator N=n.begin(); N!=n.end(); N++) {
03085 if(_field2sue[*N]->fields().back() != *N) {
03086
03087 declSet & back = s->fo.back();
03088 assert(back.find(*N) != back.end());
03089 assert(previously_merged == s->m[back]);
03090 s->m.erase(back);
03091 decl_list fields = _field2sue[*N]->fields();
03092 for(decl_list::reverse_iterator f=fields.rbegin();
03093 f!=fields.rend() && *f!=*N; f++)
03094 back.insert(*f);
03095 s->m[back] = previously_merged;
03096 }
03097 }
03098 }
03099
03100 #define CX_INVARIANT
03101 #ifdef CX_INVARIANT
03102 { int error = 0;
03103 if(s->fo.size() != s->fto.size()) error = 1;
03104 int pos = 1;
03105 for(fo=s->fo.begin(); !error && fo!=s->fo.end(); fo++, pos++) {
03106 if(s->m.find(*fo) != s->m.end() && !s->m[*fo]) error=2;
03107 for(declSet::iterator d=fo->begin(); !error && d!=fo->end(); d++) {
03108 if(_fieldpos[*d].size() < pos) error=3;
03109 decl_list all_fields = _field2sue[*d]->fields();
03110 if(_fieldpos[*d].size() > pos) {
03111 for(decl_list_p f=all_fields.begin(); !error && f!=all_fields.end();f++)
03112 if(_fieldpos[*f].size() >= pos &&
03113 fo->find(*f) == fo->end()) {
03114 error=4;
03115 cout << "d " << (*d)->name() << " @" << (*d)->coord() << endl;
03116 cout << "f " << (*f)->name() << " @" << (*f)->coord() << endl;
03117 }
03118 }
03119 for(decl_list_p f=all_fields.begin(); !error && f!=all_fields.end();f++)
03120 if(_fieldpos[*f].size() < pos) {
03121 int pos1 = 1;
03122 FieldOrder::iterator fo1 = s->fo.begin();
03123 while(pos1 < _fieldpos[*f].size()) { fo1++; pos1++; }
03124 if(fo1->find(*f) == fo1->end()) {
03125 error=5;
03126 cout << "f " << (*f)->name() << " @" << (*f)->coord() << endl;
03127 }
03128 }
03129 }
03130 }
03131 for(map<declSet,Unify_ECR*>::iterator m=s->m.begin(); !error && m!=s->m.end();
03132 m++) {
03133 if(! m->second) error=6;
03134 else if(find(s->fo.begin(), s->fo.end(), m->first) == s->fo.end())
03135 error=7;
03136 }
03137 if(error) {
03138 cout << s->all_str();
03139 cout << "error=" << error << endl;
03140 if(cur_proc) cout << "cur_proc @" << cur_proc->coord() << endl;
03141 assert(false);
03142 }
03143 }
03144 #endif
03145
03146 return true;
03147 }
03148
03149
03150 bool UnificationBasedPtr::compatible_type(typeNode *t1, typeNode *t2) {
03151
03152 if(!t1 || !t2) return false;
03153 if(t1 == t2) return true;
03154 if(t1->typ() != t2->typ()) return false;
03155 switch(t1->typ()) {
03156 case Prim: return ((primNode*)t1)->basic() == ((primNode*)t1)->basic();
03157 case Struct:
03158 case Union: return ((sueNode*)t1)->spec() == ((sueNode*)t2)->spec();
03159 case Ptr: return compatible_type(t1->type(), t2->type());
03160 case Func: return true;
03161 case Array: {
03162 arrayNode *a1 = (arrayNode*) t1,
03163 *a2 = (arrayNode*) t2;
03164 if(!compatible_type(a1->type(), a2->type())) return false;
03165 return (a1->dim() && a1->dim()->typ()==Const &&
03166 a2->dim() && a2->dim()->typ()==Const &&
03167 ((constNode*)a1->dim())->value().Integer() ==
03168 ((constNode*)a2->dim())->value().Integer());
03169 }
03170 case Tdef:
03171 return compatible_type(((tdefNode*)t1)->def(), ((tdefNode*)t2)->def());
03172 default: cout << t1->typ() << "@" << t1->coord() << " & "
03173 << t2->typ() << "@" << t2->coord() << endl;
03174 assert(false);
03175 }
03176 }
03177
03178
03179
03180 void UnificationBasedPtr::finalize() {
03181
03182
03183 bool completed_once = false;
03184 serve_again = true;
03185 do {
03186
03187 finalizing = false;
03188 new_pending = true;
03189
03190
03191
03192 map<threeAddrNode*,UnifyType*> ptr_call_set = _ptr_call;
03193 bool change = false;
03194 for(map<threeAddrNode*,UnifyType*>::iterator pc = ptr_call_set.begin();
03195 pc != ptr_call_set.end(); pc++) {
03196 threeAddrNode *the_call = pc->first;
03197 UnifyType *type = pc->second;
03198 assert(type);
03199 is_Sim_Obj(type);
03200
03201
03202
03203 if(type->ecr()->type() != type ||
03204 ! Sim_Obj_Lambda(type)->is_bottom()) {
03205 Unify_Size s = Unify_Size(Unify_Size::sizeOfAssign(the_call, linker,
03206 this));
03207
03208
03209
03210
03211 at_call(the_call, s);
03212 if(_ptr_call.find(the_call) == _ptr_call.end() ||
03213 _ptr_call[the_call] != type)
03214 change = true;
03215 }
03216 }
03217 if(completed_once && !change) break;
03218
03219
03220
03221 finalizing = true;
03222 new_pending = false;
03223 set<Unify_ECR*> all_ecr = Unify_ECR::allECR();
03224 for(set<Unify_ECR*>::iterator e=all_ecr.begin(); e!=all_ecr.end(); e++) {
03225 set<Unify_Pending*> pending = (*e)->pending().set();
03226
03227 if((*e)->type()->objTyp()==SIMPLE || (*e)->type()->objTyp()==OBJECT) {
03228 set<Unify_Pending*> more= Sim_Obj_Lambda((*e)->type())->pending().set();
03229 pending.insert(more.begin(), more.end());
03230 }
03231 repeat:
03232 for(Pendings_p p=pending.begin(); p!=pending.end(); p++) {
03233 if((*p)->is_served()) continue;
03234 (*p)->served();
03235 switch((*p)->typ()) {
03236 case Unify_Pending::collapse:
03237 collapse((Unify_ECR*) (*p)->arg1());
03238 break;
03239 case Unify_Pending::makeunknown:
03240 make_unknown((Unify_Offset*) (*p)->arg1());
03241 break;
03242 case Unify_Pending::join_ECR:
03243 join((Unify_ECR*) (*p)->arg1(), (Unify_ECR*) (*p)->arg2());
03244 break;
03245 case Unify_Pending::join_Lambda:
03246 join((Lambda*) (*p)->arg1(), (Lambda*) (*p)->arg2());
03247 break;
03248 case Unify_Pending::cjoin:
03249 cjoin(*(Unify_Size*) (*p)->arg1(), (Unify_ECR*)(*p)->arg2(),
03250 (Unify_ECR*)(*p)->arg3());
03251
03252 break;
03253 default: assert(false);
03254 }
03255 }
03256 if(! more_pending.empty()) {
03257
03258 pending = more_pending;
03259 more_pending.clear();
03260 goto repeat;
03261 }
03262
03263 }
03264
03265 completed_once = true;
03266 } while(true);
03267
03268 new_pending = true;
03269 }
03270
03271
03272
03273 Unify_ECR *UnificationBasedPtr::ecrField(UnifyType *container, declNode *field,
03274 bool field_from_annotation) {
03275 if(!container) return NULL;
03276
03277 if(field_from_annotation && ! _unique_field_defn[field]) {
03278 if(container->objTyp() == OBJECT)
03279 return container->object()->alpha->tao();
03280 if(container->objTyp() != STRUCTURE) return NULL;
03281 Unify_Structure *st = container->structure();
03282 string field_name = field->name();
03283 int pos = field_name.rfind(".");
03284 if(pos > 0) field_name = field_name.substr(pos+1, string::npos);
03285
03286 declNode *unique_field = NULL;
03287 for(FieldOrder::iterator f=st->fo.begin(); f!=st->fo.end(); f++)
03288 for(declSet::iterator d=f->begin(); d!=f->end(); d++)
03289 if((*d)->name() == field_name) {
03290 if(! unique_field) unique_field = *d;
03291 else return NULL;
03292 }
03293 if(unique_field) _unique_field_defn[field] = unique_field;
03294 }
03295
03296 field = _unique_field_defn[field];
03297
03298 if(container->is_bottom() || container->objTyp() == BLANK) {
03299 suespecNode *sue = field2sue(field);
03300 assert(sue);
03301 Unify_Structure *st = ensure_struct_obj(container->ecr(), sue, true);
03302
03303 if(container->ecr()->type() != container) {
03304
03305
03306 container = container->ecr()->type();
03307
03308
03309
03310
03311
03312 }
03313 declSet F; F.insert(field);
03314 if(st && container->objTyp()==STRUCTURE)
03315
03316
03317 make_compatible(F, st, container->ecr(), true);
03318
03319 }
03320
03321 if(container->objTyp() == SIMPLE) {
03322 promote(container->ecr(), container->simple()->s);
03323 if(container->ecr()->type() != container) {
03324
03325 container = container->ecr()->type();
03326
03327
03328
03329
03330
03331 }
03332 }
03333
03334 if(container->objTyp() == OBJECT)
03335 return container->object()->alpha->tao();
03336
03337 assert(container->objTyp() == STRUCTURE);
03338 return container->structure()->get(field, container->ecr());
03339 }
03340
03341
03342 Unify_ECR *UnificationBasedPtr::ecrDeref(UnifyType *container) {
03343 if(!container) return NULL;
03344 if(container->is_bottom() || container->objTyp() == BLANK) {
03345
03346
03347 typeNode *c_type = NULL;
03348 memoryBlock *m = container->block();
03349 if(m && m->decl())
03350 c_type = m->decl()->type();
03351 Unify_Size size;
03352 if(c_type) size = Unify_Size(Unify_Size::sizeOf(c_type));
03353
03354
03355 set<Unify_Pending*> pending = container->ecr()->pending().set();
03356 for(Pendings_p a=pending.begin(); a!=pending.end(); a++) {
03357 (*a)->un_served();
03358 if((*a)->typ() == Unify_Pending::cjoin &&
03359 ! ((Unify_Size*) (*a)->arg1())->leq(size)) {
03360
03361
03362 size = Unify_Size();
03363 if(container->objTyp() == BLANK)
03364 container->blank()->s = size;
03365 }
03366 }
03367
03368 ensure_sim_obj(container->ecr(), size);
03369 if(container->ecr()->type() != container) {
03370
03371 container = container->ecr()->type();
03372
03373
03374
03375 }
03376 }
03377 assert(container->objTyp() == SIMPLE || container->objTyp() == OBJECT);
03378 if(container->objTyp() == SIMPLE)
03379 return container->simple()->alpha->tao();
03380 else
03381 return container->object()->alpha->tao();
03382 }
03383
03384
03385 void UnificationBasedPtr::createProcBlock(procNode *proc, memoryModel &Memory,
03386 procLocation *cur_loc) {
03387 declNode *p_decl = proc->decl();
03388 UnifyType *p_type = proctype(proc);
03389 Unify_ECR *proc_ecr = p_type->ecr_no_root(),
03390 *parent = proc_ecr->parent();
03391 UnifyType *org_type = proc_ecr->type();
03392 proc_ecr->parent(NULL);
03393 proc_ecr->type(p_type);
03394 memoryBlock *b = Memory.lookup_variable(cur_loc, p_decl, cur_loc->proc());
03395 proc_ecr->parent(parent);
03396 if(! parent) proc_ecr->type(org_type);
03397 assert(proc_ecr->type() == org_type);
03398
03399 if(p_type->block()) assert(p_type->block() == b);
03400 else p_type->block(b);
03401 }
03402
03403
03404 bool UnificationBasedPtr::reachable(UnifyType *src, UnifyTypes & targets,
03405 UnifyTypes & visited) {
03406 assert(src);
03407 if(visited.find(src) != visited.end()) return false;
03408 visited.insert(src);
03409 if(targets.find(src) != targets.end()) return true;
03410 if(src->is_bottom()) return false;
03411 switch(src->objTyp()) {
03412 case BLANK: return false;
03413 case SIMPLE:
03414 case OBJECT: {
03415 bool r = reachable(Sim_Obj_Alpha(src)->tao()->type(), targets, visited);
03416 if(r) targets.insert(src);
03417 return r;
03418 }
03419 case STRUCTURE: {
03420 EltMap map = src->structure()->m;
03421 for(EltMap::iterator m=map.begin(); m!=map.end(); m++)
03422 if(m->second && reachable(m->second->type(), targets, visited)) {
03423 targets.insert(src);
03424 return true;
03425 }
03426 return false;
03427 }
03428 }
03429 }
03430
03431
03432
03433
03434 set<Unify_ECR*> UnificationBasedPtr::unique_ecr() const {
03435 set<Unify_ECR*> r;
03436 for(map<declNode*,Unify_ECR*>::const_iterator m=_ecr.begin(); m!=_ecr.end();
03437 m++)
03438 if(m->second) r.insert(m->second->root());
03439 return r;
03440 }
03441
03442
03443 void UnificationBasedPtr::print_ecr() {
03444 cout << "all Unify_ECR:\n";
03445 set<Unify_ECR*> all_ecrs=Unify_ECR::allECR(), vars;
03446 set<UnifyType*> type_printed;
03447 map<UnifyType*,decl_list> points_to;
03448
03449 for(map<declNode*, Unify_ECR*>::iterator m=_ecr.begin(); m!=_ecr.end(); m++) {
03450 #define print_one_ecr(E) \
03451 (E)->print(); \
03452 cout << endl;
03453
03454 Unify_ECR *E = m->second;
03455 assert(E && m->first);
03456 if(m->first->decl_location() == declNode::TOP && E->var() != m->first) {
03457 assert(_ecr.find(E->var()) != _ecr.end());
03458 continue;
03459 }
03460
03461 cout << " ";
03462 if(m->first->decl_location() == declNode::TOP) cout << "(global)::";
03463 cout << m->first->name() << "(";
03464 if(E->proc() && E->proc()->decl()!=E->var())
03465 cout << E->proc()->decl()->name() << ".";
03466 if(E->var()->type() && E->var()->type()->is_ellipsis() ||
03467 is_va_list(E->var()))
03468 cout << "<...>: ";
03469 else
03470 cout << E->var()->name() <<"): ";
03471 print_one_ecr(E)
03472 type_printed.insert(E->type());
03473
03474 vars.insert(E);
03475
03476
03477 UnifyType *ty = E->type();
03478 if(ty->objTyp()==OBJECT || ty->objTyp()==SIMPLE) {
03479 if(ty->objTyp()==OBJECT)
03480 ty = ty->object()->alpha->tao()->type();
03481 else
03482 ty = ty->simple()->alpha->tao()->type();
03483 points_to[ty].push_back(m->first);
03484 }
03485 }
03486
03487 #ifdef cx_vt
03488 for(set<Unify_ECR*>::iterator e=all_ecrs.begin(); e!=all_ecrs.end(); e++)
03489 if((*e)->type()->id() == vt_e) {
03490 check_28920 = true;
03491 (*e)->print();
03492 check_28920 = false;
03493 }
03494 for(map<declNode*, Unify_ECR*>::iterator m=_ecr.begin(); m!=_ecr.end(); m++) {
03495 if(m->first->type() && m->first->type()->typ() == Array &&
03496 m->first->decl_location() != declNode::FORMAL) {
03497 Unify_ECR *parent = m->second;
03498 if(parent->type()->objTyp() != SIMPLE && parent->type()->objTyp() !=OBJECT)
03499 cout << m->first->name() << "@" << m->first->coord() << " " << *parent
03500 << endl;
03501 is_Sim_Obj(parent->type());
03502 Unify_ECR *child = Sim_Obj_Alpha(parent->type())->tao();
03503 set<Unify_ECR*> parents = parentsOf(child->type());
03504 bool contain_parent = false;
03505 for(set<Unify_ECR*>::iterator p=parents.begin(); p!=parents.end(); p++)
03506 if((*p)->type() == parent->type()) { contain_parent=true; break; }
03507 if(m->first->name() == "switches")
03508 cout << "switches " << *parent << " child " << *child << " contain "
03509 << contain_parent << endl;
03510 if(!contain_parent) {
03511 vt_e = child->type()->id();
03512 vt = parent->type()->id();
03513 cout << *child << " does not contain parent " << *parent << endl;
03514 check_28920 = true;
03515 child->print();
03516 check_28920 = false;
03517 }
03518 }
03519 }
03520 #endif
03521
03522
03523 map<int,int> n_src;
03524
03525 for(map<UnifyType*,decl_list>::iterator p=points_to.begin();
03526 p!=points_to.end(); p++)
03527 if(p->second.size() > 1) {
03528 for(decl_list_p d=p->second.begin(); d!=p->second.end(); d++)
03529 cout << (*d)->name() << ",";
03530 cout << " point-to " << * p->first << endl;
03531 n_src[p->second.size()] ++;
03532 } else n_src[1]++;
03533
03534
03535 for(set<Unify_ECR*>::iterator e=all_ecrs.begin(); e!=all_ecrs.end(); e++) {
03536 if(type_printed.find((*e)->type()) != type_printed.end()) continue;
03537 type_printed.insert((*e)->type());
03538 cout << " ";
03539 print_one_ecr(*e)
03540 }
03541
03542
03543
03544
03545
03546
03547
03548
03549
03550
03551
03552
03553
03554
03555
03556
03557 cout << "#ptrs to one obj #such objs\n"
03558 << "---------------- ----------\n";
03559 for(map<int,int>::iterator m=n_src.begin(); m!=n_src.end(); m++)
03560 cout << m->first << "\t\t\t" << m->second << endl;
03561
03562 cout << "number of tmp vars created by dismantler = " << _dismantler_tmp
03563 << endl;
03564
03565 }
03566
03567
03568 bool UnificationBasedPtr::is_va_list(declNode * decl) {
03569
03570
03571 if (decl->type() && (decl->type()->typ() == Tdef)) {
03572 string name = ((tdefNode *) decl->type())->name();
03573 if (name == "va_list")
03574 return true;
03575 if (name == "__builtin_va_alist_t")
03576 return true;
03577 if (name == "__gnuc_va_list")
03578 return true;
03579 }
03580
03581 return false;
03582 }
03583
03584
03585 procNode *UnificationBasedPtr::create_synthetic_proc(declNode * decl) {
03586
03587 if(_synthetic_proc[decl]) return _synthetic_proc[decl];
03588 assert(decl->type() && decl->type()->typ()==Func);
03589 procNode *new_proc = _synthetic_proc[decl] = new procNode(decl, NULL);
03590 if(! ((funcNode*)decl->type())->returns()->is_void()) {
03591 declNode *ret = new declNode("__ret", declNode::NONE,
03592 ((funcNode*)decl->type())->returns(),
03593 NULL, NULL);
03594 new_proc->return_decl( ret );
03595 }
03596 return new_proc;
03597 }
03598
03599 UnificationBasedPtr *UnificationBasedPtr::analyze_all(Linker &linker) {
03600 cbzTimer unify_timer;
03601 unify_timer.start();
03602 UnificationBasedPtr *U = new UnificationBasedPtr(linker);
03603 for(unit_list_p u=CBZ::Program.begin(); u!=CBZ::Program.end(); u++)
03604 (*u)->walk(*U);
03605 U->finalize();
03606 unify_timer.stop();
03607 double t(unify_timer);
03608 cout << "STAT-unification-time " << t << endl;
03609 return U;
03610 }
03611
03612
03613
03614 class testUnify : public Phase {
03615 void run() {
03616 CBZ::PrintLineOffset = true;
03617 Linker linker;
03618 linker.link();
03619 UnificationBasedPtr *U = UnificationBasedPtr::analyze_all(linker);
03620 cout << "UnificationBasedPtr done\n";
03621 U->print_ecr();
03622
03623
03624
03625
03626
03627
03628
03629
03630
03631
03632
03633
03634
03635 cout << "unify done\n";
03636 }
03637 };
03638
03639 Phases unify_phase("unify", new testUnify());
03640
03641
03642
03643