qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [4469] added 'pure' function attribute - fixed indirect fun


From: Fabrice Bellard
Subject: [Qemu-devel] [4469] added 'pure' function attribute - fixed indirect function calls
Date: Sat, 17 May 2008 12:42:19 +0000

Revision: 4469
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=4469
Author:   bellard
Date:     2008-05-17 12:42:15 +0000 (Sat, 17 May 2008)

Log Message:
-----------
added 'pure' function attribute - fixed indirect function calls

Modified Paths:
--------------
    trunk/tcg/tcg.c
    trunk/tcg/tcg.h

Modified: trunk/tcg/tcg.c
===================================================================
--- trunk/tcg/tcg.c     2008-05-17 12:40:44 UTC (rev 4468)
+++ trunk/tcg/tcg.c     2008-05-17 12:42:15 UTC (rev 4469)
@@ -946,32 +946,51 @@
         def = &tcg_op_defs[op];
         switch(op) {
         case INDEX_op_call:
-            nb_args = args[-1];
-            args -= nb_args;
-            nb_iargs = args[0] & 0xffff;
-            nb_oargs = args[0] >> 16;
-            args++;
+            {
+                int call_flags;
 
-            /* output args are dead */
-            for(i = 0; i < nb_oargs; i++) {
-                arg = args[i];
-                dead_temps[arg] = 1;
-            }
-            
-            /* globals are live (they may be used by the call) */
-            memset(dead_temps, 0, s->nb_globals);
+                nb_args = args[-1];
+                args -= nb_args;
+                nb_iargs = args[0] & 0xffff;
+                nb_oargs = args[0] >> 16;
+                args++;
+                call_flags = args[nb_oargs + nb_iargs];
 
-            /* input args are live */
-            dead_iargs = 0;
-            for(i = 0; i < nb_iargs; i++) {
-                arg = args[i + nb_oargs];
-                if (dead_temps[arg]) {
-                    dead_iargs |= (1 << i);
+                /* pure functions can be removed if their result is not
+                   used */
+                if (call_flags & TCG_CALL_PURE) {
+                    for(i = 0; i < nb_oargs; i++) {
+                        arg = args[i];
+                        if (!dead_temps[arg])
+                            goto do_not_remove_call;
+                    }
+                    tcg_set_nop(s, gen_opc_buf + op_index, 
+                                args - 1, nb_args);
+                } else {
+                do_not_remove_call:
+
+                    /* output args are dead */
+                    for(i = 0; i < nb_oargs; i++) {
+                        arg = args[i];
+                        dead_temps[arg] = 1;
+                    }
+                    
+                    /* globals are live (they may be used by the call) */
+                    memset(dead_temps, 0, s->nb_globals);
+                    
+                    /* input args are live */
+                    dead_iargs = 0;
+                    for(i = 0; i < nb_iargs; i++) {
+                        arg = args[i + nb_oargs];
+                        if (dead_temps[arg]) {
+                            dead_iargs |= (1 << i);
+                        }
+                        dead_temps[arg] = 0;
+                    }
+                    s->op_dead_iargs[op_index] = dead_iargs;
                 }
-                dead_temps[arg] = 0;
+                args--;
             }
-            s->op_dead_iargs[op_index] = dead_iargs;
-            args--;
             break;
         case INDEX_op_set_label:
             args--;
@@ -1640,7 +1659,7 @@
     }
     
     /* mark dead temporaries and free the associated registers */
-    for(i = 0; i < nb_params; i++) {
+    for(i = 0; i < nb_iargs; i++) {
         arg = args[nb_oargs + i];
         if (IS_DEAD_IARG(i)) {
             ts = &s->temps[arg];

Modified: trunk/tcg/tcg.h
===================================================================
--- trunk/tcg/tcg.h     2008-05-17 12:40:44 UTC (rev 4468)
+++ trunk/tcg/tcg.h     2008-05-17 12:42:15 UTC (rev 4469)
@@ -148,6 +148,10 @@
 #define TCG_CALL_TYPE_REGPARM_1 0x0001 /* i386 style regparm call (1 reg) */
 #define TCG_CALL_TYPE_REGPARM_2 0x0002 /* i386 style regparm call (2 regs) */
 #define TCG_CALL_TYPE_REGPARM   0x0003 /* i386 style regparm call (3 regs) */
+/* A pure function only reads its arguments and globals variables and
+   cannot raise exceptions. Hence a call to a pure function can be
+   safely suppressed if the return value is not used. */
+#define TCG_CALL_PURE           0x0010 
 
 typedef enum {
     TCG_COND_EQ,






reply via email to

[Prev in Thread] Current Thread [Next in Thread]