mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-26 23:00:48 +01:00
Removes LLVM from FEX
LLVM has too many problems with it to use it as a tiered level of JIT. We won't be able to use it
This commit is contained in:
1 parent
e7058c8575
commit
5efab55ea9
14 files changed
+7
-4401
No files matched your search
Vendored
-8
@@ -14,14 +14,6 @@ check_pie_supported()
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
find_package(LLVM CONFIG QUIET)
|
||||
if(LLVM_FOUND AND TARGET LLVM)
|
||||
message(STATUS "LLVM found!")
|
||||
include_directories(${LLVM_INCLUDE_DIRS})
|
||||
else()
|
||||
message("Couldn't find LLVM and this project requires it")
|
||||
endif()
|
||||
|
||||
include(CheckCXXCompilerFlag)
|
||||
include(CheckIncludeFileCXX)
|
||||
|
||||
|
||||
Vendored
-1
@@ -35,7 +35,6 @@ Multiple architecture support is desired for easier bringup and debugging, perfo
|
||||
* "Cycle Accurate" emulation
|
||||
### Dependencies
|
||||
* [SonicUtils](https://github.com/Sonicadvance1/SonicUtils)
|
||||
* LLVM
|
||||
* clang-tidy if you want to ensure the code stays tidy
|
||||
* cmake
|
||||
* A C++17 compliant compiler (There are assumptions made about using Clang and LTO)
|
||||
+1
-3
@@ -127,8 +127,6 @@ set (SRCS
|
||||
Interface/Core/X86DebugInfo.cpp
|
||||
Interface/Core/X86HelperGen.cpp
|
||||
Interface/Core/Interpreter/InterpreterCore.cpp
|
||||
Interface/Core/LLVMJIT/LLVMCore.cpp
|
||||
Interface/Core/LLVMJIT/LLVMMemoryManager.cpp
|
||||
Interface/Core/X86Tables/BaseTables.cpp
|
||||
Interface/Core/X86Tables/DDDTables.cpp
|
||||
Interface/Core/X86Tables/EVEXTables.cpp
|
||||
@@ -263,7 +261,7 @@ set(LINUX_LIBS
|
||||
function(AddLibrary Name Type)
|
||||
add_library(${Name} ${Type} ${SRCS})
|
||||
add_dependencies(${Name} IR_INC)
|
||||
target_link_libraries(${Name} LLVM pthread rt ${JIT_LIBS} ${LINUX_LIBS} dl)
|
||||
target_link_libraries(${Name} pthread rt ${JIT_LIBS} ${LINUX_LIBS} dl)
|
||||
set_target_properties(${Name} PROPERTIES OUTPUT_NAME FEXCore)
|
||||
|
||||
target_include_directories(${Name} PUBLIC "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
|
||||
@@ -58,11 +58,6 @@ namespace FEXCore::Context {
|
||||
|
||||
bool Is64BitMode {true};
|
||||
uint64_t EmulatedCPUCores{1};
|
||||
|
||||
// LLVM JIT options
|
||||
bool LLVM_MemoryValidation {false};
|
||||
bool LLVM_IRValidation {false};
|
||||
bool LLVM_PrinterPass {false};
|
||||
} Config;
|
||||
|
||||
FEXCore::Memory::MemMapper MemoryMapper;
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include "Interface/Core/OpcodeDispatcher.h"
|
||||
#include "Interface/Core/Interpreter/InterpreterCore.h"
|
||||
#include "Interface/Core/JIT/JITCore.h"
|
||||
#include "Interface/Core/LLVMJIT/LLVMCore.h"
|
||||
#include "Interface/IR/Passes/RegisterAllocationPass.h"
|
||||
#include "Interface/IR/Passes.h"
|
||||
|
||||
@@ -460,7 +459,6 @@ namespace FEXCore::Context {
|
||||
Thread->IntBackend.reset(FEXCore::CPU::CreateInterpreterCore(this));
|
||||
Thread->CPUBackend.reset(FEXCore::CPU::CreateJITCore(this, Thread));
|
||||
break;
|
||||
case FEXCore::Config::CONFIG_LLVMJIT: Thread->CPUBackend.reset(FEXCore::CPU::CreateLLVMCore(Thread)); break;
|
||||
case FEXCore::Config::CONFIG_CUSTOM: Thread->CPUBackend.reset(CustomCPUFactory(this, &Thread->State)); break;
|
||||
default: LogMan::Msg::A("Unknown core configuration");
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,11 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
namespace FEXCore::Core {
|
||||
struct InternalThreadState;
|
||||
}
|
||||
|
||||
namespace FEXCore::CPU {
|
||||
class CPUBackend;
|
||||
|
||||
FEXCore::CPU::CPUBackend *CreateLLVMCore(FEXCore::Core::InternalThreadState *Thread);
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
#include "LogManager.h"
|
||||
#include "Common/MathUtils.h"
|
||||
#include "Interface/Core/LLVMJIT/LLVMMemoryManager.h"
|
||||
|
||||
#if defined (_M_ARM_64)
|
||||
#include "aarch64/cpu-aarch64.h"
|
||||
#endif
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
namespace FEXCore::CPU {
|
||||
|
||||
LLVMMemoryManager::LLVMMemoryManager() {
|
||||
CodeMemory = reinterpret_cast<uintptr_t>(mmap(nullptr, CODE_SIZE, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
|
||||
LogMan::Throw::A(CodeMemory != -1ULL, "Failed to allocate code memory");
|
||||
}
|
||||
|
||||
LLVMMemoryManager::~LLVMMemoryManager() {
|
||||
munmap(reinterpret_cast<void*>(CodeMemory), CODE_SIZE);
|
||||
CodeMemory = 0;
|
||||
}
|
||||
|
||||
llvm::JITSymbol LLVMMemoryManager::findSymbol(const std::string &Name) {
|
||||
return llvm::JITSymbol(getSymbolAddress(Name), llvm::JITSymbolFlags::Exported);
|
||||
}
|
||||
|
||||
uint8_t *LLVMMemoryManager::allocateCodeSection(uintptr_t Size, unsigned Alignment,
|
||||
[[maybe_unused]] unsigned SectionID,
|
||||
[[maybe_unused]] llvm::StringRef SectionName) {
|
||||
size_t Base = AlignUp(AllocateOffset, Alignment);
|
||||
size_t NewEnd = Base + Size;
|
||||
|
||||
if (NewEnd >= CODE_SIZE) {
|
||||
LogMan::Msg::A("Tried allocating code and code cache is full!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AllocateOffset = NewEnd;
|
||||
LastCodeSize = Size;
|
||||
LastCodeBase = CodeMemory + Base;
|
||||
return reinterpret_cast<uint8_t*>(CodeMemory + Base);
|
||||
}
|
||||
|
||||
uint8_t *LLVMMemoryManager::allocateDataSection(uintptr_t Size, unsigned Alignment,
|
||||
[[maybe_unused]] unsigned SectionID,
|
||||
[[maybe_unused]] llvm::StringRef SectionName,
|
||||
[[maybe_unused]] bool IsReadOnly) {
|
||||
|
||||
// Put data section right after code section
|
||||
size_t Base = AlignUp(AllocateOffset, Alignment);
|
||||
size_t NewEnd = Base + Size;
|
||||
|
||||
if (NewEnd >= CODE_SIZE) {
|
||||
LogMan::Msg::A("Tried allocating code and code cache is full!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AllocateOffset = NewEnd;
|
||||
return reinterpret_cast<uint8_t*>(CodeMemory + Base);
|
||||
}
|
||||
|
||||
bool LLVMMemoryManager::finalizeMemory([[maybe_unused]] std::string *ErrMsg) {
|
||||
#if defined (_M_ARM_64)
|
||||
vixl::aarch64::CPU::EnsureIAndDCacheCoherency(reinterpret_cast<void*>(LastCodeBase), LastCodeSize);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
#pragma once
|
||||
#include <llvm/ExecutionEngine/RTDyldMemoryManager.h>
|
||||
|
||||
namespace FEXCore::CPU {
|
||||
|
||||
class LLVMMemoryManager final : public llvm::RTDyldMemoryManager {
|
||||
public:
|
||||
LLVMMemoryManager();
|
||||
~LLVMMemoryManager();
|
||||
// uint64_t getSymbolAddress(const std::string &Name) override;
|
||||
|
||||
llvm::JITSymbol findSymbol(const std::string &Name) override;
|
||||
|
||||
uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
|
||||
unsigned SectionID,
|
||||
llvm::StringRef SectionName) override;
|
||||
|
||||
uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
|
||||
unsigned SectionID,
|
||||
llvm::StringRef SectionName,
|
||||
bool IsReadOnly) override;
|
||||
|
||||
bool finalizeMemory(std::string *ErrMsg) override;
|
||||
|
||||
size_t GetLastCodeAllocation() { return LastCodeSize; }
|
||||
|
||||
private:
|
||||
constexpr static size_t CODE_SIZE = 128 * 1024 * 1024;
|
||||
uintptr_t CodeMemory {};
|
||||
size_t AllocateOffset {};
|
||||
|
||||
uintptr_t LastCodeBase {};
|
||||
size_t LastCodeSize {};
|
||||
};
|
||||
}
|
||||
Vendored
+1
-9
@@ -11,19 +11,11 @@ This is used to easily inspect what is going on with the code generation and mak
|
||||
This is meant to be our first JIT of call and will serve multiple purposes. It'll be the JIT that is used for our runtime compilation of code.
|
||||
This means it needs to be fast during compilation and have decent runtime performance.
|
||||
Good chance that we will need to implement multiple of these depending on host architecture with some code reuse between them.
|
||||
This JIT will also be what we use for gathering sampling data for passing off to our LLVM JIT for tiered recompilation and offline compilation later.
|
||||
This JIT will also be what we use for gathering sampling data for passing off to another JIT for tiered recompilation and offline compilation later.
|
||||
Should use xbyak for our x86-64 host and Vixl for our AArch64 host. For other targets in the future we will see what is available
|
||||
|
||||
## LLVM JIT
|
||||
This is the last JIT that should theoretically generate the most optimal code for us.
|
||||
This *should* be used for a tiered recompiler system using sampling data from the IR JIT.
|
||||
Currently it just supports being a regular JIT core. There are still some hard problems that need to be solved with this JIT since LLVM isn't quite ideal for generating code for a JIT.
|
||||
|
||||
# Future ideas
|
||||
---
|
||||
* Support a custom ABI on the LLVM JIT to generate more optimal code that is shared between the IR JIT and LLVM JIT
|
||||
* This can let us do fun things like reserve host registers for guest register state. Trivial in the IR JIT, not so much for LLVM.
|
||||
* Needs a local build of LLVM that we statically link in.
|
||||
* Create an inline ASM or JIT'd dispatcher loop. Will allow our JITs to be more optimal by reserving more registers for guest state.
|
||||
* WebAssmembly or other browser language?
|
||||
* Might allow decent runtime performance of things emulated in a browser. Could be interesting.
|
||||
@@ -21,7 +21,6 @@ namespace FEXCore::Config {
|
||||
enum ConfigCore {
|
||||
CONFIG_INTERPRETER,
|
||||
CONFIG_IRJIT,
|
||||
CONFIG_LLVMJIT,
|
||||
CONFIG_CUSTOM,
|
||||
};
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ if(NOT CMAKE_ASM_NASM_COMPILER_LOADED)
|
||||
endif()
|
||||
|
||||
|
||||
set(LIBS FEXCore Common CommonCore SonicUtils pthread LLVM)
|
||||
set(LIBS FEXCore Common CommonCore SonicUtils pthread)
|
||||
set(NAME ELFLoader)
|
||||
set(SRCS ELFLoader.cpp)
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
add_subdirectory(Debugger/)
|
||||
if(LLVM_FOUND AND TARGET LLVM)
|
||||
add_subdirectory(Debugger/)
|
||||
endif()
|
||||
|
||||
set(NAME Opt)
|
||||
set(SRCS Opt.cpp)
|
||||
@@ -7,4 +9,4 @@ add_executable(${NAME} ${SRCS})
|
||||
target_include_directories(${NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Source/)
|
||||
target_include_directories(${NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/External/SonicUtils/)
|
||||
|
||||
target_link_libraries(${NAME} FEXCore Common CommonCore SonicUtils pthread LLVM)
|
||||
target_link_libraries(${NAME} FEXCore Common CommonCore SonicUtils pthread)
|
||||
@@ -61,8 +61,6 @@ namespace CPUState {
|
||||
FEX::DebuggerState::SetCoreType(FEXCore::Config::ConfigCore::CONFIG_INTERPRETER);
|
||||
if (ImGui::MenuItem("IR JIT", nullptr, FEX::DebuggerState::GetCoreType() == FEXCore::Config::ConfigCore::CONFIG_IRJIT, !FEX::DebuggerState::ActiveCore()))
|
||||
FEX::DebuggerState::SetCoreType(FEXCore::Config::ConfigCore::CONFIG_IRJIT);
|
||||
if (ImGui::MenuItem("LLVM", nullptr, FEX::DebuggerState::GetCoreType() == FEXCore::Config::ConfigCore::CONFIG_LLVMJIT, !FEX::DebuggerState::ActiveCore()))
|
||||
FEX::DebuggerState::SetCoreType(FEXCore::Config::ConfigCore::CONFIG_LLVMJIT);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user