diff --git a/alias.c b/alias.c
new file mode 100644
index 0000000..f0a942e
--- /dev/null
+++ b/alias.c
@@ -0,0 +1,822 @@
+/*  $VER: vbcc (alias.c) $Revision: 1.6 $  */
+/*  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,type *t,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)){
+    type *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)){
+	  Var *v=vilist[i];
+	  if(!is_const(v->vtyp)||!v->clist||(v->storage_class!=STATIC&&v->storage_class!=EXTERN))
+	    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)){
+      Var *v=vilist[j];
+      if(v->clist&&is_const(v->vtyp)&&(v->storage_class==STATIC||v->storage_class==EXTERN)){
+	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,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(flowgraph *fg)
+{
+  flowgraph *g;
+  flowlist *in;
+  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(Var *v)
+/*  Liefert den Typ, auf den Variable zeigen kann. Falls nicht eindeutig    */
+/*  wird CHAR zurueckgegeben, da ein char * auf alles zeigen kann.          */
+{
+    type *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,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;
+  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)){
+	    type *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(IC *p,bvtype *result)
+/*  Initialisiert den Bitvektor result mit allen Variablen, die durch das   */
+/*  IC p geaendert werden koennten.                                         */
+{
+    int i,j,t,t2;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);
+	}
+    }
+    if(p->code==CALL){
+      function_info *fi;
+      if((p->q1.flags&(VAR|DREFOBJ))==VAR&&(fi=p->q1.v->fi)&&(fi->flags&ALL_MODS)&&!(disable&65536)){
+	/*  we can get the set from the function_info */
+	for(i=0;i<fi->change_cnt;i++){
+	  if(v=fi->change_list[i].v){
+	    if(v->inr==inr&&v->index>=0){
+	      if(v->index>=vcount) ierror(0);
+	      alias_propagate(result,v->index,v->vtyp->flags&NQ,1);
+	    }else
+	      propagate_pointers(result,v,v->vtyp->flags&NQ,-1);
+	  }else{
+	    for(j=0;j<vcount-rcount;j++){
+	      v=vilist[j];
+	      if(v->nesting==0||v->storage_class==EXTERN||(v->flags&USEDASADR)){
+		t=v->vtyp->flags&NQ;
+		if(t==(fi->change_list[i].flags&NQ)||!ISSCALAR(t)){
+		  BSET(result,j);
+		  if(j<rcount) BSET(result,j+vcount-rcount);
+		}
+	      }
+	      if(j<rcount){
+		t=p_typ(vilist[j]);
+		if(t==CHAR||!ISSCALAR(t)||t==fi->change_list[i].flags)
+		  BSET(result,j+vcount-rcount);
+	      }
+	    }
+	  }
+	}
+      }else{
+	bvunite(result,av_drefs,vsize);
+	bvunite(result,av_address,vsize);
+	bvunite(result,av_globals,vsize);
+	bvunite(result,av_statics,vsize);
+      }
+    }
+    if((p->z.flags&(KONST|DREFOBJ))==(KONST|DREFOBJ)){
+      bvunite(result,av_drefs,vsize);
+    }
+}
+void ic_uses(IC *p,bvtype *result)
+/*  Initialisiert den Bitvektor result mit allen Variablen, die durch das   */
+/*  IC p benutzt werden koennten.                                           */
+{
+    int i,j,t,t2,c;Var *v;type *tp;
+    memset(result,0,vsize);
+    c=p->code;
+    if(c!=ADDRESS){
+        if((p->q1.flags&(VAR|VARADR))==VAR&&c!=ADDRESS&&(c!=CALL||(p->q1.flags&DREFOBJ))){
+            v=p->q1.v;
+            i=v->index;
+	    if(i<0||i>=vcount) ierror(0);
+	    t=q1typ(p);
+	    if(p->q1.flags&DREFOBJ){
+	      if(i>=rcount) ierror(0);
+	      alias_propagate(result,i+vcount-rcount,t,0);
+	    }
+	    alias_propagate(result,i,t,0);
+        }
+        if((p->q2.flags&(VAR|VARADR))==VAR){
+            v=p->q2.v;
+            i=v->index;
+	    if(i<0||i>=vcount) ierror(0);
+	    t=q2typ(p);
+	    if(p->q2.flags&DREFOBJ){
+	      if(i>=rcount) ierror(0);
+	      alias_propagate(result,i+vcount-rcount,t,0);
+	    }
+	    alias_propagate(result,i,t,0);
+        }
+    }
+    if((p->z.flags&(VAR|VARADR|DREFOBJ))==(VAR|DREFOBJ)){
+        v=p->z.v;
+        i=v->index;
+        if(i>=vcount) {pric2(stdout,p);ierror(0);}
+	t=(ztyp(p)&NQ);
+	alias_propagate(result,i,t,0);
+    }
+    if(p->code==CALL){
+      function_info *fi;
+      if((p->q1.flags&(VAR|DREFOBJ))==VAR&&(fi=p->q1.v->fi)&&(fi->flags&ALL_USES)&&!(disable&65536)){
+	/*  we can get the set from the function_info */
+	for(i=0;i<fi->use_cnt;i++){
+	  if(v=fi->use_list[i].v){
+	    if(v->inr==inr&&v->index>=0)
+	      alias_propagate(result,v->index,v->vtyp->flags&NQ,0);
+	    else
+	      propagate_pointers(result,v,v->vtyp->flags&NQ,-1);
+	  }else{
+	    for(j=0;j<vcount-rcount;j++){
+	      v=vilist[j];
+	      if(v->nesting==0||v->storage_class==EXTERN||(v->flags&USEDASADR)){
+		t=v->vtyp->flags&NQ;
+		if(t==(fi->use_list[i].flags&NQ)||!ISSCALAR(t))
+		  BSET(result,j);
+	      }
+	      if(j<rcount){
+		t=p_typ(vilist[j]);
+		if(t==CHAR||!ISSCALAR(t)||t==fi->use_list[i].flags)
+		  BSET(result,j+vcount-rcount);
+	      }
+	    }
+	  }
+	}
+      }else{
+	bvunite(result,av_drefs,vsize);
+	bvunite(result,av_address,vsize);
+	bvunite(result,av_globals,vsize);
+	bvunite(result,av_statics,vsize);
+      }
+    }
+    if((p->q1.flags&(KONST|DREFOBJ))==(KONST|DREFOBJ)){
+      bvunite(result,av_drefs,vsize);
+    }
+    if((p->q2.flags&(KONST|DREFOBJ))==(KONST|DREFOBJ)){
+      bvunite(result,av_drefs,vsize);
+    }
+}
+void free_alias(flowgraph *fg)
+/*  Gibt alle use/change-Listen der ICs im Flussgraphen frei.               */
+{
+    IC *p;flowgraph *g;
+    if(DEBUG&1024) printf("freeing alias info\n");
+    for(g=fg;g;g=g->normalout){
+        for(p=g->start;p;p=p->next){
+            if(p->code==LABEL&&(p->use_cnt>0||p->change_cnt>0)) ierror(0);
+            if(p->use_cnt>0) {free(p->use_list);p->use_cnt=0;}
+            if(p->change_cnt>0) {free(p->change_list);p->change_cnt=0;}
+            if(p==g->end) break;
+        }
+    }
+    have_alias=0;
+}
+void create_alias(flowgraph *fg)
+/*  Initialisiert jedes IC mit einer Liste aller Variablen, die dadurch     */
+/*  benutzt und veraendert werden koennten. Z.Z. wird bis auf Typ-basierte  */
+/*  Optimierungen der worst-case angenommen.                                */
+{
+  bvtype *vars=mymalloc(vsize);
+  IC *p;flowgraph *g;
+  flowlist *in;
+  bvtype **ppt;
+  int i,cnt,all_preds,changed;
+  unsigned long heapsize;
+  if(DEBUG&1024) printf("creating alias info\n");
+
+  ptsize=0;
+  
+  changed=1;
+  while(changed){
+    if(DEBUG&1024) printf("create_alias pass\n");
+    changed=0;
+    if(have_alias)
+      free_alias(fg);
+    heapsize=0;
+    for(g=fg;g;g=g->normalout){
+      if((optflags&1024)&&!noaliasopt){
+	/* 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 */
+	  gpt=clone_pt(g->in->graph->pt);
+	  for(in=g->in->next;in;in=in->next){
+	    ppt=in->graph->pt;
+	    if(!ppt)
+	      continue;
+	    for(i=0;i<vcount;i++){
+	      if(gpt[i]){
+		if(!ppt[i])
+		  undef_pt(gpt,i);
+		else
+		  bvunite(gpt[i],ppt[i],vsize);
+	      }
+	    }
+	  }
+	}else
+	  gpt=new_pt();                 
+      }else{
+	gpt=0;
+      }
+      for(p=g->start;p;p=p->next){
+	int da; /* always consider a direct write, even if variable is const-qualified */
+	ic_uses(p,vars);
+	for(i=0,cnt=0;i<vcount;i++)
+	  if(BTST(vars,i)) cnt++;
+	p->use_cnt=cnt;
+	if(cnt==0){
+	  p->use_list=0;
+	}else{
+	  p->use_list=mymalloc(cnt*VLS);
+	  heapsize+=cnt*VLS;
+	  for(cnt=0,i=0;i<vcount;i++){
+	    if(BTST(vars,i)){
+	      p->use_list[cnt].v=vilist[i];
+	      if(i>=vcount-rcount) p->use_list[cnt].flags=DREFOBJ;
+	      else         p->use_list[cnt].flags=0;
+	      cnt++;
+	    }
+	  }
+	}
+	ic_changes(p,vars);
+	if((p->z.flags&(VAR|DREFOBJ))==VAR)
+	  da=p->z.v->index;
+	else
+	  da=0;
+	for(i=0,cnt=0;i<vcount;i++)
+	  if(BTST(vars,i)&&(i>=vcount-rcount||i==da||!is_const(vilist[i]->vtyp))) cnt++;
+	p->change_cnt=cnt;
+	if(cnt==0){
+	  p->change_list=0;
+	}else{
+	  p->change_list=mymalloc(cnt*VLS);
+	  heapsize+=cnt*VLS;
+	  for(cnt=0,i=0;i<vcount;i++){
+	    if(BTST(vars,i)&&(i>=vcount-rcount||i==da||!is_const(vilist[i]->vtyp))){
+	      p->change_list[cnt].v=vilist[i];
+	      if(i>=vcount-rcount) p->change_list[cnt].flags=DREFOBJ;
+	      else         p->change_list[cnt].flags=0;
+	      cnt++;
+	    }
+	  }
+	}
+
+	if(p->code==CALL){
+	  if((p->q1.flags&(VAR|DREFOBJ))==(VAR|DREFOBJ)){
+	    int i=p->q1.v->index;
+	    if(i<0||i>=vcount) ierror(0);
+	    if(gpt&&gpt[i]){
+	      int j,cnt;
+	      for(cnt=0,j=0;j<vcount-rcount;j++){
+		if(BTST(gpt[i],j)&&ISFUNC(vilist[j]->vtyp->flags))
+		  cnt++;
+	      }
+	      if(cnt){
+		if(p->call_cnt) free(p->call_list);
+		p->call_cnt=cnt;
+		p->call_list=mymalloc(sizeof(*p->call_list)*cnt);
+		for(cnt=0,j=0;j<vcount-rcount;j++){
+		  if(BTST(gpt[i],j)&&ISFUNC(vilist[j]->vtyp->flags)){
+		    p->call_list[cnt].v=vilist[j];
+		    p->call_list[cnt].flags=0;
+		    cnt++;
+		  }
+		}
+		if(cnt==1&&all_preds){
+		  if(DEBUG&1024) {printf("replacing indirect call by single target:\n");pric2(stdout,p);}
+		  p->q1.flags=VAR;
+		  p->q1.val.vmax=l2zm(0L);
+		  p->q1.v=p->call_list[0].v;
+		}
+	      }
+	    }
+	  }	  
+	}
+
+	if((optflags&1024)&&!noaliasopt)
+	  trans_pt(gpt,p);
+	if(p==g->end) break;
+      }
+      if((optflags&1024)&&!noaliasopt){
+	if(!changed){
+	  if(!equal_pt(gpt,g->pt)){
+	    changed=1;
+	    free_pt(g->pt);
+	    g->pt=gpt;
+	  }else{
+	    free_pt(gpt);
+	  }
+	}else{
+	  free_pt(g->pt);
+	  g->pt=gpt;
+	}          
+      }           
+    }
+    if(DEBUG&16384) printf("create_alias heapsize=%lu\n",heapsize);
+    have_alias=1;
+  }
+  if(DEBUG&16384) printf("points-to heapsize=%lu\n",ptsize);
+  if((optflags&1024)&&!noaliasopt){
+    for(g=fg;g;g=g->normalout){
+      free_pt(g->pt);
+      g->pt=0;
+    }
+  }
+  free(vars);
+}
+#if 1
+void update_alias(Var *old,Var *new)
+/*  Aendert alle use/changes von (old) auf (new). Wird aufgerufen, wenn     */
+/*  copy-propagation eine Variable neu zu einem DREFOBJ macht.              */
+{
+    IC *p;int i;
+    if(DEBUG&1024) printf("update-alias\n");
+    for(p=first_ic;p;p=p->next){
+        for(i=0;i<p->use_cnt;i++){
+            if(p->use_list[i].v==old&&(p->use_list[i].flags&DREFOBJ)){
+                p->use_cnt++;
+                p->use_list=myrealloc(p->use_list,p->use_cnt*VLS);
+                p->use_list[p->use_cnt-1].v=new;
+                p->use_list[p->use_cnt-1].flags=DREFOBJ;
+                break;
+            }
+        }
+        for(i=0;i<p->change_cnt;i++){
+	  if(p->change_list[i].v==new||(p->change_list[i].v==old&&(p->change_list[i].flags&DREFOBJ))){
+                p->change_cnt++;
+                p->change_list=myrealloc(p->change_list,p->change_cnt*VLS);
+                p->change_list[p->change_cnt-1].v=new;
+                p->change_list[p->change_cnt-1].flags=DREFOBJ;
+                break;
+            }
+        }
+    }
+}
+#endif
