diff options
Diffstat (limited to 'offload/plugins-nextgen/common/include/JIT.h')
| -rw-r--r-- | offload/plugins-nextgen/common/include/JIT.h | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/offload/plugins-nextgen/common/include/JIT.h b/offload/plugins-nextgen/common/include/JIT.h new file mode 100644 index 000000000000..b22197b89208 --- /dev/null +++ b/offload/plugins-nextgen/common/include/JIT.h @@ -0,0 +1,125 @@ +//===- JIT.h - Target independent JIT infrastructure ----------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +//===----------------------------------------------------------------------===// + +#ifndef OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_COMMON_JIT_H +#define OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_COMMON_JIT_H + +#include "Shared/EnvironmentVar.h" +#include "Shared/Utils.h" + +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Analysis/TargetLibraryInfo.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "llvm/Support/Error.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/TargetParser/Triple.h" + +#include <functional> +#include <memory> +#include <string> + +struct __tgt_device_image; + +namespace llvm { +class MemoryBuffer; + +namespace omp { +namespace target { +namespace plugin { +struct GenericDeviceTy; +} // namespace plugin + +/// The JIT infrastructure and caching mechanism. +struct JITEngine { + /// Function type for a callback that will be called after the backend is + /// called. + using PostProcessingFn = + std::function<Expected<std::unique_ptr<MemoryBuffer>>( + std::unique_ptr<MemoryBuffer>)>; + + JITEngine(Triple::ArchType TA); + + /// Run jit compilation if \p Image is a bitcode image, otherwise simply + /// return \p Image. It is expected to return a memory buffer containing the + /// generated device image that could be loaded to the device directly. + Expected<const __tgt_device_image *> + process(const __tgt_device_image &Image, + target::plugin::GenericDeviceTy &Device); + + /// Return true if \p Image is a bitcode image that can be JITed for the given + /// architecture. + Expected<bool> checkBitcodeImage(StringRef Buffer) const; + +private: + /// Compile the bitcode image \p Image and generate the binary image that can + /// be loaded to the target device of the triple \p Triple architecture \p + /// MCpu. \p PostProcessing will be called after codegen to handle cases such + /// as assember as an external tool. + Expected<const __tgt_device_image *> + compile(const __tgt_device_image &Image, const std::string &ComputeUnitKind, + PostProcessingFn PostProcessing); + + /// Create or retrieve the object image file from the file system or via + /// compilation of the \p Image. + Expected<std::unique_ptr<MemoryBuffer>> + getOrCreateObjFile(const __tgt_device_image &Image, LLVMContext &Ctx, + const std::string &ComputeUnitKind); + + /// Run backend, which contains optimization and code generation. + Expected<std::unique_ptr<MemoryBuffer>> + backend(Module &M, const std::string &ComputeUnitKind, unsigned OptLevel); + + /// Run optimization pipeline. + void opt(TargetMachine *TM, TargetLibraryInfoImpl *TLII, Module &M, + unsigned OptLevel); + + /// Run code generation. + void codegen(TargetMachine *TM, TargetLibraryInfoImpl *TLII, Module &M, + raw_pwrite_stream &OS); + + /// The target triple used by the JIT. + const Triple TT; + + struct ComputeUnitInfo { + /// LLVM Context in which the modules will be constructed. + LLVMContext Context; + + /// Output images generated from LLVM backend. + SmallVector<std::unique_ptr<MemoryBuffer>, 4> JITImages; + + /// A map of embedded IR images to JITed images. + DenseMap<const __tgt_device_image *, __tgt_device_image *> TgtImageMap; + }; + + /// Map from (march) "CPUs" (e.g., sm_80, or gfx90a), which we call compute + /// units as they are not CPUs, to the image information we cached for them. + StringMap<ComputeUnitInfo> ComputeUnitMap; + std::mutex ComputeUnitMapMutex; + + /// Control environment variables. + StringEnvar ReplacementObjectFileName = + StringEnvar("LIBOMPTARGET_JIT_REPLACEMENT_OBJECT"); + StringEnvar ReplacementModuleFileName = + StringEnvar("LIBOMPTARGET_JIT_REPLACEMENT_MODULE"); + StringEnvar PreOptIRModuleFileName = + StringEnvar("LIBOMPTARGET_JIT_PRE_OPT_IR_MODULE"); + StringEnvar PostOptIRModuleFileName = + StringEnvar("LIBOMPTARGET_JIT_POST_OPT_IR_MODULE"); + UInt32Envar JITOptLevel = UInt32Envar("LIBOMPTARGET_JIT_OPT_LEVEL", 3); + BoolEnvar JITSkipOpt = BoolEnvar("LIBOMPTARGET_JIT_SKIP_OPT", false); +}; + +} // namespace target +} // namespace omp +} // namespace llvm + +#endif // OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_COMMON_JIT_H |
