Module: Mesa
Branch: master
Commit: 1b6ed809729dd3adee4adfa87c227bbd98d9f23a
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=1b6ed809729dd3adee4adfa87c227bbd98d9f23a

Author: Tom Stellard <tstel...@gmail.com>
Date:   Fri Nov 12 00:59:13 2010 -0800

r300/compiler: Add a more efficient version of rc_find_free_temporary()

---

 .../drivers/dri/r300/compiler/radeon_program.c     |  104 ++++++++++++++++----
 .../drivers/dri/r300/compiler/radeon_program.h     |   11 ++
 .../drivers/dri/r300/compiler/radeon_rename_regs.c |   18 +++-
 3 files changed, 110 insertions(+), 23 deletions(-)

diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program.c 
b/src/mesa/drivers/dri/r300/compiler/radeon_program.c
index 14dade9..d7bedc5 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_program.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_program.c
@@ -30,6 +30,7 @@
 #include <stdio.h>
 
 #include "radeon_compiler.h"
+#include "radeon_dataflow.h"
 
 
 /**
@@ -91,37 +92,98 @@ struct rc_src_register lmul_swizzle(unsigned int swizzle, 
struct rc_src_register
        return tmp;
 }
 
-unsigned int rc_find_free_temporary(struct radeon_compiler * c)
+struct get_used_temporaries_data {
+       unsigned char * Used;
+       unsigned int UsedLength;
+};
+
+static void get_used_temporaries_cb(
+       void * userdata,
+       struct rc_instruction * inst,
+       rc_register_file file,
+       unsigned int index,
+       unsigned int mask)
 {
-       char used[RC_REGISTER_MAX_INDEX];
-       unsigned int i;
-       struct rc_instruction * rcinst;
+       struct get_used_temporaries_data * d = userdata;
 
-       memset(used, 0, sizeof(used));
+       if (file != RC_FILE_TEMPORARY)
+               return;
 
-       for (rcinst = c->Program.Instructions.Next; rcinst != 
&c->Program.Instructions; rcinst = rcinst->Next) {
-               const struct rc_sub_instruction *inst = &rcinst->U.I;
-               const struct rc_opcode_info *opcode = 
rc_get_opcode_info(inst->Opcode);
-               unsigned int k;
+       if (index >= d->UsedLength)
+               return;
 
-               for (k = 0; k < opcode->NumSrcRegs; k++) {
-                       if (inst->SrcReg[k].File == RC_FILE_TEMPORARY)
-                               used[inst->SrcReg[k].Index] = 1;
-               }
+       d->Used[index] |= mask;
+}
 
-               if (opcode->HasDstReg) {
-                       if (inst->DstReg.File == RC_FILE_TEMPORARY)
-                               used[inst->DstReg.Index] = 1;
-               }
+/**
+ * This function fills in the parameter 'used' with a writemask that
+ * represent which components of each temporary register are used by the
+ * program.  This is meant to be combined with rc_find_free_temporary_list as a
+ * more efficient version of rc_find_free_temporary.
+ * @param used The function does not initialize this parameter.
+ */
+void rc_get_used_temporaries(
+       struct radeon_compiler * c,
+       unsigned char * used,
+       unsigned int used_length)
+{
+       struct rc_instruction * inst;
+       struct get_used_temporaries_data d;
+       d.Used = used;
+       d.UsedLength = used_length;
+
+       for(inst = c->Program.Instructions.Next;
+                       inst != &c->Program.Instructions; inst = inst->Next) {
+
+               rc_for_all_reads_mask(inst, get_used_temporaries_cb, &d);
+               rc_for_all_writes_mask(inst, get_used_temporaries_cb, &d);
        }
+}
 
