mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-04 17:50:11 +01:00
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:
parent
25a7947da7
commit
e230dcc30b
1 changed files with 38 additions and 22 deletions
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue