r300/compiler: Enable rename_reg pass for r500 cards
authorTom Stellard <tstellar@gmail.com>
Thu, 11 Nov 2010 05:34:18 +0000 (21:34 -0800)
committerTom Stellard <tstellar@gmail.com>
Mon, 22 Nov 2010 02:48:31 +0000 (18:48 -0800)
In addition, the rename_reg pass has been rewritten to use
rc_get_readers().

src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
src/mesa/drivers/dri/r300/compiler/radeon_rename_regs.c

index 2f130198d350130ca78c6faf6b2b1d1fbc307f0c..7b9c3167940ad754b78519c4aa6c6d06f5d9234e 100644 (file)
@@ -137,7 +137,7 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
                /* This pass makes it easier for the scheduler to group TEX
                 * instructions and reduces the chances of creating too
                 * many texture indirections.*/
-               {"register rename",             1, !is_r500,    rc_rename_regs,                 NULL},
+               {"register rename",             1, !is_r500 || opt, rc_rename_regs,             NULL},
                {"pair translate",              1, 1,           rc_pair_translate,              NULL},
                {"pair scheduling",             1, 1,           rc_pair_schedule,               NULL},
                {"register allocation",         1, opt,         rc_pair_regalloc,               NULL},
index 60e228be5bd8115607c800d7e76bd8a305e6f7bc..87ec3dca069e7160dd1b5cdc3cc8a6f4810cc0da 100644 (file)
 #include "radeon_compiler.h"
 #include "radeon_dataflow.h"
 
-struct reg_rename {
-       int old_index;
-       int new_index;
-       int temp_index;
-};
-
-static void rename_reg(void * data, struct rc_instruction * inst,
-                       rc_register_file * file, unsigned int * index)
-{
-       struct reg_rename *r = data;
-
-       if(r->old_index == *index && *file == RC_FILE_TEMPORARY) {
-               *index = r->new_index;
-       }
-       else if(r->new_index == *index && *file == RC_FILE_TEMPORARY) {
-               *index = r->temp_index;
-       }
-}
-
-static void rename_all(
-       struct radeon_compiler *c,
-       struct rc_instruction * start,
-       unsigned int old,
-       unsigned int new,
-       unsigned int temp)
-{
-       struct rc_instruction * inst;
-       struct reg_rename r;
-       r.old_index = old;
-       r.new_index = new;
-       r.temp_index = temp;
-       for(inst = start; inst != &c->Program.Instructions;
-                                               inst = inst->Next) {
-               rc_remap_registers(inst, rename_reg, &r);
-       }
-}
-
 /**
  * This function renames registers in an attempt to get the code close to
  * SSA form.  After this function has completed, most of the register are only
- * written to one time, with a few exceptions.  For example, this block of code
- * will not be modified by this function:
- * Mov Temp[0].x Const[0].x
- * Mov Temp[0].y Const[0].y
- * Basically, destination registers will be renamed if:
- * 1. There have been no previous writes to that register
- * or
- * 2. If the instruction is writting to the exact components (no more, no less)
- * of a register that has been written to by previous instructions.
+ * written to one time, with a few exceptions.
  *
  * This function assumes all the instructions are still of type
  * RC_INSTRUCTION_NORMAL.
  */
 void rc_rename_regs(struct radeon_compiler *c, void *user)
 {
-       unsigned int cur_index = 0;
-       unsigned int icount;
+       unsigned int new_index, i;
        struct rc_instruction * inst;
-       unsigned int * masks;
-
-       /* The number of instructions in the program is also the maximum
-        * number of temp registers that could potentially be used. */
-       icount = rc_recompute_ips(c);
-       masks = memory_pool_malloc(&c->Pool, icount * sizeof(unsigned int));
-       memset(masks, 0, icount * sizeof(unsigned int));
+       struct rc_reader_data reader_data;
 
        for(inst = c->Program.Instructions.Next;
                                        inst != &c->Program.Instructions;
                                        inst = inst->Next) {
-               const struct rc_opcode_info * info;
-               unsigned int old_index, temp_index;
-               struct rc_dst_register * dst;
-               if(inst->Type != RC_INSTRUCTION_NORMAL) {
-                       rc_error(c, "%s only works with normal instructions.",
-                                                               __FUNCTION__);
-                       return;
-               }
-               dst = &inst->U.I.DstReg;
-               info = rc_get_opcode_info(inst->U.I.Opcode);
-               if(!info->HasDstReg || dst->File != RC_FILE_TEMPORARY) {
+
+               if (inst->U.I.DstReg.File != RC_FILE_TEMPORARY)
                        continue;
+
+               rc_get_readers(c, inst, &reader_data, NULL, NULL, NULL);
+
+               if (reader_data.Abort || reader_data.ReaderCount == 0)
+                       continue;
+
+               new_index = rc_find_free_temporary(c);
+               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;
                }
-               if(dst->Index >= icount || !masks[dst->Index] ||
-                                       masks[dst->Index] == dst->WriteMask) {
-                       old_index = dst->Index;
-                       /* We need to set dst->Index here so get free temporary
-                        * will work. */
-                       dst->Index = cur_index++;
-                       temp_index = rc_find_free_temporary(c);
-                       rename_all(c, inst->Next, old_index,
-                                               dst->Index, temp_index);
-               }
-               assert(dst->Index < icount);
-               masks[dst->Index] |= dst->WriteMask;
        }
 }