xref: /aosp_15_r20/external/mesa3d/src/asahi/compiler/agx_dce.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright 2021 Alyssa Rosenzweig
3  * SPDX-License-Identifier: MIT
4  */
5 
6 #include "agx_compiler.h"
7 
8 /**
9  * SSA-based scalar dead code elimination.
10  * This pass assumes that no loop header phis are dead.
11  */
12 void
agx_dce(agx_context * ctx,bool partial)13 agx_dce(agx_context *ctx, bool partial)
14 {
15    BITSET_WORD *seen = calloc(BITSET_WORDS(ctx->alloc), sizeof(BITSET_WORD));
16 
17    agx_foreach_block(ctx, block) {
18       if (block->loop_header) {
19          agx_foreach_phi_in_block(block, I) {
20             agx_foreach_ssa_src(I, s) {
21                BITSET_SET(seen, I->src[s].value);
22             }
23          }
24       }
25    }
26 
27    agx_foreach_block_rev(ctx, block) {
28       agx_foreach_instr_in_block_safe_rev(block, I) {
29          if (block->loop_header && I->op == AGX_OPCODE_PHI)
30             break;
31 
32          bool needed = false;
33 
34          agx_foreach_ssa_dest(I, d) {
35             /* Eliminate destinations that are never read, as RA needs to
36              * handle them specially. Visible only for instructions that write
37              * multiple destinations (splits) or that write a destination but
38              * cannot be DCE'd (atomics).
39              */
40             if (BITSET_TEST(seen, I->dest[d].value)) {
41                needed = true;
42             } else if (partial) {
43                I->dest[d] = agx_null();
44             }
45          }
46 
47          if (!needed && agx_opcodes_info[I->op].can_eliminate) {
48             agx_remove_instruction(I);
49          } else {
50             agx_foreach_ssa_src(I, s) {
51                BITSET_SET(seen, I->src[s].value);
52             }
53          }
54       }
55    }
56 
57    free(seen);
58 }
59