i965/vec4: Replace vec4_instruction::regs_written with ::size_written field in bytes.
[mesa.git] / src / mesa / drivers / dri / i965 / brw_vec4_cse.cpp
index 2c29d9f89996283b9c524fd7bc223d71e1e567ae..1b91db95a8097042ae4816bd6f6aa0d1df34a363 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include "brw_vec4.h"
+#include "brw_vec4_live_variables.h"
 #include "brw_cfg.h"
 
 using namespace brw;
@@ -61,6 +62,7 @@ is_expression(const vec4_instruction *const inst)
    case BRW_OPCODE_CMPN:
    case BRW_OPCODE_ADD:
    case BRW_OPCODE_MUL:
+   case SHADER_OPCODE_MULH:
    case BRW_OPCODE_FRC:
    case BRW_OPCODE_RNDU:
    case BRW_OPCODE_RNDD:
@@ -71,6 +73,10 @@ is_expression(const vec4_instruction *const inst)
    case BRW_OPCODE_MAD:
    case BRW_OPCODE_LRP:
    case VEC4_OPCODE_UNPACK_UNIFORM:
+   case SHADER_OPCODE_FIND_LIVE_CHANNEL:
+   case SHADER_OPCODE_BROADCAST:
+   case TCS_OPCODE_SET_INPUT_URB_OFFSETS:
+   case TCS_OPCODE_SET_OUTPUT_URB_OFFSETS:
       return true;
    case SHADER_OPCODE_RCP:
    case SHADER_OPCODE_RSQ:
@@ -111,9 +117,19 @@ instructions_match(vec4_instruction *a, vec4_instruction *b)
 {
    return a->opcode == b->opcode &&
           a->saturate == b->saturate &&
+          a->predicate == b->predicate &&
+          a->predicate_inverse == b->predicate_inverse &&
           a->conditional_mod == b->conditional_mod &&
+          a->flag_subreg == b->flag_subreg &&
           a->dst.type == b->dst.type &&
+          a->offset == b->offset &&
+          a->mlen == b->mlen &&
+          a->base_mrf == b->base_mrf &&
+          a->header_size == b->header_size &&
+          a->shadow_compare == b->shadow_compare &&
           a->dst.writemask == b->dst.writemask &&
+          a->force_writemask_all == b->force_writemask_all &&
+          a->size_written == b->size_written &&
           operands_match(a, b);
 }
 
@@ -129,7 +145,8 @@ vec4_visitor::opt_cse_local(bblock_t *block)
    foreach_inst_in_block (vec4_instruction, inst, block) {
       /* Skip some cases. */
       if (is_expression(inst) && !inst->predicate && inst->mlen == 0 &&
-          (inst->dst.file != HW_REG || inst->dst.is_null()))
+          ((inst->dst.file != ARF && inst->dst.file != FIXED_GRF) ||
+           inst->dst.is_null()))
       {
          bool found = false;
 
@@ -160,21 +177,31 @@ vec4_visitor::opt_cse_local(bblock_t *block)
              */
             bool no_existing_temp = entry->tmp.file == BAD_FILE;
             if (no_existing_temp && !entry->generator->dst.is_null()) {
-               entry->tmp = src_reg(this, glsl_type::float_type);
-               entry->tmp.type = inst->dst.type;
-               entry->tmp.swizzle = BRW_SWIZZLE_XYZW;
+               entry->tmp = retype(src_reg(VGRF, alloc.allocate(
+                                              regs_written(entry->generator)),
+                                           NULL), inst->dst.type);
+
+               for (unsigned i = 0; i < regs_written(entry->generator); ++i) {
+                  vec4_instruction *copy = MOV(offset(entry->generator->dst, i),
+                                               offset(entry->tmp, i));
+                  copy->force_writemask_all =
+                     entry->generator->force_writemask_all;
+                  entry->generator->insert_after(block, copy);
+               }
 
-               vec4_instruction *copy = MOV(entry->generator->dst, entry->tmp);
-               entry->generator->insert_after(block, copy);
                entry->generator->dst = dst_reg(entry->tmp);
             }
 
             /* dest <- temp */
             if (!inst->dst.is_null()) {
                assert(inst->dst.type == entry->tmp.type);
-               vec4_instruction *copy = MOV(inst->dst, entry->tmp);
-               copy->force_writemask_all = inst->force_writemask_all;
-               inst->insert_before(block, copy);
+
+               for (unsigned i = 0; i < regs_written(inst); ++i) {
+                  vec4_instruction *copy = MOV(offset(inst->dst, i),
+                                               offset(entry->tmp, i));
+                  copy->force_writemask_all = inst->force_writemask_all;
+                  inst->insert_before(block, copy);
+               }
             }
 
             /* Set our iterator so that next time through the loop inst->next
@@ -209,7 +236,7 @@ vec4_visitor::opt_cse_local(bblock_t *block)
              * overwrote.
              */
             if (inst->dst.file == entry->generator->src[i].file &&
-                inst->dst.reg == entry->generator->src[i].reg) {
+                inst->dst.nr == entry->generator->src[i].nr) {
                entry->remove();
                ralloc_free(entry);
                break;
@@ -218,14 +245,8 @@ vec4_visitor::opt_cse_local(bblock_t *block)
             /* Kill any AEB entries using registers that don't get reused any
              * more -- a sure sign they'll fail operands_match().
              */
-            if (src->file == GRF) {
-               assert((unsigned)(src->reg * 4 + 3) < (alloc.count * 4));
-
-               int last_reg_use = MAX2(MAX2(virtual_grf_end[src->reg * 4 + 0],
-                                            virtual_grf_end[src->reg * 4 + 1]),
-                                       MAX2(virtual_grf_end[src->reg * 4 + 2],
-                                            virtual_grf_end[src->reg * 4 + 3]));
-               if (last_reg_use < ip) {
+            if (src->file == VGRF) {
+               if (var_range_end(var_from_reg(alloc, dst_reg(*src)), 4) < ip) {
                   entry->remove();
                   ralloc_free(entry);
                   break;