Mercurial > hg > CbC > old > device
changeset 56:5aa4528b6983 parallel-assign-c
A little optimized parallel assignment
author | kono |
---|---|
date | Wed, 19 Feb 2003 12:15:05 +0900 |
parents | 94564b45c4f3 |
children | 3d7f199e99d0 |
files | mc-nop-386.c |
diffstat | 1 files changed, 60 insertions(+), 175 deletions(-) [+] |
line wrap: on
line diff
--- a/mc-nop-386.c Wed Feb 19 10:34:54 2003 +0900 +++ b/mc-nop-386.c Wed Feb 19 12:15:05 2003 +0900 @@ -1038,6 +1038,8 @@ /* source (after) list2(tag,disp) */ /* source list list3(e,cdr,sz) */ +#define DEBUG_PARALLEL_ASSIGN 0 + int overrap(int t,int sz,int source) { @@ -1047,10 +1049,10 @@ for(;source;source=cadr(source)) { s=car(source); s0=cadr(s); if(car(s)==REGISTER && car(t)==REGISTER) { - if(s0==t0) return 1; + if(s0==t0) return s; } else if (is_same_type(s,t)) { s1=s0+caddr(source); -#if 0 +#if DEBUG_PARALLEL_ASSIGN>1 printf("# ovedrrap source %d t0 %d t1 %d\n",car(car(t)),t0,t1); printf("# ovedrrap target %d s0 %d s1 %d\n",car(car(source)),s0,s1); printf("# ovedrrap equal = %d\n",((t0<=s0&&s0<t1)||(t0<s1&&s1<=t1))); @@ -1092,33 +1094,65 @@ } } +int +circular_dependency(int t,int s,int *target,int *source) +{ + int target0=*target; + int t1,sz,ty,s1; + while(target0) { + if (cadddr(target0)==s) { + t1=car(target0); + s=cadddr(target0); + sz=size(ty=caddr(target0)); + if(t==t1) { +#if DEBUG_PARALLEL_ASSIGN +printf("# circular dependency %d ty %d+%d sz %d\n",car(t1),ty,cadr(t1),sz); +#endif + return 1; + } + if ((s1=overrap(t1,sz,*source))) { + /* another overrap start over */ + return circular_dependency(t,s1,target,source); + } + } + target0=cadr(target0); + } + return 0; +} + void parallel_assign(int *target,int *source,int *processing,int *use) { - int t,s,e1,p,sz,ty; + int t,s,sz,ty,target0,s1; while(*target) { - t=car(*target); s=cadddr(*target); - sz=size(ty=caddr(*target)); - if(car(t)==car(s) && cadr(t)==cadr(s)) { -#if 1 -printf("# duplicate same target check (you shouldn't see this) \n# %d ty %d+%d sz %d\n",car(t),ty,cadr(t),sz); + target0=*target; + while(target0) { + t=car(target0); s=cadddr(target0); + sz=size(ty=caddr(target0)); + if(car(t)==car(s) && cadr(t)==cadr(s)) { + /*書き込み先が自分自身*/ +#if DEBUG_PARALLEL_ASSIGN +printf("# remove same %d ty %d+%d sz %d\n",car(t),ty,cadr(t),sz); #endif - /*書き込み先が自分自身*/ - remove_target(target,t,use); - /* 破壊されては困るので、source listからは除かない */ - } else if (!(overrap(t,sz,*source))) { - /* 重なってないので安心して書き込める */ -#if 1 + remove_target(target,t,use); + /* 破壊されては困るので、source listからは除かない */ + } else if (!(s1=overrap(t,sz,*source))) { + /* 重なってないので安心して書き込める */ +#if DEBUG_PARALLEL_ASSIGN printf("# normal assign %d ty %d+%d sz %d\n",car(t),ty,cadr(t),sz); #endif - g_expr(assign_expr0(t,s,ty,ty)); - remove_target(target,t,use); remove0(source,s); - } else { -#if 1 - printf("# circular dependcy %d ty %d+%d sz %d\n",car(t),ty,cadr(t),sz); + g_expr(assign_expr0(t,s,ty,ty)); + remove_target(target,t,use); remove0(source,s); + } else { + if(circular_dependency(t,s1,target,source)) { +#if DEBUG_PARALLEL_ASSIGN + printf("# saving %d ty %d+%d sz %d\n",car(t),ty,cadr(t),sz); #endif - remove_target(target,t,use); remove0(source,s); - save_target(t,s,target,use,sz,ty); + remove_target(target,t,use); remove0(source,s); + save_target(t,s,target,use,sz,ty); + } + } + target0=cadr(target0); } } } @@ -1206,7 +1240,7 @@ target,ty,e2); arg_size += sz; } -#if 1 +#if DEBUG_PARALLEL_ASSIGN printf("# target %d ty %d+%d sz %d\n",car(car(target)),ty,cadr(car(target)),sz); #endif } @@ -1239,6 +1273,9 @@ s0=e4; } else if (is_same_type(t0,s0)) { if(cadr(t0)==cadr(s0)) { +#if DEBUG_PARALLEL_ASSIGN +printf("# remove same memory %d ty %d+%d sz %d\n",car(t0),ty,cadr(t0),sz); +#endif /* we should check size also (but currently useless */ remove0(&target,t0); /* still we have source to avoid overwrite */ @@ -1246,7 +1283,7 @@ } if(is_memory(s0)) { source=list3(s0,source,sz); -#if 1 +#if DEBUG_PARALLEL_ASSIGN printf("# source %d ty %d+%d sz %d\n",car(car(source)),ty,cadr(car(source)),sz); #endif } @@ -1301,158 +1338,6 @@ } } -#if 0 -int -arg_size(int e3,int *nargs0) -{ - int i,nargs,offset_list,e,t; - - offset_list = 0; - /* we should use prototypes's type */ - for (i = nargs = 0; e3;e3 =cadr(e3)) { - e = car(e3); t = caddr(e3); - if (i < MAX_REGISTER_VAR && scalar(t)) { - offset_list = list3(-(REG_ESI+i++),offset_list,e); - } else { - offset_list = - list3(nargs,offset_list,e); - nargs += (car(e3)==CHAR?size_of_int:size(t)); - } - } - *nargs0 = -nargs; - return offset_list; -} - - -void -jump(int e1, int env) -{ - int i,args,e2,e3,e4,e5,nargs,regs; - NMTBL *n,*code0; - int new_disp,scode,disp1,xreg; - char *xrn; - - /* We need three passes. Compute Stack size, Compute Arg, Copy it. */ - /* count number of args */ - args = caddr(e1); - args = reverse0(args); - nargs = arg_size(args,&new_disp); /* compute in normal order */ - disp1 = (fnptr->sc==CODE)?0:-size_of_int; - if (new_disp+disp1 < disp) { /* have to extend stack */ - if (fnptr->sc==CODE) - printf("\tleal %d(%%ebp),%%esp\n",new_disp-size_of_int); - else - printf("\tleal %d(%%ebp),%%esp\n",new_disp+disp_offset); - } - /* compute jump address */ - e2 = cadr(e1); - if (car(e2) == FNAME) { - code0=(NMTBL *)cadr(e2); - if (code0->sc!=CODE) { - error(STERR); return; - } - } else { /* indirect */ - g_expr(e2); - emit_push(); - } - /* compute arguments in reverse order */ -/* printf("## jump code_arg_offset=%d code_disp_offset=%d\n",code_arg_offset,code_disp_offset); */ - regs = 0; - i=MAX_REGISTER_VAR; - for (e3=nargs; e3;e3 =cadr(e3)) { - n=(NMTBL *)(e5=(cadr(e4 = caddr(e3)))); - switch(car(e4)) { - case FNAME: - printf("\tlea %s,%s\n",n->nm,register_name(creg,0)); - emit_push(); - break; - case ADDRESS: - g_expr(e5); - emit_push(); - break; - case RLVAR: - case CRLVAR: - if (env==0 && fnptr->sc==CODE) { -/* printf("## e5=%d car(e3)=%d\n",e5,car(e3)); */ - if (e5>=0 && e5==car(e3)) { - /* The same positioned local variable. No need to copy */ - reg_stack[reg_sp++] = -2; - } - break; - } - g_expr(e4); - emit_push(); - break; - case REGISTER: -/* printf("## i=%d rname[e5]=%d\n",i,rname[e5]); */ - if (i>0 && rname[e5]==REG_ESI+ --i) { - /* The same register variable. No need to copy */ - reg_stack[reg_sp++] = e5; - break; - } - default: - g_expr(e4); - emit_push(); - } - regs++; - } - if (env) { - /* change the frame pointer */ - g_expr(env); - printf("\tmovl %s,%%ebp\n",register_name(creg,0)); - } else if (fnptr->sc==FUNCTION) { - printf("\tlea %d(%%ebp),%%ebp\n",disp_offset); - } - /* force lvar offset mode to CODE */ - scode = fnptr->sc; fnptr->sc = CODE; -/* printf("## jump2 code_arg_offset=%d code_disp_offset=%d\n",code_arg_offset,code_disp_offset); */ - /* copy arguments to destination environment if necessary */ - nargs = reverse0(nargs); /* pop in normal order */ - i=0; - for (e3=nargs; e3;e3 =cadr(e3)) { - if ((e4=car(e3))<0) { - /* register case */ - if (reg_stack[--reg_sp]>=REG_ESI) { - /* the same registger */ - } else { - if(reg_stack[reg_sp]<0) { - printf("\tpopl %s\n",reg_name[rname[REG_ESI+i]]); /* e4? */ - } else { - printf("\tmovl %s,%s\n", - reg_name[rname[reg_stack[reg_sp]]], - reg_name[rname[REG_ESI+i]]); /* e4? */ - free_register(reg_stack[reg_sp]); - } - i++; - } - } else { - /* local variable case */ - if (reg_stack[reg_sp-1]== -2) { - /* same positioned variable */ - reg_sp--; - } else { - printf("\tmovl %s,%d(%%ebp)\n",register_name((xreg=emit_pop(0)),0), lvar(e4)); - } - } - } - free_register(xreg); - if (car(e2) != FNAME) { - xrn=register_name((xreg=emit_pop(0)),0); - } - free_register(xreg); - if (!env && new_disp+disp1>disp) { - /* shrink stack if necessary */ - printf("\tleal %d(%%ebp),%%esp\n",new_disp-size_of_int); - } - if (car(e2) == FNAME) { - printf("\tjmp %s\n",code0->nm); - } else { - printf("\tjmp *%s\n",xrn); - } - fnptr->sc = scode; -} -#endif - void machinop(int e1) {