i965/fs: Make virtual grf live intervals actually cover their used range.
[mesa.git] / src / mesa / drivers / dri / i965 / brw_fs.cpp
index b45035e80f038cc9e85da1844a72f7fc531e7545..baaa25c13473171ae963b150c021cd92f908653b 100644 (file)
@@ -173,6 +173,13 @@ ALU2(SHL)
 ALU2(SHR)
 ALU2(ASR)
 ALU3(LRP)
+ALU1(BFREV)
+ALU3(BFE)
+ALU2(BFI1)
+ALU3(BFI2)
+ALU1(FBH)
+ALU1(FBL)
+ALU1(CBIT)
 
 /** Gen4 predicated IF. */
 fs_inst *
@@ -218,7 +225,7 @@ fs_visitor::CMP(fs_reg dst, fs_reg src0, fs_reg src1, uint32_t condition)
     */
    if (intel->gen == 4) {
       dst.type = src0.type;
-      if (dst.file == FIXED_HW_REG)
+      if (dst.file == HW_REG)
         dst.fixed_hw_reg.type = dst.type;
    }
 
@@ -405,7 +412,7 @@ fs_reg::fs_reg(uint32_t u)
 fs_reg::fs_reg(struct brw_reg fixed_hw_reg)
 {
    init();
-   this->file = FIXED_HW_REG;
+   this->file = HW_REG;
    this->fixed_hw_reg = fixed_hw_reg;
    this->type = fixed_hw_reg.type;
 }
@@ -444,6 +451,12 @@ fs_reg::is_one() const
    return type == BRW_REGISTER_TYPE_F ? imm.f == 1.0 : imm.i == 1;
 }
 
+bool
+fs_reg::is_valid_3src() const
+{
+   return file == GRF || file == UNIFORM;
+}
+
 int
 fs_visitor::type_size(const struct glsl_type *type)
 {
@@ -1206,7 +1219,7 @@ fs_visitor::assign_curb_setup()
                                                  constant_nr / 8,
                                                  constant_nr % 8);
 
-           inst->src[i].file = FIXED_HW_REG;
+           inst->src[i].file = HW_REG;
            inst->src[i].fixed_hw_reg = retype(brw_reg, inst->src[i].type);
         }
       }
@@ -1274,12 +1287,12 @@ fs_visitor::assign_urb_setup()
       fs_inst *inst = (fs_inst *)node;
 
       if (inst->opcode == FS_OPCODE_LINTERP) {
-        assert(inst->src[2].file == FIXED_HW_REG);
+        assert(inst->src[2].file == HW_REG);
         inst->src[2].fixed_hw_reg.nr += urb_start;
       }
 
       if (inst->opcode == FS_OPCODE_CINTERP) {
-        assert(inst->src[0].file == FIXED_HW_REG);
+        assert(inst->src[0].file == HW_REG);
         inst->src[0].fixed_hw_reg.nr += urb_start;
       }
    }
@@ -1443,8 +1456,8 @@ fs_visitor::compact_virtual_grfs()
          remap_table[i] = new_index;
          virtual_grf_sizes[new_index] = virtual_grf_sizes[i];
          if (live_intervals_valid) {
-            virtual_grf_use[new_index] = virtual_grf_use[i];
-            virtual_grf_def[new_index] = virtual_grf_def[i];
+            virtual_grf_start[new_index] = virtual_grf_start[i];
+            virtual_grf_end[new_index] = virtual_grf_end[i];
          }
          ++new_index;
       }
@@ -1758,10 +1771,8 @@ fs_visitor::opt_algebraic()
 }
 
 /**
- * Must be called after calculate_live_intervales() to remove unused
- * writes to registers -- register allocation will fail otherwise
- * because something deffed but not used won't be considered to
- * interfere with other regs.
+ * Removes any instructions writing a VGRF where that VGRF is not used by any
+ * later instruction.
  */
 bool
 fs_visitor::dead_code_eliminate()
@@ -1774,9 +1785,12 @@ fs_visitor::dead_code_eliminate()
    foreach_list_safe(node, &this->instructions) {
       fs_inst *inst = (fs_inst *)node;
 
-      if (inst->dst.file == GRF && this->virtual_grf_use[inst->dst.reg] <= pc) {
-        inst->remove();
-        progress = true;
+      if (inst->dst.file == GRF) {
+         assert(this->virtual_grf_end[inst->dst.reg] >= pc);
+         if (this->virtual_grf_end[inst->dst.reg] == pc) {
+            inst->remove();
+            progress = true;
+         }
       }
 
       pc++;
@@ -2188,7 +2202,7 @@ fs_visitor::compute_to_mrf()
       /* Can't compute-to-MRF this GRF if someone else was going to
        * read it later.
        */
-      if (this->virtual_grf_use[inst->src[0].reg] > ip)
+      if (this->virtual_grf_end[inst->src[0].reg] > ip)
         continue;
 
       /* Found a move of a GRF to a MRF.  Let's see if we can go
@@ -2396,7 +2410,7 @@ clear_deps_for_inst_src(fs_inst *inst, int dispatch_width, bool *deps,
       int grf;
       if (inst->src[i].file == GRF) {
          grf = inst->src[i].reg;
-      } else if (inst->src[i].file == FIXED_HW_REG &&
+      } else if (inst->src[i].file == HW_REG &&
                  inst->src[i].fixed_hw_reg.file == BRW_GENERAL_REGISTER_FILE) {
          grf = inst->src[i].fixed_hw_reg.nr;
       } else {
@@ -2659,8 +2673,10 @@ fs_visitor::lower_uniform_pull_constant_loads()
 }
 
 void
-fs_visitor::dump_instruction(fs_inst *inst)
+fs_visitor::dump_instruction(backend_instruction *be_inst)
 {
+   fs_inst *inst = (fs_inst *)be_inst;
+
    if (inst->predicate) {
       printf("(%cf0.%d) ",
              inst->predicate_inverse ? '-' : '+',
@@ -2763,17 +2779,6 @@ fs_visitor::dump_instruction(fs_inst *inst)
    printf("\n");
 }
 
-void
-fs_visitor::dump_instructions()
-{
-   int ip = 0;
-   foreach_list(node, &this->instructions) {
-      fs_inst *inst = (fs_inst *)node;
-      printf("%d: ", ip++);
-      dump_instruction(inst);
-   }
-}
-
 /**
  * Possibly returns an instruction that set up @param reg.
  *