xref: /aosp_15_r20/external/mesa3d/src/amd/common/ac_nir_opt_shared_append.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright 2024 Valve Corporation
3  *
4  * SPDX-License-Identifier: MIT
5  */
6 
7 #include "ac_nir.h"
8 #include "nir_builder.h"
9 
10 static bool
opt_shared_append(nir_builder * b,nir_intrinsic_instr * intrin,void * unused)11 opt_shared_append(nir_builder *b,
12                   nir_intrinsic_instr *intrin,
13                   void *unused)
14 {
15    if (intrin->intrinsic != nir_intrinsic_shared_atomic)
16       return false;
17    if (nir_intrinsic_atomic_op(intrin) != nir_atomic_op_iadd)
18       return false;
19    if (intrin->def.bit_size != 32)
20       return false;
21 
22    if (!nir_src_is_const(intrin->src[0]) || !nir_src_is_const(intrin->src[1]))
23       return false;
24 
25    uint32_t addr = nir_src_as_uint(intrin->src[0]) + nir_intrinsic_base(intrin);
26    int32_t data = nir_src_as_int(intrin->src[1]);
27 
28    if (data != 1 && data != -1)
29       return false;
30 
31    if (addr >= 65536 || addr % 4)
32       return false;
33 
34    b->cursor = nir_before_instr(&intrin->instr);
35    nir_def *res;
36    if (data == 1)
37       res = nir_shared_append_amd(b, .base = addr);
38    else
39       res = nir_shared_consume_amd(b, .base = addr);
40 
41    if (nir_def_is_unused(&intrin->def)) {
42       nir_instr_remove(&intrin->instr);
43       return true;
44    }
45 
46    res = nir_iadd(b, res, nir_exclusive_scan(b, intrin->src[1].ssa, .reduction_op = nir_op_iadd));
47    nir_def_replace(&intrin->def, res);
48    return true;
49 }
50 
51 
52 bool
ac_nir_opt_shared_append(nir_shader * shader)53 ac_nir_opt_shared_append(nir_shader *shader)
54 {
55    return nir_shader_intrinsics_pass(shader, opt_shared_append, nir_metadata_control_flow, NULL);
56 }
57