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