ssa_rewrite: Correct recursive trivial phi elimination

This commit is contained in:
IndecisiveTurtle 2024-12-05 00:23:31 +02:00
commit a86b855b38
4 changed files with 8 additions and 7 deletions

View file

@ -19,12 +19,14 @@ void Block::AppendNewInst(Opcode op, std::initializer_list<Value> args) {
Block::iterator Block::PrependNewInst(iterator insertion_point, const Inst& base_inst) { Block::iterator Block::PrependNewInst(iterator insertion_point, const Inst& base_inst) {
Inst* const inst{inst_pool->Create(base_inst)}; Inst* const inst{inst_pool->Create(base_inst)};
inst->SetParent(this);
return instructions.insert(insertion_point, *inst); return instructions.insert(insertion_point, *inst);
} }
Block::iterator Block::PrependNewInst(iterator insertion_point, Opcode op, Block::iterator Block::PrependNewInst(iterator insertion_point, Opcode op,
std::initializer_list<Value> args, u32 flags) { std::initializer_list<Value> args, u32 flags) {
Inst* const inst{inst_pool->Create(op, flags)}; Inst* const inst{inst_pool->Create(op, flags)};
inst->SetParent(this);
const auto result_it{instructions.insert(insertion_point, *inst)}; const auto result_it{instructions.insert(insertion_point, *inst)};
if (inst->NumArgs() != args.size()) { if (inst->NumArgs() != args.size()) {

View file

@ -330,7 +330,6 @@ private:
template <typename T = Value, typename... Args> template <typename T = Value, typename... Args>
T Inst(Opcode op, Args... args) { T Inst(Opcode op, Args... args) {
auto it{block->PrependNewInst(insertion_point, op, {Value{args}...})}; auto it{block->PrependNewInst(insertion_point, op, {Value{args}...})};
it->SetParent(block);
return T{Value{&*it}}; return T{Value{&*it}};
} }
@ -348,7 +347,6 @@ private:
u32 raw_flags{}; u32 raw_flags{};
std::memcpy(&raw_flags, &flags.proxy, sizeof(flags.proxy)); std::memcpy(&raw_flags, &flags.proxy, sizeof(flags.proxy));
auto it{block->PrependNewInst(insertion_point, op, {Value{args}...}, raw_flags)}; auto it{block->PrependNewInst(insertion_point, op, {Value{args}...}, raw_flags)};
it->SetParent(block);
return T{Value{&*it}}; return T{Value{&*it}};
} }
}; };

View file

@ -180,8 +180,8 @@ void Inst::ClearArgs() {
void Inst::ReplaceUsesWith(Value replacement, bool preserve) { void Inst::ReplaceUsesWith(Value replacement, bool preserve) {
// Copy since user->SetArg will mutate this->uses // Copy since user->SetArg will mutate this->uses
// Could also do temp_uses = std::move(uses) but more readable // Could also do temp_uses = std::move(uses) but more readable
boost::container::list<IR::Use> temp_uses = uses; const auto temp_uses = uses;
for (auto& [user, operand] : temp_uses) { for (const auto& [user, operand] : temp_uses) {
DEBUG_ASSERT(user->Arg(operand).Inst() == this); DEBUG_ASSERT(user->Arg(operand).Inst() == this);
user->SetArg(operand, replacement); user->SetArg(operand, replacement);
} }

View file

@ -270,6 +270,7 @@ public:
block->SsaSeal(); block->SsaSeal();
} }
private:
template <typename Type> template <typename Type>
IR::Value AddPhiOperands(Type variable, IR::Inst& phi, IR::Block* block) { IR::Value AddPhiOperands(Type variable, IR::Inst& phi, IR::Block* block) {
for (IR::Block* const imm_pred : block->ImmPredecessors()) { for (IR::Block* const imm_pred : block->ImmPredecessors()) {
@ -283,7 +284,7 @@ public:
const size_t num_args{phi.NumArgs()}; const size_t num_args{phi.NumArgs()};
for (size_t arg_index = 0; arg_index < num_args; ++arg_index) { for (size_t arg_index = 0; arg_index < num_args; ++arg_index) {
const IR::Value& op{phi.Arg(arg_index)}; const IR::Value& op{phi.Arg(arg_index)};
if (op.Resolve() == same.Resolve() || op == IR::Value{&phi}) { if (op.Resolve() == same.Resolve() || op.Resolve() == IR::Value{&phi}) {
// Unique value or self-reference // Unique value or self-reference
continue; continue;
} }
@ -308,10 +309,10 @@ public:
++reinsert_point; ++reinsert_point;
} }
// Reinsert the phi node and reroute all its uses to the "same" value // Reinsert the phi node and reroute all its uses to the "same" value
const auto users = phi.Uses();
list.insert(reinsert_point, phi); list.insert(reinsert_point, phi);
phi.ReplaceUsesWith(same); phi.ReplaceUsesWith(same);
// TODO: Try to recursively remove all phi users, which might have become trivial // Try to recursively remove all phi users, which might have become trivial
const auto users = phi.Uses();
for (const auto& [user, arg_index] : users) { for (const auto& [user, arg_index] : users) {
if (user->GetOpcode() == IR::Opcode::Phi) { if (user->GetOpcode() == IR::Opcode::Phi) {
TryRemoveTrivialPhi(*user, user->GetParent(), undef_opcode); TryRemoveTrivialPhi(*user, user->GetParent(), undef_opcode);