changeset 552:74bbea56b8e5

inline scope with gcc extension passed.
author kono
date Thu, 05 Jan 2006 13:16:26 +0900
parents 73ebe9d82a9c
children 293f827ccfb2
files Changes mc-codegen.c mc-codegen.h mc-inline.c mc-parse.c test/inline.c
diffstat 6 files changed, 165 insertions(+), 60 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Wed Jan 04 14:55:46 2006 +0900
+++ b/Changes	Thu Jan 05 13:16:26 2006 +0900
@@ -7834,5 +7834,24 @@
 硬いなぁ。scope.c が全然通らない。このコンパイラも複雑すぎる。
 また、simple に戻すのをやらないといじれなくなってしまう。
 
-
-
+mode,stmode の関係が炸裂してるね。mode,stmode,ctmode と
+必要なのか。一つにできないの?
+
+
+あぁ、なるほど。local_table でstaticを出力するんだけど、こ
+のstatic は、inline で共有しないといけないわけね。別々にコ
+ードが生成されても単一のコードを呼ぶのと同じでないといけな
+いから。だから、毎回local_tableを出すのはまずい。
+使わないstaticのreferenceを出すわけにもいかない。
+local_table をinline code にいれるか?
+
+LLDECL は変。LDECL でtypeを見てやれば十分なはず。
+
+801             if (inmode && mode==LDECL) { 
+802                 parse = list4(ST_DECL,parse,(int)n,list2(stmode,ctmode));
+803             }
+
+こんな間違いしているし。
+
+inmode でも lastexp があるので、checkret は必要じゃん。
+
--- a/mc-codegen.c	Wed Jan 04 14:55:46 2006 +0900
+++ b/mc-codegen.c	Thu Jan 05 13:16:26 2006 +0900
@@ -34,7 +34,6 @@
 static int register_to_lvar(int e);
 static void remove0(int *parent,int e) ;
 static void sassign(int e1);
-static void checkjmp(int l);
 
 #if FLOAT_CODE
 
@@ -2848,10 +2847,11 @@
 	    n->dsp = ndsp;  /* emit_data will override this */
 	if (stmode==EXTRN)
 	    nsc = EXTRN;
-	else if (stmode==STATIC)
+	else if (stmode==STATIC||stmode==LDECL)
 	    nsc = STATIC;
 	n->sc = nsc;
 	if (stmode==LDECL) {
+	    // this means local static variable
 	    n = new_static_name(n->nm,'.');
 	    if (!n->next) {
 		n->next = local_static_list; local_static_list = n;
@@ -3344,7 +3344,7 @@
         t==UCHAR||t==SHORT||t==USHORT||t==ENUM);
 }
 
