mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-17 08:11:51 +00:00
PPU LLVM: Optimize branch list
This commit is contained in:
parent
cf6eb64f0b
commit
fdbb0b0e2f
@ -13,6 +13,7 @@
|
||||
#include "util/v128.hpp"
|
||||
#include "util/simd.hpp"
|
||||
#include <algorithm>
|
||||
#include <unordered_set>
|
||||
#include <span>
|
||||
|
||||
using namespace llvm;
|
||||
@ -371,8 +372,50 @@ void PPUTranslator::CallFunction(u64 target, Value* indirect)
|
||||
|
||||
if (_target >= caddr && _target <= cend)
|
||||
{
|
||||
callee = m_module->getOrInsertFunction(fmt::format("__0x%x", target), type);
|
||||
cast<Function>(callee.getCallee())->setCallingConv(CallingConv::GHC);
|
||||
std::unordered_set<u64> passed_targets{_target};
|
||||
|
||||
u32 target_last = _target;
|
||||
|
||||
// Try to follow unconditional branches as long as there is no infinite loop
|
||||
while (target_last != _target)
|
||||
{
|
||||
const ppu_opcode_t op{*ensure(m_info.get_ptr<u32>(target_last))};
|
||||
const ppu_itype::type itype = g_ppu_itype.decode(op.opcode);
|
||||
|
||||
if (((itype == ppu_itype::BC && (op.bo & 0x14) == 0x14) || itype == ppu_itype::B) && !op.lk)
|
||||
{
|
||||
const u32 new_target = (op.aa ? 0 : target_last) + (itype == ppu_itype::B ? +op.bt24 : +op.bt14);
|
||||
|
||||
if (target_last >= caddr && target_last <= cend)
|
||||
{
|
||||
if (passed_targets.emplace(new_target).second)
|
||||
{
|
||||
// Ok
|
||||
target_last = new_target;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Infinite loop detected
|
||||
target_last = _target;
|
||||
}
|
||||
|
||||
// Odd destination
|
||||
}
|
||||
else if (itype == ppu_itype::BCLR && (op.bo & 0x14) == 0x14 && !op.lk)
|
||||
{
|
||||
// Special case: empty function
|
||||
// In this case the branch can be treated as BCLR because previous CIA does not matter
|
||||
indirect = RegLoad(m_lr);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!indirect)
|
||||
{
|
||||
callee = m_module->getOrInsertFunction(fmt::format("__0x%x", target_last - base), type);
|
||||
cast<Function>(callee.getCallee())->setCallingConv(CallingConv::GHC);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user