changeset 55:94564b45c4f3

all save implementation of parallel assignment
author kono
date Wed, 19 Feb 2003 10:34:54 +0900
parents 1a6b6a7bdca6
children 5aa4528b6983
files .gdbinit Idea mc-nop-386.c mc-parse.c test/arg.c
diffstat 5 files changed, 85 insertions(+), 85 deletions(-) [+]
line wrap: on
line diff
--- a/.gdbinit	Tue Feb 18 20:34:46 2003 +0900
+++ b/.gdbinit	Wed Feb 19 10:34:54 2003 +0900
@@ -14,4 +14,4 @@
 end
 b error
 b errmsg
-r -s test/fact-a.c
+r -s test/arg.c
--- a/Idea	Tue Feb 18 20:34:46 2003 +0900
+++ b/Idea	Wed Feb 19 10:34:54 2003 +0900
@@ -1608,3 +1608,5 @@
 って、きっと return 文がないと、文句を
 言われるよね。むむむ。
 
+post processing する時にoverrapしてないという保証がない。
+
--- a/mc-nop-386.c	Tue Feb 18 20:34:46 2003 +0900
+++ b/mc-nop-386.c	Wed Feb 19 10:34:54 2003 +0900
@@ -39,7 +39,7 @@
 static void    text_mode(void);
 static void assign(int e1);
 static void assop(int e1);
-static void b_expr(int e1, char cond, int l1);
+static void b_expr(int e1, char cond, int l1,int err);
 static void emit_push(void);
 static void free_register(int i);
 static void function(int e1);
@@ -73,6 +73,7 @@
 extern int scalar(int);
 extern int reverse0(int);
 extern void remove0(int *list,int element); 
+extern int append4(int target,int t,int ty,int e1);
 
 #define TEXT_EMIT_MODE 0
 #define DATA_EMIT_MODE 1
@@ -663,7 +664,7 @@
 	return;
     case COND:
 	e2=fwdlabel();
-	b_expr(cadr(e1),0,e2);
+	b_expr(cadr(e1),0,e2,0);
 	use_register(creg,REG_EAX,0);
 	g_expr(caddr(e1));
 	/* e4 = rname[creg]; this is a bad idea */
@@ -704,7 +705,7 @@
 	regv[creg]=1;
 	return;
     default:
-	b_expr(e1,1,e2=fwdlabel());  /* including > < ... */
+	b_expr(e1,1,e2=fwdlabel(),1);  /* including > < ... */
 	xrn = register_name(creg,0);
 	printf("\txorl %s,%s\n",xrn,xrn);
 	jmp(e3=fwdlabel());
@@ -719,18 +720,18 @@
 bexpr(int e1, char cond, int l1)
 {
     gexpr_init();
-    b_expr(e1,cond,l1);
+    b_expr(e1,cond,l1,0);
 }
 
 void
-b_expr(int e1, char cond, int l1)
+b_expr(int e1, char cond, int l1,int err)
 {
     int e2,l2;
     if (chk) return;
     e2=cadr(e1);
     switch(car(e1)) {
     case LNOT:
-	b_expr(e2,!cond,l1);
+	b_expr(e2,!cond,l1,0);
 	return;
     case GT:
 	rexpr(e1,l1,cond?"g":"le");
@@ -763,13 +764,13 @@
 	rexpr(e1,l1,cond?"ne":"e");
 	return;
     case LAND:
-	b_expr(e2,0,cond?(l2=fwdlabel()):l1);
-	b_expr(caddr(e1),cond,l1);
+	b_expr(e2,0,cond?(l2=fwdlabel()):l1,0);
+	b_expr(caddr(e1),cond,l1,0);
 	if(cond) fwddef(l2);
 	return;
     case LOR:
-	b_expr(e2,1,cond?l1:(l2=fwdlabel()));
-	b_expr(caddr(e1),cond,l1);
+	b_expr(e2,1,cond?l1:(l2=fwdlabel()),0);
+	b_expr(caddr(e1),cond,l1,0);
 	if(!cond) fwddef(l2);
 	return;
     case CRGVAR:
@@ -796,6 +797,9 @@
 	if((cond&&e2)||(!cond&&!e2)) jmp(l1);
 	return;
     default:
+	if(err) {
+	    error(-1); return; /* recursice g_expr/b_expr */
+	}
 	g_expr(e1);
 	printf("\tcmpl $0,%s\n",register_name(creg,0));
 	jcond(l1,cond);
@@ -1051,33 +1055,45 @@
 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;
+	    if((t0<=s0&&s0<t1)||(t0<s1&&s1<=t1)) return s;
 	}
     }
     return 0;
 }
 
 void
-parallel_assign_post(int e1) {
-    int ce1;
-    while(e1) {
-	ce1=car(e1);
-	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));
-	    }
+remove_target(int *target,int t,int *use)
+{
+    int use0=*use;
+    while(use0) {
+	if (car(use0)==t) {
+	    free_register(caddr(use0));
+	    break;
 	}
-	e1=cadr(e1);
+	use0 = cadr(use0);
+    }
+    remove0(target,t);
+}
+
+void
+save_target(int t,int s,int *target,int *use,int sz,int ty)
+{
+    int e1;
+    /*新しいレジスタ(or スタック)を取得する*/
+    if (sz==size_of_int && (e1=get_register())!=-1) {
+	*use=list3(t,*use,e1);
+	e1=list2(REGISTER,e1);
+	g_expr(assign_expr0(e1,s,ty,ty));
+	*target = append4(*target,t,ty,e1);
+    } else {
+	disp-=sz;
+	g_expr(assign_expr0((e1=list2(LVAR,disp)),s,ty,ty));
+	*target = append4(*target,t,ty,e1);
     }
 }
 
