From 8c3b901c31881d54e345298db267669b48d4883e Mon Sep 17 00:00:00 2001 From: xieda2025 Date: Thu, 6 Nov 2025 15:29:49 +0800 Subject: [PATCH] Add easy-jit project to llvm-project - Import easy-jit as a standalone project under llvm-project - Add easy-jit to LLVM_EXTRA_PROJECTS in llvm/CMakeLists.txt - Configure integration with LLVM build system --- easy-jit/.gitignore | 16 + easy-jit/.travis-old.yml | 30 + easy-jit/CMakeLists.txt | 103 ++++ easy-jit/CMakeTests.txt | 24 + easy-jit/LICENSE | 29 + easy-jit/README.md | 202 +++++++ easy-jit/benchmark/CMakeLists.txt | 31 ++ easy-jit/benchmark/benchmark.cpp | 154 +++++ easy-jit/cmake/CMakeLists.txt | 3 + easy-jit/cmake/EasyJitConfig.cmake.in | 10 + easy-jit/doc/CMakeLists.txt | 1 + easy-jit/doc/readme/CMakeLists.txt | 19 + easy-jit/doc/readme/README.md.in | 167 ++++++ easy-jit/doc/readme/camfilter.cpp | 244 ++++++++ easy-jit/doc/readme/readme_is_up-to-date.test | 4 + easy-jit/doc/readme/update_doc.sh | 11 + easy-jit/doc/slides/cppcon'18.pdf | Bin 0 -> 464261 bytes easy-jit/include/CMakeLists.txt | 2 + easy-jit/include/easy/attributes.h | 19 + easy-jit/include/easy/code_cache.h | 87 +++ easy-jit/include/easy/exceptions.h | 24 + easy-jit/include/easy/function_wrapper.h | 132 +++++ easy-jit/include/easy/jit.h | 68 +++ easy-jit/include/easy/meta.h | 211 +++++++ easy-jit/include/easy/options.h | 50 ++ easy-jit/include/easy/param.h | 162 ++++++ .../include/easy/runtime/BitcodeTracker.h | 71 +++ easy-jit/include/easy/runtime/Context.h | 235 ++++++++ easy-jit/include/easy/runtime/Function.h | 58 ++ easy-jit/include/easy/runtime/LLVMHolder.h | 10 + .../include/easy/runtime/LLVMHolderImpl.h | 25 + easy-jit/include/easy/runtime/RuntimePasses.h | 58 ++ easy-jit/include/easy/runtime/Utils.h | 25 + easy-jit/misc/doc/generate.py | 32 ++ easy-jit/misc/doc/include.py | 19 + easy-jit/misc/doc/python.py | 7 + easy-jit/misc/docker/GenDockerfile.py | 54 ++ easy-jit/misc/docker/build_docker.sh | 3 + easy-jit/pass/CMakeLists.txt | 22 + easy-jit/pass/Easy.cpp | 526 ++++++++++++++++++ easy-jit/pass/Layout.cpp | 205 +++++++ easy-jit/pass/MayAliasTracer.cpp | 75 +++ easy-jit/pass/MayAliasTracer.h | 32 ++ easy-jit/pass/RegisterPasses.cpp | 28 + easy-jit/pass/StaticPasses.h | 13 + easy-jit/pass/Utils.cpp | 22 + easy-jit/pass/Utils.h | 13 + easy-jit/runtime/BitcodeTracker.cpp | 84 +++ easy-jit/runtime/CMakeLists.txt | 19 + easy-jit/runtime/Context.cpp | 44 ++ easy-jit/runtime/Function.cpp | 222 ++++++++ easy-jit/runtime/InitNativeTarget.cpp | 28 + easy-jit/runtime/Utils.cpp | 73 +++ easy-jit/runtime/pass/ContextAnalysis.cpp | 17 + .../runtime/pass/DevirtualizeConstant.cpp | 128 +++++ easy-jit/runtime/pass/InlineParameters.cpp | 257 +++++++++ .../runtime/pass/InlineParametersHelper.cpp | 260 +++++++++ .../runtime/pass/InlineParametersHelper.h | 58 ++ easy-jit/tests/doc/lit.cfg.in | 12 + easy-jit/tests/inlineparam/convolve.cpp | 45 ++ easy-jit/tests/install/CMakeLists.txt | 21 + easy-jit/tests/install/test.cpp | 34 ++ easy-jit/tests/lit.cfg.in | 54 ++ easy-jit/tests/meta/bad_signature_a.cpp | 19 + easy-jit/tests/meta/bad_signature_b.cpp | 18 + easy-jit/tests/meta/bad_signature_c.cpp | 19 + easy-jit/tests/meta/new_func_traits.cpp | 66 +++ easy-jit/tests/meta/type_list+func_traits.cpp | 58 ++ easy-jit/tests/simple/cache.cpp | 37 ++ easy-jit/tests/simple/compose_bad.cpp | 28 + easy-jit/tests/simple/compose_ptr.cpp | 56 ++ easy-jit/tests/simple/compose_ref.cpp | 52 ++ easy-jit/tests/simple/custom_key_cache.cpp | 65 +++ easy-jit/tests/simple/devirtualization.cpp | 42 ++ .../tests/simple/devirtualization_nohint.cpp | 41 ++ easy-jit/tests/simple/double_a.cpp | 27 + easy-jit/tests/simple/exception_a.cpp | 36 ++ easy-jit/tests/simple/float_a.cpp | 27 + easy-jit/tests/simple/fun_ptr_a.cpp | 42 ++ easy-jit/tests/simple/fun_ptr_b.cpp | 41 ++ easy-jit/tests/simple/fun_ptr_c.cpp | 47 ++ easy-jit/tests/simple/fun_ptr_d.cpp | 45 ++ easy-jit/tests/simple/fun_ptr_e.cpp | 49 ++ easy-jit/tests/simple/fun_ptr_f.cpp | 47 ++ easy-jit/tests/simple/int_a.cpp | 27 + easy-jit/tests/simple/int_ptr_a.cpp | 36 ++ easy-jit/tests/simple/long_a.cpp | 27 + easy-jit/tests/simple/multi_file+regexp.cpp | 39 ++ easy-jit/tests/simple/nortti_a.cpp | 27 + easy-jit/tests/simple/opt_level.cpp | 90 +++ easy-jit/tests/simple/ptr_a.cpp | 28 + easy-jit/tests/simple/serialize.cpp | 41 ++ easy-jit/tests/simple/serialize_multifile.cpp | 57 ++ easy-jit/tests/simple/serialize_static.cpp | 45 ++ easy-jit/tests/simple/small_struct.cpp | 32 ++ easy-jit/tests/simple/static_var_a.cpp | 27 + easy-jit/tests/simple/static_var_b.cpp | 29 + easy-jit/tests/simple/struct_arg.cpp | 102 ++++ easy-jit/tests/simple/struct_return.cpp | 73 +++ easy-jit/tests/simple/thread.cpp | 30 + easy-jit/tests/simple/unroll.cpp | 41 ++ llvm/CMakeLists.txt | 2 +- llvm/tools/CMakeLists.txt | 1 + 103 files changed, 6307 insertions(+), 1 deletion(-) create mode 100644 easy-jit/.gitignore create mode 100644 easy-jit/.travis-old.yml create mode 100644 easy-jit/CMakeLists.txt create mode 100644 easy-jit/CMakeTests.txt create mode 100644 easy-jit/LICENSE create mode 100644 easy-jit/README.md create mode 100644 easy-jit/benchmark/CMakeLists.txt create mode 100644 easy-jit/benchmark/benchmark.cpp create mode 100644 easy-jit/cmake/CMakeLists.txt create mode 100644 easy-jit/cmake/EasyJitConfig.cmake.in create mode 100644 easy-jit/doc/CMakeLists.txt create mode 100644 easy-jit/doc/readme/CMakeLists.txt create mode 100644 easy-jit/doc/readme/README.md.in create mode 100644 easy-jit/doc/readme/camfilter.cpp create mode 100644 easy-jit/doc/readme/readme_is_up-to-date.test create mode 100644 easy-jit/doc/readme/update_doc.sh create mode 100644 easy-jit/doc/slides/cppcon'18.pdf create mode 100644 easy-jit/include/CMakeLists.txt create mode 100644 easy-jit/include/easy/attributes.h create mode 100644 easy-jit/include/easy/code_cache.h create mode 100644 easy-jit/include/easy/exceptions.h create mode 100644 easy-jit/include/easy/function_wrapper.h create mode 100644 easy-jit/include/easy/jit.h create mode 100644 easy-jit/include/easy/meta.h create mode 100644 easy-jit/include/easy/options.h create mode 100644 easy-jit/include/easy/param.h create mode 100644 easy-jit/include/easy/runtime/BitcodeTracker.h create mode 100644 easy-jit/include/easy/runtime/Context.h create mode 100644 easy-jit/include/easy/runtime/Function.h create mode 100644 easy-jit/include/easy/runtime/LLVMHolder.h create mode 100644 easy-jit/include/easy/runtime/LLVMHolderImpl.h create mode 100644 easy-jit/include/easy/runtime/RuntimePasses.h create mode 100644 easy-jit/include/easy/runtime/Utils.h create mode 100644 easy-jit/misc/doc/generate.py create mode 100644 easy-jit/misc/doc/include.py create mode 100644 easy-jit/misc/doc/python.py create mode 100644 easy-jit/misc/docker/GenDockerfile.py create mode 100644 easy-jit/misc/docker/build_docker.sh create mode 100644 easy-jit/pass/CMakeLists.txt create mode 100644 easy-jit/pass/Easy.cpp create mode 100644 easy-jit/pass/Layout.cpp create mode 100644 easy-jit/pass/MayAliasTracer.cpp create mode 100644 easy-jit/pass/MayAliasTracer.h create mode 100644 easy-jit/pass/RegisterPasses.cpp create mode 100644 easy-jit/pass/StaticPasses.h create mode 100644 easy-jit/pass/Utils.cpp create mode 100644 easy-jit/pass/Utils.h create mode 100644 easy-jit/runtime/BitcodeTracker.cpp create mode 100644 easy-jit/runtime/CMakeLists.txt create mode 100644 easy-jit/runtime/Context.cpp create mode 100644 easy-jit/runtime/Function.cpp create mode 100644 easy-jit/runtime/InitNativeTarget.cpp create mode 100644 easy-jit/runtime/Utils.cpp create mode 100644 easy-jit/runtime/pass/ContextAnalysis.cpp create mode 100644 easy-jit/runtime/pass/DevirtualizeConstant.cpp create mode 100644 easy-jit/runtime/pass/InlineParameters.cpp create mode 100644 easy-jit/runtime/pass/InlineParametersHelper.cpp create mode 100644 easy-jit/runtime/pass/InlineParametersHelper.h create mode 100644 easy-jit/tests/doc/lit.cfg.in create mode 100644 easy-jit/tests/inlineparam/convolve.cpp create mode 100644 easy-jit/tests/install/CMakeLists.txt create mode 100644 easy-jit/tests/install/test.cpp create mode 100644 easy-jit/tests/lit.cfg.in create mode 100644 easy-jit/tests/meta/bad_signature_a.cpp create mode 100644 easy-jit/tests/meta/bad_signature_b.cpp create mode 100644 easy-jit/tests/meta/bad_signature_c.cpp create mode 100644 easy-jit/tests/meta/new_func_traits.cpp create mode 100644 easy-jit/tests/meta/type_list+func_traits.cpp create mode 100644 easy-jit/tests/simple/cache.cpp create mode 100644 easy-jit/tests/simple/compose_bad.cpp create mode 100644 easy-jit/tests/simple/compose_ptr.cpp create mode 100644 easy-jit/tests/simple/compose_ref.cpp create mode 100644 easy-jit/tests/simple/custom_key_cache.cpp create mode 100644 easy-jit/tests/simple/devirtualization.cpp create mode 100644 easy-jit/tests/simple/devirtualization_nohint.cpp create mode 100644 easy-jit/tests/simple/double_a.cpp create mode 100644 easy-jit/tests/simple/exception_a.cpp create mode 100644 easy-jit/tests/simple/float_a.cpp create mode 100644 easy-jit/tests/simple/fun_ptr_a.cpp create mode 100644 easy-jit/tests/simple/fun_ptr_b.cpp create mode 100644 easy-jit/tests/simple/fun_ptr_c.cpp create mode 100644 easy-jit/tests/simple/fun_ptr_d.cpp create mode 100644 easy-jit/tests/simple/fun_ptr_e.cpp create mode 100644 easy-jit/tests/simple/fun_ptr_f.cpp create mode 100644 easy-jit/tests/simple/int_a.cpp create mode 100644 easy-jit/tests/simple/int_ptr_a.cpp create mode 100644 easy-jit/tests/simple/long_a.cpp create mode 100644 easy-jit/tests/simple/multi_file+regexp.cpp create mode 100644 easy-jit/tests/simple/nortti_a.cpp create mode 100644 easy-jit/tests/simple/opt_level.cpp create mode 100644 easy-jit/tests/simple/ptr_a.cpp create mode 100644 easy-jit/tests/simple/serialize.cpp create mode 100644 easy-jit/tests/simple/serialize_multifile.cpp create mode 100644 easy-jit/tests/simple/serialize_static.cpp create mode 100644 easy-jit/tests/simple/small_struct.cpp create mode 100644 easy-jit/tests/simple/static_var_a.cpp create mode 100644 easy-jit/tests/simple/static_var_b.cpp create mode 100644 easy-jit/tests/simple/struct_arg.cpp create mode 100644 easy-jit/tests/simple/struct_return.cpp create mode 100644 easy-jit/tests/simple/thread.cpp create mode 100644 easy-jit/tests/simple/unroll.cpp diff --git a/easy-jit/.gitignore b/easy-jit/.gitignore new file mode 100644 index 000000000000..e63dd861f04e --- /dev/null +++ b/easy-jit/.gitignore @@ -0,0 +1,16 @@ +*.ll +*.ninja_deps +*.ninja_log +*/CMakeCache.txt +*/CMakeFiles/ +*/bin/ +*/build.ninja +*/cmake_install.cmake +*/rules.ninja +*/.ninja_log +*/__pycache__ +*.py[cod] +build/ +.vscode +.venv +/.cache \ No newline at end of file diff --git a/easy-jit/.travis-old.yml b/easy-jit/.travis-old.yml new file mode 100644 index 000000000000..00853c787ba6 --- /dev/null +++ b/easy-jit/.travis-old.yml @@ -0,0 +1,30 @@ +language: cpp + +dist: trusty + +addons: + apt: + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-trusty-6.0 + + packages: + - ninja-build + - g++-6 + - llvm-6.0-dev + - llvm-6.0-tools + - clang-6.0 + - libopencv-dev + +before_install: + - pip install --user --upgrade pip + - pip install --user lit + +script: + - mkdir _build && cd _build + - git clone --depth=1 https://github.com/google/benchmark.git && git clone --depth=1 https://github.com/google/googletest.git benchmark/googletest && mkdir benchmark/_build && cd benchmark/_build && cmake .. -GNinja -DCMAKE_INSTALL_PREFIX=`pwd`/../_install && ninja && ninja install && cd ../.. + - cmake -DLLVM_DIR=/usr/lib/llvm-6.0/cmake -DCMAKE_CXX_COMPILER=clang++-6.0 -DCMAKE_C_COMPILER=clang-6.0 -DEASY_JIT_EXAMPLE=ON -DEASY_JIT_BENCHMARK=ON -DBENCHMARK_DIR=`pwd`/benchmark/_install -DCMAKE_INSTALL_PREFIX=`pwd`/../_install .. -G Ninja + - ninja + - ninja install + - ninja check + diff --git a/easy-jit/CMakeLists.txt b/easy-jit/CMakeLists.txt new file mode 100644 index 000000000000..ed8ba7dd0d76 --- /dev/null +++ b/easy-jit/CMakeLists.txt @@ -0,0 +1,103 @@ +cmake_minimum_required(VERSION 3.12) +set(LLVM_SUBPROJECT_TITLE "EasyJIT") + +# Check for a standalone build and configure as appropriate from +# there. +if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + message("Building EasyJIT as a standalone project.") + project(EasyJIT) + set(EASY_JIT_STANDALONE_BUILD ON) + option(EASY_JIT_INCLUDE_TESTS "Generate build targets for the EasyJIT tests." ON) + option(EASY_JIT_INCLUDE_DOCS "Generate build targets for the EasyJIT docs." OFF) + option(EASY_JIT_EXAMPLE "Generate build targets for the EasyJIT examples." OFF) + option(EASY_JIT_INCLUDE_BENCHMARKS "Generate build targets for the EasyJIT benchmarks." OFF) + option(EASY_JIT_BENCHMARK "Build the EasyJIT benchmarks." OFF) +else() + set(EASY_JIT_STANDALONE_BUILD OFF) + option(EASY_JIT_INCLUDE_TESTS "Generate build targets for the EasyJIT tests." ${LLVM_INCLUDE_TESTS}) + option(EASY_JIT_INCLUDE_DOCS "Generate build targets for the EasyJIT docs." ${LLVM_INCLUDE_DOCS}) + option(EASY_JIT_EXAMPLE "Generate build targets for the EasyJIT examples." ${LLVM_BUILD_EXAMPLES}) + option(EASY_JIT_INCLUDE_BENCHMARKS "Generate build targets for the EasyJIT benchmarks." ${LLVM_INCLUDE_BENCHMARKS}) + option(EASY_JIT_BENCHMARK "Build the EasyJIT benchmarks." ${LLVM_BUILD_BENCHMARKS}) +endif() + +# set(CMAKE_SHARED_LIBRARY_PREFIX_CXX "") + +if("${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}") + message(FATAL_ERROR "Do not set the build directory equal to the source directory!") +endif() + +message(STATUS "CPU Architecture: ${CMAKE_HOST_SYSTEM_PROCESSOR}") +if (${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "x86_64") + add_definitions(-D_X86) +elseif (${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "aarch64") + add_definitions(-D_AARCH64) +endif() + +if(EASY_JIT_STANDALONE_BUILD) + # We need a pre-built/installed version of LLVM. + find_package(LLVM 19.1 REQUIRED HINTS ${LLVM_DIR}) + message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") + message(STATUS "Using LLVMConfig.cmake in ${LLVM_DIR}") + message(STATUS "LLVM Root: ${LLVM_TOOLS_BINARY_DIR}") + message(STATUS "LLVM Include dirs: ${LLVM_INCLUDE_DIRS}") + message(STATUS "LLVM Definitions: ${LLVM_DEFINITIONS}") + # Find llvm-lit if LLVM_DIR did not provide it + if(NOT LLVM_EXTERNAL_LIT AND EASY_JIT_INCLUDE_TESTS) + find_program(LIT_EXECUTABLE NAMES llvm-lit lit + HINTS ${LLVM_TOOLS_BINARY_DIR}) + if(LIT_EXECUTABLE) + set(LLVM_EXTERNAL_LIT ${LIT_EXECUTABLE} CACHE FILEPATH "Path to lit executable") + message(STATUS "Found lit executable: ${LLVM_EXTERNAL_LIT}") + else() + message(FATAL_ERROR "lit or llvm-lit not found. Please set LLVM_EXTERNAL_LIT to the path of lit.") + endif() + endif() +endif() + +list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/") +include(AddLLVM) + +add_definitions(${LLVM_DEFINITIONS}) +include_directories(${LLVM_INCLUDE_DIRS}) +link_directories(${LLVM_LIBRARY_DIRS}) +include_directories(include) +add_compile_options(-fno-rtti) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +if(EASY_JIT_STANDALONE_BUILD) + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin) +endif() + +set(EASY_JIT_ROOT ${CMAKE_CURRENT_SOURCE_DIR}) + +# Suppress superfluous randlib warnings about "*.a" having no symbols on MacOSX. +if (APPLE) + set(CMAKE_C_ARCHIVE_CREATE " Scr ") + set(CMAKE_CXX_ARCHIVE_CREATE " Scr ") + set(CMAKE_C_ARCHIVE_FINISH " -no_warning_for_no_symbols -c ") + set(CMAKE_CXX_ARCHIVE_FINISH " -no_warning_for_no_symbols -c ") +endif() + +add_subdirectory(cmake) +add_subdirectory(include) +add_subdirectory(pass) +add_subdirectory(runtime) + +add_custom_target(easy-jit-core DEPENDS EasyJitPass EasyJitRuntime) + +if(EASY_JIT_INCLUDE_DOCS) + add_subdirectory(doc) +endif() + +if(EASY_JIT_INCLUDE_BENCHMARKS) + add_subdirectory(benchmark) +endif() + +if(EASY_JIT_INCLUDE_TESTS) + include(CMakeTests.txt) +endif() diff --git a/easy-jit/CMakeTests.txt b/easy-jit/CMakeTests.txt new file mode 100644 index 000000000000..52d568b0e4cc --- /dev/null +++ b/easy-jit/CMakeTests.txt @@ -0,0 +1,24 @@ +# Collect test dependencies that should be built before running lit +set(EASYJIT_TEST_DEPS + EasyJitPass + EasyJitRuntime +) + +# Generate lit.site.cfg files into the binary tree +configure_lit_site_cfg( + ${CMAKE_CURRENT_SOURCE_DIR}/tests/lit.cfg.in + ${CMAKE_CURRENT_BINARY_DIR}/tests/lit.cfg +) +configure_lit_site_cfg( + ${CMAKE_CURRENT_SOURCE_DIR}/tests/doc/lit.cfg.in + ${CMAKE_CURRENT_BINARY_DIR}/tests/doc/lit.cfg +) + +# Avoid picking up arbitrary compile flags from parents (optional but common pattern) +file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/compile_flags.txt) + +# Define the lit testsuite target; works for both standalone and monorepo builds +add_lit_testsuite(check-easy-jit "Running EasyJIT tests" + ${CMAKE_CURRENT_BINARY_DIR}/tests + DEPENDS ${EASYJIT_TEST_DEPS} +) diff --git a/easy-jit/LICENSE b/easy-jit/LICENSE new file mode 100644 index 000000000000..399eaccd54d0 --- /dev/null +++ b/easy-jit/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2018, Juan Manuel Martinez Caamaño and Serge Guelton and Quarkslab. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/easy-jit/README.md b/easy-jit/README.md new file mode 100644 index 000000000000..92bfa9f00d4c --- /dev/null +++ b/easy-jit/README.md @@ -0,0 +1,202 @@ +Easy::jit: A just-in-time compiler for C++ +========================================== + +About +----- + +Easy::jit is a _compiler-assisted_ library that enables simple Just-In-Time +code generation for C++ codes. + +### Talks + +* [Easy::jit at EuroLLVM'18](https://www.youtube.com/watch?v=sFxqI6Z_bhE) +* [Easy::jit at FOSDEM'18](https://www.youtube.com/watch?v=5_rydTiB32I) + +Building +-------- + +First, install clang and LLVM. + +```bash +apt install llvm-19-dev llvm-19-tools clang-19 +## or in OpenEuler +dnf install llvm-toolset-19 llvm-toolset-19-llvm-devel llvm-toolset-19-mlir-devel +``` + +Then, configure and compile the project. + +```bash +cmake -DLLVM_DIR=/usr/lib/llvm-19/cmake +cmake --build . +## or in OpenEuler +cmake -DLLVM_DIR=/opt/openEuler/llvm-toolset-19/root/usr/lib64/cmake +cmake --build . +``` + +To build the examples, install the [opencv](https://opencv.org/) library, +and add the flags ```-DEASY_JIT_EXAMPLE=1``` to the cmake command. + +To enable benchmarking, install the [google benchmark](https://github.com/google/benchmark) framework, +and add the flags ```-DEASY_JIT_BENCHMARK=1 -DBENCHMARK_DIR=``` to the cmake command. + +Everything is ready to go! + +### Docker + +If you want to give only a quick test to the project, everything is provided to use it with docker. +To do this, generate a Dockerfile from the current directory using the scripts in ```/misc/docker```, +then generate your docker instance. + +```bash +python3 /misc/docker/GenDockerfile.py /.travis.yml > Dockerfile +docker build -t easy/test -f Dockerfile +docker run -ti easy/test /bin/bash +``` + +Basic usage +----------- + +### Compiling my project with Easy::Jit + +Since the Easy::Jit library relies on assistance from the compiler, its +mandatory to load a compiler plugin in order to use it. +The flag ```-Xclang -load -Xclang /bin/EasyJitPass.so -Xclang -fpass-plugin=/bin/EasyJitPass.so``` +loads the plugin. + +The included headers require C++14 support, and remember to add the include directories! +Use ```--std=c++14 -I/cpplib/include```. + +Finaly, the binary must be linked against the Easy::Jit runtime library, using +```-L/bin -lEasyJitRuntime```. + +Putting all together we get the command bellow. + +```bash +clang++-19 --std=c++14 \ + -Xclang -load -Xclang /path/to/easy/jit/build/bin/bin/EasyJitPass.so \ + -I/cpplib/include \ + -L/bin -lEasyJitRuntime +``` + +### Using Easy::Jit inside my project + +Consider the code below from a software that applies image filters on a video stream. +In the following sections we are going to adapt it to use the Easy::jit library. +The function to optimize is ```kernel```, which applies a mask on the entire image. + +The mask, its dimensions and area do not change often, so specializing the function for +these parameters seems reasonable. +Moreover, the image dimensions and number of channels typically remain constant during +the entire execution; however, it is impossible to know their values as they depend on the stream. + +```cpp +static void kernel(const char* mask, unsigned mask_size, unsigned mask_area, + const unsigned char* in, unsigned char* out, + unsigned rows, unsigned cols, unsigned channels) { + unsigned mask_middle = (mask_size/2+1); + unsigned middle = (cols+1)*mask_middle; + + for(unsigned i = 0; i != rows-mask_size; ++i) { + for(unsigned j = 0; j != cols-mask_size; ++j) { + for(unsigned ch = 0; ch != channels; ++ch) { + + long out_val = 0; + for(unsigned ii = 0; ii != mask_size; ++ii) { + for(unsigned jj = 0; jj != mask_size; ++jj) { + out_val += mask[ii*mask_size+jj] * in[((i+ii)*cols+j+jj)*channels+ch]; + } + } + out[(i*cols+j+middle)*channels+ch] = out_val / mask_area; + } + } + } +} + +static void apply_filter(const char *mask, unsigned mask_size, unsigned mask_area, cv::Mat &image, cv::Mat *&out) { + kernel(mask, mask_size, mask_area, image.ptr(0,0), out->ptr(0,0), image.rows, image.cols, image.channels()); +} +``` + +The main header for the library is ```easy/jit.h```, where the only core function +of the library is exported. This function is called -- guess how? -- ```easy::jit```. +We add the corresponding include directive them in the top of the file. + +```cpp +#include +``` + +With the call to ```easy::jit```, we specialize the function and obtain a new +one taking only two parameters (the input and the output frame). + +```cpp +static void apply_filter(const char *mask, unsigned mask_size, unsigned mask_area, cv::Mat &image, cv::Mat *&out) { + using namespace std::placeholders; + + auto kernel_opt = easy::jit(kernel, mask, mask_size, mask_area, _1, _2, image.rows, image.cols, image.channels()); + kernel_opt(image.ptr(0,0), out->ptr(0,0)); +} +``` + +#### Deducing which functions to expose at runtime + +Easy::jit embeds the [LLVM bitcode](https://llvm.org/docs/LangRef.html) +representation of the functions to specialize at runtime in the binary code. +To perform this, the library requires access to the implementation of these +functions. +Easy::jit does an effort to deduce which functions are specialized at runtime, +still in many cases this is not possible. + +In this case, it's possible to use the ```EASY_JIT_EXPOSE``` macro, as shown in +the following code, + +```cpp +void EASY_JIT_EXPOSE kernel() { /* ... */ } +``` + +or using a regular expression during compilation. +The command bellow exports all functions whose name starts with "^kernel". + +```bash +clang++ ... -mllvm -easy-export="^kernel.*" ... +``` + +#### Caching + +In parallel to the ```easy/jit.h``` header, there is ```easy/code_cache.h``` which +provides a code cache to avoid recompilation of functions that already have been +generated. + +Bellow we show the code from previous section, but adapted to use a code cache. + +```cpp +#include +``` + +```cpp +static void apply_filter(const char *mask, unsigned mask_size, unsigned mask_area, cv::Mat &image, cv::Mat *&out) { + using namespace std::placeholders; + + static easy::Cache<> cache; + auto const &kernel_opt = cache.jit(kernel, mask, mask_size, mask_area, _1, _2, image.rows, image.cols, image.channels()); + kernel_opt(image.ptr(0,0), out->ptr(0,0)); +} +``` + +License +------- + +See file `LICENSE` at the top-level directory of this project. + +Thanks +------ + +Special thanks to Quarkslab for their support on working in personal projects. + +Warriors +-------- + +Serge Guelton (serge_sans_paille) + +Juan Manuel Martinez Caamaño (jmmartinez) + +Kavon Farvardin (kavon) author of [atJIT](https://github.com/kavon/atJIT) diff --git a/easy-jit/benchmark/CMakeLists.txt b/easy-jit/benchmark/CMakeLists.txt new file mode 100644 index 000000000000..55738109cf15 --- /dev/null +++ b/easy-jit/benchmark/CMakeLists.txt @@ -0,0 +1,31 @@ +if(EASY_JIT_BENCHMARK) + set(CMAKE_CXX_COMPILER ${LLVM_TOOLS_BINARY_DIR}/clang++) + set(CMAKE_CXX_FLAGS "") + set(EASYJIT_PLUGIN_FLAGS -Xclang -disable-O0-optnone -Xclang -load -Xclang ${EASY_JIT_PASS} -Xclang -fpass-plugin=${EASY_JIT_PASS}) + + if(EASY_JIT_STANDALONE_BUILD) + add_executable(easyjit-benchmark benchmark.cpp) + target_compile_options(easyjit-benchmark PRIVATE ${EASYJIT_PLUGIN_FLAGS}) + find_package(benchmark CONFIG REQUIRED) + link_directories(${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) + target_link_libraries (easyjit-benchmark benchmark::benchmark) + target_link_libraries (easyjit-benchmark EasyJitRuntime pthread) + target_link_options (easyjit-benchmark PRIVATE "-Wl,-rpath,$") + set_output_directory(easyjit-benchmark BINARY_DIR ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}) + else() + add_benchmark(easyjit-benchmark benchmark.cpp) + target_compile_options(easyjit-benchmark PRIVATE ${EASYJIT_PLUGIN_FLAGS}) + target_link_libraries (easyjit-benchmark PRIVATE EasyJitRuntime pthread) + target_link_options (easyjit-benchmark PRIVATE "-Wl,-rpath,$") + set_output_directory(easyjit-benchmark BINARY_DIR ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}) + endif() + + add_dependencies(easyjit-benchmark easy-jit-core) + + # Put the benchmark executable alongside libraries in monorepo builds. + if(NOT EASY_JIT_STANDALONE_BUILD) + set_target_properties(easyjit-benchmark PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${LLVM_LIBRARY_OUTPUT_INTDIR}") + endif() + +endif() diff --git a/easy-jit/benchmark/benchmark.cpp b/easy-jit/benchmark/benchmark.cpp new file mode 100644 index 000000000000..13be036360f8 --- /dev/null +++ b/easy-jit/benchmark/benchmark.cpp @@ -0,0 +1,154 @@ + +#include +#include +#include +#include +#include + +void __attribute__((noinline)) kernel(int n, int m, int * image, int const * mask, int* out) { + for(int i = 0; i < n - m; ++i) + for(int j = 0; j < n - m; ++j) + for(int k = 0; k < m; ++k) + for(int l = 0; l < m; ++l) + out[i * (n-m+1) + j] += image[(i+k) * n + j+l] * mask[k *m + l]; +} + +/* To sort array elemets */ + +int int_cmp(int a, int b) +{ + if (a > b) + return 1; + else + { + if (a == b) + return 0; + else + return -1; + } +} + +// https://github.com/ctasims/The-C-Programming-Language--Kernighan-and-Ritchie/blob/master/ch04-functions-and-program-structure/qsort.c +void __attribute__((noinline)) Qsort(int v[], int left, int right, int (*cmp)(int, int)) +{ + int i, last; + void swap(int v[], int i, int j); + + if (left >= right) // do nothing if array contains < 2 elems + return; + // move partition elem to v[0] + swap(v, left, (left + right)/2); + last = left; + + for (i = left+1; i <= right; i++) // partition + if (cmp(v[i], v[left])) + swap(v, ++last, i); + + swap(v, left, last); // restore partition elem + Qsort(v, left, last-1, cmp); + Qsort(v, last+1, right, cmp); +} + +/* swap: interchange v[i] and v[j] */ +void swap(int v[], int i, int j) +{ + int temp; + temp = v[i]; + v[i] = v[j]; + v[j] = temp; +} + +static const int mask[3][3] = {{1,2,3},{0,0,0},{3,2,1}}; + +static void BM_convolve(benchmark::State& state) { + using namespace std::placeholders; + + bool jit = state.range(1); + int n = state.range(0); + + std::vector image(n*n,0); + std::vector out((n-3)*(n-3),0); + + auto my_kernel = easy::jit(kernel, n, 3, _1, &mask[0][0], _2); + + benchmark::ClobberMemory(); + + for (auto _ : state) { + if(jit) { + my_kernel(image.data(), out.data()); + } else { + kernel(n, 3, image.data(), &mask[0][0], out.data()); + } + benchmark::ClobberMemory(); + } +} +BENCHMARK(BM_convolve)->Ranges({{16,1024}, {0,1}}); + +static void BM_convolve_compile_jit(benchmark::State& state) { + using namespace std::placeholders; + for (auto _ : state) { + auto my_kernel = easy::jit(kernel, 11, 3, _1, &mask[0][0], _2); + benchmark::ClobberMemory(); + } +} +BENCHMARK(BM_convolve_compile_jit); + +static void BM_convolve_cache_hit_jit(benchmark::State& state) { + using namespace std::placeholders; + static easy::Cache<> cache; + cache.jit(kernel, 11, 3, _1, &mask[0][0], _2); + benchmark::ClobberMemory(); + + for (auto _ : state) { + auto const &my_kernel = cache.jit(kernel, 11, 3, _1, &mask[0][0], _2); + benchmark::ClobberMemory(); + } +} +BENCHMARK(BM_convolve_cache_hit_jit); + +static void BM_qsort(benchmark::State& state) { + using namespace std::placeholders; + + bool jit = state.range(1); + int n = state.range(0); + + std::vector vec(n); + std::iota(vec.begin(), vec.end(), 0); + std::shuffle(vec.begin(), vec.end(), std::default_random_engine()); + + auto my_qsort = easy::jit(Qsort, _1, _2, _3, int_cmp); + benchmark::ClobberMemory(); + + for (auto _ : state) { + if(jit) { + my_qsort(vec.data(), 0, vec.size()-1); + } else { + Qsort(vec.data(), 0, vec.size()-1, int_cmp); + } + benchmark::ClobberMemory(); + } +} +BENCHMARK(BM_qsort)->Ranges({{16,1024}, {0,1}}); + +static void BM_qsort_compile_jit(benchmark::State& state) { + using namespace std::placeholders; + for (auto _ : state) { + auto my_qsort = easy::jit(Qsort, _1, _2, _3, int_cmp); + benchmark::ClobberMemory(); + } +} +BENCHMARK(BM_qsort_compile_jit); + +static void BM_qsort_cache_hit_jit(benchmark::State& state) { + using namespace std::placeholders; + static easy::Cache<> cache; + cache.jit(Qsort, _1, _2, _3, int_cmp); + benchmark::ClobberMemory(); + for (auto _ : state) { + auto const &my_qsort = cache.jit(Qsort, _1, _2, _3, int_cmp); + benchmark::ClobberMemory(); + } +} +BENCHMARK(BM_qsort_cache_hit_jit); + +BENCHMARK_MAIN(); diff --git a/easy-jit/cmake/CMakeLists.txt b/easy-jit/cmake/CMakeLists.txt new file mode 100644 index 000000000000..4ee8b898f2c8 --- /dev/null +++ b/easy-jit/cmake/CMakeLists.txt @@ -0,0 +1,3 @@ +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/EasyJitConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/EasyJitConfig.cmake @ONLY) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/EasyJitConfig.cmake + DESTINATION lib/cmake) diff --git a/easy-jit/cmake/EasyJitConfig.cmake.in b/easy-jit/cmake/EasyJitConfig.cmake.in new file mode 100644 index 000000000000..230a475aac20 --- /dev/null +++ b/easy-jit/cmake/EasyJitConfig.cmake.in @@ -0,0 +1,10 @@ +# Try to find the easy::jit library, headers and compiler plugin. +# EasyJit_INCLUDE_DIRS - the easy::jit include directory +# EasyJit_LIBRARY_DIRS - library directory needed to use easy::jit +# EasyJit_LIBRARY - library needed to use easy::jit +# EasyJit_PLUGIN - compiler plugin + +set(EasyJit_INCLUDE_DIRS "@CMAKE_INSTALL_PREFIX@/include") +set(EasyJit_LIBRARY_DIRS "@CMAKE_INSTALL_PREFIX@/lib") +set(EasyJit_LIBRARY "EasyJitRuntime") +set(EasyJit_PLUGIN "@CMAKE_INSTALL_PREFIX@/lib/EasyJitPass@CMAKE_SHARED_LIBRARY_SUFFIX@") diff --git a/easy-jit/doc/CMakeLists.txt b/easy-jit/doc/CMakeLists.txt new file mode 100644 index 000000000000..303a069fdcfc --- /dev/null +++ b/easy-jit/doc/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(readme) diff --git a/easy-jit/doc/readme/CMakeLists.txt b/easy-jit/doc/readme/CMakeLists.txt new file mode 100644 index 000000000000..e37f961fec03 --- /dev/null +++ b/easy-jit/doc/readme/CMakeLists.txt @@ -0,0 +1,19 @@ +option(EASY_JIT_EXAMPLE "Build Examples" OFF) + +if(EASY_JIT_EXAMPLE) + find_package(OpenCV REQUIRED) + + set(CMAKE_CXX_COMPILER ${LLVM_TOOLS_BINARY_DIR}/clang++) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Xclang -disable-O0-optnone -Xclang -load -Xclang ${EASY_JIT_PASS} -Xclang -fpass-plugin=${EASY_JIT_PASS}") + + add_executable(easyjit-example camfilter.cpp) + add_dependencies(easyjit-example easy-jit-core) + + include_directories(${OpenCV_INCLUDE_DIRS}) + target_link_libraries(easyjit-example ${OpenCV_LIBS}) + + link_directories(${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) + + target_link_libraries (easyjit-example ${Benchmark_LIBRARIES}) + target_link_libraries (easyjit-example EasyJitRuntime pthread) +endif() diff --git a/easy-jit/doc/readme/README.md.in b/easy-jit/doc/readme/README.md.in new file mode 100644 index 000000000000..a169a01d57a5 --- /dev/null +++ b/easy-jit/doc/readme/README.md.in @@ -0,0 +1,167 @@ +Easy::jit: A just-in-time compiler for C++ +========================================== + +About +----- + +Easy::jit is a _compiler-assisted_ library that enables simple Just-In-Time +code generation for C++ codes. + +### Talks + +* [Easy::jit at EuroLLVM'18](https://www.youtube.com/watch?v=sFxqI6Z_bhE) +* [Easy::jit at FOSDEM'18](https://www.youtube.com/watch?v=5_rydTiB32I) + +Building +-------- + +First, install clang and LLVM. + +```bash +apt install llvm-19-dev llvm-19-tools clang-19 +## or in OpenEuler +dnf install llvm-toolset-19 llvm-toolset-19-llvm-devel llvm-toolset-19-mlir-devel +``` + +Then, configure and compile the project. + +```bash +cmake -DLLVM_DIR=/usr/lib/llvm-19/cmake +cmake --build . +## or in OpenEuler +cmake -DLLVM_DIR=/opt/openEuler/llvm-toolset-19/root/usr/lib64/cmake +cmake --build . +``` + +To build the examples, install the [opencv](https://opencv.org/) library, +and add the flags ```-DEASY_JIT_EXAMPLE=1``` to the cmake command. + +To enable benchmarking, install the [google benchmark](https://github.com/google/benchmark) framework, +and add the flags ```-DEASY_JIT_BENCHMARK=1 -DBENCHMARK_DIR=``` to the cmake command. + +Everything is ready to go! + +### Docker + +If you want to give only a quick test to the project, everything is provided to use it with docker. +To do this, generate a Dockerfile from the current directory using the scripts in ```/misc/docker```, +then generate your docker instance. + +```bash +python3 /misc/docker/GenDockerfile.py /.travis.yml > Dockerfile +docker build -t easy/test -f Dockerfile +docker run -ti easy/test /bin/bash +``` + +Basic usage +----------- + +### Compiling my project with Easy::Jit + +Since the Easy::Jit library relies on assistance from the compiler, its +mandatory to load a compiler plugin in order to use it. +The flag ```-Xclang -load -Xclang /bin/EasyJitPass.so -Xclang -fpass-plugin=/bin/EasyJitPass.so``` +loads the plugin. + +The included headers require C++14 support, and remember to add the include directories! +Use ```--std=c++14 -I/cpplib/include```. + +Finaly, the binary must be linked against the Easy::Jit runtime library, using +```-L/bin -lEasyJitRuntime```. + +Putting all together we get the command bellow. + +```bash +clang++-19 --std=c++14 \ + -Xclang -load -Xclang /path/to/easy/jit/build/bin/bin/EasyJitPass.so \ + -I/cpplib/include \ + -L/bin -lEasyJitRuntime +``` + +### Using Easy::Jit inside my project + +Consider the code below from a software that applies image filters on a video stream. +In the following sections we are going to adapt it to use the Easy::jit library. +The function to optimize is ```kernel```, which applies a mask on the entire image. + +The mask, its dimensions and area do not change often, so specializing the function for +these parameters seems reasonable. +Moreover, the image dimensions and number of channels typically remain constant during +the entire execution; however, it is impossible to know their values as they depend on the stream. + +```cpp + +``` + +The main header for the library is ```easy/jit.h```, where the only core function +of the library is exported. This function is called -- guess how? -- ```easy::jit```. +We add the corresponding include directive them in the top of the file. + +```cpp + +``` + +With the call to ```easy::jit```, we specialize the function and obtain a new +one taking only two parameters (the input and the output frame). + +```cpp + +``` + +#### Deducing which functions to expose at runtime + +Easy::jit embeds the [LLVM bitcode](https://llvm.org/docs/LangRef.html) +representation of the functions to specialize at runtime in the binary code. +To perform this, the library requires access to the implementation of these +functions. +Easy::jit does an effort to deduce which functions are specialized at runtime, +still in many cases this is not possible. + +In this case, it's possible to use the ```EASY_JIT_EXPOSE``` macro, as shown in +the following code, + +```cpp +void EASY_JIT_EXPOSE kernel() { /* ... */ } +``` + +or using a regular expression during compilation. +The command bellow exports all functions whose name starts with "^kernel". + +```bash +clang++ ... -mllvm -easy-export="^kernel.*" ... +``` + +#### Caching + +In parallel to the ```easy/jit.h``` header, there is ```easy/code_cache.h``` which +provides a code cache to avoid recompilation of functions that already have been +generated. + +Bellow we show the code from previous section, but adapted to use a code cache. + +```cpp + +``` + +```cpp + +``` + +License +------- + +See file `LICENSE` at the top-level directory of this project. + +Thanks +------ + +Special thanks to Quarkslab for their support on working in personal projects. + +Warriors +-------- + +Serge Guelton (serge_sans_paille) + +Juan Manuel Martinez Caamaño (jmmartinez) + +Kavon Farvardin (kavon) author of [atJIT](https://github.com/kavon/atJIT) diff --git a/easy-jit/doc/readme/camfilter.cpp b/easy-jit/doc/readme/camfilter.cpp new file mode 100644 index 000000000000..09c47920be40 --- /dev/null +++ b/easy-jit/doc/readme/camfilter.cpp @@ -0,0 +1,244 @@ +// REQUIRES: example +// test that it compiles, links and loads correctly. +// RUN: %bin/easyjit-example 1 1 2 3 4 s 1 2 3 4 s 1 2 3 4 q + +#include +#include +#include +#include +#include +#include + +// INLINE FROM HERE #INCLUDE_EASY# +#include +// TO HERE #INCLUDE_EASY# + +// INLINE FROM HERE #INCLUDE_EASY_CACHE# +#include +// TO HERE #INCLUDE_EASY_CACHE# + +struct timeval; + +static double get_fps() { + static struct timeval before; + struct timeval now; + + gettimeofday(&now, nullptr); + + long secs = now.tv_sec - before.tv_sec; + long usec = now.tv_usec - before.tv_usec; + double diff = secs + ((double)usec)/1000000.0; + before = now; + + return 1.0/diff; +} + +namespace original { +// INLINE FROM HERE #ORIGINAL# +static void kernel(const char* mask, unsigned mask_size, unsigned mask_area, + const unsigned char* in, unsigned char* out, + unsigned rows, unsigned cols, unsigned channels) { + unsigned mask_middle = (mask_size/2+1); + unsigned middle = (cols+1)*mask_middle; + + for(unsigned i = 0; i != rows-mask_size; ++i) { + for(unsigned j = 0; j != cols-mask_size; ++j) { + for(unsigned ch = 0; ch != channels; ++ch) { + + long out_val = 0; + for(unsigned ii = 0; ii != mask_size; ++ii) { + for(unsigned jj = 0; jj != mask_size; ++jj) { + out_val += mask[ii*mask_size+jj] * in[((i+ii)*cols+j+jj)*channels+ch]; + } + } + out[(i*cols+j+middle)*channels+ch] = out_val / mask_area; + } + } + } +} + +static void apply_filter(const char *mask, unsigned mask_size, unsigned mask_area, cv::Mat &image, cv::Mat *&out) { + kernel(mask, mask_size, mask_area, image.ptr(0,0), out->ptr(0,0), image.rows, image.cols, image.channels()); +} +// TO HERE #ORIGINAL# +} + +namespace jit { + using original::kernel; +// INLINE FROM HERE #EASY# +static void apply_filter(const char *mask, unsigned mask_size, unsigned mask_area, cv::Mat &image, cv::Mat *&out) { + using namespace std::placeholders; + + auto kernel_opt = easy::jit(kernel, mask, mask_size, mask_area, _1, _2, image.rows, image.cols, image.channels()); + kernel_opt(image.ptr(0,0), out->ptr(0,0)); +} +// TO HERE #EASY# +} + +namespace cache { + using original::kernel; +// INLINE FROM HERE #EASY_CACHE# +static void apply_filter(const char *mask, unsigned mask_size, unsigned mask_area, cv::Mat &image, cv::Mat *&out) { + using namespace std::placeholders; + + static easy::Cache<> cache; + auto const &kernel_opt = cache.jit(kernel, mask, mask_size, mask_area, _1, _2, image.rows, image.cols, image.channels()); + kernel_opt(image.ptr(0,0), out->ptr(0,0)); +} +// TO HERE #EASY_CACHE# +} + +static const char mask_no_filter[1] = {1}; +static const char mask_gauss_3[9] = {1,1,1,1,1,1,1,1,1}; +static const char mask_gauss_5[25] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; +static const char mask_gauss_7[49] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; + +static const char* masks[] = { + mask_no_filter, + mask_gauss_3, + mask_gauss_5, + mask_gauss_7 +}; + +static unsigned mask_size[] = { + 1, + 3, + 5, + 7 +}; + +static unsigned mask_area[] = { + 1, + 9, + 25, + 49 +}; + +static void (*apply_filter)(const char*, unsigned, unsigned, cv::Mat &, cv::Mat *&) = original::apply_filter; + +static char get_keystroke(bool test, char** argv, int argc) { + if(!test) + return cv::waitKey(1); + + // read the first character of each argument and use it as the key stroke + static int key_count = 2; + if(key_count >= argc) + return 'q'; + + char key = argv[key_count][0]; + + key_count++; + return key; +} + +static bool get_next_frame(bool test, cv::Mat &frame) { + if(test) { + // return a black frame + frame = cv::Mat(cv::Size(640, 480), CV_8UC3, cv::Scalar(0)); + return true; + } else { + // capture from the video camara + static cv::VideoCapture video(0); + + if(!video.isOpened()) { + std::cerr << "cannot open camara.\n"; + return false; + } + + video.read(frame); + return true; + } +} + +int main(int argc, char** argv) { + bool test = 0; + if(argc > 2) + test = atoi(argv[1]); + + std::cerr << "\npress 1, 2, 3, 4 to change the filter.\n" + "s to switch the implementation, from original to easy-jit(no cache), and to easy-jit(cache).\n" + "q to exit.\n\n"; + + int mask_no = 0; + + cv::Mat Frame; + static cv::Mat Output; + cv::Mat *Out = nullptr; + + unsigned time = 0; + std::stringstream fps_message; + + double fps_history[4]; + + while (true) { + if(!get_next_frame(test, Frame)) + return -1; + + // allocate the output frame + if(!Out) { + Output = Frame.clone(); + Out = &Output; + } + + get_fps(); + + // apply the filter + apply_filter(masks[mask_no], mask_size[mask_no], mask_area[mask_no], Frame, Out); + + double fps = get_fps(); + fps_history[time%4] = fps; + + if(time % 4 == 0) { + double fps_avg = std::accumulate(std::begin(fps_history), std::end(fps_history), 0.0)/4.0; + fps_message.str(""); + fps_message << "fps: " << fps_avg; + } + + // show the fps, updated every 4 iterations + cv::putText(*Out, fps_message.str().c_str(), cv::Point(30,30), + cv::FONT_HERSHEY_COMPLEX_SMALL, 0.8, + cv::Scalar(200,200,250), 1, cv::LINE_AA); + + if(!test) { + cv::imshow("camera", *Out); + } + ++time; + + // user input + char key = get_keystroke(test, argv, argc); + if (key < 0) + continue; + + switch(key) { + case 'q': + return 0; + case 's': + { + if(apply_filter == original::apply_filter) { + std::cerr << "using easy::jit (no-cache) implementation\n"; + apply_filter = jit::apply_filter; + } else if (apply_filter == jit::apply_filter) { + std::cerr << "using easy::jit (cache) implementation\n"; + apply_filter = cache::apply_filter; + } else { + std::cerr << "using original implementation\n"; + apply_filter = original::apply_filter; + } + break; + } + case '1': + case '2': + case '3': + case '4': + { + mask_no = key-'1'; + std::cerr << "change mask to " << mask_no+1 << "!\n"; + break; + } + default: + std::cerr << "unknown stroke " << key << "\n"; + } + } + + return 0; +} diff --git a/easy-jit/doc/readme/readme_is_up-to-date.test b/easy-jit/doc/readme/readme_is_up-to-date.test new file mode 100644 index 000000000000..ffcd6bb675c9 --- /dev/null +++ b/easy-jit/doc/readme/readme_is_up-to-date.test @@ -0,0 +1,4 @@ +// RUN: cd %S +// RUN: bash update_doc.sh > %t.new +// RUN: cp %S/../../README.md %t.old +// RUN: diff %t.new %t.old diff --git a/easy-jit/doc/readme/update_doc.sh b/easy-jit/doc/readme/update_doc.sh new file mode 100644 index 000000000000..6ae92cd2636f --- /dev/null +++ b/easy-jit/doc/readme/update_doc.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +pushd $DIR >> /dev/null + +easy_jit_dir=../../ +export PYTHONIOENCODING="utf-8" + +cat README.md.in | \ + python3 ${easy_jit_dir}/misc/doc/python.py | \ + python3 ${easy_jit_dir}/misc/doc/include.py diff --git a/easy-jit/doc/slides/cppcon'18.pdf b/easy-jit/doc/slides/cppcon'18.pdf new file mode 100644 index 0000000000000000000000000000000000000000..dcf515e34141acee1c9cec2f1cab27b58cf18ad6 GIT binary patch literal 464261 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�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

