Disable code generation optimization for MSan builds LLVM intermediate code instrumented by MemorySanitizer can take an inordinate amount of time to compile into machine code when using the llvm::CodeGenOpt::Default optimization level. While lower optimization levels can make the generated code slower to execute, the 'None' level is just 5-20% slower, which is negligible compared to the slowdown from the instructions added by the MSan instrumentation itself. llvm::CodeGenOpt::Default: ------------------------------------------------- Benchmark Time ------------------------------------------------- ClearImage/VK_FORMAT_R8G8B8A8_UNORM 0.912 ms ClearImage/VK_FORMAT_R32_SFLOAT 3.83 ms ClearImage/VK_FORMAT_D32_SFLOAT 0.866 ms Triangle/Hello 0.996 ms Triangle/Multisample 4.63 ms llvm::CodeGenOpt::None: ------------------------------------------------- Benchmark Time ------------------------------------------------- ClearImage/VK_FORMAT_R8G8B8A8_UNORM 0.974 ms ClearImage/VK_FORMAT_R32_SFLOAT 5.42 ms ClearImage/VK_FORMAT_D32_SFLOAT 0.937 ms Triangle/Hello 1.16 ms Triangle/Multisample 4.70 ms Bug: b/173257647 Change-Id: I0d14bf1834ce23045409fa162153991cabbeac3c Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/50448 Presubmit-Ready: Nicolas Capens <nicolascapens@google.com> Reviewed-by: Antonio Maiorano <amaiorano@google.com> Tested-by: Nicolas Capens <nicolascapens@google.com> Kokoro-Result: kokoro <noreply+kokoro@google.com>
diff --git a/src/Reactor/Nucleus.hpp b/src/Reactor/Nucleus.hpp index 4c08ddd..b300d9b 100644 --- a/src/Reactor/Nucleus.hpp +++ b/src/Reactor/Nucleus.hpp
@@ -28,6 +28,12 @@ # undef None // TODO(b/127920555) #endif +// A Clang extension to determine compiler features. +// We use it to detect Sanitizer builds (e.g. -fsanitize=memory). +#ifndef __has_feature +# define __has_feature(x) 0 +#endif + static_assert(sizeof(short) == 2, "Reactor's 'Short' type is 16-bit, and requires the C++ 'short' to match that."); static_assert(sizeof(int) == 4, "Reactor's 'Int' type is 32-bit, and requires the C++ 'int' to match that."); @@ -79,6 +85,14 @@ this->level = Level::REACTOR_DEFAULT_OPT_LEVEL; } #endif + + // TODO(b/173257647): MemorySanitizer instrumentation produces IR which takes + // a lot longer to process by the machine code optimization passes. Disabling + // them has a negligible effect on code quality but compiles much faster. + if(__has_feature(memory_sanitizer)) + { + this->level = Level::None; + } } Level getLevel() const { return level; }
diff --git a/src/Reactor/Reactor.hpp b/src/Reactor/Reactor.hpp index 05d5925..3e22ee9 100644 --- a/src/Reactor/Reactor.hpp +++ b/src/Reactor/Reactor.hpp
@@ -52,12 +52,6 @@ } #endif -// A Clang extension to determine compiler features. -// We use it to detect Sanitizer builds (e.g. -fsanitize=memory). -#ifndef __has_feature -# define __has_feature(x) 0 -#endif - // Whether Reactor routine instrumentation is enabled for MSan builds. // TODO(b/155148722): Remove when unconditionally instrumenting for all build systems. #if !defined REACTOR_ENABLE_MEMORY_SANITIZER_INSTRUMENTATION