1 /*
2 * Copyright © 2021 Valve Corporation
3 *
4 * SPDX-License-Identifier: MIT
5 */
6
7 #include "aco_ir.h"
8
9 #include <vector>
10
11 namespace aco {
12 namespace {
13
14 struct idx_ctx {
15 std::vector<RegClass> temp_rc = {s1};
16 std::vector<uint32_t> renames;
17 };
18
19 inline void
reindex_defs(idx_ctx & ctx,aco_ptr<Instruction> & instr)20 reindex_defs(idx_ctx& ctx, aco_ptr<Instruction>& instr)
21 {
22 for (Definition& def : instr->definitions) {
23 if (!def.isTemp())
24 continue;
25 uint32_t new_id = ctx.temp_rc.size();
26 RegClass rc = def.regClass();
27 ctx.renames[def.tempId()] = new_id;
28 ctx.temp_rc.emplace_back(rc);
29 def.setTemp(Temp(new_id, rc));
30 }
31 }
32
33 inline void
reindex_ops(idx_ctx & ctx,aco_ptr<Instruction> & instr)34 reindex_ops(idx_ctx& ctx, aco_ptr<Instruction>& instr)
35 {
36 for (Operand& op : instr->operands) {
37 if (!op.isTemp())
38 continue;
39 uint32_t new_id = ctx.renames[op.tempId()];
40 assert(op.regClass() == ctx.temp_rc[new_id]);
41 op.setTemp(Temp(new_id, op.regClass()));
42 }
43 }
44
45 void
reindex_program(idx_ctx & ctx,Program * program)46 reindex_program(idx_ctx& ctx, Program* program)
47 {
48 ctx.renames.resize(program->peekAllocationId());
49
50 for (Block& block : program->blocks) {
51 auto it = block.instructions.begin();
52 /* for phis, only reindex the definitions */
53 while (is_phi(*it)) {
54 reindex_defs(ctx, *it++);
55 }
56 /* reindex all other instructions */
57 while (it != block.instructions.end()) {
58 reindex_defs(ctx, *it);
59 reindex_ops(ctx, *it);
60 ++it;
61 }
62 }
63 /* update the phi operands */
64 for (Block& block : program->blocks) {
65 auto it = block.instructions.begin();
66 while (is_phi(*it)) {
67 reindex_ops(ctx, *it++);
68 }
69 }
70
71 /* update program members */
72 program->private_segment_buffer = Temp(ctx.renames[program->private_segment_buffer.id()],
73 program->private_segment_buffer.regClass());
74 program->scratch_offset =
75 Temp(ctx.renames[program->scratch_offset.id()], program->scratch_offset.regClass());
76 program->temp_rc = ctx.temp_rc;
77 }
78
79 } /* end namespace */
80
81 void
reindex_ssa(Program * program,bool update_live_out=false)82 reindex_ssa(Program* program, bool update_live_out = false)
83 {
84 idx_ctx ctx;
85 reindex_program(ctx, program);
86 if (update_live_out) {
87 monotonic_buffer_resource old_memory = std::move(program->live.memory);
88 for (IDSet& set : program->live.live_in) {
89 IDSet new_set(program->live.memory);
90 for (uint32_t id : set)
91 new_set.insert(ctx.renames[id]);
92 set = std::move(new_set);
93 }
94 }
95
96 program->allocationID = program->temp_rc.size();
97 }
98
99 } // namespace aco
100