i965/fs: add helper to retrieve instruction execution type
authorJuan A. Suarez Romero <jasuarez@igalia.com>
Mon, 18 Jul 2016 07:17:39 +0000 (07:17 +0000)
committerFrancisco Jerez <currojerez@riseup.net>
Fri, 14 Apr 2017 21:56:07 +0000 (14:56 -0700)
The execution data size is the biggest type size of any instruction
operand.

We will use it to know if the instruction deals with DF, because in Ivy
we need to double the execution size and regioning parameters.

v2:
- Fix typo in commit log (Matt)
- Use static inline function instead of fs_inst's method (Curro).
- Define the result as a constant (Curro).
- Fix indentation (Matt).
- Add braces to nested control flow (Matt).

v3 (Curro):
- Add get_exec_type() and other auxiliary functions and use them to
  calculate its size.

Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
[ Francisco Jerez: Fix bogus 'type != BAD_FILE' check.  Fix deduced
  execution type for integer vector types.  Take destination type as
  execution type where there is no valid source.  Assert-fail if the
  deduced execution type is byte.  Move into brw_ir_fs.h header for
  consistency with the VEC4 back-end. ]
Reviewed-by: Francisco Jerez <currojerez@riseup.net>
src/intel/compiler/brw_fs.cpp
src/intel/compiler/brw_ir_fs.h
src/intel/compiler/brw_reg.h

index 9dc21ac5e38848a32c68c821ed9541643983ad11..3fc7ae48943427bbf7e552552154aa2264ce17d5 100644 (file)
@@ -4585,11 +4585,7 @@ get_fpu_lowered_simd_width(const struct gen_device_info *devinfo,
        !inst->force_writemask_all) {
       const unsigned channels_per_grf = inst->exec_size /
          DIV_ROUND_UP(inst->size_written, REG_SIZE);
-      unsigned exec_type_size = 0;
-      for (int i = 0; i < inst->sources; i++) {
-         if (inst->src[i].file != BAD_FILE)
-            exec_type_size = MAX2(exec_type_size, type_sz(inst->src[i].type));
-      }
+      const unsigned exec_type_size = get_exec_type_size(inst);
       assert(exec_type_size);
 
       /* The hardware shifts exactly 8 channels per compressed half of the
index cad371248c49112a219d030798c31c33398cc23a..58beae0d1f0198c68439fe617fd400fbe96e6e43 100644 (file)
@@ -448,4 +448,37 @@ regs_read(const fs_inst *inst, unsigned i)
                        reg_size);
 }
 
+static inline enum brw_reg_type
+get_exec_type(const fs_inst *inst)
+{
+   brw_reg_type exec_type = BRW_REGISTER_TYPE_B;
+
+   for (int i = 0; i < inst->sources; i++) {
+      if (inst->src[i].file != BAD_FILE) {
+         const brw_reg_type t = get_exec_type(inst->src[i].type);
+         if (type_sz(t) > type_sz(exec_type))
+            exec_type = t;
+         else if (type_sz(t) == type_sz(exec_type) &&
+                  brw_reg_type_is_floating_point(t))
+            exec_type = t;
+      }
+   }
+
+   if (exec_type == BRW_REGISTER_TYPE_B)
+      exec_type = inst->dst.type;
+
+   /* TODO: We need to handle half-float conversions. */
+   assert(exec_type != BRW_REGISTER_TYPE_HF ||
+          inst->dst.type == BRW_REGISTER_TYPE_HF);
+   assert(exec_type != BRW_REGISTER_TYPE_B);
+
+   return exec_type;
+}
+
+static inline unsigned
+get_exec_type_size(const fs_inst *inst)
+{
+   return type_sz(get_exec_type(inst));
+}
+
 #endif
index f8c3340e452b41f60bf3bf6634f854af67c31f54..17a51fbd6556bb4bde17bc0fdb1c1962a9e09a5d 100644 (file)
@@ -325,6 +325,36 @@ type_sz(unsigned type)
    }
 }
 
+static inline bool
+brw_reg_type_is_floating_point(enum brw_reg_type type)
+{
+   switch (type) {
+   case BRW_REGISTER_TYPE_F:
+   case BRW_REGISTER_TYPE_HF:
+   case BRW_REGISTER_TYPE_DF:
+      return true;
+   default:
+      return false;
+   }
+}
+
+static inline enum brw_reg_type
+get_exec_type(const enum brw_reg_type type)
+{
+   switch (type) {
+   case BRW_REGISTER_TYPE_B:
+   case BRW_REGISTER_TYPE_V:
+      return BRW_REGISTER_TYPE_W;
+   case BRW_REGISTER_TYPE_UB:
+   case BRW_REGISTER_TYPE_UV:
+      return BRW_REGISTER_TYPE_UW;
+   case BRW_REGISTER_TYPE_VF:
+      return BRW_REGISTER_TYPE_F;
+   default:
+      return type;
+   }
+}
+
 /**
  * Return an integer type of the requested size and signedness.
  */