-int
-parallel_assign(int *target,int *source,int *processing)
+void
+parallel_assign(int *target,int *source,int *processing,int *use)
 {
     int t,s,e1,p,sz,ty;
     while(*target) {
@@ -1088,61 +1104,23 @@
 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);
+	    remove_target(target,t,use);
 	    /* 破壊されては困るので、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);
-		    g_expr(assign_expr0(e1,s,ty,ty));
-		    return list2(assign_expr0(t,e1,ty,ty),e1);
-		} else {
-		    disp-=sz;
-		    g_expr(assign_expr0((e1=list2(LVAR,disp)),s,ty,ty));
-		    return list2(assign_expr0(t,e1,ty,ty),-1);
-		}
-	    }
-	}
-	if (overrap(t,sz,*source)) {
-	    remove0(target,t);
-	    *processing=list2(t,*processing);
-	    e1=0;
-	    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);
-	    /* 横によけたものがあれば、後始末をする*/
-	    parallel_assign_post(e1);
-	} else {
+	} else if (!(overrap(t,sz,*source))) {
 	    /* 重なってないので安心して書き込める */
 #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);
+	    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);
+#endif
+	    remove_target(target,t,use); remove0(source,s);
+	    save_target(t,s,target,use,sz,ty);
 	}
     }
-    return 0;
 }
 
 void 
@@ -1213,6 +1191,7 @@
     int target = 0;
     int source = 0;
     int processing = 0;
+    int use = 0;
 
     /* まず、サイズを計算しながら、決まった形に落す。 */
 
@@ -1291,10 +1270,11 @@
 
     /* 並列代入を実行 */
 
-    e1=parallel_assign(&target,&source,&processing);
-
-    /* 後始末が残っていた */
-    parallel_assign_post(e1);
+    parallel_assign(&target,&source,&processing,&use);
+    while (use) {
+	free_register(caddr(use)); use=cadr(use);
+    }
+    if(target) error(-1);
 
     if (env) {
 	/* change the frame pointer */
@@ -1867,7 +1847,6 @@
 	printf(".globl %s\n",name);
     printf("\t.type\t%s,@function\n",name);
     printf("%s:\n",name);
-    free_all_register();
 }
 
 void
@@ -1887,6 +1866,7 @@
     printf("\t.size\t%s,_%d-%s\n",name,labelno,name);
     local_table();
     labelno++;
+    free_all_register();
 }
 
 void
@@ -1902,7 +1882,6 @@
     printf("\tpushl %%ebx\n");
     printf("\tpushl %%esi\n");
     printf("\tpushl %%edi\n");
-    free_all_register();
 }
 
 void
@@ -1940,6 +1919,7 @@
     printf("\t.size\t%s,_%d-%s\n",name,labelno,name);
     local_table();
     labelno++;
+    free_all_register();
 }
 
 
--- a/mc-parse.c	Tue Feb 18 20:34:46 2003 +0900
+++ b/mc-parse.c	Wed Feb 19 10:34:54 2003 +0900
@@ -96,6 +96,7 @@
 static void replace_return_struct(int func,int left);
 static void fdecl_struct(int type);
 static int append3(int p,int a1,int a2);
+extern int append4(int p,int a1,int a2,int a3);
 
 extern void display_ntable(NMTBL *n, char *s);
 extern void closing(void);
@@ -3235,6 +3236,17 @@
 }
 
 int
+append4(int p,int a1,int a2,int a3)
+{
+    int p1;
+    if(!p) return list4(a1,0,a2,a3);
+    p1=p;
+    while(cadr(p)) p = cadr(p);
+    rplacad(p,list4(a1,0,a2,a3));
+    return p1;
+}
+
+int
 append3(int p,int a1,int a2)
 {
     int p1;
--- a/test/arg.c	Tue Feb 18 20:34:46 2003 +0900
+++ b/test/arg.c	Wed Feb 19 10:34:54 2003 +0900
@@ -4,7 +4,13 @@
    int a0;int a1;int a2;int a3;int a4;
 };
 
-code arg1(int arg0,int arg1,int arg2,int arg3,int arg4,code(*exit1)(),void *env)
+code carg1(int arg0,int arg1,int arg2,int arg3,int arg4,code(*exit1)(),void *env)
+{
+    printf("arg1: %d %d %d %d %d : %x %x\n",arg0,arg1,arg2,arg3,arg4,exit1,env);
+    goto carg2(arg1,arg2,arg3,arg4,arg0,exit1,env);
+}
+
+code carg2(int arg0,int arg1,int arg2,int arg3,int arg4,code(*exit1)(),void *env)
 {
     struct arg args0;
     printf("arg1: %d %d %d %d %d : %x %x\n",arg0,arg1,arg2,arg3,arg4,exit1,env);
@@ -13,10 +19,10 @@
     args0.a2 = arg2;
     args0.a3 = arg3;
     args0.a4 = arg4;
-    goto args(args0,exit1,env);
+    goto cargs(args0,exit1,env);
 }
 
-code args(struct arg args0,code exit1(),void *env)
+code cargs(struct arg args0,code exit1(),void *env)
 {
     printf("args: %d %d %d %d %d : %x %x\n",
 	args0.a0,args0.a1,args0.a2,args0.a3,args0.a4,
@@ -27,7 +33,7 @@
 
 int main1(int n)
 {
-    goto arg1(0,1,2,3,4,return,environment);
+    goto carg1(0,1,2,3,4,return,environment);
     return n;
 }