aco: Refactor SSA elimination phi info to use vector instead of map.

No Fossil DB changes.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
Reviewed-by: Tony Wasserka <tony.wasserka@gmx.de>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10691>
This commit is contained in:
Timur Kristóf 2021-05-13 20:43:28 +02:00 committed by Marge Bot
parent 25a7947da7
commit e230dcc30b

View file

@ -30,16 +30,23 @@
namespace aco {
namespace {
/* map: block-id -> pair (dest, src) to store phi information */
typedef std::map<uint32_t, std::vector<std::pair<Definition, Operand>>> phi_info;
struct phi_info_item {
Definition def;
Operand op;
};
struct ssa_elimination_ctx {
phi_info logical_phi_info;
phi_info linear_phi_info;
/* The outer vectors should be indexed by block index. The inner vectors store phi information for each block. */
std::vector<std::vector<phi_info_item>> logical_phi_info;
std::vector<std::vector<phi_info_item>> linear_phi_info;
std::vector<bool> empty_blocks;
Program* program;
ssa_elimination_ctx(Program* program_) : empty_blocks(program_->blocks.size(), true), program(program_) {}
ssa_elimination_ctx(Program* program_)
: logical_phi_info(program_->blocks.size())
, linear_phi_info(program_->blocks.size())
, empty_blocks(program_->blocks.size(), true)
, program(program_) {}
};
void collect_phi_info(ssa_elimination_ctx& ctx)
@ -55,12 +62,13 @@ void collect_phi_info(ssa_elimination_ctx& ctx)
if (phi->operands[i].physReg() == phi->definitions[0].physReg())
continue;
std::vector<unsigned>& preds = phi->opcode == aco_opcode::p_phi ? block.logical_preds : block.linear_preds;
phi_info& info = phi->opcode == aco_opcode::p_phi ? ctx.logical_phi_info : ctx.linear_phi_info;
const auto result = info.emplace(preds[i], std::vector<std::pair<Definition, Operand>>());
assert(phi->definitions[0].size() == phi->operands[i].size());
result.first->second.emplace_back(phi->definitions[0], phi->operands[i]);
ctx.empty_blocks[preds[i]] = false;
std::vector<unsigned>& preds = phi->opcode == aco_opcode::p_phi ? block.logical_preds : block.linear_preds;
uint32_t pred_idx = preds[i];
auto& info_vec = phi->opcode == aco_opcode::p_phi ? ctx.logical_phi_info[pred_idx] : ctx.linear_phi_info[pred_idx];
info_vec.push_back({phi->definitions[0], phi->operands[i]});
ctx.empty_blocks[pred_idx] = false;
}
}
}
@ -69,8 +77,12 @@ void collect_phi_info(ssa_elimination_ctx& ctx)
void insert_parallelcopies(ssa_elimination_ctx& ctx)
{
/* insert the parallelcopies from logical phis before p_logical_end */
for (auto&& entry : ctx.logical_phi_info) {
Block& block = ctx.program->blocks[entry.first];
for (unsigned block_idx = 0; block_idx < ctx.program->blocks.size(); ++block_idx) {
auto &logical_phi_info = ctx.logical_phi_info[block_idx];
if (logical_phi_info.empty())
continue;
Block& block = ctx.program->blocks[block_idx];
unsigned idx = block.instructions.size() - 1;
while (block.instructions[idx]->opcode != aco_opcode::p_logical_end) {
assert(idx > 0);
@ -78,12 +90,12 @@ void insert_parallelcopies(ssa_elimination_ctx& ctx)
}
std::vector<aco_ptr<Instruction>>::iterator it = std::next(block.instructions.begin(), idx);
aco_ptr<Pseudo_instruction> pc{create_instruction<Pseudo_instruction>(aco_opcode::p_parallelcopy, Format::PSEUDO, entry.second.size(), entry.second.size())};
aco_ptr<Pseudo_instruction> pc{create_instruction<Pseudo_instruction>(aco_opcode::p_parallelcopy, Format::PSEUDO, logical_phi_info.size(), logical_phi_info.size())};
unsigned i = 0;
for (std::pair<Definition, Operand>& pair : entry.second)
for (auto& phi_info : logical_phi_info)
{
pc->definitions[i] = pair.first;
pc->operands[i] = pair.second;
pc->definitions[i] = phi_info.def;
pc->operands[i] = phi_info.op;
i++;
}
/* this shouldn't be needed since we're only copying vgprs */
@ -92,17 +104,21 @@ void insert_parallelcopies(ssa_elimination_ctx& ctx)
}
/* insert parallelcopies for the linear phis at the end of blocks just before the branch */
for (auto&& entry : ctx.linear_phi_info) {
Block& block = ctx.program->blocks[entry.first];
for (unsigned block_idx = 0; block_idx < ctx.program->blocks.size(); ++block_idx) {
auto &linear_phi_info = ctx.linear_phi_info[block_idx];
if (linear_phi_info.empty())
continue;
Block& block = ctx.program->blocks[block_idx];
std::vector<aco_ptr<Instruction>>::iterator it = block.instructions.end();
--it;
assert((*it)->isBranch());
aco_ptr<Pseudo_instruction> pc{create_instruction<Pseudo_instruction>(aco_opcode::p_parallelcopy, Format::PSEUDO, entry.second.size(), entry.second.size())};
aco_ptr<Pseudo_instruction> pc{create_instruction<Pseudo_instruction>(aco_opcode::p_parallelcopy, Format::PSEUDO, linear_phi_info.size(), linear_phi_info.size())};
unsigned i = 0;
for (std::pair<Definition, Operand>& pair : entry.second)
for (auto& phi_info : linear_phi_info)
{
pc->definitions[i] = pair.first;
pc->operands[i] = pair.second;
pc->definitions[i] = phi_info.def;
pc->operands[i] = phi_info.op;
i++;
}
pc->tmp_in_scc = block.scc_live_out;