i965/fs: Add fs_reg::is_zero() and is_one(); use for opt_algebraic().
authorKenneth Graunke <kenneth@whitecape.org>
Sat, 17 Nov 2012 23:10:53 +0000 (15:10 -0800)
committerEric Anholt <eric@anholt.net>
Fri, 30 Nov 2012 21:15:39 +0000 (13:15 -0800)
These helper macros save you from writing nasty expressions like:

   if ((inst->src[1].type == BRW_REGISTER_TYPE_F &&
         inst->src[1].imm.f == 1.0) ||
        ((inst->src[1].type == BRW_REGISTER_TYPE_D ||
          inst->src[1].type == BRW_REGISTER_TYPE_UD) &&
         inst->src[1].imm.u == 1)) {

Instead, you simply get to write inst->src[1].is_one().  Simple.
Also, this makes the FS backend match the VS backend (which has these).

This patch also converts opt_algebraic to use the new helper functions.
As a consequence, it will now also optimize integer-typed expressions.

Reviewed-by: Eric Anholt <eric@anholt.net>
src/mesa/drivers/dri/i965/brw_fs.cpp
src/mesa/drivers/dri/i965/brw_fs.h

index cc5a790dc9cf1c48237c8c1559e537295bc0c728..ee3b7fd9be668365220f8714feffcd8ce0962e33 100644 (file)
@@ -353,6 +353,24 @@ fs_reg::equals(const fs_reg &r) const
            imm.u == r.imm.u);
 }
 
+bool
+fs_reg::is_zero() const
+{
+   if (file != IMM)
+      return false;
+
+   return type == BRW_REGISTER_TYPE_F ? imm.f == 0.0 : imm.i == 0;
+}
+
+bool
+fs_reg::is_one() const
+{
+   if (file != IMM)
+      return false;
+
+   return type == BRW_REGISTER_TYPE_F ? imm.f == 1.0 : imm.i == 1;
+}
+
 int
 fs_visitor::type_size(const struct glsl_type *type)
 {
@@ -1430,8 +1448,7 @@ fs_visitor::opt_algebraic()
            continue;
 
         /* a * 1.0 = a */
-        if (inst->src[1].type == BRW_REGISTER_TYPE_F &&
-            inst->src[1].imm.f == 1.0) {
+        if (inst->src[1].is_one()) {
            inst->opcode = BRW_OPCODE_MOV;
            inst->src[1] = reg_undef;
            progress = true;
@@ -1439,10 +1456,9 @@ fs_visitor::opt_algebraic()
         }
 
          /* a * 0.0 = 0.0 */
-         if (inst->src[1].type == BRW_REGISTER_TYPE_F &&
-             inst->src[1].imm.f == 0.0) {
+         if (inst->src[1].is_zero()) {
             inst->opcode = BRW_OPCODE_MOV;
-            inst->src[0] = fs_reg(0.0f);
+            inst->src[0] = inst->src[1];
             inst->src[1] = reg_undef;
             progress = true;
             break;
@@ -1454,8 +1470,7 @@ fs_visitor::opt_algebraic()
             continue;
 
          /* a + 0.0 = a */
-         if (inst->src[1].type == BRW_REGISTER_TYPE_F &&
-             inst->src[1].imm.f == 0.0) {
+         if (inst->src[1].is_zero()) {
             inst->opcode = BRW_OPCODE_MOV;
             inst->src[1] = reg_undef;
             progress = true;
index a0ed743486bfc4f6751659dd390a47202138d61f..86c33bc8b0f2d1e8fd419a09b4a20d7b6963da9b 100644 (file)
@@ -91,6 +91,8 @@ public:
    fs_reg(class fs_visitor *v, const struct glsl_type *type);
 
    bool equals(const fs_reg &r) const;
+   bool is_zero() const;
+   bool is_one() const;
 
    /** Register file: ARF, GRF, MRF, IMM. */
    enum register_file file;