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