# 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 ... )*/
}
/*