-static void
+extern void
 checkjmp(int l)
 {
     int p = pending_jmp;
--- a/mc-codegen.h	Wed Jan 04 14:55:46 2006 +0900
+++ b/mc-codegen.h	Thu Jan 05 13:16:26 2006 +0900
@@ -46,7 +46,7 @@
 extern void arg_register(NMTBL *fnptr);
 extern int bexpr(int e1, char cond, int l1);
 extern int bexpr_u(int e1, char cond, int l1);
-extern void checkret(void);
+extern void checkret(void);     // check delayed jump, delayed last exp
 extern void closing();
 extern void cmpdimm(int e, int csreg,int label,int cond);
 extern void codegen_decl_init(); /* called before each declaration */
@@ -77,7 +77,11 @@
 extern void gen_label_call(int l);
 extern void flush_delayed_decl_data(NMTBL *n);
 
-/* used by mc-cod-* */
+/* used by mc-inline */
+
+extern void checkjmp(int l);  // generate delayed jump, l = current label
+
+/* used by mc-code-* */
 
 extern int assign_expr0(int e1,int e2,int t,int type0) ;
 extern int b_expr(int e1, char cond, int l1,int err);
--- a/mc-inline.c	Wed Jan 04 14:55:46 2006 +0900
+++ b/mc-inline.c	Thu Jan 05 13:16:26 2006 +0900
@@ -306,10 +306,10 @@
     if (car(e1)==RINDIRECT) {
 	gen_indirect_goto(cadr(e1));
 	return ;
-    } else if (car(e1)==RLVAR||car(e1)==LVAR) {
+    } else if (car(e1)==RLVAR) {
 	gen_indirect_goto(e1);
 	return ;
-    } else if (car(e1)==FLABEL) {
+    } else if (car(e1)==LVAR||car(e1)==FLABEL) {
 	gen_jmp(cadr(e1));
         control=0;
         return ;
@@ -552,19 +552,27 @@
 static int
 p_decl(int e)
 {
-    // list4(ST_DECL,parse,(int)n,stmode);
-    int stmode=cadddr(e);
+    // list4(ST_DECL,parse,(int)n,list3(mode,stmode,ctmode));
+    int ctmode=cadddr(e);;
     NMTBL *n=(NMTBL*)caddr(e);
     int dsp = n->dsp;
     int v;
+    int sstmode = stmode;
+    int smode = mode;
     // in real partial evaluation, we have to check whether this variable
     // is used or not.
+    if (ctmode) {
+	mode = car(ctmode); stmode = cadr(ctmode); ctmode = caddr(ctmode);
+    }
     switch(stmode) {
     case EXTRN: case EXTRN1: case STATIC:
-	    // def(n,0); // ctmode?
-	    return pexpr(cadr(e));
-    case LLDECL:
-	v = list2(FLABEL,fwdlabel()); break;
+	// def(n,ctmode);      we don't need this. already done.
+	// stmode = sstmode;
+	stmode = sstmode;
+	mode = smode;
+	return pexpr(cadr(e));
+//    case LLDECL:          LLDECL is mode, not stmode (bad design)
+//	v = list2(FLABEL,fwdlabel()); break;
 #if 1
     case REGISTER:
 	switch(n->ty) {
@@ -583,11 +591,17 @@
 	break;
 #endif
     default:
-	v = list3(LVAR,new_lvar(size(n->ty)),(int)n);
+	if (n->sc==FLABEL)
+	    v = list3(LVAR,fwdlabel(),(int)n);
+	else
+	    v = list3(LVAR,new_lvar(size(n->ty)),(int)n);
     }
-    inline_lvars = glist2(v,inline_lvars);
+    if (n->sc!=FLABEL)
+	inline_lvars = glist2(v,inline_lvars);
     if (heap[pdisp+dsp]) error(-1);
     heap[pdisp+dsp]=v;
+    stmode = sstmode;
+    mode = smode;
     return pexpr(cadr(e));
 }
 
@@ -748,6 +762,7 @@
 	// should this done in p_decl? (in __label__?)
 	d = cadr(e);
 	if (!(e1=(heap[pdisp+d])))  {
+	    // error(-1);
 	    e1 = heap[pdisp+d]=list3(LVAR,fwdlabel(),caddr(e));
 	}
     }
@@ -1026,14 +1041,14 @@
     // these saved value should be some struct
     int sretlabel;
     NMTBL *sfnptr;
-    int svartable = pvartable;
-    int sretcont = retcont;
+    int svartable;
+    int sretcont;
     int scslabel = cslabel;
     int sdisp = pdisp;
-    int sret_register = ret_register;
-    int sret_reg_mode = ret_reg_mode;
-    int sinline_lvars = inline_lvars;
-    int slfree=lfree;
+    int sret_register;
+    int sret_reg_mode;
+    int sinline_lvars;
+    int slfree;
     // int slreg_count=lreg_count;
 
     int narg,arg;
@@ -1041,12 +1056,24 @@
     int e1 = attr_value(n,INLINE);
     int parse = car(e1);      // inline parse tree
     int arg_disp = cadr(e1);  // number of arguments
-    int e2,e3,t,e4,dots;
+    NMTBL *local_statics = (NMTBL*)cadddr(e1);  // local static list
+    int e2,e3,t,e4,e5,dots;
     int ret_type = function_type(cadddr(e),&dots);
     int fargtype;
     NMTBL *anptr;
 
-    // checkret();
+    checkret();
+    checkjmp(-1);
+
+    svartable = pvartable;
+    sretcont = retcont;
+    scslabel = cslabel;
+    sdisp = pdisp;
+    sret_register = ret_register;
+    sret_reg_mode = ret_reg_mode;
+    sinline_lvars = inline_lvars;
+    slfree=lfree;
+    // int slreg_count=lreg_count;
 
     sretlabel = retlabel;
     sfnptr = fnptr;
@@ -1068,8 +1095,12 @@
 
     /* inline function arguments */
     narg = 0;
-    for (e3 = e1 = reverse0(caddr(e)); e3; e3 = cadr(e3)) {
+    if (!fargtype) {
+	goto no_args;  // wrong number of arguments
+    }
+    for (e3 = e5 = reverse0(caddr(e)); e3; e3 = cadr(e3)) {
 	anptr = (NMTBL*)caddr(fargtype);
+	if (!anptr) break; // should not happen?
         t=caddr(e3);  // type
 	e4 = car(e3);
 	if (0 && is_const(e4) /* ||(is_memory(e3)&&is_readonly(e3)) */ ) {
@@ -1085,7 +1116,8 @@
 	narg ++;
 	fargtype = cadr(fargtype);
     }
-    caddr(e) = reverse0(e1);  // make it normal
+    caddr(e) = reverse0(e5);  // make it normal
+no_args:
     e2 = pexpr(parse);
     pdisp = sdisp;
     pvartable = svartable;
@@ -1101,6 +1133,13 @@
     if (retcont) error(STERR); // inline can't handle return/environment
 
     leave_scope();
+    if (local_statics && local_statics != &null_nptr) {
+	// append our local static variables to the parent list
+	n = local_statics;
+	while(n->next != &null_nptr) n=n->next;
+	n->next = local_static_list; local_static_list = local_statics;
+	cadddr(e1) = 0;  // prevent duplicate initialize
+    }
     while(inline_lvars) {
 	int e;
 	int l = car(inline_lvars);
--- a/mc-parse.c	Wed Jan 04 14:55:46 2006 +0900
+++ b/mc-parse.c	Thu Jan 05 13:16:26 2006 +0900
@@ -700,7 +700,7 @@
 		getsym(0);
 		conv->static_();
 		mode=STADECL;
-		stmode=LDECL;
+		stmode=LDECL;   // ...
 	} else if(mode==GDECL) {
 		getsym(0);
 		conv->static_();
@@ -798,8 +798,8 @@
     } else {
 	conv->return_type_(type,n,sd);
 	n = def(n,ctmode);
-	if (inmode && mode==LDECL) {
-	    parse = list4(ST_DECL,parse,(int)n,stmode);
+	if (inmode && (mode==LDECL||mode==LLDECL)) { 
+	    parse = list4(ST_DECL,parse,(int)n,list3(mode,stmode,ctmode));
 	}
 	if (sym==ASS && n!=&null_nptr) { 
 	    decl_data(type,n,0,0); data_closing(n); 
@@ -818,7 +818,7 @@
 	    conv->return_type_(type,n,1);
 	    def(n,ctmode);
 	    if (inmode && mode==LDECL) {
-		parse = list4(ST_DECL,parse,(int)n,stmode);
+		parse = list4(ST_DECL,parse,(int)n,list3(mode,stmode,ctmode));
 	    }
 	    if (sym==ASS && n!=&null_nptr) {
 		decl_data(type,n,0,0);data_closing(n);
@@ -1833,7 +1833,9 @@
 
     conv->function_end_(); conv->rc_();
     if (inmode) {
-	set_attr(n,INLINE,list3(reverse0(parse),arg_disp,disp)); parse = 0;
+	set_attr(n,INLINE,
+	    list4(reverse0(parse),arg_disp,disp,(int)local_static_list)); 
+	parse = 0;
 	inline_funcs = list2((int)n,inline_funcs);
     } else {
 	if(!chk) gen_leave(control,n->nm);
@@ -2034,27 +2036,27 @@
     checksym(LPAR);
     conv->if_();
     slfree=lfree;
+    checkret();
     if (inmode) {
 	pparse = parse; parse = 0;
 	l1 = expr(0);
     } else {
-	checkret();
 	l1 = bexpr(expr(0),0,fwdlabel());
     }
     set_lfree(slfree);
     conv->if_then_();
     checksym(RPAR);
     statement(0);
+    checkret();
     if (inmode) {
 	l2 = reverse0(parse); parse = 0;
-    } else {
-	checkret();
     }
     if(sym==ELSE) {
 	conv->if_else_();
 	if (inmode) {
 	    getsym(0);
 	    statement(0);
+	    checkret();
 	    parse = list3(ST_IF,pparse,list3(l1,l2,reverse0(parse)));
 	} else {
 	    if ((l2 = control))
@@ -2083,6 +2085,7 @@
     sbreak=blabel;
     scontinue=clabel;
     if (inmode) {
+	checkret();
 	pparse = parse; parse=0;
     } else {
 	blabel=fwdlabel();
@@ -2112,10 +2115,10 @@
 	}
 	set_lfree(slfree);
 	statement(0);
+	checkret();
 	if (inmode) {
 	    parse = list4(ST_WHILE,pparse,e,reverse0(parse));
 	} else {
-	    checkret();
 	    if(control)
 		gen_jmp(clabel);
 	}
@@ -2135,6 +2138,7 @@
     sbreak=blabel;
     scontinue=clabel;
     if (inmode) {
+	checkret();
 	pparse = parse; parse = 0;
     } else {
 	blabel=fwdlabel();
@@ -2146,10 +2150,10 @@
     conv->dowhile_();
     getsym(0);
     statement(0);
+    checkret();
     if (inmode) {
 	l = reverse0(parse); parse =0;
     } else {
-	checkret();
 	fwddef(clabel);
     }
     checksym(WHILE);
@@ -2199,18 +2203,17 @@
 	lfree_type_limit = lfree;
 	decl();
 	mode=STAT;
+	checkret();
+	emit_init_vars();
 	if (inmode) {
 	    p0 = reverse0(parse); parse = 0;
-	} else {
-	    checkret();
 	}
-	emit_init_vars();
 	getsym(0);
     } else if(sym!=SM) {
+	checkret();
 	if (inmode) {
 	    p0 = expr(0);
 	} else {
-	    checkret();
 	    gexpr(expr(0),0);
 	}
 	checksym(SM);
@@ -2222,8 +2225,8 @@
     }
     set_lfree(slfree);
     control=1;
+    checkret();
     if (!inmode) {
-	checkret();
 	l=backdef();
     }
     if(sym!=SM) {
@@ -2245,10 +2248,9 @@
 	conv->for_body_();
 	getsym(0);
 	statement(0);
+	checkret();
 	if (inmode) {
 	    e = 0;
-	} else {
-	    checkret();
 	}
     } else {
 	clabel=fwdlabel();
@@ -2256,8 +2258,8 @@
 	conv->for_body_();
 	checksym(RPAR);
 	statement(0);
+	checkret();
 	if (!inmode) {
-	    checkret();
 	    fwddef(clabel);
 	    gexpr(e,0);
 	}
@@ -2268,6 +2270,7 @@
     conv->for_end_();
     if (inmode) {
 	parse = list3(ST_FOR,pparse,list4(p0,p1,e,reverse0(parse)));
+	// parse = list3(ST_FOR,pparse,list4(p0,p1,e,parse));
     } else {
 	gen_jmp(l);
 	fwddef(blabel);
@@ -2285,11 +2288,11 @@
 {
     int slimit = lfree_type_limit ;
     int sinit_vars = init_vars;
-    int pparse = parse;
+//    int pparse = parse;
     conv->lc_();
-    if (inmode) {
-	parse = 0;
-    }
+//    if (inmode) {
+//	parse = 0;
+//    }
     local_decl();
     emit_init_vars();
     lfree_type_limit = lfree;
@@ -2298,9 +2301,9 @@
     lfree_type_limit = slimit; 
     init_vars = sinit_vars;
     leave_scope();
-    if (inmode) {
-	parse = list3(ST_COMP,pparse,reverse0(parse));
-    }
+//    if (inmode) {
+//	parse = list3(ST_COMP,pparse,reverse0(parse));
+//    }
     getsym(0);
 }
 
@@ -2314,10 +2317,9 @@
     int sbreak,scase,sdefault,slfree,svalue,slist;
     int pparse = parse,v;
 
+    checkret();
     if (inmode) {
 	parse = 0;
-    } else {
-	checkret();
     }
     if (!inmode) {
 	slist = cslist;
@@ -2365,10 +2367,10 @@
     */
     statement(0);
     conv->switch_end_();
+    checkret();
     if (inmode) {
 	parse = list4(ST_SWITCH,pparse,v,reverse0(parse));
     } else {
-	checkret();
 #if CASE_CODE
 	if (control) gen_jmp(blabel);
 	genswitch(cslist,cslabel);
@@ -3479,7 +3481,7 @@
 	    if (inmode) {
 		int sparse = parse; parse=0;
 		docomp(1);
-		e1 = list3(COMMA,parse,lastexp);
+		e1 = list3(COMMA,reverse0(parse),lastexp);
 		parse = sparse;
 		lastexp = 0;
 	    } else {
@@ -4296,6 +4298,7 @@
 	ret->ty = 0;
 	ret->dsp = 0;
 	ret->attr = 0;
+	ret->next = 0;
 	return ret;
     }
     if (nptr_pool->ptr >= nptr_pool->last) {
@@ -4314,6 +4317,7 @@
     ret->ty = 0;
     ret->dsp = 0;
     ret->attr = 0;
+    ret->next = 0;
     return ret;
 }
 
@@ -4435,7 +4439,7 @@
     scope = car(current_scope);
     while(scope) {
 	ns = (NMTBL *)caddr(car(scope));
-	if (ns->sc != GVAR && !inmode) free_nptr(ns);
+	if (ns->sc != GVAR && ns->sc != STATIC && !inmode) free_nptr(ns);
 	caddr(car(scope)) = caddr(scope);
 	next = cadr(scope);
 	free_glist2(scope); // will destroy cadr
--- a/test/inline.c	Wed Jan 04 14:55:46 2006 +0900
+++ b/test/inline.c	Thu Jan 05 13:16:26 2006 +0900
@@ -9,8 +9,27 @@
 volatile const int i = 3;
 
 extern int printf(char *,...);
+inline int
+main0()
+{
+    volatile const int j = 3;
+    switch(i) {
+    case 1: printf("#0016:1\n"); break;
+    case 2: printf("#0017:2\n"); break;
+    case 3: printf("#0018:3\n"); break;
+    case 4: printf("#0019:4\n"); break;
+    }
+    switch(j) {
+    case 1: printf("#0022:1\n"); break;
+    case 2: printf("#0023:2\n"); break;
+    case 3: printf("#0024:3\n"); break;
+    case 4: printf("#0025:4\n"); break;
+    }
+    return 0;
+}
+
 int
-main0()
+main1()
 {
     volatile const int j = 3;
     switch(i) {
@@ -61,22 +80,40 @@
 inline __attribute__((always_inline)) int in2(int p,int i,int j)
 {
     int k = -20,m;
+    int order=1;
     do {
+	order <<= 4; order|=0;
 	k += 3;
+	order <<= 4; order|=7;
     } while ( k < j);
-    printf("#0066: %d do %d\n",p,k);
+    printf("#0066: %d do %d %x\n",p,k,order);
 
     while (k > j) {
+	order <<= 4; order|=0;
 	k -= 3;
+	order <<= 4; order|=7;
     } 
-    printf("#0071: %d while %d\n",p,k);
+    printf("#0071: %d while %d %x\n",p,k,order);
 
     m = 0;
     for(k=0;k<j;k++) {
+	order <<= 4; order|=0;
 	m += k;
+	order <<= 4; order|=7;
+	if (k&1) {
+	    order <<= 4; order|=0;
+	    m += k;
+	    order <<= 4; order|=7;
+	} else {
+	    order <<= 4; order|=5;
+	    m += k;
+	    order <<= 4; order|=10;
+	}
+	printf("#0077: %x\n",order);
     }
     printf("#0077: %d for %d\n",p,m);
 
+
     switch(i) {
     case 1: k = 1;
 	break;
@@ -183,6 +220,7 @@
 main(int ac,char *av[])
 {
      fnp = ins1;
+     printf("%d\n",(1,2,3,4,5));
      order(1,2,3,4,5);
      order1p(1,2,3,4,5);
      a0(5,6);
@@ -190,6 +228,7 @@
      fnp3 = in2;
      a1(9,10);
      main0(ac,av);
+     main1(ac,av);
      inmain(ac,av);
      return 0;
 }