From dfb0ba82727aeaa8c5fafe6dfce0c926e41202cf Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Wed, 6 May 2020 23:28:30 +0200 Subject: [PATCH] r600/sfn: Skip move instructions if they are only ssa and without modifiers Signed-off-by: Gert Wollny Reviewed-by: Reviewed-by: Dave Airlie Part-of: --- .../r600/sfn/sfn_emitaluinstruction.cpp | 26 ++++++++++++++++++- .../drivers/r600/sfn/sfn_emitaluinstruction.h | 1 + 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/r600/sfn/sfn_emitaluinstruction.cpp b/src/gallium/drivers/r600/sfn/sfn_emitaluinstruction.cpp index 566e253bcb5..35da6d4ef4d 100644 --- a/src/gallium/drivers/r600/sfn/sfn_emitaluinstruction.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_emitaluinstruction.cpp @@ -56,7 +56,7 @@ bool EmitAluInstruction::do_emit(nir_instr* ir) case nir_op_i2b1: return emit_alu_i2orf2_b1(instr, op2_setne_int); case nir_op_f2b1: return emit_alu_i2orf2_b1(instr, op2_setne_dx10); case nir_op_b2b1: - case nir_op_mov:return emit_alu_op1(instr, op1_mov); + case nir_op_mov:return emit_mov(instr); case nir_op_ftrunc: return emit_alu_op1(instr, op1_trunc); case nir_op_fabs: return emit_alu_op1(instr, op1_mov, {1 << alu_src0_abs}); case nir_op_fneg: return emit_alu_op1(instr, op1_mov, {1 << alu_src0_neg}); @@ -262,6 +262,30 @@ bool EmitAluInstruction::emit_alu_op1(const nir_alu_instr& instr, EAluOp opcode, return true; } +bool EmitAluInstruction::emit_mov(const nir_alu_instr& instr) +{ + /* If the op is a plain move beween SSA values we can just forward + * the register reference to the original register */ + if (instr.dest.dest.is_ssa && instr.src[0].src.is_ssa && + !instr.src[0].abs && !instr.src[0].negate && !instr.dest.saturate) { + bool result = true; + for (int i = 0; i < 4 ; ++i) { + if (instr.dest.write_mask & (1 << i)){ + auto src = from_nir(instr.src[0], i); + result &= inject_register(instr.dest.dest.ssa.index, i, + src, true); + + if (src->type() == Value::kconst) { + add_uniform((instr.dest.dest.ssa.index << 2) + i, src); + } + } + } + return result; + } else { + return emit_alu_op1(instr, op1_mov); + } +} + bool EmitAluInstruction::emit_alu_trig_op1(const nir_alu_instr& instr, EAluOp opcode) { // normalize by dividing by 2*PI, shift by 0.5, take fraction, and diff --git a/src/gallium/drivers/r600/sfn/sfn_emitaluinstruction.h b/src/gallium/drivers/r600/sfn/sfn_emitaluinstruction.h index ede38fbc163..3b26af7b0ee 100644 --- a/src/gallium/drivers/r600/sfn/sfn_emitaluinstruction.h +++ b/src/gallium/drivers/r600/sfn/sfn_emitaluinstruction.h @@ -53,6 +53,7 @@ private: void split_constants(const nir_alu_instr& instr); + bool emit_mov(const nir_alu_instr& instr); bool emit_alu_op1(const nir_alu_instr& instr, EAluOp opcode, const AluOpFlags &flags = 0); bool emit_alu_op2(const nir_alu_instr& instr, EAluOp opcode, AluOp2Opts ops = op2_opt_none); bool emit_alu_op2_split_src_mods(const nir_alu_instr& instr, EAluOp opcode, AluOp2Opts ops = op2_opt_none); -- 2.30.2