LLVMReactor: Mutex calls to llvm::orc::IRCompileLayer.

TSAN claims there are data races in the compileLayer. Specifically, it takes objection to compileLayer.addModule() being called at the same time as compileLayer.removeModule().

Bug: b/133127573
Change-Id: I19196d0c952bc308c2e47a848c93b092d5eea1ea
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/31832
Presubmit-Ready: Ben Clayton <bclayton@google.com>
Tested-by: Ben Clayton <bclayton@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
diff --git a/src/Reactor/LLVMReactor.cpp b/src/Reactor/LLVMReactor.cpp
index 7df7d8a..81f8e27 100644
--- a/src/Reactor/LLVMReactor.cpp
+++ b/src/Reactor/LLVMReactor.cpp
@@ -76,9 +76,10 @@
 #include <unordered_map>
 
 #include <fstream>
+#include <iostream>
+#include <mutex>
 #include <numeric>
 #include <thread>
-#include <iostream>
 
 #if defined(__i386__) || defined(__x86_64__)
 #include <xmmintrin.h>
@@ -599,7 +600,8 @@
 		std::unique_ptr<llvm::TargetMachine> targetMachine;
 		const llvm::DataLayout dataLayout;
 		ObjLayer objLayer;
-		CompileLayer compileLayer;
+		CompileLayer compileLayer; // guarded by mutex
+		std::mutex mutex;
 		size_t emittedFunctionsNum;
 
 	public:
@@ -690,22 +692,27 @@
 			mod->setDataLayout(dataLayout);
 
 			auto moduleKey = session.allocateVModule();
-			llvm::cantFail(compileLayer.addModule(moduleKey, std::move(mod)));
-			funcs = nullptr; // Now points to released memory.
+
+			// Resolve the function symbols - needs to be performed under mutex lock.
+			std::vector<llvm::JITSymbol> symbols;
+			{
+				std::unique_lock<std::mutex> lock(mutex);
+				llvm::cantFail(compileLayer.addModule(moduleKey, std::move(mod)));
+				funcs = nullptr; // Now points to released memory.
+				for (size_t i = 0; i < count; i++)
+				{
+					symbols.push_back(compileLayer.findSymbolIn(moduleKey, mangledNames[i], false));
+				}
+			}
 
 			// Resolve the function addresses.
 			std::vector<void*> addresses(count);
 			for (size_t i = 0; i < count; i++)
 			{
-				llvm::JITSymbol symbol = compileLayer.findSymbolIn(moduleKey, mangledNames[i], false);
-
-				llvm::Expected<llvm::JITTargetAddress> expectAddr = symbol.getAddress();
-				if(!expectAddr)
+				if(auto expectAddr = symbols[i].getAddress())
 				{
-					return nullptr;
+					addresses[i] = reinterpret_cast<void *>(static_cast<intptr_t>(expectAddr.get()));
 				}
-
-				addresses[i] = reinterpret_cast<void *>(static_cast<intptr_t>(expectAddr.get()));
 			}
 
 			return new LLVMRoutine(addresses.data(), count, releaseRoutineCallback, this, moduleKey);
@@ -750,6 +757,7 @@
 	private:
 		void releaseRoutineModule(llvm::orc::VModuleKey moduleKey)
 		{
+			std::unique_lock<std::mutex> lock(mutex);
 			llvm::cantFail(compileLayer.removeModule(moduleKey));
 		}