diff --git a/.gitmodules b/.gitmodules index 1e2e7a4..71a76c8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,11 +1,7 @@ [submodule "external/asmjit"] - path = external/asmjit + path = ThirdParty/asmjit url = https://github.com/asmjit/asmjit branch = master -[submodule "external/llvm"] - path = external/llvm - url = https://github.com/llvm/llvm-project - branch = release/7.x [submodule "external/asmjit-utilities"] - path = external/asmjit-utilities + path = ThirdParty/asmjit-utilities url = https://github.com/tetzank/asmjit-utilities diff --git a/CMakeLists.txt b/CMakeLists.txt index 3b46fe0..9d99a69 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,105 +1,129 @@ cmake_minimum_required(VERSION 3.12) -if(NOT DEFINED CMAKE_CXX_FLAGS) - set(CMAKE_CXX_FLAGS "-Wall -Wextra -march=native -fno-rtti" CACHE STRING "Flags used by the compiler during all build types.") -endif() -# build type defaults to release +# Build type defaults to release if(NOT DEFINED CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS) Debug Release RelWithdebInfo MinSizeRel.") endif() project(coat CXX) -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -include_directories("${CMAKE_SOURCE_DIR}/include/") - option(ENABLE_ASMJIT "enable AsmJit backend" ON) option(ENABLE_LLVMJIT "enable LLVM JIT backend" ON) -if(ENABLE_ASMJIT) - # find asmjit - find_path(ASMJIT_INCLUDE_DIR - asmjit/asmjit.h - HINTS external/asmjit ENV ASMJIT_ROOT - PATH_SUFFIXES src - ) - find_library(ASMJIT_LIBRARIES - asmjit - HINTS external/asmjit ENV ASMJIT_ROOT - PATH_SUFFIXES build build_next - ) - include_directories(${ASMJIT_INCLUDE_DIR}) - - # find asmjit_perf - find_path(ASMJIT_PERF_INCLUDE_DIR - asmjit-utilities/perf/jitdump.h - HINTS external/ - ) - find_library(ASMJIT_PERF_LIBRARIES - asmjit_perf - HINTS external/asmjit-utilities - PATH_SUFFIXES perf/build - ) - include_directories(${ASMJIT_PERF_INCLUDE_DIR}) -endif() +enable_testing() -if(ENABLE_LLVMJIT) - # find llvm, quick&dirty - find_path(LLVM_INCLUDE_DIR - llvm/IR/IRBuilder.h - HINTS external/llvm/llvm/install ENV LLVM_ROOT - PATH_SUFFIXES include - ) - find_library(LLVM_LIBRARIES - LLVM - HINTS external/llvm/llvm/install ENV LLVM_ROOT - PATH_SUFFIXES lib build/lib - ) - include_directories(${LLVM_INCLUDE_DIR}) -endif() +macro(coat_add_executable) + set(options TEST) + set(oneValueArgs BACKEND) + set(multiValueArgs NAMES) + cmake_parse_arguments(COAT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) + foreach(NAME ${COAT_NAMES}) + if (COAT_TEST) + set(TARGET test_${PROJECT_NAME}_${COAT_BACKEND}_${NAME}) + set(SRC src/tests/${NAME}.cpp) + else() + set(TARGET example_${PROJECT_NAME}_${COAT_BACKEND}_${NAME}) + set(SRC src/examples/${NAME}.cpp) + endif() + add_executable(${TARGET} ${SRC}) + set_target_properties(${TARGET} PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON) + target_link_libraries(${TARGET} ${PROJECT_NAME}::${COAT_BACKEND}) + if (COAT_TEST) + add_test(${TARGET} ${TARGET}) + endif() + endforeach() +endmacro() + +if (ENABLE_LLVMJIT) + find_package(LLVM CONFIG REQUIRED PATHS "/usr/lib/llvm-12/lib/cmake" NO_DEFAULT_PATH) + find_package(Clang CONFIG REQUIRED PATHS "/usr/lib/llvm-12/lib/cmake" NO_DEFAULT_PATH) -# debugging options -if(NOT DEFINED PROFILING) - set(PROFILING "" CACHE STRING "Choose type of profiling support for perf and AsmJit, options are: None, Assembly, Source") -endif() -if(PROFILING STREQUAL "Assembly") - add_compile_definitions("PROFILING_ASSEMBLY") -elseif(PROFILING STREQUAL "Source") - add_compile_definitions("PROFILING_SOURCE") -endif() + if(MSVC) + set(DISABLE_RTTI_FLAG /GR-) + else() + set(DISABLE_RTTI_FLAG -fno-rtti) + endif() -add_executable(tests tests.cpp) -if(ENABLE_ASMJIT) - target_compile_definitions(tests PRIVATE "ENABLE_ASMJIT") - target_link_libraries(tests ${ASMJIT_LIBRARIES} ${ASMJIT_PERF_LIBRARIES}) -endif() -if(ENABLE_LLVMJIT) - target_compile_definitions(tests PRIVATE "ENABLE_LLVMJIT") - target_link_libraries(tests ${LLVM_LIBRARIES}) -endif() + add_library(${PROJECT_NAME}_llvmjit INTERFACE) + set_target_properties(${PROJECT_NAME}_llvmjit PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON) + target_include_directories(${PROJECT_NAME}_llvmjit INTERFACE ${CMAKE_SOURCE_DIR}/include) + add_library(${PROJECT_NAME}::llvmjit ALIAS ${PROJECT_NAME}_llvmjit) -enable_testing() -add_subdirectory(${CMAKE_SOURCE_DIR}/examples) + separate_arguments(LLVM_DEFINITIONS) + target_compile_definitions(${PROJECT_NAME}_llvmjit INTERFACE ${LLVM_DEFINITIONS}) + + target_include_directories(${PROJECT_NAME}_llvmjit INTERFACE ${LLVM_INCLUDE_DIRS}) + if(NOT LLVM_ENABLE_RTTI) + target_compile_options(${PROJECT_NAME}_llvmjit INTERFACE ${DISABLE_RTTI_FLAG}) + endif() + + target_compile_definitions(${PROJECT_NAME}_llvmjit INTERFACE ENABLE_LLVMJIT) + if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") + target_compile_definitions(${PROJECT_NAME}_llvmjit INTERFACE LLVMJIT_DEBUG) + endif() + target_link_directories(${PROJECT_NAME}_llvmjit INTERFACE ${LLVM_LIBRARY_DIRS}) + target_link_libraries(${PROJECT_NAME}_llvmjit INTERFACE LLVMCore LLVMX86CodeGen LLVMPerfJITEvents LLVMOrcJIT LLVMExecutionEngine) + + coat_add_executable(NAMES + tests + calculator + fibonacci + BACKEND llvmjit) + + coat_add_executable(NAMES + sum + cast + call + reading_datastruct + # Just trying vector types + vectormean + vectormerge + vectorintersection + BACKEND llvmjit + TEST) -add_executable(calculator calculator.cpp) -if(ENABLE_ASMJIT) - target_compile_definitions(calculator PRIVATE "ENABLE_ASMJIT") - target_link_libraries(calculator ${ASMJIT_LIBRARIES} ${ASMJIT_PERF_LIBRARIES}) -endif() -if(ENABLE_LLVMJIT) - target_compile_definitions(calculator PRIVATE "ENABLE_LLVMJIT") - target_link_libraries(calculator ${LLVM_LIBRARIES}) endif() -add_executable(fibonacci fibonacci.cpp) if(ENABLE_ASMJIT) - target_compile_definitions(fibonacci PRIVATE "ENABLE_ASMJIT") - target_link_libraries(fibonacci ${ASMJIT_LIBRARIES} ${ASMJIT_PERF_LIBRARIES}) -endif() -if(ENABLE_LLVMJIT) - target_compile_definitions(fibonacci PRIVATE "ENABLE_LLVMJIT") - target_link_libraries(fibonacci ${LLVM_LIBRARIES}) + add_subdirectory(ThirdParty/asmjit) + set(ASMJIT_INCLUDE_DIR ThirdParty/asmjit/src/asmjit) + set(ASMJIT_LIBRARIES asmjit) + add_subdirectory(ThirdParty/asmjit-utilities/perf) + + add_library(${PROJECT_NAME}_asmjit INTERFACE) + set_target_properties(${PROJECT_NAME}_asmjit PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON) + target_include_directories(${PROJECT_NAME}_asmjit INTERFACE ${CMAKE_SOURCE_DIR}/include) + add_library(${PROJECT_NAME}::asmjit ALIAS ${PROJECT_NAME}_asmjit) + + target_compile_definitions(${PROJECT_NAME}_asmjit INTERFACE ENABLE_ASMJIT) + target_link_libraries(${PROJECT_NAME}_asmjit INTERFACE asmjit asmjit_perf) + + # Debugging options + if(NOT DEFINED PROFILING) + set(PROFILING "" CACHE STRING "Choose type of profiling support for perf and AsmJit, options are: None, Assembly, Source") + endif() + if(PROFILING STREQUAL "Assembly") + target_compile_definitions(${PROJECT_NAME}_asmjit INTERFACE PROFILING_ASSEMBLY) + elseif(PROFILING STREQUAL "Source") + target_compile_definitions(${PROJECT_NAME}_asmjit PROFILING_SOURCE) + endif() + + coat_add_executable(NAMES + tests + calculator + fibonacci + BACKEND asmjit) + + coat_add_executable(NAMES + sum + cast + call + reading_datastruct + # Just trying vector types + vectormean + BACKEND asmjit + TEST) + endif() + diff --git a/README.md b/README.md index a7603b3..c9d6e97 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,28 @@ This library tries to make JIT compilation as easy as possible. More details are explained in a [blog post](https://tetzank.github.io/posts/coat-edsl-for-codegen/). +## Build Instructions + +Ensure submodules are fetched, and build with CMake: + +``` +git submodule init +git submodule update +mkdir build +cd build +cmake .. +make -j4 +make test +``` + +The library is header-only. Small example programs are included to show how to use the library: + +``` +cd build +./example_coat_llvmjit_calculator +./example_coat_asmjit_calculator +``` + ## Example The following code snippet is a full example program. @@ -301,24 +323,6 @@ func_t foo = fn.finalize(); ``` -## Build Instructions - -The library is header-only. Small test programs are included to show how to use the library. - -Fetch JIT engines and build them (use `-j` for parallel compilation, LLVM can take a while...): -``` -$ ./buildDependencies.sh -j8 -``` - -Then, build with cmake: -``` -$ mkdir build -$ cd build -$ cmake .. -$ make -``` - - ## Profiling Instructions Profiling is currently only supported for the AsmJit backend and perf on Linux. diff --git a/external/asmjit b/ThirdParty/asmjit similarity index 100% rename from external/asmjit rename to ThirdParty/asmjit diff --git a/external/asmjit-utilities b/ThirdParty/asmjit-utilities similarity index 100% rename from external/asmjit-utilities rename to ThirdParty/asmjit-utilities diff --git a/buildDependencies.sh b/buildDependencies.sh deleted file mode 100755 index 374c585..0000000 --- a/buildDependencies.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash - -# run with -j42 to run with 42 parallel tasks - -git submodule update --init - -pushd external/asmjit -mkdir -p build -cd build -cmake -DCMAKE_BUILD_TYPE=Release .. -make $@ -popd - -pushd external/asmjit-utilities -mkdir -p perf/build -cd perf/build -ASMJIT_ROOT=../../../external/asmjit cmake -DCMAKE_BUILD_TYPE=Release .. -make $@ -popd - -pushd external/llvm/llvm -mkdir -p build -cd build -cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../install -DLLVM_BUILD_LLVM_DYLIB=ON -DLLVM_USE_PERF=ON .. -make $@ -make install -popd diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt deleted file mode 100644 index 4681278..0000000 --- a/examples/CMakeLists.txt +++ /dev/null @@ -1,80 +0,0 @@ -if(ENABLE_ASMJIT) - add_executable(sum sum.cpp) - target_compile_definitions(sum PRIVATE "ENABLE_ASMJIT") - target_link_libraries(sum ${ASMJIT_LIBRARIES} ${ASMJIT_PERF_LIBRARIES}) - add_test(test_sum sum) -endif() -if(ENABLE_LLVMJIT) - add_executable(sumLLVM sum.cpp) - target_compile_definitions(sumLLVM PRIVATE "ENABLE_LLVMJIT" "LLVMJIT_DEBUG") - target_link_libraries(sumLLVM ${LLVM_LIBRARIES}) - add_test(test_sumLLVM sumLLVM) -endif() - - -if(ENABLE_ASMJIT) - add_executable(cast cast.cpp) - target_compile_definitions(cast PRIVATE "ENABLE_ASMJIT") - target_link_libraries(cast ${ASMJIT_LIBRARIES} ${ASMJIT_PERF_LIBRARIES}) - add_test(test_cast cast) -endif() -if(ENABLE_LLVMJIT) - add_executable(castLLVM cast.cpp) - target_compile_definitions(castLLVM PRIVATE "ENABLE_LLVMJIT") - target_link_libraries(castLLVM ${LLVM_LIBRARIES}) - add_test(test_castLLVM castLLVM) -endif() - - -if(ENABLE_ASMJIT) - add_executable(call call.cpp) - target_compile_definitions(call PRIVATE "ENABLE_ASMJIT") - target_link_libraries(call ${ASMJIT_LIBRARIES} ${ASMJIT_PERF_LIBRARIES}) - add_test(test_call call) -endif() -if(ENABLE_LLVMJIT) - add_executable(callLLVM call.cpp) - target_compile_definitions(callLLVM PRIVATE "ENABLE_LLVMJIT") - target_link_libraries(callLLVM ${LLVM_LIBRARIES}) - add_test(test_callLLVM callLLVM) -endif() - - -if(ENABLE_ASMJIT) - add_executable(reading reading_datastruct.cpp) - target_compile_definitions(reading PRIVATE "ENABLE_ASMJIT") - target_link_libraries(reading ${ASMJIT_LIBRARIES} ${ASMJIT_PERF_LIBRARIES}) - add_test(test_reading reading) -endif() -if(ENABLE_LLVMJIT) - add_executable(readingLLVM reading_datastruct.cpp) - target_compile_definitions(readingLLVM PRIVATE "ENABLE_LLVMJIT" "LLVMJIT_DEBUG") - target_link_libraries(readingLLVM ${LLVM_LIBRARIES}) - add_test(test_readingLLVM readingLLVM) -endif() - -# just trying vector types -if(ENABLE_ASMJIT) - add_executable(vectormean vectormean.cpp) - target_compile_definitions(vectormean PRIVATE "ENABLE_ASMJIT") - target_link_libraries(vectormean ${ASMJIT_LIBRARIES} ${ASMJIT_PERF_LIBRARIES}) - add_test(test_vectormean vectormean) -endif() -if(ENABLE_LLVMJIT) - add_executable(vectormeanLLVM vectormean.cpp) - target_compile_definitions(vectormeanLLVM PRIVATE "ENABLE_LLVMJIT") - target_link_libraries(vectormeanLLVM ${LLVM_LIBRARIES}) - add_test(test_vectormeanLLVM vectormeanLLVM) -endif() - - -if(ENABLE_LLVMJIT) - add_executable(vectormergeLLVM vectormerge.cpp) - target_compile_definitions(vectormergeLLVM PRIVATE "ENABLE_LLVMJIT") - target_link_libraries(vectormergeLLVM ${LLVM_LIBRARIES}) -endif() -if(ENABLE_LLVMJIT) - add_executable(vectorintersectionLLVM vectorintersection.cpp) - target_compile_definitions(vectorintersectionLLVM PRIVATE "ENABLE_LLVMJIT") - target_link_libraries(vectorintersectionLLVM ${LLVM_LIBRARIES}) -endif() diff --git a/external/llvm b/external/llvm deleted file mode 160000 index 1fdec59..0000000 --- a/external/llvm +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1fdec59bffc11ae37eb51a1b9869f0696bfd5312 diff --git a/include/coat/llvmjit/Function.h b/include/coat/llvmjit/Function.h index 266db7e..b1b825b 100644 --- a/include/coat/llvmjit/Function.h +++ b/include/coat/llvmjit/Function.h @@ -239,7 +239,7 @@ struct Function{ llvm::Constant *c = llvm::cast(md->getOperand(0))->getValue(); uint64_t fnptr = llvm::cast(c)->getZExtValue(); // add function address as absolute symbol - cantFail(jit.J->define( + llvm::cantFail(jit.J->getMainJITDylib().define( llvm::orc::absoluteSymbols({{ jit.J->mangleAndIntern(f.getName()), llvm::JITEvaluatedSymbol::fromPointer((void*)fnptr) @@ -250,9 +250,9 @@ struct Function{ } llvm::orc::ThreadSafeModule tsm(std::move(M), std::move(context)); - cantFail(jit.J->addIRModule(std::move(tsm))); + llvm::cantFail(jit.J->addIRModule(std::move(tsm))); // Look up the JIT'd function - llvm::JITEvaluatedSymbol SumSym = cantFail(jit.J->lookup(name)); + llvm::JITEvaluatedSymbol SumSym = llvm::cantFail(jit.J->lookup(name)); // get function ptr return (func_type)SumSym.getAddress(); } diff --git a/include/coat/runtimellvmjit.h b/include/coat/runtimellvmjit.h index f729ae2..9b3aa94 100644 --- a/include/coat/runtimellvmjit.h +++ b/include/coat/runtimellvmjit.h @@ -7,6 +7,7 @@ #include // InitializeNativeTarget #include +#include #include #include #include diff --git a/calculator.cpp b/src/examples/calculator.cpp similarity index 100% rename from calculator.cpp rename to src/examples/calculator.cpp diff --git a/fibonacci.cpp b/src/examples/fibonacci.cpp similarity index 100% rename from fibonacci.cpp rename to src/examples/fibonacci.cpp diff --git a/tests.cpp b/src/examples/tests.cpp similarity index 100% rename from tests.cpp rename to src/examples/tests.cpp diff --git a/examples/call.cpp b/src/tests/call.cpp similarity index 100% rename from examples/call.cpp rename to src/tests/call.cpp diff --git a/examples/cast.cpp b/src/tests/cast.cpp similarity index 100% rename from examples/cast.cpp rename to src/tests/cast.cpp diff --git a/examples/reading_datastruct.cpp b/src/tests/reading_datastruct.cpp similarity index 100% rename from examples/reading_datastruct.cpp rename to src/tests/reading_datastruct.cpp diff --git a/examples/sum.cpp b/src/tests/sum.cpp similarity index 100% rename from examples/sum.cpp rename to src/tests/sum.cpp diff --git a/examples/vectorintersection.cpp b/src/tests/vectorintersection.cpp similarity index 100% rename from examples/vectorintersection.cpp rename to src/tests/vectorintersection.cpp diff --git a/examples/vectormean.cpp b/src/tests/vectormean.cpp similarity index 100% rename from examples/vectormean.cpp rename to src/tests/vectormean.cpp diff --git a/examples/vectormerge.cpp b/src/tests/vectormerge.cpp similarity index 100% rename from examples/vectormerge.cpp rename to src/tests/vectormerge.cpp