lima/ppir: convert to nir_legacy
authorErico Nunes <nunes.erico@gmail.com>
Tue, 18 Jul 2023 19:35:08 +0000 (21:35 +0200)
committerMarge Bot <emma+marge@anholt.net>
Tue, 1 Aug 2023 18:36:50 +0000 (18:36 +0000)
With the upcoming transition away from nir_register and modifiers in
nir, ppir needs to prepare for those features to be removed.
The most straightforward way for ppir without major reworks at this time
is to use the new nir_legacy helpers so that most of the backend can be
kept untouched (particularly due to use of abs/neg/sat modifiers).
Do this for now to unblock the transition with little impact; ppir can
be optimized at a later moment to have its own passes which will allow
it to drop the nir_legacy use and use just the chasing helpers.

Signed-off-by: Erico Nunes <nunes.erico@gmail.com>
Reviewed-by: Vasily Khoruzhick <anarsoul@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24246>

src/gallium/drivers/lima/ir/pp/nir.c
src/gallium/drivers/lima/ir/pp/node.c
src/gallium/drivers/lima/ir/pp/ppir.h
src/gallium/drivers/lima/lima_program.c

index b878a9c..fe093bb 100644 (file)
@@ -29,6 +29,7 @@
 #include "util/bitscan.h"
 #include "compiler/nir/nir.h"
 #include "pipe/p_state.h"
+#include "nir_legacy.h"
 
 
 #include "ppir.h"
