1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © 2021 Valve Corporation
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci *
11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
13bf215546Sopenharmony_ci * Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21bf215546Sopenharmony_ci * IN THE SOFTWARE.
22bf215546Sopenharmony_ci *
23bf215546Sopenharmony_ci */
24bf215546Sopenharmony_ci
25bf215546Sopenharmony_ci#include "aco_ir.h"
26bf215546Sopenharmony_ci
27bf215546Sopenharmony_ci#include <vector>
28bf215546Sopenharmony_ci
29bf215546Sopenharmony_cinamespace aco {
30bf215546Sopenharmony_cinamespace {
31bf215546Sopenharmony_ci
32bf215546Sopenharmony_cistruct idx_ctx {
33bf215546Sopenharmony_ci   std::vector<RegClass> temp_rc = {s1};
34bf215546Sopenharmony_ci   std::vector<uint32_t> renames;
35bf215546Sopenharmony_ci};
36bf215546Sopenharmony_ci
37bf215546Sopenharmony_ciinline void
38bf215546Sopenharmony_cireindex_defs(idx_ctx& ctx, aco_ptr<Instruction>& instr)
39bf215546Sopenharmony_ci{
40bf215546Sopenharmony_ci   for (Definition& def : instr->definitions) {
41bf215546Sopenharmony_ci      if (!def.isTemp())
42bf215546Sopenharmony_ci         continue;
43bf215546Sopenharmony_ci      uint32_t new_id = ctx.temp_rc.size();
44bf215546Sopenharmony_ci      RegClass rc = def.regClass();
45bf215546Sopenharmony_ci      ctx.renames[def.tempId()] = new_id;
46bf215546Sopenharmony_ci      ctx.temp_rc.emplace_back(rc);
47bf215546Sopenharmony_ci      def.setTemp(Temp(new_id, rc));
48bf215546Sopenharmony_ci   }
49bf215546Sopenharmony_ci}
50bf215546Sopenharmony_ci
51bf215546Sopenharmony_ciinline void
52bf215546Sopenharmony_cireindex_ops(idx_ctx& ctx, aco_ptr<Instruction>& instr)
53bf215546Sopenharmony_ci{
54bf215546Sopenharmony_ci   for (Operand& op : instr->operands) {
55bf215546Sopenharmony_ci      if (!op.isTemp())
56bf215546Sopenharmony_ci         continue;
57bf215546Sopenharmony_ci      uint32_t new_id = ctx.renames[op.tempId()];
58bf215546Sopenharmony_ci      assert(op.regClass() == ctx.temp_rc[new_id]);
59bf215546Sopenharmony_ci      op.setTemp(Temp(new_id, op.regClass()));
60bf215546Sopenharmony_ci   }
61bf215546Sopenharmony_ci}
62bf215546Sopenharmony_ci
63bf215546Sopenharmony_civoid
64bf215546Sopenharmony_cireindex_program(idx_ctx& ctx, Program* program)
65bf215546Sopenharmony_ci{
66bf215546Sopenharmony_ci   ctx.renames.resize(program->peekAllocationId());
67bf215546Sopenharmony_ci
68bf215546Sopenharmony_ci   for (Block& block : program->blocks) {
69bf215546Sopenharmony_ci      auto it = block.instructions.begin();
70bf215546Sopenharmony_ci      /* for phis, only reindex the definitions */
71bf215546Sopenharmony_ci      while (is_phi(*it)) {
72bf215546Sopenharmony_ci         reindex_defs(ctx, *it++);
73bf215546Sopenharmony_ci      }
74bf215546Sopenharmony_ci      /* reindex all other instructions */
75bf215546Sopenharmony_ci      while (it != block.instructions.end()) {
76bf215546Sopenharmony_ci         reindex_defs(ctx, *it);
77bf215546Sopenharmony_ci         reindex_ops(ctx, *it);
78bf215546Sopenharmony_ci         ++it;
79bf215546Sopenharmony_ci      }
80bf215546Sopenharmony_ci   }
81bf215546Sopenharmony_ci   /* update the phi operands */
82bf215546Sopenharmony_ci   for (Block& block : program->blocks) {
83bf215546Sopenharmony_ci      auto it = block.instructions.begin();
84bf215546Sopenharmony_ci      while (is_phi(*it)) {
85bf215546Sopenharmony_ci         reindex_ops(ctx, *it++);
86bf215546Sopenharmony_ci      }
87bf215546Sopenharmony_ci   }
88bf215546Sopenharmony_ci
89bf215546Sopenharmony_ci   /* update program members */
90bf215546Sopenharmony_ci   program->private_segment_buffer = Temp(ctx.renames[program->private_segment_buffer.id()],
91bf215546Sopenharmony_ci                                          program->private_segment_buffer.regClass());
92bf215546Sopenharmony_ci   program->scratch_offset =
93bf215546Sopenharmony_ci      Temp(ctx.renames[program->scratch_offset.id()], program->scratch_offset.regClass());
94bf215546Sopenharmony_ci   program->temp_rc = ctx.temp_rc;
95bf215546Sopenharmony_ci}
96bf215546Sopenharmony_ci
97bf215546Sopenharmony_civoid
98bf215546Sopenharmony_ciupdate_live_out(idx_ctx& ctx, std::vector<IDSet>& live_out)
99bf215546Sopenharmony_ci{
100bf215546Sopenharmony_ci   for (IDSet& set : live_out) {
101bf215546Sopenharmony_ci      IDSet new_set;
102bf215546Sopenharmony_ci      for (uint32_t id : set)
103bf215546Sopenharmony_ci         new_set.insert(ctx.renames[id]);
104bf215546Sopenharmony_ci      set = new_set;
105bf215546Sopenharmony_ci   }
106bf215546Sopenharmony_ci}
107bf215546Sopenharmony_ci
108bf215546Sopenharmony_ci} /* end namespace */
109bf215546Sopenharmony_ci
110bf215546Sopenharmony_civoid
111bf215546Sopenharmony_cireindex_ssa(Program* program)
112bf215546Sopenharmony_ci{
113bf215546Sopenharmony_ci   idx_ctx ctx;
114bf215546Sopenharmony_ci   reindex_program(ctx, program);
115bf215546Sopenharmony_ci
116bf215546Sopenharmony_ci   program->allocationID = program->temp_rc.size();
117bf215546Sopenharmony_ci}
118bf215546Sopenharmony_ci
119bf215546Sopenharmony_civoid
120bf215546Sopenharmony_cireindex_ssa(Program* program, std::vector<IDSet>& live_out)
121bf215546Sopenharmony_ci{
122bf215546Sopenharmony_ci   idx_ctx ctx;
123bf215546Sopenharmony_ci   reindex_program(ctx, program);
124bf215546Sopenharmony_ci   update_live_out(ctx, live_out);
125bf215546Sopenharmony_ci
126bf215546Sopenharmony_ci   program->allocationID = program->temp_rc.size();
127bf215546Sopenharmony_ci}
128bf215546Sopenharmony_ci
129bf215546Sopenharmony_ci} // namespace aco
130