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

Reply via email to