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