On Mon, Jul 9, 2018 at 11:03 PM, Dave Airlie <airl...@gmail.com> wrote: > On 9 July 2018 at 05:58, Bas Nieuwenhuizen <b...@basnieuwenhuizen.nl> wrote: >> On Thu, Jul 5, 2018 at 2:03 AM, Dave Airlie <airl...@gmail.com> wrote: >>> From: Dave Airlie <airl...@redhat.com> >>> >>> This uses the common compiler passes abstraction to help radv >>> avoid fixed cost compiler overheads. This uses a linked list per >>> thread stored in thread local storage, with an entry in the list >>> for each target machine. >>> >>> This should remove all the fixed overheads setup costs of creating >>> the pass manager each time. >>> >>> This takes a demo app time to compile the radv meta shaders on nocache >>> and exit from 1.7s to 1s. It also has been reported to take the startup >>> time of uncached shaders on RoTR from 12m24s to 11m35s (Alex) >>> >>> v2: fix llvm6 build, inline emit function, handle multiple targets >>> in one thread >>> v3: rebase and port onto new structure >>> v4: rename some vars (Bas) >>> v5: drag all code into radv for now, we can refactor it out later >>> for radeonsi if we make it shareable >>> v6: use a bit more C++ in the wrapper >>> v7: logic bugs fixed so it actually runs again. >>> v8: rebase on top of radeonsi changes. >>> --- >>> src/amd/vulkan/Makefile.sources | 2 + >>> src/amd/vulkan/meson.build | 2 + >>> src/amd/vulkan/radv_debug.h | 1 + >>> src/amd/vulkan/radv_device.c | 1 + >>> src/amd/vulkan/radv_llvm_helper.cpp | 148 ++++++++++++++++++++++++++++ >>> src/amd/vulkan/radv_nir_to_llvm.c | 27 +---- >>> src/amd/vulkan/radv_shader.c | 10 +- >>> src/amd/vulkan/radv_shader_helper.h | 44 +++++++++ >>> 8 files changed, 207 insertions(+), 28 deletions(-) >>> create mode 100644 src/amd/vulkan/radv_llvm_helper.cpp >>> create mode 100644 src/amd/vulkan/radv_shader_helper.h >>> >>> diff --git a/src/amd/vulkan/Makefile.sources >>> b/src/amd/vulkan/Makefile.sources >>> index 70d56e88cb3..152fdd7cb71 100644 >>> --- a/src/amd/vulkan/Makefile.sources >>> +++ b/src/amd/vulkan/Makefile.sources >>> @@ -54,6 +54,7 @@ VULKAN_FILES := \ >>> radv_meta_resolve_cs.c \ >>> radv_meta_resolve_fs.c \ >>> radv_nir_to_llvm.c \ >>> + radv_llvm_helper.cpp \ >>> radv_pass.c \ >>> radv_pipeline.c \ >>> radv_pipeline_cache.c \ >>> @@ -62,6 +63,7 @@ VULKAN_FILES := \ >>> radv_shader.c \ >>> radv_shader_info.c \ >>> radv_shader.h \ >>> + radv_shader_helper.h \ >>> radv_query.c \ >>> radv_util.c \ >>> radv_util.h \ >>> diff --git a/src/amd/vulkan/meson.build b/src/amd/vulkan/meson.build >>> index 22857926fa1..9f2842182e7 100644 >>> --- a/src/amd/vulkan/meson.build >>> +++ b/src/amd/vulkan/meson.build >>> @@ -67,6 +67,7 @@ libradv_files = files( >>> 'radv_descriptor_set.h', >>> 'radv_formats.c', >>> 'radv_image.c', >>> + 'radv_llvm_helper.cpp', >>> 'radv_meta.c', >>> 'radv_meta.h', >>> 'radv_meta_blit.c', >>> @@ -88,6 +89,7 @@ libradv_files = files( >>> 'radv_radeon_winsys.h', >>> 'radv_shader.c', >>> 'radv_shader.h', >>> + 'radv_shader_helper.h', >>> 'radv_shader_info.c', >>> 'radv_query.c', >>> 'radv_util.c', >>> diff --git a/src/amd/vulkan/radv_debug.h b/src/amd/vulkan/radv_debug.h >>> index f1b0dc26a63..9fe4c3b7404 100644 >>> --- a/src/amd/vulkan/radv_debug.h >>> +++ b/src/amd/vulkan/radv_debug.h >>> @@ -49,6 +49,7 @@ enum { >>> RADV_DEBUG_ERRORS = 0x80000, >>> RADV_DEBUG_STARTUP = 0x100000, >>> RADV_DEBUG_CHECKIR = 0x200000, >>> + RADV_DEBUG_NOTHREADLLVM = 0x400000, > > In response to your second query, I'm not sure I understand. > NOTHREADLLVM is here!
woops, I somehow missed it. > >>> }; >>> >>> enum { >>> diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c >>> index ad3465f594e..73c48cef1f0 100644 >>> --- a/src/amd/vulkan/radv_device.c >>> +++ b/src/amd/vulkan/radv_device.c >>> @@ -436,6 +436,7 @@ static const struct debug_control radv_debug_options[] >>> = { >>> {"errors", RADV_DEBUG_ERRORS}, >>> {"startup", RADV_DEBUG_STARTUP}, >>> {"checkir", RADV_DEBUG_CHECKIR}, >>> + {"nothreadllvm", RADV_DEBUG_NOTHREADLLVM}, >>> {NULL, 0} >>> }; >>> >>> diff --git a/src/amd/vulkan/radv_llvm_helper.cpp >>> b/src/amd/vulkan/radv_llvm_helper.cpp >>> new file mode 100644 >>> index 00000000000..dad881f6b1a >>> --- /dev/null >>> +++ b/src/amd/vulkan/radv_llvm_helper.cpp >>> @@ -0,0 +1,148 @@ >>> +/* >>> + * Copyright © 2018 Red Hat. >>> + * >>> + * Permission is hereby granted, free of charge, to any person obtaining a >>> + * copy of this software and associated documentation files (the >>> "Software"), >>> + * to deal in the Software without restriction, including without >>> limitation >>> + * the rights to use, copy, modify, merge, publish, distribute, sublicense, >>> + * and/or sell copies of the Software, and to permit persons to whom the >>> + * Software is furnished to do so, subject to the following conditions: >>> + * >>> + * The above copyright notice and this permission notice (including the >>> next >>> + * paragraph) shall be included in all copies or substantial portions of >>> the >>> + * Software. >>> + * >>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS >>> OR >>> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, >>> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL >>> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR >>> OTHER >>> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING >>> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER >>> DEALINGS >>> + * IN THE SOFTWARE. >>> + */ >>> +#include "ac_llvm_util.h" >>> +#include "ac_llvm_build.h" >>> +#include "radv_shader_helper.h" >>> +#include <llvm-c/Core.h> >>> +#include <llvm-c/Support.h> >>> +#include <llvm/Target/TargetMachine.h> >>> +#include <llvm/Analysis/TargetLibraryInfo.h> >>> +#include <llvm/IR/LegacyPassManager.h> >>> +#if HAVE_LLVM >= 0x0700 >>> +#include <llvm-c/Transforms/Utils.h> >>> +#endif >>> +#if HAVE_LLVM < 0x0700 >>> +#include "llvm/Support/raw_ostream.h" >>> +#endif >>> + >>> +class radv_llvm_per_thread_info { >>> +public: >>> + radv_llvm_per_thread_info(enum radeon_family arg_family, >>> + enum ac_target_machine_options >>> arg_tm_options) >>> + : family(arg_family), tm_options(arg_tm_options) {} >>> + >>> + ~radv_llvm_per_thread_info() >>> + { >>> + ac_destroy_llvm_passes(passes); >>> + ac_destroy_llvm_compiler(&llvm_info); >>> + } >>> + >>> + bool init(void) >>> + { >>> + if (!ac_init_llvm_compiler(&llvm_info, >>> + true, >>> + family, >>> + tm_options)) >>> + return false; >>> + >>> + passes = ac_create_llvm_passes(llvm_info.tm); >>> + if (!passes) >>> + return false; >>> + >>> + return true; >>> + } >>> + >>> + bool compile_to_memory_buffer(LLVMModuleRef module, >>> + struct ac_shader_binary *binary) >>> + { >>> + return ac_compile_module_to_binary(passes, module, binary); >>> + } >>> + >>> + bool is_same(enum radeon_family arg_family, >>> + enum ac_target_machine_options arg_tm_options) { >>> + if (arg_family == family && >>> + arg_tm_options == tm_options) >>> + return true; >>> + return false; >>> + } >>> + struct ac_llvm_compiler llvm_info; >>> +private: >>> + enum radeon_family family; >>> + enum ac_target_machine_options tm_options; >>> + struct ac_compiler_passes *passes; >>> +}; >>> + >>> +/* we have to store a linked list per thread due to the possiblity of >>> multiple gpus being required */ >>> +static thread_local std::list<radv_llvm_per_thread_info> >>> radv_llvm_per_thread_list; >>> + >>> +bool radv_compile_to_binary(struct ac_llvm_compiler *info, >>> + LLVMModuleRef module, >>> + struct ac_shader_binary *binary) >>> +{ >>> + radv_llvm_per_thread_info *thread_info = nullptr; >>> + >>> + for (auto &I : radv_llvm_per_thread_list) { >>> + if (I.llvm_info.tm == info->tm) { >>> + thread_info = &I; >>> + break; >>> + } >>> + } >>> + >>> + if (!thread_info) { >>> + struct ac_compiler_passes *passes = >>> ac_create_llvm_passes(info->tm); >>> + bool ret = ac_compile_module_to_binary(passes, module, >>> binary); >>> + ac_destroy_llvm_passes(passes); >>> + return ret; >>> + } >>> + >>> + return thread_info->compile_to_memory_buffer(module, binary); >>> +} >>> + >>> +bool radv_init_llvm_compiler(struct ac_llvm_compiler *info, >>> + bool okay_to_leak_target_library_info, >>> + bool thread_compiler, >>> + enum radeon_family family, >>> + enum ac_target_machine_options tm_options) >>> +{ >>> + if (thread_compiler) { >>> + for (auto &I : radv_llvm_per_thread_list) { >>> + if (I.is_same(family, tm_options)) { >>> + *info = I.llvm_info; >>> + return true; >>> + } >>> + } >>> + >>> + radv_llvm_per_thread_list.emplace_back(family, tm_options); >>> + radv_llvm_per_thread_info &tinfo = >>> radv_llvm_per_thread_list.back(); >>> + >>> + if (!tinfo.init()) >>> + return false; >> >> Clean up the newly inserted list entry? > > Once I figure out how to do it nicely :-) > > Dave. _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev