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; };