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
