Mesa (main): aco/ra: refactor register assignment for vector operands
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Fri Jun 11 10:53:23 UTC 2021
Module: Mesa
Branch: main
Commit: bb1c06343d85158bf4ac12b90e0f768cd7267640
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=bb1c06343d85158bf4ac12b90e0f768cd7267640
Author: Daniel Schürmann <daniel at schuermann.dev>
Date: Tue Jan 26 19:05:23 2021 +0100
aco/ra: refactor register assignment for vector operands
No functional changes.
Reviewed-by: Tony Wasserka <tony.wasserka at gmx.de>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8764>
---
src/amd/compiler/aco_register_allocation.cpp | 98 ++++++++++++++++------------
1 file changed, 58 insertions(+), 40 deletions(-)
diff --git a/src/amd/compiler/aco_register_allocation.cpp b/src/amd/compiler/aco_register_allocation.cpp
index 4d519cd884b..441fcf8cc79 100644
--- a/src/amd/compiler/aco_register_allocation.cpp
+++ b/src/amd/compiler/aco_register_allocation.cpp
@@ -1388,6 +1388,59 @@ bool is_mimg_vaddr_intact(ra_ctx& ctx, RegisterFile& reg_file, Instruction *inst
return true;
}
+std::pair<PhysReg, bool> get_reg_vector(ra_ctx& ctx,
+ RegisterFile& reg_file,
+ Temp temp,
+ aco_ptr<Instruction>& instr)
+{
+ Instruction* vec = ctx.vectors[temp.id()];
+ unsigned first_operand = vec->format == Format::MIMG ? 3 : 0;
+ unsigned our_offset = 0;
+ for (unsigned i = first_operand; i < vec->operands.size(); i++) {
+ Operand& op = vec->operands[i];
+ if (op.isTemp() && op.tempId() == temp.id())
+ break;
+ else
+ our_offset += op.bytes();
+ }
+
+ if (vec->format != Format::MIMG || is_mimg_vaddr_intact(ctx, reg_file, vec)) {
+ unsigned their_offset = 0;
+ /* check for every operand of the vector
+ * - whether the operand is assigned and
+ * - we can use the register relative to that operand
+ */
+ for (unsigned i = first_operand; i < vec->operands.size(); i++) {
+ Operand& op = vec->operands[i];
+ if (op.isTemp() &&
+ op.tempId() != temp.id() &&
+ op.getTemp().type() == temp.type() &&
+ ctx.assignments[op.tempId()].assigned) {
+ PhysReg reg = ctx.assignments[op.tempId()].reg;
+ reg.reg_b += (our_offset - their_offset);
+ if (get_reg_specified(ctx, reg_file, temp.regClass(), instr, reg))
+ return {reg, true};
+ }
+ their_offset += op.bytes();
+ }
+
+ /* We didn't find a register relative to other vector operands.
+ * Try to find new space which fits the whole vector.
+ */
+ RegClass vec_rc = RegClass::get(temp.type(), their_offset);
+ DefInfo info(ctx, ctx.pseudo_dummy, vec_rc, -1);
+ std::pair<PhysReg, bool> res = get_reg_simple(ctx, reg_file, info);
+ PhysReg reg = res.first;
+ if (res.second) {
+ reg.reg_b += our_offset;
+ /* make sure to only use byte offset if the instruction supports it */
+ if (get_reg_specified(ctx, reg_file, temp.regClass(), instr, reg))
+ return {reg, true};
+ }
+ }
+ return {{}, false};
+}
+
PhysReg get_reg(ra_ctx& ctx,
RegisterFile& reg_file,
Temp temp,
@@ -1417,51 +1470,16 @@ PhysReg get_reg(ra_ctx& ctx,
return reg;
}
- if (ctx.vectors.find(temp.id()) != ctx.vectors.end()) {
- Instruction* vec = ctx.vectors[temp.id()];
- unsigned first_operand = vec->format == Format::MIMG ? 3 : 0;
- unsigned byte_offset = 0;
- for (unsigned i = first_operand; i < vec->operands.size(); i++) {
- Operand& op = vec->operands[i];
- if (op.isTemp() && op.tempId() == temp.id())
- break;
- else
- byte_offset += op.bytes();
- }
-
- if (vec->format != Format::MIMG || is_mimg_vaddr_intact(ctx, reg_file, vec)) {
- unsigned k = 0;
- for (unsigned i = first_operand; i < vec->operands.size(); i++) {
- Operand& op = vec->operands[i];
- if (op.isTemp() &&
- op.tempId() != temp.id() &&
- op.getTemp().type() == temp.type() &&
- ctx.assignments[op.tempId()].assigned) {
- PhysReg reg = ctx.assignments[op.tempId()].reg;
- reg.reg_b += (byte_offset - k);
- if (get_reg_specified(ctx, reg_file, temp.regClass(), instr, reg))
- return reg;
- }
- k += op.bytes();
- }
+ std::pair<PhysReg, bool> res;
- RegClass vec_rc = RegClass::get(temp.type(), k);
- DefInfo info(ctx, ctx.pseudo_dummy, vec_rc, -1);
- std::pair<PhysReg, bool> res = get_reg_simple(ctx, reg_file, info);
- PhysReg reg = res.first;
- if (res.second) {
- reg.reg_b += byte_offset;
- /* make sure to only use byte offset if the instruction supports it */
- if (get_reg_specified(ctx, reg_file, temp.regClass(), instr, reg))
- return reg;
- }
- }
+ if (ctx.vectors.find(temp.id()) != ctx.vectors.end()) {
+ res = get_reg_vector(ctx, reg_file, temp, instr);
+ if (res.second)
+ return res.first;
}
DefInfo info(ctx, instr, temp.regClass(), operand_index);
- std::pair<PhysReg, bool> res;
-
if (!ctx.policy.skip_optimistic_path) {
/* try to find space without live-range splits */
res = get_reg_simple(ctx, reg_file, info);
More information about the mesa-commit
mailing list