Mercurial > hg > CbC > old > device
changeset 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 |
files | Changes Makefile mc-code-arm.c mc-code-ia32.c mc-code-mips.c mc-code-powerpc.c mc-code.h mc-codegen.c mc-codegen.h mc-parse.c mc-parse.h test/void_code.c |
diffstat | 12 files changed, 177 insertions(+), 98 deletions(-) [+] |
line wrap: on
line diff
--- a/Changes Sun Nov 14 23:50:11 2004 +0900 +++ b/Changes Mon Nov 15 20:33:30 2004 +0900 @@ -6638,7 +6638,31 @@ (1) make inline tree (2) evaluate inline function (copy and partial evaluation) - - - - + peval(inline_func,args) + similar to the function call (with type check) + + const いるのかなあ。 + builtin_constant_p かぁ。 + +Mon Nov 15 17:37:57 JST 2004 + +code hoge() { a; } +code hoge1() { b; } + +では、a-> b に、そのまま落ちるべきだろうね。ファイルが分離される +場合は少し困るが.... + +if (0) hoge; でhogeが生成されてしまう。control で切っても出るね。 +いや、消えてました。ただ、jmp は生成されてしまうね。checkret +で、チェックするべきでしょう。 + +checkret は、control が生成されるところで呼ばれるわけだから、本来は +control=1 にするのは、checkret だけであるべき。 + jmp(hoge) は、pending_jmp +を設定して、checkret で、pending_jmp を生成するわけだが。 +で、pending jmp が設定したlabelに等しければ、pending_jmp は0に +設定される(しかしreferenceされたかも知れないからlabelは生成する?) +label にreferenceしたかどうかのflagを付けた方が良い? + +if (1) hoge else fuga ; で fuga が生成されてしまう。bexpr で +always jump かどうかを返したいところだが...
--- a/Makefile Sun Nov 14 23:50:11 2004 +0900 +++ b/Makefile Mon Nov 15 20:33:30 2004 +0900 @@ -88,6 +88,7 @@ make check TARGET=test/bitfield1 make check TARGET=test/cext make check TARGET=test/const + make check TARGET=test/void_code # make check TARGET=test/scope STDFLAG="-std=gnu99" #MK =-make MK=
--- a/mc-code-arm.c Sun Nov 14 23:50:11 2004 +0900 +++ b/mc-code-arm.c Mon Nov 15 20:33:30 2004 +0900 @@ -3185,7 +3185,7 @@ return 1; } -void +int rexpr(int e1, int l1, int cond,int t) { int e2; @@ -3197,6 +3197,7 @@ e2 = emit_pop(1); pcond(op, ireg,e2,0,cond,l1,COND_BRANCH); emit_pop_free(e2); + return l1; } #define CMP_C1T (-1) @@ -3212,7 +3213,6 @@ void jmp(int l) { - control=0; if (chk) return; printf("\tb\t.L%d\n",l); inc_inst(1); @@ -4745,7 +4745,7 @@ } -void +int drexpr(int e1, int e2,int l1, int op,int cond) { int op1; @@ -4753,17 +4753,17 @@ if (!cond) { switch(op) { case FOP+GT: - drexpr(e2,e1,l1,FOP+GE,1); return; + return drexpr(e2,e1,l1,FOP+GE,1); case FOP+GE: - drexpr(e2,e1,l1,FOP+GT,1); return; + return drexpr(e2,e1,l1,FOP+GT,1); case FOP+EQ: op=FOP+NEQ; break; case FOP+NEQ: op=FOP+EQ; break; case DOP+GT: - drexpr(e2,e1,l1,DOP+GE,1); return; + return drexpr(e2,e1,l1,DOP+GE,1); case DOP+GE: - drexpr(e2,e1,l1,DOP+GT,1); return; + return drexpr(e2,e1,l1,DOP+GT,1); case DOP+EQ: op=DOP+NEQ; break; case DOP+NEQ: @@ -4784,6 +4784,7 @@ g_expr(list3(op1,e2,e1)); inc_inst(1); printf("\t%s\t.L%d\n",opn,l1); + return l1; } int emit_dpop(int d) @@ -4836,7 +4837,7 @@ return 0; } -void +int lrexpr(int e1, int e2,int l1, int op,int cond) { int reg,regh,regl,e3h,e3l; @@ -4871,6 +4872,7 @@ pcond(op%LOP,regl,e3l,0,cond,l1,COND_BRANCH); fwddef(l2); emit_lpop_free(e3); + return l1; } int
--- a/mc-code-ia32.c Sun Nov 14 23:50:11 2004 +0900 +++ b/mc-code-ia32.c Mon Nov 15 20:33:30 2004 +0900 @@ -1783,11 +1783,12 @@ return 1; } -void +int rexpr(int e1, int l1, int cond,int t) { g_expr(list3(CMP,cadr(e1),caddr(e1))); printf("\tj%s\t_%d\n",code_cond(car(e1),cond),l1); + return l1; } @@ -1801,7 +1802,6 @@ void jmp(int l) { - control=0; if (chk) return; printf("\tjmp\t_%d\n",l); /* align? */ @@ -2432,6 +2432,8 @@ #define COND_BRANCH 1 #define COND_VALUE 2 +/* return 1 if boolean expression */ + int drexpr0(int e1, int e2,int l1, int op,int cond,int reg,int mode) { @@ -2496,10 +2498,11 @@ return 1; } -void +int drexpr(int e1, int e2,int l1, int op,int cond) { drexpr0(e1, e2,l1, op,cond,USE_CREG,COND_BRANCH); + return l1; } static int @@ -2618,7 +2621,7 @@ printf("\tj%s\t_%d\n",s,l1); } -void +int lrexpr(int e1, int e2,int l1, int op,int cond) { int l2; @@ -2662,6 +2665,7 @@ case LOP+UGE: pcond(code_uge(cond), l1); break; } fwddef(l2); + return l1; } int emit_lpop()
--- a/mc-code-mips.c Sun Nov 14 23:50:11 2004 +0900 +++ b/mc-code-mips.c Mon Nov 15 20:33:30 2004 +0900 @@ -2827,7 +2827,7 @@ return 1; } -void +int rexpr(int e1, int l1, int cond,int t) { int e2; @@ -2839,6 +2839,7 @@ e2 = emit_pop(1); pcond(op, e2,e2,ireg,cond,l1,COND_BRANCH); emit_pop_free(e2); + return l1; } #define CMP_C1T (-1) @@ -2856,7 +2857,6 @@ void jmp(int l) { - control=0; if (chk) return; printf("\tj\t$L_%d\n",l); } @@ -4149,24 +4149,24 @@ } } -void +int drexpr(int e1, int e2,int l1, int op,int cond) { int op1; if (!cond) { switch(op) { case FOP+GT: - drexpr(e2,e1,l1,FOP+GE,1); return; + return drexpr(e2,e1,l1,FOP+GE,1); case FOP+GE: - drexpr(e2,e1,l1,FOP+GT,1); return; + return drexpr(e2,e1,l1,FOP+GT,1); case FOP+EQ: op=FOP+NEQ; break; case FOP+NEQ: op=FOP+EQ; break; case DOP+GT: - drexpr(e2,e1,l1,DOP+GE,1); return; + return drexpr(e2,e1,l1,DOP+GE,1); case DOP+GE: - drexpr(e2,e1,l1,DOP+GT,1); return; + return drexpr(e2,e1,l1,DOP+GT,1); case DOP+EQ: op=DOP+NEQ; break; case DOP+NEQ: @@ -4195,6 +4195,7 @@ case FOP+EQ: printf("\tbc1t\t$L_%d\n",l1);break; case FOP+NEQ: printf("\tbc1f\t$L_%d\n",l1);break; } + return l1; } int emit_dpop(int d) @@ -4279,7 +4280,7 @@ } #endif -void +int lrexpr(int e1, int e2,int l1, int op,int cond) { int reg,regh,regl,e3h,e3l; @@ -4317,6 +4318,7 @@ fwddef(l2); if (cr0!=-1) free_register(cr0); emit_lpop_free(e3); + return l1; } #if 0
--- a/mc-code-powerpc.c Sun Nov 14 23:50:11 2004 +0900 +++ b/mc-code-powerpc.c Mon Nov 15 20:33:30 2004 +0900 @@ -2653,7 +2653,7 @@ return 1; } -void +int rexpr(int e1, int l1, int cond,int t) { char *s; @@ -2682,6 +2682,7 @@ } g_expr(list3((t==INT?CMP:UCMP),cadr(e1),caddr(e1))); printf("\tb%s cr%d,L_%d\n",s,cmpflag,l1); + return l1; } static void @@ -2698,7 +2699,6 @@ void jmp(int l) { - control=0; if (chk) return; printf("\tb\tL_%d\n",l); } @@ -3784,23 +3784,23 @@ return 1; } -void +int drexpr(int e1, int e2,int l1, int op,int cond) { if (!cond) { switch(op) { case FOP+GT: - drexpr(e2,e1,l1,FOP+GE,1); return; + return drexpr(e2,e1,l1,FOP+GE,1); case FOP+GE: - drexpr(e2,e1,l1,FOP+GT,1); return; + return drexpr(e2,e1,l1,FOP+GT,1); case FOP+EQ: op=FOP+NEQ; break; case FOP+NEQ: op=FOP+EQ; break; case DOP+GT: - drexpr(e2,e1,l1,DOP+GE,1); return; + return drexpr(e2,e1,l1,DOP+GE,1); case DOP+GE: - drexpr(e2,e1,l1,DOP+GT,1); return; + return drexpr(e2,e1,l1,DOP+GT,1); case DOP+EQ: op=DOP+NEQ; break; case DOP+NEQ: @@ -3822,6 +3822,7 @@ printf("\tbne\tcr%d,L_%d\n",cmpflag,l1); break; } + return l1; } int emit_dpop(int d) @@ -3897,7 +3898,7 @@ } } -void +int lrexpr(int e1, int e2,int l1, int op,int cond) { int reg; @@ -3971,6 +3972,7 @@ } fwddef(l2); emit_lpop_free(e3); + return l1; } int
--- a/mc-code.h Sun Nov 14 23:50:11 2004 +0900 +++ b/mc-code.h Mon Nov 15 20:33:30 2004 +0900 @@ -109,7 +109,7 @@ extern void tosop(int op,int reg,int oreg); extern void code_opening(char *filename); extern void code_closing(); -extern void rexpr(int e1, int l1, int cond,int t); +extern int rexpr(int e1, int l1, int cond,int t); extern void jmp(int l); extern int code_get_fixed_creg(int reg,int type); extern void code_set_fixed_creg(int reg,int mode,int type); @@ -143,7 +143,7 @@ #if FLOAT_CODE /* floating point part */ -extern void drexpr(int e1, int e2,int l1, int op,int cond); +extern int drexpr(int e1, int e2,int l1, int op,int cond); extern int dpop_register(); extern int emit_dpop(int); extern void code_dregister(int e2,int reg,int d); @@ -183,7 +183,7 @@ #if LONGLONG_CODE /* 64bit int part */ -extern void lrexpr(int e1, int e2,int l1, int op,int cond); +extern int lrexpr(int e1, int e2,int l1, int op,int cond); extern int lpop_register(); extern int emit_lpop(); extern void code_lregister(int e2,int reg);
--- 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
--- a/mc-codegen.h Sun Nov 14 23:50:11 2004 +0900 +++ b/mc-codegen.h Mon Nov 15 20:33:30 2004 +0900 @@ -43,8 +43,8 @@ extern int search_struct_type(int type,char *name,int *dsp); extern int strop(int e,int ind); extern void arg_register(NMTBL *fnptr); -extern void bexpr(int e1, char cond, int l1); -extern void bexpr_u(int e1, char cond, int l1); +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 closing(); extern void cmpdimm(int e, int csreg,int label,int cond); @@ -75,7 +75,7 @@ /* used by mc-cod-* */ extern int assign_expr0(int e1,int e2,int t,int type0) ; -extern void b_expr(int e1, char cond, int l1,int err); +extern int b_expr(int e1, char cond, int l1,int err); extern int contains_p(int e,int (*p)(int)); extern void fwddef(int l); extern int fwdlabel(void);
--- a/mc-parse.c Sun Nov 14 23:50:11 2004 +0900 +++ b/mc-parse.c Mon Nov 15 20:33:30 2004 +0900 @@ -62,6 +62,7 @@ int lineno; int lsrc; int retlabel,retpending,retcont; +int pending_jmp; int struct_return; int sym,type,mode,stmode; int typedefed; @@ -1715,7 +1716,7 @@ conv->if_(); slfree=lfree; checkret(); - bexpr(expr(0),0,l1=fwdlabel()); + l1 = bexpr(expr(0),0,fwdlabel()); lfree=slfree; conv->if_then_(); checksym(RPAR);
--- a/mc-parse.h Sun Nov 14 23:50:11 2004 +0900 +++ b/mc-parse.h Mon Nov 15 20:33:30 2004 +0900 @@ -8,6 +8,7 @@ extern NMTBL *fnptr; extern int gtypedefed; extern int retlabel,retpending,retcont; +extern int pending_jmp; extern int chk; #if BIT_FIELD_CODE extern int bit_field_disp;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/void_code.c Mon Nov 15 20:33:30 2004 +0900 @@ -0,0 +1,21 @@ +main() +{ + for(;;) { + printf("aho\n"); + break; + } + do printf("aho\n"); while(0); + if (0) + printf("a\n"); + if (0) + printf("a\n"); + else + printf("b\n"); + if (1) + printf("a\n"); + else { + printf("b\n"); + printf("b\n"); + } + return 0; +}