void av_change(struct IC *p,bvtype *use,bvtype *def) /* Berechnet die Aenderungen, die sich durch IC p an use und def ergeben. */ { int i,j,n=-1; int g1,g2; /* Wenn eine Quelle==Ziel, dann wird dadurch kein neuer use erzeugt, */ /* um z.B. unbenutzte Induktionsvariablen in Schleifen zu eliminieren. */ g1=compare_objs(&p->q1,&p->z,p->typf); g2=compare_objs(&p->q2,&p->z,p->typf); if(!g1&&(p->q1.flags&(VAR|DREFOBJ))==VAR) n=p->q1.v->index; if(!g2&&(p->q2.flags&(VAR|DREFOBJ))==VAR) n=p->q2.v->index; for(j=0;j<p->use_cnt;j++){ i=p->use_list[j].v->index; if(p->use_list[j].flags&DREFOBJ) i+=vcount-rcount; if(i>=vcount) continue; if(i!=n&&!BTST(def,i)) BSET(use,i); } /* Ein Wert wird nicht zerstoert, wenn es kein elementarer Typ ist und */ /* die Groesse kleiner als die Variable (steht in alle solchen ICs in */ /* q2.val.max. */ if((p->z.flags&(VAR|DREFOBJ))==VAR&&(ISSCALAR(p->z.v->vtyp->flags)||p->z.v->vtyp->flags==0||zmeqto(p->q2.val.vmax,szof(p->z.v->vtyp)))){ i=p->z.v->index; if(i>=vcount) ierror(0); if(g1&&g2&&!BTST(use,i)) BSET(def,i); /* Wenn p geaendert wird, wird auch *p geaendert */ if(i<rcount&&!BTST(def,i+vcount-rcount)) BSET(use,i+vcount-rcount); } if((p->z.flags&(VAR|DREFOBJ))==(VAR|DREFOBJ)&&g1&&g2&&!(p->z.v->flags&DNOTTYPESAFE)){ i=p->z.v->index+vcount-rcount; if(i>=vcount) ierror(0); if(!BTST(use,i)) BSET(def,i); } }
int dead_assignments(struct flowgraph *fg) /* Findet Zuweisungen, die unnoetig sind, da die Variable nie mehr */ /* benutzt werden kann. */ { int changed=0;struct IC *p;bvtype *isused; int i,j; if(DEBUG&1024) printf("searching for dead assignments\n"); isused=mymalloc(vsize); while(fg){ memcpy(isused,fg->av_out,vsize); p=fg->end; while(p){ if(p->z.flags&VAR){ i=p->z.v->index; if(p->z.flags&DREFOBJ) i+=vcount-rcount; if(!BTST(isused,i)&&!is_volatile_ic(p)&&!(disable&1)){ if(DEBUG&1024){printf("dead assignment deleted:\n");pric2(stdout,p);} if(*p->z.v->identifier&&p->code!=ASSIGN){ err_ic=p;error(170,i>=vcount-rcount?"*":"",p->z.v->identifier);err_ic=0;} if(p->code!=GETRETURN) changed=1; if(p==fg->start){remove_IC_fg(fg,p);break;} p=p->prev;remove_IC_fg(fg,p->next); continue; } } if(p->code!=SETRETURN&&p->code!=TEST&&p->code!=COMPARE&&(p->q1.flags&VAR)&&!BTST(isused,p->q1.v->index)&&(!(p->z.flags&VAR)||!p->z.v->reg||p->z.v->identifier)){ struct IC *m,*a;int f=p->q1.flags,dt=p->q1.dtyp; p->q1.flags&=~DREFOBJ; a=p->prev;if(a) m=a->prev; else m=0; if(m&&a&&m->code==ASSIGN&&(a->q1.flags&(VAR|DREFOBJ))==VAR&&!compare_objs(&p->q1,&m->z,0)&&!compare_objs(&a->q1,&a->z,0)&&!compare_objs(&m->q1,&a->z,0)&&(a->q2.flags&KONST)&&!var_conflicts(a->q1.v,p)){ if(DEBUG&1024){ printf("reorder post-op(q1):\n"); pric2(stdout,m);pric2(stdout,a);pric(stdout,p); } p->q1=a->q1; m->next=p;p->prev=m; if(p->next) p->next->prev=a; a->next=p->next; a->prev=p;p->next=a; if(fg->end==p) fg->end=a; if(p==last_ic) last_ic=a; remove_IC_fg(fg,m); av_update(a,isused); p->use_list=myrealloc(p->use_list,(p->use_cnt+a->use_cnt)*VLS); memcpy(&p->use_list[p->use_cnt],a->use_list,a->use_cnt*VLS); p->use_cnt+=a->use_cnt; changed=1; if((f&DREFOBJ)&&p->q1.v->index>=rcount) ierror(0); } p->q1.flags=f; p->q1.dtyp=dt; } if(p->code!=TEST&&p->code!=COMPARE&&(p->q2.flags&VAR)&&!BTST(isused,p->q2.v->index)&&(!(p->z.flags&VAR)||!p->z.v->reg||p->z.v->identifier)){ struct IC *m,*a;int f=p->q2.flags,dt=p->q2.dtyp; p->q2.flags&=~DREFOBJ; a=p->prev;if(a) m=a->prev; else m=0; if(m&&a&&m->code==ASSIGN&&(a->q1.flags&(VAR|DREFOBJ))==VAR&&!compare_objs(&p->q2,&m->z,0)&&!compare_objs(&a->q1,&a->z,0)&&!compare_objs(&m->q1,&a->z,0)&&(a->q2.flags&KONST)&&!var_conflicts(a->q1.v,p)){ if(DEBUG&1024){ printf("reorder post-op(q2):\n"); pric2(stdout,m);pric2(stdout,a);pric(stdout,p); } p->q2=a->q1; m->next=p;p->prev=m; if(p->next) p->next->prev=a; a->next=p->next; a->prev=p;p->next=a; if(fg->end==p) fg->end=a; if(p==last_ic) last_ic=a; remove_IC_fg(fg,m); av_update(a,isused); p->use_list=myrealloc(p->use_list,(p->use_cnt+a->use_cnt)*VLS); memcpy(&p->use_list[p->use_cnt],a->use_list,a->use_cnt*VLS); p->use_cnt+=a->use_cnt; changed=1; if((f&DREFOBJ)&&p->q2.v->index>=rcount) ierror(0); } p->q2.flags=f; p->q2.dtyp=dt; } if(p->code!=TEST&&p->code!=COMPARE&&(p->z.flags&(VAR|DREFOBJ))==(VAR|DREFOBJ)&&!BTST(isused,p->z.v->index)){ struct IC *m,*a;int f=p->z.flags,dt=p->z.dtyp; p->z.flags&=~DREFOBJ; a=p->prev;if(a) m=a->prev; else m=0; if(m&&a&&m->code==ASSIGN&&(a->q1.flags&(VAR|DREFOBJ))==VAR&&!compare_objs(&p->z,&m->z,0)&&!compare_objs(&a->q1,&a->z,0)&&!compare_objs(&m->q1,&a->z,0)&&(a->q2.flags&KONST)&&!var_conflicts(a->q1.v,p)){ if(DEBUG&1024){ printf("reorder post-op(z):\n"); pric2(stdout,m);pric2(stdout,a);pric2(stdout,p); printf("--"); } p->z=a->q1; m->next=p;p->prev=m; if(p->next) p->next->prev=a; a->next=p->next; a->prev=p;p->next=a; if(fg->end==p) fg->end=a; if(p==last_ic) last_ic=a; remove_IC_fg(fg,m); av_update(a,isused); p->use_list=myrealloc(p->use_list,(p->use_cnt+a->use_cnt)*VLS); memcpy(&p->use_list[p->use_cnt],a->use_list,a->use_cnt*VLS); p->use_cnt+=a->use_cnt; changed=1; if((f&DREFOBJ)&&p->z.v->index>=rcount) ierror(0); } p->z.flags=f; p->z.dtyp=dt; } av_update(p,isused); if(p==fg->start) break; p=p->prev; } fg=fg->normalout; } free(isused); return(changed); }
void ParallelPairs(void *objs, int Nmyobjs, int sizeobj, int (*numget)(const void *), void (*numset)(const void *, int ), int (*procget)(const void *), void (*marry)(const void *, const void *), int (*compare_objs)(const void *, const void *)){ char *myobjs = (char*) objs; int n, p, sk, cnt, num; int maxind = 0; int procid, nprocs; MPI_Comm_rank(MPI_COMM_WORLD, &procid); MPI_Comm_size(MPI_COMM_WORLD, &nprocs); /* local sort */ qsort(myobjs, Nmyobjs, sizeobj, compare_objs); /* TW: homework replace from here --------> */ maxind = 0; for(n=0;n<Nmyobjs;++n){ num = numget(myobjs+sizeobj*n); maxind = max(maxind, num); } int globalmaxind; MPI_Allreduce(&maxind, &globalmaxind, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD); int binsize = ceil( (double)(globalmaxind)/(double)nprocs ) + 10; int *outN = (int*) calloc(nprocs, sizeof(int)); int *inN = (int*) calloc(nprocs, sizeof(int)); int *cumoutN = (int*) calloc(nprocs, sizeof(int)); int *cuminN = (int*) calloc(nprocs, sizeof(int)); sk = 0; /* count the number of objs in each bin */ int binup = binsize; for(p=0;p<nprocs;++p){ while( numget(myobjs+(sk*sizeobj) ) <= binup ){ ++(outN[p]); ++sk; if(sk==Nmyobjs){ break; } } binup += binsize; if(sk==Nmyobjs){ break; } } /* TW: <---------- replace to here */ /* communicate numbers to be sent to each bin */ MPI_Alltoall(outN, 1, MPI_INT, inN, 1, MPI_INT, MPI_COMM_WORLD); /* build incoming buffer */ int Notherobjs = 0; for(p=0;p<nprocs;++p) Notherobjs += inN[p]; for(p=0;p<nprocs;++p){ outN[p] *= sizeobj/sizeof(int); inN[p] *= sizeobj/sizeof(int); } for(p=1;p<nprocs;++p){ cumoutN[p] = cumoutN[p-1]+outN[p-1]; cuminN[p] = cuminN[p-1] + inN[p-1]; } /* fill up bins of objects from cloud */ char *otherobjs = (char*) calloc(Notherobjs*sizeobj, sizeof(char)); MPI_Alltoallv(myobjs, outN, cumoutN, MPI_INT, otherobjs, inN, cuminN, MPI_INT, MPI_COMM_WORLD); /* sort the bin */ qsort(otherobjs, Notherobjs, sizeobj, compare_objs); /* number unique objs consecutively in each bin */ for(n=1;n<Notherobjs;++n){ /* match ? */ if(!compare_objs(otherobjs+ n*sizeobj, otherobjs+(n-1)*sizeobj)){ marry(otherobjs+n*sizeobj, otherobjs+(n-1)*sizeobj); } } char *outobjs = (char*) calloc(Notherobjs*sizeobj, sizeof(char)); sk = 0; for(p=0;p<nprocs;++p) for(n=0;n<Notherobjs;++n) if(procget(otherobjs+n*sizeobj)==p){ memcpy(outobjs+sk*sizeobj, otherobjs+n*sizeobj, sizeobj); ++sk; } /* send results out */ MPI_Alltoallv(outobjs, inN, cuminN, MPI_INT, myobjs, outN, cumoutN, MPI_INT, MPI_COMM_WORLD); free(otherobjs); free(outN); free(inN); free(cumoutN); free(cuminN); }