aco: Split vector arguments at the beginning
authorConnor Abbott <cwabbott0@gmail.com>
Fri, 15 Nov 2019 12:51:27 +0000 (13:51 +0100)
committerConnor Abbott <cwabbott0@gmail.com>
Mon, 25 Nov 2019 13:17:51 +0000 (14:17 +0100)
Due to how LLVM works we have to make some of the FS inputs become
vectors, and therefore have to split them early so that they don't take
up extra register pressure due to how RA currently works.

Reviewed-by: Daniel Schürmann <daniel@schuermann.dev>
src/amd/compiler/aco_instruction_selection.cpp
src/amd/compiler/aco_instruction_selection_setup.cpp

index 23629ffe22b2d05bbbd8bc87d576f7fa5e4b4fab..3b5bf0cc7636a52cad277b7ec431867b6ed4a073 100644 (file)
@@ -7634,6 +7634,19 @@ static void emit_streamout(isel_context *ctx, unsigned stream)
 
 } /* end namespace */
 
+void split_arguments(isel_context *ctx, Pseudo_instruction *startpgm)
+{
+   /* Split all arguments except for the first (ring_offsets) and the last
+    * (exec) so that the dead channels don't stay live throughout the program.
+    */
+   for (unsigned i = 1; i < startpgm->definitions.size() - 1; i++) {
+      if (startpgm->definitions[i].regClass().size() > 1) {
+         emit_split_vector(ctx, startpgm->definitions[i].getTemp(),
+                           startpgm->definitions[i].regClass().size());
+      }
+   }
+}
+
 void handle_bc_optimize(isel_context *ctx)
 {
    /* needed when SPI_PS_IN_CONTROL.BC_OPTIMIZE_DISABLE is set to 0 */
@@ -7732,8 +7745,10 @@ void select_program(Program *program,
       setup_fp_mode(&ctx, nir);
 
       if (!i) {
-         add_startpgm(&ctx); /* needs to be after init_context() for FS */
+         /* needs to be after init_context() for FS */
+         Pseudo_instruction *startpgm = add_startpgm(&ctx);
          append_logical_start(ctx.block);
+         split_arguments(&ctx, startpgm);
       }
 
       if_context ic;
index 1c672e3eb31e82caead29e87c91899b558862828..5c9c0e925acf0530e092d527a5ca2b2ef806cc45 100644 (file)
@@ -887,7 +887,7 @@ add_fs_arg(isel_context *ctx, arg_info *args, unsigned &vgpr_idx, fs_input input
    return true;
 }
 
-void add_startpgm(struct isel_context *ctx)
+Pseudo_instruction *add_startpgm(struct isel_context *ctx)
 {
    user_sgpr_info user_sgpr_info;
    bool needs_view_index = needs_view_index_sgpr(ctx);
@@ -1038,7 +1038,10 @@ void add_startpgm(struct isel_context *ctx)
       }
    }
    startpgm->definitions[args.count] = Definition{ctx->program->allocateId(), exec, s2};
+   Pseudo_instruction *instr = startpgm.get();
    ctx->block->instructions.push_back(std::move(startpgm));
+
+   return instr;
 }
 
 int