# New Ticket Created by Matt Fowles # Please include the string: [perl #22387] # in the subject line of all future correspondence about this issue. # <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=22387 >
All~ This patch adds simple constant propagation to imcc. The tests for this level of optimization thus need to be updated which is the other part of the patch. I am a little confused as to why I had to do for(i = ins2->opsize - 2; i >= 0; i--) rather than for(i = ins2->opsize - 1; i >= 0; i--) to avoid a segfault. Comments welcome, Matt -- attachment 1 ------------------------------------------------------ url: http://rt.perl.org/rt2/attach/58435/43433/c65e68/opt2.t.patch -- attachment 2 ------------------------------------------------------ url: http://rt.perl.org/rt2/attach/58435/43434/e72442/optimizer.c.patch
Index: opt2.t =================================================================== RCS file: /cvs/public/parrot/languages/imcc/t/imcpasm/opt2.t,v retrieving revision 1.3 diff -u -r1.3 opt2.t --- opt2.t 27 Apr 2003 07:42:25 -0000 1.3 +++ opt2.t 31 May 2003 05:47:26 -0000 @@ -15,8 +15,7 @@ .end CODE _main: - set I0, 2 - print I0 + print 2 end OUT @@ -26,7 +25,7 @@ set I0, 5 loop: set I1, 2 - add I0, I1 + add I0, 2 lt I0, 20, loop print I0 end @@ -34,9 +33,8 @@ CODE _main: set I0, 5 - set I1, 2 loop: - add I0, I1 + add I0, 2 lt I0, 20, loop print I0 end
Index: optimizer.c =================================================================== RCS file: /cvs/public/parrot/languages/imcc/optimizer.c,v retrieving revision 1.25 diff -u -r1.25 optimizer.c --- optimizer.c 29 May 2003 09:27:47 -0000 1.25 +++ optimizer.c 31 May 2003 05:52:54 -0000 @@ -57,6 +57,7 @@ static void subst_constants_c(struct Parrot_Interp *interp); static void subst_constants_if(struct Parrot_Interp *interp); +static void constant_propagation(void); static int used_once(void); static int loop_optimization(struct Parrot_Interp *); static int clone_remove(void); @@ -96,7 +97,7 @@ if (optimizer_level & OPT_CFG) { info(2, "optimize\n"); - /* constant_propagation(); N/Y */ + constant_propagation(); if (clone_remove()) return 1; if (used_once()) @@ -289,6 +290,49 @@ goto set_it; } } +} + + +static void +constant_propagation() +{ + Instruction *ins, *ins2; + int i; + char b[128]; + SymReg *c, *n, *o; + info(2, "\tconstant_propagation\n"); + for (ins = instructions; ins; ins = ins->next) { + if (!strcmp(ins->op, "set") && + ins->r[1]->type == VTCONST) { + c = ins->r[1]; + o = ins->r[0]; + + debug(DEBUG_OPT1, "propagating constant %s => \n", ins_string(ins)); + for(ins2 = ins->next; ins2; ins2 = ins2->next) { + if (ins2->type & ITSAVES) + goto next_constant; + for(i = ins2->opsize - 2; i >= 0; i--) { + if(!strcmp(o->name,ins2->r[i]->name)) { + if(instruction_writes(ins2,ins2->r[i])) + goto next_constant; + else if(instruction_reads(ins2,ins2->r[i])) { + debug(DEBUG_OPT1, + "\tpropagating into %s register %i\n", + ins_string(ins2), i); + strcpy(b, c->name); + n = mk_const(str_dup(b), c->set); + --ins2->r[i]->use_count; + /*free_sym(ins2->r[i]); causes segfault*/ + ins2->r[i] = n; + } + } + + }/* for(i ... )*/ + }/* for(ins2 ... )*/ + } /* if */ +next_constant:; + + }/*for(ins ... )*/ } /*