ssa_rewrite: Recursively remove phis

This commit is contained in:
IndecisiveTurtle 2024-12-04 20:19:38 +02:00
parent 38ac0024bf
commit b5ac4c5569
4 changed files with 25 additions and 11 deletions

View File

@ -330,6 +330,7 @@ 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}};
} }
@ -347,6 +348,7 @@ 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

@ -150,7 +150,6 @@ void Inst::AddPhiOperand(Block* predecessor, const Value& value) {
} }
void Inst::Invalidate() { void Inst::Invalidate() {
ASSERT(uses.empty());
ClearArgs(); ClearArgs();
ReplaceOpcode(Opcode::Void); ReplaceOpcode(Opcode::Void);
} }

View File

@ -164,7 +164,6 @@ IR::Opcode UndefOpcode(const FlagTag) noexcept {
enum class Status { enum class Status {
Start, Start,
SetValue, SetValue,
PreparePhiArgument,
PushPhiArgument, PushPhiArgument,
}; };
@ -253,12 +252,10 @@ public:
IR::Inst* const phi{stack.back().phi}; IR::Inst* const phi{stack.back().phi};
phi->AddPhiOperand(*stack.back().pred_it, stack.back().result); phi->AddPhiOperand(*stack.back().pred_it, stack.back().result);
++stack.back().pred_it; ++stack.back().pred_it;
}
[[fallthrough]];
case Status::PreparePhiArgument:
prepare_phi_operand(); prepare_phi_operand();
break; break;
} }
}
} while (stack.size() > 1); } while (stack.size() > 1);
return stack.back().result; return stack.back().result;
} }
@ -266,16 +263,13 @@ public:
void SealBlock(IR::Block* block) { void SealBlock(IR::Block* block) {
const auto it{incomplete_phis.find(block)}; const auto it{incomplete_phis.find(block)};
if (it != incomplete_phis.end()) { if (it != incomplete_phis.end()) {
for (auto& pair : it->second) { for (auto& [variant, phi] : it->second) {
auto& variant{pair.first};
auto& phi{pair.second};
std::visit([&](auto& variable) { AddPhiOperands(variable, *phi, block); }, variant); std::visit([&](auto& variable) { AddPhiOperands(variable, *phi, block); }, variant);
} }
} }
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()) {
@ -317,6 +311,12 @@ private:
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 // TODO: Try to recursively remove all phi users, which might have become trivial
const auto users = phi.Uses();
for (const auto& [user, arg_index] : users) {
if (user->GetOpcode() == IR::Opcode::Phi) {
TryRemoveTrivialPhi(*user, user->GetParent(), undef_opcode);
}
}
return same; return same;
} }

View File

@ -129,6 +129,14 @@ public:
Inst& operator=(Inst&&) = delete; Inst& operator=(Inst&&) = delete;
Inst(Inst&&) = delete; Inst(Inst&&) = delete;
IR::Block* GetParent() {
ASSERT(parent);
return parent;
}
void SetParent(IR::Block* block) {
parent = block;
}
/// Get the number of uses this instruction has. /// Get the number of uses this instruction has.
[[nodiscard]] int UseCount() const noexcept { [[nodiscard]] int UseCount() const noexcept {
return uses.size(); return uses.size();
@ -214,6 +222,10 @@ public:
return std::bit_cast<DefinitionType>(definition); return std::bit_cast<DefinitionType>(definition);
} }
const auto Uses() const {
return uses;
}
private: private:
struct NonTriviallyDummy { struct NonTriviallyDummy {
NonTriviallyDummy() noexcept {} NonTriviallyDummy() noexcept {}
@ -226,6 +238,7 @@ private:
IR::Opcode op{}; IR::Opcode op{};
u32 flags{}; u32 flags{};
u32 definition{}; u32 definition{};
IR::Block* parent{};
union { union {
NonTriviallyDummy dummy{}; NonTriviallyDummy dummy{};
boost::container::small_vector<std::pair<Block*, Value>, 2> phi_args; boost::container::small_vector<std::pair<Block*, Value>, 2> phi_args;
@ -234,7 +247,7 @@ private:
boost::container::list<IR::Use> uses; boost::container::list<IR::Use> uses;
}; };
static_assert(sizeof(Inst) <= 152, "Inst size unintentionally increased"); static_assert(sizeof(Inst) <= 160, "Inst size unintentionally increased");
using U1 = TypedValue<Type::U1>; using U1 = TypedValue<Type::U1>;
using U8 = TypedValue<Type::U8>; using U8 = TypedValue<Type::U8>;
@ -392,4 +405,4 @@ template <>
struct hash<Shader::IR::Value> { struct hash<Shader::IR::Value> {
std::size_t operator()(const Shader::IR::Value& v) const; std::size_t operator()(const Shader::IR::Value& v) const;
}; };
} // namespace std } // namespace std