[Mesa-dev] [PATCH 47/50] glsl: add a lowering pass for dfma to dmuladd.

Dave Airlie airlied at gmail.com
Tue Mar 13 04:25:12 UTC 2018


From: Dave Airlie <airlied at redhat.com>

Just lowering dfma to dmuladd for now, I don't think it will matter
for anything we care about.

This also fixes the double dot to fma lowering to take this
flag into account and avoid creating further fma's.

Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 src/compiler/glsl/ir_optimization.h      |  1 +
 src/compiler/glsl/lower_instructions.cpp | 35 ++++++++++++++++++++++++++++----
 2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/src/compiler/glsl/ir_optimization.h b/src/compiler/glsl/ir_optimization.h
index e6f9ad3..38e35e3 100644
--- a/src/compiler/glsl/ir_optimization.h
+++ b/src/compiler/glsl/ir_optimization.h
@@ -57,6 +57,7 @@
 #define DMIN_DMAX_TO_LESS         0x400000
 #define DOPS_TO_DTRUNC            0x800000
 #define DRSQ_TO_DRCP              0x1000000
+#define DFMA_TO_DMULADD           0x2000000
 
 /* Opertaions for lower_64bit_integer_instructions() */
 #define MUL64                     (1U << 0)
diff --git a/src/compiler/glsl/lower_instructions.cpp b/src/compiler/glsl/lower_instructions.cpp
index d13a99b..b8f7224 100644
--- a/src/compiler/glsl/lower_instructions.cpp
+++ b/src/compiler/glsl/lower_instructions.cpp
@@ -184,7 +184,7 @@ private:
    void dceil_to_dtrunc(ir_expression *ir);
    void dfrac_to_dtrunc(ir_expression *ir);
    void drsq_to_drcp(ir_expression *ir);
-
+   void dfma_to_dmuladd(ir_expression *ir);
    ir_expression *_carry(operand a, operand b);
 };
 
@@ -873,9 +873,12 @@ lower_instructions_visitor::double_dot_to_fma(ir_expression *ir)
          assig = assign(temp, mul(swizzle(ir->operands[0]->clone(ir, NULL), i, 1),
                                   swizzle(ir->operands[1]->clone(ir, NULL), i, 1)));
       } else {
-         assig = assign(temp, fma(swizzle(ir->operands[0]->clone(ir, NULL), i, 1),
-                                  swizzle(ir->operands[1]->clone(ir, NULL), i, 1),
-                                  temp));
+         ir_expression *fma_expr = fma(swizzle(ir->operands[0]->clone(ir, NULL), i, 1),
+                                       swizzle(ir->operands[1]->clone(ir, NULL), i, 1),
+                                       temp);
+         if (lowering(DFMA_TO_DMULADD))
+            dfma_to_dmuladd(fma_expr);
+         assig = assign(temp, fma_expr);
       }
       this->base_ir->insert_before(assig);
    }
@@ -886,6 +889,8 @@ lower_instructions_visitor::double_dot_to_fma(ir_expression *ir)
    ir->operands[1] = swizzle(ir->operands[1], 0, 1);
    ir->operands[2] = new(ir) ir_dereference_variable(temp);
 
+   if (lowering(DFMA_TO_DMULADD))
+      dfma_to_dmuladd(ir);
    this->progress = true;
 
 }
@@ -1783,6 +1788,22 @@ lower_instructions_visitor::dfrac_to_dtrunc(ir_expression *ir)
 }
 
 void
+lower_instructions_visitor::dfma_to_dmuladd(ir_expression *ir)
+{
+   ir_variable *temp = new(ir) ir_variable(ir->operands[0]->type, "temp",
+                                           ir_var_temporary);
+   ir_rvalue *arg = ir->operands[2];
+   ir_instruction &i = *base_ir;
+   i.insert_before(temp);
+   i.insert_before(assign(temp, mul(ir->operands[0], ir->operands[1])));
+
+   ir->operation = ir_binop_add;
+   ir->init_num_operands();
+   ir->operands[0] = new(ir) ir_dereference_variable(temp);
+   ir->operands[1] = arg->clone(ir, NULL);
+   this->progress = true;
+}
+void
 lower_instructions_visitor::drsq_to_drcp(ir_expression *ir)
 {
    ir_expression *const sqrt_expr =
@@ -1976,6 +1997,12 @@ lower_instructions_visitor::visit_leave(ir_expression *ir)
          dfrac_to_dtrunc(ir);
       break;
 
+   case ir_triop_fma:
+      if (lowering(DFMA_TO_DMULADD) &&
+          ir->type->is_double())
+         dfma_to_dmuladd(ir);
+      break;
+
    default:
       return visit_continue;
    }
-- 
2.9.5



More information about the mesa-dev mailing list