diff mc-codegen.c @ 438:626d705471d5 lazy-branch

Unexecuted code in conditional. Lazy jmp code generation.
author kono
date Mon, 15 Nov 2004 20:33:30 +0900
parents 49d4483d5110
children 65e379ba36b8
line wrap: on
line diff
--- a/mc-codegen.c	Sun Nov 14 23:50:11 2004 +0900
+++ b/mc-codegen.c	Mon Nov 15 20:33:30 2004 +0900
@@ -132,6 +132,7 @@
 {
     int e2,e3,t,d,t1;
     NMTBL *n;
+    if (!control) return VOID;
 
     code_gexpr(e1);
 
@@ -427,7 +428,7 @@
 	    bexpr(cadr(e1),0,e2); // value used
 	}
 	t = code_get_fixed_creg(USE_CREG,d);
-	jmp(e3=fwdlabel());
+	gen_jmp(e3=fwdlabel());
 	fwddef(e2);
         t1=g_expr0(cadddr(e1));
 	code_set_fixed_creg(t,1,d);
@@ -539,12 +540,14 @@
 }
 
 /* bexpr for value unused */
+/*   l1 ... label for branch */
+/*   return 0 if l1 is not used, otherwise return l1 */
 
-extern void
+extern int
 bexpr_u(int e1, char cond, int l1)
 {
     int op = car(e1);
-    if (chk) return;
+    if (chk) return l1;
     // gexpr_init();
     switch(op) {
     case GT: case UGT: case GE: case UGE: case LT: 
@@ -555,45 +558,43 @@
         case EQ: case NEQ: case DOP+EQ: case DOP+NEQ:
 	if (car(caddr(e1))==CONST||(car(caddr(e1))==DCONST)||
 		car(caddr(e1))==FCONST) {
-	    b_expr(list3(rop_dual(op),caddr(e1),cadr(e1)),cond,l1,0);
-	    return;
+	    return b_expr(list3(rop_dual(op),caddr(e1),cadr(e1)),cond,l1,0);
 	}
     }
-    b_expr(e1,cond,l1,0);
+    return b_expr(e1,cond,l1,0);
 }
 
 /* bexpr for value used */
 
-extern void
+extern int
 bexpr(int e1, char cond, int l1)
 {
     int uses = use; use=1;
-    bexpr_u(e1, cond, l1);
+    l1 = bexpr_u(e1, cond, l1);
     use = uses;
+    return l1;
 }
 
 /* branch expression generator    */
 /*    if (cond?e1:!e1) goto  l1   */
 /* 1 or 0 is return for code_bool */
 
