diff --git a/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp b/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp index b2b719f88d..f8bd5a75e4 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp +++ b/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp @@ -75,7 +75,7 @@ Compiler::~Compiler() { delete m_llvm_context; } -std::pair Compiler::Compile(const std::string & name, u32 start_address, u32 instruction_count, bool generate_linkable_exits) { +std::pair Compiler::Compile(const std::string & name, u32 start_address, u32 instruction_count) { auto compilation_start = std::chrono::high_resolution_clock::now(); m_module = new llvm::Module("Module", *m_llvm_context); @@ -118,8 +118,6 @@ std::pair Compiler::Compile(const std::stri fpm->add(createCFGSimplificationPass()); fpm->doInitialization(); - m_state.generate_linkable_exits = generate_linkable_exits; - // Create the function m_state.function = (Function *)m_module->getOrInsertFunction(name, m_compiled_function_type); m_state.function->setCallingConv(CallingConv::X86_64_Win64); @@ -174,27 +172,7 @@ std::pair Compiler::Compile(const std::stri SetPc(m_ir_builder->getInt32(m_state.current_instruction_address)); - if (generate_linkable_exits) { - Value *context_i64 = m_ir_builder->CreateZExt(exit_instr_i32, m_ir_builder->getInt64Ty()); - context_i64 = m_ir_builder->CreateOr(context_i64, (u64)start_address << 32); - Value *ret_i32 = IndirectCall(m_state.current_instruction_address, context_i64, false); - Value *cmp_i1 = m_ir_builder->CreateICmpNE(ret_i32, m_ir_builder->getInt32(0)); - BasicBlock *then_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, "then_0"); - BasicBlock *merge_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, "merge_0"); - m_ir_builder->CreateCondBr(cmp_i1, then_bb, merge_bb); - - m_ir_builder->SetInsertPoint(then_bb); - context_i64 = m_ir_builder->CreateZExt(ret_i32, m_ir_builder->getInt64Ty()); - context_i64 = m_ir_builder->CreateOr(context_i64, (u64)start_address << 32); - m_ir_builder->CreateCall2(m_execute_unknown_block, m_state.args[CompileTaskState::Args::State], context_i64); - m_ir_builder->CreateBr(merge_bb); - - m_ir_builder->SetInsertPoint(merge_bb); - m_ir_builder->CreateRet(m_ir_builder->getInt32(0)); - } - else { - m_ir_builder->CreateRet(exit_instr_i32); - } + m_ir_builder->CreateRet(exit_instr_i32); } // If the function has a default exit block then generate code for it @@ -204,24 +182,8 @@ std::pair Compiler::Compile(const std::stri PHINode *exit_instr_i32 = m_ir_builder->CreatePHI(m_ir_builder->getInt32Ty(), 0); exit_instr_list.push_back(exit_instr_i32); - if (generate_linkable_exits) { - Value *cmp_i1 = m_ir_builder->CreateICmpNE(exit_instr_i32, m_ir_builder->getInt32(0)); - BasicBlock *then_bb = GetBasicBlockFromAddress(0xFFFFFFFF, "then_0"); - BasicBlock *merge_bb = GetBasicBlockFromAddress(0xFFFFFFFF, "merge_0"); - m_ir_builder->CreateCondBr(cmp_i1, then_bb, merge_bb); + m_ir_builder->CreateRet(exit_instr_i32); - m_ir_builder->SetInsertPoint(then_bb); - Value *context_i64 = m_ir_builder->CreateZExt(exit_instr_i32, m_ir_builder->getInt64Ty()); - context_i64 = m_ir_builder->CreateOr(context_i64, (u64)start_address << 32); - m_ir_builder->CreateCall2(m_execute_unknown_block, m_state.args[CompileTaskState::Args::State], context_i64); - m_ir_builder->CreateBr(merge_bb); - - m_ir_builder->SetInsertPoint(merge_bb); - m_ir_builder->CreateRet(m_ir_builder->getInt32(0)); - } - else { - m_ir_builder->CreateRet(exit_instr_i32); - } } // Add incoming values for all exit instr PHI nodes @@ -308,13 +270,6 @@ RecompilationEngine::~RecompilationEngine() { free(FunctionCachePagesCommited); } -Executable executeFunc; -Executable executeUntilReturn; - -const Executable *RecompilationEngine::GetExecutable(u32 address, bool isFunction) { - return isFunction ? &executeFunc : &executeUntilReturn; -} - bool RecompilationEngine::isAddressCommited(u32 address) const { size_t offset = address * sizeof(Executable); @@ -511,7 +466,7 @@ void RecompilationEngine::CompileBlock(BlockEntry & block_entry) { return; Log() << "Compile: " << block_entry.ToString() << "\n"; const std::pair &compileResult = - m_compiler.Compile(fmt::format("fn_0x%08X", block_entry.address), block_entry.address, block_entry.instructionCount, false /*generate_linkable_exits*/); + m_compiler.Compile(fmt::format("fn_0x%08X", block_entry.address), block_entry.address, block_entry.instructionCount); // If entry doesn't exist, create it (using lock) std::unordered_map::iterator It = m_address_to_function.find(block_entry.address); @@ -547,8 +502,6 @@ ppu_recompiler_llvm::CPUHybridDecoderRecompiler::CPUHybridDecoderRecompiler(PPUT , m_interpreter(new PPUInterpreter(ppu)) , m_decoder(m_interpreter) , m_recompilation_engine(RecompilationEngine::GetInstance()) { - executeFunc = CPUHybridDecoderRecompiler::ExecuteFunction; - executeUntilReturn = CPUHybridDecoderRecompiler::ExecuteTillReturn; } ppu_recompiler_llvm::CPUHybridDecoderRecompiler::~CPUHybridDecoderRecompiler() { diff --git a/rpcs3/Emu/Cell/PPULLVMRecompiler.h b/rpcs3/Emu/Cell/PPULLVMRecompiler.h index a755014755..1f9c5f127c 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompiler.h +++ b/rpcs3/Emu/Cell/PPULLVMRecompiler.h @@ -71,7 +71,7 @@ namespace ppu_recompiler_llvm { * Compile a code fragment described by a cfg and return an executable and the ExecutionEngine storing it * Pointer to function can be retrieved with getPointerToFunction */ - std::pair Compile(const std::string & name, u32 start_address, u32 instruction_count, bool generate_linkable_exits); + std::pair Compile(const std::string & name, u32 start_address, u32 instruction_count); /// Retrieve compiler stats Stats GetStats(); @@ -506,9 +506,6 @@ namespace ppu_recompiler_llvm { /// This is set to false at the start of compilation of an instruction. /// If a branch instruction is encountered, this is set to true by the decode function. bool hit_branch_instruction; - - /// Create code such that exit points can be linked to other blocks - bool generate_linkable_exits; }; /// Recompilation engine @@ -745,9 +742,6 @@ namespace ppu_recompiler_llvm { return m_ir_builder->CreateCall(fn, fn_args); } - /// Indirect call - llvm::Value * IndirectCall(u32 address, llvm::Value * context_i64, bool is_function); - /// Test an instruction against the interpreter template void VerifyInstructionAgainstInterpreter(const char * name, void (Compiler::*recomp_fn)(Args...), void (PPUInterpreter::*interp_fn)(Args...), PPUState & input_state, Args... args); @@ -781,13 +775,6 @@ namespace ppu_recompiler_llvm { public: virtual ~RecompilationEngine() override; - /** - * Get the executable for the specified address - * The pointer is always valid during the lifetime of RecompilationEngine - * but the function pointed to can be updated. - **/ - const Executable *GetExecutable(u32 address, bool isFunction); - /** * Get the executable for the specified address if a compiled version is * available, otherwise returns nullptr. diff --git a/rpcs3/Emu/Cell/PPULLVMRecompilerCore.cpp b/rpcs3/Emu/Cell/PPULLVMRecompilerCore.cpp index 1485e518f0..3c66119ab0 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompilerCore.cpp +++ b/rpcs3/Emu/Cell/PPULLVMRecompilerCore.cpp @@ -5273,25 +5273,6 @@ void Compiler::WriteMemory(Value * addr_i64, Value * val_ix, u32 alignment, bool m_ir_builder->CreateAlignedStore(val_ix, eaddr_ix_ptr, alignment); } -llvm::Value * Compiler::IndirectCall(u32 address, Value * context_i64, bool is_function) { - const Executable *functionPtr = m_recompilation_engine.GetExecutable(address, is_function); - auto location_i64 = m_ir_builder->getInt64((uint64_t)functionPtr); - auto location_i64_ptr = m_ir_builder->CreateIntToPtr(location_i64, m_ir_builder->getInt64Ty()->getPointerTo()); - auto executable_i64 = m_ir_builder->CreateLoad(location_i64_ptr); - auto executable_ptr = m_ir_builder->CreateIntToPtr(executable_i64, m_compiled_function_type->getPointerTo()); - auto ret_i32 = m_ir_builder->CreateCall2(executable_ptr, m_state.args[CompileTaskState::Args::State], context_i64); - - auto cmp_i1 = m_ir_builder->CreateICmpEQ(ret_i32, m_ir_builder->getInt32(0xFFFFFFFF)); - auto then_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, "then_all_fs"); - auto merge_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, "merge_all_fs"); - m_ir_builder->CreateCondBr(cmp_i1, then_bb, merge_bb); - - m_ir_builder->SetInsertPoint(then_bb); - m_ir_builder->CreateRet(m_ir_builder->getInt32(0)); - m_ir_builder->SetInsertPoint(merge_bb); - return ret_i32; -} - void Compiler::CompilationError(const std::string & error) { LOG_ERROR(PPU, "[0x%08X] %s", m_state.current_instruction_address, error.c_str()); Emu.Pause();