LLVM 19.0.0git
Go to the documentation of this file.
1//===- Utility.cpp ------ Collection of generic offloading utilities ------===//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
10#include "llvm/IR/Constants.h"
11#include "llvm/IR/GlobalValue.h"
13#include "llvm/IR/Value.h"
16using namespace llvm;
17using namespace llvm::offloading;
20 LLVMContext &C = M.getContext();
21 StructType *EntryTy =
22 StructType::getTypeByName(C, "struct.__tgt_offload_entry");
23 if (!EntryTy)
24 EntryTy = StructType::create(
25 "struct.__tgt_offload_entry", PointerType::getUnqual(C),
26 PointerType::getUnqual(C), M.getDataLayout().getIntPtrType(C),
28 return EntryTy;
31// TODO: Rework this interface to be more generic.
32std::pair<Constant *, GlobalVariable *>
35 int32_t Flags, int32_t Data) {
36 llvm::Triple Triple(M.getTargetTriple());
37 Type *Int8PtrTy = PointerType::getUnqual(M.getContext());
38 Type *Int32Ty = Type::getInt32Ty(M.getContext());
39 Type *SizeTy = M.getDataLayout().getIntPtrType(M.getContext());
41 Constant *AddrName = ConstantDataArray::getString(M.getContext(), Name);
43 StringRef Prefix =
44 Triple.isNVPTX() ? "$offloading$entry_name" : ".offloading.entry_name";
46 // Create the constant string used to look up the symbol in the device.
47 auto *Str =
48 new GlobalVariable(M, AddrName->getType(), /*isConstant=*/true,
49 GlobalValue::InternalLinkage, AddrName, Prefix);
50 Str->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
52 // Construct the offloading entry.
53 Constant *EntryData[] = {
56 ConstantInt::get(SizeTy, Size),
57 ConstantInt::get(Int32Ty, Flags),
58 ConstantInt::get(Int32Ty, Data),
59 };
60 Constant *EntryInitializer = ConstantStruct::get(getEntryTy(M), EntryData);
61 return {EntryInitializer, Str};
65 uint64_t Size, int32_t Flags, int32_t Data,
67 llvm::Triple Triple(M.getTargetTriple());
69 auto [EntryInitializer, NameGV] =
72 StringRef Prefix =
73 Triple.isNVPTX() ? "$offloading$entry$" : ".offloading.entry.";
74 auto *Entry = new GlobalVariable(
75 M, getEntryTy(M),
76 /*isConstant=*/true, GlobalValue::WeakAnyLinkage, EntryInitializer,
77 Prefix + Name, nullptr, GlobalValue::NotThreadLocal,
78 M.getDataLayout().getDefaultGlobalsAddressSpace());
80 // The entry has to be created in the section the linker expects it to be.
82 Entry->setSection((SectionName + "$OE").str());
83 else
84 Entry->setSection(SectionName);
85 Entry->setAlignment(Align(1));
88std::pair<GlobalVariable *, GlobalVariable *>
90 llvm::Triple Triple(M.getTargetTriple());
92 auto *ZeroInitilaizer =
93 ConstantAggregateZero::get(ArrayType::get(getEntryTy(M), 0u));
94 auto *EntryInit = Triple.isOSBinFormatCOFF() ? ZeroInitilaizer : nullptr;
95 auto *EntryType = ArrayType::get(getEntryTy(M), 0);
99 auto *EntriesB =
100 new GlobalVariable(M, EntryType, /*isConstant=*/true, Linkage, EntryInit,
101 "__start_" + SectionName);
102 EntriesB->setVisibility(GlobalValue::HiddenVisibility);
103 auto *EntriesE =
104 new GlobalVariable(M, EntryType, /*isConstant=*/true, Linkage, EntryInit,
105 "__stop_" + SectionName);
106 EntriesE->setVisibility(GlobalValue::HiddenVisibility);
108 if (Triple.isOSBinFormatELF()) {
109 // We assume that external begin/end symbols that we have created above will
110 // be defined by the linker. This is done whenever a section name with a
111 // valid C-identifier is present. We define a dummy variable here to force
112 // the linker to always provide these symbols.
113 auto *DummyEntry = new GlobalVariable(
114 M, ZeroInitilaizer->getType(), true, GlobalVariable::InternalLinkage,
115 ZeroInitilaizer, "__dummy." + SectionName);
116 DummyEntry->setSection(SectionName);
117 appendToCompilerUsed(M, DummyEntry);
118 } else {
119 // The COFF linker will merge sections containing a '$' together into a
120 // single section. The order of entries in this section will be sorted
121 // alphabetically by the characters following the '$' in the name. Set the
122 // sections here to ensure that the beginning and end symbols are sorted.
123 EntriesB->setSection((SectionName + "$OA").str());
124 EntriesE->setSection((SectionName + "$OZ").str());
125 }
127 return std::make_pair(EntriesB, EntriesE);
This file contains the declarations for the subclasses of Constant, which represent the different fla...
uint64_t Addr
std::string Name
uint64_t Size
IntegerType * Int32Ty
static ConstantAggregateZero * get(Type *Ty)
Definition: Constants.cpp:1663
static Constant * getString(LLVMContext &Context, StringRef Initializer, bool AddNull=true)
This method constructs a CDS and initializes it with a text string.
Definition: Constants.cpp:2881
static Constant * getPointerBitCastOrAddrSpaceCast(Constant *C, Type *Ty)
Create a BitCast or AddrSpaceCast for a pointer type depending on the address space.
Definition: Constants.cpp:2087
static Constant * get(StructType *T, ArrayRef< Constant * > V)
Definition: Constants.cpp:1356
This is an important base class in LLVM.
Definition: Constant.h:41
@ HiddenVisibility
The GV is hidden.
Definition: GlobalValue.h:68
@ InternalLinkage
Rename collisions when linking (static functions).
Definition: GlobalValue.h:59
@ WeakODRLinkage
Same, but only replaced by something equivalent.
Definition: GlobalValue.h:57
@ ExternalLinkage
Externally visible function.
Definition: GlobalValue.h:52
@ WeakAnyLinkage
Keep one copy of named function when linking (weak)
Definition: GlobalValue.h:56
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Class to represent struct types.
Definition: DerivedTypes.h:216
static StructType * getTypeByName(LLVMContext &C, StringRef Name)
Return the type with the specified name, or null if there is none by that name.
Definition: Type.cpp:632
static StructType * create(LLVMContext &Context, StringRef Name)
This creates an identified struct.
Definition: Type.cpp:513
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
bool isOSBinFormatCOFF() const
Tests whether the OS uses the COFF binary format.
Definition: Triple.h:708
bool isNVPTX() const
Tests whether the target is NVPTX (32- or 64-bit).
Definition: Triple.h:824
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
Definition: Triple.h:703
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
static IntegerType * getInt32Ty(LLVMContext &C)
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
std::pair< Constant *, GlobalVariable * > getOffloadingEntryInitializer(Module &M, Constant *Addr, StringRef Name, uint64_t Size, int32_t Flags, int32_t Data)
Create a constant struct initializer used to register this global at runtime.
Definition: Utility.cpp:33
StructType * getEntryTy(Module &M)
Returns the type of the offloading entry we use to store kernels and globals that will be registered ...
Definition: Utility.cpp:19
void emitOffloadingEntry(Module &M, Constant *Addr, StringRef Name, uint64_t Size, int32_t Flags, int32_t Data, StringRef SectionName)
Create an offloading section struct used to register this global at runtime.
Definition: Utility.cpp:64
std::pair< GlobalVariable *, GlobalVariable * > getOffloadEntryArray(Module &M, StringRef SectionName)
Creates a pair of globals used to iterate the array of offloading entries by accessing the section va...
Definition: Utility.cpp:89
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39