-extern void
+extern int
 b_expr(int e1, char cond, int l1,int err)
 {
     int e2,l2,t;
-    if (!control) return;
+    if (!control) return l1;
     l2 = 0;
     e2=cadr(e1);
     switch(car(e1)) {
     case LNOT:
-	b_expr(e2,!cond,l1,0);
-	return;
+	return b_expr(e2,!cond,l1,0);
     case GT: case GE: case LT: case LE:
     case EQ: case NEQ:
-	rexpr(e1,l1,cond,INT);
-	return;
+	return rexpr(e1,l1,cond,INT);
+	return l1;
     case UGT: case UGE: case ULT: case ULE:
-	rexpr(e1,l1,cond,UNSIGNED);
-	return;
+	return rexpr(e1,l1,cond,UNSIGNED);
 #if FLOAT_CODE
     case DOP+GT:
     case DOP+GE:
@@ -603,14 +604,12 @@
     case FOP+GE:
     case FOP+EQ:
     case FOP+NEQ:
-	drexpr(cadr(e1),caddr(e1),l1,car(e1),cond);
-	return;
+	return drexpr(cadr(e1),caddr(e1),l1,car(e1),cond);
     case FOP+LT:
     case FOP+LE:
     case DOP+LT:
     case DOP+LE:
-	drexpr(caddr(e1),cadr(e1),l1,rop_dual(car(e1)),cond);
-	return;
+	return drexpr(caddr(e1),cadr(e1),l1,rop_dual(car(e1)),cond);
 #endif
 #if LONGLONG_CODE
     case LOP+GT:
@@ -619,93 +618,94 @@
     case LOP+NEQ:
     case LOP+UGT:
     case LOP+UGE:
-	lrexpr(cadr(e1),caddr(e1),l1,car(e1),cond);
-	return;
+	return lrexpr(cadr(e1),caddr(e1),l1,car(e1),cond);
     case LOP+LT:
     case LOP+LE:
     case LOP+ULT:
     case LOP+ULE:
-	lrexpr(caddr(e1),cadr(e1),l1,rop_dual(car(e1)),cond);
-	return;
+	return lrexpr(caddr(e1),cadr(e1),l1,rop_dual(car(e1)),cond);
 #endif
     case LAND:
-	bexpr(e2,0,cond?(l2=fwdlabel()):l1);
-	bexpr_u(caddr(e1),cond,l1);
+	l2=bexpr(e2,0,cond?(l2=fwdlabel()):l1);
+	l1=bexpr_u(caddr(e1),cond,l1);
 	if(cond) fwddef(l2);
-	return;
+	return l1;
     case LOR:
-	bexpr(e2,1,cond?l1:(l2=fwdlabel()));
-	bexpr_u(caddr(e1),cond,l1);
+	l2=bexpr(e2,1,cond?l1:(l2=fwdlabel()));
+	l1=bexpr_u(caddr(e1),cond,l1);
 	if(!cond) fwddef(l2);
-	return;
+	return l1;
     case CRGVAR: case CURGVAR:
 	code_cmp_crgvar(e1,USE_CREG,1,l1,cond);
-	return;
+	return l1;
     case SRGVAR: case SURGVAR:
 	code_cmp_crgvar(e1,USE_CREG,size_of_short,l1,cond);
-	return;
+	return l1;
     case CRLVAR: case CURLVAR:
 	code_cmp_crlvar(e2,USE_CREG,1,l1,cond);
-	return;
+	return l1;
     case SRLVAR: case SURLVAR:
 	code_cmp_crlvar(e2,USE_CREG,size_of_short,l1,cond);
-	return;
+	return l1;
     case RGVAR:
 	code_cmp_rgvar(e1,USE_CREG,l1,cond);
-	return;
+	return l1;
     case RLVAR:
 	code_cmp_rlvar(e2,USE_CREG,l1,cond);
-	return;
+	return l1;
 #if FLOATC_DOE
     case DRLVAR:
 	code_cmp_drlvar(e2,USE_CREG,1,l1,cond);
-	return;
+	return l1;
     case FRLVAR:
 	code_cmp_drlvar(e2,USE_CREG,0,l1,cond);
-	return;
+	return l1;
     case DRGVAR:
 	code_cmp_drgvar(e2,USE_CREG,1,l1,cond);
-	return;
+	return l1;
     case FRGVAR:
 	code_cmp_drgvar(e2,USE_CREG,0,l1,cond);
-	return;
+	return l1;
     case FREGISTER:
 	code_cmp_dregister(e2,0,l1,cond);
-	return;
+	return l1;
     case DREGISTER:
 	code_cmp_dregister(e2,1,l1,cond);
-	return;
+	return l1;
     case DCONST:
     case FCONST:
-	if(control&&((dcadr(e2)!=0.0)^cond)) jmp(l1);
-	return;
+	if(control&&((dcadr(e2)!=0.0)^cond)) {
+	    gen_jmp(l1); return l1;
+	else return 0;
 #endif
 #if LONGLONG_DOE
     case LRLVAR:
 	code_cmp_lrlvar(e2,1,l1,cond);
-	return;
+	return l1;
     case LRGVAR:
 	code_cmp_lrgvar(e2,1,l1,cond);
-	return;
+	return l1;
     case LREGISTER:
 	code_cmp_lregister(e2,1,l1,cond);
-	return;
+	return l1;
     case LCONST:
-	if(control&&((lcadr(e2)!=0)^cond)) jmp(l1);
-	return;
+	if(control&&((lcadr(e2)!=0)^cond)) {
+	    gen_jmp(l1); return l1;
+	else return 0;
 #endif
     case REGISTER:
 	code_cmp_register(e2,l1,cond);
-	return;
+	return l1;
     case CONST:
-	if(control&&((cond&&e2)||(!cond&&!e2))) jmp(l1);
-	return;
+	if(control&&((cond&&e2)||(!cond&&!e2))) {
+	    gen_jmp(l1); return l1;
+	} else return 0;
     default:
 	if(err) {
-	    error(-1); return; /* recursive g_expr/b_expr */
+	    error(-1); return l1; /* recursive g_expr/b_expr */
 	}
 	t=g_expr(e1);
-	if (!use) return;
+	if (!use) return l1;
 	if (0) ;
 #if FLOAT_CODE
 	else if(t==FLOAT)
@@ -719,7 +719,7 @@
 #endif
 	else
 	    code_cmp_register(USE_CREG,l1,cond);
-	return;
+	return l1;
     }
 }
 
@@ -2214,9 +2214,23 @@
     return labelno++;
 }
 
+static void
+checkjmp(int l)
+{
+    if (pending_jmp) {
+	if (pending_jmp!=l) {
+	    jmp(pending_jmp);
+	    control=0;
+	}
+	pending_jmp=0;
+    }
+}
+
 extern void
 fwddef(int l)
 {       
+    if (l==0) return;
+    checkjmp(l);
     control=1;
     if (!chk)
 	code_label(l);
@@ -2225,6 +2239,7 @@
 extern int
 backdef(void)
 {       
+    checkjmp(0);
     control=1;
     if (!chk)
 	code_label(labelno);
@@ -2236,13 +2251,14 @@
 {
     int fl;
 
+    checkjmp(0);
     fl = 0;
     if (control) {
-	jmp(fl=fwdlabel());
+	gen_jmp(fl=fwdlabel());
     }
     fwddef(cslabel);
     if (dlabel)
-	jmp(dlabel);
+	gen_jmp(dlabel);
     if (fl) {
 	fwddef(fl);
     }
@@ -2252,7 +2268,7 @@
 ret(void)
 {       
     code_set_return_register(1);
-    jmp(retlabel); 
+    gen_jmp(retlabel); 
 }
 
 extern void
@@ -2894,12 +2910,14 @@
     if (cslabel==0) {
 	if (!control) error(-1); // no execute code in switch
 	jmp(cslabel=fwdlabel());
+	control=0;
     } else if (retpending) {
 	ret();
 	control=0;
 	retpending=0;
     }
     if (lastexp) {
+	if(!control) error(-1);
 	gexpr(lastexp,0);
 	lastexp = 0;
     }
@@ -3761,7 +3779,10 @@
 extern void
 gen_jmp(int l)
 {
-    jmp(l);
+    control=0;
+    if (!pending_jmp) {
+	pending_jmp = l;
+    }
 }
 
 extern void