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