-       for (i = 0; i < RC_REGISTER_MAX_INDEX; i++) {
-               if (!used[i])
+/* Search a list of used temporaries for a free one
+ * \sa rc_get_used_temporaries
+ * @note If this functions finds a free temporary, it will mark it as used
+ * in the used temporary list (param 'used')
+ * @param used list of used temporaries
+ * @param used_length number of items in param 'used'
+ * @param mask which components must be free in the temporary index that is
+ * returned.
+ * @return -1 If there are no more free temporaries, otherwise the index of
+ * a temporary register where the components specified in param 'mask' are
+ * not being used.
+ */
+int rc_find_free_temporary_list(
+       struct radeon_compiler * c,
+       unsigned char * used,
+       unsigned int used_length,
+       unsigned int mask)
+{
+       int i;
+       for(i = 0; i < used_length; i++) {
+               if ((~used[i] & mask) == mask) {
+                       used[i] |= mask;
                        return i;
+               }
        }
+       return -1;
+}
 
-       rc_error(c, "Ran out of temporary registers\n");
-       return 0;
+unsigned int rc_find_free_temporary(struct radeon_compiler * c)
+{
+       unsigned char used[RC_REGISTER_MAX_INDEX];
+       int free;
+
+       memset(used, 0, sizeof(used));
+
+       rc_get_used_temporaries(c, used, RC_REGISTER_MAX_INDEX);
+
+       free = rc_find_free_temporary_list(c, used, RC_REGISTER_MAX_INDEX,
+                                                               RC_MASK_XYZW);
+       if (free < 0) {
+               rc_error(c, "Ran out of temporary registers\n");
+               return 0;
+       }
+       return free;
 }
 
 
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program.h 
b/src/mesa/drivers/dri/r300/compiler/radeon_program.h
index a4d50d3..be078b4 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_program.h
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_program.h
@@ -236,6 +236,17 @@ void rc_local_transform(
        struct radeon_compiler *c,
        void *user);
 
+void rc_get_used_temporaries(
+       struct radeon_compiler * c,
+       unsigned char * used,
+       unsigned int used_length);
+
+int rc_find_free_temporary_list(
+       struct radeon_compiler * c,
+       unsigned char * used,
+       unsigned int used_length,
+       unsigned int mask);
+
 unsigned int rc_find_free_temporary(struct radeon_compiler * c);
 
 struct rc_instruction *rc_alloc_instruction(struct radeon_compiler * c);
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_rename_regs.c 
b/src/mesa/drivers/dri/r300/compiler/radeon_rename_regs.c
index 87ec3dc..88165f7 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_rename_regs.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_rename_regs.c
@@ -33,6 +33,7 @@
 
 #include "radeon_compiler.h"
 #include "radeon_dataflow.h"
+#include "radeon_program.h"
 
 /**
  * This function renames registers in an attempt to get the code close to
@@ -44,10 +45,17 @@
  */
 void rc_rename_regs(struct radeon_compiler *c, void *user)
 {
-       unsigned int new_index, i;
+       unsigned int i, used_length;
+       int new_index;
        struct rc_instruction * inst;
        struct rc_reader_data reader_data;
+       unsigned char * used;
 
+       used_length = 2 * rc_recompute_ips(c);
+       used = memory_pool_malloc(&c->Pool, sizeof(unsigned char) * 
used_length);
+       memset(used, 0, sizeof(unsigned char) * used_length);
+
+       rc_get_used_temporaries(c, used, used_length);
        for(inst = c->Program.Instructions.Next;
                                        inst != &c->Program.Instructions;
                                        inst = inst->Next) {
@@ -60,7 +68,13 @@ void rc_rename_regs(struct radeon_compiler *c, void *user)
                if (reader_data.Abort || reader_data.ReaderCount == 0)
                        continue;
 
-               new_index = rc_find_free_temporary(c);
+               new_index = rc_find_free_temporary_list(c, used, used_length,
+                                               RC_MASK_XYZW);
+               if (new_index < 0) {
+                       rc_error(c, "Ran out of temporary registers\n");
+                       return;
+               }
+
                reader_data.Writer->U.I.DstReg.Index = new_index;
                for(i = 0; i < reader_data.ReaderCount; i++) {
                        reader_data.Readers[i].U.Src->Index = new_index;

_______________________________________________
mesa-commit mailing list
mesa-commit@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to