Fix LLVM host triple for ORCv2 JIT

llvm::orc::JITTargetMachineBuilder::detectHost() currently states:
// FIXME: getProcessTriple is bogus. It returns the host LLVM was compiled on,
//        rather than a valid triple for the current process.

This change uses LLVM_DEFAULT_TARGET_TRIPLE instead, which we define
based on the platform and predefined macros (see llvm-config.h).

This doesn't fix any known bugs, but it's good to not leave the triple
unknown, to avoid future issues. This change also refactors passing
the JITTargetMachineBuilder by rvalue reference and uses some less
cryptic variable names.

Bug: b/171236524
Change-Id: I7be752be66082654307210817250eb1dd025cb0c
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/49851
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json
index fe4b758..a03b732 100644
--- a/.vscode/c_cpp_properties.json
+++ b/.vscode/c_cpp_properties.json
@@ -13,9 +13,9 @@
                 "${workspaceFolder}/src",
                 "${workspaceFolder}/third_party/benchmark/include",
                 "${workspaceFolder}/third_party/cppdap/include",
-                "${workspaceFolder}/third_party/llvm-7.0/configs/common/include",
-                "${workspaceFolder}/third_party/llvm-7.0/configs/windows/include",
-                "${workspaceFolder}/third_party/llvm-7.0/llvm/include",
+                "${workspaceFolder}/third_party/llvm-10.0/configs/common/include",
+                "${workspaceFolder}/third_party/llvm-10.0/configs/windows/include",
+                "${workspaceFolder}/third_party/llvm-10.0/llvm/include",
                 "${workspaceFolder}/third_party/marl/include",
                 "${workspaceFolder}/third_party/SPIRV-Headers/include",
                 "${workspaceFolder}/third_party/SPIRV-Tools/include"
@@ -36,9 +36,9 @@
                 "${workspaceFolder}/src",
                 "${workspaceFolder}/third_party/benchmark/include",
                 "${workspaceFolder}/third_party/cppdap/include",
-                "${workspaceFolder}/third_party/llvm-7.0/configs/common/include",
-                "${workspaceFolder}/third_party/llvm-7.0/configs/windows/include",
-                "${workspaceFolder}/third_party/llvm-7.0/llvm/include",
+                "${workspaceFolder}/third_party/llvm-10.0/configs/common/include",
+                "${workspaceFolder}/third_party/llvm-10.0/configs/windows/include",
+                "${workspaceFolder}/third_party/llvm-10.0/llvm/include",
                 "${workspaceFolder}/third_party/marl/include",
                 "${workspaceFolder}/third_party/SPIRV-Headers/include",
                 "${workspaceFolder}/third_party/SPIRV-Tools/include"
@@ -58,9 +58,9 @@
                 "${workspaceFolder}/src",
                 "${workspaceFolder}/third_party/benchmark/include",
                 "${workspaceFolder}/third_party/cppdap/include",
-                "${workspaceFolder}/third_party/llvm-7.0/configs/common/include",
-                "${workspaceFolder}/third_party/llvm-7.0/configs/windows/include",
-                "${workspaceFolder}/third_party/llvm-7.0/llvm/include",
+                "${workspaceFolder}/third_party/llvm-10.0/configs/common/include",
+                "${workspaceFolder}/third_party/llvm-10.0/configs/windows/include",
+                "${workspaceFolder}/third_party/llvm-10.0/llvm/include",
                 "${workspaceFolder}/third_party/marl/include",
                 "${workspaceFolder}/third_party/SPIRV-Headers/include",
                 "${workspaceFolder}/third_party/SPIRV-Tools/include"
diff --git a/src/Reactor/BUILD.gn b/src/Reactor/BUILD.gn
index eedc36c..a2724bb 100644
--- a/src/Reactor/BUILD.gn
+++ b/src/Reactor/BUILD.gn
@@ -351,7 +351,7 @@
     } else if (is_mac) {
       include_dirs += [ "$llvm_dir/configs/darwin/include/" ]
     } else {
-      assert(false, "llvm-7.0 not configured for target platform")
+      assert(false, "llvm not configured for target platform")
     }
   }
 }
diff --git a/src/Reactor/LLVMJIT.cpp b/src/Reactor/LLVMJIT.cpp
index 36c85e8..567f11d 100644
--- a/src/Reactor/LLVMJIT.cpp
+++ b/src/Reactor/LLVMJIT.cpp
@@ -29,6 +29,7 @@
 #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
 #include "llvm/IR/LegacyPassManager.h"
+#include "llvm/Support/Host.h"
 #include "llvm/Support/TargetSelect.h"
 #include "llvm/Transforms/InstCombine/InstCombine.h"
 #include "llvm/Transforms/Scalar.h"
@@ -65,13 +66,14 @@
 
 	llvm::orc::JITTargetMachineBuilder getTargetMachineBuilder(rr::Optimization::Level optLevel) const;
 	const llvm::DataLayout &getDataLayout() const;
