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