From 376b9aa40eea3b44466396bc7176667c33d8ba07 Mon Sep 17 00:00:00 2001 From: Roman Zhuykov Date: Wed, 16 Oct 2024 10:11:12 +0300 Subject: [PATCH 01/18] Adjust LLVM build script and readme --- static_core/scripts/llvm/README.md | 17 ++++++------ static_core/scripts/llvm/build_llvm.sh | 37 +++++++++++--------------- 2 files changed, 25 insertions(+), 29 deletions(-) diff --git a/static_core/scripts/llvm/README.md b/static_core/scripts/llvm/README.md index 0faea9145..64d134804 100644 --- a/static_core/scripts/llvm/README.md +++ b/static_core/scripts/llvm/README.md @@ -15,6 +15,7 @@ Some variables are mandatory, others are optional. ```bash ### Required variables BUILD_DIR= +INSTALL_DIR= (default: "/opt", installing there usually requires root privileges) LLVM_SOURCES=/llvm VERSION=(default: "main") PACKAGE_VERSION=(default: $VERSION) # must match REQUIRED_LLVM_VERSION in libllvmbackend/CMakeLists.txt @@ -28,10 +29,9 @@ BUILD_OHOS_RELEASE=(default: BUILD_OHOS_RELEASE_GN=(default: false) ### Optional variables -INSTALL_DIR= (default: "") -DO_STRIPPING=(default: true) -DO_TAR=(default: true) +DO_STRIPPING=(default: true) +DO_TAR=(default: true) OHOS_SDK=, required for any OHOS build. @@ -59,21 +59,22 @@ LLVM_SOURCES="/home/user/src/llvm-for-ark/llvm" \ VERSION="15.0.4-ark99-beta9" \ PACKAGE_VERSION="15.0.4-ark99" \ OPTIMIZE_DEBUG=false \ +DO_STRIPPING=false \ BUILD_X86_DEBUG=true \ BUILD_AARCH64_DEBUG=true \ bash -x ./build_llvm.sh ``` In this example, only `x86_64` and `arm64` debug versions are built. Then, they can be specified for Ark build, like: -* host build: `-DLLVM_TARGET_PATH=/home/user/build/llvm-15.0.4-ark99-beta9-debug-x86_64` +* host build: `-DLLVM_TARGET_PATH=/home/user/inst/llvm-15.0.4-ark99-beta9-debug-x86_64` * cross-arm64 build: - * `-DLLVM_TARGET_PATH=/home/user/build/llvm-15.0.4-ark99-beta9-debug-aarch64` - * `-DLLVM_HOST_PATH=/home/user/build/llvm-15.0.4-ark99-beta9-debug-x86_64` + * `-DLLVM_TARGET_PATH=/home/user/inst/llvm-15.0.4-ark99-beta9-debug-aarch64` + * `-DLLVM_HOST_PATH=/home/user/inst/llvm-15.0.4-ark99-beta9-debug-x86_64` ## Example with packaging all necessary versions ```bash -INSTALL_DIR="/mnt/scratch/install" \ +INSTALL_DIR="/opt" \ BUILD_DIR="/mnt/scratch/build" \ LLVM_SOURCES="/mnt/scratch/src/llvm-for-ark/llvm" \ VERSION="15.0.4-ark99-beta9" \ @@ -86,5 +87,5 @@ BUILD_AARCH64_DEBUG=true \ BUILD_AARCH64_RELEASE=true \ BUILD_OHOS_RELEASE=true \ BUILD_OHOS_RELEASE_GN=true \ -bash -x ./build_llvm.sh +sudo bash -x ./build_llvm.sh ``` diff --git a/static_core/scripts/llvm/build_llvm.sh b/static_core/scripts/llvm/build_llvm.sh index df835fe12..f34c4055f 100755 --- a/static_core/scripts/llvm/build_llvm.sh +++ b/static_core/scripts/llvm/build_llvm.sh @@ -16,15 +16,17 @@ set -euo pipefail # Required variables BUILD_DIR=${BUILD_DIR:-""} +INSTALL_DIR=${INSTALL_DIR:-"/opt"} LLVM_SOURCES=${LLVM_SOURCES:-""} + # Optional variables -INSTALL_DIR=${INSTALL_DIR:-""} # empty -- do not install VERSION=${VERSION:-"main"} # Specifies build and install directory names: PACKAGE_VERSION=${PACKAGE_VERSION:-${VERSION}} BUILD_SUFFIX=${BUILD_SUFFIX:-""} # llvm--{debug,release}-{aarch64,x86} OPTIMIZE_DEBUG=${OPTIMIZE_DEBUG:-true} # Compile debug versions with -O2 -DO_STRIPPING=${DO_STRIPPING:-true} # checked only if install -DO_TARS=${DO_TARS:-true} # checked only if install +DO_STRIPPING=${DO_STRIPPING:-true} +DO_TARS=${DO_TARS:-true} + # Select a target to build BUILD_X86_DEBUG=${BUILD_X86_DEBUG:-false} BUILD_X86_RELEASE=${BUILD_X86_RELEASE:-false} @@ -52,6 +54,11 @@ if [[ -z "${BUILD_DIR}" ]]; then exit 1 fi +if [[ -z "${INSTALL_DIR}" ]]; then + echo "Please, specify install directory with INSTALL_DIR variable" + exit 1 +fi + if [[ -z "${LLVM_SOURCES}" ]]; then echo "Please, specify llvm sources directory with LLVM_SOURCES variable" exit 1 @@ -152,9 +159,7 @@ if [[ "x${BUILD_X86_DEBUG}" == "xtrue" ]]; then "${LLVM_SOURCES}" ninja distribution - if [[ -n "${INSTALL_DIR}" ]]; then - install "${INSTALL_PREFIX}" "${DO_STRIPPING}" "${DO_TARS}" - fi + install "${INSTALL_PREFIX}" "${DO_STRIPPING}" "${DO_TARS}" AUTO_LLVM_TABLEGEN="${BUILD_PREFIX}/bin/llvm-tblgen" if [[ ! -f "${AUTO_LLVM_TABLEGEN}" ]]; then @@ -195,9 +200,7 @@ if [[ "x${BUILD_X86_RELEASE}" == "xtrue" ]]; then "${LLVM_SOURCES}" ninja distribution - if [[ -n "${INSTALL_DIR}" ]]; then - install "${INSTALL_PREFIX}" "${DO_STRIPPING}" "${DO_TARS}" - fi + install "${INSTALL_PREFIX}" "${DO_STRIPPING}" "${DO_TARS}" AUTO_LLVM_TABLEGEN="${BUILD_PREFIX}/bin/llvm-tblgen" if [[ ! -f "${AUTO_LLVM_TABLEGEN}" ]]; then @@ -248,9 +251,7 @@ if [[ "x${BUILD_AARCH64_DEBUG}" == "xtrue" ]]; then "${LLVM_SOURCES}" ninja distribution - if [[ -n "${INSTALL_DIR}" ]]; then - install "${INSTALL_PREFIX}" "${DO_STRIPPING}" "${DO_TARS}" - fi + install "${INSTALL_PREFIX}" "${DO_STRIPPING}" "${DO_TARS}" fi if [[ "x${BUILD_AARCH64_RELEASE}" == "xtrue" ]]; then @@ -293,9 +294,7 @@ if [[ "x${BUILD_AARCH64_RELEASE}" == "xtrue" ]]; then "${LLVM_SOURCES}" ninja distribution - if [[ -n "${INSTALL_DIR}" ]]; then - install "${INSTALL_PREFIX}" "${DO_STRIPPING}" "${DO_TARS}" - fi + install "${INSTALL_PREFIX}" "${DO_STRIPPING}" "${DO_TARS}" fi if [[ "x${BUILD_OHOS_RELEASE}" == "xtrue" ]]; then @@ -332,9 +331,7 @@ if [[ "x${BUILD_OHOS_RELEASE}" == "xtrue" ]]; then "${LLVM_SOURCES}" ninja distribution - if [[ -n "${INSTALL_DIR}" ]]; then - install "${INSTALL_PREFIX}" "${DO_STRIPPING}" "${DO_TARS}" - fi + install "${INSTALL_PREFIX}" "${DO_STRIPPING}" "${DO_TARS}" fi if [[ "x${BUILD_OHOS_RELEASE_GN}" == "xtrue" ]]; then @@ -380,7 +377,5 @@ if [[ "x${BUILD_OHOS_RELEASE_GN}" == "xtrue" ]]; then "${LLVM_SOURCES}" ninja distribution - if [[ -n "${INSTALL_DIR}" ]]; then - install "${INSTALL_PREFIX}" "${DO_STRIPPING}" "${DO_TARS}" - fi + install "${INSTALL_PREFIX}" "${DO_STRIPPING}" "${DO_TARS}" fi -- Gitee From 0ca9917cc670d994cbc67cdec2f237ad19dc4bbe Mon Sep 17 00:00:00 2001 From: Leonid Skvortsov Date: Fri, 4 Oct 2024 18:22:56 +0300 Subject: [PATCH 02/18] Fix entrypoints in GN build --- static_core/libllvmbackend/BUILD.gn | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/static_core/libllvmbackend/BUILD.gn b/static_core/libllvmbackend/BUILD.gn index 59356034f..395a68e96 100644 --- a/static_core/libllvmbackend/BUILD.gn +++ b/static_core/libllvmbackend/BUILD.gn @@ -195,12 +195,13 @@ if (is_llvmbackend) { extra_dependencies = [ "$ark_root/runtime:arkruntime_gen_intrinsics_yaml" ] } - entrypoints_yaml = "$ark_root/runtime/entrypoints/entrypoints.yaml" + entrypoints_yaml = rebase_path("$target_gen_dir/../runtime/entrypoints.yaml") ark_gen_file("libllvmbackend_entrypoints_gen_inl") { template_file = "$llvmbackend_templates_dir/entrypoints_gen.inl.erb" data = [ entrypoints_yaml ] api = [ "$llvmbackend_templates_dir/entrypoints.rb" ] output_file = "$target_gen_dir/entrypoints_gen.inl" + extra_dependencies = [ "$ark_root:concat_entrypoints_yamls" ] } ark_gen_file("libllvmbackend_entrypoints_llvm_ark_interface_gen_inl") { @@ -209,6 +210,7 @@ if (is_llvmbackend) { data = [ entrypoints_yaml ] api = [ "$llvmbackend_templates_dir/entrypoints.rb" ] output_file = "$target_gen_dir/entrypoints_llvm_ark_interface_gen.inl" + extra_dependencies = [ "$ark_root:concat_entrypoints_yamls" ] } ark_gen_file("libllvmbackend_llvm_passes_inl") { -- Gitee From a7732af90be30dfe04d431291f4beaed1b56de1c Mon Sep 17 00:00:00 2001 From: Leonid Skvortsov Date: Tue, 8 Oct 2024 18:09:30 +0300 Subject: [PATCH 03/18] Follow NonNull attribute to intrinsic calls --- static_core/libllvmbackend/lowering/llvm_ir_constructor.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/static_core/libllvmbackend/lowering/llvm_ir_constructor.cpp b/static_core/libllvmbackend/lowering/llvm_ir_constructor.cpp index 4c976f6c0..1bbfe73b9 100644 --- a/static_core/libllvmbackend/lowering/llvm_ir_constructor.cpp +++ b/static_core/libllvmbackend/lowering/llvm_ir_constructor.cpp @@ -4414,12 +4414,18 @@ void LLVMIrConstructor::VisitIntrinsic(GraphVisitor *v, Inst *inst) if (g_options.IsCompilerEncodeIntrinsics()) { bool lowered = ctor->TryEmitIntrinsic(inst, entryId); if (lowered) { + ASSERT(!inst->NoNullPtr()); return; } } // Create call otherwise auto result = ctor->CreateIntrinsicCall(inst); if (inst->GetType() != DataType::VOID) { + if (inst->NoNullPtr()) { + ASSERT(inst->GetType() == DataType::REFERENCE); + ASSERT(result->getType()->isPointerTy()); + result->addRetAttr(llvm::Attribute::NonNull); + } ctor->ValueMapAdd(inst, result); } } -- Gitee From adbc01071d7f3416dfbf5215d5e569b4ae972c14 Mon Sep 17 00:00:00 2001 From: Roman Zhuykov Date: Wed, 16 Oct 2024 09:46:15 +0300 Subject: [PATCH 04/18] Bump llvm version to ark19 --- static_core/libllvmbackend/CMakeLists.txt | 2 +- static_core/libllvmbackend/llvm.gni | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/static_core/libllvmbackend/CMakeLists.txt b/static_core/libllvmbackend/CMakeLists.txt index d5f009d58..30c6db24d 100644 --- a/static_core/libllvmbackend/CMakeLists.txt +++ b/static_core/libllvmbackend/CMakeLists.txt @@ -228,7 +228,7 @@ endif() panda_target_compile_options(llvmbackend PUBLIC "-Wno-unused-parameter") -panda_target_compile_definitions(llvmbackend PUBLIC REQUIRED_LLVM_VERSION=15.0.4-ark18) +panda_target_compile_definitions(llvmbackend PUBLIC REQUIRED_LLVM_VERSION=15.0.4-ark19) if (PANDA_LLVM_AOT AND PANDA_TARGET_AMD64 AND PANDA_COMPILER_TARGET_AARCH64 AND PANDA_WITH_TESTS) set(PANDA_LLVM_AOT_TESTS_SOURCES diff --git a/static_core/libllvmbackend/llvm.gni b/static_core/libllvmbackend/llvm.gni index 227919178..b47bf0dbd 100644 --- a/static_core/libllvmbackend/llvm.gni +++ b/static_core/libllvmbackend/llvm.gni @@ -11,7 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -llvm_version = "15.0.4-ark18" +llvm_version = "15.0.4-ark19" llvm_lib_file_suffix = "lib/libLLVM-15.so" declare_args() { -- Gitee From 8a16592e0da6b7771cb128cd0e72b89751c95504 Mon Sep 17 00:00:00 2001 From: Roman Zhuykov Date: Fri, 27 Sep 2024 16:18:09 +0300 Subject: [PATCH 05/18] [CI] Clang-tidy/clang-format scripts adjustments --- static_core/CMakeLists.txt | 2 +- static_core/cmake/ClangTidy.cmake | 6 +++ .../clang-tidy/clang-tidy_llvm_config.json | 10 ++++ .../scripts/clang-tidy/clang_tidy_check.py | 54 ++++++++++++++----- .../scripts/code_style/code_style_check.py | 21 +++++--- 5 files changed, 73 insertions(+), 20 deletions(-) create mode 100644 static_core/scripts/clang-tidy/clang-tidy_llvm_config.json diff --git a/static_core/CMakeLists.txt b/static_core/CMakeLists.txt index ddc400a3f..63d72c8c4 100644 --- a/static_core/CMakeLists.txt +++ b/static_core/CMakeLists.txt @@ -347,7 +347,7 @@ if(PANDA_WITH_TESTS) ) if (NOT PANDA_TARGET_MACOS) - add_dependencies(tests_full code-style-check) + add_dependencies(tests_full code-style-check doxygen-style-check clang-tidy-llvmbackend) endif() add_subdirectory(scripts) diff --git a/static_core/cmake/ClangTidy.cmake b/static_core/cmake/ClangTidy.cmake index 1d6bf74d8..444bf268b 100644 --- a/static_core/cmake/ClangTidy.cmake +++ b/static_core/cmake/ClangTidy.cmake @@ -40,3 +40,9 @@ add_custom_target(test-cmake-checker COMMAND ${PANDA_ROOT}/scripts/cmake-checker/cmake_checker.py ${PANDA_ROOT} TEST USES_TERMINAL ) + +add_custom_target(clang-tidy-llvmbackend + COMMAND ${PANDA_ROOT}/scripts/clang-tidy/clang_tidy_check.py ${PANDA_ROOT} ${PANDA_BINARY_ROOT} "--cfg-filter=${PANDA_ROOT}/scripts/clang-tidy/clang-tidy_llvm_config.json" + USES_TERMINAL + DEPENDS panda_gen_files +) diff --git a/static_core/scripts/clang-tidy/clang-tidy_llvm_config.json b/static_core/scripts/clang-tidy/clang-tidy_llvm_config.json new file mode 100644 index 000000000..ebf474cc2 --- /dev/null +++ b/static_core/scripts/clang-tidy/clang-tidy_llvm_config.json @@ -0,0 +1,10 @@ +[ + "libllvmbackend", + "irtoc/backend/", + "compiler/aot/aot_builder/aot_builder.cpp", + "compiler/aot/aot_builder/llvm_aot_builder.cpp", + "compiler/aot/aot_file.cpp", + "compiler/optimizer/ir/aot_data.cpp", + "compiler/tools/paoc/paoc.cpp", + "compiler/tools/paoc/paoc_llvm.cpp" +] diff --git a/static_core/scripts/clang-tidy/clang_tidy_check.py b/static_core/scripts/clang-tidy/clang_tidy_check.py index 9a5fcc476..b6882d65d 100755 --- a/static_core/scripts/clang-tidy/clang_tidy_check.py +++ b/static_core/scripts/clang-tidy/clang_tidy_check.py @@ -29,9 +29,13 @@ def get_args(): 'panda_dir', help='panda sources directory.', type=str) parser.add_argument( 'build_dir', help='panda build directory.', type=str) + parser.add_argument( + '--cfg-filter', type=str, action='store', dest='cfg_filter', + required=False, + help='Path to config with filenames to be checked. If missed all source files will be checked.') parser.add_argument( '--filename-filter', type=str, action='store', dest='filename_filter', - required=False, default="*", + required=False, help='Regexp for filename with path to it. If missed all source files will be checked.') parser.add_argument( '--full', action="store_true", help='Check all files with all compile keys.') @@ -207,7 +211,7 @@ default_disabled_checks = [ ] -def run_clang_tidy(src_path: str, panda_dir: str, build_dir: str, compile_args: str) -> bool: +def run_clang_tidy(src_path: str, panda_dir: str, build_dir: str, compile_args: str, delayed_stderr: list, job_num: int) -> bool: # Used by ctcache to provide a wrapper for real clang-tidy that will check the cache # before launching clang-tidy and save the result to ctcache server cmd_path = os.getenv('CLANG_TIDY_PATH') @@ -234,10 +238,14 @@ def run_clang_tidy(src_path: str, panda_dir: str, build_dir: str, compile_args: print("Note: bad output for ", src_path) return True - print('Failed: ' + ' '.join(cmd) + '\n' + out_msg) + failed_output = f'Failed: ' + ' '.join(cmd) + failed_output += f'\n{out_msg}\n' if e.stderr: - print(e.stderr.decode()) + failed_output += e.stderr.decode() + + delayed_stderr[job_num] = failed_output + print(failed_output) return False @@ -254,12 +262,15 @@ def get_full_path(relative_path: str, location_base: str, panda_dir: str, build_ def check_file_list(file_list: list, panda_dir: str, build_dir: str, proc_count: int) -> bool: pool = multiprocessing.Pool(proc_count) jobs = [] - for src, args in file_list: + manager = multiprocessing.Manager() + delayed_stderr = manager.list([None] * len(file_list)) + for i in range(len(file_list)): + src, args = file_list[i] msg = "Done clang-tidy: %s" % (src) proc = pool.apply_async(func=run_clang_tidy, args=( - src, panda_dir, build_dir, args)) + src, panda_dir, build_dir, args, delayed_stderr, i)) jobs.append((proc, msg)) # Wait for jobs to complete before exiting @@ -283,6 +294,7 @@ def check_file_list(file_list: list, panda_dir: str, build_dir: str, proc_count: # Safely terminate the pool pool.close() pool.join() + print('\n'.join([ds for ds in delayed_stderr if ds])) return main_ret_val @@ -403,10 +415,13 @@ def verify_uniq_element_list(uniq_element_list: list) -> bool: return len(uniq_element_list) == len(set(uniq_element_list)) -def verify_args(panda_dir: str, build_dir: str) -> str: +def verify_args(panda_dir: str, build_dir: str, filename_filter: str, cfg_filter: str): if not verify_uniq_element_list(default_disabled_checks): return "Error: Dupclicated defauls disabled checks" + if filename_filter and cfg_filter: + return "Error: --filename-filter and --cfg-filter cannot be used together, please remove one." + return "" @@ -452,6 +467,13 @@ def get_proc_count(cmd_ard : int) -> int: return multiprocessing.cpu_count() +def parse_config(cfg_filter): + cfg_data = None + with open(cfg_filter) as cfg: + cfg_data = json.load(cfg) + return f"({'|'.join(cfg_data)})" + + if __name__ == "__main__": arguments = get_args() files_list = [] @@ -459,17 +481,25 @@ if __name__ == "__main__": if not os.path.exists(os.path.join(arguments.build_dir, 'compile_commands.json')): sys.exit("Error: Missing file `compile_commands.json` in build directory") - err_msg = verify_args(arguments.panda_dir, arguments.build_dir) + err_msg = verify_args( + arguments.panda_dir, arguments.build_dir, arguments.filename_filter, arguments.cfg_filter) if err_msg: sys.exit(err_msg) - files_list = get_file_list( - arguments.panda_dir, arguments.build_dir, arguments.filename_filter) + filename_filter = "*" + + if arguments.filename_filter: + filename_filter = arguments.filename_filter + elif arguments.cfg_filter: + filename_filter = parse_config(arguments.cfg_filter) + + files_list = get_file_list(arguments.panda_dir, arguments.build_dir, filename_filter) if not files_list: sys.exit("Can't be prepaired source list." - "Please check availble in build `dir compile_commands.json`" - "and correcting of parameter `--filename-filter` if you use it.") + "Please check available in build `dir compile_commands.json`" + "and correcting of parameter `--filename-filter`" + " or `--cfg-filter` if you use it.") check_headers_in_es2panda_sources(arguments.panda_dir) print('Checked for system headers: Starting') diff --git a/static_core/scripts/code_style/code_style_check.py b/static_core/scripts/code_style/code_style_check.py index b3a8ad6c5..f8735d1e9 100755 --- a/static_core/scripts/code_style/code_style_check.py +++ b/static_core/scripts/code_style/code_style_check.py @@ -39,7 +39,7 @@ def get_args(): return parser.parse_args() -def run_clang_format(src_path, panda_dir, reformat, msg): +def run_clang_format(src_path, panda_dir, reformat, msg, delayed_stderr, job_num): check_cmd = [str(os.path.join(panda_dir, 'scripts', 'code_style', 'run_code_style_tools.sh'))] reformat_cmd = [CLANG_FORMAT, '-i'] @@ -56,11 +56,14 @@ def run_clang_format(src_path, panda_dir, reformat, msg): print("Note: missed output for ", src_path) return True - print('Failed: ', ' '.join(cmd)) - print(e.stdout.decode()) + failed_output = f'Failed: ' + ' '.join(cmd) + failed_output += f'\n{e.stdout.decode()}\n' if e.stderr: - print(e.stderr.decode()) + failed_output += e.stderr.decode() + + delayed_stderr[job_num] = failed_output + print(failed_output) return False @@ -84,16 +87,19 @@ def check_file_list(file_list : list, panda_dir : str, reformat : bool, proc_cou main_ret_val = True total_count = str(len(file_list)) idx = 0 - for src in file_list: + manager = multiprocessing.Manager() + delayed_stderr = manager.list([None] * len(file_list)) + for i in range(len(file_list)): + src = file_list[i] idx += 1 msg = "[%s/%s] Running clang-format: %s" % (str(idx), total_count, src) proc = pool.apply_async(func=run_clang_format, args=( - src, panda_dir, reformat, msg)) + src, panda_dir, reformat, msg, delayed_stderr, i)) jobs.append(proc) # Wait for jobs to complete before exiting while(not all([p.ready() for p in jobs])): - time.sleep(5) + time.sleep(1) for job in jobs: if not job.get(): @@ -103,6 +109,7 @@ def check_file_list(file_list : list, panda_dir : str, reformat : bool, proc_cou # Safely terminate the pool pool.close() pool.join() + print('\n'.join([ds for ds in delayed_stderr if ds])) return main_ret_val -- Gitee From f6a53fb954d51409eeee969dbf7a465fb6aa0672 Mon Sep 17 00:00:00 2001 From: Roman Zhuykov Date: Thu, 26 Sep 2024 18:42:07 +0300 Subject: [PATCH 06/18] [CI] Tweak llvmaot options for etsstdlib --- static_core/plugins/ets/CMakeLists.txt | 13 +++- static_core/plugins/ets/tests/CMakeLists.txt | 73 ++++++-------------- 2 files changed, 33 insertions(+), 53 deletions(-) diff --git a/static_core/plugins/ets/CMakeLists.txt b/static_core/plugins/ets/CMakeLists.txt index aa939c5aa..40530c4a8 100644 --- a/static_core/plugins/ets/CMakeLists.txt +++ b/static_core/plugins/ets/CMakeLists.txt @@ -126,10 +126,19 @@ endif() if(PANDA_WITH_COMPILER) add_subdirectory(compiler) - set (COMPILER_OPTIONS "--compiler-check-final=true") + if(PANDA_LLVM_AOT) + set(STDLIB_PAOC_MODE "llvm") + set(COMPILER_OPTIONS "--compiler-check-final=true" "--llvm-gc-check=true" "--llvm-pre-opt=2") + if (NOT PANDA_ENABLE_THREAD_SANITIZER) + set(COMPILER_OPTIONS ${COMPILER_OPTIONS} "--llvmaot-threads=4" "--llvmaot-methods-per-module=512") + endif() + else() + set(STDLIB_PAOC_MODE "aot") + set(COMPILER_OPTIONS "--compiler-check-final=true") + endif() add_custom_target(ets-compile-stdlib-default COMMENT "Running ark_aot compilation for etsstdlib with default options" - COMMAND ${CMAKE_SOURCE_DIR}/plugins/ets/compiler/tools/paoc_compile_stdlib.sh --prefix="${PANDA_RUN_PREFIX}" --binary-dir=${CMAKE_BINARY_DIR} -compiler-options="${COMPILER_OPTIONS}" -paoc-output=${CMAKE_CURRENT_BINARY_DIR}/etsstdlib.an + COMMAND ${CMAKE_SOURCE_DIR}/plugins/ets/compiler/tools/paoc_compile_stdlib.sh --prefix="${PANDA_RUN_PREFIX}" --binary-dir=${CMAKE_BINARY_DIR} -compiler-options="${COMPILER_OPTIONS}" --paoc-mode=${STDLIB_PAOC_MODE} -paoc-output=${CMAKE_CURRENT_BINARY_DIR}/etsstdlib.an DEPENDS ark_aot etsstdlib ) endif() diff --git a/static_core/plugins/ets/tests/CMakeLists.txt b/static_core/plugins/ets/tests/CMakeLists.txt index cfb5dfcc3..dba84cf13 100644 --- a/static_core/plugins/ets/tests/CMakeLists.txt +++ b/static_core/plugins/ets/tests/CMakeLists.txt @@ -402,51 +402,32 @@ endfunction() set (COMPILER_OPTIONS_OSR "--compiler-ignore-failures=true" ${COMPILER_OPTIONS}) function(compile_stdlib TARGET_ARCH) - add_custom_target(ets-compile-stdlib-aot-${TARGET_ARCH} - COMMENT "Running ark_aot compilation for etsstdlib for ${TARGET_ARCH} with default options" - COMMAND ${ARK_AOT_RUNNER} --binary-dir=${CMAKE_BINARY_DIR} --target-arch=${TARGET_ARCH} --paoc-mode=aot -compiler-options="${COMPILER_OPTIONS}" -paoc-output=etsstdlib_aot_${TARGET_ARCH}.an - DEPENDS ark_aot etsstdlib - ) - add_custom_target(ets-compile-stdlib-jit-${TARGET_ARCH} - COMMENT "Running ark_aot compilation for etsstdlib for ${TARGET_ARCH} with jit mode" - COMMAND ${ARK_AOT_RUNNER} --binary-dir=${CMAKE_BINARY_DIR} --target-arch=${TARGET_ARCH} --paoc-mode=jit -compiler-options="${COMPILER_OPTIONS}" -paoc-output=etsstdlib_jit_${TARGET_ARCH}.an - DEPENDS ark_aot etsstdlib - ) - add_custom_target(ets-compile-stdlib-aot-${TARGET_ARCH}-no-inline - COMMENT "Running ark_aot compilation for etsstdlib for ${TARGET_ARCH} without inlining" - COMMAND ${ARK_AOT_RUNNER} --binary-dir=${CMAKE_BINARY_DIR} --target-arch=${TARGET_ARCH} --paoc-mode=aot -compiler-options="${COMPILER_OPTIONS_NO_INLINE}" -paoc-output=etsstdlib_aot_${TARGET_ARCH}_no_inline.an - DEPENDS ark_aot etsstdlib - ) - add_custom_target(ets-compile-stdlib-aot-${TARGET_ARCH}-stw - COMMENT "Running ark_aot compilation for etsstdlib for ${TARGET_ARCH} with gc stw" - COMMAND ${ARK_AOT_RUNNER} --binary-dir=${CMAKE_BINARY_DIR} --target-arch=${TARGET_ARCH} --paoc-mode=aot -compiler-options="${COMPILER_OPTIONS_GC_STW}" -paoc-output=etsstdlib_aot_${TARGET_ARCH}_stw.an - DEPENDS ark_aot etsstdlib - ) - add_dependencies(ets-compile-stdlib ets-compile-stdlib-aot-${TARGET_ARCH} ets-compile-stdlib-jit-${TARGET_ARCH} ets-compile-stdlib-aot-${TARGET_ARCH}-no-inline ets-compile-stdlib-aot-${TARGET_ARCH}-stw) if (PANDA_LLVM_AOT) - add_custom_target(ets-compile-stdlib-llvm-${TARGET_ARCH} - COMMENT "Running ark_aot compilation for etsstdlib for ${TARGET_ARCH} with llvm" - COMMAND ${ARK_AOT_RUNNER} --binary-dir=${CMAKE_BINARY_DIR} --target-arch=${TARGET_ARCH} --paoc-mode=llvm -compiler-options="${COMPILER_OPTIONS_LLVM}" -paoc-output=etsstdlib_llvmaot_${TARGET_ARCH}.an + add_custom_target(ets-compile-stdlib-llvmaot-${TARGET_ARCH} + COMMENT "Running LLVMAOT compilation for etsstdlib for ${TARGET_ARCH}" + COMMAND ${ARK_AOT_RUNNER} --binary-dir=${CMAKE_BINARY_DIR} --target-arch=${TARGET_ARCH} --paoc-mode=llvm -compiler-options="${COMPILER_OPTIONS}" -paoc-output=etsstdlib_llvmaot_${TARGET_ARCH}.an DEPENDS ark_aot etsstdlib ) - add_custom_target(ets-compile-stdlib-llvm-pre-opt-2-${TARGET_ARCH} - COMMENT "Running ark_aot compilation for etsstdlib for ${TARGET_ARCH} with llvm pre-opt" - COMMAND ${ARK_AOT_RUNNER} --binary-dir=${CMAKE_BINARY_DIR} --target-arch=${TARGET_ARCH} --paoc-mode=llvm -compiler-options="${COMPILER_OPTIONS_LLVM_PRE_OPT}" -paoc-output=etsstdlib_llvmaot_pre_opt_2_${TARGET_ARCH}.an + add_custom_target(ets-compile-stdlib-llvmaot-${TARGET_ARCH}-no-inline + COMMENT "Running LLVMAOT compilation for etsstdlib for ${TARGET_ARCH} without inlining" + COMMAND ${ARK_AOT_RUNNER} --binary-dir=${CMAKE_BINARY_DIR} --target-arch=${TARGET_ARCH} --paoc-mode=llvm -compiler-options="${COMPILER_OPTIONS_NO_INLINE}" -paoc-output=etsstdlib_llvmaot_${TARGET_ARCH}_no_inline.an DEPENDS ark_aot etsstdlib ) - add_dependencies( - ets-compile-stdlib - ets-compile-stdlib-llvm-${TARGET_ARCH} - ets-compile-stdlib-llvm-pre-opt-2-${TARGET_ARCH} + add_custom_target(ets-compile-stdlib-llvmaot-${TARGET_ARCH}-no-pre-opt + COMMENT "Running LLVMAOT compilation for etsstdlib for ${TARGET_ARCH} with llvm without pre-opt" + COMMAND ${ARK_AOT_RUNNER} --binary-dir=${CMAKE_BINARY_DIR} --target-arch=${TARGET_ARCH} --paoc-mode=llvm -compiler-options="${COMPILER_OPTIONS_NO_PRE_OPT}" -paoc-output=etsstdlib_llvmaot_${TARGET_ARCH}_no_pre_opt.an + DEPENDS ark_aot etsstdlib ) - endif() - if (TARGET_ARCH STREQUAL "arm64") - add_custom_target(ets-compile-stdlib-osr-${TARGET_ARCH} - COMMENT "Running ark_aot compilation for etsstdlib for ${TARGET_ARCH} with osr mode" - COMMAND ${ARK_AOT_RUNNER} --binary-dir=${CMAKE_BINARY_DIR} --target-arch=${TARGET_ARCH} --paoc-mode=osr -compiler-options="${COMPILER_OPTIONS_OSR}" -paoc-output=etsstdlib_osr_${TARGET_ARCH}.an + add_custom_target(ets-compile-stdlib-llvmaot-${TARGET_ARCH}-stw + COMMENT "Running LLVMAOT compilation for etsstdlib for ${TARGET_ARCH} with gc stw" + COMMAND ${ARK_AOT_RUNNER} --binary-dir=${CMAKE_BINARY_DIR} --target-arch=${TARGET_ARCH} --paoc-mode=llvm -compiler-options="${COMPILER_OPTIONS_GC_STW}" -paoc-output=etsstdlib_llvmaot_${TARGET_ARCH}_stw.an DEPENDS ark_aot etsstdlib ) - add_dependencies(ets-compile-stdlib ets-compile-stdlib-osr-${TARGET_ARCH}) + add_dependencies(ets-compile-stdlib + ets-compile-stdlib-llvmaot-${TARGET_ARCH} + ets-compile-stdlib-llvmaot-${TARGET_ARCH}-no-inline + ets-compile-stdlib-llvmaot-${TARGET_ARCH}-no-pre-opt + ets-compile-stdlib-llvmaot-${TARGET_ARCH}-stw) endif() endfunction() @@ -465,23 +446,13 @@ endif() if(PANDA_TEST_COMPILE_STDLIB) set (ARK_AOT_RUNNER ${CMAKE_SOURCE_DIR}/plugins/ets/compiler/tools/paoc_compile_stdlib.sh) - if (NOT PANDA_CI_TESTING_MODE STREQUAL "Nightly") - set (COMPILER_OPTIONS "--compiler-check-final=true") - if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") - set (COMPILER_OPTIONS ${COMPILER_OPTIONS} "--compiler-inst-graph-coloring-limit=2000") - endif() + set (COMPILER_OPTIONS "--compiler-check-final=true" "--llvm-gc-check=true" "--llvm-pre-opt=2") + if (NOT PANDA_ENABLE_THREAD_SANITIZER) + set (COMPILER_OPTIONS ${COMPILER_OPTIONS} "--llvmaot-threads=4" "--llvmaot-methods-per-module=512") endif() set (COMPILER_OPTIONS_NO_INLINE "--compiler-inlining=false" ${COMPILER_OPTIONS}) set (COMPILER_OPTIONS_GC_STW "--gc-type=stw" ${COMPILER_OPTIONS}) - if (PANDA_LLVM_AOT) - set (COMPILER_OPTIONS_LLVM ${COMPILER_OPTIONS}) - set (COMPILER_OPTIONS_LLVM_PRE_OPT "--llvm-pre-opt=2" ${COMPILER_OPTIONS}) - # NOTE(zdenis): False positives come from libLLVM.so - if (NOT PANDA_ENABLE_THREAD_SANITIZER) - set (COMPILER_OPTIONS_LLVM "--llvmaot-threads=4" "--llvmaot-methods-per-module=512" ${COMPILER_OPTIONS_LLVM}) - set (COMPILER_OPTIONS_LLVM_PRE_OPT "--llvmaot-threads=4" "--llvmaot-methods-per-module=512" ${COMPILER_OPTIONS_LLVM_PRE_OPT}) - endif() - endif () + set (COMPILER_OPTIONS_NO_PRE_OPT ${COMPILER_OPTIONS} "--llvm-pre-opt=0") add_custom_target(ets-compile-stdlib) if (PANDA_COMPILER_TARGET_X86_64) compile_stdlib(x86_64) -- Gitee From bf23f7006cb020fec5d7fa2f6badc9ac1d5a3a58 Mon Sep 17 00:00:00 2001 From: Roman Zhuykov Date: Thu, 26 Sep 2024 18:43:07 +0300 Subject: [PATCH 07/18] [CI] Enable llvm in SDK build script --- static_core/scripts/sdk/build_sdk.sh | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/static_core/scripts/sdk/build_sdk.sh b/static_core/scripts/sdk/build_sdk.sh index ed902afa6..9f6bfbb7a 100755 --- a/static_core/scripts/sdk/build_sdk.sh +++ b/static_core/scripts/sdk/build_sdk.sh @@ -65,7 +65,7 @@ function build_panda() { COMMONS_CMAKE_ARGS="\ -GNinja \ -S$ARK_ROOT \ - -DCMAKE_BUILD_TYPE=$PANDA_SDK_BUILD_TYPE \ + -DCMAKE_BUILD_TYPE=${PANDA_SDK_BUILD_TYPE} \ -DPANDA_PRODUCT_BUILD=$product_build \ -DPANDA_WITH_ECMASCRIPT=ON \ -DPANDA_WITH_ETS=ON \ @@ -116,7 +116,9 @@ function linux_tools() { -DPANDA_CROSS_AARCH64_TOOLCHAIN_FILE=cmake/toolchain/cross-ohos-musl-aarch64.cmake \ -DTOOLCHAIN_SYSROOT=$OHOS_SDK_NATIVE/sysroot \ -DTOOLCHAIN_CLANG_ROOT=$OHOS_SDK_NATIVE/llvm \ - -DPANDA_WITH_ECMASCRIPT=ON" + -DPANDA_WITH_ECMASCRIPT=ON \ + -DPANDA_LLVM_BACKEND=ON \ + -DLLVM_TARGET_PATH=/opt/llvm-15-${PANDA_SDK_BUILD_TYPE,,}-x86_64" local linux_build_targets="ark ark_aot ark_disasm ark_link es2panda e2p_test_plugin etsnative" build_panda "$linux_build_dir" "$linux_cmake_args" "$linux_build_targets" copy_into_sdk "$linux_build_dir" "$PANDA_SDK_PATH/linux_host_tools" "$SCRIPT_DIR"/linux_host_tools.txt @@ -140,7 +142,10 @@ function ohos() { -DTOOLCHAIN_SYSROOT=$OHOS_SDK_NATIVE/sysroot \ -DTOOLCHAIN_CLANG_ROOT=$OHOS_SDK_NATIVE/llvm \ -DPANDA_ETS_INTEROP_JS=ON \ - -DPANDA_WITH_ECMASCRIPT=ON" + -DPANDA_WITH_ECMASCRIPT=ON \ + -DPANDA_LLVM_BACKEND=ON \ + -DLLVM_HOST_PATH=/opt/llvm-15-${PANDA_SDK_BUILD_TYPE,,}-x86_64 \ + -DLLVM_TARGET_PATH=/opt/llvm-15-release-ohos" local ohos_build_targets="ark ark_aot arkruntime arkassembler ets_interop_js_napi e2p_test_plugin etsnative" build_panda "$ohos_build_dir" "$target_cmake_args" "$ohos_build_targets" copy_into_sdk "$ohos_build_dir" "$taget_sdk_dir" "$SCRIPT_DIR"/ohos_arm64.txt -- Gitee From 9ee11ebf8d5143d15458ada957f0bae6c40bb30e Mon Sep 17 00:00:00 2001 From: Roman Zhuykov Date: Fri, 27 Sep 2024 13:53:48 +0300 Subject: [PATCH 08/18] [CI] cts-generator: add arm64-host and llvm-irtoc runs --- static_core/tests/CMakeLists.txt | 3 ++ .../tests/cts-generator/CMakeLists.txt | 29 +------------------ 2 files changed, 4 insertions(+), 28 deletions(-) diff --git a/static_core/tests/CMakeLists.txt b/static_core/tests/CMakeLists.txt index aa236767b..697a203d1 100644 --- a/static_core/tests/CMakeLists.txt +++ b/static_core/tests/CMakeLists.txt @@ -31,6 +31,9 @@ add_dependencies(irtoc-interpreter-tests irtoc-opcode-suite) if(NOT PANDA_TARGET_AMD64 OR PANDA_TARGET_WINDOWS) add_dependencies(core_tests cts-assembly regression) add_subdirectory(cts-coverage-tool) + if(PANDA_TARGET_ARM64 AND NOT CMAKE_CROSSCOMPILING) + add_subdirectory(cts-generator) + endif() else() add_custom_target(verifier-tests COMMENT "Regression tests for verifier") add_dependencies(core_tests cts-assembly regression verifier-tests) diff --git a/static_core/tests/cts-generator/CMakeLists.txt b/static_core/tests/cts-generator/CMakeLists.txt index 92b74363c..aba30003c 100644 --- a/static_core/tests/cts-generator/CMakeLists.txt +++ b/static_core/tests/cts-generator/CMakeLists.txt @@ -157,19 +157,7 @@ if(NOT CMAKE_CROSSCOMPILING) -p "${PROJECT_BINARY_DIR}/../../" -x "${CTS_TEMP_DIR}" -v 1 - ${QUICKENER_ARGLAUNCH} - --global-timeout ${PANDA_CTS_TESTING_TIMEOUT} - --timeout ${PANDA_CTS_TEST_TIMEOUT} - -j ${PANDA_CTS_JOBS_NUMBER} - --verifier-config "${PROJECT_BINARY_DIR}/verifier.config" - ${CTS_TEST_PRLIMIT_OPTIONS} - ${CTS_TEST_SELECT_OPTION_ARGS} VERBATIM - COMMAND ${CTS_TEST_RUNNER} - -t "${CTS_GENERATED_DIR}" - -p "${PROJECT_BINARY_DIR}/../../" - -x "${CTS_TEMP_DIR}" - -v 1 - -o "--interpreter-type=cpp" + -o "--compiler-enable-jit=false" ${QUICKENER_ARGLAUNCH} --global-timeout ${PANDA_CTS_TESTING_TIMEOUT} --timeout ${PANDA_CTS_TEST_TIMEOUT} @@ -178,21 +166,6 @@ if(NOT CMAKE_CROSSCOMPILING) ${CTS_TEST_PRLIMIT_OPTIONS} --exclude-tag verifier ${CTS_TEST_SELECT_OPTION_ARGS} VERBATIM - COMMAND ${CTS_TEST_RUNNER} - -t "${CTS_GENERATED_DIR}" - -p "${PROJECT_BINARY_DIR}/../../" - -x "${CTS_TEMP_DIR}" - -v 1 - ${QUICKENER_ARGLAUNCH} - --global-timeout ${PANDA_CTS_TESTING_TIMEOUT} - --timeout ${PANDA_CTS_TEST_TIMEOUT} - -j ${PANDA_CTS_JOBS_NUMBER} - --verifier-config "${PROJECT_BINARY_DIR}/verifier.config" - -o "--compiler-hotness-threshold=0" - -o "--no-async-jit" - ${CTS_TEST_PRLIMIT_OPTIONS} - --exclude-tag verifier - ${CTS_TEST_SELECT_OPTION_JIT_ARGS} VERBATIM DEPENDS "$" "$" "${TARGETFILE_ARKQUICK}" "$" "${OUTPUT_FILES}" ) -- Gitee From 2092d5292b23b894d24b0d27318fb8906392bcab Mon Sep 17 00:00:00 2001 From: Roman Zhuykov Date: Fri, 27 Sep 2024 16:17:32 +0300 Subject: [PATCH 09/18] [CI] Add 'expr_5.sts' to AOT ignore lists --- .../test-lists/ets-cts/ets-cts-ignored-AMD64-AOT.txt | 3 +++ .../test-lists/ets-cts/ets-cts-ignored-ARM64-AOT.txt | 3 +++ 2 files changed, 6 insertions(+) diff --git a/static_core/tests/tests-u-runner/test-lists/ets-cts/ets-cts-ignored-AMD64-AOT.txt b/static_core/tests/tests-u-runner/test-lists/ets-cts/ets-cts-ignored-AMD64-AOT.txt index 4874bc64f..481152a19 100644 --- a/static_core/tests/tests-u-runner/test-lists/ets-cts/ets-cts-ignored-AMD64-AOT.txt +++ b/static_core/tests/tests-u-runner/test-lists/ets-cts/ets-cts-ignored-AMD64-AOT.txt @@ -240,3 +240,6 @@ 13.compilation_units_packages_and_modules/04.import_directives/05.type_import_binding/type_binding_var_boxed.sts 13.compilation_units_packages_and_modules/04.import_directives/05.type_import_binding/type_binding_var_default.sts 13.compilation_units_packages_and_modules/04.import_directives/05.type_import_binding/type_binding_var_primitive.sts + +# LLVM AOT removes unused allocation +17.experimental_features/02.array_creation_expressions/01.runtime_evaluation_of_array_creation_expressions/expr_5.sts diff --git a/static_core/tests/tests-u-runner/test-lists/ets-cts/ets-cts-ignored-ARM64-AOT.txt b/static_core/tests/tests-u-runner/test-lists/ets-cts/ets-cts-ignored-ARM64-AOT.txt index 4874bc64f..481152a19 100644 --- a/static_core/tests/tests-u-runner/test-lists/ets-cts/ets-cts-ignored-ARM64-AOT.txt +++ b/static_core/tests/tests-u-runner/test-lists/ets-cts/ets-cts-ignored-ARM64-AOT.txt @@ -240,3 +240,6 @@ 13.compilation_units_packages_and_modules/04.import_directives/05.type_import_binding/type_binding_var_boxed.sts 13.compilation_units_packages_and_modules/04.import_directives/05.type_import_binding/type_binding_var_default.sts 13.compilation_units_packages_and_modules/04.import_directives/05.type_import_binding/type_binding_var_primitive.sts + +# LLVM AOT removes unused allocation +17.experimental_features/02.array_creation_expressions/01.runtime_evaluation_of_array_creation_expressions/expr_5.sts -- Gitee From 96f85ec2b9ddc1bb0bf0e12fa231c303c4901d9a Mon Sep 17 00:00:00 2001 From: Roman Zhuykov Date: Tue, 24 Sep 2024 18:55:49 +0300 Subject: [PATCH 10/18] Dump method name with signature --- static_core/compiler/tools/paoc/paoc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static_core/compiler/tools/paoc/paoc.cpp b/static_core/compiler/tools/paoc/paoc.cpp index e1b025265..57b0a4aef 100644 --- a/static_core/compiler/tools/paoc/paoc.cpp +++ b/static_core/compiler/tools/paoc/paoc.cpp @@ -64,7 +64,7 @@ void Paoc::CompilingContext::DumpStatistics() const { ASSERT(stats); char sep = ','; - *stats << method->GetFullName() << sep; + *stats << '"' << method->GetFullName(true) << '"' << sep; *stats << "paoc-summary" << sep; *stats << allocator.GetAllocatedSize() << sep; *stats << graphLocalAllocator.GetAllocatedSize() << '\n'; -- Gitee From 5e58221bc8214e10ddacea013fefda0a11463b4f Mon Sep 17 00:00:00 2001 From: Denis Zavedeev Date: Tue, 24 Sep 2024 18:14:18 +0300 Subject: [PATCH 11/18] Detect missing llvm_codegen_func --- static_core/libllvmbackend/lowering/llvm_ir_constructor.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/static_core/libllvmbackend/lowering/llvm_ir_constructor.cpp b/static_core/libllvmbackend/lowering/llvm_ir_constructor.cpp index 1bbfe73b9..7a62eb50b 100644 --- a/static_core/libllvmbackend/lowering/llvm_ir_constructor.cpp +++ b/static_core/libllvmbackend/lowering/llvm_ir_constructor.cpp @@ -4418,6 +4418,7 @@ void LLVMIrConstructor::VisitIntrinsic(GraphVisitor *v, Inst *inst) return; } } + ASSERT(!EncodesBuiltin(ctor->GetGraph()->GetRuntime(), entryId, ctor->GetGraph()->GetArch())); // Create call otherwise auto result = ctor->CreateIntrinsicCall(inst); if (inst->GetType() != DataType::VOID) { -- Gitee From 208237f85e296336898260008b59e0bc38c8749a Mon Sep 17 00:00:00 2001 From: Denis Zavedeev Date: Fri, 18 Oct 2024 10:17:32 +0300 Subject: [PATCH 12/18] Refactor 'EmitStringGetBytesTlab' Signed-off-by: Denis Zavedeev --- .../ets/libllvmbackend/ets_llvm_ir_constructor_gen.inl | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/static_core/plugins/ets/libllvmbackend/ets_llvm_ir_constructor_gen.inl b/static_core/plugins/ets/libllvmbackend/ets_llvm_ir_constructor_gen.inl index 009d72857..4d9a8a750 100644 --- a/static_core/plugins/ets/libllvmbackend/ets_llvm_ir_constructor_gen.inl +++ b/static_core/plugins/ets/libllvmbackend/ets_llvm_ir_constructor_gen.inl @@ -358,10 +358,8 @@ bool LLVMIrConstructor::EmitStringGetBytesTlab(Inst *inst) auto offset = GetGraph()->GetRuntime()->GetArrayU8ClassPointerTlsOffset(GetGraph()->GetArch()); auto klass = llvmbackend::runtime_calls::LoadTLSValue(&builder_, arkInterface_, offset, builder_.getPtrTy()); auto eid = RuntimeInterface::EntrypointId::STRING_GET_BYTES_TLAB; - auto result = CreateEntrypointCall(eid, inst, - {GetInputValue(inst, 0), GetInputValue(inst, 1), GetInputValue(inst, 2), klass}); - ASSERT(result->getCallingConv() == llvm::CallingConv::C); - result->setCallingConv(llvm::CallingConv::ArkFast4); + auto result = + CreateFastPathCall(inst, eid, {GetInputValue(inst, 0), GetInputValue(inst, 1), GetInputValue(inst, 2), klass}); result->addRetAttr(llvm::Attribute::NonNull); result->addRetAttr(llvm::Attribute::NoAlias); ValueMapAdd(inst, result); -- Gitee From 8271dc743f63b602ff318bc8526f2bfcdf138153 Mon Sep 17 00:00:00 2001 From: Denis Zavedeev Date: Fri, 18 Oct 2024 10:41:33 +0300 Subject: [PATCH 13/18] Drop numArgs parameter in EmitFastPath Signed-off-by: Denis Zavedeev --- .../lowering/llvm_ir_constructor.cpp | 26 ++++++++++--------- .../lowering/llvm_ir_constructor.h | 2 +- .../ets_llvm_ir_constructor_gen.inl | 12 ++++----- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/static_core/libllvmbackend/lowering/llvm_ir_constructor.cpp b/static_core/libllvmbackend/lowering/llvm_ir_constructor.cpp index 7a62eb50b..d523741ee 100644 --- a/static_core/libllvmbackend/lowering/llvm_ir_constructor.cpp +++ b/static_core/libllvmbackend/lowering/llvm_ir_constructor.cpp @@ -423,11 +423,13 @@ bool LLVMIrConstructor::TryEmitIntrinsic(Inst *inst, RuntimeInterface::Intrinsic // Specific intrinsic Emitters -bool LLVMIrConstructor::EmitFastPath(Inst *inst, RuntimeInterface::EntrypointId eid, uint32_t numArgs) +bool LLVMIrConstructor::EmitFastPath(Inst *inst, RuntimeInterface::EntrypointId eid) { - ArenaVector args(GetGraph()->GetLocalAllocator()->Adapter()); - for (uint32_t i = 0; i < numArgs; i++) { - args.push_back(GetInputValue(inst, i)); + llvm::SmallVector args; + for (uint32_t i = 0; i < inst->GetInputsCount(); i++) { + if (!inst->GetInput(i).GetInst()->IsSaveState()) { + args.push_back(GetInputValue(inst, i)); + } } auto call = CreateFastPathCall(inst, eid, args); @@ -440,42 +442,42 @@ bool LLVMIrConstructor::EmitFastPath(Inst *inst, RuntimeInterface::EntrypointId bool LLVMIrConstructor::EmitStringEquals(Inst *inst) { - return EmitFastPath(inst, RuntimeInterface::EntrypointId::STRING_EQUALS_COMPRESSED, 2U); + return EmitFastPath(inst, RuntimeInterface::EntrypointId::STRING_EQUALS_COMPRESSED); } bool LLVMIrConstructor::EmitStringBuilderBool(Inst *inst) { - return EmitFastPath(inst, RuntimeInterface::EntrypointId::STRING_BUILDER_BOOL, 2U); + return EmitFastPath(inst, RuntimeInterface::EntrypointId::STRING_BUILDER_BOOL); } bool LLVMIrConstructor::EmitStringBuilderChar(Inst *inst) { - return EmitFastPath(inst, RuntimeInterface::EntrypointId::STRING_BUILDER_CHAR, 2U); + return EmitFastPath(inst, RuntimeInterface::EntrypointId::STRING_BUILDER_CHAR); } bool LLVMIrConstructor::EmitStringBuilderString(Inst *inst) { - return EmitFastPath(inst, RuntimeInterface::EntrypointId::STRING_BUILDER_STRING_COMPRESSED, 2U); + return EmitFastPath(inst, RuntimeInterface::EntrypointId::STRING_BUILDER_STRING_COMPRESSED); } bool LLVMIrConstructor::EmitStringConcat2(Inst *inst) { - return EmitFastPath(inst, RuntimeInterface::EntrypointId::STRING_CONCAT2_TLAB, 2U); + return EmitFastPath(inst, RuntimeInterface::EntrypointId::STRING_CONCAT2_TLAB); } bool LLVMIrConstructor::EmitStringConcat3(Inst *inst) { - return EmitFastPath(inst, RuntimeInterface::EntrypointId::STRING_CONCAT3_TLAB, 3U); + return EmitFastPath(inst, RuntimeInterface::EntrypointId::STRING_CONCAT3_TLAB); } bool LLVMIrConstructor::EmitStringConcat4(Inst *inst) { - return EmitFastPath(inst, RuntimeInterface::EntrypointId::STRING_CONCAT4_TLAB, 4U); + return EmitFastPath(inst, RuntimeInterface::EntrypointId::STRING_CONCAT4_TLAB); } bool LLVMIrConstructor::EmitStringCompareTo(Inst *inst) { - return EmitFastPath(inst, RuntimeInterface::EntrypointId::STRING_COMPARE_TO, 2U); + return EmitFastPath(inst, RuntimeInterface::EntrypointId::STRING_COMPARE_TO); } bool LLVMIrConstructor::EmitIsInf(Inst *inst) diff --git a/static_core/libllvmbackend/lowering/llvm_ir_constructor.h b/static_core/libllvmbackend/lowering/llvm_ir_constructor.h index ab8fb64a2..3d99476d2 100644 --- a/static_core/libllvmbackend/lowering/llvm_ir_constructor.h +++ b/static_core/libllvmbackend/lowering/llvm_ir_constructor.h @@ -34,7 +34,7 @@ class LLVMIrConstructor : public GraphVisitor { private: // Specific intrinsic Emitters - bool EmitFastPath(Inst *inst, RuntimeInterface::EntrypointId eid, uint32_t numArgs); + bool EmitFastPath(Inst *inst, RuntimeInterface::EntrypointId eid); bool EmitStringEquals(Inst *inst); bool EmitStringBuilderBool(Inst *inst); bool EmitStringBuilderChar(Inst *inst); diff --git a/static_core/plugins/ets/libllvmbackend/ets_llvm_ir_constructor_gen.inl b/static_core/plugins/ets/libllvmbackend/ets_llvm_ir_constructor_gen.inl index 4d9a8a750..39af1d2fc 100644 --- a/static_core/plugins/ets/libllvmbackend/ets_llvm_ir_constructor_gen.inl +++ b/static_core/plugins/ets/libllvmbackend/ets_llvm_ir_constructor_gen.inl @@ -48,7 +48,7 @@ bool LLVMIrConstructor::EmitArrayCopyTo(Inst *inst) bool LLVMIrConstructor::EmitStdStringSubstring(Inst *inst) { - return EmitFastPath(inst, RuntimeInterface::EntrypointId::SUB_STRING_FROM_STRING_TLAB_COMPRESSED, 3U); + return EmitFastPath(inst, RuntimeInterface::EntrypointId::SUB_STRING_FROM_STRING_TLAB_COMPRESSED); } bool LLVMIrConstructor::EmitStringBuilderAppendBool(Inst *inst) @@ -160,7 +160,7 @@ bool LLVMIrConstructor::EmitStringBuilderAppendStrings(Inst *inst) default: UNREACHABLE(); } - return EmitFastPath(inst, eid, inst->GetInputsCount() - 1U); // -1 to skip save state + return EmitFastPath(inst, eid); } bool LLVMIrConstructor::EmitStringBuilderToString(Inst *inst) @@ -311,7 +311,7 @@ void LLVMIrConstructor::StringBuilderAppendStringMain(Inst *inst, llvm::Value *s bool LLVMIrConstructor::EmitDoubleToStringDecimal(Inst *inst) { - return EmitFastPath(inst, RuntimeInterface::EntrypointId::DOUBLE_TO_STRING_DECIMAL, 3U); + return EmitFastPath(inst, RuntimeInterface::EntrypointId::DOUBLE_TO_STRING_DECIMAL); } bool LLVMIrConstructor::EmitStringTrimLeft(Inst *inst) @@ -340,17 +340,17 @@ bool LLVMIrConstructor::EmitStringTrim(Inst *inst) bool LLVMIrConstructor::EmitCharIsWhiteSpace(Inst *inst) { - return EmitFastPath(inst, RuntimeInterface::EntrypointId::CHAR_IS_WHITE_SPACE, 1U); + return EmitFastPath(inst, RuntimeInterface::EntrypointId::CHAR_IS_WHITE_SPACE); } bool LLVMIrConstructor::EmitStringStartsWith(Inst *inst) { - return EmitFastPath(inst, RuntimeInterface::EntrypointId::STRING_STARTS_WITH, 3U); + return EmitFastPath(inst, RuntimeInterface::EntrypointId::STRING_STARTS_WITH); } bool LLVMIrConstructor::EmitStringEndsWith(Inst *inst) { - return EmitFastPath(inst, RuntimeInterface::EntrypointId::STRING_ENDS_WITH, 3U); + return EmitFastPath(inst, RuntimeInterface::EntrypointId::STRING_ENDS_WITH); } bool LLVMIrConstructor::EmitStringGetBytesTlab(Inst *inst) -- Gitee From 86e1c73a4f98fad3f5b7a9fb0e8be022227d7864 Mon Sep 17 00:00:00 2001 From: Denis Zavedeev Date: Fri, 18 Oct 2024 16:21:34 +0300 Subject: [PATCH 14/18] Use Tck_MustTail Signed-off-by: Denis Zavedeev --- static_core/libllvmbackend/llvm_irtoc_compiler.cpp | 1 + static_core/libllvmbackend/lowering/llvm_ir_constructor.cpp | 5 +++-- static_core/tests/checked/checker.rb | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/static_core/libllvmbackend/llvm_irtoc_compiler.cpp b/static_core/libllvmbackend/llvm_irtoc_compiler.cpp index 7d5e20f75..46b13c37e 100644 --- a/static_core/libllvmbackend/llvm_irtoc_compiler.cpp +++ b/static_core/libllvmbackend/llvm_irtoc_compiler.cpp @@ -165,6 +165,7 @@ void LLVMIrtocCompiler::InitializeSpecificLLVMOptions(Arch arch) SetLLVMOption("aarch64-enable-ptr32", "true"); } SetLLVMOption("inline-remark-attribute", "true"); + SetLLVMOption("verify-musttail-calls", "false"); LLVMCompiler::InitializeLLVMOptions(); } diff --git a/static_core/libllvmbackend/lowering/llvm_ir_constructor.cpp b/static_core/libllvmbackend/lowering/llvm_ir_constructor.cpp index d523741ee..987655aeb 100644 --- a/static_core/libllvmbackend/lowering/llvm_ir_constructor.cpp +++ b/static_core/libllvmbackend/lowering/llvm_ir_constructor.cpp @@ -573,7 +573,7 @@ bool LLVMIrConstructor::EmitSlowPathEntry(Inst *inst) auto call = builder_.CreateCall(callee->getFunctionType(), callee, args); call->setCallingConv(callee->getCallingConv()); - call->setTailCallKind(llvm::CallInst::TailCallKind::TCK_Tail); + call->setTailCallKind(llvm::CallInst::TailCallKind::TCK_MustTail); call->addFnAttr(llvm::Attribute::get(call->getContext(), "ark-tail-call")); CreateReturn(call); return true; @@ -691,7 +691,7 @@ bool LLVMIrConstructor::EmitTailCall(Inst *inst) } else { UNREACHABLE(); } - call->setTailCallKind(llvm::CallInst::TailCallKind::TCK_Tail); + call->setTailCallKind(llvm::CallInst::TailCallKind::TCK_MustTail); call->addFnAttr(llvm::Attribute::get(call->getContext(), "ark-tail-call")); CreateReturn(call); std::fill(ccValues_.begin(), ccValues_.end(), nullptr); @@ -2258,6 +2258,7 @@ llvm::CallInst *LLVMIrConstructor::CreateTailCallFastPath(Inst *inst) auto ftype = llvm::FunctionType::get(GetType(inst->GetType()), argTypes, false); callee = llvm::Function::Create(ftype, llvm::Function::ExternalLinkage, externalName, func_->getParent()); cc = func_->getCallingConv(); + callee->setCallingConv(cc); } else { size_t size = func_->arg_size(); ASSERT(callee->arg_size() <= size); diff --git a/static_core/tests/checked/checker.rb b/static_core/tests/checked/checker.rb index 6f0b49b9c..efb96ed61 100755 --- a/static_core/tests/checked/checker.rb +++ b/static_core/tests/checked/checker.rb @@ -188,7 +188,7 @@ class Checker # Current search scope @disasm_scope = nil - Dir.mkdir(@cwd) unless File.exists?(@cwd) + Dir.mkdir(@cwd) unless File.exist?(@cwd) clear_data end -- Gitee From 9056fc4c45dd08c91ca67efd3032742c321ff192 Mon Sep 17 00:00:00 2001 From: Denis Zavedeev Date: Mon, 28 Oct 2024 11:59:48 +0300 Subject: [PATCH 15/18] MergePostWrb Signed-off-by: Denis Zavedeev --- static_core/libllvmbackend/BUILD.gn | 1 + static_core/libllvmbackend/CMakeLists.txt | 1 + .../libllvmbackend/llvm_ark_interface.cpp | 6 + .../libllvmbackend/llvm_ark_interface.h | 1 + .../libllvmbackend/lowering/gc_barriers.cpp | 27 ++++ .../libllvmbackend/lowering/gc_barriers.h | 4 + .../libllvmbackend/transforms/builtins.cpp | 42 ++++++ .../libllvmbackend/transforms/builtins.h | 3 + .../transforms/llvm_optimizer.cpp | 1 + .../transforms/passes/merge_post_wrb.cpp | 142 ++++++++++++++++++ .../transforms/passes/merge_post_wrb.h | 70 +++++++++ .../transforms/passes/passes.yaml | 6 + .../libllvmbackend/transforms/pipeline.cfg | 1 + .../plugins/ets/tests/checked/CMakeLists.txt | 1 + .../ets/tests/checked/llvm_merge_post_wrb.sts | 54 +++++++ 15 files changed, 360 insertions(+) create mode 100644 static_core/libllvmbackend/transforms/passes/merge_post_wrb.cpp create mode 100644 static_core/libllvmbackend/transforms/passes/merge_post_wrb.h create mode 100644 static_core/plugins/ets/tests/checked/llvm_merge_post_wrb.sts diff --git a/static_core/libllvmbackend/BUILD.gn b/static_core/libllvmbackend/BUILD.gn index 395a68e96..e2b0cad61 100644 --- a/static_core/libllvmbackend/BUILD.gn +++ b/static_core/libllvmbackend/BUILD.gn @@ -96,6 +96,7 @@ if (is_llvmbackend) { "transforms/passes/intrinsics_lowering.cpp", "transforms/passes/loop_peeling.cpp", "transforms/passes/mem_barriers.cpp", + "transforms/passes/merge_post_wrb.cpp", "transforms/passes/panda_runtime_lowering.cpp", "transforms/passes/propagate_lenarray.cpp", "transforms/passes/prune_deopt.cpp", diff --git a/static_core/libllvmbackend/CMakeLists.txt b/static_core/libllvmbackend/CMakeLists.txt index 30c6db24d..34c1b14c0 100644 --- a/static_core/libllvmbackend/CMakeLists.txt +++ b/static_core/libllvmbackend/CMakeLists.txt @@ -71,6 +71,7 @@ set(SOURCES transforms/passes/intrinsics_lowering.cpp transforms/passes/loop_peeling.cpp transforms/passes/mem_barriers.cpp + transforms/passes/merge_post_wrb.cpp transforms/passes/panda_runtime_lowering.cpp transforms/passes/propagate_lenarray.cpp transforms/passes/prune_deopt.cpp diff --git a/static_core/libllvmbackend/llvm_ark_interface.cpp b/static_core/libllvmbackend/llvm_ark_interface.cpp index 4ecd8923b..f305d5b75 100644 --- a/static_core/libllvmbackend/llvm_ark_interface.cpp +++ b/static_core/libllvmbackend/llvm_ark_interface.cpp @@ -189,6 +189,12 @@ uint32_t LLVMArkInterface::GetManagedThreadPostWrbOneObjectOffset() const return cross_values::GetManagedThreadPostWrbOneObjectOffset(arkArch); } +uint32_t LLVMArkInterface::GetManagedThreadPostWrbTwoObjectsOffset() const +{ + Arch arkArch = LLVMArchToArkArch(triple_.getArch()); + return cross_values::GetManagedThreadPostWrbTwoObjectsOffset(arkArch); +} + size_t LLVMArkInterface::GetStackOverflowCheckOffset() const { return runtime_->GetStackOverflowCheckOffset(); diff --git a/static_core/libllvmbackend/llvm_ark_interface.h b/static_core/libllvmbackend/llvm_ark_interface.h index 65411e392..0a24da19c 100644 --- a/static_core/libllvmbackend/llvm_ark_interface.h +++ b/static_core/libllvmbackend/llvm_ark_interface.h @@ -124,6 +124,7 @@ public: uint32_t GetClassOffset() const; uint32_t GetManagedThreadPostWrbOneObjectOffset() const; + uint32_t GetManagedThreadPostWrbTwoObjectsOffset() const; size_t GetStackOverflowCheckOffset() const; uint32_t GetVTableOffset(llvm::Function *caller, uint32_t methodId) const; diff --git a/static_core/libllvmbackend/lowering/gc_barriers.cpp b/static_core/libllvmbackend/lowering/gc_barriers.cpp index bab5986e7..494f4c27a 100644 --- a/static_core/libllvmbackend/lowering/gc_barriers.cpp +++ b/static_core/libllvmbackend/lowering/gc_barriers.cpp @@ -118,4 +118,31 @@ void EmitPostWRB(llvm::IRBuilder<> *builder, llvm::Value *mem, llvm::Value *offs call->setCallingConv(llvm::CallingConv::ArkFast3); } +void EmitPostWRBTwoObjs(llvm::IRBuilder<> *builder, llvm::Value *mem, llvm::Value *offset, llvm::Value *value1, + llvm::Value *value2, LLVMArkInterface *arkInterface, llvm::Value *threadRegValue, + llvm::Value * /*frameRegValue*/) +{ + ASSERT(!arkInterface->IsIrtocMode()); + ASSERT(mem->getType()->isPointerTy()); + ASSERT(value1->getType()->isPointerTy() && + value1->getType()->getPointerAddressSpace() == LLVMArkInterface::GC_ADDR_SPACE); + ASSERT(value2->getType()->isPointerTy() && + value2->getType()->getPointerAddressSpace() == LLVMArkInterface::GC_ADDR_SPACE); + + auto tlsOffset = arkInterface->GetManagedThreadPostWrbTwoObjectsOffset(); + + auto gcPtrTy = builder->getPtrTy(LLVMArkInterface::GC_ADDR_SPACE); + auto ptrTy = builder->getPtrTy(); + auto memTy = mem->getType(); + auto int32Ty = builder->getInt32Ty(); + auto threadRegPtr = builder->CreateIntToPtr(threadRegValue, ptrTy); + auto addr = builder->CreateConstInBoundsGEP1_64(builder->getInt8Ty(), threadRegPtr, tlsOffset); + auto callee = builder->CreateLoad(ptrTy, addr, "post_wrb_two_objects_addr"); + + // LLVM AOT, 4 parameters + auto funcTy = llvm::FunctionType::get(builder->getVoidTy(), {memTy, int32Ty, gcPtrTy, gcPtrTy}, false); + auto call = builder->CreateCall(funcTy, callee, {mem, offset, value1, value2}); + call->setCallingConv(llvm::CallingConv::ArkFast4); +} + } // namespace ark::llvmbackend::gc_barriers diff --git a/static_core/libllvmbackend/lowering/gc_barriers.h b/static_core/libllvmbackend/lowering/gc_barriers.h index 5d8c70d65..269454bf2 100644 --- a/static_core/libllvmbackend/lowering/gc_barriers.h +++ b/static_core/libllvmbackend/lowering/gc_barriers.h @@ -28,6 +28,10 @@ void EmitPreWRB(llvm::IRBuilder<> *builder, llvm::Value *mem, bool isVolatileMem void EmitPostWRB(llvm::IRBuilder<> *builder, llvm::Value *mem, llvm::Value *offset, llvm::Value *value, LLVMArkInterface *arkInterface, llvm::Value *threadRegValue, llvm::Value *frameRegValue); + +void EmitPostWRBTwoObjs(llvm::IRBuilder<> *builder, llvm::Value *mem, llvm::Value *offset, llvm::Value *value1, + llvm::Value *value2, LLVMArkInterface *arkInterface, llvm::Value *threadRegValue, + llvm::Value *frameRegValue); } // namespace ark::llvmbackend::gc_barriers #endif // LIBLLVMBACKEND_LOWERING_GC_BARRIERS_H diff --git a/static_core/libllvmbackend/transforms/builtins.cpp b/static_core/libllvmbackend/transforms/builtins.cpp index ca1633a05..f876de201 100644 --- a/static_core/libllvmbackend/transforms/builtins.cpp +++ b/static_core/libllvmbackend/transforms/builtins.cpp @@ -62,6 +62,19 @@ llvm::Value *PostWRBHelper(llvm::IRBuilder<> *builder, llvm::CallInst *inst, LLV ark::llvmbackend::gc_barriers::EmitPostWRB(builder, mem, offset, value, arkInterface, threadReg, nullptr); return nullptr; } +llvm::Value *PostWRBTwoObjsHelper(llvm::IRBuilder<> *builder, llvm::CallInst *inst, LLVMArkInterface *arkInterface) +{ + auto mem = inst->getOperand(0U); + auto offset = inst->getOperand(1U); + auto value1 = inst->getOperand(2U); + auto value2 = inst->getOperand(3U); + + ASSERT(!arkInterface->IsIrtocMode()); + auto threadReg = GetThreadRegValue(builder, arkInterface); + ark::llvmbackend::gc_barriers::EmitPostWRBTwoObjs(builder, mem, offset, value1, value2, arkInterface, threadReg, + nullptr); + return nullptr; +} llvm::Value *FastClassLoadingHelper(llvm::IRBuilder<> *builder, LLVMArkInterface *arkInterface, llvm::BasicBlock *continuation) { @@ -307,6 +320,32 @@ llvm::Function *PostWRB(llvm::Module *module, unsigned addrSpace) return function; } +llvm::Function *PostWRBTwoObjs(llvm::Module *module, unsigned addrSpace) +{ + auto *builtinName = + (addrSpace == LLVMArkInterface::GC_ADDR_SPACE) ? POST_WRB_TWO_OBJS_GCADR_BUILTIN : POST_WRB_TWO_OBJS_BUILTIN; + auto *function = module->getFunction(builtinName); + if (function != nullptr) { + return function; + } + + auto &ctx = module->getContext(); + auto type = llvm::FunctionType::get(llvm::Type::getVoidTy(ctx), + {llvm::PointerType::get(ctx, addrSpace), llvm::Type::getInt32Ty(ctx), + llvm::PointerType::get(ctx, LLVMArkInterface::GC_ADDR_SPACE), + llvm::PointerType::get(ctx, LLVMArkInterface::GC_ADDR_SPACE)}, + false); + function = llvm::Function::Create(type, llvm::Function::ExternalLinkage, builtinName, module); + function->setDoesNotThrow(); + function->setSectionPrefix(BUILTIN_SECTION); + function->addFnAttr(llvm::Attribute::ArgMemOnly); + function->addFnAttr(llvm::Attribute::WillReturn); + function->addParamAttr(0U, llvm::Attribute::ReadNone); + function->addParamAttr(2U, llvm::Attribute::ReadNone); + function->addParamAttr(3U, llvm::Attribute::ReadNone); + return function; +} + llvm::Function *LoadString(llvm::Module *module) { auto function = module->getFunction(LOAD_STRING_BUILTIN); @@ -435,6 +474,9 @@ llvm::Value *LowerBuiltin(llvm::IRBuilder<> *builder, llvm::CallInst *inst, LLVM if (funcName.equals(POST_WRB_GCADR_BUILTIN) || funcName.equals(POST_WRB_BUILTIN)) { return PostWRBHelper(builder, inst, arkInterface); } + if (funcName.equals(POST_WRB_TWO_OBJS_BUILTIN) || funcName.equals(POST_WRB_TWO_OBJS_GCADR_BUILTIN)) { + return PostWRBTwoObjsHelper(builder, inst, arkInterface); + } if (funcName.equals(LOAD_STRING_BUILTIN)) { return LowerLoadString(builder, inst, arkInterface); } diff --git a/static_core/libllvmbackend/transforms/builtins.h b/static_core/libllvmbackend/transforms/builtins.h index b079b7cfb..e42c8271d 100644 --- a/static_core/libllvmbackend/transforms/builtins.h +++ b/static_core/libllvmbackend/transforms/builtins.h @@ -29,6 +29,7 @@ llvm::Function *LoadClass(llvm::Module *module); llvm::Function *LoadInitClass(llvm::Module *module); llvm::Function *PreWRB(llvm::Module *module, unsigned addrSpace); llvm::Function *PostWRB(llvm::Module *module, unsigned addrSpace); +llvm::Function *PostWRBTwoObjs(llvm::Module *module, unsigned addrSpace); llvm::Function *LoadString(llvm::Module *module); llvm::Function *ResolveVirtual(llvm::Module *module); llvm::Function *BarrierReturnVoid(llvm::Module *module); @@ -44,6 +45,8 @@ constexpr auto PRE_WRB_BUILTIN = "__builtin_pre_wrb"; constexpr auto PRE_WRB_GCADR_BUILTIN = "__builtin_pre_wrb_gcadr"; constexpr auto POST_WRB_BUILTIN = "__builtin_post_wrb"; constexpr auto POST_WRB_GCADR_BUILTIN = "__builtin_post_wrb_gcadr"; +constexpr auto POST_WRB_TWO_OBJS_BUILTIN = "__builtin_post_wrb_two_objs"; +constexpr auto POST_WRB_TWO_OBJS_GCADR_BUILTIN = "__builtin_post_wrb_two_objs_gcadr"; constexpr auto LOAD_STRING_BUILTIN = "__builtin_load_string"; constexpr auto RESOLVE_VIRTUAL_BUILTIN = "__builtin_resolve_virtual"; constexpr auto BARRIER_RETURN_VOID_BUILTIN = "__builtin_barrier_return_void"; diff --git a/static_core/libllvmbackend/transforms/llvm_optimizer.cpp b/static_core/libllvmbackend/transforms/llvm_optimizer.cpp index 4bfdcc3f4..829fe3953 100644 --- a/static_core/libllvmbackend/transforms/llvm_optimizer.cpp +++ b/static_core/libllvmbackend/transforms/llvm_optimizer.cpp @@ -24,6 +24,7 @@ #include "passes/gc_intrusion_check.h" #include "passes/intrinsics_lowering.h" #include "passes/mem_barriers.h" +#include "passes/merge_post_wrb.h" #include "passes/gep_propagation.h" #include "passes/panda_runtime_lowering.h" #include "passes/prune_deopt.h" diff --git a/static_core/libllvmbackend/transforms/passes/merge_post_wrb.cpp b/static_core/libllvmbackend/transforms/passes/merge_post_wrb.cpp new file mode 100644 index 000000000..a77b171c4 --- /dev/null +++ b/static_core/libllvmbackend/transforms/passes/merge_post_wrb.cpp @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2023-2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "merge_post_wrb.h" + +#include +#include + +#include "llvm_ark_interface.h" +#include "mem/mem.h" +#include "transforms/builtins.h" + +namespace ark::llvmbackend::passes { + +llvm::PreservedAnalyses MergePostWrb::run(llvm::Module &module, llvm::ModuleAnalysisManager & /*analysisManager*/) +{ + preWRBBuiltin_ = builtins::PreWRB(&module, 0); + postWRBBuiltin_ = builtins::PostWRB(&module, 0); + postWRBTwoObjsBuiltin_ = builtins::PostWRBTwoObjs(&module, 0); + preWRBGcAddrBuiltin_ = builtins::PreWRB(&module, LLVMArkInterface::GC_ADDR_SPACE); + postWRBGcAddrBuiltin_ = builtins::PostWRB(&module, LLVMArkInterface::GC_ADDR_SPACE); + postWRBGcAddrTwoObjsBuiltin_ = builtins::PostWRBTwoObjs(&module, LLVMArkInterface::GC_ADDR_SPACE); + + bool changed = false; + llvm::SmallVector chains; + for (auto &function : module) { + for (auto &block : function) { + if (block.empty()) { + continue; + } + + for (auto *inst = &block.front(); inst != nullptr;) { + auto *preWRB = llvm::dyn_cast_or_null(inst); + if (preWRB == nullptr) { + inst = GetNextWithEffects(inst); + continue; + } + + auto *preBuiltin = preWRB->getCalledFunction(); + if (preBuiltin != preWRBBuiltin_ && preBuiltin != preWRBGcAddrBuiltin_) { + inst = GetNextWithEffects(inst); + continue; + } + + inst = GetNextWithEffects(inst); + auto *store = llvm::dyn_cast_or_null(inst); + if (store == nullptr) { + continue; + } + + inst = GetNextWithEffects(inst); + auto *postWRB = llvm::dyn_cast_or_null(inst); + if (postWRB == nullptr) { + continue; + } + + auto *postBuiltin = postWRB->getCalledFunction(); + if (postBuiltin != postWRBBuiltin_ && postBuiltin != postWRBGcAddrBuiltin_) { + continue; + } + + bool inGcAddrSpace = false; + if (preBuiltin == preWRBBuiltin_ && postBuiltin == postWRBBuiltin_) { + inGcAddrSpace = false; + } else if (preBuiltin == preWRBGcAddrBuiltin_ && postBuiltin == postWRBGcAddrBuiltin_) { + inGcAddrSpace = true; + } else { + llvm_unreachable("Incorrent preWRB-store-postWRB chain!"); + } + + chains.emplace_back(preWRB, store, postWRB, inGcAddrSpace); + } + + for (size_t iChain = 0; iChain + 1 < chains.size(); iChain++) { + if (RunOnTwoStores(chains[iChain], chains[iChain + 1])) { + changed = true; + iChain++; + } + } + chains.clear(); + } + } + return changed ? llvm::PreservedAnalyses::none() : llvm::PreservedAnalyses::all(); +} + +bool MergePostWrb::RunOnTwoStores(const StoreChain &store1, const StoreChain &store2) +{ + if (store1.inGcAddrSpace_ != store2.inGcAddrSpace_) { + return false; + } + + auto *gep1 = llvm::dyn_cast(store1.store_->getPointerOperand()); + auto *gep2 = llvm::dyn_cast(store2.store_->getPointerOperand()); + if (gep1 == nullptr || gep2 == nullptr || gep1->getPointerOperand() != gep2->getPointerOperand()) { + return false; + } + + auto *offset1 = llvm::dyn_cast(store1.postWRB_->getArgOperand(1)); + auto *offset2 = llvm::dyn_cast(store2.postWRB_->getArgOperand(1)); + + if (offset1 == nullptr || offset2 == nullptr || + offset2->getSExtValue() - offset1->getSExtValue() != OBJECT_POINTER_SIZE) { + return false; + } + + store1.preWRB_->moveBefore(store2.preWRB_); + store1.store_->moveBefore(store2.store_); + llvm::IRBuilder<> builder(store2.postWRB_->getContext()); + builder.SetInsertPoint(store2.postWRB_); + builder.CreateCall(store1.inGcAddrSpace_ ? postWRBGcAddrTwoObjsBuiltin_ : postWRBTwoObjsBuiltin_, + {store1.postWRB_->getArgOperand(0), store1.postWRB_->getArgOperand(1), + store1.postWRB_->getArgOperand(2), store2.postWRB_->getArgOperand(2)}); + store1.postWRB_->eraseFromParent(); + store2.postWRB_->eraseFromParent(); + return true; +} + +llvm::Instruction *MergePostWrb::GetNextWithEffects(llvm::Instruction *inst) +{ + if (inst == nullptr) { + return nullptr; + } + + do { + inst = inst->getNextNode(); + } while ((inst != nullptr) && !inst->mayHaveSideEffects()); + return inst; +} + +} // namespace ark::llvmbackend::passes diff --git a/static_core/libllvmbackend/transforms/passes/merge_post_wrb.h b/static_core/libllvmbackend/transforms/passes/merge_post_wrb.h new file mode 100644 index 000000000..a19ce25f0 --- /dev/null +++ b/static_core/libllvmbackend/transforms/passes/merge_post_wrb.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2023-2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LIBLLVMBACKEND_TRANSFORMS_PASSES_BARRIER2_H +#define LIBLLVMBACKEND_TRANSFORMS_PASSES_BARRIER2_H + +#include +#include +#include + +namespace ark::llvmbackend { +struct LLVMCompilerOptions; +} // namespace ark::llvmbackend + +namespace ark::llvmbackend::passes { + +/// This pass merges two calls of post wrb to one call to wrb for two objects +class MergePostWrb : public llvm::PassInfoMixin { +public: + static constexpr llvm::StringRef ARG_NAME = "merge-post-wrb"; + + explicit MergePostWrb() = default; + + static bool ShouldInsert([[maybe_unused]] const ark::llvmbackend::LLVMCompilerOptions *options) + { + return true; + } + + // NOLINTNEXTLINE(readability-identifier-naming) + llvm::PreservedAnalyses run(llvm::Module &module, llvm::ModuleAnalysisManager &analysisManager); + +private: + struct StoreChain { + StoreChain(llvm::CallInst *preWRB, llvm::StoreInst *store, llvm::CallInst *postWRB, bool inGcAddrSpace) + : preWRB_(preWRB), store_(store), postWRB_(postWRB), inGcAddrSpace_(inGcAddrSpace) + { + } + + llvm::CallInst *preWRB_; + llvm::StoreInst *store_; + llvm::CallInst *postWRB_; + bool inGcAddrSpace_; + }; + bool RunOnTwoStores(const StoreChain &store1, const StoreChain &store2); + llvm::Instruction *GetNextWithEffects(llvm::Instruction *inst); + +private: + llvm::Function *preWRBBuiltin_ = nullptr; + llvm::Function *postWRBBuiltin_ = nullptr; + llvm::Function *postWRBTwoObjsBuiltin_ = nullptr; + llvm::Function *preWRBGcAddrBuiltin_ = nullptr; + llvm::Function *postWRBGcAddrBuiltin_ = nullptr; + llvm::Function *postWRBGcAddrTwoObjsBuiltin_ = nullptr; +}; + +} // namespace ark::llvmbackend::passes + +#endif // LIBLLVMBACKEND_TRANSFORMS_PASSES_BARRIER2_H diff --git a/static_core/libllvmbackend/transforms/passes/passes.yaml b/static_core/libllvmbackend/transforms/passes/passes.yaml index 5a1c5f684..8c7433787 100644 --- a/static_core/libllvmbackend/transforms/passes/passes.yaml +++ b/static_core/libllvmbackend/transforms/passes/passes.yaml @@ -178,3 +178,9 @@ llvm_passes: Replace builtin for LenArray with size type: [function] setup: default + +- name: MergePostWrb + description: > + Merge two calls of post wrb to one call to wrb for two objects + type: [module] + setup: default diff --git a/static_core/libllvmbackend/transforms/pipeline.cfg b/static_core/libllvmbackend/transforms/pipeline.cfg index 7503bc6ab..c3f691412 100644 --- a/static_core/libllvmbackend/transforms/pipeline.cfg +++ b/static_core/libllvmbackend/transforms/pipeline.cfg @@ -228,6 +228,7 @@ module( div-rem-pairs, # Hoist/decompose integer division and remainder simplifycfg # Simplify the CFG ), + merge-post-wrb, function( aarch64-fixup-sdiv, # ARK Fixup SDiv and SRem instructions on AArch64 diff --git a/static_core/plugins/ets/tests/checked/CMakeLists.txt b/static_core/plugins/ets/tests/checked/CMakeLists.txt index cd4281165..67086ddea 100644 --- a/static_core/plugins/ets/tests/checked/CMakeLists.txt +++ b/static_core/plugins/ets/tests/checked/CMakeLists.txt @@ -251,3 +251,4 @@ panda_add_checked_test_ets(FILE ${CMAKE_CURRENT_SOURCE_DIR}/escape_analysis_cast panda_add_checked_test_ets(FILE ${CMAKE_CURRENT_SOURCE_DIR}/load_array.sts) panda_add_checked_test_ets(FILE ${CMAKE_CURRENT_SOURCE_DIR}/optimize_negation.sts) panda_add_checked_test_ets(FILE ${CMAKE_CURRENT_SOURCE_DIR}/llvm_infer_flags.sts) +panda_add_checked_test_ets(FILE ${CMAKE_CURRENT_SOURCE_DIR}/llvm_merge_post_wrb.sts) diff --git a/static_core/plugins/ets/tests/checked/llvm_merge_post_wrb.sts b/static_core/plugins/ets/tests/checked/llvm_merge_post_wrb.sts new file mode 100644 index 000000000..d7c87520f --- /dev/null +++ b/static_core/plugins/ets/tests/checked/llvm_merge_post_wrb.sts @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//! CHECKER Merge post WRB optimization +//! RUN_LLVM options: "--llvm-options=--print-after=merge-post-wrb --compiler-regex='.*test'" +//! READ_FILE "console.out" +//! LLVM_METHOD /define protected.*test/ +//! INST_NEXT /call void @__builtin_pre_wrb_gcadr\(ptr addrspace\(271\) %\d+, i1 false\)/ +//! INST_NEXT /call void @__builtin_pre_wrb_gcadr\(ptr addrspace\(271\) %\d+, i1 false\)/ +//! INST_NEXT /store ptr addrspace\(271\) %v\d+, ptr addrspace\(271\) %\d+, align 4/ +//! INST_NEXT /store ptr addrspace\(271\) %v\d+, ptr addrspace\(271\) %\d+, align 4/ +//! INST_NEXT_NOT /call void @__builtin_post_wrb_gcadr/ +//! INST_NEXT /call void @__builtin_post_wrb_two_objs_gcadr\(ptr addrspace\(271\) %v\d+, i32 8, ptr addrspace\(271\) %v\d+, ptr addrspace\(271\) %v\d+\)/ +//! INST_NEXT /call void @__builtin_pre_wrb_gcadr\(ptr addrspace\(271\) %\d+, i1 false\)/ +//! INST_NEXT /call void @__builtin_pre_wrb_gcadr\(ptr addrspace\(271\) %\d+, i1 false\)/ +//! INST_NEXT /store ptr addrspace\(271\) %v\d+, ptr addrspace\(271\) %\d+, align 4/ +//! INST_NEXT /store ptr addrspace\(271\) %v\d+, ptr addrspace\(271\) %\d+, align 4/ +//! INST_NEXT_NOT /call void @__builtin_post_wrb_gcadr/ +//! INST_NEXT /call void @__builtin_post_wrb_two_objs_gcadr\(ptr addrspace\(271\) %v\d+, i32 12, ptr addrspace\(271\) %v\d+, ptr addrspace\(271\) %v\d+\)/ +//! RUN entry: "ETSGLOBAL::test" + +class A { + public field: int = 0; +} + +class B { + public field1: A = new A(); + public field2: A = new A(); + public field3: A = new A(); +} + +function test() { + let val1 = new A() + let val2 = new A() + let b = new B() + + b.field1 = val1 + b.field2 = val2 + + b.field2 = val1; + b.field3 = val1; +} -- Gitee From 7060f7e01ca8549c4fc54a8ce9b530c0abec3dd9 Mon Sep 17 00:00:00 2001 From: Denis Zavedeev Date: Mon, 28 Oct 2024 17:57:38 +0300 Subject: [PATCH 16/18] Review Signed-off-by: Denis Zavedeev --- .../libllvmbackend/lowering/gc_barriers.cpp | 3 +- .../libllvmbackend/lowering/gc_barriers.h | 3 +- .../libllvmbackend/transforms/builtins.cpp | 3 +- .../transforms/passes/merge_post_wrb.cpp | 109 +++++++++--------- .../transforms/passes/merge_post_wrb.h | 6 + .../libllvmbackend/transforms/pipeline.cfg | 1 - 6 files changed, 66 insertions(+), 59 deletions(-) diff --git a/static_core/libllvmbackend/lowering/gc_barriers.cpp b/static_core/libllvmbackend/lowering/gc_barriers.cpp index 494f4c27a..ef3608766 100644 --- a/static_core/libllvmbackend/lowering/gc_barriers.cpp +++ b/static_core/libllvmbackend/lowering/gc_barriers.cpp @@ -119,8 +119,7 @@ void EmitPostWRB(llvm::IRBuilder<> *builder, llvm::Value *mem, llvm::Value *offs } void EmitPostWRBTwoObjs(llvm::IRBuilder<> *builder, llvm::Value *mem, llvm::Value *offset, llvm::Value *value1, - llvm::Value *value2, LLVMArkInterface *arkInterface, llvm::Value *threadRegValue, - llvm::Value * /*frameRegValue*/) + llvm::Value *value2, LLVMArkInterface *arkInterface, llvm::Value *threadRegValue) { ASSERT(!arkInterface->IsIrtocMode()); ASSERT(mem->getType()->isPointerTy()); diff --git a/static_core/libllvmbackend/lowering/gc_barriers.h b/static_core/libllvmbackend/lowering/gc_barriers.h index 269454bf2..bd9ac5fae 100644 --- a/static_core/libllvmbackend/lowering/gc_barriers.h +++ b/static_core/libllvmbackend/lowering/gc_barriers.h @@ -30,8 +30,7 @@ void EmitPostWRB(llvm::IRBuilder<> *builder, llvm::Value *mem, llvm::Value *offs LLVMArkInterface *arkInterface, llvm::Value *threadRegValue, llvm::Value *frameRegValue); void EmitPostWRBTwoObjs(llvm::IRBuilder<> *builder, llvm::Value *mem, llvm::Value *offset, llvm::Value *value1, - llvm::Value *value2, LLVMArkInterface *arkInterface, llvm::Value *threadRegValue, - llvm::Value *frameRegValue); + llvm::Value *value2, LLVMArkInterface *arkInterface, llvm::Value *threadRegValue); } // namespace ark::llvmbackend::gc_barriers #endif // LIBLLVMBACKEND_LOWERING_GC_BARRIERS_H diff --git a/static_core/libllvmbackend/transforms/builtins.cpp b/static_core/libllvmbackend/transforms/builtins.cpp index f876de201..e5f155dda 100644 --- a/static_core/libllvmbackend/transforms/builtins.cpp +++ b/static_core/libllvmbackend/transforms/builtins.cpp @@ -71,8 +71,7 @@ llvm::Value *PostWRBTwoObjsHelper(llvm::IRBuilder<> *builder, llvm::CallInst *in ASSERT(!arkInterface->IsIrtocMode()); auto threadReg = GetThreadRegValue(builder, arkInterface); - ark::llvmbackend::gc_barriers::EmitPostWRBTwoObjs(builder, mem, offset, value1, value2, arkInterface, threadReg, - nullptr); + ark::llvmbackend::gc_barriers::EmitPostWRBTwoObjs(builder, mem, offset, value1, value2, arkInterface, threadReg); return nullptr; } llvm::Value *FastClassLoadingHelper(llvm::IRBuilder<> *builder, LLVMArkInterface *arkInterface, diff --git a/static_core/libllvmbackend/transforms/passes/merge_post_wrb.cpp b/static_core/libllvmbackend/transforms/passes/merge_post_wrb.cpp index a77b171c4..baf17d606 100644 --- a/static_core/libllvmbackend/transforms/passes/merge_post_wrb.cpp +++ b/static_core/libllvmbackend/transforms/passes/merge_post_wrb.cpp @@ -37,64 +37,69 @@ llvm::PreservedAnalyses MergePostWrb::run(llvm::Module &module, llvm::ModuleAnal llvm::SmallVector chains; for (auto &function : module) { for (auto &block : function) { - if (block.empty()) { - continue; - } - - for (auto *inst = &block.front(); inst != nullptr;) { - auto *preWRB = llvm::dyn_cast_or_null(inst); - if (preWRB == nullptr) { - inst = GetNextWithEffects(inst); - continue; - } - - auto *preBuiltin = preWRB->getCalledFunction(); - if (preBuiltin != preWRBBuiltin_ && preBuiltin != preWRBGcAddrBuiltin_) { - inst = GetNextWithEffects(inst); - continue; - } - - inst = GetNextWithEffects(inst); - auto *store = llvm::dyn_cast_or_null(inst); - if (store == nullptr) { - continue; - } - - inst = GetNextWithEffects(inst); - auto *postWRB = llvm::dyn_cast_or_null(inst); - if (postWRB == nullptr) { - continue; - } - - auto *postBuiltin = postWRB->getCalledFunction(); - if (postBuiltin != postWRBBuiltin_ && postBuiltin != postWRBGcAddrBuiltin_) { - continue; - } - - bool inGcAddrSpace = false; - if (preBuiltin == preWRBBuiltin_ && postBuiltin == postWRBBuiltin_) { - inGcAddrSpace = false; - } else if (preBuiltin == preWRBGcAddrBuiltin_ && postBuiltin == postWRBGcAddrBuiltin_) { - inGcAddrSpace = true; - } else { - llvm_unreachable("Incorrent preWRB-store-postWRB chain!"); - } - - chains.emplace_back(preWRB, store, postWRB, inGcAddrSpace); - } - - for (size_t iChain = 0; iChain + 1 < chains.size(); iChain++) { - if (RunOnTwoStores(chains[iChain], chains[iChain + 1])) { - changed = true; - iChain++; - } - } + CollectStoreChains(&chains, &block); + changed |= MergeStores(chains); chains.clear(); } } return changed ? llvm::PreservedAnalyses::none() : llvm::PreservedAnalyses::all(); } +void MergePostWrb::CollectStoreChains(llvm::SmallVector *chains, llvm::BasicBlock *block) +{ + ASSERT(chains->empty()); + if (block->empty()) { + return; + } + + for (auto *inst = &block->front(); inst != nullptr;) { + auto *preWRB = llvm::dyn_cast_or_null(inst); + if (preWRB == nullptr) { + inst = GetNextWithEffects(inst); + continue; + } + + auto *preBuiltin = preWRB->getCalledFunction(); + if (preBuiltin != preWRBBuiltin_ && preBuiltin != preWRBGcAddrBuiltin_) { + inst = GetNextWithEffects(inst); + continue; + } + + inst = GetNextWithEffects(inst); + auto *store = llvm::dyn_cast_or_null(inst); + if (store == nullptr) { + continue; + } + + inst = GetNextWithEffects(inst); + auto *postWRB = llvm::dyn_cast_or_null(inst); + if (postWRB == nullptr) { + continue; + } + + auto *postBuiltin = postWRB->getCalledFunction(); + if (postBuiltin != postWRBBuiltin_ && postBuiltin != postWRBGcAddrBuiltin_) { + continue; + } + + bool inGcAddrSpace = preBuiltin == preWRBGcAddrBuiltin_ && postBuiltin == postWRBGcAddrBuiltin_; + ASSERT(inGcAddrSpace || (preBuiltin == preWRBBuiltin_ && postBuiltin == postWRBBuiltin_)); + chains->emplace_back(preWRB, store, postWRB, inGcAddrSpace); + } +} + +bool MergePostWrb::MergeStores(const llvm::SmallVector &chains) +{ + bool changed = false; + for (size_t i = 0; i + 1 < chains.size(); i++) { + if (RunOnTwoStores(chains[i], chains[i + 1])) { + changed = true; + i++; + } + } + return changed; +} + bool MergePostWrb::RunOnTwoStores(const StoreChain &store1, const StoreChain &store2) { if (store1.inGcAddrSpace_ != store2.inGcAddrSpace_) { diff --git a/static_core/libllvmbackend/transforms/passes/merge_post_wrb.h b/static_core/libllvmbackend/transforms/passes/merge_post_wrb.h index a19ce25f0..52712d79f 100644 --- a/static_core/libllvmbackend/transforms/passes/merge_post_wrb.h +++ b/static_core/libllvmbackend/transforms/passes/merge_post_wrb.h @@ -53,9 +53,15 @@ private: llvm::CallInst *postWRB_; bool inGcAddrSpace_; }; + bool RunOnTwoStores(const StoreChain &store1, const StoreChain &store2); + llvm::Instruction *GetNextWithEffects(llvm::Instruction *inst); + void CollectStoreChains(llvm::SmallVector *chains, llvm::BasicBlock *block); + + bool MergeStores(const llvm::SmallVector &chains); + private: llvm::Function *preWRBBuiltin_ = nullptr; llvm::Function *postWRBBuiltin_ = nullptr; diff --git a/static_core/libllvmbackend/transforms/pipeline.cfg b/static_core/libllvmbackend/transforms/pipeline.cfg index c3f691412..6277bd448 100644 --- a/static_core/libllvmbackend/transforms/pipeline.cfg +++ b/static_core/libllvmbackend/transforms/pipeline.cfg @@ -229,7 +229,6 @@ module( simplifycfg # Simplify the CFG ), merge-post-wrb, - function( aarch64-fixup-sdiv, # ARK Fixup SDiv and SRem instructions on AArch64 mem-barriers, # ARK Memory Barriers placement -- Gitee From b509015c14752e588b0cabded2e1c02439a3ca52 Mon Sep 17 00:00:00 2001 From: Denis Zavedeev Date: Tue, 29 Oct 2024 18:16:28 +0300 Subject: [PATCH 17/18] Fix clang-tidy Signed-off-by: Denis Zavedeev --- .../transforms/passes/merge_post_wrb.cpp | 28 +++++++++---------- .../transforms/passes/merge_post_wrb.h | 26 +++++++++++++++-- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/static_core/libllvmbackend/transforms/passes/merge_post_wrb.cpp b/static_core/libllvmbackend/transforms/passes/merge_post_wrb.cpp index baf17d606..0c4e0aa28 100644 --- a/static_core/libllvmbackend/transforms/passes/merge_post_wrb.cpp +++ b/static_core/libllvmbackend/transforms/passes/merge_post_wrb.cpp @@ -102,33 +102,33 @@ bool MergePostWrb::MergeStores(const llvm::SmallVector &chains) bool MergePostWrb::RunOnTwoStores(const StoreChain &store1, const StoreChain &store2) { - if (store1.inGcAddrSpace_ != store2.inGcAddrSpace_) { + if (store1.IsInGcAddrSpace() != store2.IsInGcAddrSpace()) { return false; } - auto *gep1 = llvm::dyn_cast(store1.store_->getPointerOperand()); - auto *gep2 = llvm::dyn_cast(store2.store_->getPointerOperand()); + auto *gep1 = llvm::dyn_cast(store1.GetStore()->getPointerOperand()); + auto *gep2 = llvm::dyn_cast(store2.GetStore()->getPointerOperand()); if (gep1 == nullptr || gep2 == nullptr || gep1->getPointerOperand() != gep2->getPointerOperand()) { return false; } - auto *offset1 = llvm::dyn_cast(store1.postWRB_->getArgOperand(1)); - auto *offset2 = llvm::dyn_cast(store2.postWRB_->getArgOperand(1)); + auto *offset1 = llvm::dyn_cast(store1.GetPostWrb()->getArgOperand(1)); + auto *offset2 = llvm::dyn_cast(store2.GetPostWrb()->getArgOperand(1)); if (offset1 == nullptr || offset2 == nullptr || offset2->getSExtValue() - offset1->getSExtValue() != OBJECT_POINTER_SIZE) { return false; } - store1.preWRB_->moveBefore(store2.preWRB_); - store1.store_->moveBefore(store2.store_); - llvm::IRBuilder<> builder(store2.postWRB_->getContext()); - builder.SetInsertPoint(store2.postWRB_); - builder.CreateCall(store1.inGcAddrSpace_ ? postWRBGcAddrTwoObjsBuiltin_ : postWRBTwoObjsBuiltin_, - {store1.postWRB_->getArgOperand(0), store1.postWRB_->getArgOperand(1), - store1.postWRB_->getArgOperand(2), store2.postWRB_->getArgOperand(2)}); - store1.postWRB_->eraseFromParent(); - store2.postWRB_->eraseFromParent(); + store1.GetPreWrb()->moveBefore(store2.GetPreWrb()); + store1.GetStore()->moveBefore(store2.GetStore()); + llvm::IRBuilder<> builder(store2.GetPostWrb()->getContext()); + builder.SetInsertPoint(store2.GetPostWrb()); + builder.CreateCall(store1.IsInGcAddrSpace() ? postWRBGcAddrTwoObjsBuiltin_ : postWRBTwoObjsBuiltin_, + {store1.GetPostWrb()->getArgOperand(0), store1.GetPostWrb()->getArgOperand(1), + store1.GetPostWrb()->getArgOperand(2), store2.GetPostWrb()->getArgOperand(2)}); + store1.GetPostWrb()->eraseFromParent(); + store2.GetPostWrb()->eraseFromParent(); return true; } diff --git a/static_core/libllvmbackend/transforms/passes/merge_post_wrb.h b/static_core/libllvmbackend/transforms/passes/merge_post_wrb.h index 52712d79f..1a6022e3c 100644 --- a/static_core/libllvmbackend/transforms/passes/merge_post_wrb.h +++ b/static_core/libllvmbackend/transforms/passes/merge_post_wrb.h @@ -42,12 +42,34 @@ public: llvm::PreservedAnalyses run(llvm::Module &module, llvm::ModuleAnalysisManager &analysisManager); private: - struct StoreChain { + class StoreChain { + public: StoreChain(llvm::CallInst *preWRB, llvm::StoreInst *store, llvm::CallInst *postWRB, bool inGcAddrSpace) - : preWRB_(preWRB), store_(store), postWRB_(postWRB), inGcAddrSpace_(inGcAddrSpace) + : preWRB_ {preWRB}, store_ {store}, postWRB_ {postWRB}, inGcAddrSpace_ {inGcAddrSpace} { } + llvm::CallInst *GetPreWrb() const + { + return preWRB_; + } + + llvm::StoreInst *GetStore() const + { + return store_; + } + + llvm::CallInst *GetPostWrb() const + { + return postWRB_; + } + + bool IsInGcAddrSpace() const + { + return inGcAddrSpace_; + } + + private: llvm::CallInst *preWRB_; llvm::StoreInst *store_; llvm::CallInst *postWRB_; -- Gitee From 24f689278c771d7aeedc7c909b175ae0af74ac8e Mon Sep 17 00:00:00 2001 From: Denis Zavedeev Date: Thu, 31 Oct 2024 12:45:54 +0300 Subject: [PATCH 18/18] Add IsSuccessive check Signed-off-by: Denis Zavedeev --- .../transforms/passes/merge_post_wrb.cpp | 4 +++ .../transforms/passes/merge_post_wrb.h | 5 +++ .../ets/tests/checked/llvm_merge_post_wrb.sts | 36 +++++++++++++++++++ 3 files changed, 45 insertions(+) diff --git a/static_core/libllvmbackend/transforms/passes/merge_post_wrb.cpp b/static_core/libllvmbackend/transforms/passes/merge_post_wrb.cpp index 0c4e0aa28..fe7ac02e7 100644 --- a/static_core/libllvmbackend/transforms/passes/merge_post_wrb.cpp +++ b/static_core/libllvmbackend/transforms/passes/merge_post_wrb.cpp @@ -102,6 +102,10 @@ bool MergePostWrb::MergeStores(const llvm::SmallVector &chains) bool MergePostWrb::RunOnTwoStores(const StoreChain &store1, const StoreChain &store2) { + if (!IsSuccessive(store1.GetPostWrb(), store2.GetPreWrb())) { + return false; + } + if (store1.IsInGcAddrSpace() != store2.IsInGcAddrSpace()) { return false; } diff --git a/static_core/libllvmbackend/transforms/passes/merge_post_wrb.h b/static_core/libllvmbackend/transforms/passes/merge_post_wrb.h index 1a6022e3c..e406ac0cf 100644 --- a/static_core/libllvmbackend/transforms/passes/merge_post_wrb.h +++ b/static_core/libllvmbackend/transforms/passes/merge_post_wrb.h @@ -84,6 +84,11 @@ private: bool MergeStores(const llvm::SmallVector &chains); + bool IsSuccessive(llvm::Instruction *from, llvm::Instruction *to) + { + return GetNextWithEffects(from) == to; + } + private: llvm::Function *preWRBBuiltin_ = nullptr; llvm::Function *postWRBBuiltin_ = nullptr; diff --git a/static_core/plugins/ets/tests/checked/llvm_merge_post_wrb.sts b/static_core/plugins/ets/tests/checked/llvm_merge_post_wrb.sts index d7c87520f..a23b80569 100644 --- a/static_core/plugins/ets/tests/checked/llvm_merge_post_wrb.sts +++ b/static_core/plugins/ets/tests/checked/llvm_merge_post_wrb.sts @@ -31,6 +31,10 @@ //! INST_NEXT /call void @__builtin_post_wrb_two_objs_gcadr\(ptr addrspace\(271\) %v\d+, i32 12, ptr addrspace\(271\) %v\d+, ptr addrspace\(271\) %v\d+\)/ //! RUN entry: "ETSGLOBAL::test" +//! CHECKER Merge post WRB optimization 2 +//! RUN_LLVM options: "" +//! RUN entry: "ETSGLOBAL::main" + class A { public field: int = 0; } @@ -52,3 +56,35 @@ function test() { b.field2 = val1; b.field3 = val1; } + +class IntegerBox { + public v: int + + constructor(v: int) { + this.v = v; + } +} + +class MyDemo { + a: IntegerBox | null = null + b: IntegerBox | null = null +} + +function check__noinline__(myDemo: MyDemo) { + if (myDemo.a == null || myDemo.a!.v != 1) { + throw new Error() + } + if (myDemo.b != null) { + throw new Error() + } +} + +function main() { + let one = new IntegerBox(1) + let two = new IntegerBox(2) + + let demo = new MyDemo() + demo.a = one + check__noinline__(demo) + demo.b = two +} -- Gitee