Skip to content

Commit

Permalink
Merge pull request #4774 from liushuyu/orcjit-v2
Browse files Browse the repository at this point in the history
runtime/jit-rt: revive and migrates the whole thing to OrcJIT v2
  • Loading branch information
kinke authored Jan 12, 2025
2 parents 4e6bbba + 48a48ec commit 268ad13
Show file tree
Hide file tree
Showing 28 changed files with 658 additions and 650 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ commonSteps: &commonSteps
fi
# Install lit
python3 --version
python3 -m pip install --user lit
python3 -m pip install --user lit psutil
python3 -c "import lit.main; lit.main.main();" --version . | head -n 1
# Download & extract host LDC if HOST_LDC_VERSION is set
if [[ -v HOST_LDC_VERSION ]]; then
Expand Down
2 changes: 1 addition & 1 deletion .github/actions/1-setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ runs:
if [[ '${{ runner.os }}-${{ inputs.arch }}' == 'macOS-arm64' ]]; then
brew install lit
else
python3 -m pip install --user lit
python3 -m pip install --user lit psutil
fi
python3 -c "import lit.main; lit.main.main();" --version . | head -n 1
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/supported_llvm_versions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ jobs:
if [[ '${{ matrix.os }}' == 'macos-14' ]]; then
brew install lit
else
python3 -m pip install --user lit
python3 -m pip install --user lit psutil
fi
python3 -c "import lit.main; lit.main.main();" --version . | head -n 1
- name: 'Linux: Install gdb, lld, llvm-dev and libclang-common-dev'
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# LDC master

