mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-29 22:20:48 +00:00
LLVM: Implement Recursive Intrinsics
This commit is contained in:
parent
fcf0b74c79
commit
b073d08a52
@ -4,6 +4,9 @@
|
|||||||
|
|
||||||
#include "util/v128.hpp"
|
#include "util/v128.hpp"
|
||||||
#include "util/simd.hpp"
|
#include "util/simd.hpp"
|
||||||
|
#include "util/logs.hpp"
|
||||||
|
|
||||||
|
LOG_CHANNEL(llvm_log, "LLVM");
|
||||||
|
|
||||||
llvm::LLVMContext g_llvm_ctx;
|
llvm::LLVMContext g_llvm_ctx;
|
||||||
|
|
||||||
@ -369,25 +372,85 @@ llvm::Constant* cpu_translator::make_const_vector<v128>(v128 v, llvm::Type* t, u
|
|||||||
|
|
||||||
void cpu_translator::replace_intrinsics(llvm::Function& f)
|
void cpu_translator::replace_intrinsics(llvm::Function& f)
|
||||||
{
|
{
|
||||||
for (auto& bb : f)
|
for (llvm::BasicBlock& bb : f)
|
||||||
{
|
{
|
||||||
for (auto bit = bb.begin(); bit != bb.end();)
|
std::set<std::string, std::less<>> 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.empty())
|
||||||
|
{
|
||||||
|
llvm_log.trace("cpu_translator::replace_intrinsics(): function '%s' names_size=%d, names[0]=%s", func_name, names.size(), *names.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (names.contains(func_name))
|
||||||
|
{
|
||||||
|
fmt::throw_exception("cpu_translator::replace_intrinsics(): Recursion detected at function '%s'!", func_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
names.emplace(std::string(func_name));
|
||||||
|
|
||||||
|
// Set insert point after call instruction
|
||||||
|
// In order to obtain a clear range of the inserted instructions
|
||||||
|
if (llvm::Instruction* next = ci->getNextNode())
|
||||||
|
{
|
||||||
|
m_ir->SetInsertPoint(next);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_ir->SetInsertPoint(std::addressof(bb));
|
||||||
|
}
|
||||||
|
|
||||||
|
ci->replaceAllUsesWith(it->second(ci));
|
||||||
|
|
||||||
|
InstListType::iterator end = m_ir->GetInsertPoint();
|
||||||
|
|
||||||
|
for (InstListType::iterator next_it = ci->eraseFromParent(), inner = next_it; inner != end;)
|
||||||
|
{
|
||||||
|
if (llvm::isa<llvm::CallInst>(&*inner))
|
||||||
{
|
{
|
||||||
if (auto it = m_intrinsics.find(std::string_view(cf->getName().data(), cf->getName().size())); it != m_intrinsics.end())
|
inner = fix_funcs(inner);
|
||||||
{
|
}
|
||||||
m_ir->SetInsertPoint(ci);
|
else
|
||||||
ci->replaceAllUsesWith(it->second(ci));
|
{
|
||||||
bit = ci->eraseFromParent();
|
inner++;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
++bit;
|
// TODO: Simplify in C++23 with 'names.erase(func_name);'
|
||||||
|
names.erase(ensure(names.find(func_name), FN(x != names.end())));
|
||||||
|
return end;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto bit = bb.begin(); bit != bb.end(); bit = fix_funcs(bit))
|
||||||
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6049,6 +6049,8 @@ public:
|
|||||||
final_result = eval(insert(final_result, i, r_fraction));
|
final_result = eval(insert(final_result, i, r_fraction));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//final_result = eval(select(final_result != (0), final_result, bitcast<u32[4]>(pshufb(splat<u8[16]>(0), bitcast<u8[16]>(final_result)))));
|
||||||
|
|
||||||
return bitcast<f32[4]>(bitcast<u32[4]>(final_result | bitcast<u32[4]>(fix_exponent) | a_sign));
|
return bitcast<f32[4]>(bitcast<u32[4]>(final_result | bitcast<u32[4]>(fix_exponent) | a_sign));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user