Skip to content

Commit 643c9b2

Browse files
committed
[OpenMP] Make generating offloading entries more generic
This patch moves the logic for generating the offloading entries to the OpenMPIRBuilder. This makes it easier to re-use in other places, such as for OpenMP support in Flang or using the same method for generating offloading entires for other languages like Cuda. Reviewed By: tianshilei1992 Differential Revision: https://reviews.llvm.org/D123460
1 parent 5b524da commit 643c9b2

File tree

5 files changed

+62
-112
lines changed

5 files changed

+62
-112
lines changed

clang/lib/CodeGen/CGOpenMPRuntime.cpp

Lines changed: 1 addition & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,51 +1329,6 @@ llvm::Function *CGOpenMPRuntime::emitTaskOutlinedFunction(
13291329
return Res;
13301330
}
13311331

1332-
static void buildStructValue(ConstantStructBuilder &Fields, CodeGenModule &CGM,
1333-
const RecordDecl *RD, const CGRecordLayout &RL,
1334-
ArrayRef<llvm::Constant *> Data) {
1335-
llvm::StructType *StructTy = RL.getLLVMType();
1336-
unsigned PrevIdx = 0;
1337-
ConstantInitBuilder CIBuilder(CGM);
1338-
const auto *DI = Data.begin();
1339-
for (const FieldDecl *FD : RD->fields()) {
1340-
unsigned Idx = RL.getLLVMFieldNo(FD);
1341-
// Fill the alignment.
1342-
for (unsigned I = PrevIdx; I < Idx; ++I)
1343-
Fields.add(llvm::Constant::getNullValue(StructTy->getElementType(I)));
1344-
PrevIdx = Idx + 1;
1345-
Fields.add(*DI);
1346-
++DI;
1347-
}
1348-
}
1349-
1350-
template <class... As>
1351-
static llvm::GlobalVariable *
1352-
createGlobalStruct(CodeGenModule &CGM, QualType Ty, bool IsConstant,
1353-
ArrayRef<llvm::Constant *> Data, const Twine &Name,
1354-
As &&... Args) {
1355-
const auto *RD = cast<RecordDecl>(Ty->getAsTagDecl());
1356-
const CGRecordLayout &RL = CGM.getTypes().getCGRecordLayout(RD);
1357-
ConstantInitBuilder CIBuilder(CGM);
1358-
ConstantStructBuilder Fields = CIBuilder.beginStruct(RL.getLLVMType());
1359-
buildStructValue(Fields, CGM, RD, RL, Data);
1360-
return Fields.finishAndCreateGlobal(
1361-
Name, CGM.getContext().getAlignOfGlobalVarInChars(Ty), IsConstant,
1362-
std::forward<As>(Args)...);
1363-
}
1364-
1365-
template <typename T>
1366-
static void
1367-
createConstantGlobalStructAndAddToParent(CodeGenModule &CGM, QualType Ty,
1368-
ArrayRef<llvm::Constant *> Data,
1369-
T &Parent) {
1370-
const auto *RD = cast<RecordDecl>(Ty->getAsTagDecl());
1371-
const CGRecordLayout &RL = CGM.getTypes().getCGRecordLayout(RD);
1372-
ConstantStructBuilder Fields = Parent.beginStruct(RL.getLLVMType());
1373-
buildStructValue(Fields, CGM, RD, RL, Data);
1374-
Fields.finishAndAddTo(Parent);
1375-
}
1376-
13771332
void CGOpenMPRuntime::setLocThreadIdInsertPt(CodeGenFunction &CGF,
13781333
bool AtCurrentPoint) {
13791334
auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn);
@@ -3136,32 +3091,7 @@ void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
31363091
void CGOpenMPRuntime::createOffloadEntry(
31373092
llvm::Constant *ID, llvm::Constant *Addr, uint64_t Size, int32_t Flags,
31383093
llvm::GlobalValue::LinkageTypes Linkage) {
3139-
StringRef Name = Addr->getName();
3140-
llvm::Module &M = CGM.getModule();
3141-
llvm::LLVMContext &C = M.getContext();
3142-
3143-
// Create constant string with the name.
3144-
llvm::Constant *StrPtrInit = llvm::ConstantDataArray::getString(C, Name);
3145-
3146-
std::string StringName = getName({"omp_offloading", "entry_name"});
3147-
auto *Str = new llvm::GlobalVariable(
3148-
M, StrPtrInit->getType(), /*isConstant=*/true,
3149-
llvm::GlobalValue::InternalLinkage, StrPtrInit, StringName);
3150-
Str->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
3151-
3152-
llvm::Constant *Data[] = {
3153-
llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(ID, CGM.VoidPtrTy),
3154-
llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(Str, CGM.Int8PtrTy),
3155-
llvm::ConstantInt::get(CGM.SizeTy, Size),
3156-
llvm::ConstantInt::get(CGM.Int32Ty, Flags),
3157-
llvm::ConstantInt::get(CGM.Int32Ty, 0)};
3158-
std::string EntryName = getName({"omp_offloading", "entry", ""});
3159-
llvm::GlobalVariable *Entry = createGlobalStruct(
3160-
CGM, getTgtOffloadEntryQTy(), /*IsConstant=*/true, Data,
3161-
Twine(EntryName).concat(Name), llvm::GlobalValue::WeakAnyLinkage);
3162-
3163-
// The entry has to be created in the section the linker expects it to be.
3164-
Entry->setSection("omp_offloading_entries");
3094+
OMPBuilder.emitOffloadingEntry(ID, Addr->getName(), Size, Flags);
31653095
}
31663096

