diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -9378,15 +9378,10 @@ // fill arrays. Instead, we create an array constant. SmallVector Mapping(CombinedInfo.Types.size(), 0); llvm::copy(CombinedInfo.Types, Mapping.begin()); - llvm::Constant *MapTypesArrayInit = - llvm::ConstantDataArray::get(CGF.Builder.getContext(), Mapping); std::string MaptypesName = CGM.getOpenMPRuntime().getName({"offload_maptypes"}); - auto *MapTypesArrayGbl = new llvm::GlobalVariable( - CGM.getModule(), MapTypesArrayInit->getType(), - /*isConstant=*/true, llvm::GlobalValue::PrivateLinkage, - MapTypesArrayInit, MaptypesName); - MapTypesArrayGbl->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); + auto *MapTypesArrayGbl = + OMPBuilder.createOffloadMaptypes(Mapping, MaptypesName); Info.MapTypesArray = MapTypesArrayGbl; // The information types are only built if there is debug information @@ -9400,17 +9395,10 @@ }; SmallVector InfoMap(CombinedInfo.Exprs.size()); llvm::transform(CombinedInfo.Exprs, InfoMap.begin(), fillInfoMap); - - llvm::Constant *MapNamesArrayInit = llvm::ConstantArray::get( - llvm::ArrayType::get( - llvm::Type::getInt8Ty(CGF.Builder.getContext())->getPointerTo(), - CombinedInfo.Exprs.size()), - InfoMap); - auto *MapNamesArrayGbl = new llvm::GlobalVariable( - CGM.getModule(), MapNamesArrayInit->getType(), - /*isConstant=*/true, llvm::GlobalValue::PrivateLinkage, - MapNamesArrayInit, - CGM.getOpenMPRuntime().getName({"offload_mapnames"})); + std::string MapnamesName = + CGM.getOpenMPRuntime().getName({"offload_mapnames"}); + auto *MapNamesArrayGbl = + OMPBuilder.createOffloadMapnames(InfoMap, MapnamesName); Info.MapNamesArray = MapNamesArrayGbl; } @@ -9425,15 +9413,8 @@ } } if (EndMapTypesDiffer) { - MapTypesArrayInit = - llvm::ConstantDataArray::get(CGF.Builder.getContext(), Mapping); - MaptypesName = CGM.getOpenMPRuntime().getName({"offload_maptypes"}); - MapTypesArrayGbl = new llvm::GlobalVariable( - CGM.getModule(), MapTypesArrayInit->getType(), - /*isConstant=*/true, llvm::GlobalValue::PrivateLinkage, - MapTypesArrayInit, MaptypesName); - MapTypesArrayGbl->setUnnamedAddr( - llvm::GlobalValue::UnnamedAddr::Global); + MapTypesArrayGbl = + OMPBuilder.createOffloadMaptypes(Mapping, MaptypesName); Info.MapTypesArrayEnd = MapTypesArrayGbl; } } diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h b/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h --- a/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h +++ b/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h @@ -623,6 +623,15 @@ /// 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/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp --- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp +++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp @@ -2229,6 +2229,33 @@ 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/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp b/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp --- a/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp +++ b/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp @@ -2287,4 +2287,68 @@ 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