#### Big news
- Revived dynamic-compile (JIT) functionality (formerly unsupported since LLVM 12), supporting LLVM 18+ now. (#4774)
- ldc2.conf: `%%ldcversion%%` placeholder added, allowing to refer to version-specific directories.

#### Platform support
Expand Down
27 changes: 20 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -452,20 +452,33 @@ include(HandleLTOPGOBuildOptions)
#
# Enable Dynamic compilation if supported for this platform and LLVM version.
#
set(LDC_DYNAMIC_COMPILE "AUTO" CACHE STRING "Support dynamic compilation (ON|OFF). Enabled by default; not supported for LLVM >= 12.")
set(LDC_DYNAMIC_COMPILE "AUTO" CACHE STRING "Support dynamic compilation (ON|OFF). Enabled by default; not supported for LLVM < 18.")
option(LDC_DYNAMIC_COMPILE_USE_CUSTOM_PASSES "Use custom LDC passes in jit" ON)
if(LDC_DYNAMIC_COMPILE STREQUAL "AUTO")
if(LDC_LLVM_VER LESS 1200)
set(LDC_DYNAMIC_COMPILE ON)
else()
# TODO: port from ORCv1 API (dropped with LLVM 12) to ORCv2 (added with LLVM 7)
if(LDC_LLVM_VER LESS 1800)
set(LDC_DYNAMIC_COMPILE OFF)
else()
set(LDC_DYNAMIC_COMPILE ON)
endif()
endif()
# https://llvm.org/docs/JITLink.html for the list of supported platforms
if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|x64|amd64|aarch64|arm64|riscv64|loongarch64")
set(_LDC_DYNAMIC_COMPILE_USE_LLVM_JITLINK_DEFAULT ON)
else()
set(_LDC_DYNAMIC_COMPILE_USE_LLVM_JITLINK_DEFAULT OFF)
endif()
# Disable LLVM JITLink on Windows for now, currently does not work very well on Windows
if(WIN32)
set(_LDC_DYNAMIC_COMPILE_USE_LLVM_JITLINK_DEFAULT OFF)
endif()
option(LDC_DYNAMIC_COMPILE_USE_LLVM_JITLINK "Use the experimental but faster LLVM JITLink dynamic code linker" "${_LDC_DYNAMIC_COMPILE_USE_LLVM_JITLINK_DEFAULT}")
message(STATUS "-- Building LDC with dynamic compilation support (LDC_DYNAMIC_COMPILE): ${LDC_DYNAMIC_COMPILE}")
if(LDC_DYNAMIC_COMPILE)
add_definitions(-DLDC_DYNAMIC_COMPILE)
add_definitions(-DLDC_DYNAMIC_COMPILE_API_VERSION=3)
add_definitions(-DLDC_DYNAMIC_COMPILE_API_VERSION=4)
endif()
if (LDC_DYNAMIC_COMPILE_USE_LLVM_JITLINK)
add_compile_definitions(-DLDC_JITRT_USE_JITLINK)
endif()

#
Expand Down Expand Up @@ -545,7 +558,7 @@ else()
# Define a 'HOST_D' CMake linker language for the static LDCShared
# library, using the host ldmd2 compiler ≥ v1.5 as archiver, which
# supports LTO objects and cross-archiving.
set(CMAKE_HOST_D_CREATE_STATIC_LIBRARY "${D_COMPILER} -lib ${D_COMPILER_FLAGS} ${DFLAGS_BASE} -of=<TARGET> <OBJECTS>")
set(CMAKE_HOST_D_CREATE_STATIC_LIBRARY "\"${D_COMPILER}\" -lib ${D_COMPILER_FLAGS} ${DFLAGS_BASE} -of=<TARGET> <OBJECTS>")
set(LDC_LIB_LANGUAGE HOST_D)
endif()
endif()
Expand Down
9 changes: 6 additions & 3 deletions cmake/Modules/BuildDExecutable.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,10 @@ function(build_d_executable target_name output_exe d_src_files compiler_args lin
endif()
add_custom_command(
OUTPUT ${object_file}
COMMAND ${D_COMPILER} -c ${dflags} -of${object_file} ${d_src_files}
COMMAND "${D_COMPILER}" -c ${dflags} -of${object_file} ${d_src_files}
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
DEPENDS ${d_src_files} ${extra_compile_deps}
VERBATIM
)
set(object_files ${object_file})
else()
Expand All @@ -62,9 +63,10 @@ function(build_d_executable target_name output_exe d_src_files compiler_args lin
set(object_file ${PROJECT_BINARY_DIR}/obj/${target_name}/${object_file}${CMAKE_CXX_OUTPUT_EXTENSION})
add_custom_command(
OUTPUT ${object_file}
COMMAND ${D_COMPILER} -c ${dflags} -of${object_file} ${f}
COMMAND "${D_COMPILER}" -c ${dflags} -of${object_file} ${f}
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
DEPENDS ${f} ${extra_compile_deps}
VERBATIM
)
list(APPEND object_files ${object_file})
endforeach()
Expand Down Expand Up @@ -108,9 +110,10 @@ function(build_d_executable target_name output_exe d_src_files compiler_args lin

add_custom_command(
OUTPUT ${output_exe}
COMMAND ${D_COMPILER} ${dflags} -of${output_exe} ${objects_args} ${dep_libs} ${translated_linker_args}
COMMAND "${D_COMPILER}" ${dflags} -of${output_exe} ${objects_args} ${dep_libs} ${translated_linker_args}
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
DEPENDS ${target_name}_d_objects ${object_files} ${link_deps}
VERBATIM
)
add_custom_target(${target_name} ALL DEPENDS ${output_exe})
endif()
Expand Down
2 changes: 1 addition & 1 deletion driver/toobj.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ void writeModule(llvm::Module *m, const char *filename) {
// run LLVM optimization passes
{
::TimeTraceScope timeScope("Optimize", filename);
ldc_optimize_module(m);
ldc_optimize_module(m, gTargetMachine);
}

if (global.params.dllimport != DLLImport::none) {
Expand Down
86 changes: 43 additions & 43 deletions gen/dynamiccompile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//

#include "gen/dynamiccompile.h"
#include <llvm/IR/DerivedTypes.h>

#if defined(LDC_DYNAMIC_COMPILE)

Expand Down Expand Up @@ -91,14 +92,15 @@ using GlobalValsMap =
void getPredefinedSymbols(IRState *irs, GlobalValsMap &symList) {
assert(nullptr != irs);
const llvm::Triple *triple = global.params.targetTriple;
if (triple->isWindowsMSVCEnvironment() ||
triple->isWindowsGNUEnvironment()) {
// Actual signatures doesn't matter here, we only want it to show in
if (triple->isWindowsMSVCEnvironment() || triple->isWindowsGNUEnvironment()) {
// Actual signatures doesn't matter here, we only want them to show in
// symbols list
symList.insert(std::make_pair(
getPredefinedSymbol(irs->module, "__chkstk",
llvm::Type::getInt32Ty(irs->context())),
GlobalValVisibility::Declaration));
for (auto &syms : {"\1__chkstk", "memset", "memcpy"}) {
symList.insert(std::make_pair(
getPredefinedSymbol(irs->module, syms,
llvm::Type::getInt32Ty(irs->context())),
GlobalValVisibility::Declaration));
}
if (!opts::dynamicCompileTlsWorkaround) {
symList.insert(std::make_pair(
getPredefinedSymbol(irs->module, "_tls_index",
Expand Down Expand Up @@ -364,10 +366,8 @@ llvm::Constant *getArrayPtr(llvm::Type *type, llvm::Constant *array) {
idxs, true);
}

llvm::Constant *getI8Ptr(llvm::GlobalValue *val) {
assert(nullptr != val);
return llvm::ConstantExpr::getBitCast(
val, llvm::IntegerType::getInt8PtrTy(val->getContext()));
static llvm::PointerType *getI8PtrType(llvm::LLVMContext &C) {
return LLPointerType::getUnqual(LLType::getInt8Ty(C));
}

std::pair<llvm::Constant *, llvm::Constant *>
Expand Down Expand Up @@ -410,7 +410,7 @@ llvm::Constant *createStringInitializer(llvm::Module &mod,
true, llvm::GlobalValue::PrivateLinkage,
llvm::ConstantDataArray::getString(mod.getContext(), str, true), ".str");
return llvm::ConstantExpr::getBitCast(
nameVar, llvm::Type::getInt8PtrTy(mod.getContext()));
nameVar, getI8PtrType(mod.getContext()));
}

// void createStaticString(llvm::Module& mod,
Expand All @@ -436,16 +436,15 @@ llvm::Constant *createStringInitializer(llvm::Module &mod,
// struct RtCompileVarList
// {
// i8* name;
// i8* ptr;
// i8* init;
// }

llvm::StructType *getVarListElemType(llvm::LLVMContext &context) {
llvm::Type *elements[] = {
llvm::IntegerType::getInt8PtrTy(context),
llvm::IntegerType::getInt8PtrTy(context),
getI8PtrType(context),
getI8PtrType(context),
};
return llvm::StructType::create(context, elements, /*"RtCompileVarList"*/ "",
true);
return llvm::StructType::create(context, elements, /*"RtCompileVarList"*/ "");
}

// struct RtCompileSymList
Expand All @@ -456,11 +455,10 @@ llvm::StructType *getVarListElemType(llvm::LLVMContext &context) {

llvm::StructType *getSymListElemType(llvm::LLVMContext &context) {
llvm::Type *elements[] = {
llvm::IntegerType::getInt8PtrTy(context),
llvm::IntegerType::getInt8PtrTy(context),
getI8PtrType(context),
getI8PtrType(context),
};
return llvm::StructType::create(context, elements, /*"RtCompileSymList"*/ "",
true);
return llvm::StructType::create(context, elements, /*"RtCompileSymList"*/ "");
}

// struct RtCompileFuncList
Expand All @@ -472,12 +470,11 @@ llvm::StructType *getSymListElemType(llvm::LLVMContext &context) {

llvm::StructType *getFuncListElemType(llvm::LLVMContext &context) {
llvm::Type *elements[] = {
llvm::IntegerType::getInt8PtrTy(context),
llvm::IntegerType::getInt8PtrTy(context),
llvm::IntegerType::getInt8PtrTy(context),
getI8PtrType(context),
getI8PtrType(context),
getI8PtrType(context),
};
return llvm::StructType::create(context, elements, /*"RtCompileFuncList"*/ "",
true);
return llvm::StructType::create(context, elements, /*"RtCompileFuncList"*/ "");
}

// struct RtCompileModuleList
Expand All @@ -490,6 +487,8 @@ llvm::StructType *getFuncListElemType(llvm::LLVMContext &context) {
// i32 funcListSize;
// RtCompileSymList* symList;
// i32 symListSize;
// RtCompileVarList* varList;
// i32 varListSize;
// };

llvm::StructType *getModuleListElemType(llvm::LLVMContext &context,
Expand All @@ -504,7 +503,7 @@ llvm::StructType *getModuleListElemType(llvm::LLVMContext &context,
llvm::Type *elements[] = {
llvm::IntegerType::get(context, 32),
llvm::PointerType::getUnqual(ret),
llvm::IntegerType::getInt8PtrTy(context),
getI8PtrType(context),
llvm::IntegerType::get(context, 32),
llvm::PointerType::getUnqual(funcListElemType),
llvm::IntegerType::get(context, 32),
Expand All @@ -513,7 +512,7 @@ llvm::StructType *getModuleListElemType(llvm::LLVMContext &context,
llvm::PointerType::getUnqual(varListElemType),
llvm::IntegerType::get(context, 32),
};
ret->setBody(elements, true);
ret->setBody(elements);
return ret;
}

Expand Down Expand Up @@ -546,8 +545,8 @@ generateFuncList(IRState *irs, const Types &types,
auto name = it.first->getName();
llvm::Constant *fields[] = {
createStringInitializer(irs->module, name),
getI8Ptr(it.second.thunkVar),
getI8Ptr(it.second.thunkFunc),
it.second.thunkVar,
it.second.thunkFunc,
};
elements.push_back(
llvm::ConstantStruct::get(types.funcListElemType, fields));
Expand All @@ -563,7 +562,7 @@ generateFuncList(IRState *irs, const Types &types,
llvm::Constant *fields[] = {
createStringInitializer(irs->module, name),
nullp,
getI8Ptr(func),
func,
};
elements.push_back(
llvm::ConstantStruct::get(types.funcListElemType, fields));
Expand All @@ -578,7 +577,7 @@ llvm::Constant *generateSymListElem(llvm::Module &module, const Types &types,

llvm::Constant *fields[] = {
createStringInitializer(module, name),
getI8Ptr(&val),
&val,
};
return llvm::ConstantStruct::get(types.symListElemType, fields);
}
Expand Down Expand Up @@ -618,7 +617,7 @@ generateVarList(IRState *irs, const Types &types) {
auto name = gvar->getName();
llvm::Constant *fields[] = {
createStringInitializer(irs->module, name),
getI8Ptr(gvar),
gvar,
};
elements.push_back(
llvm::ConstantStruct::get(types.varListElemType, fields));
Expand Down Expand Up @@ -650,16 +649,18 @@ llvm::GlobalVariable *generateModuleListElem(IRState *irs, const Types &types,
};

auto init = llvm::ConstantStruct::get(elem_type, fields);
auto *modListElem = new llvm::GlobalVariable(
irs->module, elem_type, false, llvm::GlobalValue::PrivateLinkage, init,
".rtcompile_modlist_elem");
modListElem->setAlignment(irs->module.getDataLayout().getABITypeAlign(elem_type->getPointerTo()));

return new llvm::GlobalVariable(irs->module, elem_type, false,
llvm::GlobalValue::PrivateLinkage, init,
".rtcompile_modlist_elem");
return modListElem;
}

llvm::PointerType *getModListHeadType(llvm::LLVMContext &context,
const Types &types) {
(void)types;
return llvm::IntegerType::getInt8PtrTy(context);
return getI8PtrType(context);
}

llvm::GlobalVariable *declareModListHead(llvm::Module &module,
Expand All @@ -685,11 +686,10 @@ void generateCtorBody(IRState *irs, const Types &types, llvm::Function *func,
auto elemIndex = llvm::ConstantInt::get(irs->context(), APInt(32, 1));
auto modListHeadPtr = declareModListHead(irs->module, types);
llvm::Value *gepVals[] = {zero64, elemIndex};
auto elemNextPtr = builder.CreateGEP(modListElem, gepVals);
auto prevHeadVal = builder.CreateLoad(builder.CreateBitOrPointerCast(
modListHeadPtr, types.modListElemType->getPointerTo()->getPointerTo()));
auto elemNextPtr = builder.CreateGEP(types.modListElemType, modListElem, gepVals);
auto prevHeadVal = builder.CreateLoad(types.modListElemType->getPointerTo()->getPointerTo(), modListHeadPtr);
auto voidPtr = builder.CreateBitOrPointerCast(
modListElem, llvm::IntegerType::getInt8PtrTy(irs->context()));
modListElem, getI8PtrType(irs->context()));
builder.CreateStore(voidPtr, modListHeadPtr);
builder.CreateStore(prevHeadVal, elemNextPtr);

Expand Down Expand Up @@ -721,7 +721,7 @@ void setupModuleBitcodeData(const llvm::Module &srcModule, IRState *irs,
llvm::WriteBitcodeToFile(srcModule, os);

auto runtimeCompiledIr = new llvm::GlobalVariable(
irs->module, llvm::Type::getInt8PtrTy(irs->context()), true,
irs->module, getI8PtrType(irs->context()), true,
llvm::GlobalValue::PrivateLinkage, nullptr, ".rtcompile_ir");

auto runtimeCompiledIrSize = new llvm::GlobalVariable(
Expand Down Expand Up @@ -761,7 +761,7 @@ void createThunkFunc(llvm::Module &module, const llvm::Function *src,
auto bb = llvm::BasicBlock::Create(module.getContext(), "", dst);
llvm::IRBuilder<> builder(module.getContext());
builder.SetInsertPoint(bb);
auto thunkPtr = builder.CreateLoad(thunkVar);
auto thunkPtr = builder.CreateLoad(llvm::PointerType::getUnqual(module.getContext()), thunkVar);
llvm::SmallVector<llvm::Value *, 6> args;
for (auto &arg : dst->args()) {
args.push_back(&arg);
Expand Down
Loading

0 comments on commit 268ad13

Please sign in to comment.