i965/fs: Simplify and fix register offset calculation of try_copy_propagate().
authorFrancisco Jerez <currojerez@riseup.net>
Tue, 10 May 2016 23:01:56 +0000 (16:01 -0700)
committerSamuel Iglesias Gonsálvez <siglesias@igalia.com>
Mon, 16 May 2016 07:55:32 +0000 (09:55 +0200)
try_copy_propagate() was special-casing UNIFORM registers (the
BAD_FILE, ARF and FIXED_GRF cases are dead, see the assertion at the
top of the function) and then failing to take into account the
possibility of the instruction reading from a non-zero offset of the
destination of the copy.  The VGRF/ATTR handling takes it into account
correctly, and there is no reason we couldn't use the exact same logic
for the UNIFORM file aside from the fact that uniforms represent
reg_offset in different units.  We can work around that easily by
defining an additional constant with the right unit reg_offset is
expressed in.

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp

index b9ff031bf82af37d5b80c266d13b5c59b9b459f1..bfaeaaa8452b94988e9f741854de8e36b68a9bb5 100644 (file)
@@ -446,27 +446,6 @@ fs_visitor::try_copy_propagate(fs_inst *inst, int arg, acp_entry *entry)
    inst->src[arg].stride *= entry->src.stride;
    inst->saturate = inst->saturate || entry->saturate;
 
-   switch (entry->src.file) {
-   case UNIFORM:
-   case BAD_FILE:
-   case ARF:
-   case FIXED_GRF:
-      inst->src[arg].reg_offset = entry->src.reg_offset;
-      inst->src[arg].subreg_offset = entry->src.subreg_offset;
-      break;
-   case ATTR:
-   case VGRF:
-      {
-         /* In this case, we'll just leave the width alone.  The source
-          * register could have different widths depending on how it is
-          * being used.  For instance, if only half of the register was
-          * used then we want to preserve that and continue to only use
-          * half.
-          *
-          * Also, we have to deal with mapping parts of vgrfs to other
-          * parts of vgrfs so we have to do some reg_offset magic.
-          */
-
          /* Compute the offset of inst->src[arg] relative to entry->dst */
          const unsigned rel_offset = (inst->src[arg].reg_offset
                                       - entry->dst.reg_offset) * REG_SIZE +
@@ -479,21 +458,20 @@ fs_visitor::try_copy_propagate(fs_inst *inst, int arg, acp_entry *entry)
          const unsigned component = rel_offset / type_sz(entry->dst.type);
          const unsigned suboffset = rel_offset % type_sz(entry->dst.type);
 
+         /* Account for the inconsistent units reg_offset is expressed in.
+          * FINISHME -- Make the units of reg_offset consistent (e.g. bytes?)
+          *             for all register files.
+          */
+         const unsigned reg_size = (entry->src.file == UNIFORM ? 4 : REG_SIZE);
+
          /* Calculate the byte offset at the origin of the copy of the given
           * component and suboffset.
           */
          const unsigned offset = suboffset +
             component * entry->src.stride * type_sz(entry->src.type) +
-            entry->src.reg_offset * REG_SIZE + entry->src.subreg_offset;
-         inst->src[arg].reg_offset = offset / REG_SIZE;
-         inst->src[arg].subreg_offset = offset % REG_SIZE;
-      }
-      break;
-
-   case MRF:
-   case IMM:
-      unreachable("not reached");
-   }
+            entry->src.reg_offset * reg_size + entry->src.subreg_offset;
+         inst->src[arg].reg_offset = offset / reg_size;
+         inst->src[arg].subreg_offset = offset % reg_size;
 
    if (has_source_modifiers) {
       if (entry->dst.type != inst->src[arg].type) {