i965/nir: Do not scalarize phis in non-scalar setups
[mesa.git] / src / mesa / drivers / dri / i965 / brw_vec4_copy_propagation.cpp
index 478ae09b6770b1c1cf31c6f6a6dd3b8e9521c5c4..2d9afa8145fcefffc5181237107e304d60e9ddc7 100644 (file)
@@ -74,9 +74,8 @@ is_channel_updated(vec4_instruction *inst, src_reg *values[4], int ch)
    if (!src || src->file != GRF)
       return false;
 
-   return (src->reg == inst->dst.reg &&
-          src->reg_offset == inst->dst.reg_offset &&
-          inst->dst.writemask & (1 << BRW_GET_SWZ(src->swizzle, ch)));
+   return (src->in_range(inst->dst, inst->regs_written) &&
+           inst->dst.writemask & (1 << BRW_GET_SWZ(src->swizzle, ch)));
 }
 
 static unsigned
@@ -105,7 +104,8 @@ is_logic_op(enum opcode opcode)
 }
 
 static bool
-try_constant_propagate(struct brw_context *brw, vec4_instruction *inst,
+try_constant_propagate(const struct brw_device_info *devinfo,
+                       vec4_instruction *inst,
                        int arg, struct copy_entry *entry)
 {
    /* For constant propagation, we only handle the same constant
@@ -133,14 +133,14 @@ try_constant_propagate(struct brw_context *brw, vec4_instruction *inst,
    }
 
    if (inst->src[arg].abs) {
-      if ((brw->gen >= 8 && is_logic_op(inst->opcode)) ||
+      if ((devinfo->gen >= 8 && is_logic_op(inst->opcode)) ||
           !brw_abs_immediate(value.type, &value.fixed_hw_reg)) {
          return false;
       }
    }
 
    if (inst->src[arg].negate) {
-      if ((brw->gen >= 8 && is_logic_op(inst->opcode)) ||
+      if ((devinfo->gen >= 8 && is_logic_op(inst->opcode)) ||
           !brw_negate_immediate(value.type, &value.fixed_hw_reg)) {
          return false;
       }
@@ -152,13 +152,14 @@ try_constant_propagate(struct brw_context *brw, vec4_instruction *inst,
 
    switch (inst->opcode) {
    case BRW_OPCODE_MOV:
+   case SHADER_OPCODE_BROADCAST:
       inst->src[arg] = value;
       return true;
 
    case SHADER_OPCODE_POW:
    case SHADER_OPCODE_INT_QUOTIENT:
    case SHADER_OPCODE_INT_REMAINDER:
-      if (brw->gen < 8)
+      if (devinfo->gen < 8)
          break;
       /* fallthrough */
    case BRW_OPCODE_DP2:
@@ -247,7 +248,8 @@ try_constant_propagate(struct brw_context *brw, vec4_instruction *inst,
 }
 
 static bool
-try_copy_propagate(struct brw_context *brw, vec4_instruction *inst,
+try_copy_propagate(const struct brw_device_info *devinfo,
+                   vec4_instruction *inst,
                    int arg, struct copy_entry *entry)
 {
    /* For constant propagation, we only handle the same constant
@@ -284,7 +286,7 @@ try_copy_propagate(struct brw_context *brw, vec4_instruction *inst,
        value.file != ATTR)
       return false;
 
-   if (brw->gen >= 8 && (value.negate || value.abs) &&
+   if (devinfo->gen >= 8 && (value.negate || value.abs) &&
        is_logic_op(inst->opcode)) {
       return false;
    }
@@ -302,7 +304,7 @@ try_copy_propagate(struct brw_context *brw, vec4_instruction *inst,
     * instructions.
     */
    if ((has_source_modifiers || value.file == UNIFORM ||
-        value.swizzle != BRW_SWIZZLE_XYZW) && !inst->can_do_source_mods(brw))
+        value.swizzle != BRW_SWIZZLE_XYZW) && !inst->can_do_source_mods(devinfo))
       return false;
 
    if (has_source_modifiers && value.type != inst->src[arg].type)
@@ -338,8 +340,8 @@ try_copy_propagate(struct brw_context *brw, vec4_instruction *inst,
       if (dst_saturate_mask != inst->dst.writemask)
          return false;
 
-      /* Limit saturate propagation only to SEL with src1 bounded within 1.0
-       * and 1.0 otherwise, skip copy propagate altogether
+      /* Limit saturate propagation only to SEL with src1 bounded within 0.0
+       * and 1.0, otherwise skip copy propagate altogether.
        */
       switch(inst->opcode) {
       case BRW_OPCODE_SEL:
@@ -397,6 +399,10 @@ vec4_visitor::opt_copy_propagation(bool do_constant_prop)
             inst->src[i].reladdr)
            continue;
 
+         /* We only handle single-register copies. */
+         if (inst->regs_read(i) != 1)
+            continue;
+
         int reg = (alloc.offsets[inst->src[i].reg] +
                    inst->src[i].reg_offset);
 
@@ -430,10 +436,10 @@ vec4_visitor::opt_copy_propagation(bool do_constant_prop)
         if (c != 4)
            continue;
 
-         if (do_constant_prop && try_constant_propagate(brw, inst, i, &entry))
+         if (do_constant_prop && try_constant_propagate(devinfo, inst, i, &entry))
             progress = true;
 
-        if (try_copy_propagate(brw, inst, i, &entry))
+        if (try_copy_propagate(devinfo, inst, i, &entry))
            progress = true;
       }
 
@@ -451,8 +457,9 @@ vec4_visitor::opt_copy_propagation(bool do_constant_prop)
         for (int i = 0; i < 4; i++) {
            if (inst->dst.writemask & (1 << i)) {
                entries[reg].value[i] = direct_copy ? &inst->src[0] : NULL;
-               entries[reg].saturatemask |= (((inst->saturate && direct_copy) ? 1 : 0) << i);
-           }
+               entries[reg].saturatemask |=
+                  inst->saturate && direct_copy ? 1 << i : 0;
+            }
         }
 
         /* Clear the records for any registers whose current value came from
@@ -463,7 +470,7 @@ vec4_visitor::opt_copy_propagation(bool do_constant_prop)
         else {
            for (unsigned i = 0; i < alloc.total_size; i++) {
               for (int j = 0; j < 4; j++) {
-                 if (is_channel_updated(inst, entries[i].value, j)){
+                 if (is_channel_updated(inst, entries[i].value, j)) {
                     entries[i].value[j] = NULL;
                     entries[i].saturatemask &= ~(1 << j);
                   }