From: Rhys Perry Date: Mon, 9 Dec 2019 21:20:10 +0000 (+0000) Subject: aco: replace extract_vector with copies X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=92ace0bb31b782ac9ac9592bb62992169337fe22;p=mesa.git aco: replace extract_vector with copies Helps a small number of small shaders with situations like this: a = p_create_vector ... b = p_extract_vector a, 3 and copy propagation can't be done Totals from affected shaders: SGPRS: 14304 -> 14416 (0.78 %) VGPRS: 8716 -> 6592 (-24.37 %) Spilled SGPRs: 0 -> 0 (0.00 %) Spilled VGPRs: 0 -> 0 (0.00 %) Code Size: 184664 -> 176888 (-4.21 %) bytes Max Waves: 6260 -> 6260 (0.00 %) Instructions: 35561 -> 33617 (-5.47 %) Signed-off-by: Rhys Perry Part-of: --- diff --git a/src/amd/compiler/aco_optimizer.cpp b/src/amd/compiler/aco_optimizer.cpp index 605b06c5b1a..19e78f9e656 100644 --- a/src/amd/compiler/aco_optimizer.cpp +++ b/src/amd/compiler/aco_optimizer.cpp @@ -2353,7 +2353,7 @@ void select_instruction(opt_ctx &ctx, aco_ptr& instr) return; } - /* convert split_vector into extract_vector if only one definition is ever used */ + /* convert split_vector into a copy or extract_vector if only one definition is ever used */ if (instr->opcode == aco_opcode::p_split_vector) { unsigned num_used = 0; unsigned idx = 0; @@ -2363,7 +2363,39 @@ void select_instruction(opt_ctx &ctx, aco_ptr& instr) idx = i; } } - if (num_used == 1) { + bool done = false; + if (num_used == 1 && ctx.info[instr->operands[0].tempId()].is_vec() && + ctx.uses[instr->operands[0].tempId()] == 1) { + Instruction *vec = ctx.info[instr->operands[0].tempId()].instr; + + unsigned off = 0; + Operand op; + for (Operand& vec_op : vec->operands) { + if (off == idx * instr->definitions[0].size()) { + op = vec_op; + break; + } + off += vec_op.size(); + } + if (off != instr->operands[0].size()) { + ctx.uses[instr->operands[0].tempId()]--; + for (Operand& vec_op : vec->operands) { + if (vec_op.isTemp()) + ctx.uses[vec_op.tempId()]--; + } + if (op.isTemp()) + ctx.uses[op.tempId()]++; + + aco_ptr extract{create_instruction(aco_opcode::p_create_vector, Format::PSEUDO, 1, 1)}; + extract->operands[0] = op; + extract->definitions[0] = instr->definitions[idx]; + instr.reset(extract.release()); + + done = true; + } + } + + if (!done && num_used == 1) { aco_ptr extract{create_instruction(aco_opcode::p_extract_vector, Format::PSEUDO, 2, 1)}; extract->operands[0] = instr->operands[0]; extract->operands[1] = Operand((uint32_t) idx);