This patch implements the register content preserving move operation.
Thanks,
Vishal
Previously:
-------------
Now:1..3
ok 1 - in P param
ok 2 - tailcall 1
not ok 3 - tailcall 2 # TODO use temp
# Failed (TODO) test (t/compilers/imcc/imcpasm/optc.t at line 59)
# '# IMCC does produce b0rken PASM files
# # see http://[EMAIL PROTECTED]/rt3/Ticket/Display.html?id=32392
# _main:
# @pcc_sub_call_0:
# set_args
# set_p_pc P0, foo
# get_results
# invokecc P0
# set_returns
# returncc
# foo:
# get_params
# [EMAIL PROTECTED]:
# @pcc_sub_call_1:
# set I0, I1
# set I1, I0
# branch [EMAIL PROTECTED]
# '
# doesn't match '/ set I(\d), I(\d)
# set I\2, I(\d)
# set I\3, I\1/
# '
------
1..3
ok 1 - in P param
ok 2 - tailcall 1
ok 3 - tailcall 2 # TODO use temp
Patch:
-------Index: src/utils.c
===================================================================
--- src/utils.c (revision 13113)
+++ src/utils.c (working copy)
@@ -48,6 +48,7 @@
=cut
*/
+#define MAX_REGISTER 256
INTVAL
intval_mod(INTVAL i2, INTVAL i3)
@@ -678,12 +679,29 @@
TODO add a define, if it's implemented so that we can start filling the gaps
+TODO The current implementation will not work for following cases
+
+1. I0->I1 I1->I0 I0->I3
+2. I1->I2 I3->I2
+
+Vishal Soni
=cut
*/
/* proto TODO mv to hdr */
typedef int (*reg_move_func)(Interp*, unsigned char d, unsigned char s, void *);
+int reorder_move(unsigned char (*a)[MAX_REGISTER],unsigned char *val ,int src , int prev, int depth ,reg_move_func mov,Interp *interpreter,void *info,int temp);
+int find_first_indegree(unsigned char (*a)[MAX_REGISTER] , int dest);
+int find_root(unsigned char (*a)[MAX_REGISTER],unsigned char* root_vertex ,int src, int dest);
+void emit_mov(reg_move_func mov,Interp *interpreter,void *info,int emit,int emit_temp,int src,int dest,int temp);
+void
+Parrot_register_move(Interp *interpreter, int n_regs,
+ unsigned char *dest_regs, unsigned char *src_regs,
+ unsigned char temp_reg,
+ reg_move_func mov,
+ reg_move_func mov_alt,
+ void *info);
void
Parrot_register_move(Interp *interpreter, int n_regs,
@@ -693,16 +711,113 @@
reg_move_func mov_alt,
void *info)
{
- int i;
+ //int i;
/* TODO */
/* brute force and wrong */
- for (i = 0; i < n_regs; ++i) {
+ /* for (i = 0; i < n_regs; ++i) {
if (dest_regs[i] != src_regs[i])
mov(interpreter, dest_regs[i], src_regs[i], info);
+ printf("Vishal:[%d],[%d]\n",dest_regs[i],src_regs[i]);
+ }*/
+
+ int i;
+ unsigned char (*reg_move_graph)[MAX_REGISTER] = (unsigned char (*)[MAX_REGISTER])mem_sys_allocate_zeroed(sizeof (unsigned char)*MAX_REGISTER *MAX_REGISTER);
+ unsigned char *root_vertx= (unsigned char *)mem_sys_allocate_zeroed(sizeof (unsigned char)*MAX_REGISTER);
+
+ for (i = 0 ; i < n_regs; i++)
+ {
+ reg_move_graph[src_regs[i]][dest_regs[i]]=1;
+ root_vertx[find_root(reg_move_graph,root_vertx,src_regs[i],dest_regs[i])]=1;
}
+
+ unsigned char *val = (unsigned char *)mem_sys_allocate_zeroed(sizeof (unsigned char)*MAX_REGISTER);
+ for (i = 0 ; i < MAX_REGISTER; i++)
+ {
+ if (root_vertx[i]>0)
+ {
+ mov(interpreter,temp_reg,i,info);
+ reorder_move(reg_move_graph,val,i,-1,0,mov,interpreter,info,temp_reg);
+ }
+ }
+ free(val);
+ free(reg_move_graph);
+ free(root_vertx);
}
+int find_root(unsigned char (*a)[MAX_REGISTER],unsigned char* root_vertex ,int src, int dest)
+{
+ if (a[src][dest]==2)
+ {
+ a[src][dest]=1;
+ return dest;
+ }
+ root_vertex[src]=0;
+ a[src][dest]=2;
+ int in_degree=find_first_indegree(a,src);
+ if (in_degree==-1)
+ {
+ a[src][dest]=1;
+ return src;
+ }
+ return find_root(a,root_vertex,in_degree,src);
+}
+
+int find_first_indegree(unsigned char (*a)[MAX_REGISTER] , int dest)
+{
+ int i=0;
+ for( i= 0; i<MAX_REGISTER; i++)
+ {
+ if (a[i][dest] >0 )
+ {
+ return i;
+ }
+ }
+ return -1;
+}
+int reorder_move(unsigned char (*a)[MAX_REGISTER],unsigned char (*val),int src , int prev, int depth , reg_move_func mov,Interp *interpreter,void *info,int temp)
+{
+ int i=0;
+ val[src]=1;
+ for (i=0;i<MAX_REGISTER;i++)
+ {
+ if (a[src][i]>0 )
+ {
+ if (val[i]==1)
+ {
+ emit_mov(mov,interpreter,info,prev,0,i,src,temp);
+ emit_mov(mov,interpreter,info,prev,depth <= 1,src,prev,temp);
+ return 1;
+ }
+ if (val[i]!=2 )
+ {
+ depth++;
+ int x=reorder_move(a,val,i,src,depth,mov,interpreter,info,temp);
+ depth--;
+ emit_mov(mov,interpreter,info,prev,x && (depth <= 1),src,prev,temp);
+ return x;
+ }
+ }
+ }
+ val[src]=2;
+ emit_mov(mov,interpreter,info,prev,0,src,prev,temp);
+ return 0;
+}
+
+void emit_mov(reg_move_func mov,Interp *interpreter,void *info,int emit,int emit_temp,int dest,int src,int temp)
+{
+ if (emit >-1 )
+ {
+ if (emit_temp)
+ {
+ mov(interpreter,dest,temp,info);
+ }
+ else
+ {
+ mov(interpreter,dest,src,info);
+ }
+ }
+}
/*
=back
Index: src/utils.c =================================================================== --- src/utils.c (revision 13113) +++ src/utils.c (working copy) @@ -48,6 +48,7 @@ =cut */ +#define MAX_REGISTER 256 INTVAL intval_mod(INTVAL i2, INTVAL i3) @@ -678,12 +679,29 @@ TODO add a define, if it's implemented so that we can start filling the gaps +TODO The current implementation will not work for following cases + +1. I0->I1 I1->I0 I0->I3 +2. I1->I2 I3->I2 + +Vishal Soni =cut */ /* proto TODO mv to hdr */ typedef int (*reg_move_func)(Interp*, unsigned char d, unsigned char s, void *); +int reorder_move(unsigned char (*a)[MAX_REGISTER],unsigned char *val ,int src , int prev, int depth ,reg_move_func mov,Interp *interpreter,void *info,int temp); +int find_first_indegree(unsigned char (*a)[MAX_REGISTER] , int dest); +int find_root(unsigned char (*a)[MAX_REGISTER],unsigned char* root_vertex ,int src, int dest); +void emit_mov(reg_move_func mov,Interp *interpreter,void *info,int emit,int emit_temp,int src,int dest,int temp); +void +Parrot_register_move(Interp *interpreter, int n_regs, + unsigned char *dest_regs, unsigned char *src_regs, + unsigned char temp_reg, + reg_move_func mov, + reg_move_func mov_alt, + void *info); void Parrot_register_move(Interp *interpreter, int n_regs, @@ -693,16 +711,113 @@ reg_move_func mov_alt, void *info) { - int i; + //int i; /* TODO */ /* brute force and wrong */ - for (i = 0; i < n_regs; ++i) { + /* for (i = 0; i < n_regs; ++i) { if (dest_regs[i] != src_regs[i]) mov(interpreter, dest_regs[i], src_regs[i], info); + printf("Vishal:[%d],[%d]\n",dest_regs[i],src_regs[i]); + }*/ + + int i; + unsigned char (*reg_move_graph)[MAX_REGISTER] = (unsigned char (*)[MAX_REGISTER])mem_sys_allocate_zeroed(sizeof (unsigned char)*MAX_REGISTER *MAX_REGISTER); + unsigned char *root_vertx= (unsigned char *)mem_sys_allocate_zeroed(sizeof (unsigned char)*MAX_REGISTER); + + for (i = 0 ; i < n_regs; i++) + { + reg_move_graph[src_regs[i]][dest_regs[i]]=1; + root_vertx[find_root(reg_move_graph,root_vertx,src_regs[i],dest_regs[i])]=1; } + + unsigned char *val = (unsigned char *)mem_sys_allocate_zeroed(sizeof (unsigned char)*MAX_REGISTER); + for (i = 0 ; i < MAX_REGISTER; i++) + { + if (root_vertx[i]>0) + { + mov(interpreter,temp_reg,i,info); + reorder_move(reg_move_graph,val,i,-1,0,mov,interpreter,info,temp_reg); + } + } + free(val); + free(reg_move_graph); + free(root_vertx); } +int find_root(unsigned char (*a)[MAX_REGISTER],unsigned char* root_vertex ,int src, int dest) +{ + if (a[src][dest]==2) + { + a[src][dest]=1; + return dest; + } + root_vertex[src]=0; + a[src][dest]=2; + int in_degree=find_first_indegree(a,src); + if (in_degree==-1) + { + a[src][dest]=1; + return src; + } + return find_root(a,root_vertex,in_degree,src); +} + +int find_first_indegree(unsigned char (*a)[MAX_REGISTER] , int dest) +{ + int i=0; + for( i= 0; i<MAX_REGISTER; i++) + { + if (a[i][dest] >0 ) + { + return i; + } + } + return -1; +} +int reorder_move(unsigned char (*a)[MAX_REGISTER],unsigned char (*val),int src , int prev, int depth , reg_move_func mov,Interp *interpreter,void *info,int temp) +{ + int i=0; + val[src]=1; + for (i=0;i<MAX_REGISTER;i++) + { + if (a[src][i]>0 ) + { + if (val[i]==1) + { + emit_mov(mov,interpreter,info,prev,0,i,src,temp); + emit_mov(mov,interpreter,info,prev,depth <= 1,src,prev,temp); + return 1; + } + if (val[i]!=2 ) + { + depth++; + int x=reorder_move(a,val,i,src,depth,mov,interpreter,info,temp); + depth--; + emit_mov(mov,interpreter,info,prev,x && (depth <= 1),src,prev,temp); + return x; + } + } + } + val[src]=2; + emit_mov(mov,interpreter,info,prev,0,src,prev,temp); + return 0; +} + +void emit_mov(reg_move_func mov,Interp *interpreter,void *info,int emit,int emit_temp,int dest,int src,int temp) +{ + if (emit >-1 ) + { + if (emit_temp) + { + mov(interpreter,dest,temp,info); + } + else + { + mov(interpreter,dest,src,info); + } + } +} /* =back