Add LLVM-Submodule backend option

Bug: b/217573066

Change-Id: I68c569ca3e2a7a88debb5a95d438a7dce9f6fc09
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/63308
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
Presubmit-Ready: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Commit-Queue: Martin Troiber <martin.troiber@gmail.com>
diff --git a/.gitmodules b/.gitmodules
index 3d9142e..cb86c5c 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -22,3 +22,6 @@
 [submodule "third_party/git-hooks"]
 	path = third_party/git-hooks
 	url = https://swiftshader.googlesource.com/git-hooks
+[submodule "third_party/llvm-project"]
+	path = third_party/llvm-project
+	url = https://github.com/llvm/llvm-project.git
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1082853..8192d87 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -177,7 +177,7 @@
 
 set(DEFAULT_REACTOR_BACKEND "LLVM")
 set(REACTOR_BACKEND ${DEFAULT_REACTOR_BACKEND} CACHE STRING "JIT compiler back-end used by Reactor")
-set_property(CACHE REACTOR_BACKEND PROPERTY STRINGS LLVM Subzero)
+set_property(CACHE REACTOR_BACKEND PROPERTY STRINGS LLVM LLVM-Submodule Subzero)
 
 set(DEFAULT_SWIFTSHADER_LLVM_VERSION "10.0")
 set(SWIFTSHADER_LLVM_VERSION ${DEFAULT_SWIFTSHADER_LLVM_VERSION} CACHE STRING "LLVM version to use")
@@ -263,6 +263,10 @@
     InitSubmodule(cppdap ${THIRD_PARTY_DIR}/cppdap)
 endif()
 
+if(${REACTOR_BACKEND} STREQUAL "LLVM-Submodule")
+    InitSubmodule(llvm-submodule ${THIRD_PARTY_DIR}/llvm-project)
+endif()
+
 ###########################################################
 # Convenience macros
 ###########################################################
@@ -646,6 +650,27 @@
 set_target_properties(llvm PROPERTIES FOLDER "third_party")
 
 ###########################################################
+# LLVM-Submodule
+###########################################################
+if(${REACTOR_BACKEND} STREQUAL "LLVM-Submodule")
+    set(LLVM_INCLUDE_TESTS FALSE)
+    set(LLVM_ENABLE_RTTI TRUE)
+    add_subdirectory(${THIRD_PARTY_DIR}/llvm-project/llvm EXCLUDE_FROM_ALL)
+    if(ARCH STREQUAL "aarch64")
+        llvm_map_components_to_libnames(llvm_libs orcjit aarch64asmparser aarch64codegen)
+    elseif(ARCH STREQUAL "arm")
+        llvm_map_components_to_libnames(llvm_libs orcjit armasmparser armcodegen)
+    elseif(ARCH MATCHES "mips*")
+        llvm_map_components_to_libnames(llvm_libs orcjit mipsasmparser mipscodegen)
+    elseif(ARCH STREQUAL "ppc64le")
+        llvm_map_components_to_libnames(llvm_libs orcjit powerpcasmparser powerpccodegen)
+    elseif(ARCH MATCHES "x86*")
+        llvm_map_components_to_libnames(llvm_libs orcjit x86asmparser x86codegen)
+    endif()
+    set_target_properties(${llvm_libs} PROPERTIES FOLDER "third_party")
+endif()
+
+###########################################################
 # Subzero
 ###########################################################
 add_subdirectory(${THIRD_PARTY_DIR}/llvm-subzero EXCLUDE_FROM_ALL)
@@ -739,10 +764,12 @@
 
 if(${REACTOR_BACKEND} STREQUAL "LLVM")
     add_library(Reactor ALIAS ReactorLLVM)
+elseif(${REACTOR_BACKEND} STREQUAL "LLVM-Submodule")
+    add_library(Reactor ALIAS ReactorLLVMSubmodule)
 elseif(${REACTOR_BACKEND} STREQUAL "Subzero")
     add_library(Reactor ALIAS ReactorSubzero)
 else()
-    message(FATAL_ERROR "REACTOR_BACKEND must be 'LLVM' or 'Subzero'")
+    message(FATAL_ERROR "REACTOR_BACKEND must be 'LLVM', 'LLVM-Submodule' or 'Subzero'")
 endif()
 
 if (NOT TARGET SPIRV-Tools)
diff --git a/src/Reactor/CMakeLists.txt b/src/Reactor/CMakeLists.txt
index 8eb2034..a184624 100644
--- a/src/Reactor/CMakeLists.txt
+++ b/src/Reactor/CMakeLists.txt
@@ -145,3 +145,40 @@
         llvm
         ${REACTOR_PRIVATE_LINK_LIBRARIES}
 )
+
+# ReactorLLVMSubmodule library
+
+add_library(ReactorLLVMSubmodule STATIC EXCLUDE_FROM_ALL
+    ${REACTOR_SRC_FILES}
+    ${LLVM_SRC_FILES}
+)
+
+set_target_properties(ReactorLLVMSubmodule PROPERTIES
+    POSITION_INDEPENDENT_CODE 1
+    FOLDER "Reactor"
+)
+
+target_include_directories(ReactorLLVMSubmodule
+    PUBLIC
+        .
+        "${THIRD_PARTY_DIR}/llvm-project/llvm/include"
+        "${CMAKE_BINARY_DIR}/third_party/llvm-project/llvm/include"
+)
+
+target_compile_definitions(ReactorLLVMSubmodule
+    PUBLIC
+        ${REACTOR_PUBLIC_COMPILE_DEFINITIONS}
+    PRIVATE
+        ${REACTOR_PRIVATE_COMPILE_DEFINITIONS}
+)
+
+target_compile_options(ReactorLLVMSubmodule
+    PRIVATE
+        ${ROOT_PROJECT_COMPILE_OPTIONS}
+)
+
+target_link_libraries(ReactorLLVMSubmodule
+    PRIVATE
+        ${llvm_libs}
+        ${REACTOR_PRIVATE_LINK_LIBRARIES}
+)
diff --git a/src/Reactor/LLVMJIT.cpp b/src/Reactor/LLVMJIT.cpp
index 6e87fdb..b326e19 100644
--- a/src/Reactor/LLVMJIT.cpp
+++ b/src/Reactor/LLVMJIT.cpp
@@ -155,8 +155,10 @@
 #else
 		// TODO(b/191193823): TODO(ndesaulniers): Update this after
 		// go/compilers/fc018ebb608ee0c1239b405460e49f1835ab6175
-#	if LLVM_VERSION_MAJOR < 9999
-#		error Implement stack size checks using the "warn-stack-size" function attribute.
+#	if LLVM_VERSION_MAJOR <= 15
+		// Resolve TODO
+#	elif LLVM_VERSION_MAJOR < 9999
+#		warning Implement stack size checks using the "warn-stack-size" function attribute.
 #	endif
 #endif
 		};
diff --git a/third_party/llvm-project b/third_party/llvm-project
new file mode 160000
index 0000000..fc3b34c
--- /dev/null
+++ b/third_party/llvm-project
@@ -0,0 +1 @@
+Subproject commit fc3b34c50803274b8ba3b8a30df9177b7d29063c