changeset 52:ddaa1aa5b49b

parallel assignment done (not circular dependency)
author kono
date Mon, 17 Feb 2003 13:06:18 +0900
parents c2ef3a2fbe88
children 64a4e3789fd2
files Idea mc-nop-386.c
diffstat 2 files changed, 82 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- a/Idea	Sun Feb 16 22:21:23 2003 +0900
+++ b/Idea	Mon Feb 17 13:06:18 2003 +0900
@@ -1571,3 +1571,13 @@
 
 代入しなくて良いからと言って、ソース
 のリストから除いては、上書きを防げない。
+
+Sun Feb 16 22:55:58 JST 2003
+
+vdisp ってなんだったんだ?
+
+Mon Feb 17 12:35:39 JST 2003
+
+並列代入は出来たみたい。代入は小さいものを先にすべきなのか?
+まぁ、できりゃいいんだけど、横に避けるものが大きいのはいや
+だよね。
--- a/mc-nop-386.c	Sun Feb 16 22:21:23 2003 +0900
+++ b/mc-nop-386.c	Mon Feb 17 13:06:18 2003 +0900
@@ -117,7 +117,6 @@
 static int  creg;     /* current register */
 static int  dreg;     /* temporary register */
 static int  reg_sp;   /* REGister Stack-Pointer */
-static int  vdisp;
 
 
 #define REG_EAX   0
@@ -1029,26 +1028,28 @@
 }
 
 /* goto arguments list                                      */
-/* target         list4(list2(tag,disp),cdr,source_expr,ty) */
+/* target         list4(list2(tag,disp),cdr,ty,source_expr) */
 /*     source         expr=listn(tag,...)                   */
 /*     source (after) list2(tag,disp)                       */
-/* source list    list2(e,cdr)                              */
+/* source list    list3(e,cdr,sz)                           */
 
 int
-overrap(int t,int source)
+overrap(int t,int sz,int source)
 {
-    int s0,s1;
-    int t0=cadr(car(t));
-    int t1=size(caddr(t));
+    int s,s0,s1;
+    int t0=cadr(t);
+    int t1=t0+sz;
     for(;source;source=cadr(source)) {
-	s0=cadr(caddr(source));
-	if(car(car(source))==REGISTER && car(car(t))==REGISTER) {
+	s=car(source); s0=cadr(s); 
+	if(car(s)==REGISTER && car(t)==REGISTER) {
 	    if(s0==t0) return 1;
-	} else if (is_same_type(car(source),car(t))) {
-	    s1=s0+size(caddr(source));
+	} else if (is_same_type(s,t)) {
+	    s1=s0+caddr(source);
+#if 0
 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)));
+#endif
 	    if((t0<=s0&&s0<=t1)||(t0<=s1&&s1<=t1)) return 1;
 	}
     }
@@ -1063,6 +1064,9 @@
 	if (ce1) {
 	    if(car(ce1))
 		g_expr(car(ce1));
+#if 1
+printf("# post process ty %d+%d\n",cadr(car(ce1)),caddr(car(ce1)));
+#endif
 	    if(cadr(ce1)>=0) {
 		free_register(cadr(ce1));
 	    }
@@ -1078,13 +1082,23 @@
     while(*target) {
 	t=car(*target); s=cadddr(*target);
 	sz=size(ty=caddr(*target)); 
-printf("#0p type %d car(type) %d size %d\n",ty,car(ty),sz);
+	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);
+#endif
+            /*書き込み先が自分自身*/
+	    remove0(target,t);
+	    /* 破壊されては困るので、source listからは除かない */
+	    continue;
+	}
 	for(p=*processing;p;p=cadr(p)) {
 	    if(car(p)==t) { /*ターゲットが処理リスト中にある*/
 
 		/* どけてしまえば、もう関係ない。二度と処理する必要もない。*/
 		remove0(target,t); remove0(source,s); remove0(processing,p);
-
+#if 1
+printf("# circular dependcy %d ty %d+%d sz %d\n",car(t),ty,cadr(t),sz);
+#endif
 		/*新しいレジスタ(or スタック)を取得する*/
 		if (sz==size_of_int && (e1=get_register())!=-1) {
 		    e1=list2(REGISTER,e1);
@@ -1097,25 +1111,32 @@
 		}
 	    }
 	}
-	if(car(t)==car(s) && cadr(t)==cadr(s)) {
-            /*書き込み先が自分自身*/
-	    remove0(target,t);
-	} else if (overrap(*target,*source)) {
+	if (overrap(t,sz,*source)) {
 	    remove0(target,t);
 	    *processing=list2(t,*processing);
 	    e1=0;
-	    while (overrap(*target,*source)) {
+	    do {
 		/*書き込み先がソースと重なっているあいだ*/
-		/*他のを先にする*/
+		/*他のを先に処理する*/
+#if 1
+printf("# recursive%d %d ty %d+%d sz %d\n",e1,car(t),ty,cadr(t),sz);
+#endif
 		e1=list2(parallel_assign(target,source,processing),e1);
-	    }
-	    /* これで空いたはず*/
+	    } while (overrap(t,sz,*source));
+	    /* これで空いた */
+#if 1
+printf("# recursive%d done %d ty %d+%d sz %d\n",e1,car(t),ty,cadr(t),sz);
+#endif
+	    g_expr(assign_expr0(t,s,ty,ty));
 	    remove0(source,s);
 	    remove0(processing,t);
-	    g_expr(assign_expr0(t,car(s),ty,ty));
 	    /* 横によけたものがあれば、後始末をする*/
 	    parallel_assign_post(e1);
 	} else {
+	    /* 重なってないので安心して書き込める */
+#if 1
+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));
 	    remove0(target,t); remove0(source,s);
 	}
