Module: Mesa
Branch: main
Commit: 989e9867a64045421cf77c0d0bb2d184408ed21f
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=989e9867a64045421cf77c0d0bb2d184408ed21f

Author: Daniel Schürmann <dan...@schuermann.dev>
Date:   Tue May 11 22:58:27 2021 +0200

aco: fix additional register requirements for spilling

It could happen that VGPR spilling without SGPR spilling
calculated a negative spills_to_vgpr number and then
increasing the VGPR target demand above the limit.

Cc: mesa-stable

Reviewed-by: Tony Wasserka <tony.wasse...@gmx.de>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10756>

---

 src/amd/compiler/aco_spill.cpp | 37 ++++++++++++++++++++++++-------------
 1 file changed, 24 insertions(+), 13 deletions(-)

diff --git a/src/amd/compiler/aco_spill.cpp b/src/amd/compiler/aco_spill.cpp
index 3e0c3ea3cb6..c2670736855 100644
--- a/src/amd/compiler/aco_spill.cpp
+++ b/src/amd/compiler/aco_spill.cpp
@@ -1715,20 +1715,31 @@ void spill(Program* program, live& live_vars)
    lower_to_cssa(program, live_vars);
 
    /* calculate target register demand */
-   RegisterDemand register_target = program->max_reg_demand;
-   uint16_t sgpr_limit = get_addr_sgpr_from_waves(program, program->min_waves);
-   uint16_t vgpr_limit = get_addr_vgpr_from_waves(program, program->min_waves);
-   if (register_target.sgpr > sgpr_limit)
-      register_target.vgpr += (register_target.sgpr - sgpr_limit + 
program->wave_size - 1 + 32) / program->wave_size;
-   register_target.sgpr = sgpr_limit;
-
-   if (register_target.vgpr > vgpr_limit)
-      register_target.sgpr = sgpr_limit - 5;
-   int spills_to_vgpr = (program->max_reg_demand.sgpr - register_target.sgpr + 
program->wave_size - 1 + 32) / program->wave_size;
-   register_target.vgpr = vgpr_limit - spills_to_vgpr;
+   const RegisterDemand demand = program->max_reg_demand; /* current max */
+   const uint16_t sgpr_limit = get_addr_sgpr_from_waves(program, 
program->min_waves);
+   const uint16_t vgpr_limit = get_addr_vgpr_from_waves(program, 
program->min_waves);
+   uint16_t extra_vgprs = 0;
+   uint16_t extra_sgprs = 0;
+
+   /* calculate extra VGPRs required for spilling SGPRs */
+   if (demand.sgpr > sgpr_limit) {
+      unsigned sgpr_spills = demand.sgpr - sgpr_limit;
+      extra_vgprs = DIV_ROUND_UP(sgpr_spills, program->wave_size) + 1;
+   }
+   /* add extra SGPRs required for spilling VGPRs */
+   if (demand.vgpr + extra_vgprs > vgpr_limit) {
+      extra_sgprs = 5; /* scratch_resource (s4) + scratch_offset (s1) */
+      if (demand.sgpr + extra_sgprs > sgpr_limit) {
+         /* re-calculate in case something has changed */
+         unsigned sgpr_spills = demand.sgpr + extra_sgprs - sgpr_limit;
+         extra_vgprs = DIV_ROUND_UP(sgpr_spills, program->wave_size) + 1;
+      }
+   }
+   /* the spiller has to target the following register demand */
+   const RegisterDemand target(vgpr_limit - extra_vgprs, sgpr_limit - 
extra_sgprs);
 
    /* initialize ctx */
-   spill_ctx ctx(register_target, program, live_vars.register_demand);
+   spill_ctx ctx(target, program, live_vars.register_demand);
    compute_global_next_uses(ctx);
    get_rematerialize_info(ctx);
 
@@ -1737,7 +1748,7 @@ void spill(Program* program, live& live_vars)
       spill_block(ctx, i);
 
    /* assign spill slots and DCE rematerialized code */
-   assign_spill_slots(ctx, spills_to_vgpr);
+   assign_spill_slots(ctx, extra_vgprs);
 
    /* update live variable information */
    live_vars = live_var_analysis(program);

_______________________________________________
mesa-commit mailing list
mesa-commit@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to