/* $VER: vbcc (alias.c) V0.8 *//* Listen benutzter/veraenderter Variablen und Behandlung von Decknamen. */ #include "opt.h" static char FILE_[]=__FILE__; static bvtype **gpt; static unsigned long ptsize; #define is_restrict(i) ((i)<=vcount-rcount&&(vilist[i]->vtyp->flags&RESTRICT)) /* sets points-to-info for var i to undefined */void undef_pt(bvtype **pt,int i){ if(i<0||i>=vcount) ierror(0); if(pt[i]) ptsize-=vsize; free(pt[i]); pt[i]=0; if(i<rcount){ i+=vcount-rcount; if(pt[i]) ptsize-=vsize; free(pt[i]); pt[i]=0; }} /* walks through a clist and sets the corresponding bit in bv for every variable whose address is contained in the clist */void add_clist_refs(bvtype *bv,struct Typ *t,struct const_list *cl){ /*FIXME: bei Aufrufen auch auf locale, nicht USEDASDEST|USEDASADDR */ int i;zmax sz; if(ISARRAY(t->flags)){ for(sz=l2zm(0L);!zmleq(t->size,sz)&&cl;sz=zmadd(sz,l2zm(1L)),cl=cl->next){ if(!cl->other){ierror(0);return;} add_clist_refs(bv,t->next,cl->other); } return; } if(ISUNION(t->flags)){ add_clist_refs(bv,(*t->exact->sl)[0].styp,cl); return; } if(ISSTRUCT(t->flags)){ struct Typ *st; for(i=0;i<t->exact->count&&cl;i++){ if(!cl->other){ierror(0);return;} st=(*t->exact->sl)[i].styp; if(!(*t->exact->sl)[i].identifier) ierror(0); if((*t->exact->sl)[i].identifier[0]){ add_clist_refs(bv,st,cl->other); cl=cl->next; } } return; } if(cl->tree&&(cl->tree->o.flags&VARADR)){ /* careful: variable might not have a valid index if it is not used within the function optimized */ i=cl->tree->o.v->index; if(i>=0&&i<vcount-rcount&&vilist[i]==cl->tree->o.v){ /*printf("add %s\n",vilist[i]->identifier);*/ BSET(bv,i); } }} /* copies points-to-info for one var to another */void copy_pt(bvtype **pt,int to,int from){ if(to<0||to>=vcount) ierror(0); if(from<0||from>=vcount) ierror(0); if(!pt[from]){ if(from>=vcount-rcount&&pt[from-(vcount-rcount)]){ /* if dref check, whether from only points to initialized const */ int i;bvtype *new; for(i=0;i<vcount;i++){ if(BTST(pt[from-(vcount-rcount)],i)){ struct Var *v=vilist[i]; if(!is_const(v->vtyp)||!v->clist) break; } } if(i==vcount){ /* yes, take the points-to-info from clist */ if(!pt[to]||to+vcount-rcount==from){ new=mymalloc(vsize); ptsize+=vsize; }else new=pt[to]; memset(new,0,vsize); for(i=0;i<vcount;i++){ if(BTST(pt[from-(vcount-rcount)],i)) add_clist_refs(new,vilist[i]->vtyp,vilist[i]->clist); } if(to+vcount-rcount==from){ ptsize-=vsize; free(pt[to]); } pt[to]=new; return; } } undef_pt(pt,to); }else{ if(!pt[to]){ pt[to]=mymalloc(vsize); ptsize+=vsize; } memcpy(pt[to],pt[from],vsize); }} /* set var i points only to j in points-to-info */void set_pt(bvtype **pt,int i,int j){ if(i<0||i>=vcount) ierror(0); if(j<0||j>=vcount) ierror(0); if(!pt[i]){ pt[i]=mymalloc(vsize); ptsize+=vsize; } memset(pt[i],0,vsize); BSET(pt[i],j);} void print_single_pt(bvtype *pt){ int j; if(pt){ for(j=0;j<vcount;j++){ if(BTST(pt,j)) printf(" %s<%s>(%p)\n",(j>=vcount-rcount)?"*":"",vilist[j]->identifier,(void*)vilist[j]); } }else{ printf(" (undefined)\n"); }} void print_pt(bvtype **pt){ int i,j; if(!pt) return; printf("points-to:\n"); for(i=0;i<vcount;i++){ printf("%s<%s>(%p):\n",(i>=vcount-rcount)?"*":"",vilist[i]->identifier,(void*)vilist[i]); print_single_pt(pt[i]); }} /* creates new points-to-info; every var set to undefined */bvtype **new_pt(void){ bvtype **pt; int i; pt=mymalloc(vcount*sizeof(*pt)); ptsize+=vcount*sizeof(*pt); for(i=0;i<vcount;i++){ if(i<rcount&&(vilist[i]->vtyp->flags&RESTRICT)){ pt[i]=mymalloc(vsize); ptsize+=vsize; memset(pt[i],0,vsize); BSET(pt[i],i+vcount-rcount); }else pt[i]=0; } return pt;} void free_pt(bvtype **pt){ int i; if(pt){ for(i=0;i<vcount;i++){ if(pt[i]) ptsize-=vsize; free(pt[i]); } ptsize-=vcount*sizeof(*pt); free(pt); }} /* set points-to-info of *v to union of points-to of all vars in the points-to-info of v */void dref_pt(bvtype **pt,int i){ int j,d; if(i<0||i>=rcount) ierror(0); d=i+vcount-rcount; if(!pt[i]){ undef_pt(pt,d); return; } if(!pt[d]){ pt[d]=mymalloc(vsize); ptsize+=vsize; } memset(pt[d],0,vsize); for(j=0;j<vcount;j++){ if(BTST(pt[i],j)){ struct Var *v=vilist[j]; if(v->clist&&is_const(v->vtyp)){ add_clist_refs(pt[d],v->vtyp,v->clist); }else if(!pt[j]){ undef_pt(pt,d); return; }else bvunite(pt[d],pt[j],vsize); } }} void trans_pt(bvtype **pt,struct IC *p){ int i,j,newset=-1,sv,cp; if((p->code==ADDI2P||p->code==SUBIFP)&&!compare_objs(&p->q1,&p->z,ztyp(p))) return; if((p->z.flags&VAR)&&ISSCALAR(p->z.v->vtyp->flags)){ i=p->z.v->index; if(i<0||i>=vcount) ierror(0); if(p->z.flags&DREFOBJ){ if(i>=rcount) ierror(0); i+=vcount-rcount; } if(!is_restrict(i)){ if(p->code==ASSIGN){ newset=i;sv=-1;cp=-1; if(p->q1.flags&VARADR){ sv=p->q1.v->index; set_pt(pt,i,p->q1.v->index); }else if(p->q1.flags&VAR){ j=p->q1.v->index; if(j<0||j>=vcount) ierror(0); if(p->q1.flags&DREFOBJ){ if(j>=rcount) ierror(0); j+=vcount-rcount; } cp=j; copy_pt(pt,i,j); }else{ if(!pt[i]){ pt[i]=mymalloc(vsize); ptsize+=vsize; } memset(pt[i],0,vsize); } } if(p->code==ADDRESS){ newset=i;sv=p->q1.v->index;cp=-1; set_pt(pt,i,p->q1.v->index); } if((p->code==ADDI2P||p->code==SUBIFP)&&(p->q1.flags&VAR)){ newset=i;sv=-1;cp=-1; if(p->q1.flags&VARADR){ sv=p->q1.v->index; set_pt(pt,i,p->q1.v->index); }else{ j=p->q1.v->index; if(j<0||j>=vcount) ierror(0); if(p->q1.flags&DREFOBJ){ if(j>=rcount) ierror(0); j+=vcount-rcount; } cp=j; copy_pt(pt,i,j); } } } } if(newset>=0&&newset<rcount){ if(newset<0) ierror(0); dref_pt(pt,newset); } for(i=0;i<p->change_cnt;i++){ j=p->change_list[i].v->index; if(j<0||j>=vcount) ierror(0); if(p->change_list[i].flags&DREFOBJ){ if(j>=rcount) ierror(0); j+=vcount-rcount; } if(j!=newset&&!is_restrict(j)){ if(newset>=0&&pt[j]){ if(sv>=0){ if(sv>=vcount) ierror(0); BSET(pt[j],sv); } if(cp>=0&&pt[cp]){ if(cp<0||cp>=vcount) ierror(0); bvunite(pt[j],pt[cp],vsize); } }else undef_pt(pt,j); } }} bvtype **clone_pt(bvtype **pt){ int i; bvtype **new; if(!pt) return new_pt(); new=mymalloc(vcount*sizeof(*new)); ptsize+=vcount*sizeof(*new); for(i=0;i<vcount;i++){ if(pt[i]){ new[i]=mymalloc(vsize); ptsize+=vsize; memcpy(new[i],pt[i],vsize); }else new[i]=0; } return new;} /* tests if two points-to-infos are identical */int equal_pt(bvtype **pt1,bvtype **pt2){ int i; if(!pt1&&!pt2) return 1; if(!pt1||!pt2) return 0; for(i=0;i<vcount;i++){ if(!pt1[i]&&!pt2[i]) continue; if(!pt1[i]||!pt2[i]) return 0; if(memcmp(pt1[i],pt2[i],vsize)) return 0; } return 1;}#if 0void calc_pt(struct flowgraph *fg){ struct flowgraph *g; struct flowlist *in; struct IC *p; bvtype **pt,**ppt; int i,all_preds,changed; changed=1; while(changed){ if(DEBUG&1024) printf("calc_pt pass\n"); changed=0; for(g=fg;g;g=g->normalout){ /* do all predecessors already have points-to-info? */ all_preds=1; for(in=g->in;in;in=in->next){ if(!in->graph->pt){ all_preds=0; break; } } if(all_preds&&g->in){ /* calc union of all predecessors */ pt=clone_pt(g->in->graph->pt); for(in=g->in->next;in;in=in->next){ ppt=in->graph->pt; for(i=0;i<vcount;i++){ if(pt[i]){ if(!ppt[i]) undef_pt(pt,i); else bvunite(pt[i],ppt[i],vsize); } } } }else pt=new_pt(); for(p=g->start;p;p=p->next){ trans_pt(pt,p); if(p==g->end) break; } if(pt==g->pt) ierror(0); if(!changed){ if(!equal_pt(pt,g->pt)){ changed=1; free_pt(g->pt); g->pt=pt; }else{ free_pt(pt); } }else{ free_pt(g->pt); g->pt=pt; } } }}#endifint p_typ(struct Var *v)/* Liefert den Typ, auf den Variable zeigen kann. Falls nicht eindeutig *//* wird CHAR zurueckgegeben, da ein char * auf alles zeigen kann. */{ struct Typ *t=v->vtyp;int f; /* Kein Zeiger? Dann moeglicherweise Struktur, die verschiedene Zeiger */ /* enthalten koennte. Koennte man evtl. noch genauer pruefen. */ if(!ISPOINTER(t->flags)||!t->next||(v->flags&DNOTTYPESAFE)) return CHAR; f=t->next->flags&NQ; if(f==VOID) f=CHAR; return f;} /* propagates information if a variable whose address may have been taken is modified */static void propagate_pointers(bvtype *set,struct Var *v,int t,int i){ int j,t2; if(v->nesting==0||v->storage_class==EXTERN||(v->flags&USEDASADR)){ if(noaliasopt){ bvunite(set,av_drefs,vsize); }else{ for(j=0;j<rcount;j++){ t2=p_typ(vilist[j]); if(t==t2||t2==CHAR||!ISSCALAR(t)||!ISSCALAR(t2)){ if(!gpt||!gpt[j]||(i>=0&&BTST(gpt[j],i))) BSET(set,j+vcount-rcount); } } } }}void alias_propagate(bvtype *set,int i,int t,int wr){ int j,t2; struct Var *v; if(i<0||i>=vcount) ierror(0); t&=NQ; BSET(set,i); if(wr&&i<rcount) BSET(set,i+vcount-rcount); if(i>=vcount-rcount){ /* DREFOBJ */ if(noaliasopt||t==CHAR||!ISSCALAR(t)){ bvunite(set,av_drefs,vsize); bvunite(set,av_address,vsize); bvunite(set,av_globals,vsize); }else{ for(j=0;j<vcount-rcount;j++){ v=vilist[j]; if(!gpt||!gpt[i-(vcount-rcount)]||BTST(gpt[i-(vcount-rcount)],j)){ v=vilist[j]; if(!v) ierror(0); if(v->nesting==0||v->storage_class==EXTERN||(v->flags&USEDASADR)){ struct Typ *tp=v->vtyp; if(!v->vtyp) ierror(0); do{ t2=tp->flags&NQ; tp=tp->next; }while(ISARRAY(t2)); if(t==t2||!ISSCALAR(t2)){ BSET(set,j); if(wr&&j<rcount) {BSET(set,j+vcount-rcount);continue;} } } } if(j<rcount){ if(i<(vcount-rcount)) ierror(0); if(!gpt|| (!gpt[i-(vcount-rcount)]&&!is_restrict(j))|| (!gpt[j]&&!is_restrict(i-(vcount-rcount)))|| (gpt[j]&&gpt[i-(vcount-rcount)]&&bvdointersect(gpt[i-(vcount-rcount)],gpt[j],vsize))){ t2=p_typ(v); if(t==t2||t2==CHAR||!ISSCALAR(t2)) BSET(set,j+vcount-rcount); } } } } }else{ v=vilist[i]; propagate_pointers(set,v,t,i); }} void ic_changes(struct IC *p,bvtype *result)/* Initialisiert den Bitvektor result mit allen Variablen, die durch das *//* IC p geaendert werden koennten. */{ int i,j,t,t2;struct Var *v; memset(result,0,vsize); t=(ztyp(p)&NQ); if(p->z.flags&VAR){ v=p->z.v; i=v->index; /* Hilfsvariable, die waehrend diesem cse-Durchlauf eingefuehrt */ /* wurde. */ if(i<0) return; if(i>=vcount) ierror(0); if(p->z.flags&DREFOBJ){ if(i>=rcount) ierror(0); alias_propagate(result,i+vcount-rcount,t,1); }else{ alias_propagate(result,i,t,1); if(i<rcount) BSET(result,i+vcount-rcount); }Lines 1–500 of 816. Load more
/* $VER: vbcc (alias.c) V0.8 */ /* Listen benutzter/veraenderter Variablen und Behandlung von Decknamen. */ #include "opt.h" static char FILE_[]=__FILE__; static bvtype **gpt; static unsigned long ptsize; #define is_restrict(i) ((i)<=vcount-rcount&&(vilist[i]->vtyp->flags&RESTRICT)) /* sets points-to-info for var i to undefined */ void undef_pt(bvtype **pt,int i) { if(i<0||i>=vcount) ierror(0); if(pt[i]) ptsize-=vsize; free(pt[i]); pt[i]=0; if(i<rcount){ i+=vcount-rcount; if(pt[i]) ptsize-=vsize; free(pt[i]); pt[i]=0; } } /* walks through a clist and sets the corresponding bit in bv for every variable whose address is contained in the clist */ void add_clist_refs(bvtype *bv,struct Typ *t,struct const_list *cl) { /*FIXME: bei Aufrufen auch auf locale, nicht USEDASDEST|USEDASADDR */ int i;zmax sz; if(ISARRAY(t->flags)){ for(sz=l2zm(0L);!zmleq(t->size,sz)&&cl;sz=zmadd(sz,l2zm(1L)),cl=cl->next){ if(!cl->other){ierror(0);return;} add_clist_refs(bv,t->next,cl->other); } return; } if(ISUNION(t->flags)){ add_clist_refs(bv,(*t->exact->sl)[0].styp,cl); return; } if(ISSTRUCT(t->flags)){ struct Typ *st; for(i=0;i<t->exact->count&&cl;i++){ if(!cl->other){ierror(0);return;} st=(*t->exact->sl)[i].styp; if(!(*t->exact->sl)[i].identifier) ierror(0); if((*t->exact->sl)[i].identifier[0]){ add_clist_refs(bv,st,cl->other); cl=cl->next; } } return; } if(cl->tree&&(cl->tree->o.flags&VARADR)){ /* careful: variable might not have a valid index if it is not used within the function optimized */ i=cl->tree->o.v->index; if(i>=0&&i<vcount-rcount&&vilist[i]==cl->tree->o.v){ /*printf("add %s\n",vilist[i]->identifier);*/ BSET(bv,i); } } } /* copies points-to-info for one var to another */ void copy_pt(bvtype **pt,int to,int from) { if(to<0||to>=vcount) ierror(0); if(from<0||from>=vcount) ierror(0); if(!pt[from]){ if(from>=vcount-rcount&&pt[from-(vcount-rcount)]){ /* if dref check, whether from only points to initialized const */ int i;bvtype *new; for(i=0;i<vcount;i++){ if(BTST(pt[from-(vcount-rcount)],i)){ struct Var *v=vilist[i]; if(!is_const(v->vtyp)||!v->clist) break; } } if(i==vcount){ /* yes, take the points-to-info from clist */ if(!pt[to]||to+vcount-rcount==from){ new=mymalloc(vsize); ptsize+=vsize; }else new=pt[to]; memset(new,0,vsize); for(i=0;i<vcount;i++){ if(BTST(pt[from-(vcount-rcount)],i)) add_clist_refs(new,vilist[i]->vtyp,vilist[i]->clist); } if(to+vcount-rcount==from){ ptsize-=vsize; free(pt[to]); } pt[to]=new; return; } } undef_pt(pt,to); }else{ if(!pt[to]){ pt[to]=mymalloc(vsize); ptsize+=vsize; } memcpy(pt[to],pt[from],vsize); } } /* set var i points only to j in points-to-info */ void set_pt(bvtype **pt,int i,int j) { if(i<0||i>=vcount) ierror(0); if(j<0||j>=vcount) ierror(0); if(!pt[i]){ pt[i]=mymalloc(vsize); ptsize+=vsize; } memset(pt[i],0,vsize); BSET(pt[i],j); } void print_single_pt(bvtype *pt) { int j; if(pt){ for(j=0;j<vcount;j++){ if(BTST(pt,j)) printf(" %s<%s>(%p)\n",(j>=vcount-rcount)?"*":"",vilist[j]->identifier,(void*)vilist[j]); } }else{ printf(" (undefined)\n"); } } void print_pt(bvtype **pt) { int i,j; if(!pt) return; printf("points-to:\n"); for(i=0;i<vcount;i++){ printf("%s<%s>(%p):\n",(i>=vcount-rcount)?"*":"",vilist[i]->identifier,(void*)vilist[i]); print_single_pt(pt[i]); } } /* creates new points-to-info; every var set to undefined */ bvtype **new_pt(void) { bvtype **pt; int i; pt=mymalloc(vcount*sizeof(*pt)); ptsize+=vcount*sizeof(*pt); for(i=0;i<vcount;i++){ if(i<rcount&&(vilist[i]->vtyp->flags&RESTRICT)){ pt[i]=mymalloc(vsize); ptsize+=vsize; memset(pt[i],0,vsize); BSET(pt[i],i+vcount-rcount); }else pt[i]=0; } return pt; } void free_pt(bvtype **pt) { int i; if(pt){ for(i=0;i<vcount;i++){ if(pt[i]) ptsize-=vsize; free(pt[i]); } ptsize-=vcount*sizeof(*pt); free(pt); } } /* set points-to-info of *v to union of points-to of all vars in the points-to-info of v */ void dref_pt(bvtype **pt,int i) { int j,d; if(i<0||i>=rcount) ierror(0); d=i+vcount-rcount; if(!pt[i]){ undef_pt(pt,d); return; } if(!pt[d]){ pt[d]=mymalloc(vsize); ptsize+=vsize; } memset(pt[d],0,vsize); for(j=0;j<vcount;j++){ if(BTST(pt[i],j)){ struct Var *v=vilist[j]; if(v->clist&&is_const(v->vtyp)){ add_clist_refs(pt[d],v->vtyp,v->clist); }else if(!pt[j]){ undef_pt(pt,d); return; }else bvunite(pt[d],pt[j],vsize); } } } void trans_pt(bvtype **pt,struct IC *p) { int i,j,newset=-1,sv,cp; if((p->code==ADDI2P||p->code==SUBIFP)&&!compare_objs(&p->q1,&p->z,ztyp(p))) return; if((p->z.flags&VAR)&&ISSCALAR(p->z.v->vtyp->flags)){ i=p->z.v->index; if(i<0||i>=vcount) ierror(0); if(p->z.flags&DREFOBJ){ if(i>=rcount) ierror(0); i+=vcount-rcount; } if(!is_restrict(i)){ if(p->code==ASSIGN){ newset=i;sv=-1;cp=-1; if(p->q1.flags&VARADR){ sv=p->q1.v->index; set_pt(pt,i,p->q1.v->index); }else if(p->q1.flags&VAR){ j=p->q1.v->index; if(j<0||j>=vcount) ierror(0); if(p->q1.flags&DREFOBJ){ if(j>=rcount) ierror(0); j+=vcount-rcount; } cp=j; copy_pt(pt,i,j); }else{ if(!pt[i]){ pt[i]=mymalloc(vsize); ptsize+=vsize; } memset(pt[i],0,vsize); } } if(p->code==ADDRESS){ newset=i;sv=p->q1.v->index;cp=-1; set_pt(pt,i,p->q1.v->index); } if((p->code==ADDI2P||p->code==SUBIFP)&&(p->q1.flags&VAR)){ newset=i;sv=-1;cp=-1; if(p->q1.flags&VARADR){ sv=p->q1.v->index; set_pt(pt,i,p->q1.v->index); }else{ j=p->q1.v->index; if(j<0||j>=vcount) ierror(0); if(p->q1.flags&DREFOBJ){ if(j>=rcount) ierror(0); j+=vcount-rcount; } cp=j; copy_pt(pt,i,j); } } } } if(newset>=0&&newset<rcount){ if(newset<0) ierror(0); dref_pt(pt,newset); } for(i=0;i<p->change_cnt;i++){ j=p->change_list[i].v->index; if(j<0||j>=vcount) ierror(0); if(p->change_list[i].flags&DREFOBJ){ if(j>=rcount) ierror(0); j+=vcount-rcount; } if(j!=newset&&!is_restrict(j)){ if(newset>=0&&pt[j]){ if(sv>=0){ if(sv>=vcount) ierror(0); BSET(pt[j],sv); } if(cp>=0&&pt[cp]){ if(cp<0||cp>=vcount) ierror(0); bvunite(pt[j],pt[cp],vsize); } }else undef_pt(pt,j); } } } bvtype **clone_pt(bvtype **pt) { int i; bvtype **new; if(!pt) return new_pt(); new=mymalloc(vcount*sizeof(*new)); ptsize+=vcount*sizeof(*new); for(i=0;i<vcount;i++){ if(pt[i]){ new[i]=mymalloc(vsize); ptsize+=vsize; memcpy(new[i],pt[i],vsize); }else new[i]=0; } return new; } /* tests if two points-to-infos are identical */ int equal_pt(bvtype **pt1,bvtype **pt2) { int i; if(!pt1&&!pt2) return 1; if(!pt1||!pt2) return 0; for(i=0;i<vcount;i++){ if(!pt1[i]&&!pt2[i]) continue; if(!pt1[i]||!pt2[i]) return 0; if(memcmp(pt1[i],pt2[i],vsize)) return 0; } return 1; } #if 0 void calc_pt(struct flowgraph *fg) { struct flowgraph *g; struct flowlist *in; struct IC *p; bvtype **pt,**ppt; int i,all_preds,changed; changed=1; while(changed){ if(DEBUG&1024) printf("calc_pt pass\n"); changed=0; for(g=fg;g;g=g->normalout){ /* do all predecessors already have points-to-info? */ all_preds=1; for(in=g->in;in;in=in->next){ if(!in->graph->pt){ all_preds=0; break; } } if(all_preds&&g->in){ /* calc union of all predecessors */ pt=clone_pt(g->in->graph->pt); for(in=g->in->next;in;in=in->next){ ppt=in->graph->pt; for(i=0;i<vcount;i++){ if(pt[i]){ if(!ppt[i]) undef_pt(pt,i); else bvunite(pt[i],ppt[i],vsize); } } } }else pt=new_pt(); for(p=g->start;p;p=p->next){ trans_pt(pt,p); if(p==g->end) break; } if(pt==g->pt) ierror(0); if(!changed){ if(!equal_pt(pt,g->pt)){ changed=1; free_pt(g->pt); g->pt=pt; }else{ free_pt(pt); } }else{ free_pt(g->pt); g->pt=pt; } } } } #endif int p_typ(struct Var *v) /* Liefert den Typ, auf den Variable zeigen kann. Falls nicht eindeutig */ /* wird CHAR zurueckgegeben, da ein char * auf alles zeigen kann. */ { struct Typ *t=v->vtyp;int f; /* Kein Zeiger? Dann moeglicherweise Struktur, die verschiedene Zeiger */ /* enthalten koennte. Koennte man evtl. noch genauer pruefen. */ if(!ISPOINTER(t->flags)||!t->next||(v->flags&DNOTTYPESAFE)) return CHAR; f=t->next->flags&NQ; if(f==VOID) f=CHAR; return f; } /* propagates information if a variable whose address may have been taken is modified */ static void propagate_pointers(bvtype *set,struct Var *v,int t,int i) { int j,t2; if(v->nesting==0||v->storage_class==EXTERN||(v->flags&USEDASADR)){ if(noaliasopt){ bvunite(set,av_drefs,vsize); }else{ for(j=0;j<rcount;j++){ t2=p_typ(vilist[j]); if(t==t2||t2==CHAR||!ISSCALAR(t)||!ISSCALAR(t2)){ if(!gpt||!gpt[j]||(i>=0&&BTST(gpt[j],i))) BSET(set,j+vcount-rcount); } } } } } void alias_propagate(bvtype *set,int i,int t,int wr) { int j,t2; struct Var *v; if(i<0||i>=vcount) ierror(0); t&=NQ; BSET(set,i); if(wr&&i<rcount) BSET(set,i+vcount-rcount); if(i>=vcount-rcount){ /* DREFOBJ */ if(noaliasopt||t==CHAR||!ISSCALAR(t)){ bvunite(set,av_drefs,vsize); bvunite(set,av_address,vsize); bvunite(set,av_globals,vsize); }else{ for(j=0;j<vcount-rcount;j++){ v=vilist[j]; if(!gpt||!gpt[i-(vcount-rcount)]||BTST(gpt[i-(vcount-rcount)],j)){ v=vilist[j]; if(!v) ierror(0); if(v->nesting==0||v->storage_class==EXTERN||(v->flags&USEDASADR)){ struct Typ *tp=v->vtyp; if(!v->vtyp) ierror(0); do{ t2=tp->flags&NQ; tp=tp->next; }while(ISARRAY(t2)); if(t==t2||!ISSCALAR(t2)){ BSET(set,j); if(wr&&j<rcount) {BSET(set,j+vcount-rcount);continue;} } } } if(j<rcount){ if(i<(vcount-rcount)) ierror(0); if(!gpt|| (!gpt[i-(vcount-rcount)]&&!is_restrict(j))|| (!gpt[j]&&!is_restrict(i-(vcount-rcount)))|| (gpt[j]&&gpt[i-(vcount-rcount)]&&bvdointersect(gpt[i-(vcount-rcount)],gpt[j],vsize))){ t2=p_typ(v); if(t==t2||t2==CHAR||!ISSCALAR(t2)) BSET(set,j+vcount-rcount); } } } } }else{ v=vilist[i]; propagate_pointers(set,v,t,i); } } void ic_changes(struct IC *p,bvtype *result) /* Initialisiert den Bitvektor result mit allen Variablen, die durch das */ /* IC p geaendert werden koennten. */ { int i,j,t,t2;struct Var *v; memset(result,0,vsize); t=(ztyp(p)&NQ); if(p->z.flags&VAR){ v=p->z.v; i=v->index; /* Hilfsvariable, die waehrend diesem cse-Durchlauf eingefuehrt */ /* wurde. */ if(i<0) return; if(i>=vcount) ierror(0); if(p->z.flags&DREFOBJ){ if(i>=rcount) ierror(0); alias_propagate(result,i+vcount-rcount,t,1); }else{ alias_propagate(result,i,t,1); if(i<rcount) BSET(result,i+vcount-rcount); }