mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-05 22:41:25 +12:00
SPU LLVM: Always use linux-gnu target triple (affects Windows)
Unify internal code generation to make better use of GHC calling convention. Ideally, it would just work on Windows as well, but some random bug appeared. This bug was causing freezes on SPU LLVM compilation. This commit desperately attempts to workaround it.
This commit is contained in:
parent
c69fe0f664
commit
eafbc77c0d
3 changed files with 24 additions and 8 deletions
|
@ -743,6 +743,8 @@ jit_compiler::jit_compiler(const std::unordered_map<std::string, u64>& _link, co
|
||||||
{
|
{
|
||||||
std::string result;
|
std::string result;
|
||||||
|
|
||||||
|
auto null_mod = std::make_unique<llvm::Module> ("null_", m_context);
|
||||||
|
|
||||||
if (m_link.empty())
|
if (m_link.empty())
|
||||||
{
|
{
|
||||||
std::unique_ptr<llvm::RTDyldMemoryManager> mem;
|
std::unique_ptr<llvm::RTDyldMemoryManager> mem;
|
||||||
|
@ -754,10 +756,11 @@ jit_compiler::jit_compiler(const std::unordered_map<std::string, u64>& _link, co
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mem = std::make_unique<MemoryManager2>();
|
mem = std::make_unique<MemoryManager2>();
|
||||||
|
null_mod->setTargetTriple(llvm::Triple::normalize("x86_64-unknown-linux-gnu"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auxiliary JIT (does not use custom memory manager, only writes the objects)
|
// Auxiliary JIT (does not use custom memory manager, only writes the objects)
|
||||||
m_engine.reset(llvm::EngineBuilder(std::make_unique<llvm::Module>("null_", m_context))
|
m_engine.reset(llvm::EngineBuilder(std::move(null_mod))
|
||||||
.setErrorStr(&result)
|
.setErrorStr(&result)
|
||||||
.setEngineKind(llvm::EngineKind::JIT)
|
.setEngineKind(llvm::EngineKind::JIT)
|
||||||
.setMCJITMemoryManager(std::move(mem))
|
.setMCJITMemoryManager(std::move(mem))
|
||||||
|
@ -772,7 +775,7 @@ jit_compiler::jit_compiler(const std::unordered_map<std::string, u64>& _link, co
|
||||||
auto mem = std::make_unique<MemoryManager>(m_link);
|
auto mem = std::make_unique<MemoryManager>(m_link);
|
||||||
m_jit_el = std::make_unique<EventListener>(*mem);
|
m_jit_el = std::make_unique<EventListener>(*mem);
|
||||||
|
|
||||||
m_engine.reset(llvm::EngineBuilder(std::make_unique<llvm::Module>("null", m_context))
|
m_engine.reset(llvm::EngineBuilder(std::move(null_mod))
|
||||||
.setErrorStr(&result)
|
.setErrorStr(&result)
|
||||||
.setEngineKind(llvm::EngineKind::JIT)
|
.setEngineKind(llvm::EngineKind::JIT)
|
||||||
.setMCJITMemoryManager(std::move(mem))
|
.setMCJITMemoryManager(std::move(mem))
|
||||||
|
|
|
@ -2455,8 +2455,16 @@ public:
|
||||||
static_assert(sizeof...(FArgs) == sizeof...(Args), "spu_llvm_recompiler::call(): unexpected arg number");
|
static_assert(sizeof...(FArgs) == sizeof...(Args), "spu_llvm_recompiler::call(): unexpected arg number");
|
||||||
const auto type = llvm::FunctionType::get(get_type<RT>(), {args->getType()...}, false);
|
const auto type = llvm::FunctionType::get(get_type<RT>(), {args->getType()...}, false);
|
||||||
const auto func = llvm::cast<llvm::Function>(m_module->getOrInsertFunction({lame.data(), lame.size()}, type).getCallee());
|
const auto func = llvm::cast<llvm::Function>(m_module->getOrInsertFunction({lame.data(), lame.size()}, type).getCallee());
|
||||||
|
#ifdef _WIN32
|
||||||
|
func->setCallingConv(llvm::CallingConv::Win64);
|
||||||
|
#endif
|
||||||
m_engine->addGlobalMapping({lame.data(), lame.size()}, reinterpret_cast<std::uintptr_t>(_func));
|
m_engine->addGlobalMapping({lame.data(), lame.size()}, reinterpret_cast<std::uintptr_t>(_func));
|
||||||
return m_ir->CreateCall(func, {args...});
|
|
||||||
|
const auto inst = m_ir->CreateCall(func, {args...});
|
||||||
|
#ifdef _WIN32
|
||||||
|
inst->setCallingConv(llvm::CallingConv::Win64);
|
||||||
|
#endif
|
||||||
|
return inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bitcast with immediate constant folding
|
// Bitcast with immediate constant folding
|
||||||
|
|
|
@ -3410,7 +3410,7 @@ class spu_llvm_recompiler : public spu_recompiler_base, public cpu_translator
|
||||||
// 1. Thread context
|
// 1. Thread context
|
||||||
// 2. Local storage pointer
|
// 2. Local storage pointer
|
||||||
// 3.
|
// 3.
|
||||||
#ifdef _WIN32
|
#if 0
|
||||||
const auto chunk_type = get_ftype<u8*, u8*, u8*, u32>();
|
const auto chunk_type = get_ftype<u8*, u8*, u8*, u32>();
|
||||||
#else
|
#else
|
||||||
const auto chunk_type = get_ftype<void, u8*, u8*, u32>();
|
const auto chunk_type = get_ftype<void, u8*, u8*, u32>();
|
||||||
|
@ -3424,7 +3424,7 @@ class spu_llvm_recompiler : public spu_recompiler_base, public cpu_translator
|
||||||
result->setLinkage(llvm::GlobalValue::InternalLinkage);
|
result->setLinkage(llvm::GlobalValue::InternalLinkage);
|
||||||
result->addAttribute(1, llvm::Attribute::NoAlias);
|
result->addAttribute(1, llvm::Attribute::NoAlias);
|
||||||
result->addAttribute(2, llvm::Attribute::NoAlias);
|
result->addAttribute(2, llvm::Attribute::NoAlias);
|
||||||
#ifndef _WIN32
|
#if 1
|
||||||
result->setCallingConv(llvm::CallingConv::GHC);
|
result->setCallingConv(llvm::CallingConv::GHC);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -3448,7 +3448,7 @@ class spu_llvm_recompiler : public spu_recompiler_base, public cpu_translator
|
||||||
fn->setLinkage(llvm::GlobalValue::InternalLinkage);
|
fn->setLinkage(llvm::GlobalValue::InternalLinkage);
|
||||||
fn->addAttribute(1, llvm::Attribute::NoAlias);
|
fn->addAttribute(1, llvm::Attribute::NoAlias);
|
||||||
fn->addAttribute(2, llvm::Attribute::NoAlias);
|
fn->addAttribute(2, llvm::Attribute::NoAlias);
|
||||||
#ifndef _WIN32
|
#if 1
|
||||||
fn->setCallingConv(llvm::CallingConv::GHC);
|
fn->setCallingConv(llvm::CallingConv::GHC);
|
||||||
#endif
|
#endif
|
||||||
empl.first->second.fn = fn;
|
empl.first->second.fn = fn;
|
||||||
|
@ -4298,7 +4298,7 @@ public:
|
||||||
|
|
||||||
// Create LLVM module
|
// Create LLVM module
|
||||||
std::unique_ptr<Module> module = std::make_unique<Module>(m_hash + ".obj", m_context);
|
std::unique_ptr<Module> module = std::make_unique<Module>(m_hash + ".obj", m_context);
|
||||||
module->setTargetTriple(Triple::normalize(sys::getProcessTriple()));
|
module->setTargetTriple(Triple::normalize("x86_64-unknown-linux-gnu"));
|
||||||
module->setDataLayout(m_jit.get_engine().getTargetMachine()->createDataLayout());
|
module->setDataLayout(m_jit.get_engine().getTargetMachine()->createDataLayout());
|
||||||
m_module = module.get();
|
m_module = module.get();
|
||||||
|
|
||||||
|
@ -4451,6 +4451,7 @@ public:
|
||||||
|
|
||||||
const auto dispatcher = llvm::cast<llvm::Function>(m_module->getOrInsertFunction("spu_dispatcher", main_func->getType()).getCallee());
|
const auto dispatcher = llvm::cast<llvm::Function>(m_module->getOrInsertFunction("spu_dispatcher", main_func->getType()).getCallee());
|
||||||
m_engine->addGlobalMapping("spu_dispatcher", reinterpret_cast<u64>(spu_runtime::tr_all));
|
m_engine->addGlobalMapping("spu_dispatcher", reinterpret_cast<u64>(spu_runtime::tr_all));
|
||||||
|
dispatcher->setCallingConv(main_func->getCallingConv());
|
||||||
|
|
||||||
// Proceed to the next code
|
// Proceed to the next code
|
||||||
if (entry_chunk->chunk->getReturnType() != get_type<void>())
|
if (entry_chunk->chunk->getReturnType() != get_type<void>())
|
||||||
|
@ -5887,7 +5888,11 @@ public:
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
m_ir->CreateCall(get_intrinsic<u8*, u8*, u32>(llvm::Intrinsic::memcpy), {dst, src, zext<u32>(size).eval(m_ir), m_ir->getTrue()});
|
auto spu_memcpy = [](u8* dst, const u8* src, u32 size)
|
||||||
|
{
|
||||||
|
std::memcpy(dst, src, size);
|
||||||
|
};
|
||||||
|
call("spu_memcpy", +spu_memcpy, dst, src, zext<u32>(size).eval(m_ir));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_ir->CreateBr(next);
|
m_ir->CreateBr(next);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue