aco: don't create vector affinities for operands which are not killed or are duplicates
[mesa.git] / src / amd / compiler / aco_register_allocation.cpp
index 4eaf9b1742aecbb40236b7f3b6fa1b071798c7f0..a3e01b11c68359ea6b78a3b2f40edeaa968a68c8 100644 (file)
@@ -395,6 +395,14 @@ std::pair<PhysReg, bool> get_reg_simple(ra_ctx& ctx,
 
    /* best fit algorithm: find the smallest gap to fit in the variable */
    if (stride == 1) {
+
+      if (rc.type() == RegType::vgpr && (size == 4 || size == 8)) {
+         info.stride = 4;
+         std::pair<PhysReg, bool> res = get_reg_simple(ctx, reg_file, info);
+         if (res.second)
+            return res;
+      }
+
       unsigned best_pos = 0xFFFF;
       unsigned gap_size = 0xFFFF;
       unsigned next_pos = 0xFFFF;
@@ -935,14 +943,7 @@ PhysReg get_reg(ra_ctx& ctx,
    DefInfo info(ctx, instr, temp.regClass());
 
    /* try to find space without live-range splits */
-   std::pair<PhysReg, bool> res;
-   if (info.rc.type() == RegType::vgpr && (info.size == 4 || info.size == 8)) {
-      DefInfo info_strided = {info.lb, info.ub, info.size, 4, info.rc};
-      std::pair<PhysReg, bool> res = get_reg_simple(ctx, reg_file, info_strided);
-   }
-   if (!res.second)
-      res = get_reg_simple(ctx, reg_file, info);
-
+   std::pair<PhysReg, bool> res = get_reg_simple(ctx, reg_file, info);
 
    if (res.second)
       return res.first;
@@ -1409,7 +1410,7 @@ void register_allocation(Program *program, std::vector<TempSet>& live_out_per_bl
          /* add vector affinities */
          if (instr->opcode == aco_opcode::p_create_vector) {
             for (const Operand& op : instr->operands) {
-               if (op.isTemp() && op.getTemp().type() == instr->definitions[0].getTemp().type())
+               if (op.isTemp() && op.isFirstKill() && op.getTemp().type() == instr->definitions[0].getTemp().type())
                   ctx.vectors[op.tempId()] = instr.get();
             }
          }
@@ -1838,8 +1839,17 @@ void register_allocation(Program *program, std::vector<TempSet>& live_out_per_bl
                definition.setFixed(reg);
             }
 
-            if (!definition.isFixed())
-               definition.setFixed(get_reg(ctx, register_file, definition.getTemp(), parallelcopy, instr));
+            if (!definition.isFixed()) {
+               Temp tmp = definition.getTemp();
+               /* subdword instructions before RDNA write full registers */
+               if (tmp.regClass().is_subdword() &&
+                   !instr_can_access_subdword(instr) &&
+                   ctx.program->chip_class <= GFX9) {
+                  assert(tmp.bytes() <= 4);
+                  tmp = Temp(definition.tempId(), v1);
+               }
+               definition.setFixed(get_reg(ctx, register_file, tmp, parallelcopy, instr));
+            }
 
             assert(definition.isFixed() && ((definition.getTemp().type() == RegType::vgpr && definition.physReg() >= 256) ||
                                             (definition.getTemp().type() != RegType::vgpr && definition.physReg() < 256)));