From 7001cfa3477831df680617750b6e5e37c363d102 Mon Sep 17 00:00:00 2001 From: Frodo Baggins Date: Mon, 21 Oct 2024 18:24:51 -0700 Subject: [PATCH] broken. add some asserts --- CMakeLists.txt | 4 ++++ src/shader_recompiler/ir/microinstruction.cpp | 18 ++++++++++++++++-- src/shader_recompiler/ir/value.h | 1 - 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 04bd6a331..ac81009ba 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,10 @@ if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release) endif() +if (CMAKE_BUILD_TYPE STREQUAL "Debug") + add_compile_definitions(_DEBUG) +endif() + project(shadPS4) # Forcing PIE makes sure that the base address is high enough so that it doesn't clash with the PS4 memory. diff --git a/src/shader_recompiler/ir/microinstruction.cpp b/src/shader_recompiler/ir/microinstruction.cpp index 419161b3a..664219de7 100644 --- a/src/shader_recompiler/ir/microinstruction.cpp +++ b/src/shader_recompiler/ir/microinstruction.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include +#include #include #include "shader_recompiler/exception.h" @@ -31,6 +32,8 @@ Inst::Inst(const Inst& base) : op{base.op}, flags{base.flags} { } Inst::~Inst() { + // necessary? Or are all Insts destroyed at once? + ClearArgs(); if (op == Opcode::Phi) { std::destroy_at(&phi_args); } else { @@ -175,12 +178,19 @@ void Inst::ClearArgs() { } void Inst::ReplaceUsesWith(Value replacement) { + // move uses because SetArg will call UndoUse and would otherwise + // mutate uses while iterating +#ifdef _DEBUG + boost::container::list temp_uses = uses; +#else + boost::container::list temp_uses = std::move(uses); +#endif if (!replacement.IsImmediate()) { - for (auto& [user, operand] : uses) { + for (auto& [user, operand] : temp_uses) { + DEBUG_ASSERT(user->Arg(operand).Inst() == this); user->SetArg(operand, replacement); } } - uses.clear(); Invalidate(); } @@ -197,11 +207,15 @@ void Inst::ReplaceOpcode(IR::Opcode opcode) { } void Inst::Use(Inst* used, u32 operand) { + DEBUG_ASSERT(std::none_of(used->uses.begin(), used->uses.end(), [&](const IR::Use& use) { + return use.operand == operand && use.user == this; + })); used->uses.emplace_front(this, operand); } void Inst::UndoUse(Inst* used, u32 operand) { IR::Use use(this, operand); + DEBUG_ASSERT(1 == std::count(used->uses.begin(), used->uses.end(), use)); used->uses.remove(use); } diff --git a/src/shader_recompiler/ir/value.h b/src/shader_recompiler/ir/value.h index 7d5532a67..6f5c9d824 100644 --- a/src/shader_recompiler/ir/value.h +++ b/src/shader_recompiler/ir/value.h @@ -16,7 +16,6 @@ #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"