From 381126e1f8c440ebe7c6010f9621b382ecd821e3 Mon Sep 17 00:00:00 2001 From: Valentin Clement Date: Mon, 3 May 2021 15:42:19 -0400 Subject: [PATCH] [OpenMPIRBuilder] Add createOffloadMaptypes and createOffloadMapnames functions Add function to create the offload_maptypes and the offload_mapnames globals. These two functions are used in clang. They will be used in the Flang/MLIR lowering as well. Reviewed By: Meinersbur Differential Revision: https://reviews.llvm.org/D101503 --- include/llvm/Frontend/OpenMP/OMPIRBuilder.h | 9 +++ lib/Frontend/OpenMP/OMPIRBuilder.cpp | 27 +++++++++ unittests/Frontend/OpenMPIRBuilderTest.cpp | 64 +++++++++++++++++++++ 3 files changed, 100 insertions(+) diff --git a/include/llvm/Frontend/OpenMP/OMPIRBuilder.h b/include/llvm/Frontend/OpenMP/OMPIRBuilder.h index 4b8f4e7a597..a117dbf14fd 100644 --- a/include/llvm/Frontend/OpenMP/OMPIRBuilder.h +++ b/include/llvm/Frontend/OpenMP/OMPIRBuilder.h @@ -623,6 +623,15 @@ public: /// variables. StringMap, BumpPtrAllocator> InternalVars; + /// Create the global variable holding the offload mappings information. + GlobalVariable *createOffloadMaptypes(SmallVectorImpl &Mappings, + std::string VarName); + + /// Create the global variable holding the offload names information. + GlobalVariable * + createOffloadMapnames(SmallVectorImpl &Names, + std::string VarName); + public: /// Generator for __kmpc_copyprivate /// diff --git a/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/lib/Frontend/OpenMP/OMPIRBuilder.cpp index aff38fa47b2..ac97d080367 100644 --- a/lib/Frontend/OpenMP/OMPIRBuilder.cpp +++ b/lib/Frontend/OpenMP/OMPIRBuilder.cpp @@ -2229,6 +2229,33 @@ Value *OpenMPIRBuilder::getOMPCriticalRegionLock(StringRef CriticalName) { return getOrCreateOMPInternalVariable(KmpCriticalNameTy, Name); } +GlobalVariable * +OpenMPIRBuilder::createOffloadMaptypes(SmallVectorImpl &Mappings, + std::string VarName) { + llvm::Constant *MaptypesArrayInit = + llvm::ConstantDataArray::get(M.getContext(), Mappings); + auto *MaptypesArrayGlobal = new llvm::GlobalVariable( + M, MaptypesArrayInit->getType(), + /*isConstant=*/true, llvm::GlobalValue::PrivateLinkage, MaptypesArrayInit, + VarName); + MaptypesArrayGlobal->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); + return MaptypesArrayGlobal; +} + +GlobalVariable * +OpenMPIRBuilder::createOffloadMapnames(SmallVectorImpl &Names, + std::string VarName) { + llvm::Constant *MapNamesArrayInit = llvm::ConstantArray::get( + llvm::ArrayType::get( + llvm::Type::getInt8Ty(M.getContext())->getPointerTo(), Names.size()), + Names); + auto *MapNamesArrayGlobal = new llvm::GlobalVariable( + M, MapNamesArrayInit->getType(), + /*isConstant=*/true, llvm::GlobalValue::PrivateLinkage, MapNamesArrayInit, + VarName); + return MapNamesArrayGlobal; +} + // Create all simple and struct types exposed by the runtime and remember // the llvm::PointerTypes of them for easy access later. void OpenMPIRBuilder::initializeTypes(Module &M) { diff --git a/unittests/Frontend/OpenMPIRBuilderTest.cpp b/unittests/Frontend/OpenMPIRBuilderTest.cpp index 8da58d57a97..01fe6ada2fc 100644 --- a/unittests/Frontend/OpenMPIRBuilderTest.cpp +++ b/unittests/Frontend/OpenMPIRBuilderTest.cpp @@ -2287,4 +2287,68 @@ TEST_F(OpenMPIRBuilderTest, CreateSections) { ASSERT_EQ(NumFiniCBCalls, 1U); } +TEST_F(OpenMPIRBuilderTest, CreateOffloadMaptypes) { + OpenMPIRBuilder OMPBuilder(*M); + OMPBuilder.initialize(); + + IRBuilder<> Builder(BB); + + SmallVector Mappings = {0, 1}; + GlobalVariable *OffloadMaptypesGlobal = + OMPBuilder.createOffloadMaptypes(Mappings, "offload_maptypes"); + EXPECT_FALSE(M->global_empty()); + EXPECT_EQ(OffloadMaptypesGlobal->getName(), "offload_maptypes"); + EXPECT_TRUE(OffloadMaptypesGlobal->isConstant()); + EXPECT_TRUE(OffloadMaptypesGlobal->hasGlobalUnnamedAddr()); + EXPECT_TRUE(OffloadMaptypesGlobal->hasPrivateLinkage()); + EXPECT_TRUE(OffloadMaptypesGlobal->hasInitializer()); + Constant *Initializer = OffloadMaptypesGlobal->getInitializer(); + EXPECT_TRUE(isa(Initializer)); + ConstantDataArray *MappingInit = dyn_cast(Initializer); + EXPECT_EQ(MappingInit->getNumElements(), Mappings.size()); + EXPECT_TRUE(MappingInit->getType()->getElementType()->isIntegerTy(64)); + Constant *CA = ConstantDataArray::get(Builder.getContext(), Mappings); + EXPECT_EQ(MappingInit, CA); +} + +TEST_F(OpenMPIRBuilderTest, CreateOffloadMapnames) { + OpenMPIRBuilder OMPBuilder(*M); + OMPBuilder.initialize(); + + IRBuilder<> Builder(BB); + + Constant *Cst1 = OMPBuilder.getOrCreateSrcLocStr("array1", "file1", 2, 5); + Constant *Cst2 = OMPBuilder.getOrCreateSrcLocStr("array2", "file1", 3, 5); + SmallVector Names = {Cst1, Cst2}; + + GlobalVariable *OffloadMaptypesGlobal = + OMPBuilder.createOffloadMapnames(Names, "offload_mapnames"); + EXPECT_FALSE(M->global_empty()); + EXPECT_EQ(OffloadMaptypesGlobal->getName(), "offload_mapnames"); + EXPECT_TRUE(OffloadMaptypesGlobal->isConstant()); + EXPECT_FALSE(OffloadMaptypesGlobal->hasGlobalUnnamedAddr()); + EXPECT_TRUE(OffloadMaptypesGlobal->hasPrivateLinkage()); + EXPECT_TRUE(OffloadMaptypesGlobal->hasInitializer()); + Constant *Initializer = OffloadMaptypesGlobal->getInitializer(); + EXPECT_TRUE(isa(Initializer->getOperand(0)->stripPointerCasts())); + EXPECT_TRUE(isa(Initializer->getOperand(1)->stripPointerCasts())); + + GlobalVariable *Name1Gbl = + cast(Initializer->getOperand(0)->stripPointerCasts()); + EXPECT_TRUE(isa(Name1Gbl->getInitializer())); + ConstantDataArray *Name1GblCA = + dyn_cast(Name1Gbl->getInitializer()); + EXPECT_EQ(Name1GblCA->getAsCString(), ";file1;array1;2;5;;"); + + GlobalVariable *Name2Gbl = + cast(Initializer->getOperand(1)->stripPointerCasts()); + EXPECT_TRUE(isa(Name2Gbl->getInitializer())); + ConstantDataArray *Name2GblCA = + dyn_cast(Name2Gbl->getInitializer()); + EXPECT_EQ(Name2GblCA->getAsCString(), ";file1;array2;3;5;;"); + + EXPECT_TRUE(Initializer->getType()->getArrayElementType()->isPointerTy()); + EXPECT_EQ(Initializer->getType()->getArrayNumElements(), Names.size()); +} + } // namespace