[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