static void SetStride(ALIASADDRESS *addr, int stride) { int i; for (i=0; i < DAGSIZE; i++) { ALIASADDRESS *scan = addresses[i]; while (scan) { if (addr != scan && addr->name == scan->name) { if (addr->offset < scan->offset) { int o2 = addr->offset + (scan->offset - addr->offset) % stride; if (addr->offset == o2) { AliasUnion(&addr->pointsto, scan->pointsto); scan->merge = addr; } else { ALIASADDRESS *sc2 = LookupAddress(addr->name, o2); if (sc2 && sc2 != scan) { AliasUnion(&sc2->pointsto, scan->pointsto); scan->merge = sc2; } } } } scan = scan->next; } } }
static void HandleAssnBlock(QUAD *head) { ALIASNAME *dest = NULL; if ((head->temps & TEMP_LEFT) && head->dc.left->mode == i_direct) { // we don't support writing to arbitrary memory, e.g. a pointer returned from a function call return; } else if (head->dc.left->mode == i_immed) { dest = LookupMem(head->dc.left); dest = LookupAliasName(dest, 0); } else { diag("HandleAssnBlock: invalid dest type"); } if (head->dc.right->mode == i_direct && ((head->temps & TEMP_RIGHT) || head->dc.right->retval)) { ALIASLIST *src = tempInfo[head->dc.right->offset->v.sp->value.i]->pointsto; while (src) { ALIASNAME *srcn = src->address->name; LIST *addr = srcn->addresses; while (addr) { ALIASADDRESS *aa= (ALIASADDRESS *)addr ->data; ALIASADDRESS *aadest = LookupAddress(dest, aa->offset); AliasUnion(&aadest->pointsto, aa->pointsto); addr = addr->next; } src = src->next; } } else if (head->dc.right->mode == i_immed) { ALIASNAME *src = LookupMem(head->dc.right); LIST *addr; addr = src->addresses; while (addr) { ALIASADDRESS *aa= (ALIASADDRESS *)addr->data; ALIASADDRESS *aadest = LookupAddress(dest, aa->offset); AliasUnion(&aadest->pointsto, aa->pointsto); addr = addr->next; } } else { diag("HandleAssnBlock: invalid src type"); } }
static void HandleAssnBlock(QUAD *head) { ALIASLIST *src=NULL, *dest=NULL; int i, n = head->ans->offset->v.i; if ((head->temps & TEMP_LEFT) && head->dc.left->mode == i_direct) { dest = tempInfo[head->dc.left->offset->v.sp->value.i]->pointsto; } else if (head->dc.left->mode == i_immed) { ALIASNAME *an = LookupMem(head->dc.left); ALIASADDRESS *aa; an = LookupAliasName(an, 0); aa = LookupAddress(an, 0); dest = aa->pointsto; } else { diag("HandleAssnBlock: invalid dest type"); } if (head->dc.right->mode == i_direct && ((head->temps & TEMP_RIGHT) || head->dc.right->retval)) { src = tempInfo[head->dc.right->offset->v.sp->value.i]->pointsto; } else if (head->dc.right->mode == i_immed) { ALIASNAME *an = LookupMem(head->dc.right); ALIASADDRESS *aa; an = LookupAliasName(an, 0); aa = LookupAddress(an, 0); src = aa->pointsto; } else { diag("HandleAssnBlock: invalid src type"); } for (i=0; i < n; i++) { ALIASLIST *lsrc = src; while (lsrc) { ALIASADDRESS *aasrc = GetAddress(lsrc->address->name, i); if (aasrc) { ALIASLIST *ldest = dest; while (ldest) { ALIASADDRESS *aadest = LookupAddress(ldest->address->name, i); AliasUnion(&aadest->pointsto, aasrc->pointsto); ldest = ldest->next; } } lsrc = lsrc->next; } } }
static void HandleParm(QUAD *head) { if (head->dc.left->size == ISZ_ADDR) { // temp, mem ALIASLIST *result = NULL, **base = NULL, *addr; if (head->temps & TEMP_LEFT) { base = &tempInfo[head->dc.left->offset->v.sp->value.i]->pointsto; } else if (!isintconst(head->dc.left->offset)) { ALIASNAME *an; ALIASADDRESS *aa; switch (head->dc.left->offset->type) { case en_labcon: case en_global: case en_label: case en_pc: case en_threadlocal: return; default: break; } an = LookupMem(head->dc.left->offset->v.sp->imvalue); if (head->dc.left->mode == i_direct) an = LookupAliasName(an, 0); aa = LookupAddress(an, 0); base = &aa->pointsto; } if (base) { addr = *base; AliasUnionParm(&parmList, (*base)); while (addr) { if (addr->address->name->byUIV) { if (!IntersectsUIV(addr->address->pointsto)) { ALIASNAME *an = LookupAliasName(addr->address->name, 0); ALIASADDRESS *aa = LookupAddress(an, 0); ALIASLIST *al = aAlloc(sizeof(ALIASLIST)); al->address = aa; AliasUnion(&addr->address->pointsto, al); } } addr = addr->next; } } } }
static void Infer(IMODE *ans, IMODE *reg, ALIASLIST *pointsto) { if (pointsto) { ALIASLIST *result = NULL; int c = InferOffset(reg); int l = InferStride(reg); BOOL xchanged = changed; while (pointsto) { ALIASADDRESS *addr = LookupAddress(pointsto->address->name, pointsto->address->offset + c); ALIASLIST *al = aAlloc(sizeof(ALIASLIST)); al->address = addr; AliasUnion(&result, al); SetStride(pointsto->address, l); pointsto = pointsto->next; } changed = xchanged; AliasUnion(&tempInfo[ans->offset->v.sp->value.i]->pointsto, result); } }
static ALIASADDRESS *LookupAddress(ALIASNAME *name, int offset) { int str[(sizeof(ALIASNAME *) + sizeof(int))/sizeof(int)]; int hash; ALIASADDRESS *addr, **search; IMODE *im; LIST *li; str[0] = offset; *((ALIASNAME **)(str + 1)) = name; hash = dhash((UBYTE *)str, sizeof(str)); search = &addresses[hash]; while (*search) { if ((*search)->name == name && (*search)->offset == offset) return (*search); search = &(*search)->next; } addr = (*search) = aAlloc(sizeof(ALIASADDRESS)); addr->name = name; addr->offset = offset; if (addr->name->byUIV) { im = addr->name->v.uiv->im; } else { im = addr->name->v.name; } switch (im->offset->type) { case en_auto: // if (im->offset->v.sp->storage_class != sc_parameter) break; case en_global: { ALIASLIST *l = aAlloc(sizeof(ALIASLIST)); l->address = addr; AliasUnion(&parmList, l); } break; default: break; } li = aAlloc(sizeof(LIST)); li->data = addr; li->next = name->addresses; name->addresses = li; return addr; }
static void HandlePhi(QUAD *head) { if (tempInfo[head->dc.v.phi->T0]->enode->v.sp->imvalue->size == ISZ_ADDR) { struct _phiblock *pb = head->dc.v.phi->temps; ALIASLIST *l = NULL; BOOLEAN xchanged = changed; while (pb) { AliasUnion(&l, tempInfo[pb->Tn]->pointsto); pb = pb->next; } changed = xchanged; tempInfo[head->dc.v.phi->T0]->pointsto = l; } }
static void HandleAdd(QUAD *head) { if ((head->ans->size == ISZ_ADDR) && (head->temps & TEMP_ANS)) { if (head->dc.opcode == i_add && head->dc.left->mode == i_immed) { if (head->temps & TEMP_RIGHT) { if (isintconst(head->dc.left->offset)) { // C + R ALIASLIST *scan = tempInfo[head->dc.right->offset->v.sp->value.i]->pointsto; ALIASLIST *result = NULL; BOOLEAN xchanged = changed; while (scan) { ALIASADDRESS *addr = LookupAddress(scan->address->name, scan->address->offset + head->dc.left->offset->v.i); ALIASLIST *al = aAlloc(sizeof(ALIASLIST)); al->address = addr; AliasUnion(&result, al); scan = scan->next; } changed = xchanged; AliasUnion(&tempInfo[head->ans->offset->v.sp->value.i]->pointsto, result); } else { // p + R if (head->dc.left->offset->type != en_labcon) // needed for exports { ALIASNAME *nm = LookupMem(head->dc.left->offset->v.sp->imvalue); ALIASADDRESS *aa = LookupAddress(nm, 0); ALIASLIST *al = aAlloc(sizeof(ALIASLIST)); al->address = aa; Infer(head->ans, head->dc.right, al); } } } else if (head->dc.right->mode == i_immed) { if (!isintconst(head->dc.left->offset) && head->dc.left->offset->type != en_labcon) { // p + C ALIASNAME *nm = LookupMem(head->dc.left->offset->v.sp->imvalue); ALIASADDRESS *aa = LookupAddress(nm, head->dc.right->offset->v.i); ALIASLIST *al = aAlloc(sizeof(ALIASLIST)); al->address = aa; AliasUnion(&tempInfo[head->ans->offset->v.sp->value.i]->pointsto,al); } else if (!isintconst(head->dc.right->offset) && head->dc.right->offset->type != en_labcon) { // C + p ALIASNAME *nm = LookupMem(head->dc.right->offset->v.sp->imvalue); ALIASADDRESS *aa = LookupAddress(nm, head->dc.left->offset->v.i); ALIASLIST *al = aAlloc(sizeof(ALIASLIST)); al->address = aa; AliasUnion(&tempInfo[head->ans->offset->v.sp->value.i]->pointsto, al); } } } else if (head->dc.right->mode == i_immed) { if (head->temps & TEMP_LEFT) { if (isintconst(head->dc.right->offset)) { // R+C int c = head->dc.opcode == i_add ? head->dc.right->offset->v.i : -head->dc.right->offset->v.i; ALIASLIST *scan = tempInfo[head->dc.left->offset->v.sp->value.i]->pointsto; ALIASLIST *result = NULL; BOOLEAN xchanged = changed; while (scan) { ALIASADDRESS *addr = LookupAddress(scan->address->name, scan->address->offset + c); ALIASLIST *al = aAlloc(sizeof(ALIASLIST)); al->address = addr; AliasUnion(&result, al); scan = scan->next; } changed = xchanged; AliasUnion(&tempInfo[head->ans->offset->v.sp->value.i]->pointsto, result); } else { // R + p if (head->dc.right->offset->type != en_labcon) // needed for exports { ALIASNAME *nm = LookupMem(head->dc.right->offset->v.sp->imvalue); ALIASADDRESS *aa = LookupAddress(nm, 0); ALIASLIST *al = aAlloc(sizeof(ALIASLIST)); al->address = aa; Infer(head->ans, head->dc.left, al); } } } } else if ((head ->temps & (TEMP_LEFT | TEMP_RIGHT)) == (TEMP_LEFT | TEMP_RIGHT)) { // R+R ALIASLIST *src; IMODE *one = head->dc.left; IMODE *two = head->dc.right; if (two->size == ISZ_ADDR) { IMODE *three = one; one = two; two = three; } if (one->size == ISZ_ADDR) { // now one has the pointer, two has something else src = tempInfo[one->offset->v.sp->value.i]->pointsto; Infer(head->ans, two, src); } } } }
static void HandleAssn(QUAD *head) { if (head->ans == head->dc.left) return; if (head->ans->mode == i_ind) { if (head->temps & TEMP_LEFT) { // ind, temp ALIASLIST *addr; ALIASLIST *src = tempInfo[head->dc.left->offset->v.sp->value.i]->pointsto; addr = tempInfo[head->ans->offset->v.sp->value.i]->pointsto; while (addr) { AliasUnion(&addr->address->pointsto, src); addr = addr->next; } } else if (head->dc.left->mode == i_immed && head->dc.left->size == ISZ_ADDR && head->dc.left->offset->type != en_labcon ) { // ind, immed ALIASLIST *addr; ALIASNAME *an = LookupMem(head->ans->offset->v.sp->imvalue); ALIASADDRESS *aa; if (head->ans->mode == i_direct) an = LookupAliasName(an, 0); aa = LookupAddress(an, 0); addr = tempInfo[head->ans->offset->v.sp->value.i]->pointsto; while (addr) { AliasUnion(&addr->address->pointsto, aa->pointsto); addr = addr->next; } } } else if (head->dc.left->mode == i_ind && (head->temps & TEMP_ANS)) { // temp, ind ALIASLIST *result = NULL; ALIASLIST *addr = tempInfo[head->dc.left->offset->v.sp->value.i]->pointsto; BOOLEAN xchanged = changed; while (addr) { if (addr->address->name->byUIV) { if (!IntersectsUIV(addr->address->pointsto)) { ALIASNAME *an = LookupAliasName(addr->address->name, addr->address->offset); ALIASADDRESS *aa = LookupAddress(an, 0); ALIASLIST *al = aAlloc(sizeof(ALIASLIST)); al->address = aa; AliasUnion(&addr->address->pointsto, al); } } AliasUnion(&result, addr->address->pointsto); addr = addr->next; } changed = xchanged; tempInfo[head->ans->offset->v.sp->value.i]->pointsto = result; } else if (head->ans->size == ISZ_ADDR) { if (!(head->temps & TEMP_ANS) && !head->ans->retval) { if (head->temps & TEMP_LEFT) { // mem, temp ALIASLIST *al; ALIASNAME *an = LookupMem(head->ans); ALIASADDRESS *aa; an = LookupAliasName(an, 0); aa = LookupAddress(an, 0); AliasUnion(&aa->pointsto, tempInfo[head->dc.left->offset->v.sp->value.i]->pointsto); } else if (head->dc.left->mode == i_immed && head->dc.left->size == ISZ_ADDR && head->dc.left->offset->type != en_labcon ) { // mem, immed ALIASNAME *an2 = LookupMem(head->dc.left); ALIASADDRESS *aa2 = LookupAddress(an2, 0); ALIASNAME *an = LookupMem(head->ans->offset->v.sp->imvalue); ALIASADDRESS *aa; ALIASLIST *al = aAlloc(sizeof(ALIASLIST)); al->address = aa2; if (head->ans->mode == i_direct) an = LookupAliasName(an, 0); aa = LookupAddress(an, 0); AliasUnion(&aa->pointsto, al); } } else if (head->temps & TEMP_ANS) { if (head->dc.left->mode == i_immed && head->dc.left->size == ISZ_ADDR && head->dc.left->offset->type != en_labcon&& !isintconst(head->dc.left->offset) ) { // temp, immed BOOLEAN xchanged = changed; ALIASNAME *an = LookupMem(head->dc.left); ALIASADDRESS *aa = LookupAddress(an, 0); ALIASLIST *al = (ALIASLIST *)aAlloc(sizeof(ALIASLIST)); al->address = aa; tempInfo[head->ans->offset->v.sp->value.i]->pointsto = NULL; AliasUnion(&tempInfo[head->ans->offset->v.sp->value.i]->pointsto, al); changed = xchanged; } else if (head->dc.left->retval) { AliasUnion(&tempInfo[head->ans->offset->v.sp->value.i]->pointsto, parmList); } else if (!(head->temps & TEMP_LEFT) && head->dc.left->mode == i_direct) { // temp, mem ALIASLIST *result = NULL; ALIASNAME *an = LookupMem(head->dc.left); ALIASADDRESS *aa; ALIASLIST *addr; BOOLEAN xchanged = changed; an = LookupAliasName(an, 0); aa = LookupAddress(an, 0); AliasUnion(&tempInfo[head->ans->offset->v.sp->value.i]->pointsto, aa->pointsto); changed = xchanged; } else if (head->temps & TEMP_LEFT) { // temp, temp AliasUnion(&tempInfo[head->ans->offset->v.sp->value.i]->pointsto, tempInfo[head->dc.left->offset->v.sp->value.i]->pointsto); } } } }