xref: /aosp_15_r20/external/mesa3d/src/imagination/rogue/passes/rogue_trim.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2022 Imagination Technologies Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21  * SOFTWARE.
22  */
23 
24 #include "rogue.h"
25 #include "util/macros.h"
26 
27 #include <stdbool.h>
28 
29 /**
30  * \file rogue_trim.c
31  *
32  * \brief Contains the rogue_trim pass.
33  */
34 
rogue_trim_instrs(rogue_shader * shader)35 static bool rogue_trim_instrs(rogue_shader *shader)
36 {
37    bool progress = false;
38 
39    shader->next_block = 0;
40    shader->next_instr = 0;
41 
42    rogue_foreach_block (block, shader) {
43       progress |= (block->index != shader->next_block);
44       block->index = shader->next_block++;
45       rogue_foreach_instr_in_block (instr, block) {
46          progress |= (instr->index != shader->next_instr);
47          instr->index = shader->next_instr++;
48       }
49    }
50 
51    return progress;
52 }
53 
rogue_trim_regs(rogue_shader * shader)54 static bool rogue_trim_regs(rogue_shader *shader)
55 {
56    bool progress = false;
57 
58    rogue_reset_reg_usage(shader, ROGUE_REG_CLASS_SSA);
59    rogue_reset_reg_usage(shader, ROGUE_REG_CLASS_TEMP);
60 
61    unsigned index[ROGUE_REG_CLASS_COUNT] = { 0 };
62 
63    rogue_foreach_regarray (regarray, shader) {
64       enum rogue_reg_class class = regarray->regs[0]->class;
65       if (class != ROGUE_REG_CLASS_SSA && class != ROGUE_REG_CLASS_TEMP)
66          continue;
67 
68       if (regarray->parent)
69          continue;
70 
71       rogue_regarray_set(shader, regarray, class, index[class], true);
72 
73       rogue_foreach_subarray (subarray, regarray) {
74          unsigned idx_offset =
75             subarray->regs[0]->index - regarray->regs[0]->index;
76          progress &= rogue_regarray_set(shader,
77                                         subarray,
78                                         class,
79                                         index[class] + idx_offset,
80                                         false);
81       }
82 
83       index[class] += regarray->size;
84    }
85 
86    rogue_foreach_reg (reg, shader, ROGUE_REG_CLASS_SSA) {
87       if (reg->dirty)
88          continue;
89 
90       progress |= rogue_reg_set(shader, reg, reg->class, index[reg->class]++);
91    }
92 
93    rogue_foreach_reg (reg, shader, ROGUE_REG_CLASS_TEMP) {
94       if (reg->dirty)
95          continue;
96 
97       progress |= rogue_reg_set(shader, reg, reg->class, index[reg->class]++);
98    }
99 
100    return progress;
101 }
102 
103 /* Renumbers instructions, blocks, and temp/ssa registers. */
104 PUBLIC
rogue_trim(rogue_shader * shader)105 bool rogue_trim(rogue_shader *shader)
106 {
107    if (shader->is_grouped)
108       return false;
109 
110    bool progress = false;
111 
112    progress |= rogue_trim_instrs(shader);
113    progress |= rogue_trim_regs(shader);
114 
115    return progress;
116 }
117