-	const llvm::Triple getTargetTriple() const;
+	const llvm::Triple &getTargetTriple() const;
 
 private:
-	JITGlobals(const llvm::orc::JITTargetMachineBuilder &jtmb, const llvm::DataLayout &dataLayout);
+	JITGlobals(llvm::orc::JITTargetMachineBuilder &&jitTargetMachineBuilder, llvm::DataLayout &&dataLayout);
 
 	static llvm::CodeGenOpt::Level toLLVM(rr::Optimization::Level level);
-	const llvm::orc::JITTargetMachineBuilder jtmb;
+
+	const llvm::orc::JITTargetMachineBuilder jitTargetMachineBuilder;
 	const llvm::DataLayout dataLayout;
 };
 
@@ -82,19 +84,47 @@
 		llvm::InitializeNativeTargetAsmPrinter();
 		llvm::InitializeNativeTargetAsmParser();
 
-		auto jtmb = llvm::orc::JITTargetMachineBuilder::detectHost();
-		ASSERT_MSG(jtmb, "JITTargetMachineBuilder::detectHost() failed");
-		auto dataLayout = jtmb->getDefaultDataLayoutForTarget();
+		// TODO(b/171236524): JITTargetMachineBuilder::detectHost() currently uses the target triple of the host,
+		// rather than a valid triple for the current process. Once fixed, we can use that function instead.
+		llvm::orc::JITTargetMachineBuilder jitTargetMachineBuilder(llvm::Triple(LLVM_DEFAULT_TARGET_TRIPLE));
+
+		// Retrieve host CPU name and sub-target features and add them to builder.
+		// Relocation model, code model and codegen opt level are kept to default values.
+		llvm::StringMap<bool> cpuFeatures;
+		bool ok = llvm::sys::getHostCPUFeatures(cpuFeatures);
+
+#if defined(__i386__) || defined(__x86_64__) || \
+    (defined(__linux__) && (defined(__arm__) || defined(__aarch64__)))
+		ASSERT_MSG(ok, "llvm::sys::getHostCPUFeatures returned false");
+#else
+		(void)ok;  // getHostCPUFeatures always returns false on other platforms
+#endif
+
+		for(auto &feature : cpuFeatures)
+		{
+			jitTargetMachineBuilder.getFeatures().AddFeature(feature.first(), feature.second);
+		}
+
+#if LLVM_VERSION_MAJOR >= 11 /* TODO(b/165000222): Unconditional after LLVM 11 upgrade */
+		jitTargetMachineBuilder.setCPU(std::string(llvm::sys::getHostCPUName()));
+#else
+		jitTargetMachineBuilder.setCPU(llvm::sys::getHostCPUName());
+#endif
+
+		auto dataLayout = jitTargetMachineBuilder.getDefaultDataLayoutForTarget();
 		ASSERT_MSG(dataLayout, "JITTargetMachineBuilder::getDefaultDataLayoutForTarget() failed");
-		return JITGlobals(jtmb.get(), dataLayout.get());
+
+		return JITGlobals(std::move(jitTargetMachineBuilder), std::move(dataLayout.get()));
 	}();
+
 	return &instance;
 }
 
 llvm::orc::JITTargetMachineBuilder JITGlobals::getTargetMachineBuilder(rr::Optimization::Level optLevel) const
 {
-	llvm::orc::JITTargetMachineBuilder out = jtmb;
+	llvm::orc::JITTargetMachineBuilder out = jitTargetMachineBuilder;
 	out.setCodeGenOptLevel(toLLVM(optLevel));
+
 	return out;
 }
 
@@ -103,13 +133,13 @@
 	return dataLayout;
 }
 
-const llvm::Triple JITGlobals::getTargetTriple() const
+const llvm::Triple &JITGlobals::getTargetTriple() const
 {
-	return jtmb.getTargetTriple();
+	return jitTargetMachineBuilder.getTargetTriple();
 }
 
-JITGlobals::JITGlobals(const llvm::orc::JITTargetMachineBuilder &jtmb, const llvm::DataLayout &dataLayout)
-    : jtmb(jtmb)
+JITGlobals::JITGlobals(llvm::orc::JITTargetMachineBuilder &&jitTargetMachineBuilder, llvm::DataLayout &&dataLayout)
+    : jitTargetMachineBuilder(jitTargetMachineBuilder)
     , dataLayout(dataLayout)
 {
 }
@@ -529,8 +559,8 @@
 	    size_t count,
 	    const rr::Config &config)
 	    : objectLayer(session, []() {
-		    static MemoryMapper mm;
-		    return std::make_unique<llvm::SectionMemoryManager>(&mm);
+		    static MemoryMapper memoryMapper;
+		    return std::make_unique<llvm::SectionMemoryManager>(&memoryMapper);
 	    })
 	    , compileLayer(session, objectLayer, std::make_unique<llvm::orc::ConcurrentIRCompiler>(JITGlobals::get()->getTargetMachineBuilder(config.getOptimization().getLevel())))
 	    , mangle(session, JITGlobals::get()->getDataLayout())