@@ -1171,6 +1192,17 @@
     );
 }
 
+int
+is_memory(int e1)
+{
+    int ce1=car(e1);
+    return (   
+         ce1==LVAR ||ce1==RLVAR||ce1==CRLVAR ||
+         ce1==GVAR ||ce1==RGVAR||ce1==CRGVAR ||
+         ce1==REGISTER
+    );
+}
+
 void
 jump(int e1, int env)
 {
@@ -1180,7 +1212,6 @@
     int target = 0;
     int source = 0;
     int processing = 0;
-    int sdisp = disp;
 
     /* まず、サイズを計算しながら、決まった形に落す。 */
     /* ここで、書込先アドレスを決める */
@@ -1188,7 +1219,6 @@
     arg_size = 0; regs = 0; max_regs = MAX_REGISTER_VAR-1;
     for (e3 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) {	
 	e2 = car(e3); sz = size(ty=caddr(e3)); 
-printf("#00 type %d car(type) %d size %d\n",ty,car(ty),sz);
 	if (regs <= max_regs&&integral(ty)) {
 	    target=list4(list2(REGISTER,virtual((regs++)+REG_ESI)),
 		target,ty,e2);
@@ -1197,6 +1227,9 @@
 		target,ty,e2);
 	    arg_size += sz;
 	}
+#if 1
+printf("# target %d ty %d+%d sz %d\n",car(car(target)),ty,cadr(car(target)),sz);
+#endif
     }
 
     /* disp を飛び先似合わせて修正 */
@@ -1212,24 +1245,25 @@
 
     for (e2 = target; e2; e2 = cadr(e2)) {	
 	t0=car(e2); s0=cadddr(e2);
+	sz=size(ty=caddr(e2));
 	if (!is_simple(car(s0))) {
-	    disp-=size(ty=caddr(e2));
+	    disp-=sz;
 	    g_expr(assign_expr0((e4=list2(LVAR,cvar(disp))),s0,ty,ty));
 	    cadddr(e2)=e4;
 	    s0=e4;
-#if 0
-	} else if (is_same_type(t0,s0)) {
-	    if(cadr(t0)==cadr(s0)) {
-		/* we should check size also (but currently useless */
-		remove0(&target,t0);
-		/* still we have to avoid overwrite */
+        } else if (is_same_type(t0,s0)) {
+            if(cadr(t0)==cadr(s0)) {
+                /* we should check size also (but currently useless */
+                remove0(&target,t0);
+                /* still we have source to avoid overwrite */
 	    }
-	} else {
-printf("#01 diffrent type t0: car(t0)=%d s0: car(s0)=%d\n",car(t0),car(s0));
+        }
+	if(is_memory(s0)) {
+	    source=list3(s0,source,sz);
+#if 1
+printf("# source %d ty %d+%d sz %d\n",car(car(source)),ty,cadr(car(source)),sz);
 #endif
 	}
-	source=list2(e4,source);
-printf("#01 type %d car(type) %d\n",ty,car(ty));
     }
 
     /* compute jump address */
@@ -1278,8 +1312,6 @@
 	printf("\tjmp *%s\n",register_name(e2,0));
 	emit_pop_free(e2);
     }
-    if (vdisp<disp) vdisp=disp;
-    disp=sdisp;
 }
 
 #if 0
@@ -1835,7 +1867,6 @@
 code_enter1(int args)
 {
     code_disp_label=fwdlabel();
-    vdisp = disp;
     printf("\tlea _%d(%%ebp),%%esp\n",code_disp_label);
     /*
     if(disp0) {
@@ -1848,7 +1879,7 @@
 void
 code_leave(char *name)
 {
-    printf("\t.set _%d,%d\n",code_disp_label,cvar(vdisp));
+    printf("\t.set _%d,%d\n",code_disp_label,cvar(disp));
     printf("_%d:\n",labelno);
     printf("\t.size\t%s,_%d-%s\n",name,labelno,name);
     local_table();
@@ -1858,7 +1889,6 @@
 void
 enter(char *name)
 {
-    vdisp = disp;
     printf("\t.align 2\n");
     if (stmode!=STATIC)
 	printf(".globl %s\n",name);
@@ -1875,7 +1905,6 @@
 void
 enter1()
 {
-    vdisp = disp;
     func_disp_label=fwdlabel();
     printf("\tlea _%d(%%ebp),%%esp\n",func_disp_label); 
     /* if(disp) printf("\tsubl $%d,%%esp\n",-disp); */
@@ -1896,14 +1925,14 @@
     }
     fwddef(retlabel);
     /* use_register(creg,REG_EAX,0); too late */
-    /* if(disp) printf("\taddl $%d,%%esp\n",-vdisp);  */
+    /* if(disp) printf("\taddl $%d,%%esp\n",-disp);  */
     printf("\tlea %d(%%ebp),%%esp\n",disp_offset);
     printf("\tpopl %%edi\n");
     printf("\tpopl %%esi\n");
     printf("\tpopl %%ebx\n");
     printf("\tleave\n");
     printf("\tret\n");
-    printf("\t.set _%d,%d\n",func_disp_label,vdisp+disp_offset);
+    printf("\t.set _%d,%d\n",func_disp_label,disp+disp_offset);
     printf("_%d:\n",labelno);
     printf("\t.size\t%s,_%d-%s\n",name,labelno,name);
     local_table();