From 22bd7dcc421cfdec614093c4027bd2292e9b55c4 Mon Sep 17 00:00:00 2001 From: Ivan Chikish Date: Thu, 13 Apr 2023 11:30:53 +0300 Subject: [PATCH] PPU LLVM: disable DSE pass and use volatile store/loads --- rpcs3/Emu/CPU/CPUTranslator.h | 3 ++- rpcs3/Emu/Cell/PPUThread.cpp | 2 +- rpcs3/Emu/Cell/PPUTranslator.cpp | 19 +++++++++++-------- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/rpcs3/Emu/CPU/CPUTranslator.h b/rpcs3/Emu/CPU/CPUTranslator.h index da465e3d52..e21763e6b3 100644 --- a/rpcs3/Emu/CPU/CPUTranslator.h +++ b/rpcs3/Emu/CPU/CPUTranslator.h @@ -21,6 +21,7 @@ #include "llvm/IR/Module.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Support/KnownBits.h" +#include "llvm/Support/ModRef.h" #include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/IntrinsicsX86.h" @@ -3051,7 +3052,7 @@ public: } template - auto call(llvm::Function* func, Args&&... args) + auto callf(llvm::Function* func, Args&&... args) { llvm_value_t r; r.value = m_ir->CreateCall(func, {std::forward(args).eval(m_ir)...}); diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 9f277d5b6c..0adc43c0a7 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -3996,7 +3996,7 @@ static void ppu_initialize2(jit_compiler& jit, const ppu_module& module_part, co //pm.add(createLICMPass()); //pm.add(createLoopInstSimplifyPass()); //pm.add(createNewGVNPass()); - pm.add(createDeadStoreEliminationPass()); + //pm.add(createDeadStoreEliminationPass()); //pm.add(createSCCPPass()); //pm.add(createReassociatePass()); //pm.add(createInstructionCombiningPass()); diff --git a/rpcs3/Emu/Cell/PPUTranslator.cpp b/rpcs3/Emu/Cell/PPUTranslator.cpp index d75a4b0a61..51972b4544 100644 --- a/rpcs3/Emu/Cell/PPUTranslator.cpp +++ b/rpcs3/Emu/Cell/PPUTranslator.cpp @@ -372,7 +372,7 @@ void PPUTranslator::CallFunction(u64 target, Value* indirect) if (indirect) { - m_ir->CreateStore(Trunc(indirect, GetType()), m_ir->CreateStructGEP(m_thread_type, m_thread, static_cast(&m_cia - m_locals)), true); + m_ir->CreateStore(Trunc(indirect, GetType()), m_ir->CreateStructGEP(m_thread_type, m_thread, static_cast(&m_cia - m_locals))); // Try to optimize if (auto inst = dyn_cast_or_null(indirect)) @@ -605,11 +605,14 @@ Value* PPUTranslator::ReadMemory(Value* addr, Type* type, bool is_be, u32 align) // Read, byteswap, bitcast const auto int_type = m_ir->getIntNTy(size); const auto value = m_ir->CreateAlignedLoad(int_type, GetMemory(addr), llvm::MaybeAlign{align}); + value->setVolatile(true); return bitcast(Call(int_type, fmt::format("llvm.bswap.i%u", size), value), type); } // Read normally - return m_ir->CreateAlignedLoad(type, GetMemory(addr), llvm::MaybeAlign{align}); + const auto r = m_ir->CreateAlignedLoad(type, GetMemory(addr), llvm::MaybeAlign{align}); + r->setVolatile(true); + return r; } void PPUTranslator::WriteMemory(Value* addr, Value* value, bool is_be, u32 align) @@ -625,7 +628,7 @@ void PPUTranslator::WriteMemory(Value* addr, Value* value, bool is_be, u32 align } // Write - m_ir->CreateAlignedStore(value, GetMemory(addr), llvm::MaybeAlign{align}); + m_ir->CreateAlignedStore(value, GetMemory(addr), llvm::MaybeAlign{align})->setVolatile(true); } void PPUTranslator::CompilationError(const std::string& error) @@ -1393,22 +1396,22 @@ void PPUTranslator::VREFP(ppu_opcode_t op) void PPUTranslator::VRFIM(ppu_opcode_t op) { - set_vr(op.vd, vec_handle_result(call(get_intrinsic(Intrinsic::floor), get_vr(op.vb)))); + set_vr(op.vd, vec_handle_result(callf(get_intrinsic(Intrinsic::floor), get_vr(op.vb)))); } void PPUTranslator::VRFIN(ppu_opcode_t op) { - set_vr(op.vd, vec_handle_result(call(get_intrinsic(Intrinsic::roundeven), get_vr(op.vb)))); + set_vr(op.vd, vec_handle_result(callf(get_intrinsic(Intrinsic::roundeven), get_vr(op.vb)))); } void PPUTranslator::VRFIP(ppu_opcode_t op) { - set_vr(op.vd, vec_handle_result(call(get_intrinsic(Intrinsic::ceil), get_vr(op.vb)))); + set_vr(op.vd, vec_handle_result(callf(get_intrinsic(Intrinsic::ceil), get_vr(op.vb)))); } void PPUTranslator::VRFIZ(ppu_opcode_t op) { - set_vr(op.vd, vec_handle_result(call(get_intrinsic(Intrinsic::trunc), get_vr(op.vb)))); + set_vr(op.vd, vec_handle_result(callf(get_intrinsic(Intrinsic::trunc), get_vr(op.vb)))); } void PPUTranslator::VRLB(ppu_opcode_t op) @@ -1431,7 +1434,7 @@ void PPUTranslator::VRLW(ppu_opcode_t op) void PPUTranslator::VRSQRTEFP(ppu_opcode_t op) { - set_vr(op.vd, vec_handle_result(fsplat(1.0) / call(get_intrinsic(Intrinsic::sqrt), get_vr(op.vb)))); + set_vr(op.vd, vec_handle_result(fsplat(1.0) / callf(get_intrinsic(Intrinsic::sqrt), get_vr(op.vb)))); } void PPUTranslator::VSEL(ppu_opcode_t op)