Mercurial > hg > CbC > old > device
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; }