yBz=6lK68j`#S~=fc4)~!~Dvi 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

$H{+4Rzaa?(lyyPdx!C7njE{aFFiC0}d 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

yz|jqS*|~ob?Ot$ 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 SdZxm^55BDT{{HR9_qV?%g1-R( literal 0 HcmV?d00001 diff --git a/easy-jit/include/CMakeLists.txt b/easy-jit/include/CMakeLists.txt new file mode 100644 index 000000000000..ad252203ea38 --- /dev/null +++ b/easy-jit/include/CMakeLists.txt @@ -0,0 +1,2 @@ +install(DIRECTORY easy + DESTINATION include FILES_MATCHING PATTERN "*.h") diff --git a/easy-jit/include/easy/attributes.h b/easy-jit/include/easy/attributes.h new file mode 100644 index 000000000000..469d595ea541 --- /dev/null +++ b/easy-jit/include/easy/attributes.h @@ -0,0 +1,19 @@ +#ifndef NOINLINE +#define NOINLINE + +#define CI_SECTION "segment,compiler-if" +#define JIT_SECTION "segment,easy-jit" +#define LAYOUT_SECTION "segment,layout" + +// mark functions in the easy::jit interface as no inline. +// it's easier for the pass to find the original functions to be jitted. +#define EASY_JIT_COMPILER_INTERFACE \ + __attribute__((noinline)) __attribute__((section(CI_SECTION))) + +#define EASY_JIT_EXPOSE \ + __attribute__((section(JIT_SECTION))) + +#define EASY_JIT_LAYOUT\ + __attribute__((section(LAYOUT_SECTION))) + +#endif // NOINLINE diff --git a/easy-jit/include/easy/code_cache.h b/easy-jit/include/easy/code_cache.h new file mode 100644 index 000000000000..ba1b8d6f2adb --- /dev/null +++ b/easy-jit/include/easy/code_cache.h @@ -0,0 +1,87 @@ +#ifndef CACHE +#define CACHE + +#include +#include + +namespace easy { + +namespace { +using AutoKey = std::pair; + +template +class CacheBase { + + public: + + using Key = KeyTy; + + protected: + + std::unordered_map Cache_; + using iterator = typename std::unordered_map::iterator; + + template + auto const & compile_if_not_in_cache(std::pair &CacheEntry, T &&Fun, Args&& ... args) { + using wrapper_ty = decltype(easy::jit(std::forward(Fun), std::forward(args)...)); + + FunctionWrapperBase &FWB = CacheEntry.first->second; + if(CacheEntry.second) { + auto FW = easy::jit(std::forward(Fun), std::forward(args)...); + FWB = std::move(FW); + } + return reinterpret_cast(FWB); + } +}; +} + +template +class Cache : public CacheBase { + public: + + template + auto const& EASY_JIT_COMPILER_INTERFACE jit(Key const &K, T &&Fun, Args&& ... args) { + auto CacheEntry = CacheBase::Cache_.emplace(K, FunctionWrapperBase()); + return CacheBase::compile_if_not_in_cache(CacheEntry, std::forward(Fun), std::forward(args)...); + } + + template + auto const& EASY_JIT_COMPILER_INTERFACE jit(Key &&K, T &&Fun, Args&& ... args) { + auto CacheEntry = CacheBase::Cache_.emplace(K, FunctionWrapperBase()); + return CacheBase::compile_if_not_in_cache(CacheEntry, std::forward(Fun), std::forward(args)...); + } + + bool has(Key const &K) const { + auto const CacheEntry = CacheBase::Cache_.find(K); + return CacheEntry != CacheBase::Cache_.end(); + } +}; + + +template<> +class Cache : public CacheBase { + public: + + template + auto const& EASY_JIT_COMPILER_INTERFACE jit(T &&Fun, Args&& ... args) { + void* FunPtr = reinterpret_cast(meta::get_as_pointer(Fun)); + auto CacheEntry = + CacheBase::Cache_.emplace( + Key(FunPtr, get_context_for(std::forward(args)...)), + FunctionWrapperBase()); + return CacheBase::compile_if_not_in_cache(CacheEntry, std::forward(Fun), std::forward(args)...); + } + + template + bool has(T &&Fun, Args&& ... args) const { + void* FunPtr = reinterpret_cast(meta::get_as_pointer(Fun)); + auto const CacheEntry = + CacheBase::Cache_.find(Key(FunPtr, + get_context_for(std::forward(args)...))); + return CacheEntry != Cache_.end(); + } +}; + +} + +#endif // CACHE diff --git a/easy-jit/include/easy/exceptions.h b/easy-jit/include/easy/exceptions.h new file mode 100644 index 000000000000..2fad51aab34f --- /dev/null +++ b/easy-jit/include/easy/exceptions.h @@ -0,0 +1,24 @@ +#ifndef EXCEPTIONS +#define EXCEPTIONS + +#include +#include +#include + +namespace easy { + struct exception + : public std::runtime_error { + exception(std::string const &Message, std::string const &Reason) + : std::runtime_error(Message + Reason) {} + virtual ~exception() = default; + }; +} + +#define DefineEasyException(Exception, Message) \ + struct Exception : public easy::exception { \ + Exception() : easy::exception(Message, "") {} \ + Exception(std::string const &Reason) : easy::exception(Message, Reason) {} \ + virtual ~Exception() = default; \ + } + +#endif diff --git a/easy-jit/include/easy/function_wrapper.h b/easy-jit/include/easy/function_wrapper.h new file mode 100644 index 000000000000..68e4bf475e36 --- /dev/null +++ b/easy-jit/include/easy/function_wrapper.h @@ -0,0 +1,132 @@ +#ifndef FUNCTION_WRAPPER +#define FUNCTION_WRAPPER + +#include +#include +#include +#include + +#ifndef _MSC_VER +#define __cdecl +#endif + +namespace easy { + +class FunctionWrapperBase { + + protected: + std::unique_ptr Fun_; + + public: + // null object + FunctionWrapperBase() = default; + + // default constructor + FunctionWrapperBase(std::unique_ptr F) + : Fun_(std::move(F)) {} + + // steal the implementation + FunctionWrapperBase(FunctionWrapperBase &&FW) + : Fun_(std::move(FW.Fun_)) {} + FunctionWrapperBase& operator=(FunctionWrapperBase &&FW) { + Fun_ = std::move(FW.Fun_); + return *this; + } + + Function const& getFunction() const { + return *Fun_; + } + + void* getRawPointer() const { + return getFunction().getRawPointer(); + } + + void serialize(std::ostream& os) const { + getFunction().serialize(os); + } + + static FunctionWrapperBase deserialize(std::istream& is) { + std::unique_ptr Fun = Function::deserialize(is); + return FunctionWrapperBase{std::move(Fun)}; + } +}; + +template +class FunctionWrapper; + +template +class FunctionWrapper : + public FunctionWrapperBase { + public: + FunctionWrapper(std::unique_ptr F) + : FunctionWrapperBase(std::move(F)) {} + + template + Ret operator()(Args&& ... args) const { + return getFunctionPointer()(std::forward(args)...); + } + + auto getFunctionPointer() const { + return reinterpret_cast(getRawPointer()); + } + + static FunctionWrapper deserialize(std::istream& is) { + std::unique_ptr Fun = Function::deserialize(is); + return FunctionWrapper{std::move(Fun)}; + } +}; + +// specialization for void return +template +class FunctionWrapper : + public FunctionWrapperBase { + public: + FunctionWrapper(std::unique_ptr F) + : FunctionWrapperBase(std::move(F)) {} + + template + void operator()(Args&& ... args) const { + return getFunctionPointer()(std::forward(args)...); + } + + auto getFunctionPointer() const { + return ((void(__cdecl *)(Params...))getRawPointer()); + } + + static FunctionWrapper deserialize(std::istream& is) { + std::unique_ptr Fun = Function::deserialize(is); + return FunctionWrapper{std::move(Fun)}; + } +}; + +template +struct is_function_wrapper { + + template + struct is_function_wrapper_helper { + static constexpr bool value = false; + }; + + template + struct is_function_wrapper_helper> { + static constexpr bool value = true; + using return_type = Ret; + using params = meta::type_list; + }; + + using helper = is_function_wrapper_helper>; + + static constexpr bool value = helper::value; +}; + +template +struct is_function_wrapper> { + static constexpr bool value = true; + using return_type = Ret; + using params = meta::type_list; +}; + + +} + +#endif diff --git a/easy-jit/include/easy/jit.h b/easy-jit/include/easy/jit.h new file mode 100644 index 000000000000..f9e48908618b --- /dev/null +++ b/easy-jit/include/easy/jit.h @@ -0,0 +1,68 @@ +#ifndef EASY +#define EASY + +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace easy { + +namespace { +template +FunctionWrapper +WrapFunction(std::unique_ptr F, meta::type_list) { + return FunctionWrapper(std::move(F)); +} + +template +auto jit_with_context(easy::Context const &C, T &&Fun) { + + auto* FunPtr = meta::get_as_pointer(Fun); + using FunOriginalTy = std::remove_pointer_t>; + + using new_type_traits = meta::new_function_traits>; + using new_return_type = typename new_type_traits::return_type; + using new_parameter_types = typename new_type_traits::parameter_list; + + auto CompiledFunction = + Function::Compile(reinterpret_cast(FunPtr), C); + + auto Wrapper = + WrapFunction(std::move(CompiledFunction), + typename new_parameter_types::template push_front ()); + return Wrapper; +} + +template +easy::Context get_context_for(Args&& ... args) { + using FunOriginalTy = std::remove_pointer_t>; + static_assert(std::is_function::value, + "easy::jit: supports only on functions and function pointers"); + + using parameter_list = typename meta::function_traits::parameter_list; + + static_assert(parameter_list::size <= sizeof...(Args), + "easy::jit: not providing enough argument to actual call"); + + easy::Context C; + easy::set_parameters(parameter_list(), C, + std::forward(args)...); + return C; +} +} + +template +auto EASY_JIT_COMPILER_INTERFACE jit(T &&Fun, Args&& ... args) { + auto C = get_context_for(std::forward(args)...); + return jit_with_context(C, std::forward(Fun)); +} + +} + +#endif diff --git a/easy-jit/include/easy/meta.h b/easy-jit/include/easy/meta.h new file mode 100644 index 000000000000..c095fa87ae97 --- /dev/null +++ b/easy-jit/include/easy/meta.h @@ -0,0 +1,211 @@ +#ifndef META +#define META + +#include +#include +#include +#include + +namespace easy { +namespace meta { + +template +struct type_list { + + template + using push_front = struct type_list; + template + using push_back = struct type_list; + template + using remove = type_list<>; + template + static constexpr bool has = false; + + // undefined + template + using at = void; + template + using set = meta::type_list<>; + + static constexpr size_t size = 0; + static constexpr bool empty = true; +}; + +template +struct type_list { + using head = Head; + using tail = struct type_list; + + template + using push_front = struct type_list; + template + using push_back = struct type_list; + template + using at = std::conditional_t>; + + template + using set = std::conditional_t, + typename tail::template set::template push_front>; + + template + using remove = std::conditional_t::value, + typename tail::template remove, + typename tail::template remove::template push_front>; + template + static constexpr bool has = std::is_same::value || tail:: template has; + + static constexpr size_t size = 1+tail::size; + static constexpr bool empty = false; +}; + +template +struct init_list { + + template + struct helper { + using type = typename helper::type::template push_front; + }; + + template + struct helper<0,TT> { + using type = meta::type_list<>; + }; + + using type = typename helper::type; +}; + +template +T* get_as_pointer(T &&A) { return &A; } + +template +T* get_as_pointer(T* A) { return A; } + + +namespace { + +template +using is_ph = std::is_placeholder>; + +template +struct discard_options { + + template + struct helper { + using type = meta::type_list<>; + }; + + template + struct helper { + using head = typename AL::head; + using tail = typename AL::tail; + static bool constexpr is_opt = + options::is_option>::value; + using recursive = typename helper::type; + using type = std::conditional_t>; + }; + + using type = typename helper::type; +}; + +template +struct max_placeholder { + + template + struct helper { + static constexpr size_t max = Max; + }; + + template + struct helper { + using head = typename AL::head; + using tail = typename AL::tail; + static constexpr size_t max = helper(is_ph::value, Max)>::max; + }; + + static constexpr size_t max = helper::max; +}; + +template +struct map_placeholder_to_type { + + template + struct helper { + static_assert(Seen::size == N, "Seen::size != N"); + static_assert(Result::size == N, "Result::size != N"); + static_assert(!Result::template has, "Void cannot appear in the resulting type"); + using type = Result; + }; + + template + struct helper{ + using al_head = typename AL::head; + using al_tail = typename AL::tail; + + static bool constexpr parse_placeholder = is_ph::value && !Seen::template has; + static size_t constexpr result_idx = parse_placeholder?is_ph::value-1:0; + static size_t constexpr arg_idx = PL::size - AL::size; + using pl_at_idx = typename PL::template at; + + // for + // foo(int, bool, float) and specialization foo(int(4), _2, _1) + // [int,bool,float] [int,_2,_1] [void,void] [] 2 + // [int,bool,float] [_2,_1] [void,void] [] 2 + // [int,bool,float] [_1] [void,bool] [_2] 2 + // [int,bool,float] [] [float,bool] [_2,_1] 2 + // yields new foo'(float _1, bool _2) = foo(int(4), _2, _1); + + static_assert(PL::size >= AL::size, "easy::jit: More parameters than arguments specified"); + static_assert(result_idx < Result::size, "easy::jit: Cannot have a placeholder outside the maximum"); + using new_result = std::conditional_t, Result>; + using new_seen = std::conditional_t, Seen>; + + using type = typename helper::type; + }; + template + struct helper, Result, Seen, N, false>{ + static_assert(N==-1 /*just to make this context dependent*/, "easy::jit: Invalid bind, placeholder cannot be bound to a formal argument"); + }; + + using default_param = void; + static constexpr size_t N = max_placeholder::max; + using type = typename helper::type, meta::type_list<>, N, N == 0>::type; +}; + +template +struct get_new_param_list { + using type = typename map_placeholder_to_type::type; +}; + +template +Ret get_return_type(Ret(*)(Args...)); + +template +type_list get_parameter_list(Ret(*)(Args...)); + +} + +template +struct function_traits { + static_assert(std::is_function::value, "function expected."); + using ptr_ty = std::decay_t; + using return_type = decltype(get_return_type(std::declval())); + using parameter_list = decltype(get_parameter_list(std::declval())); +}; + +template +struct new_function_traits { + using OriginalTraits = function_traits; + using return_type = typename OriginalTraits::return_type; + using clean_arg_list = typename discard_options::type; + using parameter_list = typename get_new_param_list::type; +}; + +} +} + + + +#endif diff --git a/easy-jit/include/easy/options.h b/easy-jit/include/easy/options.h new file mode 100644 index 000000000000..f01648a5562f --- /dev/null +++ b/easy-jit/include/easy/options.h @@ -0,0 +1,50 @@ +#ifndef OPTIONS +#define OPTIONS + +#include + +#define EASY_NEW_OPTION_STRUCT(Name) \ + struct Name; \ + template<> struct is_option { \ + static constexpr bool value = true; }; \ + struct Name + +#define EASY_HANDLE_OPTION_STRUCT(Name, Ctx) \ + void handle(easy::Context &Ctx) const + + +namespace easy { +namespace options{ + + template + struct is_option { + static constexpr bool value = false; + }; + + EASY_NEW_OPTION_STRUCT(opt_level) + : public std::pair { + + opt_level(unsigned OptLevel, unsigned OptSize) + : std::pair(OptLevel,OptSize) {} + + EASY_HANDLE_OPTION_STRUCT(opt_level, C) { + C.setOptLevel(first, second); + } + }; + + // option used for writing the ir to a file, useful for debugging + EASY_NEW_OPTION_STRUCT(dump_ir) { + dump_ir(std::string const &file) + : file_(file) {} + + EASY_HANDLE_OPTION_STRUCT(dump_ir, C) { + C.setDebugFile(file_); + } + + private: + std::string file_; + }; +} +} + +#endif // OPTIONS diff --git a/easy-jit/include/easy/param.h b/easy-jit/include/easy/param.h new file mode 100644 index 000000000000..1ea63de6a6c6 --- /dev/null +++ b/easy-jit/include/easy/param.h @@ -0,0 +1,162 @@ +#ifndef PARAM +#define PARAM + +#include +#include +#include +#include +#include + +namespace easy { + +namespace layout { + + // the address of this function is used as id :) + template + char* serialize_arg(Arg a); + + template + layout_id __attribute__((noinline)) EASY_JIT_LAYOUT get_layout() { + // horrible hack to get the ptr of get_struct_layout_internal as void* + union { + void* as_void_ptr; + decltype(serialize_arg)* as_fun_ptr; + } dummy; + dummy.as_fun_ptr = serialize_arg; + return dummy.as_void_ptr; + } + + template + void set_layout(easy::Context &C) { + C.setArgumentLayout(get_layout()); + } +} + +namespace { + +// special types +template +struct set_parameter_helper { + + template + struct function_wrapper_specialization_is_possible { + + template + static std::true_type can_assign_fun_pointer(std::remove_pointer_t); + + template + static std::false_type can_assign_fun_pointer (...); + + using type = decltype(can_assign_fun_pointer( + *std::declval().getFunctionPointer())); + + static constexpr bool value { type::value }; + }; + + template + using _if = std::enable_if_t; + + template + static void set_param(Context &C, + _if<(bool)std::is_placeholder>::value, Arg>) { + C.setParameterIndex(std::is_placeholder>::value-1); + } + + template + static void set_param(Context &C, + _if::value, Arg> &&arg) { + static_assert(function_wrapper_specialization_is_possible::value, + "easy::jit composition is not possible. Incompatible types."); + C.setParameterModule(arg.getFunction()); + } +}; + +template<> +struct set_parameter_helper { + + template + using _if = std::enable_if_t; + + template + static void set_param(Context &C, + _if::value, Arg> &&arg) { + Param arg_as_param = arg; + C.setParameterInt(arg_as_param); + } + + template + static void set_param(Context &C, + _if::value, Arg> &&arg) { + Param arg_as_param = arg; + C.setParameterFloat(arg_as_param); + } + + template + static void set_param(Context &C, + _if::value, Arg> &&arg) { + Param arg_as_param = arg; + C.setParameterTypedPointer(arg_as_param); + } + + template + static void set_param(Context &C, + _if::value, Arg> &&arg) { + C.setParameterTypedPointer(std::addressof(arg)); + } + + template + static void set_param(Context &C, + _if::value, Arg> &&arg) { + C.setParameterStruct(layout::serialize_arg(arg)); + } +}; + +template +struct set_parameter { + + static constexpr bool is_ph = std::is_placeholder>::value; + static constexpr bool is_fw = easy::is_function_wrapper::value; + static constexpr bool is_special = is_ph || is_fw; + + using help = set_parameter_helper; +}; + +} + +template +void set_options(Context &, NoOptions&& ...) { + static_assert(meta::type_list::empty, "Remaining options to be processed!"); +} + +template +void set_options(Context &C, Option0&& Opt, Options&& ... Opts) { + using OptTy = std::decay_t; + OptTy& OptRef = std::ref(Opt); + static_assert(options::is_option::value, "An easy::jit option is expected"); + + OptRef.handle(C); + set_options(C, std::forward(Opts)...); +} + +template +std::enable_if_t +set_parameters(ParameterList, + Context& C, Options&& ... opts) { + set_options(C, std::forward(opts)...); +} + +template +std::enable_if_t +set_parameters(ParameterList, + Context &C, Arg0 &&arg0, Args&& ... args) { + using Param0 = typename ParameterList::head; + using ParametersTail = typename ParameterList::tail; + + layout::set_layout(C); + set_parameter::help::template set_param(C, std::forward(arg0)); + set_parameters(ParametersTail(), C, std::forward(args)...); +} + +} + +#endif // PARAM diff --git a/easy-jit/include/easy/runtime/BitcodeTracker.h b/easy-jit/include/easy/runtime/BitcodeTracker.h new file mode 100644 index 000000000000..30804a910c8d --- /dev/null +++ b/easy-jit/include/easy/runtime/BitcodeTracker.h @@ -0,0 +1,71 @@ +#ifndef BITCODETRACKER +#define BITCODETRACKER + +#include +#include +#include + +#include + +#include +#include + +namespace easy { + +struct GlobalMapping { + const char* Name; + void* Address; +}; + +struct FunctionInfo { + const char* Name; + GlobalMapping* Globals; + const char* Bitcode; + size_t BitcodeLen; + + FunctionInfo(const char* N, GlobalMapping* G, const char* B, size_t BL) + : Name(N), Globals(G), Bitcode(B), BitcodeLen(BL) + { } +}; + +struct LayoutInfo { + size_t NumFields; +}; + +class BitcodeTracker { + + // map function to all the info required for jit compilation + std::unordered_map Functions; + std::unordered_map NameToAddress; + + // map the addresses of the layout_id with the number of parameters + std::unordered_map Layouts; + + public: + + void registerFunction(void* FPtr, const char* Name, GlobalMapping* Globals, const char* Bitcode, size_t BitcodeLen) { + // llvm::dbgs() << "[RUNTIME] " __FILE__ ":" << __LINE__<< " Register function " << Name << "\n"; + Functions.emplace(FPtr, FunctionInfo{Name, Globals, Bitcode, BitcodeLen}); + NameToAddress.emplace(Name, FPtr); + } + + void registerLayout(layout_id Id, size_t N) { + Layouts.emplace(Id, LayoutInfo{N}); + } + + void* getAddress(std::string const &Name); + std::tuple getNameAndGlobalMapping(void* FPtr); + bool hasGlobalMapping(void* FPtr) const; + LayoutInfo const & getLayoutInfo(easy::layout_id id) const; + + using ModuleContextPair = std::pair, std::unique_ptr>; + ModuleContextPair getModule(void* FPtr); + std::unique_ptr getModuleWithContext(void* FPtr, llvm::LLVMContext &C); + + // get the singleton object + static BitcodeTracker& GetTracker(); +}; + +} + +#endif diff --git a/easy-jit/include/easy/runtime/Context.h b/easy-jit/include/easy/runtime/Context.h new file mode 100644 index 000000000000..b5a06a8a78dc --- /dev/null +++ b/easy-jit/include/easy/runtime/Context.h @@ -0,0 +1,235 @@ +#ifndef CONTEXT +#define CONTEXT + +#include +#include +#include +#include +#include +#include + +#include + +namespace easy { + +struct serialized_arg { + std::vector buf; + + serialized_arg(char* serialized) { + uint32_t size = *reinterpret_cast(serialized); + const char* data = serialized + sizeof(uint32_t); + buf.insert(buf.end(), data, data+size); + + free(serialized); + } +}; + +typedef void* layout_id; + +struct ArgumentBase { + + enum ArgumentKind { + AK_Forward, + AK_Int, + AK_Float, + AK_Ptr, + AK_Struct, + AK_Module, + }; + + ArgumentBase() = default; + virtual ~ArgumentBase() = default; + + bool operator==(ArgumentBase const &Other) const { + return this->kind() == Other.kind() && + this->compareWithSameType(Other); + } + + template + std::enable_if_t::value, ArgTy const*> + as() const { + if(kind() == ArgTy::Kind) return static_cast(this); + else return nullptr; + } + + friend std::hash; + + virtual ArgumentKind kind() const noexcept = 0; + + protected: + virtual bool compareWithSameType(ArgumentBase const&) const = 0; + virtual size_t hash() const noexcept = 0; +}; + +#define DeclareArgument(Name, Type) \ + class Name##Argument \ + : public ArgumentBase { \ + \ + using HashType = std::remove_const_t>; \ + \ + Type Data_; \ + public: \ + Name##Argument(Type D) : ArgumentBase(), Data_(D) {} \ + virtual ~Name ## Argument() override = default ;\ + Type get() const { return Data_; } \ + static constexpr ArgumentKind Kind = AK_##Name;\ + ArgumentKind kind() const noexcept override { return Kind; } \ + \ + protected: \ + bool compareWithSameType(ArgumentBase const& Other) const override { \ + auto const &OtherCast = static_cast(Other); \ + return Data_ == OtherCast.Data_; \ + } \ + \ + size_t hash() const noexcept override { return std::hash{}(Data_); } \ + } + +DeclareArgument(Forward, unsigned); +DeclareArgument(Int, int64_t); +DeclareArgument(Float, double); +DeclareArgument(Ptr, void const*); +DeclareArgument(Module, easy::Function const&); + +class StructArgument + : public ArgumentBase { + serialized_arg Data_; + + public: + StructArgument(serialized_arg &&arg) + : ArgumentBase(), Data_(arg) {} + virtual ~StructArgument() override = default; + std::vector const & get() const { return Data_.buf; } + static constexpr ArgumentKind Kind = AK_Struct; + ArgumentKind kind() const noexcept override { return Kind; } + + protected: + bool compareWithSameType(ArgumentBase const& Other) const override { + auto const &OtherCast = static_cast(Other); + return get() == OtherCast.get(); + } + + size_t hash() const noexcept override { + std::hash hash{}; + size_t R = 0; + for (char c : get()) + R ^= hash(c); + return R; + } +}; + +// class that holds information about the just-in-time context +class Context { + + std::vector> ArgumentMapping_; + unsigned OptLevel_ = 2, OptSize_ = 0; + std::string DebugFile_; + + // describes how the arguments of the function are passed + // struct arguments can be packed in a single int, or passed field by field, + // keep track of how many arguments a parameter takes + std::vector ArgumentLayout_; + + template + inline Context& setArg(Args && ... args) { + ArgumentMapping_.emplace_back(new ArgTy(std::forward(args)...)); + return *this; + } + + public: + + Context() = default; + + bool operator==(const Context&) const; + + // set the mapping between + Context& setParameterIndex(unsigned); + Context& setParameterInt(int64_t); + Context& setParameterFloat(double); + Context& setParameterPointer(void const*); + Context& setParameterStruct(serialized_arg); + Context& setParameterModule(easy::Function const&); + + Context& setArgumentLayout(layout_id id) { + ArgumentLayout_.push_back(id); // each layout id is associated with a number of fields in the bitcode tracker + return *this; + } + + decltype(ArgumentLayout_) const & getLayout() const { + return ArgumentLayout_; + } + + template + Context& setParameterTypedPointer(T* ptr) { + return setParameterPointer(reinterpret_cast(ptr)); + } + + Context& setOptLevel(unsigned OptLevel, unsigned OptSize) { + OptLevel_ = OptLevel; + OptSize_ = OptSize; + return *this; + } + + Context& setDebugFile(std::string const &File) { + DebugFile_ = File; + return *this; + } + + std::pair getOptLevel() const { + return std::make_pair(OptLevel_, OptSize_); + } + + std::string const& getDebugFile() const { + return DebugFile_; + } + + auto begin() const { return ArgumentMapping_.begin(); } + auto end() const { return ArgumentMapping_.end(); } + size_t size() const { return ArgumentMapping_.size(); } + + ArgumentBase const& getArgumentMapping(size_t i) const { + return *ArgumentMapping_[i]; + } + + friend bool operator<(easy::Context const &C1, easy::Context const &C2); +}; + +} + +namespace std +{ + template struct hash> + { + typedef std::pair argument_type; + typedef std::size_t result_type; + result_type operator()(argument_type const& s) const noexcept { + return std::hash{}(s.first) ^ std::hash{}(s.second); + } + }; + + template<> struct hash + { + typedef easy::ArgumentBase argument_type; + typedef std::size_t result_type; + result_type operator()(argument_type const& s) const noexcept { + return s.hash(); + } + }; + + template<> struct hash + { + typedef easy::Context argument_type; + typedef std::size_t result_type; + result_type operator()(argument_type const& C) const noexcept { + size_t H = 0; + std::hash ArgHash; + std::hash> OptHash; + for(auto const &Arg : C) + H ^= ArgHash(*Arg); + H ^= OptHash(C.getOptLevel()); + return H; + } + }; +} + + +#endif diff --git a/easy-jit/include/easy/runtime/Function.h b/easy-jit/include/easy/runtime/Function.h new file mode 100644 index 000000000000..4251f44e403d --- /dev/null +++ b/easy-jit/include/easy/runtime/Function.h @@ -0,0 +1,58 @@ +#ifndef FUNCTION +#define FUNCTION + +#include "LLVMHolder.h" +#include + +namespace easy { + class Function; +} + +namespace llvm { + class Module; +} + +namespace std { + template<> struct hash + { + typedef easy::Function argument_type; + typedef std::size_t result_type; + result_type operator()(argument_type const& F) const noexcept; + }; +} + +namespace easy { + +class Context; +struct GlobalMapping; + +class Function { + + // do not reorder the fields and do not add virtual methods! + void* Address; + std::unique_ptr Holder; + + public: + + Function(void* Addr, std::unique_ptr H); + + void* getRawPointer() const { + return Address; + } + + void serialize(std::ostream&) const; + static std::unique_ptr deserialize(std::istream&); + + bool operator==(easy::Function const&) const; + + llvm::Module const& getLLVMModule() const; + + static std::unique_ptr Compile(void *Addr, easy::Context const &C); + + friend + std::hash::result_type std::hash::operator()(argument_type const& F) const noexcept; +}; + +} + +#endif diff --git a/easy-jit/include/easy/runtime/LLVMHolder.h b/easy-jit/include/easy/runtime/LLVMHolder.h new file mode 100644 index 000000000000..9ce5cf717bb6 --- /dev/null +++ b/easy-jit/include/easy/runtime/LLVMHolder.h @@ -0,0 +1,10 @@ +#ifndef LLVMHOLDER +#define LLVMHOLDER +namespace easy { +class LLVMHolder { + public: + virtual ~LLVMHolder() = default; +}; +} + +#endif diff --git a/easy-jit/include/easy/runtime/LLVMHolderImpl.h b/easy-jit/include/easy/runtime/LLVMHolderImpl.h new file mode 100644 index 000000000000..6b1b4b537aac --- /dev/null +++ b/easy-jit/include/easy/runtime/LLVMHolderImpl.h @@ -0,0 +1,25 @@ +#ifndef LLVMHOLDER_IMPL +#define LLVMHOLDER_IMPL + +#include + +#include +#include + +namespace easy { +class LLVMHolderImpl : public easy::LLVMHolder { + public: + + std::unique_ptr Context_; + std::unique_ptr Engine_; + llvm::Module* M_; // the execution engine has the ownership + + LLVMHolderImpl(std::unique_ptr EE, std::unique_ptr C, llvm::Module* M) + : Context_(std::move(C)), Engine_(std::move(EE)), M_(M) { + } + + virtual ~LLVMHolderImpl() = default; +}; +} + +#endif diff --git a/easy-jit/include/easy/runtime/RuntimePasses.h b/easy-jit/include/easy/runtime/RuntimePasses.h new file mode 100644 index 000000000000..48e3c88e52d2 --- /dev/null +++ b/easy-jit/include/easy/runtime/RuntimePasses.h @@ -0,0 +1,58 @@ +#ifndef RUNTIME_PASSES +#define RUNTIME_PASSES + +#include +#include +#include +#include + +namespace easy { + + struct ContextAnalysisResult { + private: + easy::Context const *C; + public: + explicit ContextAnalysisResult(easy::Context const &C); + ContextAnalysisResult(); + + easy::Context const &getContext() const { return *C; } + bool invalidate(llvm::Module &M, const llvm::PreservedAnalyses &PA, + llvm::ModuleAnalysisManager::Invalidator &Inv) { return false; } + }; + + class ContextAnalysisPass : public llvm::AnalysisInfoMixin { + friend llvm::AnalysisInfoMixin; + static llvm::AnalysisKey Key; + + public: + explicit ContextAnalysisPass(easy::Context const &C); + ContextAnalysisPass(); + using Result = ContextAnalysisResult; + Result run(llvm::Module &M, llvm::ModuleAnalysisManager &MAM); + + private: + Result Result_; + }; + + + class InlineParametersPass : public llvm::PassInfoMixin { + public: + explicit InlineParametersPass(llvm::StringRef TargetName); + InlineParametersPass(); + llvm::PreservedAnalyses run(llvm::Module &M, llvm::ModuleAnalysisManager &MAM); + private: + llvm::StringRef TargetName_; + }; + + class DevirtualizeConstantPass : public llvm::PassInfoMixin { + public: + explicit DevirtualizeConstantPass(llvm::StringRef TargetName); + DevirtualizeConstantPass(); + llvm::PreservedAnalyses run(llvm::Function &F, llvm::FunctionAnalysisManager &FAM); + private: + llvm::StringRef TargetName_; + }; + +} + +#endif diff --git a/easy-jit/include/easy/runtime/Utils.h b/easy-jit/include/easy/runtime/Utils.h new file mode 100644 index 000000000000..3619c2a9a399 --- /dev/null +++ b/easy-jit/include/easy/runtime/Utils.h @@ -0,0 +1,25 @@ +#ifndef UTILS +#define UTILS + +#include +#include +#include + +namespace llvm { + class LLVMContext; + class Module; + class Function; +} + +namespace easy { + +llvm::StringRef GetEntryFunctionName(llvm::Module const &M); +void MarkAsEntry(llvm::Function &F); +void UnmarkEntry(llvm::Module &M); + +std::unique_ptr +CloneModuleWithContext(llvm::Module const &LM, llvm::LLVMContext &C); + +} + +#endif diff --git a/easy-jit/misc/doc/generate.py b/easy-jit/misc/doc/generate.py new file mode 100644 index 000000000000..71ab10d41a30 --- /dev/null +++ b/easy-jit/misc/doc/generate.py @@ -0,0 +1,32 @@ +import re +import sys + +def get_split(tag): + start = re.compile("") + def split(contents): + start_match = start.search(contents, pos=0) + if not start_match: + return contents, "", "", False + end_match = end.search(contents, pos=start_match.end()) + if not end_match: + return contents, "", "", False + pre = contents[0 : start_match.start()] + args = contents[start_match.end() : end_match.start()] + post = contents[end_match.end() : ] + return pre, args, post, True + + return split + +def match_and_expand(tag, expand_with): + do_match_and_expand(sys.stdin.read(), get_split(tag), expand_with) + return + +def do_match_and_expand(contents, split, expand_with): + pre, code, post, match = split(contents) + if match : + do_match_and_expand(pre, split, expand_with) + expand_with(code) + do_match_and_expand(post, split, expand_with) + else: + print(contents, end='') diff --git a/easy-jit/misc/doc/include.py b/easy-jit/misc/doc/include.py new file mode 100644 index 000000000000..e464e4790cf2 --- /dev/null +++ b/easy-jit/misc/doc/include.py @@ -0,0 +1,19 @@ +import generate +import re + + +def on_include(args): + args = args.split() + filename = args[0]; + label = args[1]; + + all_code = open(filename.strip()).read() + + inline = re.compile(".*// INLINE FROM HERE #"+ label +"#(?P.*)// TO HERE #" + label + "#.*", flags=re.DOTALL) + code = inline.match(all_code) + code = code.group(1).rstrip().lstrip() + + print(code, end='') + return + +generate.match_and_expand("include", on_include) diff --git a/easy-jit/misc/doc/python.py b/easy-jit/misc/doc/python.py new file mode 100644 index 000000000000..40703b2c54d2 --- /dev/null +++ b/easy-jit/misc/doc/python.py @@ -0,0 +1,7 @@ +import generate + +def on_python(python_code): + exec (python_code) in {'__builtins__':{}}, {} + return + +generate.match_and_expand("python", on_python) diff --git a/easy-jit/misc/docker/GenDockerfile.py b/easy-jit/misc/docker/GenDockerfile.py new file mode 100644 index 000000000000..aa9d22f49b1a --- /dev/null +++ b/easy-jit/misc/docker/GenDockerfile.py @@ -0,0 +1,54 @@ +import yaml +import sys + +Head = "# Dockerfile derived from easy::jit's .travis.yml" +From = "ubuntu:latest" +Manteiner = "Juan Manuel Martinez Caamaño jmartinezcaamao@gmail.com" +base_packages = ['build-essential', 'python', 'python-pip', 'git', 'wget', 'unzip', 'cmake'] + +travis = yaml.load(open(sys.argv[1])) +travis_sources = travis['addons']['apt']['sources'] +travis_packages = travis['addons']['apt']['packages'] +before_install = travis['before_install'] +script = travis['script'] + +# I could not get a better way to do this +AddSourceCmd = { + "llvm-toolchain-trusty-6.0" : "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-6.0 main | tee -a /etc/apt/sources.list > /dev/null", + "ubuntu-toolchain-r-test" : "apt-add-repository -y \"ppa:ubuntu-toolchain-r/test\"" +} + +Sources = ["RUN {cmd} \n".format(cmd=AddSourceCmd[source]) for source in travis_sources] + +Apt = """# add sources +RUN apt-get update +RUN apt-get install -y software-properties-common +{AddSources} +# install apt packages, base first, then travis +RUN apt-get update +RUN apt-get upgrade -y +RUN apt-get install -y {base_packages} && \\ + apt-get install -y {travis_packages} +""".format(AddSources = "".join(Sources), base_packages = " ".join(base_packages), travis_packages=" ".join(travis_packages)) + +Checkout = "RUN git clone --depth=50 --branch=${branch} https://github.com/jmmartinez/easy-just-in-time.git easy-just-in-time && cd easy-just-in-time\n" +BeforeInstall = "".join(["RUN cd /easy-just-in-time && {0} \n".format(cmd) for cmd in before_install]) +Run = "RUN cd easy-just-in-time && \\\n" + "".join([" {cmd} && \\ \n".format(cmd=cmd) for cmd in script]) + " echo ok!" + +Template = """{Head} + +FROM {From} + +LABEL manteiner {Manteiner} + +ARG branch=master + +{Apt} +# checkout +{Checkout} +# install other deps +{BeforeInstall} +# compile and test! +{Run}""" + +print(Template.format(Head=Head, From=From, Manteiner=Manteiner, Apt=Apt, BeforeInstall=BeforeInstall, Checkout=Checkout, Run=Run)) diff --git a/easy-jit/misc/docker/build_docker.sh b/easy-jit/misc/docker/build_docker.sh new file mode 100644 index 000000000000..0601295861aa --- /dev/null +++ b/easy-jit/misc/docker/build_docker.sh @@ -0,0 +1,3 @@ +#!/bin/bash +python3 GenDockerfile.py ../../.travis.yml > Dockerfile.easy && + docker build -t easy/test -f Dockerfile.easy . diff --git a/easy-jit/pass/CMakeLists.txt b/easy-jit/pass/CMakeLists.txt new file mode 100644 index 000000000000..dd840a53e46a --- /dev/null +++ b/easy-jit/pass/CMakeLists.txt @@ -0,0 +1,22 @@ + +add_llvm_pass_plugin(EasyJitPass SHARED + RegisterPasses.cpp + Easy.cpp + Layout.cpp + Utils.cpp + MayAliasTracer.cpp + DEPENDS intrinsics_gen + ) + +set(EASY_JIT_PASS ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/EasyJitPass${CMAKE_SHARED_LIBRARY_SUFFIX} PARENT_SCOPE) + +install(TARGETS EasyJitPass + LIBRARY DESTINATION lib) + +# Get proper shared-library behavior (where symbols are not necessarily +# resolved when the shared library is linked) on OS X. +if(APPLE) + set_target_properties(EasyJitPass PROPERTIES + LINK_FLAGS "-undefined dynamic_lookup" + ) +endif(APPLE) diff --git a/easy-jit/pass/Easy.cpp b/easy-jit/pass/Easy.cpp new file mode 100644 index 000000000000..97451def6960 --- /dev/null +++ b/easy-jit/pass/Easy.cpp @@ -0,0 +1,526 @@ +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#include +#include + +#include + +#include + +#define DEBUG_TYPE "easy-register-bitcode" +#include + +#include +#include + +#include +#include +#include + +#include + +#include "MayAliasTracer.h" +#include "StaticPasses.h" +#include "Utils.h" + +#include + +using namespace llvm; + +static cl::opt RegexString("easy-export", + cl::desc("A regular expression to describe functions to expose at runtime."), + cl::init("")); + +namespace easy { + + struct RegisterBitcodeMixin : public PassInfoMixin { + public: + PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM) { + // execute the rest of the easy::jit passes + LLVM_DEBUG(dbgs() << "RegisterBitcode run on module " << M.getName() << "\n"); + + SmallVector ObjectsToJIT; + + collectObjectsToJIT(M, ObjectsToJIT); + + if(ObjectsToJIT.empty()) + return PreservedAnalyses::all(); + + SmallVector LocalVariables; + collectLocalGlobals(M, LocalVariables); + nameGlobals(LocalVariables, "unnamed_local_global"); + + auto Bitcode = embedBitcode(M, ObjectsToJIT); + GlobalVariable* GlobalMapping = getGlobalMapping(M, LocalVariables); + + Function* RegisterBitcodeFun = declareRegisterBitcode(M, GlobalMapping); + registerBitcode(M, ObjectsToJIT, Bitcode, GlobalMapping, RegisterBitcodeFun); + + LLVM_DEBUG(WriteIntermediateToFile(M, (M.getName() + "_pass.ll").str())); + + return PreservedAnalyses::none(); + } + static bool isRequired() { return true; } + private: + + static void WriteIntermediateToFile(llvm::Module const &M, std::string const& File) { + if(File.empty()) + return; + std::error_code Error; + llvm::raw_fd_ostream Out(File, Error, llvm::sys::fs::OF_None); + + if(Error) { + dbgs() << "WHAT\n"; + return; + } + + Out << M; + llvm::dbgs() << "Wrote to " << File << "\n"; + } + + static bool canExtractBitcode(GlobalObject &GO, std::string &Reason) { + if(GO.isDeclaration()) { + Reason = "Can't extract a declaration."; + return false; + } + return true; + } + + static auto compilerInterface(Module &M) { + SmallVector, 4> Funs; + std::copy_if(M.begin(), M.end(), std::back_inserter(Funs), + [](Function &F) {return F.getSection() == CI_SECTION;}); + return Funs; + } + + static bool mayBeOverload(Function *FOverload, Function *F) { + auto *FOverloadTy = FOverload->getFunctionType(); + auto *FTy = F->getFunctionType(); + if (FTy->getReturnType() != FOverloadTy->getReturnType()) + return false; + if (FTy->getNumParams() != FOverloadTy->getNumParams()) + return false; + if (FOverloadTy->isVarArg()) + return false; + + auto FParamIter = FTy->param_begin(); + auto FOverloadParamIter = FOverloadTy->param_begin(); + + // TODO: check that first parameter type are compatible? + if (!isa(*FOverloadParamIter)) + return false; + + for (++FParamIter, ++FOverloadParamIter; FParamIter != FTy->param_end(); + ++FParamIter, ++FOverloadParamIter) { + if (*FParamIter != *FOverloadParamIter) + return false; + } + + // an overload must be registered in a virtual table + for(User* U : F->users()) { + auto* CE = dyn_cast(U); + if(!CE || !CE->isCast()) + continue; + + for(User* CEU : CE->users()) { + if(auto* Init = dyn_cast(CEU)) { + return true; // probably a vtable + } + } + } + + return false; + } + + void collectObjectsToJIT(Module &M, SmallVectorImpl &ObjectsToJIT) { + + // get **all** functions passed as parameter to easy jit calls + // not only the target function, but also its parameters + deduceObjectsToJIT(M); + regexFunctionsToJIT(M); + deduceVirtualMethodsToJIT(M); + + // get functions in section jit section + for(GlobalObject &GO : M.global_objects()) { + if(GO.getSection() != JIT_SECTION) + continue; + + GO.setSection(""); // drop the identifier + + std::string Reason; + if(!canExtractBitcode(GO, Reason)) { + LLVM_DEBUG(dbgs() << "Could not extract global '" << GO.getName() << "'. " << Reason << "\n"); + continue; + } + LLVM_DEBUG(dbgs() << "Global '" << GO.getName() << "' marked for extraction.\n"); + + ObjectsToJIT.push_back(&GO); + } + + // also collect virtual functions in two steps + + } + + static bool isConstant(GlobalObject const& GO) { + if(isa(GO)) + return true; + return cast(GO).isConstant(); + } + + void deduceVirtualMethodsToJIT(Module &M) { + // First collect all loaded types we could monitor stores but stores + // could be done at call site, outside of ObjectsToJIT's scopes + + SmallPtrSet VirtualMethodTys; + for(Function& F: M) { + if(F.getSection() != JIT_SECTION) + continue; + for(auto& I : instructions(F)) { + auto* CI = dyn_cast(&I); + if(!CI) + continue; + + if (CI->getCalledFunction()) continue; + + auto* LI = dyn_cast(CI->getCalledOperand()); + if (!LI) + continue; + auto* LLI = dyn_cast(LI->getOperand(0)); + if (!LLI) + continue; + + MDNode *Tag = LLI->getMetadata(LLVMContext::MD_tbaa); + if(!Tag || !Tag->isTBAAVtableAccess()) + continue; + + llvm::dbgs() << "Found virtual: " << *CI << " from " << *LI << " from " << *LLI << ", type = " << *CI->getFunctionType() << "\n"; + dbgs() << "--------------------\n"; + dbgs() << F; + dbgs() << "--------------------\n"; + VirtualMethodTys.insert(CI->getFunctionType()); + } + } + + // Second look at functions that have a type compatible with the virtual one + for(GlobalObject &GO : M.global_objects()) { + GlobalVariable* GV = dyn_cast(&GO); + if(!GV || ! GV->hasInitializer()) + continue; + + ConstantStruct* CS = dyn_cast(GV->getInitializer()); + if(!CS || CS->getNumOperands() != 1) + continue; + + ConstantAggregate* CA = dyn_cast(CS->getOperand(0)); + if(!CA) + continue; + + for(Use& U : CA->operands()) { + Constant* C = dyn_cast(U.get()); + if(!C) + continue; + if(auto* CE = dyn_cast(C)) { + if(CE->isCast()) { + C = CE->getOperand(0); + } + } + auto* F = dyn_cast(C); + if(!F) + continue; + + auto* FTy = F->getFunctionType(); + if(VirtualMethodTys.count(FTy)) { + F->setSection(JIT_SECTION); + // also look for overloads + for(auto& FOverload: M) { + if(&FOverload == F) + continue; + if(mayBeOverload(&FOverload, F)) + FOverload.setSection(JIT_SECTION); + } + } + } + } + } + + void deduceObjectsToJIT(Module &M) { + for(Function &EasyJitFun : compilerInterface(M)) { + for(Use& U : EasyJitFun.uses()) { + if(AbstractCallSite CS{&U}) { + for (int i = 0; i < CS.getNumArgOperands(); i++) { + Value* O = CS.getCallArgOperand(i); + O = O->stripPointerCasts(); + MayAliasTracer Tracer(O); + for(GlobalObject& GO: M.global_objects()) { + if(isConstant(GO) and Tracer.count(GO)) { + GO.setSection(JIT_SECTION); + } + } + } + } + } + } + } + + static void regexFunctionsToJIT(Module &M) { + if(RegexString.empty()) + return; + llvm::Regex Match(RegexString); + for(GlobalObject &GO : M.global_objects()) + if(Match.match(GO.getName())) + GO.setSection(JIT_SECTION); + } + + static void collectLocalGlobals(Module &M, SmallVectorImpl &Globals) { + for(GlobalVariable &GV : M.globals()) + if(GV.hasLocalLinkage()) { + LLVM_DEBUG(dbgs() << "Found local global: " << GV << "\n"); + Globals.push_back(&GV); + } + } + + static void nameGlobals(SmallVectorImpl &Globals, Twine Name) { + for(GlobalValue *GV : Globals) + if(!GV->hasName()) + GV->setName(Name); + } + + static GlobalVariable* + getGlobalMapping(Module &M, SmallVectorImpl &Globals) { + LLVMContext &C = M.getContext(); + SmallVector Entries; + + Type* PtrTy = PointerType::get(C, 0); + StructType *EntryTy = StructType::get(C, {PtrTy, PtrTy}, true); + + for(GlobalValue* GV : Globals) { + GlobalVariable* Name = getStringGlobal(M, GV->getName()); + Constant* NameCast = ConstantExpr::getPointerCast(Name, PtrTy); + Constant* GVCast = GV; + if(GV->getType() != PtrTy) + GVCast = ConstantExpr::getPointerCast(GV, PtrTy); + Constant* Entry = ConstantStruct::get(EntryTy, {NameCast, GVCast}); + Entries.push_back(Entry); + } + Entries.push_back(Constant::getNullValue(EntryTy)); + + Constant* Init = ConstantArray::get(ArrayType::get(EntryTy, Entries.size()), Entries); + LLVM_DEBUG(dbgs() << "Global mapping: " << *Init << "\n"); + return new GlobalVariable(M, Init->getType(), true, + GlobalVariable::PrivateLinkage, + Init, "global_mapping"); + } + + static SmallVector + embedBitcode(Module &M, SmallVectorImpl &Objs) { + SmallVector Bitcode(Objs.size()); + for(size_t i = 0, n = Objs.size(); i != n; ++i) { + LLVM_DEBUG(dbgs() << "Embedding bitcode for " << Objs[i]->getName() << "\n"); + Bitcode[i] = embedBitcode(M, *Objs[i]); + } + return Bitcode; + } + + static GlobalVariable* embedBitcode(Module &M, GlobalObject& GO) { + std::unique_ptr Embed = CloneModule(M); + + GlobalValue *FEmbed = Embed->getNamedValue(GO.getName()); + assert(FEmbed && "global value with that name exists"); + cleanModule(*FEmbed, *Embed); + + Twine ModuleName = GO.getName() + "_bitcode"; + Embed->setModuleIdentifier(ModuleName.str()); + + return writeModuleToGlobal(M, *Embed, FEmbed->getName() + "_bitcode"); + } + + static std::string moduleToString(Module &M) { + std::string s; + raw_string_ostream so(s); + WriteBitcodeToFile(M, so); + so.flush(); + return s; + } + + static GlobalVariable* writeModuleToGlobal(Module &M, Module &Embed, Twine Name) { + std::string Bitcode = moduleToString(Embed); + Constant* BitcodeInit = ConstantDataArray::getString(M.getContext(), Bitcode, true); + return new GlobalVariable(M, BitcodeInit->getType(), true, + GlobalVariable::PrivateLinkage, + BitcodeInit, Name); + } + + static void cleanModule(GlobalValue &Entry, Module &M) { + + llvm::StripDebugInfo(M); + + bool ForFunction = isa(Entry); + + LLVM_DEBUG(dbgs() << "Cleaning module" << M.getName() << " for " << Entry.getName() << ", ForFunction = " << ForFunction << "\n"); + + auto Referenced = getReferencedFromEntry(Entry); + Referenced.push_back(&Entry); + + if(ForFunction) { + Entry.setLinkage(GlobalValue::ExternalLinkage); + } + + //clean the cloned module + + ModulePassManager PM; + ModuleAnalysisManager AM; + AM.registerPass([]() { return PassInstrumentationAnalysis(); }); + PM.addPass(GlobalDCEPass()); + PM.addPass(StripDeadDebugInfoPass()); + PM.addPass(StripDeadPrototypesPass()); + PM.run(M, AM); + + if(ForFunction) { + fixLinkages(Entry, M); + } + } + + static std::vector getReferencedFromEntry(GlobalValue &Entry) { + std::vector Funs; + + SmallPtrSet Visited; + SmallVector ToVisit; + ToVisit.push_back(&Entry); + + while(!ToVisit.empty()) { + User* U = ToVisit.pop_back_val(); + if(!Visited.insert(U).second) + continue; + if(Function* UF = dyn_cast(U)) { + Funs.push_back(UF); + + for(Instruction &I : instructions(UF)) + for(Value* Op : I.operands()) + if(User* OpU = dyn_cast(Op)) + ToVisit.push_back(OpU); + } + else if(GlobalVariable* GV = dyn_cast(U)) { + if(GV->hasInitializer()) { + ToVisit.push_back(GV->getInitializer()); + } + } + + for(Value* Op : U->operands()) + if(User* OpU = dyn_cast(Op)) + ToVisit.push_back(OpU); + } + + return Funs; + } + + static void fixLinkages(GlobalValue &Entry, Module &M) { + for(GlobalValue &GV : M.global_values()) { + if(GV.getName().starts_with("llvm.")) + continue; + + if(GlobalObject* GO = dyn_cast(&GV)) { + GO->setComdat(nullptr); + } + + if(auto* GVar = dyn_cast(&GV)) { + if (!GVar->isConstant()) { + GVar->setInitializer(nullptr); + GVar->setVisibility(GlobalValue::DefaultVisibility); + GVar->setLinkage(GlobalValue::ExternalLinkage); + LLVM_DEBUG(dbgs() << "fix bitcode var linkage for " << *GVar << "\n"); + } + } else if(auto* F = dyn_cast(&GV)) { + // f becomes private + F->removeFnAttr(Attribute::NoInline); + if(F == &Entry) + continue; + + if(!F->isDeclaration() && + (F->getVisibility() != GlobalValue::DefaultVisibility || + F->getLinkage() != GlobalValue::PrivateLinkage)) { + F->setVisibility(GlobalValue::DefaultVisibility); + F->setLinkage(GlobalValue::PrivateLinkage); + } + } else llvm::report_fatal_error("Easy::Jit [not yet implemented]: handle aliases, ifuncs."); + } + } + + Function* declareRegisterBitcode(Module &M, GlobalVariable *GlobalMapping) { + StringRef Name = "easy_register"; + if(Function* F = M.getFunction(Name)) + return F; + + LLVMContext &C = M.getContext(); + DataLayout const &DL = M.getDataLayout(); + + Type* Void = Type::getVoidTy(C); + Type* I8Ptr = PointerType::get(C, 0); + Type* GMTy = GlobalMapping->getType(); + Type* SizeT = DL.getLargestLegalIntType(C); + + assert(SizeT); + + FunctionType* FTy = + FunctionType::get(Void, {I8Ptr, I8Ptr, GMTy, I8Ptr, SizeT}, false); + return Function::Create(FTy, Function::ExternalLinkage, Name, &M); + } + + static void + registerBitcode(Module &M, SmallVectorImpl &Objs, + SmallVectorImpl &Bitcodes, + Value* GlobalMapping, + Function* RegisterBitcodeFun) { + // Create static initializer with low priority to register everything + Type* FPtr = RegisterBitcodeFun->getFunctionType()->getParamType(0); + Type* StrPtr = RegisterBitcodeFun->getFunctionType()->getParamType(1); + Type* BitcodePtr = RegisterBitcodeFun->getFunctionType()->getParamType(3); + Type* SizeTy = RegisterBitcodeFun->getFunctionType()->getParamType(4); + + Function *Ctor = GetCtor(M, "register_bitcode"); + IRBuilder<> B(Ctor->getEntryBlock().getTerminator()); + + for(size_t i = 0, n = Objs.size(); i != n; ++i) { + GlobalVariable* Name = getStringGlobal(M, Objs[i]->getName()); + ArrayType* ArrTy = cast(Bitcodes[i]->getInitializer()->getType()); + size_t Size = ArrTy->getNumElements()-1; /*-1 for the 0 terminator*/ + + Value* Fun = B.CreatePointerCast(Objs[i], FPtr); + Value* NameCast = B.CreatePointerCast(Name, StrPtr); + Value* Bitcode = B.CreatePointerCast(Bitcodes[i], BitcodePtr); + Value* BitcodeSize = ConstantInt::get(SizeTy, Size, false); + + // fun, name, gm, bitcode, bitcode size + auto* CI = B.CreateCall(RegisterBitcodeFun, + {Fun, NameCast, GlobalMapping, Bitcode, BitcodeSize}, ""); + LLVM_DEBUG(dbgs() << "Call:::: " << *CI << "\n"); + } + } + + static GlobalVariable* getStringGlobal(Module& M, StringRef Name) { + Constant* Init = ConstantDataArray::getString(M.getContext(), Name, true); + return new GlobalVariable(M, Init->getType(), true, + GlobalVariable::PrivateLinkage, + Init, Name + "_name"); + } + }; + + void registerBitcodePass(llvm::ModulePassManager &PM) { + PM.addPass(RegisterBitcodeMixin()); + } +} diff --git a/easy-jit/pass/Layout.cpp b/easy-jit/pass/Layout.cpp new file mode 100644 index 000000000000..e327fd180053 --- /dev/null +++ b/easy-jit/pass/Layout.cpp @@ -0,0 +1,205 @@ +#include + +#include +#include +#include +#include +#include +#include +#include + +#define DEBUG_TYPE "easy-register-layout" +#include + +#include + +#include "Utils.h" +#include +#include + +using namespace llvm; + +namespace easy { + struct RegisterLayoutMixin : public PassInfoMixin { + public: + PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM) { + LLVM_DEBUG(dbgs() << "RegisterLayout run on module " << M.getName() << "\n"); + + SmallVector LayoutFunctions; + collectLayouts(M, LayoutFunctions); + + if(LayoutFunctions.empty()) + return PreservedAnalyses::all(); + + Function* Register = declareRegisterLayout(M); + registerLayouts(LayoutFunctions, Register); + + return PreservedAnalyses::none(); + } + static bool isRequired() { return true; } + + static void collectLayouts(Module &M, SmallVectorImpl &LayoutFunctions) { + for(Function &F : M) + if(F.getSection() == LAYOUT_SECTION) + LayoutFunctions.push_back(&F); + } + + static Function* GetSerializeStruct(Function* F) { + // fragile! + for(Instruction &I : llvm::instructions(F)) { + if(isa(I)) + continue; + for(Value* Op : I.operands()) { + if(ConstantExpr* OpCE = dyn_cast(Op)) + if(OpCE->getOpcode() == Instruction::BitCast) + Op = OpCE->getOperand(0); + if(Function* F = dyn_cast(Op)) + return F; + } + } + assert(false && "unreachable"); + return nullptr; + } + + //Can this be simplified with emitMalloc ? + static Function* DeclareMalloc(Module &M) { + if(Function* Malloc = M.getFunction("malloc")) + return Malloc; + Type* IntPtrTy = M.getDataLayout().getIntPtrType(M.getContext()); + Type* OpqPtrTy = PointerType::get(M.getContext(), 0); + FunctionType* FTy = FunctionType::get(OpqPtrTy, {IntPtrTy}, false); + return Function::Create(FTy, Function::ExternalLinkage, "malloc", &M); + } + + template + static size_t GetStructSize(TypeIterator begin, TypeIterator end, DataLayout const &DL) { + return std::accumulate(begin, end, 0ul, + [&DL](size_t A, Type* T) { return A + DL.getTypeStoreSize(T); } ); + } + + static void SerializeStruct(IRBuilder<> &B, size_t &Offset, DataLayout const & DL, + Value* Buf, Value* ByVal, Type* CurLevelTy, Type* RootTy, SmallVectorImpl &GEPOffset) { + StructType* Struct = dyn_cast(CurLevelTy); + if(!Struct) { + // Compute the address of the current field relative to the root struct + Value* ArgPtr = B.CreateGEP(RootTy, ByVal, GEPOffset, "struct.ptr"); + // Load the field value with the correct type + Value* Argument = B.CreateLoad(CurLevelTy, ArgPtr); + + // Store the field into the serialization buffer at current byte offset + Value* DstI8 = B.CreateConstGEP1_32(Type::getInt8Ty(B.getContext()), Buf, Offset); + Value* DstTyped = B.CreatePointerCast(DstI8, PointerType::getUnqual(B.getContext())); + B.CreateStore(Argument, DstTyped); + + Offset += DL.getTypeStoreSize(Argument->getType()); + return; + } + + Type* I32Ty = Type::getInt32Ty(B.getContext()); + GEPOffset.push_back(nullptr); + for(size_t Arg = 0; Arg != Struct->getNumElements(); Arg++) { + GEPOffset.back() = ConstantInt::get(I32Ty, Arg); + SerializeStruct(B, Offset, DL, Buf, ByVal, Struct->getElementType(Arg), RootTy, GEPOffset); + } + GEPOffset.pop_back(); + } + + static void SerializeArguments(IRBuilder<> &B, size_t &Offset, DataLayout const & DL, Value* Buf, Function* F) { + for(size_t Arg = 0; Arg != F->arg_size(); Arg++) { + Value *Argument = F->arg_begin()+Arg; + Type* ArgTy = Argument->getType(); + + Value* Ptr = B.CreateConstGEP1_32(Type::getInt8Ty(B.getContext()), Buf, Offset); + Ptr = B.CreatePointerCast(Ptr, PointerType::getUnqual(B.getContext()), Argument->getName() + ".ptr"); + B.CreateStore(Argument, Ptr); + + LLVM_DEBUG(dbgs() << "Store at " << Offset << "\n"); + + Offset += DL.getTypeStoreSize(Argument->getType()); + } + } + + static void DefineSerializeStruct(Function *F) { + if(!F->isDeclaration()) + return; + + LLVMContext &C = F->getContext(); + + Module &M = *F->getParent(); + Function *Malloc = DeclareMalloc(M); + + DataLayout const &DL = M.getDataLayout(); + + //Why PassedAsAPointer can be decided only by the first argument? + FunctionType *FTy = F->getFunctionType(); + StructType *STy = F->arg_begin()->hasByValAttr() ? cast(F->arg_begin()->getParamByValType()) : nullptr; + bool PassedAsAPointer = STy; + + Type* I32 = Type::getInt32Ty(C); + Type* OpqPtr = PointerType::getUnqual(C); + size_t I32Size = DL.getTypeStoreSize(I32); + + BasicBlock *BB = BasicBlock::Create(C, "entry", F); + IRBuilder<> B(BB); + + size_t ArgSize; + if(PassedAsAPointer) ArgSize = GetStructSize(STy->element_begin(), STy->element_end(), DL); + else ArgSize = GetStructSize(FTy->param_begin(), FTy->param_end(), DL); + + LLVM_DEBUG(dbgs() << F->getName() << ": I32Size = " << I32Size << ", ArgSize = " << ArgSize << "\n"); + + // buf = malloc(sizeof(int32_t) + ArgSize) + Value* Buf = B.CreateCall(Malloc, {ConstantInt::get(Malloc->getFunctionType()->getParamType(0), I32Size + ArgSize)}, "buf"); + // *buf = ArgSize + B.CreateStore(ConstantInt::get(I32, ArgSize), B.CreatePointerCast(Buf, OpqPtr, "size.ptr")); + + SmallVector Offset = { ConstantInt::getNullValue(I32) }; + if(PassedAsAPointer) SerializeStruct(B, I32Size, DL, Buf, F->arg_begin(), STy, STy, Offset); + else SerializeArguments(B, I32Size, DL, Buf, F); + + B.CreateRet(Buf); + } + + static void registerLayouts(SmallVectorImpl &LayoutFunctions, Function* Register) { + + FunctionType* RegisterTy = Register->getFunctionType(); + Type* IdTy = RegisterTy->getParamType(0); + Type* NTy = RegisterTy->getParamType(1); + + // register the layout info in a constructor + Function* Ctor = GetCtor(*Register->getParent(), "register_layout"); + IRBuilder<> B(Ctor->getEntryBlock().getTerminator()); + + for(Function *F : LayoutFunctions) { + Function* SerializeStructFun = GetSerializeStruct(F); + + DefineSerializeStruct(SerializeStructFun); + + size_t N = SerializeStructFun->getFunctionType()->getNumParams(); + Value* Id = B.CreatePointerCast(SerializeStructFun, IdTy); + B.CreateCall(Register, {Id, ConstantInt::get(NTy, N, false)}); + } + } + + static Function* declareRegisterLayout(Module &M) { + StringRef Name = "easy_register_layout"; + if(Function* F = M.getFunction(Name)) + return F; + + LLVMContext &C = M.getContext(); + DataLayout const &DL = M.getDataLayout(); + + Type* Void = Type::getVoidTy(C); + Type* OpqPtr = PointerType::get(C, 0); + Type* SizeT = DL.getLargestLegalIntType(C); + + FunctionType* FTy = + FunctionType::get(Void, {OpqPtr, SizeT}, false); + return Function::Create(FTy, Function::ExternalLinkage, Name, &M); + } + }; + + void registerLayoutPass(llvm::ModulePassManager &PM) { + PM.addPass(RegisterLayoutMixin()); + } +} diff --git a/easy-jit/pass/MayAliasTracer.cpp b/easy-jit/pass/MayAliasTracer.cpp new file mode 100644 index 000000000000..589232f46ad5 --- /dev/null +++ b/easy-jit/pass/MayAliasTracer.cpp @@ -0,0 +1,75 @@ +#include "MayAliasTracer.h" + +#include +#include +#include +#include + +using namespace llvm; + +void easy::MayAliasTracer::mayAliasWithStoredValues(Value* V, VSet &Loaded, VSet &Stored) { + if(!Stored.insert(V).second) + return; + if(auto* GO = dyn_cast(V)) + GOs_.insert(GO); + + if(auto * II = dyn_cast(V)) { + if(II->getIntrinsicID() == Intrinsic::memcpy) { + mayAliasWithLoadedValues(II->getArgOperand(1), Loaded, Stored); + } + } + + if(auto* SI = dyn_cast(V)) { + mayAliasWithLoadedValues(SI->getValueOperand(), Loaded, Stored); + } + + if(isa(V)||isa(V)||isa(V)) { + for(User* U : V->users()) { + mayAliasWithStoredValues(U, Loaded, Stored); + } + } +} + +void easy::MayAliasTracer::mayAliasWithLoadedValues(Value * V, VSet &Loaded, VSet &Stored) { + if(!Loaded.insert(V).second) + return; + if(auto* GO = dyn_cast(V)) + GOs_.insert(GO); + + auto mayAliasWithLoadedOperand = [this, &Loaded, &Stored](Value* V) { mayAliasWithLoadedValues(V, Loaded, Stored);}; + + //TODO: generalize that + if(auto* PHI = dyn_cast(V)) { + std::for_each(PHI->op_begin(), PHI->op_end(), mayAliasWithLoadedOperand); + } + if(auto* Select = dyn_cast(V)) { + mayAliasWithLoadedValues(Select->getTrueValue(), Loaded, Stored); + mayAliasWithLoadedValues(Select->getFalseValue(), Loaded, Stored); + } + if(auto* Alloca = dyn_cast(V)) { + mayAliasWithStoredValues(Alloca, Loaded, Stored); + } + if(auto *GEP = dyn_cast(V)) { + mayAliasWithLoadedValues(GEP->getPointerOperand(), Loaded, Stored); + } + if(auto *BC = dyn_cast(V)) { + mayAliasWithLoadedValues(BC->getOperand(0), Loaded, Stored); + } + if(auto const* CE = dyn_cast(V)) { + switch(CE->getOpcode()) { + case Instruction::GetElementPtr: + case Instruction::BitCast: + return mayAliasWithLoadedValues(CE->getOperand(0), Loaded, Stored); + default: + ; + } + } + if(auto* OtherGV = dyn_cast(V)) { + if(OtherGV->hasInitializer()) + mayAliasWithLoadedValues(OtherGV->getInitializer(), Loaded, Stored); + mayAliasWithStoredValues(OtherGV, Loaded, Stored); + } + if(auto* CA = dyn_cast(V)) { + std::for_each(CA->op_begin(), CA->op_end(), mayAliasWithLoadedOperand); + } +} diff --git a/easy-jit/pass/MayAliasTracer.h b/easy-jit/pass/MayAliasTracer.h new file mode 100644 index 000000000000..2e3148e6b869 --- /dev/null +++ b/easy-jit/pass/MayAliasTracer.h @@ -0,0 +1,32 @@ +#ifndef MAY_ALIAS_TRACER +#define MAY_ALIAS_TRACER + +#include + +namespace llvm { + class Value; + class GlobalObject; +} + +namespace easy { + class MayAliasTracer { + llvm::SmallPtrSet GOs_; + + using VSet = llvm::SmallPtrSetImpl; + void mayAliasWithStoredValues(llvm::Value* V, VSet &Loaded, VSet &Stored); + void mayAliasWithLoadedValues(llvm::Value* V, VSet &Loaded, VSet &Stored); + + + public: + + MayAliasTracer(llvm::Value* V) { + llvm::SmallPtrSet VLoaded; + llvm::SmallPtrSet VStored; + mayAliasWithLoadedValues(V, VLoaded, VStored); + } + auto count(llvm::GlobalObject& GO) const { return GOs_.count(&GO);} + }; + +} + +#endif diff --git a/easy-jit/pass/RegisterPasses.cpp b/easy-jit/pass/RegisterPasses.cpp new file mode 100644 index 000000000000..47883d7c7a5a --- /dev/null +++ b/easy-jit/pass/RegisterPasses.cpp @@ -0,0 +1,28 @@ +#include "StaticPasses.h" + +#include +#include +#include + +#include +#include + +using namespace llvm; +using namespace easy; + +// The old pass manager inserts RegisterBitcodePass after last of optimization. +//@TODO: figure out the insertion point of these passes. +llvm::PassPluginLibraryInfo getEasyJitPassPluginInfo() { + return {LLVM_PLUGIN_API_VERSION, "RegisterBitcode", LLVM_VERSION_STRING, + [](PassBuilder &PB) { + PB.registerPipelineEarlySimplificationEPCallback( + [](llvm::ModulePassManager &PM, llvm::OptimizationLevel) { + easy::registerLayoutPass(PM); + easy::registerBitcodePass(PM); + }); + }}; +} +extern "C" LLVM_ATTRIBUTE_WEAK ::llvm::PassPluginLibraryInfo +llvmGetPassPluginInfo() { + return getEasyJitPassPluginInfo(); +} \ No newline at end of file diff --git a/easy-jit/pass/StaticPasses.h b/easy-jit/pass/StaticPasses.h new file mode 100644 index 000000000000..8b402f5fb8d4 --- /dev/null +++ b/easy-jit/pass/StaticPasses.h @@ -0,0 +1,13 @@ +#ifndef STATIC_PASSES +#define STATIC_PASSES + +#include + +#include + +namespace easy { + void registerBitcodePass(llvm::ModulePassManager &PM); + void registerLayoutPass(llvm::ModulePassManager &PM); +} + +#endif diff --git a/easy-jit/pass/Utils.cpp b/easy-jit/pass/Utils.cpp new file mode 100644 index 000000000000..63a91c74fc35 --- /dev/null +++ b/easy-jit/pass/Utils.cpp @@ -0,0 +1,22 @@ +#include "Utils.h" + +#include +#include +#include + +#include + +using namespace llvm; + +Function* GetCtor(Module &M, Twine Name, unsigned Priority) { + LLVMContext &C = M.getContext(); + Type* Void = Type::getVoidTy(C); + FunctionType* VoidFun = FunctionType::get(Void, false); + Function* Ctor = Function::Create(VoidFun, Function::PrivateLinkage, Name, &M); + BasicBlock* Entry = BasicBlock::Create(C, "entry", Ctor); + ReturnInst::Create(C, Entry); + + llvm::appendToGlobalCtors(M, Ctor, Priority); + + return Ctor; +} diff --git a/easy-jit/pass/Utils.h b/easy-jit/pass/Utils.h new file mode 100644 index 000000000000..e492af30f332 --- /dev/null +++ b/easy-jit/pass/Utils.h @@ -0,0 +1,13 @@ +#ifndef UTILS_H +#define UTILS_H + +#include + +namespace llvm { + class Module; + class Function; +} + +llvm::Function* GetCtor(llvm::Module &M, llvm::Twine Name, unsigned Priority = 65535); + +#endif // UTILS_H diff --git a/easy-jit/runtime/BitcodeTracker.cpp b/easy-jit/runtime/BitcodeTracker.cpp new file mode 100644 index 000000000000..8f88ca99ee61 --- /dev/null +++ b/easy-jit/runtime/BitcodeTracker.cpp @@ -0,0 +1,84 @@ +#include + +#include +#include + +#include + +using namespace easy; +using namespace llvm; + +namespace easy { + DefineEasyException(BitcodeNotRegistered, "Cannot find bitcode."); + DefineEasyException(BitcodeParseError, "Cannot parse bitcode for: "); +} + +BitcodeTracker& BitcodeTracker::GetTracker() { + static BitcodeTracker TheTracker; + return TheTracker; +} + +bool BitcodeTracker::hasGlobalMapping(void* FPtr) const { + auto InfoPtr = Functions.find(FPtr); + return InfoPtr != Functions.end(); +} + +LayoutInfo const & BitcodeTracker::getLayoutInfo(easy::layout_id id) const { + auto InfoPair = Layouts.find(id); + assert(InfoPair != Layouts.end()); + return InfoPair->second; +} + +void* BitcodeTracker::getAddress(std::string const &Name) { + auto Addr = NameToAddress.find(Name); + if(Addr == NameToAddress.end()) + return nullptr; + return Addr->second; +} + +std::tuple BitcodeTracker::getNameAndGlobalMapping(void* FPtr) { + auto InfoPtr = Functions.find(FPtr); + if(InfoPtr == Functions.end()) { + throw easy::BitcodeNotRegistered(); + } + + return std::make_tuple(InfoPtr->second.Name, InfoPtr->second.Globals); +} + +std::unique_ptr BitcodeTracker::getModuleWithContext(void* FPtr, llvm::LLVMContext &C) { + auto InfoPtr = Functions.find(FPtr); + if(InfoPtr == Functions.end()) { + throw easy::BitcodeNotRegistered(); + } + + auto &Info = InfoPtr->second; + + llvm::StringRef BytecodeStr(Info.Bitcode, Info.BitcodeLen); + std::unique_ptr Buf(llvm::MemoryBuffer::getMemBuffer(BytecodeStr)); + auto ModuleOrErr = + llvm::parseBitcodeFile(Buf->getMemBufferRef(), C); + + if (ModuleOrErr.takeError()) { + throw easy::BitcodeParseError(Info.Name); + } + + return std::move(ModuleOrErr.get()); +} + +BitcodeTracker::ModuleContextPair BitcodeTracker::getModule(void* FPtr) { + + std::unique_ptr Context(new llvm::LLVMContext()); + auto Module = getModuleWithContext(FPtr, *Context); + return ModuleContextPair(std::move(Module), std::move(Context)); +} + +// function to interface with the generated code +extern "C" { +void easy_register(void* FPtr, const char* Name, GlobalMapping* Globals, const char* Bitcode, size_t BitcodeLen) { + BitcodeTracker::GetTracker().registerFunction(FPtr, Name, Globals, Bitcode, BitcodeLen); +} +void easy_register_layout(layout_id Id, size_t N) { + BitcodeTracker::GetTracker().registerLayout(Id, N); +} +} + diff --git a/easy-jit/runtime/CMakeLists.txt b/easy-jit/runtime/CMakeLists.txt new file mode 100644 index 000000000000..3096881c9010 --- /dev/null +++ b/easy-jit/runtime/CMakeLists.txt @@ -0,0 +1,19 @@ +add_library(EasyJitRuntime SHARED + BitcodeTracker.cpp + Context.cpp + Function.cpp + InitNativeTarget.cpp + Utils.cpp + pass/ContextAnalysis.cpp + pass/DevirtualizeConstant.cpp + pass/InlineParameters.cpp + pass/InlineParametersHelper.cpp +) + +llvm_config(EasyJitRuntime core codegen interpreter support mcjit native executionengine passes objcarcopts) + + +set(EASY_JIT_RUNTIME ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_SHARED_LIBRARY_PREFIX}EasyJitRuntime${CMAKE_SHARED_LIBRARY_SUFFIX} PARENT_SCOPE) + +install(TARGETS EasyJitRuntime + LIBRARY DESTINATION lib) diff --git a/easy-jit/runtime/Context.cpp b/easy-jit/runtime/Context.cpp new file mode 100644 index 000000000000..725cd0142af6 --- /dev/null +++ b/easy-jit/runtime/Context.cpp @@ -0,0 +1,44 @@ +#include "easy/runtime/Context.h" + +using namespace easy; + +Context& Context::setParameterIndex(unsigned param_idx) { + return setArg(param_idx); +} + +Context& Context::setParameterInt(int64_t val) { + return setArg(val); +} + +Context& Context::setParameterFloat(double val) { + return setArg(val); +} + +Context& Context::setParameterPointer(const void* val) { + return setArg(val); +} + +Context& Context::setParameterStruct(serialized_arg arg) { + return setArg(std::move(arg)); +} + +Context& Context::setParameterModule(easy::Function const &F) { + return setArg(F); +} + +bool Context::operator==(const Context& Other) const { + if(getOptLevel() != Other.getOptLevel()) + return false; + if(size() != Other.size()) + return false; + + for(auto this_it = begin(), other_it = Other.begin(); + this_it != end(); ++this_it, ++other_it) { + ArgumentBase &ThisArg = **this_it; + ArgumentBase &OtherArg = **other_it; + if(!(ThisArg == OtherArg)) + return false; + } + + return true; +} diff --git a/easy-jit/runtime/Function.cpp b/easy-jit/runtime/Function.cpp new file mode 100644 index 000000000000..ce48f9a58109 --- /dev/null +++ b/easy-jit/runtime/Function.cpp @@ -0,0 +1,222 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#ifdef NDEBUG +#include +#endif + + +using namespace easy; + +namespace easy { + DefineEasyException(ExecutionEngineCreateError, "Failed to create execution engine for:"); + DefineEasyException(CouldNotOpenFile, "Failed to file to dump intermediate representation."); +} + +Function::Function(void* Addr, std::unique_ptr H) + : Address(Addr), Holder(std::move(H)) { +} + +static std::unique_ptr GetHostTargetMachine() { + std::unique_ptr TM(llvm::EngineBuilder().selectTarget()); + return TM; +} + +static void Optimize(llvm::Module& M, const char* Name, const easy::Context& C, llvm::OptimizationLevel OptLevel) { + + llvm::LoopAnalysisManager LAM; + llvm::FunctionAnalysisManager FAM; + llvm::CGSCCAnalysisManager CGAM; + llvm::ModuleAnalysisManager MAM; + + MAM.registerPass([&C]{return ContextAnalysisPass(C);}); + + std::unique_ptr TM = GetHostTargetMachine(); + assert(TM); + + llvm::PassBuilder PB(TM.get()); + + PB.registerModuleAnalyses(MAM); + PB.registerCGSCCAnalyses(CGAM); + PB.registerFunctionAnalyses(FAM); + PB.registerLoopAnalyses(LAM); + PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); + + llvm::ModulePassManager MPM; + + MPM.addPass(easy::InlineParametersPass(Name)); + MPM.addPass(PB.buildPerModuleDefaultPipeline(OptLevel)); + MPM.addPass(llvm::createModuleToFunctionPassAdaptor(easy::DevirtualizeConstantPass(Name))); + +#ifdef NDEBUG + MPM.addPass(llvm::VerifierPass()); +#endif + + MPM.addPass(PB.buildPerModuleDefaultPipeline(OptLevel)); + + MPM.run(M, MAM); +} + +static std::unique_ptr GetEngine(std::unique_ptr M, const char *Name) { + llvm::EngineBuilder ebuilder(std::move(M)); + std::string eeError; + + std::unique_ptr EE(ebuilder.setErrorStr(&eeError) + .setMCPU(llvm::sys::getHostCPUName()) + .setEngineKind(llvm::EngineKind::JIT) + .setOptLevel(llvm::CodeGenOptLevel::Aggressive) + .create()); + + if(!EE) { + throw easy::ExecutionEngineCreateError(Name); + } + + return EE; +} + +static void MapGlobals(llvm::ExecutionEngine& EE, GlobalMapping* Globals) { + for(GlobalMapping *GM = Globals; GM->Name; ++GM) { + EE.addGlobalMapping(GM->Name, (uint64_t)GM->Address); + } + EE.addGlobalMapping("__dso_handle", (uint64_t)&EE); + EE.finalizeObject(); +} + +static void WriteOptimizedToFile(llvm::Module const &M, std::string const& File) { + if(File.empty()) + return; + std::error_code Error; + llvm::raw_fd_ostream Out(File, Error, llvm::sys::fs::OF_None); + + if(Error) + throw CouldNotOpenFile(Error.message()); + + Out << M; +} + +std::unique_ptr +CompileAndWrap(const char*Name, GlobalMapping* Globals, + std::unique_ptr Ctx, + std::unique_ptr M) { + + llvm::Module* MPtr = M.get(); + std::unique_ptr EE = GetEngine(std::move(M), Name); + + if(Globals) { + MapGlobals(*EE, Globals); + } + + void *Address = (void*)EE->getFunctionAddress(Name); + + std::unique_ptr Holder(new easy::LLVMHolderImpl{std::move(EE), std::move(Ctx), MPtr}); + return std::unique_ptr(new Function(Address, std::move(Holder))); +} + +llvm::Module const& Function::getLLVMModule() const { + return *static_cast(*this->Holder).M_; +} + +static llvm::OptimizationLevel getOptimizationLevel(const std::pair & OptLevelPair) { + unsigned OptLevel = OptLevelPair.first; + unsigned OptSize = OptLevelPair.second; + assert(OptLevel <= 3 && "Optimization level for speed should be 0, 1, 2, or 3"); + assert(OptSize <= 2 && "Optimization level for size should be 0, 1, or 2"); + assert((OptSize == 0 || OptLevel == 2) && "Optimize for size should be encoded with speedup level == 2"); + if(OptLevel == 0) + return llvm::OptimizationLevel::O0; + if(OptLevel == 1) + return llvm::OptimizationLevel::O1; + if(OptLevel == 2) { + if(OptSize == 0) + return llvm::OptimizationLevel::O2; + else if (OptSize == 1) + return llvm::OptimizationLevel::Os; + else // OptSize == 2 + return llvm::OptimizationLevel::Oz; + } + if(OptLevel == 3) + return llvm::OptimizationLevel::O3; + return llvm::OptimizationLevel::O2; +} + +std::unique_ptr Function::Compile(void *Addr, easy::Context const& C) { + // llvm::DebugFlag = true; + // llvm::setCurrentDebugType("jit"); + + auto &BT = BitcodeTracker::GetTracker(); + + const char* Name; + GlobalMapping* Globals; + std::tie(Name, Globals) = BT.getNameAndGlobalMapping(Addr); + + std::unique_ptr M; + std::unique_ptr Ctx; + std::tie(M, Ctx) = BT.getModule(Addr); + + llvm::OptimizationLevel OptimizationLevel = getOptimizationLevel(C.getOptLevel()); + + Optimize(*M, Name, C, OptimizationLevel); + + WriteOptimizedToFile(*M, C.getDebugFile()); + + return CompileAndWrap(Name, Globals, std::move(Ctx), std::move(M)); +} + +void easy::Function::serialize(std::ostream& os) const { + std::string buf; + llvm::raw_string_ostream stream(buf); + + LLVMHolderImpl const *H = reinterpret_cast(Holder.get()); + llvm::WriteBitcodeToFile(*H->M_, stream); + stream.flush(); + + os << buf; +} + +std::unique_ptr easy::Function::deserialize(std::istream& is) { + + auto &BT = BitcodeTracker::GetTracker(); + + std::string buf(std::istreambuf_iterator(is), {}); // read the entire istream + auto MemBuf = llvm::MemoryBuffer::getMemBuffer(llvm::StringRef(buf)); + + std::unique_ptr Ctx(new llvm::LLVMContext()); + auto ModuleOrError = llvm::parseBitcodeFile(*MemBuf, *Ctx); + if(ModuleOrError.takeError()) { + return nullptr; + } + + auto M = std::move(ModuleOrError.get()); + + std::string FunName = easy::GetEntryFunctionName(*M).str(); + + GlobalMapping* Globals = nullptr; + if(void* OrigFunPtr = BT.getAddress(FunName)) { + std::tie(std::ignore, Globals) = BT.getNameAndGlobalMapping(OrigFunPtr); + } + + return CompileAndWrap(FunName.c_str(), Globals, std::move(Ctx), std::move(M)); +} + +bool Function::operator==(easy::Function const& other) const { + LLVMHolderImpl& This = static_cast(*this->Holder); + LLVMHolderImpl& Other = static_cast(*other.Holder); + return This.M_ == Other.M_; +} + +std::hash::result_type +std::hash::operator()(argument_type const& F) const noexcept { + LLVMHolderImpl& This = static_cast(*F.Holder); + return std::hash{}(This.M_); +} diff --git a/easy-jit/runtime/InitNativeTarget.cpp b/easy-jit/runtime/InitNativeTarget.cpp new file mode 100644 index 000000000000..85232e88439b --- /dev/null +++ b/easy-jit/runtime/InitNativeTarget.cpp @@ -0,0 +1,28 @@ +#include + +#include +#include +#include + +using namespace llvm; + +namespace { +class InitNativeTarget { + public: + InitNativeTarget() { +#if defined(_X86) + LLVMInitializeX86Target(); + LLVMInitializeX86TargetInfo(); + LLVMInitializeX86TargetMC(); + LLVMInitializeX86AsmPrinter(); +#elif defined(__aarch64__) + LLVMInitializeAArch64Target(); + LLVMInitializeAArch64TargetInfo(); + LLVMInitializeAArch64TargetMC(); + LLVMInitializeAArch64AsmPrinter(); +#endif + + sys::DynamicLibrary::LoadLibraryPermanently(nullptr); + } +} Init; +} diff --git a/easy-jit/runtime/Utils.cpp b/easy-jit/runtime/Utils.cpp new file mode 100644 index 000000000000..b4b472110441 --- /dev/null +++ b/easy-jit/runtime/Utils.cpp @@ -0,0 +1,73 @@ +#include +#include +#include + +#include +#include +#include + +#include + +#include + +using namespace llvm; + +static const char EasyJitMD[] = "easy::jit"; +static const char EntryTag[] = "entry"; + +llvm::StringRef easy::GetEntryFunctionName(Module const &M) { + NamedMDNode* MD = M.getNamedMetadata(EasyJitMD); + + for(MDNode *Operand : MD->operands()) { + if(Operand->getNumOperands() != 2) + continue; + MDString* Entry = dyn_cast(Operand->getOperand(0)); + MDString* Name = dyn_cast(Operand->getOperand(1)); + + if(!Entry || !Name || Entry->getString() != EntryTag) + continue; + + return Name->getString(); + } + + llvm_unreachable("No entry function in easy::jit module!"); + return ""; +} + +void easy::MarkAsEntry(llvm::Function &F) { + Module &M = *F.getParent(); + LLVMContext &Ctx = F.getContext(); + NamedMDNode* MD = M.getOrInsertNamedMetadata(EasyJitMD); + MDNode* Node = MDNode::get(Ctx, { MDString::get(Ctx, EntryTag), + MDString::get(Ctx, F.getName())}); + MD->addOperand(Node); +} + +void easy::UnmarkEntry(llvm::Module &M) { + NamedMDNode* MD = M.getOrInsertNamedMetadata(EasyJitMD); + M.eraseNamedMetadata(MD); +} + +std::unique_ptr +easy::CloneModuleWithContext(llvm::Module const &LM, llvm::LLVMContext &C) { + // I have not found a better way to do this withouth having to fully reimplement + // CloneModule + + std::string buf; + + // write module + { + llvm::raw_string_ostream stream(buf); + llvm::WriteBitcodeToFile(LM, stream); + stream.flush(); + } + + // read the module + auto MemBuf = llvm::MemoryBuffer::getMemBuffer(llvm::StringRef(buf)); + auto ModuleOrError = llvm::parseBitcodeFile(*MemBuf, C); + if(ModuleOrError.takeError()) + return nullptr; + + auto LMCopy = std::move(ModuleOrError.get()); + return LMCopy; +} diff --git a/easy-jit/runtime/pass/ContextAnalysis.cpp b/easy-jit/runtime/pass/ContextAnalysis.cpp new file mode 100644 index 000000000000..a071ab212454 --- /dev/null +++ b/easy-jit/runtime/pass/ContextAnalysis.cpp @@ -0,0 +1,17 @@ +#include + +using namespace llvm; +using namespace easy; + +ContextAnalysisResult::ContextAnalysisResult(easy::Context const &C) : C(&C) {} +ContextAnalysisResult::ContextAnalysisResult() : C(nullptr) {} + +AnalysisKey ContextAnalysisPass::Key; + +ContextAnalysisPass::ContextAnalysisPass(easy::Context const &C) : Result_(C) {} +ContextAnalysisPass::ContextAnalysisPass() : Result_() {} + +ContextAnalysisPass::Result ContextAnalysisPass::run(Module &M, ModuleAnalysisManager &MAM) { + return Result_; +} + diff --git a/easy-jit/runtime/pass/DevirtualizeConstant.cpp b/easy-jit/runtime/pass/DevirtualizeConstant.cpp new file mode 100644 index 000000000000..81bd8438e712 --- /dev/null +++ b/easy-jit/runtime/pass/DevirtualizeConstant.cpp @@ -0,0 +1,128 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace llvm; + +static ConstantInt* getVTableHostAddress(Value& V) { + auto* VTable = dyn_cast(&V); + if(!VTable) + return nullptr; + MDNode *Tag = VTable->getMetadata(LLVMContext::MD_tbaa); + if(!Tag || !Tag->isTBAAVtableAccess()) + return nullptr; + + // that's a vtable + auto* Location = dyn_cast(VTable->getPointerOperand()->stripPointerCasts()); + if(!Location) + return nullptr; + + if(auto* CE = dyn_cast(Location)) { + if(CE->getOpcode() == Instruction::IntToPtr) { + Location = CE->getOperand(0); + } + } + auto* CLocation = dyn_cast(Location); + if(!CLocation) + return nullptr; + return CLocation; +} + +static Function* findFunctionAndLinkModules(Module& M, void* HostValue) { + auto &BT = easy::BitcodeTracker::GetTracker(); + const char* FName = std::get<0>(BT.getNameAndGlobalMapping(HostValue)); + + if(!FName) + return nullptr; + + std::unique_ptr LM = BT.getModuleWithContext(HostValue, M.getContext()); + + if(!Linker::linkModules(M, std::move(LM), Linker::OverrideFromSrc, + [](Module &, const StringSet<> &){})) + { + GlobalValue *GV = M.getNamedValue(FName); + if(Function* F = dyn_cast(GV)) { + F->setLinkage(Function::PrivateLinkage); + return F; + } + else { + assert(false && "wtf"); + } + } + return nullptr; +} + +template +bool Devirtualize(IIter it, IIter end) { + bool Changed = false; + + // We are trying to match %1 from CallInsts like %3 + // Matching %1 means we are doing a virtualized call in %3. + + // %1 = load ptr, ptr inttoptr (i64 187650338298944 to ptr), align 64, !tbaa !9 + // %2 = load ptr, ptr %1, align 8 + // %3 = tail call noundef i32 %2(ptr noundef nonnull align 8 dereferenceable(8) inttoptr (i64 187650338298944 to ptr)) + for (; it != end; ++it) { + Instruction &I = *it; + CallInst* CI = dyn_cast(&I); // %3 + if(!CI) + continue; + + // Try to take us to where we load the VTable + // This only happens when we are calling a temp, not a function + if (CI->getCalledFunction()) + continue; + LoadInst* LI = dyn_cast(CI->getCalledOperand()); // %2 + + // must come from a pointer load + if (!LI) + continue; + + LoadInst* LLI = dyn_cast(LI->getOperand(0)); // %1 + if (!LLI) + continue; + + auto* VTable = getVTableHostAddress(*LLI); + if(!VTable) + continue; + + void** RuntimeLoadedValue = *(void***)(uintptr_t)(VTable->getZExtValue()); + + void* CalledPtrHostValue = *RuntimeLoadedValue; + llvm::Function* F = findFunctionAndLinkModules(*LLI->getParent()->getParent()->getParent(), CalledPtrHostValue); + if(!F) + continue; + + LI->replaceAllUsesWith(F); + + Changed = true; + } + return Changed; +} + + +easy::DevirtualizeConstantPass::DevirtualizeConstantPass(llvm::StringRef Name) : TargetName_(Name) {} +easy::DevirtualizeConstantPass::DevirtualizeConstantPass() : TargetName_("") {} +PreservedAnalyses easy::DevirtualizeConstantPass::run(llvm::Function &F, FunctionAnalysisManager &FAM) { + const auto &MPMProxy = FAM.getResult(F); + + if(F.getName() != TargetName_) + return PreservedAnalyses::all(); + + if(Devirtualize(inst_begin(F), inst_end(F))) { + return PreservedAnalyses::all(); + } + + return PreservedAnalyses::none(); +} diff --git a/easy-jit/runtime/pass/InlineParameters.cpp b/easy-jit/runtime/pass/InlineParameters.cpp new file mode 100644 index 000000000000..c9104cea6a42 --- /dev/null +++ b/easy-jit/runtime/pass/InlineParameters.cpp @@ -0,0 +1,257 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "InlineParametersHelper.h" + +using namespace llvm; +using easy::HighLevelLayout; + +HighLevelLayout GetNewLayout(easy::Context const &C, HighLevelLayout &HLL) { + + assert(C.size() == HLL.Args_.size()); + + size_t NNewArgs = 0; + for(auto const &Arg : C) + if(auto const *Map = Arg->as()) + NNewArgs = std::max(NNewArgs, Map->get()+1); + + HighLevelLayout NewHLL(HLL); + NewHLL.Args_.clear(); + NewHLL.Args_.resize(NNewArgs, HighLevelLayout::HighLevelArg()); + + SmallSet VisitedArgs; + + // only forwarded params are kept + for(size_t arg = 0; arg != HLL.Args_.size(); ++arg) { + if(auto const *Map = C.getArgumentMapping(arg).as()) { + if(!VisitedArgs.insert(Map->get()).second) + continue; + NewHLL.Args_[Map->get()] = HLL.Args_[arg]; + } + } + + // set the param_idx once all the parameter sizes are known + for(size_t new_arg = 0, ParamIdx = 0; new_arg != NewHLL.Args_.size(); ++new_arg) { + NewHLL.Args_[new_arg].FirstParamIdx_ = ParamIdx; + ParamIdx += NewHLL.Args_[new_arg].Types_.size(); + } + return NewHLL; +} + +FunctionType* GetWrapperTy(HighLevelLayout &HLL, LLVMContext& C) { + SmallVector Args; + // Reserve a opaque pointer here, its type is recorded in attr sret. + if(HLL.StructReturn_) + Args.push_back(PointerType::getUnqual(C)); + for(auto &HLArg : HLL.Args_) + Args.insert(Args.end(), HLArg.Types_.begin(), HLArg.Types_.end()); + return FunctionType::get(HLL.Return_, Args, false); +} + +void GetInlineArgs(easy::Context const &C, + Function& F, HighLevelLayout &FHLL, + Function &Wrapper, HighLevelLayout &WrapperHLL, + SmallVectorImpl &Args, IRBuilder<> &B, + SmallVectorImpl + &PostLinkageSymbols) { + + LLVMContext &Ctx = F.getContext(); + DataLayout const &DL = F.getParent()->getDataLayout(); + + if(FHLL.StructReturn_) + Args.push_back(&*Wrapper.arg_begin()); + + for(size_t i = 0, n = C.size(); i != n; ++i) { + auto const &Arg = C.getArgumentMapping(i); + auto &ArgInF = FHLL.Args_[i]; + + switch(Arg.kind()) { + + case easy::ArgumentBase::AK_Forward: { + auto Forward = GetForwardArgs(ArgInF, FHLL, Wrapper, WrapperHLL); + Args.insert(Args.end(), Forward.begin(), Forward.end()); + } break; + case easy::ArgumentBase::AK_Int: + case easy::ArgumentBase::AK_Float: { + Args.push_back(easy::GetScalarArgument(Arg, ArgInF.Types_[0])); + } break; + + case easy::ArgumentBase::AK_Ptr: { + auto const *Ptr = Arg.as(); + Type* PtrTy = FHLL.Args_[i].Types_[0]; + + Constant* PtrVal = easy::GetScalarArgument(Arg, PtrTy); + // This linkage should be postponed as later as possible, as it will change the memory layout + // of current module, and cause severe dangling pointer problems. + // If this pointer is a global variable, it should be linked after linkage. + StringRef GlobalName = easy::GetGlobalName(*Wrapper.getParent(), *Ptr); + if (!GlobalName.empty()) + PostLinkageSymbols.push_back({GlobalName, easy::ArgumentBase::AK_Ptr, i}); + + Args.push_back(PtrVal); + } break; + + case easy::ArgumentBase::AK_Struct: { + auto const *Struct = Arg.as(); + auto &ArgInF = FHLL.Args_[i]; + + if(ArgInF.StructByPointer_) { + // struct is passed trough a pointer + // StructType should be extracted from origin Function. + Type* StructType = F.getParamByValType(ArgInF.FirstParamIdx_); + AllocaInst* ParamAlloc = easy::GetStructAlloc(B, DL, *Struct, StructType); + Args.push_back(ParamAlloc); + } else if (ArgInF.StructByArray_) { + // struct is passed as an array + Type* ArrayTy = ArgInF.Types_[0]; + size_t N = ArrayTy->getArrayNumElements(); + Type* FieldTy = ArrayTy->getArrayElementType(); + SmallVector ArrayValues; + + for(size_t ParamIdx = 0, RawOffset = 0; ParamIdx != N; ++ParamIdx) { + const char* RawField = &Struct->get()[RawOffset]; + + Constant* FieldValue; + size_t RawSize; + std::tie(FieldValue, RawSize) = easy::GetConstantFromRaw(DL, FieldTy, (uint8_t const*)RawField); + + ArrayValues.push_back(FieldValue); + RawOffset += RawSize; + } + + Constant* ArrayConst = ConstantArray::get(cast(ArrayTy), ArrayValues); + Args.push_back(ArrayConst); + } else { + // struct is passed by value (may be many values) + size_t N = ArgInF.Types_.size(); + for(size_t ParamIdx = 0, RawOffset = 0; ParamIdx != N; ++ParamIdx) { + Type* FieldTy = ArgInF.Types_[ParamIdx]; + const char* RawField = &Struct->get()[RawOffset]; + + Constant* FieldValue; + size_t RawSize; + std::tie(FieldValue, RawSize) = easy::GetConstantFromRaw(DL, FieldTy, (uint8_t const*)RawField); + + Args.push_back(FieldValue); + RawOffset += RawSize; + } + } + } break; + + case easy::ArgumentBase::AK_Module: { + + auto &ArgInF = FHLL.Args_[i]; + assert(ArgInF.Types_.size() == 1); + + easy::Function const &Function = Arg.as()->get(); + llvm::Module const& FunctionModule = Function.getLLVMModule(); + auto FunctionName = easy::GetEntryFunctionName(FunctionModule); + + // Linking is postponed after creation of WrapperFun. + PostLinkageSymbols.push_back({FunctionName, easy::ArgumentBase::AK_Module, i}); + llvm::FunctionType* FTy = F.getFunctionType(); + + // Just a placeholder + llvm::Function* FunctionInWrapper = Function::Create(FTy, Function::PrivateLinkage, FunctionName, Wrapper.getParent()); + + Args.push_back(FunctionInWrapper); + + } break; + } + } +} + +void RemapAttributes(Function const &F, HighLevelLayout const& HLL, Function &Wrapper, HighLevelLayout const& NewHLL) { + auto FAttributes = F.getAttributes(); + + auto FunAttrs = FAttributes.getFnAttrs(); + for(Attribute Attr : FunAttrs) + Wrapper.addFnAttr(Attr); + + for(size_t new_arg = 0; new_arg != NewHLL.Args_.size(); ++new_arg) { + auto const &NewArg = NewHLL.Args_[new_arg]; + auto const &OrgArg = HLL.Args_[NewArg.Position_]; + + for(size_t field = 0; field != NewArg.Types_.size(); ++field) { + Wrapper.addParamAttrs(field + NewArg.FirstParamIdx_, + AttrBuilder(F.getContext(), FAttributes.getParamAttrs(field + OrgArg.FirstParamIdx_))); + } + } +} + +Function* CreateWrapperFun(Module &M, Function &F, HighLevelLayout &HLL, easy::Context const &C, + SmallVectorImpl &PostLinkageSymbols, Value* &Call) { + LLVMContext &CC = M.getContext(); + + HighLevelLayout NewHLL(GetNewLayout(C, HLL)); + FunctionType *WrapperTy = GetWrapperTy(NewHLL,CC); + + Function* Wrapper = Function::Create(WrapperTy, Function::ExternalLinkage, "", &M); + + BasicBlock* BB = BasicBlock::Create(CC, "", Wrapper); + IRBuilder<> B(BB); + + SmallVector Args; + GetInlineArgs(C, F, HLL, *Wrapper, NewHLL, Args, B, PostLinkageSymbols); + + // The call will be updated after linking + Call = B.CreateCall(&F, Args); + + if(Call->getType()->isVoidTy()) { + B.CreateRetVoid(); + } else { + B.CreateRet(Call); + } + + RemapAttributes(F, HLL, *Wrapper, NewHLL); + + return Wrapper; +} + + +easy::InlineParametersPass::InlineParametersPass(llvm::StringRef Name) : TargetName_(Name) {} +easy::InlineParametersPass::InlineParametersPass() : TargetName_("") {} +PreservedAnalyses easy::InlineParametersPass::run(llvm::Module &M, llvm::ModuleAnalysisManager &MAM) { + easy::Context const &C = MAM.getResult(M).getContext(); + SmallVector PostLinkageSymbols; + + llvm::Function* F = M.getFunction(TargetName_); + assert(F); + + llvm::Value* CallToUpdate = nullptr; + + HighLevelLayout HLL(C, *F); + llvm::Function* WrapperFun = CreateWrapperFun(M, *F, HLL, C, PostLinkageSymbols, CallToUpdate); + // Give it a temporary name to be discoverable after linkage. + Twine TempName = "__easy_wrapper_" + TargetName_; + WrapperFun->setName(TempName); + // After linking, the place of Function F and WrapperFun may change + if(LinkAndUpdateSymbol(M, TargetName_, TempName.str(), PostLinkageSymbols, C, CallToUpdate)){ + F = M.getFunction(TargetName_); + WrapperFun = M.getFunction(TempName.str()); + assert(F); + assert(WrapperFun); + } + + // privatize F, steal its name, copy its attributes, and its cc + F->setLinkage(llvm::Function::PrivateLinkage); + WrapperFun->takeName(F); + WrapperFun->setCallingConv(CallingConv::C); + + // add metadata to identify the entry function + easy::MarkAsEntry(*WrapperFun); + + return PreservedAnalyses::none(); +} + \ No newline at end of file diff --git a/easy-jit/runtime/pass/InlineParametersHelper.cpp b/easy-jit/runtime/pass/InlineParametersHelper.cpp new file mode 100644 index 000000000000..d1615bbcbb34 --- /dev/null +++ b/easy-jit/runtime/pass/InlineParametersHelper.cpp @@ -0,0 +1,260 @@ +#include "InlineParametersHelper.h" +#include "easy/runtime/Utils.h" +#include + +#include + +#include + +using namespace llvm; +using namespace easy; + +HighLevelLayout::HighLevelLayout(easy::Context const& C, llvm::Function &F) { + StructReturn_ = nullptr; + + FunctionType* FTy = F.getFunctionType(); + if(F.arg_begin()->hasStructRetAttr()) + StructReturn_ = F.getParamStructRetType(0); + + Return_ = FTy->getReturnType(); + + auto &BT = easy::BitcodeTracker::GetTracker(); + + size_t ParamIdx = 0; + size_t ArgIdx = 0; + if(StructReturn_) + ParamIdx++; + + for(easy::layout_id lid : C.getLayout()) { + size_t N = BT.getLayoutInfo(lid).NumFields; + + Args_.emplace_back(ArgIdx, ParamIdx); + HighLevelArg& Arg = Args_.back(); + + size_t ArgEnd = (ParamIdx+N); + + bool SingleArg = (ParamIdx + 1) == ArgEnd; + if(SingleArg) { + Type* ParamTy = FTy->getParamType(ParamIdx); + Arg.Types_.push_back(ParamTy); + Arg.StructByPointer_ = ParamTy->isPointerTy(); + Arg.StructByArray_ = ParamTy->isArrayTy(); + ++ParamIdx; + ++ArgIdx; + } else { + for(; ParamIdx != ArgEnd; ++ParamIdx) + Arg.Types_.push_back(FTy->getParamType(ParamIdx)); + ++ArgIdx; + } + } +} + +llvm::SmallVector +easy::GetForwardArgs(easy::HighLevelLayout::HighLevelArg &ArgInF, easy::HighLevelLayout &FHLL, + llvm::Function &Wrapper, easy::HighLevelLayout &WrapperHLL) { + + llvm::SmallVector Args; + + auto GetArg = [&Wrapper, &FHLL](size_t i) -> Argument* + { return &*(Wrapper.arg_begin()+i+(FHLL.StructReturn_ ? 1 : 0)); }; + + // find layout in the new wrapper + size_t ArgPosition = ArgInF.Position_; + auto &ArgInWrapper = *std::find_if(WrapperHLL.Args_.begin(), WrapperHLL.Args_.end(), + [ArgPosition](HighLevelLayout::HighLevelArg &ArgInWrapper) + { return ArgInWrapper.Position_ == ArgPosition; }); + + for(size_t j = 0; j != ArgInF.Types_.size(); ++j) { + Args.push_back(GetArg(ArgInWrapper.FirstParamIdx_ + j)); + } + return Args; +} + +Constant* easy::GetScalarArgument(ArgumentBase const& Arg, Type* T) { + switch(Arg.kind()) { + case easy::ArgumentBase::AK_Int: { + auto const *Int = Arg.as(); + return ConstantInt::get(T, Int->get(), true); + } + case easy::ArgumentBase::AK_Float: { + auto const *Float = Arg.as(); + return ConstantFP::get(T, Float->get()); + } + case easy::ArgumentBase::AK_Ptr: { + auto const *Ptr = Arg.as(); + uintptr_t Addr = (uintptr_t)Ptr->get(); + return ConstantExpr::getIntToPtr( + ConstantInt::get(Type::getInt64Ty(T->getContext()), Addr, false), + T); + } + default: + return nullptr; + } +} + +llvm::StringRef easy::GetGlobalName(llvm::Module &M, easy::PtrArgument const &Ptr) { + auto &BT = easy::BitcodeTracker::GetTracker(); + void* PtrValue = const_cast(Ptr.get()); + if(BT.hasGlobalMapping(PtrValue)) { + return std::get<0>(BT.getNameAndGlobalMapping(PtrValue)); + } + return ""; +} + +static +void UpdateCallArg(llvm::Value* Call, easy::Context const &C, Value* newArg, size_t argNo) { + assert(Call != nullptr && "CallToUpdate is null."); + if(auto *CI = dyn_cast(Call)) { + CI->setArgOperand(argNo, newArg); + } + else { + report_fatal_error("CallToUpdate is not a call instruction.", true); + } +} + +bool easy::LinkAndUpdateSymbol(llvm::Module &M, llvm::StringRef FName, llvm::StringRef WrapperName, llvm::SmallVectorImpl &Symbols, easy::Context const &C, llvm::Value* CallToUpdate) { + assert(CallToUpdate != nullptr); + assert(llvm::isa(CallToUpdate) && "CallToUpdate is not a call instruction."); + + auto &BT = easy::BitcodeTracker::GetTracker(); + SmallVector,8> ModulesToLink; + + // Collect modules to link + for (auto& Symbol : Symbols) { + auto const &Arg = C.getArgumentMapping(Symbol.ArgNo); + switch (Arg.kind()) { + case easy::ArgumentBase::AK_Ptr: { + auto const *Ptr = Arg.as(); + Constant* PtrVal = GetScalarArgument(Arg, PointerType::getUnqual(M.getContext())); + void * PtrValue = const_cast(Ptr->get()); + if(BT.hasGlobalMapping(PtrValue)) { + std::unique_ptr LM = BT.getModuleWithContext(PtrValue, M.getContext()); + ModulesToLink.push_back(std::move(LM)); + } + } break; + case easy::ArgumentBase::AK_Module: { + easy::Function const &Function = Arg.as()->get(); + auto const &Module = Function.getLLVMModule(); + std::unique_ptr LM = + easy::CloneModuleWithContext(Module, M.getContext()); + assert(LM); + easy::UnmarkEntry(*LM); + ModulesToLink.push_back(std::move(LM)); + } break; + default: + break; + } + } + + // Link modules + for(auto &LM : ModulesToLink) { + if(Linker::linkModules(M, std::move(LM), Linker::OverrideFromSrc, + [](Module &, const StringSet<> &){})) { + llvm::report_fatal_error("Failed to link with module!", true); + } + } + + if (ModulesToLink.empty()) + return false; + + // Look up the symbol + for (auto& Symbol : Symbols) { + StringRef Name = Symbol.Name; + assert(!Name.empty() && "Unnamed symbol shouldn't reach here."); + auto Kind = Symbol.Kind; + auto *GV = M.getNamedValue(Name); + switch (Kind) { + case easy::ArgumentBase::AK_Ptr: { + if (GlobalVariable *G = dyn_cast(GV)) { + GV->setLinkage(llvm::Function::PrivateLinkage); + assert(GV->getType()->isPointerTy() && "Global variable passed as ptr arg is not a pointer"); + UpdateCallArg(CallToUpdate, C, GV, Symbol.ArgNo); + } + else if (llvm::Function *F = dyn_cast(GV)) { + F->setLinkage(llvm::Function::PrivateLinkage); + UpdateCallArg(CallToUpdate, C, F, Symbol.ArgNo); + } + else { + report_fatal_error("Global varialbe passed as ptr but is not a pointer nor a function", true); + } + } break; + case easy::ArgumentBase::AK_Module: { + llvm::Function* FunctionInM = M.getFunction(Name); + FunctionInM->setLinkage(llvm::Function::PrivateLinkage); + UpdateCallArg(CallToUpdate, C, FunctionInM, Symbol.ArgNo); + } break; + default: + break; + } + + } + + return true; +} + +std::pair easy::GetConstantFromRaw(llvm::DataLayout const& DL, + llvm::Type* T, const uint8_t* Raw) { + // pack in a I8 constant vector and cast + Type* I8 = Type::getInt8Ty(T->getContext()); + size_t Size = DL.getTypeStoreSize(T); // TODO: not sure about this + + SmallVector Elements(Size, nullptr); + for(size_t i = 0; i != Size; ++i) { + Elements[i] = ConstantInt::get(I8, Raw[i]); + } + + Constant* DataAsI8 = ConstantVector::get(Elements); + Constant* DataAsT; + if(T->isPointerTy()) { + Type* TInt = DL.getIntPtrType(T->getContext()); + Constant* DataAsTSizedInt = ConstantExpr::getBitCast(DataAsI8, TInt); + DataAsT = ConstantExpr::getIntToPtr(DataAsTSizedInt, T); + } else { + DataAsT = ConstantExpr::getBitCast(DataAsI8, T); + } + return {DataAsT, Size}; +} + +static +size_t StoreStructField(llvm::IRBuilder<> &B, + llvm::DataLayout const &DL, + Type* Ty, + uint8_t const* Raw, + AllocaInst* Alloc, SmallVectorImpl &GEP) { + + StructType* STy = dyn_cast(Ty); + size_t RawOffset = 0; + if(STy) { + errs() << "struct " << *STy << "\n"; + size_t Fields = STy->getNumContainedTypes(); + for(size_t Field = 0; Field != Fields; ++Field) { + GEP.push_back(B.getInt32(Field)); + size_t Size = StoreStructField(B, DL, STy->getElementType(Field), Raw+RawOffset, Alloc, GEP); + RawOffset += Size; + GEP.pop_back(); + } + } else { + Constant* FieldValue; + std::tie(FieldValue, RawOffset) = easy::GetConstantFromRaw(DL, Ty, (uint8_t const*)Raw); + + Value* FieldPtr = B.CreateGEP(Alloc->getAllocatedType(), Alloc, GEP, "field.gep"); + B.CreateStore(FieldValue, FieldPtr); + } + return RawOffset; +} + +llvm::AllocaInst* easy::GetStructAlloc(llvm::IRBuilder<> &B, + llvm::DataLayout const &DL, + easy::StructArgument const &Struct, + llvm::Type* StructTy) { + AllocaInst* Alloc = B.CreateAlloca(StructTy); + + SmallVector GEP = {B.getInt32(0)}; + + // TODO: Data points to the data structure or holds the data structure itself ? + // Check that size matches the .data() + + size_t Size = StoreStructField(B, DL, StructTy, (uint8_t const*)Struct.get().data(), Alloc, GEP); + + return Alloc; +} diff --git a/easy-jit/runtime/pass/InlineParametersHelper.h b/easy-jit/runtime/pass/InlineParametersHelper.h new file mode 100644 index 000000000000..a4182196947f --- /dev/null +++ b/easy-jit/runtime/pass/InlineParametersHelper.h @@ -0,0 +1,58 @@ +#ifndef INLINEPARAMETERSHELPER_H +#define INLINEPARAMETERSHELPER_H + +#include +#include +#include +#include +#include + +#include + +namespace easy { + +struct HighLevelLayout { + struct HighLevelArg { + size_t Position_; + size_t FirstParamIdx_; + llvm::SmallVector Types_; + bool StructByPointer_ = false; + bool StructByArray_ = false; + + HighLevelArg(size_t Pos, size_t FirstParamIdx) : + Position_(Pos), FirstParamIdx_(FirstParamIdx) { } + explicit HighLevelArg() = default; + }; + + //StructReturn_ now is just an indicator of sret, can be opt to bool. + llvm::Type* StructReturn_; + llvm::SmallVector Args_; + llvm::Type* Return_; + + HighLevelLayout(easy::Context const& C, llvm::Function &F); +}; + +struct PostLinkageSymbol { + llvm::StringRef Name; + ArgumentBase::ArgumentKind Kind; + size_t ArgNo; +}; + +llvm::SmallVector GetForwardArgs(easy::HighLevelLayout::HighLevelArg &ArgInF, easy::HighLevelLayout &FHLL, + llvm::Function &Wrapper, easy::HighLevelLayout &WrapperHLL); +llvm::Constant* GetScalarArgument(easy::ArgumentBase const& Arg, llvm::Type* T); + +llvm::StringRef GetGlobalName(llvm::Module &M, easy::PtrArgument const &Ptr); + +// Return true if any linkage happened +bool LinkAndUpdateSymbol(llvm::Module &M, llvm::StringRef FName, llvm::StringRef WrapperName, llvm::SmallVectorImpl &Symbols, easy::Context const &C, llvm::Value* CallToUpdate); + +llvm::AllocaInst* GetStructAlloc(llvm::IRBuilder<> &B, llvm::DataLayout const &DL, easy::StructArgument const &Struct, llvm::Type* StructTy); + +std::pair GetConstantFromRaw(llvm::DataLayout const& DL, llvm::Type* T, const uint8_t* Raw); + +std::pair GetConstantFromRaw(llvm::DataLayout const& DL, llvm::Type* T, const uint8_t* Raw); + +} + +#endif // INLINEPARAMETERSHELPER_H diff --git a/easy-jit/tests/doc/lit.cfg.in b/easy-jit/tests/doc/lit.cfg.in new file mode 100644 index 000000000000..6954458e638e --- /dev/null +++ b/easy-jit/tests/doc/lit.cfg.in @@ -0,0 +1,12 @@ +import lit.formats +import lit.util + +from subprocess import call + +lit_config.load_config(config, os.path.join("@CMAKE_CURRENT_BINARY_DIR@", "./tests/lit.cfg")) +config.test_source_root = "@CMAKE_CURRENT_SOURCE_DIR@/doc" +config.test_exec_root = "@CMAKE_CURRENT_BINARY_DIR@/tests/doc" + +# for the documentation example +if "@EASY_JIT_EXAMPLE@" in ["1", "ON"]: + config.available_features.add('example') diff --git a/easy-jit/tests/inlineparam/convolve.cpp b/easy-jit/tests/inlineparam/convolve.cpp new file mode 100644 index 000000000000..73aa6ba73432 --- /dev/null +++ b/easy-jit/tests/inlineparam/convolve.cpp @@ -0,0 +1,45 @@ +// RUN: %clangxx %cxxflags %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t +// RUN: %t > %t.out + +#include + +#include +#include +#include + +using namespace std::placeholders; + +void __attribute__((noinline)) kernel(int n, int m, int * image, int const * mask, int* out) { + int i = 0; + int j = 0; + int k = 0; + int l = 0; + out[i * (n-m+1) + j] += image[(i+k) * n + j+l] * mask[k *m + l]; +} + +void test_convolve() { + std::vector image(16*16,0); + std::vector out((16-3)*(16-3),0); + std::vector out_nonjit((16-3)*(16-3), 0); + + static const int mask[3][3] = {{1,2,3},{0,0,0},{3,2,1}}; + + auto my_kernel = easy::jit(kernel, 16, 3, _1, &mask[0][0], _2); + + my_kernel(image.data(), out.data()); + + kernel(16, 3, image.data(), &mask[0][0], out_nonjit.data()); + + for(int i = 0; i != out.size(); ++i) { + if(out[i] != out_nonjit[i]) { + printf("%d != %d\n", out[i], out_nonjit[i]); + exit(-1); + } + } +} + +int main() { + test_convolve(); + return 0; +} + \ No newline at end of file diff --git a/easy-jit/tests/install/CMakeLists.txt b/easy-jit/tests/install/CMakeLists.txt new file mode 100644 index 000000000000..2506ae2b972c --- /dev/null +++ b/easy-jit/tests/install/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.4.3) + +project(test) + +find_package(EasyJit REQUIRED CONFIG) + +message("Easy::Jit include dir: " ${EasyJit_INCLUDE_DIRS}) +message("Easy::Jit lib dir: " ${EasyJit_LIBRARY_DIRS}) +message("Easy::Jit runtime: " ${EasyJit_LIBRARY}) +message("Easy::Jit plugin: " ${EasyJit_PLUGIN}) + +include_directories(${EasyJit_INCLUDE_DIRS}) +link_directories(${EasyJit_LIBRARY_DIRS}) + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --std=c++14 -Xclang -disable-O0-optnone -Xclang -load -Xclang ${EasyJit_PLUGIN} -Xclang -fpass-plugin=${EasyJit_PLUGIN}") + +add_executable(InstallTest + test.cpp +) + +target_link_libraries(InstallTest ${EasyJit_LIBRARY}) diff --git a/easy-jit/tests/install/test.cpp b/easy-jit/tests/install/test.cpp new file mode 100644 index 000000000000..75674407b7e4 --- /dev/null +++ b/easy-jit/tests/install/test.cpp @@ -0,0 +1,34 @@ +// REQUIRES: install +// +// clean before, if not there may be unconsistencies +// RUN: rm -fr build.ninja CMakeCache.txt CMakeFiles cmake_install.cmake InstallTest rules.ninja +// +// RUN: cmake -DCMAKE_CXX_COMPILER=%clang++ -DEasyJit_DIR=%install_dir/lib/cmake %S -G Ninja +// RUN: cmake --build . +// RUN: ./InstallTest > %t.out +// RUN: %FileCheck %s < %t.out + +#include +#include + +#include +#include + +using namespace std::placeholders; + +void test(int a) { + printf("this is a test %d!\n", a); +} + +int main() { + easy::Cache<> C; + auto test_jit0 = easy::jit(test, 0); + auto const &test_jit1 = C.jit(test, 1); + + // CHECK: this is a test 0! + // CHECK: this is a test 1! + test_jit0(); + test_jit1(); + + return 0; +} diff --git a/easy-jit/tests/lit.cfg.in b/easy-jit/tests/lit.cfg.in new file mode 100644 index 000000000000..463be704d29a --- /dev/null +++ b/easy-jit/tests/lit.cfg.in @@ -0,0 +1,54 @@ +import lit.formats +import lit.util +import os + +config.name = 'easy_jit' +config.suffixes = ['.c', '.cpp', '.ll', '.test'] + +config.test_format = lit.formats.ShTest(True) + +config.test_source_root = "@CMAKE_CURRENT_SOURCE_DIR@/tests" +config.test_exec_root = "@CMAKE_CURRENT_BINARY_DIR@/tests" + +config.environment['PATH'] = os.pathsep.join(["@LLVM_TOOLS_BINARY_DIR@"] + [ config.environment['PATH'] ]) + +runtime_lib = os.path.basename("@EASY_JIT_RUNTIME@").split('.')[0].replace("lib", "", 1) +runtime_lib_dir = os.path.dirname("@EASY_JIT_RUNTIME@") +llvm_lib_dir = os.path.join(os.path.dirname("@LLVM_TOOLS_BINARY_DIR@"), "lib") + +includes = ["@EASY_JIT_ROOT@"] +include_flags = " ".join(["-I'" + os.path.abspath(dir) + "'" for dir in "@LLVM_INCLUDE_DIRS@".split()] + ["-I'" + os.path.join(dir, "include") + "'" for dir in includes] ) + +ld_paths = [runtime_lib_dir, llvm_lib_dir] +ld_flags = "" +for ld_path in ld_paths: + ld_flags = ld_flags + " -L'" + os.path.abspath(ld_path) + "' -rpath '" + os.path.abspath(ld_path) + "' " + +ld_flags = ld_flags + " -l" + runtime_lib + +# substitutions +config.substitutions.append(('%bin', "@CMAKE_ARCHIVE_OUTPUT_DIRECTORY@")) +config.substitutions.append(('%install_dir', "@CMAKE_INSTALL_PREFIX@")) +config.substitutions.append(('%llvm_tools_dir', "@LLVM_TOOLS_BINARY_DIR@")) + +common_flags = "-g -Xclang -disable-O0-optnone " + +config.substitutions.append(('%clangxx', os.path.join("@LLVM_TOOLS_BINARY_DIR@", "clang++"))) +config.substitutions.append(('%clang', os.path.join("@LLVM_TOOLS_BINARY_DIR@", "clang"))) +config.substitutions.append(('%opt', os.path.join("@LLVM_TOOLS_BINARY_DIR@", "opt"))) +config.substitutions.append(('%cxxflags', common_flags + "--std=c++14")) +config.substitutions.append(('%cflags', common_flags)) +config.substitutions.append(('%include_flags', include_flags)) +config.substitutions.append(('%lib_pass', "@EASY_JIT_PASS@")) +config.substitutions.append(('%lib_runtime', "@EASY_JIT_RUNTIME@")) +config.substitutions.append(('%ld_flags', ld_flags)) + +config.substitutions.append(('%not', "!")) + +config.substitutions.append(('%FileCheck', os.path.join("@LLVM_TOOLS_BINARY_DIR@", "FileCheck"))) + +if "@EASY_JIT_BENCHMARK@" in ["1", "ON"] : + config.available_features.add('benchmark') + +if "@CMAKE_INSTALL_PREFIX@" and os.path.exists(os.path.join("@CMAKE_INSTALL_PREFIX@", "include", "easy")): + config.available_features.add('install') diff --git a/easy-jit/tests/meta/bad_signature_a.cpp b/easy-jit/tests/meta/bad_signature_a.cpp new file mode 100644 index 000000000000..ee030f0599fb --- /dev/null +++ b/easy-jit/tests/meta/bad_signature_a.cpp @@ -0,0 +1,19 @@ +// RUN: %not %clangxx %cxxflags -O2 %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t 2> %t.log +// RUN: %FileCheck %s < %t.log + +#include +#include + +// CHECK: An easy::jit option is expected + +using namespace std::placeholders; + +int foo(int) { + return 0; +} + +int main(int, char** argv) { + + auto foo_ = easy::jit(foo, 1, 2); + return 0; +} diff --git a/easy-jit/tests/meta/bad_signature_b.cpp b/easy-jit/tests/meta/bad_signature_b.cpp new file mode 100644 index 000000000000..92602b3c947e --- /dev/null +++ b/easy-jit/tests/meta/bad_signature_b.cpp @@ -0,0 +1,18 @@ +// RUN: %not %clangxx %cxxflags -O2 %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t 2> %t.log +// RUN: %FileCheck %s < %t.log + +#include +#include + +using namespace std::placeholders; + +int foo(int, int, int) { + return 0; +} + +int main(int, char** argv) { + + auto foo_ = easy::jit(foo, 1, 2); + foo_(); // CHECK: easy::jit: not providing enough argument to actual call + return 0; +} diff --git a/easy-jit/tests/meta/bad_signature_c.cpp b/easy-jit/tests/meta/bad_signature_c.cpp new file mode 100644 index 000000000000..278f5337e5f7 --- /dev/null +++ b/easy-jit/tests/meta/bad_signature_c.cpp @@ -0,0 +1,19 @@ +// RUN: %not %clangxx %cxxflags -O2 %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t 2> %t.log +// RUN: %FileCheck %s < %t.log + +#include +#include + +// CHECK: Invalid bind, placeholder cannot be bound to a formal argument + +using namespace std::placeholders; + +int foo(float) { + return 0; +} + +int main(int, char** argv) { + + auto foo_ = easy::jit(foo, _2); + return 0; +} diff --git a/easy-jit/tests/meta/new_func_traits.cpp b/easy-jit/tests/meta/new_func_traits.cpp new file mode 100644 index 000000000000..0355ff2a6f1a --- /dev/null +++ b/easy-jit/tests/meta/new_func_traits.cpp @@ -0,0 +1,66 @@ +// RUN: %clangxx %cxxflags %include_flags %s -o /dev/null + +#include +#include +#include + +using namespace easy; +using namespace easy::meta; +using namespace std::placeholders; + +int foo(int, bool, float, int); +int baz(int, bool); + +int main() { + + using foo_type = decltype(foo); + using baz_type = decltype(baz); + using new_foo_traits_a = new_function_traits>; + using new_foo_traits_b = new_function_traits>; + using new_foo_traits_c = new_function_traits>; + using new_foo_traits_d = new_function_traits>; + using new_foo_traits_e = new_function_traits>; + using new_foo_traits_f = new_function_traits>; + using new_baz_traits_g = new_function_traits>; + using new_baz_traits_h = new_function_traits>; + + // full specialization + static_assert(new_foo_traits_a::parameter_list::empty, "fail A not empty"); + static_assert(new_foo_traits_b::parameter_list::empty, "fail B not empty"); + static_assert(new_foo_traits_c::parameter_list::empty, "fail C not empty"); + + // two int parameters + static_assert(new_foo_traits_d::parameter_list::size == 2, "fail D size"); + static_assert(std::is_same< + typename new_foo_traits_d::parameter_list, + meta::type_list + >::value, "fail D types"); + + // one int parameter + static_assert(new_foo_traits_e::parameter_list::size == 1, "fail E size"); + static_assert(new_foo_traits_f::parameter_list::size == 2, "fail F size"); + + static_assert(std::is_same< + typename new_foo_traits_e::parameter_list, + meta::type_list + >::value, "fail E types"); + static_assert(std::is_same< + typename new_foo_traits_f::parameter_list, + meta::type_list + >::value, "fail F types"); + + static_assert(new_baz_traits_g::parameter_list::size == 2, "fail G size"); + static_assert(new_baz_traits_h::parameter_list::size == 2, "fail H size"); + + static_assert(std::is_same< + typename new_baz_traits_g::parameter_list, + meta::type_list + >::value, "fail G types"); + + static_assert(std::is_same< + typename new_baz_traits_h::parameter_list, + meta::type_list + >::value, "fail H types"); + + return 0; +} diff --git a/easy-jit/tests/meta/type_list+func_traits.cpp b/easy-jit/tests/meta/type_list+func_traits.cpp new file mode 100644 index 000000000000..483db38eaa49 --- /dev/null +++ b/easy-jit/tests/meta/type_list+func_traits.cpp @@ -0,0 +1,58 @@ +// RUN: %clangxx %cxxflags %include_flags %s -o /dev/null + +#include +#include + +using namespace easy; +using namespace easy::meta; + +int foo(int, bool, float); + +int main() { + static_assert(std::is_same< + type_list::head, + int>::value, + "not same type"); + + static_assert(std::is_same< + type_list::at<0>, + int>::value, + "not same type"); + static_assert(std::is_same< + type_list::at<1>, + bool>::value, + "not same type"); + static_assert(std::is_same< + type_list::at<2>, + float>::value, + "not same type"); + static_assert(type_list::size == 3, + "not correct size"); + static_assert(!type_list::empty, + "detected as empty"); + static_assert(std::is_same< + type_list::tail::head, + bool>::value, + "not same type"); + + using foo_type = decltype(foo); + using foo_traits = function_traits; + + static_assert(std::is_same::value, + "not same type"); + static_assert(std::is_same< + foo_traits::parameter_list, + type_list>::value, + "not same type"); + + static_assert(std::is_same< + typename meta::init_list<3,void>::type, + type_list>::value, + "not same type"); + static_assert(std::is_same< + typename meta::init_list<0,void>::type, + type_list<>>::value, + "not same type"); + + return 0; +} diff --git a/easy-jit/tests/simple/cache.cpp b/easy-jit/tests/simple/cache.cpp new file mode 100644 index 000000000000..06a99171ecfc --- /dev/null +++ b/easy-jit/tests/simple/cache.cpp @@ -0,0 +1,37 @@ +// RUN: %clangxx %cxxflags %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t +// RUN: %t > %t.out +// RUN: %FileCheck %s < %t.out + +#include + +#include +#include + +using namespace std::placeholders; + +int add (int a, int b) { + return a+b; +} + +int main() { + easy::Cache<> C; + + // CHECK: inc(4) is 5 + // CHECK: inc(5) is 6 + // CHECK: inc(6) is 7 + // CHECK: inc(7) is 8 + + for(int i = 0; i != 16; ++i) { + auto const &inc = C.jit(add, _1, 1); + + if(!C.has(add, _1, 1)) { + printf("code not in cache!\n"); + return -1; + } + + for(int v = 4; v != 8; ++v) + printf("inc(%d) is %d\n", v, inc(v)); + } + + return 0; +} diff --git a/easy-jit/tests/simple/compose_bad.cpp b/easy-jit/tests/simple/compose_bad.cpp new file mode 100644 index 000000000000..ac8208789cdf --- /dev/null +++ b/easy-jit/tests/simple/compose_bad.cpp @@ -0,0 +1,28 @@ +// RUN: %not %clangxx %cxxflags %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t + +#include + +#include +#include +#include + +using namespace std::placeholders; + +float mul(float a, float b) { + return a*b; +} + +int accumulate(std::vector const &vec, int acum, int(*fun)(int)) { + int a = acum; + for(int e : vec) + a += fun(e); + return a; +} + +int main(int argc, char** argv) { + + easy::FunctionWrapper mul_by_two = easy::jit(mul, _1, 2.0); + easy::FunctionWrapper const&)> mul_vector_by_two = easy::jit(accumulate, _1, 0, mul_by_two); + + return 0; +} diff --git a/easy-jit/tests/simple/compose_ptr.cpp b/easy-jit/tests/simple/compose_ptr.cpp new file mode 100644 index 000000000000..064a5a97111c --- /dev/null +++ b/easy-jit/tests/simple/compose_ptr.cpp @@ -0,0 +1,56 @@ +// RUN: %clangxx %cxxflags %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t +// RUN: %t 8 1 2 3 4 5 6 7 8 %t.ll > %t.out +// RUN: %FileCheck %s < %t.out +// RUN: %FileCheck --check-prefix=CHECK-IR %s < %t.ll +// +// CHECK: 72 +// +// only one function in the final IR +// CHECK-IR: define + +#include + +#include +#include +#include + +using namespace std::placeholders; + +int mul(int a, int b) { + return a*b; +} + +int accumulate(std::vector const &vec, int acum, int(*fun)(int)) { + int a = acum; + for(int e : vec) + a += fun(e); + return a; +} + +int main(int argc, char** argv) { + + int n = atoi(argv[1]); + + // read input + std::vector vec; + for(int i = 0; i != n; ++i) + vec.emplace_back(atoi(argv[i+2])); + + // generate code + easy::FunctionWrapper mul_by_two = easy::jit(mul, _1, 2); + + static_assert(easy::is_function_wrapper::value, "Value not detected as function wrapper!"); + static_assert(easy::is_function_wrapper::value, "Reference not detected as function wrapper!"); + static_assert(easy::is_function_wrapper::value, "RReference not detected as function wrapper!"); + + easy::FunctionWrapper const&)> mul_vector_by_two = easy::jit(accumulate, _1, 0, mul_by_two, + easy::options::dump_ir(argv[argc-1])); + + // kernel! + int result = mul_vector_by_two(vec); + + // output + printf("%d\n", result); + + return 0; +} diff --git a/easy-jit/tests/simple/compose_ref.cpp b/easy-jit/tests/simple/compose_ref.cpp new file mode 100644 index 000000000000..c01be958bbbf --- /dev/null +++ b/easy-jit/tests/simple/compose_ref.cpp @@ -0,0 +1,52 @@ +// RUN: %clangxx %cxxflags %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t +// RUN: %t 8 1 2 3 4 5 6 7 8 %t.ll > %t.out +// RUN: %FileCheck %s < %t.out +// RUN: %FileCheck --check-prefix=CHECK-IR %s < %t.ll +// +// CHECK: 72 +// +// only one function in the final IR +// CHECK-IR: define +// CHECK-IR: define + +#include + +#include +#include +#include + +using namespace std::placeholders; + +int mul(int a, int b) { + return a*b; +} + +int accumulate(std::vector const &vec, int acum, int(&fun)(int)) { + int a = acum; + for(int e : vec) + a += fun(e); + return a; +} + +int main(int argc, char** argv) { + + int n = atoi(argv[1]); + + // read input + std::vector vec; + for(int i = 0; i != n; ++i) + vec.emplace_back(atoi(argv[i+2])); + + // generate code + easy::FunctionWrapper mul_by_two = easy::jit(mul, _1, 2); + easy::FunctionWrapper const&)> mul_vector_by_two = easy::jit(accumulate, _1, 0, mul_by_two, + easy::options::dump_ir(argv[argc-1])); + + // kernel! + int result = mul_vector_by_two(vec); + + // output + printf("%d\n", result); + + return 0; +} diff --git a/easy-jit/tests/simple/custom_key_cache.cpp b/easy-jit/tests/simple/custom_key_cache.cpp new file mode 100644 index 000000000000..bfea3398e0e0 --- /dev/null +++ b/easy-jit/tests/simple/custom_key_cache.cpp @@ -0,0 +1,65 @@ +// RUN: %clangxx %cxxflags %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t +// RUN: %t > %t.out +// RUN: %FileCheck %s < %t.out + +#include + +#include +#include +#include + +using namespace std::placeholders; + +int add (int a, int b) { + return a+b; +} + +void test_int() { + easy::Cache C; + + for(int i = 0; i != 6; ++i) { + auto const &inc = C.jit(i, add, _1, i); + + if(!C.has(i)) { + printf("code not in cache!\n"); + } + + // CHECK-NOT: code not in cache + // CHECK: inc.int(0) is 0 + // CHECK: inc.int(0) is 1 + // CHECK: inc.int(0) is 2 + // CHECK: inc.int(0) is 3 + // CHECK: inc.int(0) is 4 + // CHECK: inc.int(0) is 5 + + printf("inc.int(%d) is %d\n", 0, inc(0)); + } +} + +void test_string() { + easy::Cache C; + + for(int i = 0; i != 6; ++i) { + auto const &inc = C.jit(std::to_string(i), add, _1, i); + + if(!C.has(std::to_string(i))) { + printf("code not in cache!\n"); + } + + // CHECK-NOT: code not in cache + // CHECK: inc.str(0) is 0 + // CHECK: inc.str(0) is 1 + // CHECK: inc.str(0) is 2 + // CHECK: inc.str(0) is 3 + // CHECK: inc.str(0) is 4 + // CHECK: inc.str(0) is 5 + + printf("inc.str(%d) is %d\n", 0, inc(0)); + } +} + +int main() { + test_int(); + test_string(); + return 0; +} diff --git a/easy-jit/tests/simple/devirtualization.cpp b/easy-jit/tests/simple/devirtualization.cpp new file mode 100644 index 000000000000..ab1a3cb99b01 --- /dev/null +++ b/easy-jit/tests/simple/devirtualization.cpp @@ -0,0 +1,42 @@ +// RUN: %clangxx %cxxflags -O2 %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t +// RUN: %t "%t.ll" > %t.out +// RUN: %FileCheck %s < %t.out + +#include +#include + +#include +#include + + +using namespace std::placeholders; + +struct Foo { + virtual int EASY_JIT_EXPOSE doit() { return 1; } + virtual ~Foo() = default; +}; + +struct Bar : Foo { + int EASY_JIT_EXPOSE doit() override { return 2; } +}; + +int doit(Foo* f) { + return f->doit(); +} + +int main(int argc, char** argv) { + Foo* f = nullptr; + if(argc == 1) + f = new Foo(); + else + f = new Bar(); + + easy::FunctionWrapper easy_doit = easy::jit(doit, f, easy::options::dump_ir(argv[1])); + + // CHECK: doit() is 2 + printf("doit() is %d\n", easy_doit()); + + delete f; + + return 0; +} diff --git a/easy-jit/tests/simple/devirtualization_nohint.cpp b/easy-jit/tests/simple/devirtualization_nohint.cpp new file mode 100644 index 000000000000..7c5275a6da69 --- /dev/null +++ b/easy-jit/tests/simple/devirtualization_nohint.cpp @@ -0,0 +1,41 @@ +// RUN: %clangxx %cxxflags -O2 %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t +// RUN: %t "%t.ll" > %t.out +// RUN: %FileCheck %s < %t.out + +#include +#include + +#include +#include + +using namespace std::placeholders; + +struct Foo { + virtual int doit() { return 1; } + virtual ~Foo() = default; +}; + +struct Bar : Foo { + int doit() override { return 2; } +}; + +int doit(Foo* f) { + return f->doit(); +} + +int main(int argc, char** argv) { + Foo* f = nullptr; + if(argc == 1) + f = new Foo(); + else + f = new Bar(); + + easy::FunctionWrapper easy_doit = easy::jit(doit, f, easy::options::dump_ir(argv[1])); + + // CHECK: doit() is 2 + printf("doit() is %d\n", easy_doit()); + + delete f; + + return 0; +} diff --git a/easy-jit/tests/simple/double_a.cpp b/easy-jit/tests/simple/double_a.cpp new file mode 100644 index 000000000000..693a98c87012 --- /dev/null +++ b/easy-jit/tests/simple/double_a.cpp @@ -0,0 +1,27 @@ +// RUN: %clangxx %cxxflags %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t +// RUN: %t > %t.out +// RUN: %FileCheck %s < %t.out + +#include + +#include +#include + +using namespace std::placeholders; + +double add (double a, double b) { + return a+b; +} + +int main() { + easy::FunctionWrapper inc = easy::jit(add, _1, 1); + + // CHECK: inc(4.00) is 5.00 + // CHECK: inc(5.00) is 6.00 + // CHECK: inc(6.00) is 7.00 + // CHECK: inc(7.00) is 8.00 + for(int v = 4; v != 8; ++v) + printf("inc(%.2f) is %.2f\n", (double)v, inc(v)); + + return 0; +} diff --git a/easy-jit/tests/simple/exception_a.cpp b/easy-jit/tests/simple/exception_a.cpp new file mode 100644 index 000000000000..e08de0d14029 --- /dev/null +++ b/easy-jit/tests/simple/exception_a.cpp @@ -0,0 +1,36 @@ +// RUN: %clangxx %cxxflags %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t +// RUN: %t > %t.out +// RUN: %FileCheck %s < %t.out + +#include + +#include +#include + +using namespace std::placeholders; + +int add (int a, int b) { + if(a == 8) + throw std::runtime_error{"an expected error occured"}; + return a+b; +} + +int main() { + easy::FunctionWrapper inc = easy::jit(add, _1, 1); + + // CHECK: inc(4) is 5 + // CHECK: inc(5) is 6 + // CHECK: inc(6) is 7 + // CHECK: inc(7) is 8 + // CHECK: inc(8) is exception: an expected error occured + // CHECK: inc(9) is 10 + for(int v = 4; v != 10; ++v) { + try { + printf("inc(%d) is %d\n", v, inc(v)); + } catch(std::runtime_error &e) { + printf("inc(%d) is exception: %s\n", v, e.what()); + } + } + + return 0; +} diff --git a/easy-jit/tests/simple/float_a.cpp b/easy-jit/tests/simple/float_a.cpp new file mode 100644 index 000000000000..2951af105388 --- /dev/null +++ b/easy-jit/tests/simple/float_a.cpp @@ -0,0 +1,27 @@ +// RUN: %clangxx %cxxflags %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t +// RUN: %t > %t.out +// RUN: %FileCheck %s < %t.out + +#include + +#include +#include + +using namespace std::placeholders; + +float add (float a, float b) { + return a+b; +} + +int main() { + easy::FunctionWrapper inc = easy::jit(add, _1, 1); + + // CHECK: inc(4.00) is 5.00 + // CHECK: inc(5.00) is 6.00 + // CHECK: inc(6.00) is 7.00 + // CHECK: inc(7.00) is 8.00 + for(int v = 4; v != 8; ++v) + printf("inc(%.2f) is %.2f\n", (float)v, inc(v)); + + return 0; +} diff --git a/easy-jit/tests/simple/fun_ptr_a.cpp b/easy-jit/tests/simple/fun_ptr_a.cpp new file mode 100644 index 000000000000..8baf94dda274 --- /dev/null +++ b/easy-jit/tests/simple/fun_ptr_a.cpp @@ -0,0 +1,42 @@ +// RUN: %clangxx %cxxflags %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t +// RUN: %t "%t.ll" > %t.out +// RUN: %FileCheck %s < %t.out +// RUN: %FileCheck --check-prefix=CHECK-IR %s < %t.ll + +#include +#include + +#include +#include + +// only one function +// reading from a global variable +// CHECK-IR: @[[GLOBAL:.+]] = external +// CHECK-IR: define +// CHECK-IR: add +// CHECK-IR: ret + + +using namespace std::placeholders; + +static int bubu() { + static int v = 0; + return v++; +} + +static int add (int a, int (*f)()) { + return a+f(); +} + +int main(int argc, char** argv) { + easy::FunctionWrapper inc = easy::jit(add, _1, bubu, easy::options::dump_ir(argv[1])); + + // CHECK: inc(4) is 4 + // CHECK: inc(5) is 6 + // CHECK: inc(6) is 8 + // CHECK: inc(7) is 10 + for(int v = 4; v != 8; ++v) + printf("inc(%d) is %d\n", v, inc(v)); + + return 0; +} diff --git a/easy-jit/tests/simple/fun_ptr_b.cpp b/easy-jit/tests/simple/fun_ptr_b.cpp new file mode 100644 index 000000000000..bae22d1361d0 --- /dev/null +++ b/easy-jit/tests/simple/fun_ptr_b.cpp @@ -0,0 +1,41 @@ +// RUN: %clangxx %cxxflags %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t +// RUN: %t "%t.ll" > %t.out +// RUN: %FileCheck %s < %t.out +// RUN: %FileCheck --check-prefix=CHECK-IR %s < %t.ll + +#include +#include + +#include +#include + +// only one function, without any call +// CHECK-IR: call{{.*@.*}} + + +using namespace std::placeholders; + +static void foo(void* dat) { + (*(int*)dat) += 1; +} + +static void map (void* data, unsigned nmemb, unsigned size, void (*f)(void*)) { + for(unsigned i = 0; i < nmemb; ++i) + f((char*)data + i * size); +} + +int main(int argc, char** argv) { + easy::FunctionWrapper map_w = easy::jit(map, _1, _2, _3, foo, easy::options::dump_ir(argv[1])); + + int data[] = {1,2,3,4}; + map_w(data, sizeof(data)/sizeof(data[0]), sizeof(data[0])); + + // CHECK: data[0] is 2 + // CHECK: data[1] is 3 + // CHECK: data[2] is 4 + // CHECK: data[3] is 5 + for(int v = 0; v != 4; ++v) + printf("data[%d] is %d\n", v, data[v]); + + return 0; +} diff --git a/easy-jit/tests/simple/fun_ptr_c.cpp b/easy-jit/tests/simple/fun_ptr_c.cpp new file mode 100644 index 000000000000..2590bf653cfc --- /dev/null +++ b/easy-jit/tests/simple/fun_ptr_c.cpp @@ -0,0 +1,47 @@ +// RUN: %clangxx %cxxflags %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t +// RUN: %t "%t.ll" > %t.out +// RUN: %FileCheck %s < %t.out +// RUN: %FileCheck --check-prefix=CHECK-IR %s < %t.ll + +#include +#include + +#include +#include + +// only one function, without any call +// CHECK-IR: call{{ }} + + +using namespace std::placeholders; + +static void foo(void* dat) { + (*(int*)dat) += 1; +} +static void bar(void* dat) { + (*(int*)dat) += 2; +} + +static void map (void* data, unsigned nmemb, unsigned size, void (*f)(void*)) { + for(unsigned i = 0; i < nmemb; ++i) + f((char*)data + i * size); +} + +int main(int argc, char** argv) { + + static void (*(come_and_get_some[]))(void*dat) = {foo, bar}; + + easy::FunctionWrapper map_w = easy::jit(map, _1, _2, _3, come_and_get_some[argc?1:0], easy::options::dump_ir(argv[1])); + + int data[] = {1,2,3,4}; + map_w(data, sizeof(data)/sizeof(data[0]), sizeof(data[0])); + + // CHECK: data[0] is 3 + // CHECK: data[1] is 4 + // CHECK: data[2] is 5 + // CHECK: data[3] is 6 + for(int v = 0; v != 4; ++v) + printf("data[%d] is %d\n", v, data[v]); + + return 0; +} diff --git a/easy-jit/tests/simple/fun_ptr_d.cpp b/easy-jit/tests/simple/fun_ptr_d.cpp new file mode 100644 index 000000000000..34ea293c47e3 --- /dev/null +++ b/easy-jit/tests/simple/fun_ptr_d.cpp @@ -0,0 +1,45 @@ +// RUN: %clangxx %cxxflags %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t +// RUN: %t "%t.ll" > %t.out +// RUN: %FileCheck %s < %t.out +// RUN: %FileCheck --check-prefix=CHECK-IR %s < %t.ll + +#include +#include + +#include +#include + +// only one function +// reading from a global variable +// CHECK-IR: @[[GLOBAL:.+]] = external +// CHECK-IR: define +// CHECK-IR: add +// CHECK-IR: ret + + +using namespace std::placeholders; + +static int bubu() { + static int v = 0; + return v++; +} +static int bibi() { + return 0; +} + +static int add (int a, int (*f)()) { + return a+f(); +} + +int main(int argc, char** argv) { + easy::FunctionWrapper inc = easy::jit(add, _1, argc?bubu:bibi, easy::options::dump_ir(argv[1])); + + // CHECK: inc(4) is 4 + // CHECK: inc(5) is 6 + // CHECK: inc(6) is 8 + // CHECK: inc(7) is 10 + for(int v = 4; v != 8; ++v) + printf("inc(%d) is %d\n", v, inc(v)); + + return 0; +} diff --git a/easy-jit/tests/simple/fun_ptr_e.cpp b/easy-jit/tests/simple/fun_ptr_e.cpp new file mode 100644 index 000000000000..5ae0bde95baf --- /dev/null +++ b/easy-jit/tests/simple/fun_ptr_e.cpp @@ -0,0 +1,49 @@ +// RUN: %clangxx %cxxflags %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t +// RUN: %t "%t.ll" > %t.out +// RUN: %FileCheck %s < %t.out +// RUN: %FileCheck --check-prefix=CHECK-IR %s < %t.ll + +#include +#include + +#include +#include + +// only one function, without any call +// CHECK-IR: call{{ }} + + +using namespace std::placeholders; + +static void foo(void* dat) { + (*(int*)dat) += 1; +} +static void bar(void* dat) { + (*(int*)dat) += 2; +} + +static void map (void* data, unsigned nmemb, unsigned size, void (*f)(void*)) { + for(unsigned i = 0; i < nmemb; ++i) + f((char*)data + i * size); +} + +int main(int argc, char** argv) { + + void (*(come_and_get_some[2]))(void*dat); + come_and_get_some[0] = foo; + come_and_get_some[1] = bar; + + easy::FunctionWrapper map_w = easy::jit(map, _1, _2, _3, come_and_get_some[argc?1:0], easy::options::dump_ir(argv[1])); + + int data[] = {1,2,3,4}; + map_w(data, sizeof(data)/sizeof(data[0]), sizeof(data[0])); + + // CHECK: data[0] is 3 + // CHECK: data[1] is 4 + // CHECK: data[2] is 5 + // CHECK: data[3] is 6 + for(int v = 0; v != 4; ++v) + printf("data[%d] is %d\n", v, data[v]); + + return 0; +} diff --git a/easy-jit/tests/simple/fun_ptr_f.cpp b/easy-jit/tests/simple/fun_ptr_f.cpp new file mode 100644 index 000000000000..f51b2b6706d6 --- /dev/null +++ b/easy-jit/tests/simple/fun_ptr_f.cpp @@ -0,0 +1,47 @@ +// RUN: %clangxx %cxxflags %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t +// RUN: %t "%t.ll" > %t.out +// RUN: %FileCheck %s < %t.out +// RUN: %FileCheck --check-prefix=CHECK-IR %s < %t.ll + +#include +#include + +#include +#include + +// only one function, without any call +// CHECK-IR: call{{ }} + + +using namespace std::placeholders; + +static void foo(void* dat) { + (*(int*)dat) += 1; +} +static void bar(void* dat) { + (*(int*)dat) += 2; +} + +static void map (void* data, unsigned nmemb, unsigned size, void (*f)(void*)) { + for(unsigned i = 0; i < nmemb; ++i) + f((char*)data + i * size); +} + +int main(int argc, char** argv) { + + void (*(come_and_get_some[2]))(void*dat) = {foo, bar}; + + easy::FunctionWrapper map_w = easy::jit(map, _1, _2, _3, come_and_get_some[argc?1:0], easy::options::dump_ir(argv[1])); + + int data[] = {1,2,3,4}; + map_w(data, sizeof(data)/sizeof(data[0]), sizeof(data[0])); + + // CHECK: data[0] is 3 + // CHECK: data[1] is 4 + // CHECK: data[2] is 5 + // CHECK: data[3] is 6 + for(int v = 0; v != 4; ++v) + printf("data[%d] is %d\n", v, data[v]); + + return 0; +} diff --git a/easy-jit/tests/simple/int_a.cpp b/easy-jit/tests/simple/int_a.cpp new file mode 100644 index 000000000000..9258a6b5a598 --- /dev/null +++ b/easy-jit/tests/simple/int_a.cpp @@ -0,0 +1,27 @@ +// RUN: %clangxx %cxxflags %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t +// RUN: %t > %t.out +// RUN: %FileCheck %s < %t.out + +#include + +#include +#include + +using namespace std::placeholders; + +int add (int a, int b) { + return a+b; +} + +int main() { + easy::FunctionWrapper inc = easy::jit(add, _1, 1); + + // CHECK: inc(4) is 5 + // CHECK: inc(5) is 6 + // CHECK: inc(6) is 7 + // CHECK: inc(7) is 8 + for(int v = 4; v != 8; ++v) + printf("inc(%d) is %d\n", v, inc(v)); + + return 0; +} diff --git a/easy-jit/tests/simple/int_ptr_a.cpp b/easy-jit/tests/simple/int_ptr_a.cpp new file mode 100644 index 000000000000..c7bd542d482e --- /dev/null +++ b/easy-jit/tests/simple/int_ptr_a.cpp @@ -0,0 +1,36 @@ +// RUN: %clangxx %cxxflags %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t +// RUN: %t "%t.ll" > %t.out +// RUN: %FileCheck %s < %t.out +// RUN: %FileCheck --check-prefix=CHECK-IR %s < %t.ll + +#include +#include + +#include +#include + +// verify that the variable 'b' is not loaded, and the addition is performed using its constant value +// CHECK-IR-NOT: inttoptr +// CHECK-IR-NOT: load i32 +// CHECK-IR: add{{.*}}4321 + +using namespace std::placeholders; + +static int add (int a, int const *b) { + return a+*b; +} + +int const b = 4321; + +int main(int argc, char** argv) { + easy::FunctionWrapper inc = easy::jit(add, _1, &b, easy::options::dump_ir(argv[1])); + + // CHECK: inc(4) is 4325 + // CHECK: inc(5) is 4326 + // CHECK: inc(6) is 4327 + // CHECK: inc(7) is 4328 + for(int v = 4; v != 8; ++v) + printf("inc(%d) is %d\n", v, inc(v)); + + return 0; +} diff --git a/easy-jit/tests/simple/long_a.cpp b/easy-jit/tests/simple/long_a.cpp new file mode 100644 index 000000000000..8cdb1ac9f973 --- /dev/null +++ b/easy-jit/tests/simple/long_a.cpp @@ -0,0 +1,27 @@ +// RUN: %clangxx %cxxflags %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t +// RUN: %t > %t.out +// RUN: %FileCheck %s < %t.out + +#include + +#include +#include + +using namespace std::placeholders; + +int add (long a, long b) { + return a+b; +} + +int main() { + easy::FunctionWrapper inc = easy::jit(add, _1, -1); + + // CHECK: inc(4) is 3 + // CHECK: inc(5) is 4 + // CHECK: inc(6) is 5 + // CHECK: inc(7) is 6 + for(int v = 4; v != 8; ++v) + printf("inc(%d) is %d\n", v, inc(v)); + + return 0; +} diff --git a/easy-jit/tests/simple/multi_file+regexp.cpp b/easy-jit/tests/simple/multi_file+regexp.cpp new file mode 100644 index 000000000000..a775f94a9005 --- /dev/null +++ b/easy-jit/tests/simple/multi_file+regexp.cpp @@ -0,0 +1,39 @@ +// RUN: %clangxx %cxxflags %include_flags %s -Xclang -load -Xclang %lib_pass -Xclang -fpass-plugin=%lib_pass -DMAIN -c -o %t.main.o +// RUN: %clangxx %cxxflags %include_flags %s -Xclang -load -Xclang %lib_pass -Xclang -fpass-plugin=%lib_pass -DLIB -c -o %t.lib.o -mllvm -easy-export="add" +// RUN: %clangxx %ld_flags %t.main.o %t.lib.o -o %t +// RUN: %t > %t.out +// RUN: %FileCheck %s < %t.out + +#ifdef LIB + +extern "C" int add (int a, int b) { + return a+b; +} + +#endif + +#ifdef MAIN + +#include + +#include +#include + +using namespace std::placeholders; + +extern "C" int add (int a, int b); + +int main() { + easy::FunctionWrapper inc = easy::jit(add, _1, 1); + + // CHECK: inc(4) is 5 + // CHECK: inc(5) is 6 + // CHECK: inc(6) is 7 + // CHECK: inc(7) is 8 + for(int v = 4; v != 8; ++v) + printf("inc(%d) is %d\n", v, inc(v)); + + return 0; +} + +#endif diff --git a/easy-jit/tests/simple/nortti_a.cpp b/easy-jit/tests/simple/nortti_a.cpp new file mode 100644 index 000000000000..faabc5e544c7 --- /dev/null +++ b/easy-jit/tests/simple/nortti_a.cpp @@ -0,0 +1,27 @@ +// RUN: %clangxx %cxxflags %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t -fno-rtti +// RUN: %t > %t.out +// RUN: %FileCheck %s < %t.out + +#include + +#include +#include + +using namespace std::placeholders; + +int add (int a, int b) { + return a+b; +} + +int main() { + easy::FunctionWrapper inc = easy::jit(add, _1, 1); + + // CHECK: inc(4) is 5 + // CHECK: inc(5) is 6 + // CHECK: inc(6) is 7 + // CHECK: inc(7) is 8 + for(int v = 4; v != 8; ++v) + printf("inc(%d) is %d\n", v, inc(v)); + + return 0; +} diff --git a/easy-jit/tests/simple/opt_level.cpp b/easy-jit/tests/simple/opt_level.cpp new file mode 100644 index 000000000000..2d9a55db3925 --- /dev/null +++ b/easy-jit/tests/simple/opt_level.cpp @@ -0,0 +1,90 @@ +// RUN: %clangxx %cxxflags %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t +// RUN: %t > %t.out +// RUN: %FileCheck %s < %t.out + +#include + +#include +#include + +using namespace std::placeholders; + +int add (int a, int b) { + return a+b; +} + +void test_level_O0 (){ + easy::FunctionWrapper inc = easy::jit(add, _1, 1, easy::options::opt_level(0, 0)); + for(int v = 4; v != 8; ++v) + printf("inc(%d) is %d\n", v, inc(v)); +} + +void test_level_O1 (){ + easy::FunctionWrapper inc = easy::jit(add, _1, 1, easy::options::opt_level(1, 0)); + for(int v = 4; v != 8; ++v) + printf("inc(%d) is %d\n", v, inc(v)); +} + +void test_level_O2 (){ + easy::FunctionWrapper inc = easy::jit(add, _1, 1, easy::options::opt_level(2, 0)); + for(int v = 4; v != 8; ++v) + printf("inc(%d) is %d\n", v, inc(v)); +} + +void test_level_O3 (){ + easy::FunctionWrapper inc = easy::jit(add, _1, 1, easy::options::opt_level(3, 0)); + for(int v = 4; v != 8; ++v) + printf("inc(%d) is %d\n", v, inc(v)); +} + +void test_level_Os (){ + easy::FunctionWrapper inc = easy::jit(add, _1, 1, easy::options::opt_level(2, 1)); + for(int v = 4; v != 8; ++v) + printf("inc(%d) is %d\n", v, inc(v)); +} + +void test_level_Oz (){ + easy::FunctionWrapper inc = easy::jit(add, _1, 1, easy::options::opt_level(2, 2)); + for(int v = 4; v != 8; ++v) + printf("inc(%d) is %d\n", v, inc(v)); +} + +int main() { + // CHECK: inc(4) is 5 + // CHECK: inc(5) is 6 + // CHECK: inc(6) is 7 + // CHECK: inc(7) is 8 + test_level_O0(); + + // CHECK: inc(4) is 5 + // CHECK: inc(5) is 6 + // CHECK: inc(6) is 7 + // CHECK: inc(7) is 8 + test_level_O1(); + + // CHECK: inc(4) is 5 + // CHECK: inc(5) is 6 + // CHECK: inc(6) is 7 + // CHECK: inc(7) is 8 + test_level_O2(); + + // CHECK: inc(4) is 5 + // CHECK: inc(5) is 6 + // CHECK: inc(6) is 7 + // CHECK: inc(7) is 8 + test_level_O3(); + + // CHECK: inc(4) is 5 + // CHECK: inc(5) is 6 + // CHECK: inc(6) is 7 + // CHECK: inc(7) is 8 + test_level_Os(); + + // CHECK: inc(4) is 5 + // CHECK: inc(5) is 6 + // CHECK: inc(6) is 7 + // CHECK: inc(7) is 8 + test_level_Oz(); + + return 0; +} diff --git a/easy-jit/tests/simple/ptr_a.cpp b/easy-jit/tests/simple/ptr_a.cpp new file mode 100644 index 000000000000..dc8547a6efdf --- /dev/null +++ b/easy-jit/tests/simple/ptr_a.cpp @@ -0,0 +1,28 @@ +// RUN: %clangxx %cxxflags %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t +// RUN: %t > %t.out +// RUN: %FileCheck %s < %t.out + +#include + +#include +#include + +using namespace std::placeholders; + +int add (int a, int *b) { + return a+*b; +} + +int main() { + int b = 1; + easy::FunctionWrapper inc = easy::jit(add, _1, &b); + + // CHECK: inc(4) is 5 + // CHECK: inc(5) is 6 + // CHECK: inc(6) is 7 + // CHECK: inc(7) is 8 + for(int v = 4; v != 8; ++v) + printf("inc(%d) is %d\n", v, inc(v)); + + return 0; +} diff --git a/easy-jit/tests/simple/serialize.cpp b/easy-jit/tests/simple/serialize.cpp new file mode 100644 index 000000000000..9a12c6a781f6 --- /dev/null +++ b/easy-jit/tests/simple/serialize.cpp @@ -0,0 +1,41 @@ +// RUN: %clangxx %cxxflags %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t +// RUN: %t > %t.out +// RUN: %FileCheck %s < %t.out + +#include + +#include +#include +#include +#include + +using namespace std::placeholders; + +int add (int a, int b) { + return a+b; +} + +int main() { + auto inc_store = easy::jit(add, _1, 1); + + std::stringstream out; + inc_store.serialize(out); + out.flush(); + + std::string buffer = out.str(); + + assert(buffer.size()); + printf("buffer.size() = %lu\n", buffer.size()); + + std::stringstream in(buffer); + auto inc_load = easy::FunctionWrapper::deserialize(in); + + // CHECK: inc(4) is 5 + // CHECK: inc(5) is 6 + // CHECK: inc(6) is 7 + // CHECK: inc(7) is 8 + for(int v = 4; v != 8; ++v) + printf("inc(%d) is %d\n", v, inc_load(v)); + + return 0; +} diff --git a/easy-jit/tests/simple/serialize_multifile.cpp b/easy-jit/tests/simple/serialize_multifile.cpp new file mode 100644 index 000000000000..cfebac7fac5d --- /dev/null +++ b/easy-jit/tests/simple/serialize_multifile.cpp @@ -0,0 +1,57 @@ +// RUN: %clangxx %cxxflags %include_flags %s -DMAIN -c -o %t.main.o +// RUN: %clangxx %cxxflags %include_flags %s -Xclang -load -Xclang %lib_pass -Xclang -fpass-plugin=%lib_pass -DLIB -c -o %t.lib.o -mllvm -easy-export="add" +// RUN: %clangxx %ld_flags %t.main.o %t.lib.o -o %t +// RUN: %t > %t.out +// RUN: %FileCheck %s < %t.out + +#include + +#include +#include +#include +#include + +using namespace std::placeholders; + +#ifdef LIB + +static int var = 0; + +static int add (int a, int b) { + return a+b+(var++); +} + +std::string get_add(int b) { + auto inc_store = easy::jit(add, _1, 1); + + std::ostringstream out; + inc_store.serialize(out); + out.flush(); + + return out.str(); +} + +#endif + +#ifdef MAIN + +std::string get_add(int b); + +int main() { + + std::string bitcode = get_add(1); + std::istringstream in(bitcode); + auto inc_load = easy::FunctionWrapper::deserialize(in); + + // CHECK: inc(4) is 5 + // CHECK: inc(5) is 7 + // CHECK: inc(6) is 9 + // CHECK: inc(7) is 11 + for(int v = 4; v != 8; ++v) { + printf("inc(%d) is %d\n", v, inc_load(v)); + } + + return 0; +} + +#endif diff --git a/easy-jit/tests/simple/serialize_static.cpp b/easy-jit/tests/simple/serialize_static.cpp new file mode 100644 index 000000000000..a3a2a6d828f8 --- /dev/null +++ b/easy-jit/tests/simple/serialize_static.cpp @@ -0,0 +1,45 @@ +// RUN: %clangxx %cxxflags %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t +// RUN: %t > %t.out +// RUN: %FileCheck %s < %t.out + +#include + +#include +#include +#include +#include + +using namespace std::placeholders; + +static int var = 0; + +int add (int a, int b) { + return a+b+var; +} + +int main() { + auto inc_store = easy::jit(add, _1, 1); + + std::stringstream out; + inc_store.serialize(out); + out.flush(); + + std::string buffer = out.str(); + + assert(buffer.size()); + printf("buffer.size() = %lu\n", buffer.size()); + + std::stringstream in(buffer); + auto inc_load = easy::FunctionWrapper::deserialize(in); + + // CHECK: inc(4) is 6 + // CHECK: inc(5) is 8 + // CHECK: inc(6) is 10 + // CHECK: inc(7) is 12 + for(int v = 4; v != 8; ++v) { + var++; + printf("inc(%d) is %d\n", v, inc_load(v)); + } + + return 0; +} diff --git a/easy-jit/tests/simple/small_struct.cpp b/easy-jit/tests/simple/small_struct.cpp new file mode 100644 index 000000000000..2ff6474308f0 --- /dev/null +++ b/easy-jit/tests/simple/small_struct.cpp @@ -0,0 +1,32 @@ +// RUN: %clangxx %cxxflags %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t +// RUN: %t > %t.out +// RUN: %FileCheck %s < %t.out + +#include + +#include +#include + +using namespace std::placeholders; + +struct Point { + int x; + int y; +}; + +int add (Point a, Point b) { + return a.x+b.x+a.y+b.y; +} + +int main() { + easy::FunctionWrapper inc = easy::jit(add, _1, Point{1,1}); + + // CHECK: inc(4,4) is 10 + // CHECK: inc(5,5) is 12 + // CHECK: inc(6,6) is 14 + // CHECK: inc(7,7) is 16 + for(int v = 4; v != 8; ++v) + printf("inc(%d,%d) is %d\n", v, v, inc(Point{v,v})); + + return 0; +} diff --git a/easy-jit/tests/simple/static_var_a.cpp b/easy-jit/tests/simple/static_var_a.cpp new file mode 100644 index 000000000000..4e7982603598 --- /dev/null +++ b/easy-jit/tests/simple/static_var_a.cpp @@ -0,0 +1,27 @@ +// RUN: %clangxx %cxxflags %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t +// RUN: %t "%t.ll" > %t.out +// RUN: %FileCheck %s < %t.out + +#include + +#include +#include + +using namespace std::placeholders; + +void add (int a, int b) { + printf("inc(%d) is %d\n", a, a+b); +} + +int main(int argc, char** argv) { + easy::FunctionWrapper inc = easy::jit(add, _1, 1, easy::options::dump_ir(argv[1])); + + // CHECK: inc(4) is 5 + // CHECK: inc(5) is 6 + // CHECK: inc(6) is 7 + // CHECK: inc(7) is 8 + for(int v = 4; v != 8; ++v) + inc(v); + + return 0; +} diff --git a/easy-jit/tests/simple/static_var_b.cpp b/easy-jit/tests/simple/static_var_b.cpp new file mode 100644 index 000000000000..3f0d0bfe35d0 --- /dev/null +++ b/easy-jit/tests/simple/static_var_b.cpp @@ -0,0 +1,29 @@ +// RUN: %clangxx %cxxflags %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t +// RUN: %t > %t.out +// RUN: %FileCheck %s < %t.out + +#include + +#include +#include + +using namespace std::placeholders; + +void add (int b) { + static int a = 4; + printf("inc(%d) is %d\n", a, a+b); + a++; +} + +int main() { + easy::FunctionWrapper inc = easy::jit(add, 1); + + // CHECK: inc(4) is 5 + // CHECK: inc(5) is 6 + // CHECK: inc(6) is 7 + // CHECK: inc(7) is 8 + for(int v = 4; v != 8; ++v) + inc(); + + return 0; +} diff --git a/easy-jit/tests/simple/struct_arg.cpp b/easy-jit/tests/simple/struct_arg.cpp new file mode 100644 index 000000000000..01ba1992cd37 --- /dev/null +++ b/easy-jit/tests/simple/struct_arg.cpp @@ -0,0 +1,102 @@ +// RUN: %clangxx %cxxflags %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t +// RUN: %t > %t.out + +#include + +#include +#include + +using namespace std::placeholders; + +template +struct Point { + T x; + T y; + + Point(T _x, T _y) { + x = _x; + y = _y; + } +}; + +template +long whopie (Point a, T b) { + return a.x * b + a.y * b; +} + +template +void test_swap() { + T val = 1; + auto whop = easy::jit(whopie, _2, _1); + + for(int v = 4; v != 8; ++v) { + long z = whop(val, Point(v*2, v*3)); + printf(" swap(%d) %ld\n", v, z); + + if(z != whopie(Point(v*2, v*3), val)) + exit(-1); + } +} + +template +void test_specialzie_a() { + T val = 1; + auto whop = easy::jit(whopie, _1, val); + + for(int v = 4; v != 8; ++v) { + long z = whop(Point(v*2, v*3)); + printf(" spec_a(%d) %ld\n", v, z); + + if(z != whopie(Point(v*2, v*3), val)) + exit(-1); + } +} + +template +void test_specialzie_b() { + T val = 1; + auto whop = easy::jit(whopie, Point(val*2, val*3), _1); + + for(int v = 4; v != 8; ++v) { + long z = whop(v); + printf(" spec_b(%d) %ld\n", v, z); + + if(z != whopie(Point(val*2, val*3), v)) + exit(-1); + } +} + +template +void test_specialzie_ab() { + T val = 1; + auto whop = easy::jit(whopie, Point(val*2, val*3), val); + + for(int v = 4; v != 8; ++v) { + long z = whop(); + printf(" spec_ab() %ld\n", z); + + if(z != whopie(Point(val*2, val*3), val)) + exit(-1); + } +} + +template +void test() { + printf("== %s ==\n", typeid(T).name()); + test_swap(); + test_specialzie_a(); + test_specialzie_b(); + test_specialzie_ab(); +} + +int main() { + + test(); + test(); + test(); + test(); + test(); + test(); + + return 0; +} diff --git a/easy-jit/tests/simple/struct_return.cpp b/easy-jit/tests/simple/struct_return.cpp new file mode 100644 index 000000000000..22d1cbf03eb0 --- /dev/null +++ b/easy-jit/tests/simple/struct_return.cpp @@ -0,0 +1,73 @@ +// RUN: %clangxx %cxxflags %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t +// RUN: %t > %t.out +// RUN: %FileCheck %s < %t.out + +#include + +#include +#include + +using namespace std::placeholders; + +template +struct Point { + T x; + T y; +}; + +template +Point build (T a, T b) { + return Point{(T)(a-7), (T)(2*b)}; +} + +template +void test() { + T val = 1; + easy::FunctionWrapper(T)> build_val = easy::jit(build, _1, val); + + for(int v = 4; v != 8; ++v) { + Point xy = build_val((T)v); + printf("point = %d %d \n", (int)xy.x, (int)xy.y); + } +} + +int main() { + + // CHECK: point = -3 2 + // CHECK: point = -2 2 + // CHECK: point = -1 2 + // CHECK: point = 0 2 + test(); + + // CHECK: point = -3 2 + // CHECK: point = -2 2 + // CHECK: point = -1 2 + // CHECK: point = 0 2 + test(); + + // CHECK: point = -3 2 + // CHECK: point = -2 2 + // CHECK: point = -1 2 + // CHECK: point = 0 2 + test(); + + // CHECK: point = -3 2 + // CHECK: point = -2 2 + // CHECK: point = -1 2 + // CHECK: point = 0 2 + test(); + + // CHECK: point = -3 2 + // CHECK: point = -2 2 + // CHECK: point = -1 2 + // CHECK: point = 0 2 + test(); + + // CHECK: point = -3 2 + // CHECK: point = -2 2 + // CHECK: point = -1 2 + // CHECK: point = 0 2 + test(); + + return 0; +} diff --git a/easy-jit/tests/simple/thread.cpp b/easy-jit/tests/simple/thread.cpp new file mode 100644 index 000000000000..fc1e845cd0f9 --- /dev/null +++ b/easy-jit/tests/simple/thread.cpp @@ -0,0 +1,30 @@ +// RUN: %clangxx %cxxflags %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -lpthread -o %t +// RUN: %t > %t.out +// RUN: %FileCheck %s < %t.out + +#include + +#include +#include +#include + +using namespace std::placeholders; + +int add (int a, int b) { + return a+b; +} + +int main() { + auto inc_future = std::async(std::launch::async, + [](){ return easy::jit(add, _1, 1);}); + + // CHECK: inc(4) is 5 + // CHECK: inc(5) is 6 + // CHECK: inc(6) is 7 + // CHECK: inc(7) is 8 + auto inc = inc_future.get(); + for(int v = 4; v != 8; ++v) + printf("inc(%d) is %d\n", v, inc(v)); + + return 0; +} diff --git a/easy-jit/tests/simple/unroll.cpp b/easy-jit/tests/simple/unroll.cpp new file mode 100644 index 000000000000..f6a739ea63b4 --- /dev/null +++ b/easy-jit/tests/simple/unroll.cpp @@ -0,0 +1,41 @@ +// RUN: %clangxx %cxxflags -O2 %include_flags %ld_flags %s -Xclang -fpass-plugin=%lib_pass -o %t +// RUN: %t "%t.ll" > %t.out +// RUN: %FileCheck %s < %t.out +// RUN: %FileCheck --check-prefix=CHECK-IR %s < %t.ll + +#include +#include + +#include +#include + +// only one function +// with only one block (~no branch) +// CHECK-IR: define +// CHECK-IR-NOT: define +// CHECK-IR-NOT: br +// CHECK-IR: ret + +using namespace std::placeholders; + +int dot(int *a, std::vector b, int n) { + int x = 0; + for(size_t i = 0; i != n; ++i) { + x += a[i]*b[i]; + } + return x; +} + +int main(int, char** argv) { + + std::vector a = {1,2,3,4}, + b = {4,3,2,1}; + + auto dot_a = easy::jit(dot, a.data(), _1, 4, easy::options::dump_ir(argv[1])); + int x = dot_a(b); + + // CHECK: dot is 20 + printf("dot is %d\n", x); + + return 0; +} diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt index 12618966c4ad..2eb21ad0e52d 100644 --- a/llvm/CMakeLists.txt +++ b/llvm/CMakeLists.txt @@ -116,7 +116,7 @@ endif() # one for llvm+clang+... using the same sources. set(LLVM_ALL_PROJECTS "bolt;clang;clang-tools-extra;compiler-rt;cross-project-tests;libc;libclc;lld;lldb;mlir;openmp;polly;pstl") # The flang project is not yet part of "all" projects (see C++ requirements) -set(LLVM_EXTRA_PROJECTS "flang") +set(LLVM_EXTRA_PROJECTS "flang;easy-jit") # List of all known projects in the mono repo set(LLVM_KNOWN_PROJECTS "${LLVM_ALL_PROJECTS};${LLVM_EXTRA_PROJECTS}") set(LLVM_ENABLE_PROJECTS "" CACHE STRING diff --git a/llvm/tools/CMakeLists.txt b/llvm/tools/CMakeLists.txt index db66dad5dc0d..6c3be258a12f 100644 --- a/llvm/tools/CMakeLists.txt +++ b/llvm/tools/CMakeLists.txt @@ -45,6 +45,7 @@ add_llvm_external_project(clang) add_llvm_external_project(flang) add_llvm_external_project(lldb) add_llvm_external_project(bolt) +add_llvm_external_project(easy-jit) # Automatically add remaining sub-directories containing a 'CMakeLists.txt' # file as external projects. -- Gitee