31673097
void CGOpenMPRuntime::createOffloadEntriesAndInfoMetadata() {
@@ -3426,35 +3356,6 @@ void CGOpenMPRuntime::emitKmpRoutineEntryT(QualType KmpInt32Ty) {
34263356
}
34273357
}
34283358

3429-
QualType CGOpenMPRuntime::getTgtOffloadEntryQTy() {
3430-
// Make sure the type of the entry is already created. This is the type we
3431-
// have to create:
3432-
// struct __tgt_offload_entry{
3433-
// void *addr; // Pointer to the offload entry info.
3434-
// // (function or global)
3435-
// char *name; // Name of the function or global.
3436-
// size_t size; // Size of the entry info (0 if it a function).
3437-
// int32_t flags; // Flags associated with the entry, e.g. 'link'.
3438-
// int32_t reserved; // Reserved, to use by the runtime library.
3439-
// };
3440-
if (TgtOffloadEntryQTy.isNull()) {
3441-
ASTContext &C = CGM.getContext();
3442-
RecordDecl *RD = C.buildImplicitRecord("__tgt_offload_entry");
3443-
RD->startDefinition();
3444-
addFieldToRecordDecl(C, RD, C.VoidPtrTy);
3445-
addFieldToRecordDecl(C, RD, C.getPointerType(C.CharTy));
3446-
addFieldToRecordDecl(C, RD, C.getSizeType());
3447-
addFieldToRecordDecl(
3448-
C, RD, C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/true));
3449-
addFieldToRecordDecl(
3450-
C, RD, C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/true));
3451-
RD->completeDefinition();
3452-
RD->addAttr(PackedAttr::CreateImplicit(C));
3453-
TgtOffloadEntryQTy = C.getRecordType(RD);
3454-
}
3455-
return TgtOffloadEntryQTy;
3456-
}
3457-
34583359
namespace {
34593360
struct PrivateHelpersTy {
34603361
PrivateHelpersTy(const Expr *OriginalRef, const VarDecl *Original,

clang/lib/CodeGen/CGOpenMPRuntime.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -518,15 +518,6 @@ class CGOpenMPRuntime {
518518
/// kmp_int64 st; // stride
519519
/// };
520520
QualType KmpDimTy;
521-
/// Type struct __tgt_offload_entry{
522-
/// void *addr; // Pointer to the offload entry info.
523-
/// // (function or global)
524-
/// char *name; // Name of the function or global.
525-
/// size_t size; // Size of the entry info (0 if it a function).
526-
/// int32_t flags;
527-
/// int32_t reserved;
528-
/// };
529-
QualType TgtOffloadEntryQTy;
530521
/// Entity that registers the offloading constants that were emitted so
531522
/// far.
532523
class OffloadEntriesInfoManagerTy {
@@ -782,9 +773,6 @@ class CGOpenMPRuntime {
782773
/// metadata.
783774
void loadOffloadInfoMetadata();
784775

785-
/// Returns __tgt_offload_entry type.
786-
QualType getTgtOffloadEntryQTy();
787-
788776
/// Start scanning from statement \a S and and emit all target regions
789777
/// found along the way.
790778
/// \param S Starting statement.

llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,27 @@ class OpenMPIRBuilder {
779779
/// Value.
780780
GlobalValue *createGlobalFlag(unsigned Value, StringRef Name);
781781

782+
/// Create an offloading section struct used to register this global at
783+
/// runtime.
784+
///
785+
/// Type struct __tgt_offload_entry{
786+
/// void *addr; // Pointer to the offload entry info.
787+
/// // (function or global)
788+
/// char *name; // Name of the function or global.
789+
/// size_t size; // Size of the entry info (0 if it a function).
790+
/// int32_t flags;
791+
/// int32_t reserved;
792+
/// };
793+
///
794+
/// \param Addr The pointer to the global being registered.
795+
/// \param Name The symbol name associated with the global.
796+
/// \param Size The size in bytes of the global (0 for functions).
797+
/// \param Flags Flags associated with the entry.
798+
/// \param SectionName The section this entry will be placed at.
799+
void emitOffloadingEntry(Constant *Addr, StringRef Name, uint64_t Size,
800+
int32_t Flags,
801+
StringRef SectionName = "omp_offloading_entries");
802+
782803
/// Generate control flow and cleanup for cancellation.
783804
///
784805
/// \param CancelFlag Flag indicating if the cancellation is performed.

llvm/include/llvm/Frontend/OpenMP/OMPKinds.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ __OMP_ARRAY_TYPE(KmpCriticalName, Int32, 8)
8686
OMP_STRUCT_TYPE(VarName, "struct." #Name, __VA_ARGS__)
8787

8888
__OMP_STRUCT_TYPE(Ident, ident_t, Int32, Int32, Int32, Int32, Int8Ptr)
89+
__OMP_STRUCT_TYPE(OffloadEntry, __tgt_offload_entry, Int8Ptr, Int8Ptr, SizeTy,
90+
Int32, Int32)
8991
__OMP_STRUCT_TYPE(AsyncInfo, __tgt_async_info, Int8Ptr)
9092

9193
#undef __OMP_STRUCT_TYPE

llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,44 @@ OpenMPIRBuilder::createCancel(const LocationDescription &Loc,
753753
return Builder.saveIP();
754754
}
755755

756+
void OpenMPIRBuilder::emitOffloadingEntry(Constant *Addr, StringRef Name,
757+
uint64_t Size, int32_t Flags,
758+
StringRef SectionName) {
759+
Type *Int8PtrTy = Type::getInt8PtrTy(M.getContext());
760+
Type *Int32Ty = Type::getInt32Ty(M.getContext());
761+
Type *SizeTy = M.getDataLayout().getIntPtrType(M.getContext());
762+
763+
Constant *AddrName = ConstantDataArray::getString(M.getContext(), Name);
764+
765+
// Create the constant string used to look up the symbol in the device.
766+
auto *Str =
767+
new llvm::GlobalVariable(M, AddrName->getType(), /*isConstant=*/true,
768+
llvm::GlobalValue::InternalLinkage, AddrName,
769+
".omp_offloading.entry_name");
770+
Str->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
771+
772+
// Construct the offloading entry.
773+
Constant *EntryData[] = {
774+
ConstantExpr::getPointerBitCastOrAddrSpaceCast(Addr, Int8PtrTy),
775+
ConstantExpr::getPointerBitCastOrAddrSpaceCast(Str, Int8PtrTy),
776+
ConstantInt::get(SizeTy, Size),
777+
ConstantInt::get(Int32Ty, Flags),
778+
ConstantInt::get(Int32Ty, 0),
779+
};
780+
Constant *EntryInitializer =
781+
ConstantStruct::get(OpenMPIRBuilder::OffloadEntry, EntryData);
782+
783+
auto *Entry = new GlobalVariable(
784+
M, OpenMPIRBuilder::OffloadEntry,
785+
/* isConstant = */ true, GlobalValue::WeakAnyLinkage, EntryInitializer,
786+
".omp_offloading.entry." + Name, nullptr, GlobalValue::NotThreadLocal,
787+
M.getDataLayout().getDefaultGlobalsAddressSpace());
788+
789+
// The entry has to be created in the section the linker expects it to be.
790+
Entry->setSection(SectionName);
791+
Entry->setAlignment(Align(1));
792+
}
793+
756794
void OpenMPIRBuilder::emitCancelationCheckImpl(Value *CancelFlag,
757795
omp::Directive CanceledDirective,
758796
FinalizeCallbackTy ExitCB) {

0 commit comments

Comments
 (0)