PPU/LLVM: Avoid using an indirect call for function call

This commit is contained in:
Vincent Lejeune 2015-08-21 17:03:27 +02:00
parent b2ca9edde2
commit eb90e509f9
1 changed files with 6 additions and 23 deletions

View File

@ -5199,7 +5199,11 @@ void Compiler::CreateBranch(llvm::Value * cmp_i1, llvm::Value * target_i32, bool
}
SetPc(target_i32);
IndirectCall(target_address, m_ir_builder->getInt64(0), true);
Function *fn = m_module->getFunction(fmt::format("function_0x%08X", target_address));
if (fn)
m_ir_builder->CreateCall2(fn, m_state.args[CompileTaskState::Args::State], m_ir_builder->getInt64(0));
else
Call<u32>("execute_unknown_function", nullptr, m_state.args[CompileTaskState::Args::State], m_ir_builder->getInt64(0));
m_ir_builder->CreateBr(GetBasicBlockFromAddress(m_state.current_instruction_address + 4));
}
else {
@ -5221,32 +5225,11 @@ void Compiler::CreateBranch(llvm::Value * cmp_i1, llvm::Value * target_i32, bool
}
else if (lk) {
BasicBlock *next_block = GetBasicBlockFromAddress(m_state.current_instruction_address + 4);
BasicBlock *unknown_function_block = GetBasicBlockFromAddress(m_state.current_instruction_address, "unknown_function");
auto switch_instr = m_ir_builder->CreateSwitch(target_i32, unknown_function_block);
m_ir_builder->SetInsertPoint(unknown_function_block);
m_ir_builder->CreateCall2(m_execute_unknown_function, m_state.args[CompileTaskState::Args::State], m_ir_builder->getInt64(0));
m_ir_builder->CreateBr(next_block);
auto call_i = m_state.cfg->calls.find(m_state.current_instruction_address);
if (call_i != m_state.cfg->calls.end()) {
for (auto function_i = call_i->second.begin(); function_i != call_i->second.end(); function_i++) {
auto block = GetBasicBlockFromAddress(m_state.current_instruction_address, fmt::format("0x%08X", *function_i));
m_ir_builder->SetInsertPoint(block);
IndirectCall(*function_i, m_ir_builder->getInt64(0), true);
m_ir_builder->CreateBr(next_block);
switch_instr->addCase(m_ir_builder->getInt32(*function_i), block);
}
}
}
else {
auto switch_instr = m_ir_builder->CreateSwitch(target_i32, GetBasicBlockFromAddress(0xFFFFFFFF));
auto branch_i = m_state.cfg->branches.find(m_state.current_instruction_address);
if (branch_i != m_state.cfg->branches.end()) {
for (auto next_instr_i = branch_i->second.begin(); next_instr_i != branch_i->second.end(); next_instr_i++) {
switch_instr->addCase(m_ir_builder->getInt32(*next_instr_i), GetBasicBlockFromAddress(*next_instr_i));
}
}
m_ir_builder->CreateRet(m_ir_builder->getInt32(-1));
}
}