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:
Ryan Houdek committed 2020-08-19 18:02:28 -07:00
1 parent e7058c8575
commit 5efab55ea9
14 files changed
+7 -4401

No files matched your search

-8
View File
@@ -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)
-1
View File
@@ -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
View File
@@ -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}")
-5
View File
@@ -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;
-2
View File
@@ -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 {};
};
}
+1 -9
View File
@@ -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.
-1
View File
@@ -21,7 +21,6 @@ namespace FEXCore::Config {
enum ConfigCore {
CONFIG_INTERPRETER,
CONFIG_IRJIT,
CONFIG_LLVMJIT,
CONFIG_CUSTOM,
};
+1 -1
View File
@@ -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)
+4 -2
View File
@@ -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)
-2
View File
@@ -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();
}