mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-08 07:51:28 +12:00
PPU/LLVM: Remove indirect call completly
This commit is contained in:
parent
60d5dd40f7
commit
58181c5c17
3 changed files with 5 additions and 84 deletions
|
@ -75,7 +75,7 @@ Compiler::~Compiler() {
|
|||
delete m_llvm_context;
|
||||
}
|
||||
|
||||
std::pair<Executable, llvm::ExecutionEngine *> Compiler::Compile(const std::string & name, u32 start_address, u32 instruction_count, bool generate_linkable_exits) {
|
||||
std::pair<Executable, llvm::ExecutionEngine *> 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<Executable, llvm::ExecutionEngine *> 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<Executable, llvm::ExecutionEngine *> 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<Executable, llvm::ExecutionEngine *> 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<Executable, llvm::ExecutionEngine *> &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<u32, ExecutableStorage>::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() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue