Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:55

0001 //===- Utility.h - Collection of geneirc offloading utilities -------------===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_FRONTEND_OFFLOADING_UTILITY_H
0010 #define LLVM_FRONTEND_OFFLOADING_UTILITY_H
0011 
0012 #include <cstdint>
0013 
0014 #include "llvm/ADT/StringMap.h"
0015 #include "llvm/ADT/StringRef.h"
0016 #include "llvm/IR/Module.h"
0017 #include "llvm/Object/OffloadBinary.h"
0018 #include "llvm/Support/Error.h"
0019 #include "llvm/Support/MemoryBufferRef.h"
0020 
0021 namespace llvm {
0022 namespace offloading {
0023 
0024 /// This is the record of an object that just be registered with the offloading
0025 /// runtime.
0026 struct EntryTy {
0027   /// Reserved bytes used to detect an older version of the struct, always zero.
0028   uint64_t Reserved = 0x0;
0029   /// The current version of the struct for runtime forward compatibility.
0030   uint16_t Version = 0x1;
0031   /// The expected consumer of this entry, e.g. CUDA or OpenMP.
0032   uint16_t Kind;
0033   /// Flags associated with the global.
0034   uint32_t Flags;
0035   /// The address of the global to be registered by the runtime.
0036   void *Address;
0037   /// The name of the symbol in the device image.
0038   char *SymbolName;
0039   /// The number of bytes the symbol takes.
0040   uint64_t Size;
0041   /// Extra generic data used to register this entry.
0042   uint64_t Data;
0043   /// An extra pointer, usually null.
0044   void *AuxAddr;
0045 };
0046 
0047 /// Offloading entry flags for CUDA / HIP. The first three bits indicate the
0048 /// type of entry while the others are a bit field for additional information.
0049 enum OffloadEntryKindFlag : uint32_t {
0050   /// Mark the entry as a global entry. This indicates the presense of a
0051   /// kernel if the size size field is zero and a variable otherwise.
0052   OffloadGlobalEntry = 0x0,
0053   /// Mark the entry as a managed global variable.
0054   OffloadGlobalManagedEntry = 0x1,
0055   /// Mark the entry as a surface variable.
0056   OffloadGlobalSurfaceEntry = 0x2,
0057   /// Mark the entry as a texture variable.
0058   OffloadGlobalTextureEntry = 0x3,
0059   /// Mark the entry as being extern.
0060   OffloadGlobalExtern = 0x1 << 3,
0061   /// Mark the entry as being constant.
0062   OffloadGlobalConstant = 0x1 << 4,
0063   /// Mark the entry as being a normalized surface.
0064   OffloadGlobalNormalized = 0x1 << 5,
0065 };
0066 
0067 /// Returns the type of the offloading entry we use to store kernels and
0068 /// globals that will be registered with the offloading runtime.
0069 StructType *getEntryTy(Module &M);
0070 
0071 /// Create an offloading section struct used to register this global at
0072 /// runtime.
0073 ///
0074 /// \param M The module to be used
0075 /// \param Addr The pointer to the global being registered.
0076 /// \param Kind The offloading language expected to consume this.
0077 /// \param Name The symbol name associated with the global.
0078 /// \param Size The size in bytes of the global (0 for functions).
0079 /// \param Flags Flags associated with the entry.
0080 /// \param Data Extra data storage associated with the entry.
0081 /// \param SectionName The section this entry will be placed at.
0082 /// \param AuxAddr An extra pointer if needed.
0083 void emitOffloadingEntry(Module &M, object::OffloadKind Kind, Constant *Addr,
0084                          StringRef Name, uint64_t Size, uint32_t Flags,
0085                          uint64_t Data, StringRef SectionName,
0086                          Constant *AuxAddr = nullptr);
0087 
0088 /// Create a constant struct initializer used to register this global at
0089 /// runtime.
0090 /// \return the constant struct and the global variable holding the symbol name.
0091 std::pair<Constant *, GlobalVariable *>
0092 getOffloadingEntryInitializer(Module &M, object::OffloadKind Kind,
0093                               Constant *Addr, StringRef Name, uint64_t Size,
0094                               uint32_t Flags, uint64_t Data, Constant *AuxAddr);
0095 
0096 /// Creates a pair of globals used to iterate the array of offloading entries by
0097 /// accessing the section variables provided by the linker.
0098 std::pair<GlobalVariable *, GlobalVariable *>
0099 getOffloadEntryArray(Module &M, StringRef SectionName);
0100 
0101 namespace amdgpu {
0102 /// Check if an image is compatible with current system's environment. The
0103 /// system environment is given as a 'target-id' which has the form:
0104 ///
0105 /// <target-id> := <processor> ( ":" <target-feature> ( "+" | "-" ) )*
0106 ///
0107 /// If a feature is not specific as '+' or '-' it is assumed to be in an 'any'
0108 /// and is compatible with either '+' or '-'. The HSA runtime returns this
0109 /// information using the target-id, while we use the ELF header to determine
0110 /// these features.
0111 bool isImageCompatibleWithEnv(StringRef ImageArch, uint32_t ImageFlags,
0112                               StringRef EnvTargetID);
0113 
0114 /// Struct for holding metadata related to AMDGPU kernels, for more information
0115 /// about the metadata and its meaning see:
0116 /// https://llvm.org/docs/AMDGPUUsage.html#code-object-v3
0117 struct AMDGPUKernelMetaData {
0118   /// Constant indicating that a value is invalid.
0119   static constexpr uint32_t KInvalidValue =
0120       std::numeric_limits<uint32_t>::max();
0121   /// The amount of group segment memory required by a work-group in bytes.
0122   uint32_t GroupSegmentList = KInvalidValue;
0123   /// The amount of fixed private address space memory required for a work-item
0124   /// in bytes.
0125   uint32_t PrivateSegmentSize = KInvalidValue;
0126   /// Number of scalar registers required by a wavefront.
0127   uint32_t SGPRCount = KInvalidValue;
0128   /// Number of vector registers required by each work-item.
0129   uint32_t VGPRCount = KInvalidValue;
0130   /// Number of stores from a scalar register to a register allocator created
0131   /// spill location.
0132   uint32_t SGPRSpillCount = KInvalidValue;
0133   /// Number of stores from a vector register to a register allocator created
0134   /// spill location.
0135   uint32_t VGPRSpillCount = KInvalidValue;
0136   /// Number of accumulator registers required by each work-item.
0137   uint32_t AGPRCount = KInvalidValue;
0138   /// Corresponds to the OpenCL reqd_work_group_size attribute.
0139   uint32_t RequestedWorkgroupSize[3] = {KInvalidValue, KInvalidValue,
0140                                         KInvalidValue};
0141   /// Corresponds to the OpenCL work_group_size_hint attribute.
0142   uint32_t WorkgroupSizeHint[3] = {KInvalidValue, KInvalidValue, KInvalidValue};
0143   /// Wavefront size.
0144   uint32_t WavefrontSize = KInvalidValue;
0145   /// Maximum flat work-group size supported by the kernel in work-items.
0146   uint32_t MaxFlatWorkgroupSize = KInvalidValue;
0147 };
0148 
0149 /// Reads AMDGPU specific metadata from the ELF file and propagates the
0150 /// KernelInfoMap.
0151 Error getAMDGPUMetaDataFromImage(MemoryBufferRef MemBuffer,
0152                                  StringMap<AMDGPUKernelMetaData> &KernelInfoMap,
0153                                  uint16_t &ELFABIVersion);
0154 } // namespace amdgpu
0155 } // namespace offloading
0156 } // namespace llvm
0157 
0158 #endif // LLVM_FRONTEND_OFFLOADING_UTILITY_H