From 419fab0fea1863ce32f71f11a44267a7719e783e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net> Date: Sun, 9 Mar 1997 01:11:13 -0800 Subject: [PATCH] peephole optimizer and code generator bugfixed and improved Rev: bin/mkpeep.pike:1.3 Rev: src/docode.c:1.13 Rev: src/interpret.c:1.30 Rev: src/language.yacc:1.29 Rev: src/lex.c:1.17 Rev: src/operators.h:1.2 Rev: src/peep.c:1.7 Rev: src/peep.in:1.5 Rev: src/testsuite.in:1.34 --- bin/mkpeep.pike | 18 +++++-- src/docode.c | 50 ++++++++++++++++++-- src/interpret.c | 14 +++++- src/language.yacc | 3 +- src/lex.c | 4 +- src/operators.h | 4 ++ src/peep.c | 116 ++++++++++++++++++++++++++++++++-------------- src/peep.in | 2 + src/testsuite.in | 3 +- 9 files changed, 169 insertions(+), 45 deletions(-) diff --git a/bin/mkpeep.pike b/bin/mkpeep.pike index 181ed1569d..04609cbc65 100755 --- a/bin/mkpeep.pike +++ b/bin/mkpeep.pike @@ -312,20 +312,21 @@ void dump2(mixed *data,int ind) { if(i+1<sizeof(d[1]) && d[1][i+1][0]=='(') { - write(sprintf("%*ninsert_opcode(%s,arg%d,cl,cf);\n",ind,d[1][i],i)); + write(sprintf("%*ninsopt(%s,arg%d,cl,cf);\n",ind,d[1][i],i)); i++; }else{ - write(sprintf("%*ninsert_opcode2(%s,cl,cf);\n",ind,d[1][i])); + write(sprintf("%*ninsopt2(%s,cl,cf);\n",ind,d[1][i])); } q++; } if(sizeof(d[1])) { if(q) - write(sprintf("%*nfifo_len+=%d;\n",ind,q+JUMPBACK)); + write(sprintf("%*nfifo_len+=%d;\n",ind,q)); write(sprintf("%*nfree_string(cf);\n",ind)); write(sprintf("%*ndebug();\n",ind)); } + write(sprintf("%*nfifo_len+=%d;\n",ind,q+JUMPBACK)); write(sprintf("%*ncontinue;\n",ind)); ind-=2; @@ -373,6 +374,17 @@ int main(int argc, string *argv) write(" INT32 current_line;\n"); write(" struct pike_string *current_file;\n"); write("\n"); + write("#ifdef DEBUG\n"); + write(" if(a_flag>5) {\n"); + write(" fprintf(stderr,\"#%d,%d:\",eye,fifo_len);\n"); + write(" fprintf(stderr,\"%s(%d)\", get_token_name(opcode(-2)),argument(-2));\n"); + write(" fprintf(stderr,\" %s(%d)\", get_token_name(opcode(-1)),argument(-1));\n"); + write(" fprintf(stderr,\" . %s(%d)\", get_token_name(opcode(0)),argument(0));\n"); + write(" fprintf(stderr,\" %s(%d)\", get_token_name(opcode(1)),argument(1));\n"); + write(" fprintf(stderr,\" %s(%d)\", get_token_name(opcode(2)),argument(2));\n"); + write(" fprintf(stderr,\" %s(%d)\\n\",get_token_name(opcode(3)),argument(3));\n"); + write(" }\n"); + write("#endif\n\n"); dump2(data,4); diff --git a/src/docode.c b/src/docode.c index b052a41aa6..12e2c9f2ae 100644 --- a/src/docode.c +++ b/src/docode.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: docode.c,v 1.12 1997/03/05 05:22:55 hubbe Exp $"); +RCSID("$Id: docode.c,v 1.13 1997/03/09 09:11:10 hubbe Exp $"); #include "las.h" #include "program.h" #include "language.h" @@ -22,6 +22,7 @@ RCSID("$Id: docode.c,v 1.12 1997/03/05 05:22:55 hubbe Exp $"); #include "builtin_functions.h" #include "peep.h" #include "docode.h" +#include "operators.h" INT32 current_break=-1; INT32 current_continue=-1; @@ -159,6 +160,13 @@ int do_docode(node *n,INT16 flags) void do_jump_when_zero(node *n,int j); +static int is_efun(node *n, c_fun fun) +{ + return n && n->token == F_CONSTANT && + n->u.sval.subtype == FUNCTION_BUILTIN && + n->u.sval.u.efun->function == fun; +} + void do_jump_when_non_zero(node *n,int j) { if(!node_is_tossable(n)) @@ -175,10 +183,28 @@ void do_jump_when_non_zero(node *n,int j) switch(n->token) { + case F_APPLY: + if(is_efun(CAR(n), f_not)) + { + do_jump_when_zero(CDR(n), j); + return; + } + break; + case F_NOT: do_jump_when_zero(CAR(n), j); return; - case F_OR: + + case F_LAND: + { + int tmp=alloc_label(); + do_jump_when_zero(CAR(n), tmp); + do_jump_when_non_zero(CDR(n), j); + emit(F_LABEL,tmp); + return; + } + + case F_LOR: do_jump_when_non_zero(CAR(n), j); do_jump_when_non_zero(CDR(n), j); return; @@ -205,10 +231,28 @@ void do_jump_when_zero(node *n,int j) switch(n->token) { + case F_APPLY: + if(is_efun(CAR(n), f_not)) + { + do_jump_when_non_zero(CDR(n), j); + return; + } + break; + case F_NOT: do_jump_when_non_zero(CAR(n), j); return; - case F_AND: + + case F_LOR: + { + int tmp=alloc_label(); + do_jump_when_non_zero(CAR(n), tmp); + do_jump_when_zero(CDR(n), j); + emit(F_LABEL,tmp); + return; + } + + case F_LAND: do_jump_when_zero(CAR(n), j); do_jump_when_zero(CDR(n), j); return; diff --git a/src/interpret.c b/src/interpret.c index 8bb77beff2..81bd795b92 100644 --- a/src/interpret.c +++ b/src/interpret.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: interpret.c,v 1.29 1997/03/08 12:54:06 hubbe Exp $"); +RCSID("$Id: interpret.c,v 1.30 1997/03/09 09:11:11 hubbe Exp $"); #include "interpret.h" #include "object.h" #include "program.h" @@ -881,6 +881,18 @@ static void eval_instruction(unsigned char *pc) } break; + CASE(F_EQ_OR); + if(is_eq(sp-2,sp-1)) + { + pop_n_elems(2); + pc+=sizeof(INT32); + }else{ + pop_n_elems(2); + push_int(1); + DOJUMP(); + } + break; + CASE(F_CATCH); if(o_catch(pc+sizeof(INT32))) return; /* There was a return inside the evaluated code */ diff --git a/src/language.yacc b/src/language.yacc index d34d0fc7ea..5122e1f040 100644 --- a/src/language.yacc +++ b/src/language.yacc @@ -56,6 +56,7 @@ %token F_AND F_OR F_XOR %token F_LSH F_RSH %token F_LAND F_LOR +%token F_EQ_OR %token F_SWITCH F_SSCANF F_CATCH %token F_CAST @@ -157,7 +158,7 @@ /* This is the grammar definition of Pike. */ #include "global.h" -RCSID("$Id: language.yacc,v 1.28 1997/03/05 05:12:07 hubbe Exp $"); +RCSID("$Id: language.yacc,v 1.29 1997/03/09 09:11:11 hubbe Exp $"); #ifdef HAVE_MEMORY_H #include <memory.h> #endif diff --git a/src/lex.c b/src/lex.c index 01e9e894a3..d69d0a1695 100644 --- a/src/lex.c +++ b/src/lex.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: lex.c,v 1.16 1997/03/08 12:54:06 hubbe Exp $"); +RCSID("$Id: lex.c,v 1.17 1997/03/09 09:11:12 hubbe Exp $"); #include "language.h" #include "array.h" #include "lex.h" @@ -272,6 +272,8 @@ struct keyword instr_names[]= { "apply and pop", F_APPLY_AND_POP, 1 }, { "2 locals", F_2_LOCALS, 1 }, { "byte", F_BYTE, 1 }, +{ "nop", F_NOP }, +{ "==||", F_EQ_OR, 1 }, }; struct instr instrs[F_MAX_INSTR - F_OFFSET]; diff --git a/src/operators.h b/src/operators.h index e42f381115..4887aa8d49 100644 --- a/src/operators.h +++ b/src/operators.h @@ -15,6 +15,7 @@ COMPARISON(f_lt,"`<" , is_lt(sp-2,sp-1)) COMPARISON(f_le,"`<=",!is_gt(sp-2,sp-1)) COMPARISON(f_gt,"`>" , is_gt(sp-2,sp-1)) COMPARISON(f_ge,"`>=",!is_lt(sp-2,sp-1)) + void f_add(INT32 args); void o_subtract(); void f_minus(INT32 args); @@ -40,6 +41,9 @@ void o_compl(); void f_compl(INT32 args); void o_negate(); void o_range(); +void f_index(INT32 args); +void f_arrow(INT32 args); +void f_sizeof(INT32 args); void init_operators(); /* Prototypes end here */ diff --git a/src/peep.c b/src/peep.c index a56921283a..9a3124daff 100644 --- a/src/peep.c +++ b/src/peep.c @@ -81,6 +81,7 @@ int insert_opcode2(int f,int current_line, struct pike_string *current_file) return insert_opcode(f,0,current_line, current_file); } + void update_arg(int instr,INT32 arg) { p_instr *p; @@ -153,6 +154,7 @@ static void ins_f_byte_with_arg(unsigned int a,unsigned INT32 b) case F_DEC_NEQ_LOOP: \ case F_LAND: \ case F_LOR: \ + case F_EQ_OR: \ case F_CATCH: \ case F_FOREACH @@ -191,20 +193,41 @@ void assemble(void) for(e=0;e<length;e++) { - int tmp; switch(c[e].opcode) { case BRANCH_CASES: case F_POINTER: while(1) { + int tmp,tmp2; tmp=labels[c[e].arg]; while(c[tmp].opcode == F_LABEL || c[tmp].opcode == F_NOP) tmp++; - if(c[tmp].opcode!=F_BRANCH) break; - c[e].arg=c[tmp].arg; + if(c[tmp].opcode==F_BRANCH) + { + c[e].arg=c[tmp].arg; + continue; + } + +#define TWOO(X,Y) (((X)<<8)+(Y)) + + switch(TWOO(c[e].opcode,c[tmp].opcode)) + { + case TWOO(F_LOR,F_BRANCH_WHEN_NON_ZERO): + c[e].opcode=F_BRANCH_WHEN_NON_ZERO; + case TWOO(F_LOR,F_LOR): + c[e].arg=c[tmp].arg; + continue; + + case TWOO(F_LAND,F_BRANCH_WHEN_ZERO): + c[e].opcode=F_BRANCH_WHEN_ZERO; + case TWOO(F_LAND,F_LAND): + c[e].arg=c[tmp].arg; + continue; + } + break; } uses[c[e].arg]++; } @@ -311,6 +334,47 @@ void assemble(void) static int fifo_len, eye,len; static p_instr *instructions; +int insopt(int f, INT32 b, int cl, struct pike_string *cf) +{ + p_instr *p; + +#ifdef DEBUG + if(!hasarg(f) && b) + fatal("hasarg() is wrong!\n"); +#endif + + p=(p_instr *)low_make_buf_space(sizeof(p_instr), &instrbuf); + + if(fifo_len) + { + MEMMOVE(p-fifo_len+1,p-fifo_len,fifo_len*sizeof(p_instr)); + p-=fifo_len; + fifo_len++; + } + +#ifdef DEBUG + if(!instrbuf.s.len) + fatal("Low make buf space failed!!!!!!\n"); +#endif + + p->opcode=f; + p->line=current_line; + copy_shared_string(p->file, current_file); + p->arg=b; + + return p - (p_instr *)instrbuf.s.str; +} + +int insopt2(int f, int cl, struct pike_string *cf) +{ +#ifdef DEBUG + if(hasarg(f)) + fatal("hasarg() is wrong!\n"); +#endif + return insert_opcode(f,0,cl, cf); +} + + static void debug() { if(fifo_len > (long)instrbuf.s.len / (long)sizeof(p_instr)) @@ -336,23 +400,18 @@ static p_instr *instr(int offset) debug(); - if(offset >= 0) + if(offset < fifo_len) { - if(offset < fifo_len) - { - p=(p_instr *)low_make_buf_space(0, &instrbuf); - p-=fifo_len; - p+=offset; - return p; - }else{ - offset-=fifo_len; - offset+=eye; - if(offset >= len) return 0; - return instructions+offset; - } + p=(p_instr *)low_make_buf_space(0, &instrbuf); + p-=fifo_len; + p+=offset; + if(((char *)p)<instrbuf.s.str) return 0; + return p; }else{ - fatal("Can't handle negative offsets in peephole optimizer!\n"); - return 0; /* Make GCC happy */ + offset-=fifo_len; + offset+=eye; + if(offset >= len) return 0; + return instructions+offset; } } @@ -393,37 +452,24 @@ static void pop_n_opcodes(int n) { p_instr *p; - d=fifo_len; - if(d>n) d=n; + d=n; + if(d>fifo_len) d=fifo_len; #ifdef DEBUG if((long)d > (long)instrbuf.s.len / (long)sizeof(p_instr)) fatal("Popping out of instructions.\n"); #endif - low_make_buf_space(-((INT32)sizeof(p_instr))*fifo_len, &instrbuf); p=(p_instr *)low_make_buf_space(0, &instrbuf); + p-=fifo_len; for(e=0;e<d;e++) free_string(p[e].file); fifo_len-=d; if(fifo_len) MEMMOVE(p,p+d,fifo_len*sizeof(p_instr)); n-=d; + low_make_buf_space(-((INT32)sizeof(p_instr))*d, &instrbuf); } eye+=n; } -static void dofix() -{ - p_instr *p,tmp; - int e; - - if(fifo_len) - { - p=(p_instr *)low_make_buf_space(0, &instrbuf); - tmp=p[-1]; - for(e=0;e<fifo_len;e++) - p[-1-e]=p[-2-e]; - p[-1-e]=tmp; - } -} static void asm_opt(void) { diff --git a/src/peep.in b/src/peep.in index b100f7ae23..3fab269e3d 100644 --- a/src/peep.in +++ b/src/peep.in @@ -94,6 +94,8 @@ GT BRANCH_WHEN_ZERO: BRANCH_WHEN_LE ($2a) LE BRANCH_WHEN_ZERO: BRANCH_WHEN_GT ($2a) GE BRANCH_WHEN_ZERO: BRANCH_WHEN_LT ($2a) +EQ LOR: EQ_OR ($2a) + EQ NOT: NE NE NOT: EQ LT NOT: GE diff --git a/src/testsuite.in b/src/testsuite.in index 7dd2e80402..ccc0366844 100644 --- a/src/testsuite.in +++ b/src/testsuite.in @@ -1,4 +1,5 @@ -test_true([["$Id: testsuite.in,v 1.33 1997/03/08 12:54:09 hubbe Exp $"]]) +test_true([["$Id: testsuite.in,v 1.34 1997/03/09 09:11:13 hubbe Exp $"]]) +test_program([[inline string foo(string s){ while(s[0] == ' ' || s[0] == '\t') s = s[1..]; return(s); } string a() { return foo(" bar"); }]]) test_true([[lambda(function f) {return 1;}(object_program(this_object()));]]) test_eq([[class { int `()(){ return 4711; } }()(); ]],4711) teste_eval_error(mixed foo=({}); sort(@foo); ) -- GitLab