From 6036cc8f79de5fe783da84880d10ec62502cfa83 Mon Sep 17 00:00:00 2001 From: Frodo Baggins Date: Mon, 21 Oct 2024 16:41:02 -0700 Subject: [PATCH] add use tracking for Insts --- .../backend/spirv/emit_spirv.cpp | 1 - src/shader_recompiler/ir/microinstruction.cpp | 30 +++++++++---------- src/shader_recompiler/ir/value.h | 20 +++++++++---- 3 files changed, 29 insertions(+), 22 deletions(-) diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp index e84908a57..fefaea6a5 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp @@ -1,6 +1,5 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later - #include #include #include diff --git a/src/shader_recompiler/ir/microinstruction.cpp b/src/shader_recompiler/ir/microinstruction.cpp index f0b4882b3..fae4b4a49 100644 --- a/src/shader_recompiler/ir/microinstruction.cpp +++ b/src/shader_recompiler/ir/microinstruction.cpp @@ -116,10 +116,10 @@ void Inst::SetArg(size_t index, Value value) { } const IR::Value arg{Arg(index)}; if (!arg.IsImmediate()) { - UndoUse(arg); + UndoUse(arg.Inst()); } if (!value.IsImmediate()) { - Use(value); + Use(value.Inst(), index); } if (op == Opcode::Phi) { phi_args[index].second = value; @@ -140,12 +140,13 @@ Block* Inst::PhiBlock(size_t index) const { void Inst::AddPhiOperand(Block* predecessor, const Value& value) { if (!value.IsImmediate()) { - Use(value); + Use(value.Inst(), phi_args.size()); } phi_args.emplace_back(predecessor, value); } void Inst::Invalidate() { + ASSERT(uses.empty()); ClearArgs(); ReplaceOpcode(Opcode::Void); } @@ -155,14 +156,14 @@ void Inst::ClearArgs() { for (auto& pair : phi_args) { IR::Value& value{pair.second}; if (!value.IsImmediate()) { - UndoUse(value); + UndoUse(value.Inst()); } } phi_args.clear(); } else { for (auto& value : args) { if (!value.IsImmediate()) { - UndoUse(value); + UndoUse(value.Inst()); } } // Reset arguments to null @@ -172,12 +173,13 @@ void Inst::ClearArgs() { } void Inst::ReplaceUsesWith(Value replacement) { - Invalidate(); - ReplaceOpcode(Opcode::Identity); if (!replacement.IsImmediate()) { - Use(replacement); + for (auto& [user, operand] : uses) { + user->SetArg(operand, replacement); + } } - args[0] = replacement; + uses.clear(); + Invalidate(); } void Inst::ReplaceOpcode(IR::Opcode opcode) { @@ -192,14 +194,12 @@ void Inst::ReplaceOpcode(IR::Opcode opcode) { op = opcode; } -void Inst::Use(const Value& value) { - Inst* const inst{value.Inst()}; - ++inst->use_count; +void Inst::Use(Inst* used, u32 operand) { + used->uses.emplace_front(this, operand); } -void Inst::UndoUse(const Value& value) { - Inst* const inst{value.Inst()}; - --inst->use_count; +void Inst::UndoUse(Inst* used) { + used->uses.remove_if([this](const IR::Use& use) { return use.user == this; }); } } // namespace Shader::IR diff --git a/src/shader_recompiler/ir/value.h b/src/shader_recompiler/ir/value.h index a282b9168..a87db2f77 100644 --- a/src/shader_recompiler/ir/value.h +++ b/src/shader_recompiler/ir/value.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -15,6 +16,7 @@ #include "shader_recompiler/exception.h" #include "shader_recompiler/ir/attribute.h" #include "shader_recompiler/ir/opcodes.h" +#include "shader_recompiler/ir/patch.h" #include "shader_recompiler/ir/reg.h" #include "shader_recompiler/ir/type.h" @@ -104,6 +106,11 @@ public: explicit TypedValue(IR::Inst* inst_) : TypedValue(Value(inst_)) {} }; +struct Use { + Inst* user; + u32 operand; +}; + class Inst : public boost::intrusive::list_base_hook<> { public: explicit Inst(IR::Opcode op_, u32 flags_) noexcept; @@ -117,12 +124,12 @@ public: /// Get the number of uses this instruction has. [[nodiscard]] int UseCount() const noexcept { - return use_count; + return uses.size(); } /// Determines whether this instruction has uses or not. [[nodiscard]] bool HasUses() const noexcept { - return use_count > 0; + return uses.size() > 0; } /// Get the opcode this microinstruction represents. @@ -199,11 +206,10 @@ private: NonTriviallyDummy() noexcept {} }; - void Use(const Value& value); - void UndoUse(const Value& value); + void Use(Inst* used, u32 operand); + void UndoUse(Inst* used); IR::Opcode op{}; - int use_count{}; u32 flags{}; u32 definition{}; union { @@ -211,8 +217,10 @@ private: boost::container::small_vector, 2> phi_args; std::array args; }; + + boost::container::list uses; }; -static_assert(sizeof(Inst) <= 128, "Inst size unintentionally increased"); +static_assert(sizeof(Inst) <= 152, "Inst size unintentionally increased"); using U1 = TypedValue; using U8 = TypedValue;