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! >> }; >> >> 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