aco: let p_start_linear_vgpr take an operand
authorRhys Perry <pendingchaos02@gmail.com>
Fri, 17 Mar 2023 16:44:25 +0000 (16:44 +0000)
committerMarge Bot <emma+marge@anholt.net>
Thu, 25 May 2023 16:29:16 +0000 (16:29 +0000)
Signed-off-by: Rhys Perry <pendingchaos02@gmail.com>
Reviewed-by: Georg Lehmann <dadschoorse@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22636>

src/amd/compiler/aco_lower_to_hw_instr.cpp
src/amd/compiler/aco_opcodes.py
src/amd/compiler/aco_register_allocation.cpp
src/amd/compiler/aco_validate.cpp

index a008cc0..c048aa4 100644 (file)
@@ -2233,6 +2233,19 @@ lower_to_hw_instr(Program* program)
                handle_operands(copy_operations, &ctx, program->gfx_level, pi);
                break;
             }
+            case aco_opcode::p_start_linear_vgpr: {
+               if (instr->operands.empty())
+                  break;
+
+               Definition def(instr->definitions[0].physReg(),
+                              RegClass::get(RegType::vgpr, instr->definitions[0].bytes()));
+
+               std::map<PhysReg, copy_operation> copy_operations;
+               copy_operations[def.physReg()] = {instr->operands[0], def,
+                                                 instr->operands[0].bytes()};
+               handle_operands(copy_operations, &ctx, program->gfx_level, pi);
+               break;
+            }
             case aco_opcode::p_exit_early_if: {
                /* don't bother with an early exit near the end of the program */
                if ((block->instructions.size() - 1 - instr_idx) <= 4 &&
index d656c0d..5fab419 100644 (file)
@@ -305,7 +305,7 @@ opcode("p_barrier", format=Format.PSEUDO_BARRIER)
 opcode("p_spill")
 opcode("p_reload")
 
-# start/end linear vgprs
+# Start/end linear vgprs. p_start_linear_vgpr can take an operand to copy from, into the linear vgpr
 opcode("p_start_linear_vgpr")
 opcode("p_end_linear_vgpr")
 
index 95de800..1e8625e 100644 (file)
@@ -1890,7 +1890,8 @@ handle_pseudo(ra_ctx& ctx, const RegisterFile& reg_file, Instruction* instr)
    case aco_opcode::p_create_vector:
    case aco_opcode::p_split_vector:
    case aco_opcode::p_parallelcopy:
-   case aco_opcode::p_wqm: break;
+   case aco_opcode::p_wqm:
+   case aco_opcode::p_start_linear_vgpr: break;
    default: return;
    }
 
@@ -2943,7 +2944,9 @@ register_allocation(Program* program, std::vector<IDSet>& live_out_per_block, ra
                      definition->setFixed(reg);
                }
             } else if (instr->opcode == aco_opcode::p_wqm ||
-                       instr->opcode == aco_opcode::p_parallelcopy) {
+                       instr->opcode == aco_opcode::p_parallelcopy ||
+                       (instr->opcode == aco_opcode::p_start_linear_vgpr &&
+                        !instr->operands.empty())) {
                PhysReg reg = instr->operands[i].physReg();
                if (instr->operands[i].isTemp() &&
                    instr->operands[i].getTemp().type() == definition->getTemp().type() &&
index b95e60b..7a21f90 100644 (file)
@@ -585,6 +585,15 @@ validate_ir(Program* program)
                            instr->operands[i].isUndefined(),
                         "Operands of p_dual_src_export_gfx11 must be VGPRs or undef", instr.get());
                }
+            } else if (instr->opcode == aco_opcode::p_start_linear_vgpr) {
+               check(instr->definitions.size() == 1, "Must have one definition", instr.get());
+               check(instr->operands.size() <= 1, "Must have one or zero operands", instr.get());
+               if (!instr->definitions.empty())
+                  check(instr->definitions[0].regClass().is_linear_vgpr(),
+                        "Definition must be linear VGPR", instr.get());
+               if (!instr->definitions.empty() && !instr->operands.empty())
+                  check(instr->definitions[0].bytes() == instr->operands[0].bytes(),
+                        "Operand size must match definition", instr.get());
             }
             break;
          }