@@ -52,16 +53,16 @@ static void *ppir_node_create_ssa(ppir_block *block, ppir_op op, nir_ssa_def *ss
 }
 
 static void *ppir_node_create_reg(ppir_block *block, ppir_op op,
-                                  nir_register *reg, unsigned mask)
+                                  nir_ssa_def *def, unsigned mask)
 {
-   ppir_node *node = ppir_node_create(block, op, reg->index, mask);
+   ppir_node *node = ppir_node_create(block, op, def->index, mask);
    if (!node)
       return NULL;
 
    ppir_dest *dest = ppir_node_get_dest(node);
 
    list_for_each_entry(ppir_reg, r, &block->comp->reg_list, list) {
-      if (r->index == reg->index) {
+      if (r->index == def->index) {
          dest->reg = r;
          break;
       }
@@ -78,22 +79,22 @@ static void *ppir_node_create_reg(ppir_block *block, ppir_op op,
 }
 
 static void *ppir_node_create_dest(ppir_block *block, ppir_op op,
-                                   nir_dest *dest, unsigned mask)
+                                   nir_legacy_dest *dest, unsigned mask)
 {
    unsigned index = -1;
 
    if (dest) {
       if (dest->is_ssa)
-         return ppir_node_create_ssa(block, op, &dest->ssa);
+         return ppir_node_create_ssa(block, op, dest->ssa);
       else
-         return ppir_node_create_reg(block, op, dest->reg.reg, mask);
+         return ppir_node_create_reg(block, op, dest->reg.handle, mask);
    }
 
    return ppir_node_create(block, op, index, 0);
 }
 
 static void ppir_node_add_src(ppir_compiler *comp, ppir_node *node,
-                              ppir_src *ps, nir_src *ns, unsigned mask)
+                              ppir_src *ps, nir_legacy_src *ns, unsigned mask)
 {
    ppir_node *child = NULL;
 
@@ -103,15 +104,15 @@ static void ppir_node_add_src(ppir_compiler *comp, ppir_node *node,
          ppir_node_add_dep(node, child, ppir_dep_src);
    }
    else {
-      nir_register *reg = ns->reg.reg;
+      nir_reg_src *rs = &ns->reg;
       while (mask) {
          int swizzle = ps->swizzle[u_bit_scan(&mask)];
-         child = comp->var_nodes[(reg->index << 2) + comp->reg_base + swizzle];
+         child = comp->var_nodes[(rs->handle->index << 2) + swizzle];
          /* Reg is read before it was written, create a dummy node for it */
          if (!child) {
-            child = ppir_node_create_reg(node->block, ppir_op_dummy, reg,
+            child = ppir_node_create_reg(node->block, ppir_op_dummy, rs->handle,
                u_bit_consecutive(0, 4));
-            comp->var_nodes[(reg->index << 2) + comp->reg_base + swizzle] = child;
+            comp->var_nodes[(rs->handle->index << 2) + swizzle] = child;
          }
          /* Don't add dummies or recursive deps for ops like r1 = r1 + ssa1 */
          if (child && node != child && child->op != ppir_op_dummy)
@@ -158,21 +159,39 @@ static int nir_to_ppir_opcodes[nir_num_opcodes] = {
 static bool ppir_emit_alu(ppir_block *block, nir_instr *ni)
 {
    nir_alu_instr *instr = nir_instr_as_alu(ni);
+   nir_dest *dst = &instr->dest.dest;
    int op = nir_to_ppir_opcodes[instr->op];
 
    if (op == ppir_op_unsupported) {
       ppir_error("unsupported nir_op: %s\n", nir_op_infos[instr->op].name);
       return false;
    }
+   nir_legacy_alu_dest legacy_dest = nir_legacy_chase_alu_dest(dst);
 
-   ppir_alu_node *node = ppir_node_create_dest(block, op, &instr->dest.dest,
-                                               instr->dest.write_mask);
+   /* Don't try to translate folded fsat since their source won't be valid */
+   if (instr->op == nir_op_fsat && nir_legacy_fsat_folds(instr))
+      return true;
+
+   /* Skip folded fabs/fneg since we do not have dead code elimination */
+   if ((instr->op == nir_op_fabs || instr->op == nir_op_fneg) &&
+       nir_legacy_float_mod_folds(instr)) {
+      /* Add parent node as a the folded dest ssa node to keep
+       * the dependency chain */
+      nir_alu_src *ns = &instr->src[0];
+      assert(ns->src.is_ssa);
+      ppir_node *parent = block->comp->var_nodes[ns->src.ssa->index];
+      assert(parent);
+      block->comp->var_nodes[dst->ssa.index] = parent;
+      return true;
+   }
+
+   ppir_alu_node *node = ppir_node_create_dest(block, op, &legacy_dest.dest,
+                                               legacy_dest.write_mask);
    if (!node)
       return false;
 
    ppir_dest *pd = &node->dest;
-   nir_alu_dest *nd = &instr->dest;
-   if (nd->saturate)
+   if (legacy_dest.fsat)
       pd->modifier = ppir_outmod_clamp_fraction;
 
    unsigned src_mask;
@@ -192,13 +211,13 @@ static bool ppir_emit_alu(ppir_block *block, nir_instr *ni)
    node->num_src = num_child;
 
    for (int i = 0; i < num_child; i++) {
-      nir_alu_src *ns = instr->src + i;
+      nir_legacy_alu_src ns = nir_legacy_chase_alu_src(instr->src + i, true);
       ppir_src *ps = node->src + i;
-      memcpy(ps->swizzle, ns->swizzle, sizeof(ps->swizzle));
-      ppir_node_add_src(block->comp, &node->node, ps, &ns->src, src_mask);
+      memcpy(ps->swizzle, ns.swizzle, sizeof(ps->swizzle));
+      ppir_node_add_src(block->comp, &node->node, ps, &ns.src, src_mask);
 
-      ps->absolute = ns->abs;
-      ps->negate = ns->negate;
+      ps->absolute = ns.fabs;
+      ps->negate = ns.fneg;
    }
 
    list_addtail(&node->node.list, &block->node_list);
@@ -242,8 +261,9 @@ static ppir_node *ppir_emit_discard_if(ppir_block *block, nir_instr *ni)
    branch = ppir_node_to_branch(node);
 
    /* second src and condition will be updated during lowering */
+   nir_legacy_src legacy_src = nir_legacy_chase_src(&instr->src[0]);
    ppir_node_add_src(block->comp, node, &branch->src[0],
-                     &instr->src[0], u_bit_consecutive(0, instr->num_components));
+                     &legacy_src, u_bit_consecutive(0, instr->num_components));
    branch->num_src = 1;
    branch->target = comp->discard_block;
 
@@ -266,11 +286,22 @@ static bool ppir_emit_intrinsic(ppir_block *block, nir_instr *ni)
    ppir_alu_node *alu_node;
 
    switch (instr->intrinsic) {
-   case nir_intrinsic_load_input:
-      if (!instr->dest.is_ssa)
-         mask = u_bit_consecutive(0, instr->num_components);
+   case nir_intrinsic_decl_reg:
+   case nir_intrinsic_store_reg:
+      /* Nothing to do for these */
+      return true;
+
+   case nir_intrinsic_load_reg: {
+      nir_legacy_dest legacy_dest = nir_legacy_chase_dest(&instr->dest);
+      lnode = ppir_node_create_dest(block, ppir_op_dummy, &legacy_dest, mask);
+      return true;
+   }
 
-      lnode = ppir_node_create_dest(block, ppir_op_load_varying, &instr->dest, mask);
+   case nir_intrinsic_load_input: {
+      mask = u_bit_consecutive(0, instr->num_components);
+
+      nir_legacy_dest legacy_dest = nir_legacy_chase_dest(&instr->dest);
+      lnode = ppir_node_create_dest(block, ppir_op_load_varying, &legacy_dest, mask);
       if (!lnode)
          return false;
 
@@ -280,16 +311,18 @@ static bool ppir_emit_intrinsic(ppir_block *block, nir_instr *ni)
          lnode->index += (uint32_t)(nir_src_as_float(instr->src[0]) * 4);
       else {
          lnode->num_src = 1;
-         ppir_node_add_src(block->comp, &lnode->node, &lnode->src, instr->src, 1);
+         nir_legacy_src legacy_src = nir_legacy_chase_src(instr->src);
+         ppir_node_add_src(block->comp, &lnode->node, &lnode->src, &legacy_src, 1);
       }
       list_addtail(&lnode->node.list, &block->node_list);
       return true;
+   }
 
    case nir_intrinsic_load_frag_coord:
    case nir_intrinsic_load_point_coord:
-   case nir_intrinsic_load_front_face:
-      if (!instr->dest.is_ssa)
-         mask = u_bit_consecutive(0, instr->num_components);
+   case nir_intrinsic_load_front_face: {
+      assert(instr->dest.is_ssa);
+      mask = u_bit_consecutive(0, instr->num_components);
 
       ppir_op op;
       switch (instr->intrinsic) {
@@ -307,19 +340,21 @@ static bool ppir_emit_intrinsic(ppir_block *block, nir_instr *ni)
          break;
       }
 
-      lnode = ppir_node_create_dest(block, op, &instr->dest, mask);
+      nir_legacy_dest legacy_dest = nir_legacy_chase_dest(&instr->dest);
+      lnode = ppir_node_create_dest(block, op, &legacy_dest, mask);
       if (!lnode)
          return false;
 
       lnode->num_components = instr->num_components;
       list_addtail(&lnode->node.list, &block->node_list);
       return true;
+   }
 
-   case nir_intrinsic_load_uniform:
-      if (!instr->dest.is_ssa)
-         mask = u_bit_consecutive(0, instr->num_components);
+   case nir_intrinsic_load_uniform: {
+      mask = u_bit_consecutive(0, instr->num_components);
 
-      lnode = ppir_node_create_dest(block, ppir_op_load_uniform, &instr->dest, mask);
+      nir_legacy_dest legacy_dest = nir_legacy_chase_dest(&instr->dest);
+      lnode = ppir_node_create_dest(block, ppir_op_load_uniform, &legacy_dest, mask);
       if (!lnode)
          return false;
 
@@ -329,11 +364,13 @@ static bool ppir_emit_intrinsic(ppir_block *block, nir_instr *ni)
          lnode->index += (uint32_t)nir_src_as_float(instr->src[0]);
       else {
          lnode->num_src = 1;
-         ppir_node_add_src(block->comp, &lnode->node, &lnode->src, instr->src, 1);
+         nir_legacy_src legacy_src = nir_legacy_chase_src(instr->src);
+         ppir_node_add_src(block->comp, &lnode->node, &lnode->src, &legacy_src, 1);
       }
 
       list_addtail(&lnode->node.list, &block->node_list);
       return true;
+   }
 
    case nir_intrinsic_store_output: {
       /* In simple cases where the store_output is ssa, that register
@@ -356,11 +393,14 @@ static bool ppir_emit_intrinsic(ppir_block *block, nir_instr *ni)
          return false;
       }
 
-      if (!block->comp->uses_discard && instr->src->is_ssa) {
+      assert(instr->src->is_ssa);
+      if (!block->comp->uses_discard) {
          node = block->comp->var_nodes[instr->src->ssa->index];
+         assert(node);
          switch (node->op) {
          case ppir_op_load_uniform:
          case ppir_op_load_texture:
+         case ppir_op_dummy:
          case ppir_op_const:
             break;
          default: {
@@ -388,7 +428,8 @@ static bool ppir_emit_intrinsic(ppir_block *block, nir_instr *ni)
       for (int i = 0; i < instr->num_components; i++)
          alu_node->src[0].swizzle[i] = i;
 
-      ppir_node_add_src(block->comp, &alu_node->node, alu_node->src, instr->src,
+      nir_legacy_src legacy_src = nir_legacy_chase_src(instr->src);
+      ppir_node_add_src(block->comp, &alu_node->node, alu_node->src, &legacy_src,
                         u_bit_consecutive(0, instr->num_components));
 
       alu_node->node.is_out = 1;
@@ -477,10 +518,10 @@ static bool ppir_emit_tex(ppir_block *block, nir_instr *ni)
    /* emit ld_tex node */
 
    unsigned mask = 0;
-   if (!instr->dest.is_ssa)
-      mask = u_bit_consecutive(0, nir_tex_instr_dest_size(instr));
+   mask = u_bit_consecutive(0, nir_tex_instr_dest_size(instr));
 
-   node = ppir_node_create_dest(block, ppir_op_load_texture, &instr->dest, mask);
+   nir_legacy_dest legacy_dest = nir_legacy_chase_dest(&instr->dest);
+   node = ppir_node_create_dest(block, ppir_op_load_texture, &legacy_dest, mask);
    if (!node)
       return false;
 
@@ -499,20 +540,20 @@ static bool ppir_emit_tex(ppir_block *block, nir_instr *ni)
          FALLTHROUGH;
       case nir_tex_src_coord: {
          nir_src *ns = &instr->src[i].src;
-         if (ns->is_ssa) {
-            ppir_node *child = block->comp->var_nodes[ns->ssa->index];
-            if (child->op == ppir_op_load_varying) {
-               /* If the successor is load_texture, promote it to load_coords */
-               nir_tex_src *nts = (nir_tex_src *)ns;
-               if (nts->src_type == nir_tex_src_coord ||
-                   nts->src_type == nir_tex_src_backend1)
-                  child->op = ppir_op_load_coords;
-            }
+         assert(ns->is_ssa);
+         ppir_node *child = block->comp->var_nodes[ns->ssa->index];
+         if (child->op == ppir_op_load_varying) {
+            /* If the successor is load_texture, promote it to load_coords */
+            nir_tex_src *nts = (nir_tex_src *)ns;
+            if (nts->src_type == nir_tex_src_coord ||
+                nts->src_type == nir_tex_src_backend1)
+               child->op = ppir_op_load_coords;
          }
 
          /* src[0] is not used by the ld_tex instruction but ensures
           * correct scheduling due to the pipeline dependency */
-         ppir_node_add_src(block->comp, &node->node, &node->src[0], &instr->src[i].src,
+         nir_legacy_src legacy_src = nir_legacy_chase_src(&instr->src[i].src);
+         ppir_node_add_src(block->comp, &node->node, &node->src[0], &legacy_src,
                            u_bit_consecutive(0, instr->coord_components));
          node->num_src++;
          break;
@@ -521,7 +562,8 @@ static bool ppir_emit_tex(ppir_block *block, nir_instr *ni)
       case nir_tex_src_lod:
          node->lod_bias_en = true;
          node->explicit_lod = (instr->src[i].src_type == nir_tex_src_lod);
-         ppir_node_add_src(block->comp, &node->node, &node->src[1], &instr->src[i].src, 1);
+         nir_legacy_src legacy_src = nir_legacy_chase_src(&instr->src[i].src);
+         ppir_node_add_src(block->comp, &node->node, &node->src[1], &legacy_src, 1);
          node->num_src++;
          break;
       default:
@@ -679,8 +721,9 @@ static bool ppir_emit_if(ppir_compiler *comp, nir_if *if_stmt)
    if (!node)
       return false;
    else_branch = ppir_node_to_branch(node);
+   nir_legacy_src legacy_src = nir_legacy_chase_src(&if_stmt->condition);
    ppir_node_add_src(block->comp, node, &else_branch->src[0],
-                     &if_stmt->condition, 1);
+                     &legacy_src, 1);
    else_branch->num_src = 1;
    /* Negate condition to minimize branching. We're generating following:
     * current_block: { ...; if (!statement) branch else_block; }
@@ -799,10 +842,10 @@ static bool ppir_emit_cf_list(ppir_compiler *comp, struct exec_list *list)
    return true;
 }
 
-static ppir_compiler *ppir_compiler_create(void *prog, unsigned num_reg, unsigned num_ssa)
+static ppir_compiler *ppir_compiler_create(void *prog, unsigned num_ssa)
 {
    ppir_compiler *comp = rzalloc_size(
-      prog, sizeof(*comp) + ((num_reg << 2) + num_ssa) * sizeof(ppir_node *));
+      prog, sizeof(*comp) + (num_ssa << 2) * sizeof(ppir_node *));
    if (!comp)
       return NULL;
 
@@ -812,7 +855,6 @@ static ppir_compiler *ppir_compiler_create(void *prog, unsigned num_reg, unsigne
    comp->blocks = _mesa_hash_table_u64_create(prog);
 
    comp->var_nodes = (ppir_node **)(comp + 1);
-   comp->reg_base = num_ssa;
    comp->prog = prog;
 
    return comp;
@@ -910,7 +952,8 @@ bool ppir_compile_nir(struct lima_fs_compiled_shader *prog, struct nir_shader *n
                       struct util_debug_callback *debug)
 {
    nir_function_impl *func = nir_shader_get_entrypoint(nir);
-   ppir_compiler *comp = ppir_compiler_create(prog, func->reg_alloc, func->ssa_alloc);
+   assert(func->reg_alloc == 0);
+   ppir_compiler *comp = ppir_compiler_create(prog, func->ssa_alloc);
    if (!comp)
       return false;
 
@@ -948,13 +991,13 @@ bool ppir_compile_nir(struct lima_fs_compiled_shader *prog, struct nir_shader *n
    for (int i = 0; i < ppir_output_num; i++)
       comp->out_type_to_reg[i] = -1;
 
-   foreach_list_typed(nir_register, reg, node, &func->registers) {
+   nir_foreach_reg_decl(decl, func) {
       ppir_reg *r = rzalloc(comp, ppir_reg);
       if (!r)
          return false;
 
-      r->index = reg->index;
-      r->num_components = reg->num_components;
+      r->index = decl->dest.ssa.index;
+      r->num_components = nir_intrinsic_num_components(decl);
       r->is_head = false;
       list_addtail(&r->list, &comp->reg_list);
       comp->reg_num++;
index 7465e4e..e22a06c 100644 (file)
@@ -371,7 +371,7 @@ void *ppir_node_create(ppir_block *block, ppir_op op, int index, unsigned mask)
       if (mask) {
          /* reg has 4 slots for each component write node */
          while (mask)
-            comp->var_nodes[(index << 2) + comp->reg_base + u_bit_scan(&mask)] = node;
+            comp->var_nodes[(index << 2) + u_bit_scan(&mask)] = node;
          snprintf(node->name, sizeof(node->name), "reg%d", index);
       } else {
          comp->var_nodes[index] = node;
index 306d3e2..f9191a1 100644 (file)
@@ -416,7 +416,6 @@ typedef struct ppir_compiler {
 
    /* array for searching ssa/reg node */
    ppir_node **var_nodes;
-   unsigned reg_base;
 
    struct ra_regs *ra;
    struct lima_fs_compiled_shader *prog;
index a773161..11a3127 100644 (file)
@@ -30,6 +30,7 @@
 #include "compiler/nir/nir.h"
 #include "compiler/nir/nir_serialize.h"
 #include "nir/tgsi_to_nir.h"
+#include "nir_legacy.h"
 
 #include "pipe/p_state.h"
 
@@ -207,7 +208,7 @@ lima_alu_to_scalar_filter_cb(const nir_instr *instr, const void *data)
 }
 
 static bool
-lima_vec_to_movs_filter_cb(const nir_instr *instr, unsigned writemask,
+lima_vec_to_regs_filter_cb(const nir_instr *instr, unsigned writemask,
                            const void *data)
 {
    assert(writemask > 0);
@@ -265,22 +266,23 @@ lima_program_optimize_fs_nir(struct nir_shader *s,
    /* Must be run after optimization loop */
    NIR_PASS_V(s, lima_nir_scale_trig);
 
-   /* Lower modifiers */
-   NIR_PASS_V(s, nir_lower_to_source_mods, nir_lower_all_source_mods);
    NIR_PASS_V(s, nir_copy_prop);
    NIR_PASS_V(s, nir_opt_dce);
 
-   NIR_PASS_V(s, nir_convert_from_ssa, true, false);
+   NIR_PASS_V(s, nir_convert_from_ssa, true, true);
    NIR_PASS_V(s, nir_remove_dead_variables, nir_var_function_temp, NULL);
 
    NIR_PASS_V(s, nir_move_vec_src_uses_to_dest);
-   NIR_PASS_V(s, nir_lower_vec_to_movs, lima_vec_to_movs_filter_cb, NULL);
+   NIR_PASS_V(s, nir_lower_vec_to_regs, lima_vec_to_regs_filter_cb, NULL);
+
    NIR_PASS_V(s, nir_opt_dce); /* clean up any new dead code from vec to movs */
 
    NIR_PASS_V(s, lima_nir_duplicate_load_uniforms);
    NIR_PASS_V(s, lima_nir_duplicate_load_inputs);
    NIR_PASS_V(s, lima_nir_duplicate_load_consts);
 
+   NIR_PASS_V(s, nir_legacy_trivialize, true);
+
    nir_sweep(s);
 }