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:
Nekotekina 2019-10-15 17:43:33 +03:00
parent c69fe0f664
commit eafbc77c0d
3 changed files with 24 additions and 8 deletions

View file

@ -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))

View file

@ -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

View file

@ -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);