Update Reactor/LLVMJIT for RISC-V.
This CL fixes 3 RISC-V issues:
* JIT Linking on RISC-V is only supported with
ObjectLinkingLayer.
* jitTargetMachineBuilder.getFeatures() on RISC-V does
not return the RISC-V CPU extensions, so they are
manually added.
Note that these CPU extensions will be widely supported.
Android for instance will require at least RV64GC, where
the "G" stands for the +m +a +f +d extensions, and the C
stands for the +c extension.
* setCodeModel needs to be set to Medium on RISC-V.
Bug: b/273278430
Test: succesfully ran graphics tests in risc-v cuttlefish
with swiftshader running in the guest.
Change-Id: I9081be16450b9bd4d2b1e67e5777578fb1a688fc
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/71768
Commit-Queue: Jean-François Geyelin <jif@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Tested-by: Jean-François Geyelin <jif@google.com>
diff --git a/src/Reactor/LLVMJIT.cpp b/src/Reactor/LLVMJIT.cpp
index fad747a..11c7bab 100644
--- a/src/Reactor/LLVMJIT.cpp
+++ b/src/Reactor/LLVMJIT.cpp
@@ -26,9 +26,23 @@
__pragma(warning(disable : 4146)) // unary minus operator applied to unsigned type, result still unsigned
#endif
+// See https://groups.google.com/g/llvm-dev/c/CAE7Va57h2c/m/74ITeXFEAQAJ
+// for information about `RTDyldObjectLinkingLayer` vs `ObjectLinkingLayer`.
+// On RISC-V, only `ObjectLinkingLayer` is supported.
+#if defined(__riscv)
+#define USE_LEGACY_OBJECT_LINKING_LAYER 0
+#else
+#define USE_LEGACY_OBJECT_LINKING_LAYER 1
+#endif
+
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
+
+#if USE_LEGACY_OBJECT_LINKING_LAYER
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
+#else
+#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
+#endif
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/Verifier.h"
@@ -216,13 +230,28 @@
#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 */
+
+#if defined(__riscv) && __riscv_xlen == 64
+ // jitTargetMachineBuilder.getFeatures() on RISC-V does
+ // not return the RISC-V CPU extensions, so they are
+ // manually added.
+ jitTargetMachineBuilder.getFeatures().AddFeature("+m");
+ jitTargetMachineBuilder.getFeatures().AddFeature("+a");
+ jitTargetMachineBuilder.getFeatures().AddFeature("+f");
+ jitTargetMachineBuilder.getFeatures().AddFeature("+d");
+ jitTargetMachineBuilder.getFeatures().AddFeature("+c");
+ // The default code model is "Small".
+ // On RISC-V, using the default code model results in an
+ // "Unsupported riscv relocation" error.
+ jitTargetMachineBuilder.setCodeModel(llvm::CodeModel::Medium);
+#endif
+
jitTargetMachineBuilder.setCPU(std::string(llvm::sys::getHostCPUName()));
#else
jitTargetMachineBuilder.setCPU(llvm::sys::getHostCPUName());
@@ -746,9 +775,13 @@
#if LLVM_VERSION_MAJOR >= 13
, session(std::move(Unwrap(llvm::orc::SelfExecutorProcessControl::Create())))
#endif
+#if USE_LEGACY_OBJECT_LINKING_LAYER
, objectLayer(session, [this]() {
return std::make_unique<llvm::SectionMemoryManager>(&memoryMapper);
})
+#else
+ , objectLayer(session, llvm::cantFail(llvm::jitlink::InProcessMemoryManager::Create()))
+#endif
, addresses(count)
{
bool fatalCompileIssue = false;
@@ -861,7 +894,11 @@
std::string name;
llvm::orc::ExecutionSession session;
MemoryMapper memoryMapper;
+#if USE_LEGACY_OBJECT_LINKING_LAYER
llvm::orc::RTDyldObjectLinkingLayer objectLayer;
+#else
+ llvm::orc::ObjectLinkingLayer objectLayer;
+#endif
std::vector<const void *> addresses;
};