mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-28 22:13:24 +00:00
PPU LLVM: SSA reordering
Fetch indirect jump target Flush registers earlier
This commit is contained in:
parent
da87bb6710
commit
c087a9534a
@ -97,6 +97,12 @@ Function* PPUTranslator::Translate(const ppu_function& info)
|
|||||||
// Process blocks
|
// Process blocks
|
||||||
const auto block = std::make_pair(info.addr, info.size);
|
const auto block = std::make_pair(info.addr, info.size);
|
||||||
{
|
{
|
||||||
|
// Optimize BLR (prefetch LR)
|
||||||
|
if (vm::ps3::read32(vm::cast(block.first + block.second - 4)) == ppu_instructions::BLR())
|
||||||
|
{
|
||||||
|
RegLoad(m_lr);
|
||||||
|
}
|
||||||
|
|
||||||
// Process the instructions
|
// Process the instructions
|
||||||
for (m_current_addr = block.first; m_current_addr < block.first + block.second; m_current_addr += 4)
|
for (m_current_addr = block.first; m_current_addr < block.first + block.second; m_current_addr += 4)
|
||||||
{
|
{
|
||||||
@ -149,6 +155,7 @@ Value* PPUTranslator::RotateLeft(Value* arg, Value* n)
|
|||||||
void PPUTranslator::CallFunction(u64 target, Value* indirect)
|
void PPUTranslator::CallFunction(u64 target, Value* indirect)
|
||||||
{
|
{
|
||||||
const auto type = FunctionType::get(GetType<void>(), {m_thread_type->getPointerTo()}, false);
|
const auto type = FunctionType::get(GetType<void>(), {m_thread_type->getPointerTo()}, false);
|
||||||
|
const auto block = m_ir->GetInsertBlock();
|
||||||
|
|
||||||
if (!indirect)
|
if (!indirect)
|
||||||
{
|
{
|
||||||
@ -162,12 +169,21 @@ void PPUTranslator::CallFunction(u64 target, Value* indirect)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const auto addr = indirect ? indirect : (Value*)m_ir->getInt64(target);
|
// Try to optimize
|
||||||
const auto pos = m_ir->CreateLShr(addr, 2, "", true);
|
if (auto inst = dyn_cast_or_null<Instruction>(indirect))
|
||||||
|
{
|
||||||
|
if (auto next = inst->getNextNode())
|
||||||
|
{
|
||||||
|
m_ir->SetInsertPoint(next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto pos = m_ir->CreateLShr(indirect, 2, "", true);
|
||||||
const auto ptr = m_ir->CreateGEP(m_ir->CreateLoad(m_call), {m_ir->getInt64(0), pos});
|
const auto ptr = m_ir->CreateGEP(m_ir->CreateLoad(m_call), {m_ir->getInt64(0), pos});
|
||||||
indirect = m_ir->CreateIntToPtr(m_ir->CreateLoad(ptr), type->getPointerTo());
|
indirect = m_ir->CreateIntToPtr(m_ir->CreateLoad(ptr), type->getPointerTo());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_ir->SetInsertPoint(block);
|
||||||
m_ir->CreateCall(indirect, {m_thread})->setTailCallKind(llvm::CallInst::TCK_Tail);
|
m_ir->CreateCall(indirect, {m_thread})->setTailCallKind(llvm::CallInst::TCK_Tail);
|
||||||
m_ir->CreateRetVoid();
|
m_ir->CreateRetVoid();
|
||||||
}
|
}
|
||||||
@ -176,12 +192,14 @@ Value* PPUTranslator::RegInit(Value*& local)
|
|||||||
{
|
{
|
||||||
const auto index = ::narrow<uint>(&local - m_locals);
|
const auto index = ::narrow<uint>(&local - m_locals);
|
||||||
|
|
||||||
if (!m_globals[index])
|
if (auto old = cast_or_null<Instruction>(m_globals[index]))
|
||||||
{
|
{
|
||||||
// Initialize global, will be written in FlushRegisters
|
old->eraseFromParent();
|
||||||
m_globals[index] = m_ir->CreateStructGEP(nullptr, m_thread, index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// (Re)Initialize global, will be written in FlushRegisters
|
||||||
|
m_globals[index] = m_ir->CreateStructGEP(nullptr, m_thread, index);
|
||||||
|
|
||||||
return m_globals[index];
|
return m_globals[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,19 +228,30 @@ void PPUTranslator::RegStore(llvm::Value* value, llvm::Value*& local)
|
|||||||
|
|
||||||
void PPUTranslator::FlushRegisters()
|
void PPUTranslator::FlushRegisters()
|
||||||
{
|
{
|
||||||
|
const auto block = m_ir->GetInsertBlock();
|
||||||
|
|
||||||
for (auto& local : m_locals)
|
for (auto& local : m_locals)
|
||||||
{
|
{
|
||||||
const uint index = static_cast<uint>(&local - m_locals);
|
const uint index = static_cast<uint>(&local - m_locals);
|
||||||
|
|
||||||
|
// Store value if necessary
|
||||||
if (local && m_globals[index])
|
if (local && m_globals[index])
|
||||||
{
|
{
|
||||||
// Store value if necessary
|
if (auto next = cast<Instruction>(m_globals[index])->getNextNode())
|
||||||
m_ir->CreateStore(local, m_globals[index]);
|
{
|
||||||
|
m_ir->SetInsertPoint(next);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_ir->SetInsertPoint(block);
|
||||||
|
}
|
||||||
|
|
||||||
// Don't need to store again
|
m_ir->CreateStore(local, m_globals[index]);
|
||||||
m_globals[index] = nullptr;
|
m_globals[index] = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_ir->SetInsertPoint(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value* PPUTranslator::Solid(Value* value)
|
Value* PPUTranslator::Solid(Value* value)
|
||||||
@ -1569,8 +1598,7 @@ void PPUTranslator::BC(ppu_opcode_t op)
|
|||||||
|
|
||||||
if (op.lk)
|
if (op.lk)
|
||||||
{
|
{
|
||||||
RegInit(m_lr);
|
m_ir->CreateStore(m_ir->getInt64(m_current_addr + 4), m_ir->CreateStructGEP(nullptr, m_thread, &m_lr - m_locals));
|
||||||
m_ir->CreateStore(m_ir->getInt64(m_current_addr + 4), m_g_lr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CallFunction(target);
|
CallFunction(target);
|
||||||
@ -1629,16 +1657,13 @@ void PPUTranslator::MCRF(ppu_opcode_t op)
|
|||||||
|
|
||||||
void PPUTranslator::BCLR(ppu_opcode_t op)
|
void PPUTranslator::BCLR(ppu_opcode_t op)
|
||||||
{
|
{
|
||||||
RegInit(m_lr);
|
|
||||||
|
|
||||||
const auto target = RegLoad(m_lr);
|
const auto target = RegLoad(m_lr);
|
||||||
|
|
||||||
UseCondition(CheckBranchProbability(op.bo), CheckBranchCondition(op.bo, op.bi));
|
UseCondition(CheckBranchProbability(op.bo), CheckBranchCondition(op.bo, op.bi));
|
||||||
|
|
||||||
if (op.lk)
|
if (op.lk)
|
||||||
{
|
{
|
||||||
RegInit(m_lr);
|
m_ir->CreateStore(m_ir->getInt64(m_current_addr + 4), m_ir->CreateStructGEP(nullptr, m_thread, &m_lr - m_locals));
|
||||||
m_ir->CreateStore(m_ir->getInt64(m_current_addr + 4), m_g_lr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CallFunction(0, target);
|
CallFunction(0, target);
|
||||||
@ -1701,8 +1726,7 @@ void PPUTranslator::BCCTR(ppu_opcode_t op)
|
|||||||
|
|
||||||
if (op.lk)
|
if (op.lk)
|
||||||
{
|
{
|
||||||
RegInit(m_lr);
|
m_ir->CreateStore(m_ir->getInt64(m_current_addr + 4), m_ir->CreateStructGEP(nullptr, m_thread, &m_lr - m_locals));
|
||||||
m_ir->CreateStore(m_ir->getInt64(m_current_addr + 4), m_g_lr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CallFunction(0, target);
|
CallFunction(0, target);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user