1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 02:32:36 +01:00

LLVM: Implement Recursive Intrinsics

This commit is contained in:
Elad 2024-11-08 11:59:15 +02:00 committed by Elad Ashkenazi
parent 0111fd0d0e
commit ae8f027c8d

View File

@ -371,23 +371,69 @@ void cpu_translator::replace_intrinsics(llvm::Function& f)
{
for (auto& bb : f)
{
for (auto bit = bb.begin(); bit != bb.end();)
std::set<std::string_view> names;
using InstListType = llvm::BasicBlock::InstListType;
std::function<InstListType::iterator(InstListType::iterator)> fix_funcs;
fix_funcs = [&](InstListType::iterator inst_bit)
{
if (auto ci = llvm::dyn_cast<llvm::CallInst>(&*bit))
auto ci = llvm::dyn_cast<llvm::CallInst>(&*inst_bit);
if (!ci)
{
if (auto cf = ci->getCalledFunction())
{
if (auto it = m_intrinsics.find(std::string_view(cf->getName().data(), cf->getName().size())); it != m_intrinsics.end())
{
m_ir->SetInsertPoint(ci);
ci->replaceAllUsesWith(it->second(ci));
bit = ci->eraseFromParent();
continue;
return std::next(inst_bit);
}
const auto cf = ci->getCalledFunction();
if (!cf)
{
return std::next(inst_bit);
}
std::string_view func_name{cf->getName().data(), cf->getName().size()};
const auto it = m_intrinsics.find(func_name);
if (it == m_intrinsics.end())
{
return std::next(inst_bit);
}
if (names.contains(func_name))
{
fmt::throw_exception("cpu_translator::replace_intrinsics(): Recursion detected at function '%s'!", func_name);
}
names.emplace(func_name);
m_ir->SetInsertPoint(ci);
auto result = it->second(ci);
auto end = m_ir->GetInsertPoint();
inst_bit->replaceAllUsesWith(result);
const auto next_it = inst_bit->eraseFromParent();
for (auto inner = ci->getNextNode(); inner && InstListType::iterator(inner) != end;)
{
if (auto it_ci = llvm::dyn_cast<llvm::CallInst>(&*inner))
{
fix_funcs(InstListType::iterator(inner));
}
else
{
inner = inner->getNextNode();
}
}
++bit;
ensure(names.erase(func_name));
return next_it;
};
for (auto bit = bb.begin(); bit != bb.end(); bit = fix_funcs(bit))
{
}
}
}