mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-21 18:22:33 +01:00
LLVM: Implement Recursive Intrinsics
This commit is contained in:
parent
0111fd0d0e
commit
ae8f027c8d
@ -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())
|
||||
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))
|
||||
{
|
||||
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;
|
||||
}
|
||||
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))
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user