From 6fd6374e276644890efc1292d9fdd9a60a7b2b41 Mon Sep 17 00:00:00 2001 From: Rhys Perry Date: Fri, 23 Apr 2021 15:09:01 +0100 Subject: [PATCH] aco/ra: fix get_reg_for_operand() with vector operands MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rhys Perry Reviewed-by: Daniel Schürmann Part-of: --- src/amd/compiler/aco_register_allocation.cpp | 40 +++++++------------- src/amd/compiler/tests/test_regalloc.cpp | 34 +++++++++++++++++ 2 files changed, 48 insertions(+), 26 deletions(-) diff --git a/src/amd/compiler/aco_register_allocation.cpp b/src/amd/compiler/aco_register_allocation.cpp index 583fb252d5f..b821c2e7a28 100644 --- a/src/amd/compiler/aco_register_allocation.cpp +++ b/src/amd/compiler/aco_register_allocation.cpp @@ -644,7 +644,8 @@ void adjust_max_used_regs(ra_ctx& ctx, RegClass rc, unsigned reg) void update_renames(ra_ctx& ctx, RegisterFile& reg_file, std::vector>& parallelcopies, - aco_ptr& instr, bool rename_not_killed_ops) + aco_ptr& instr, bool rename_not_killed_ops, + bool fill_killed_ops=false) { /* clear operands */ for (std::pair& copy : parallelcopies) { @@ -700,7 +701,7 @@ void update_renames(ra_ctx& ctx, RegisterFile& reg_file, op.setTemp(copy.second.getTemp()); op.setFixed(copy.second.physReg()); - fill = !op.isKillBeforeDef(); + fill = fill_killed_ops || !op.isKillBeforeDef(); } } @@ -1730,29 +1731,22 @@ void get_reg_for_operand(ra_ctx& ctx, RegisterFile& register_file, /* check if the operand is fixed */ PhysReg src = ctx.assignments[operand.tempId()].reg; PhysReg dst; - bool blocking_var = false; if (operand.isFixed()) { assert(operand.physReg() != src); /* check if target reg is blocked, and move away the blocking var */ - if (register_file[operand.physReg()]) { - assert(register_file[operand.physReg()] != 0xF0000000); - uint32_t blocking_id = register_file[operand.physReg()]; - RegClass rc = ctx.assignments[blocking_id].rc; - Operand pc_op = Operand(Temp{blocking_id, rc}); - pc_op.setFixed(ctx.assignments[blocking_id].reg); + if (register_file.test(operand.physReg(), operand.bytes())) { + PhysRegInterval target{operand.physReg(), operand.size()}; - /* make space in the register file for get_reg() and then block the target reg */ - register_file.clear(src, operand.regClass()); - register_file.clear(pc_op.physReg(), rc); - register_file.block(operand.physReg(), operand.regClass()); + RegisterFile tmp_file(register_file); - /* find free reg */ - PhysReg reg = get_reg(ctx, register_file, pc_op.getTemp(), parallelcopy, ctx.pseudo_dummy); - update_renames(ctx, register_file, parallelcopy, ctx.pseudo_dummy, true); - Definition pc_def = Definition(reg, pc_op.regClass()); - parallelcopy.emplace_back(pc_op, pc_def); - blocking_var = true; + std::set> blocking_vars = collect_vars(ctx, tmp_file, target); + + tmp_file.clear(src, operand.regClass()); //TODO: try to avoid moving block vars to src + tmp_file.block(operand.physReg(), operand.regClass()); + + DefInfo info(ctx, instr, operand.regClass(), -1); + get_regs_for_copies(ctx, tmp_file, parallelcopy, blocking_vars, info.bounds, instr, PhysRegInterval()); } dst = operand.physReg(); @@ -1765,13 +1759,7 @@ void get_reg_for_operand(ra_ctx& ctx, RegisterFile& register_file, pc_op.setFixed(src); Definition pc_def = Definition(dst, pc_op.regClass()); parallelcopy.emplace_back(pc_op, pc_def); - update_renames(ctx, register_file, parallelcopy, instr, true); - - if (operand.isKillBeforeDef()) - register_file.fill(parallelcopy.back().second); - /* fill in case the blocking var is a killed operand (update_renames() will not fill it) */ - if (blocking_var) - register_file.fill(parallelcopy[parallelcopy.size() - 2].second); + update_renames(ctx, register_file, parallelcopy, instr, true, true); } Temp read_variable(ra_ctx& ctx, Temp val, unsigned block_idx) diff --git a/src/amd/compiler/tests/test_regalloc.cpp b/src/amd/compiler/tests/test_regalloc.cpp index 65a3374e197..bd998b3bde9 100644 --- a/src/amd/compiler/tests/test_regalloc.cpp +++ b/src/amd/compiler/tests/test_regalloc.cpp @@ -113,3 +113,37 @@ BEGIN_TEST(regalloc.precolor.blocking_vector) finish_ra_test(ra_test_policy()); END_TEST + +BEGIN_TEST(regalloc.precolor.vector.test) + //>> s2: %tmp0:s[0-1], s1: %tmp1:s[2], s1: %tmp2:s[3] = p_startpgm + if (!setup_cs("s2 s1 s1", GFX10)) + return; + + //! s1: %tmp2_2:s[0], s2: %tmp0_2:s[2-3] = p_parallelcopy %tmp2:s[3], %tmp0:s[0-1] + //! p_unit_test %tmp0_2:s[2-3] + Operand op(inputs[0]); + op.setFixed(PhysReg(2)); + bld.pseudo(aco_opcode::p_unit_test, op); + + //! p_unit_test %tmp2_2:s[0] + bld.pseudo(aco_opcode::p_unit_test, inputs[2]); + + finish_ra_test(ra_test_policy()); +END_TEST + +BEGIN_TEST(regalloc.precolor.vector.collect) + //>> s2: %tmp0:s[0-1], s1: %tmp1:s[2], s1: %tmp2:s[3] = p_startpgm + if (!setup_cs("s2 s1 s1", GFX10)) + return; + + //! s1: %tmp2_2:s[0], s1: %tmp1_2:s[1], s2: %tmp0_2:s[2-3] = p_parallelcopy %tmp2:s[3], %tmp1:s[2], %tmp0:s[0-1] + //! p_unit_test %tmp0_2:s[2-3] + Operand op(inputs[0]); + op.setFixed(PhysReg(2)); + bld.pseudo(aco_opcode::p_unit_test, op); + + //! p_unit_test %tmp1_2:s[1], %tmp2_2:s[0] + bld.pseudo(aco_opcode::p_unit_test, inputs[1], inputs[2]); + + finish_ra_test(ra_test_policy()); +END_TEST