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)
 {