diff --git a/include/llvm/Frontend/OpenMP/OMPIRBuilder.h b/include/llvm/Frontend/OpenMP/OMPIRBuilder.h index a92c3ba381c..8144f1527a0 100644 --- a/include/llvm/Frontend/OpenMP/OMPIRBuilder.h +++ b/include/llvm/Frontend/OpenMP/OMPIRBuilder.h @@ -636,6 +636,31 @@ public: createOffloadMapnames(SmallVectorImpl &Names, std::string VarName); + struct MapperAllocas { + AllocaInst *ArgsBase = nullptr; + AllocaInst *Args = nullptr; + AllocaInst *ArgSizes = nullptr; + }; + + /// Create the allocas instruction used in call to mapper functions. + void createMapperAllocas(const LocationDescription &Loc, + InsertPointTy AllocaIP, unsigned NumOperands, + struct MapperAllocas &MapperAllocas); + + /// Create the call for the target mapper function. + /// \param Loc The source location description. + /// \param MapperFunc Function to be called. + /// \param SrcLocInfo Source location information global. + /// \param MaptypesArgs + /// \param MapnamesArg + /// \param MapperAllocas The AllocaInst used for the call. + /// \param DeviceID Device ID for the call. + /// \param TotalNbOperand Number of operand in the call. + void emitMapperCall(const LocationDescription &Loc, Function *MapperFunc, + Value *SrcLocInfo, Value *MaptypesArg, Value *MapnamesArg, + struct MapperAllocas &MapperAllocas, int64_t DeviceID, + unsigned NumOperands); + public: /// Generator for __kmpc_copyprivate /// diff --git a/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/lib/Frontend/OpenMP/OMPIRBuilder.cpp index 60d71805c75..76954f9a37e 100644 --- a/lib/Frontend/OpenMP/OMPIRBuilder.cpp +++ b/lib/Frontend/OpenMP/OMPIRBuilder.cpp @@ -2318,6 +2318,51 @@ OpenMPIRBuilder::createOffloadMaptypes(SmallVectorImpl &Mappings, return MaptypesArrayGlobal; } +void OpenMPIRBuilder::createMapperAllocas(const LocationDescription &Loc, + InsertPointTy AllocaIP, + unsigned NumOperands, + struct MapperAllocas &MapperAllocas) { + if (!updateToLocation(Loc)) + return; + + auto *ArrI8PtrTy = ArrayType::get(Int8Ptr, NumOperands); + auto *ArrI64Ty = ArrayType::get(Int64, NumOperands); + Builder.restoreIP(AllocaIP); + AllocaInst *ArgsBase = Builder.CreateAlloca(ArrI8PtrTy); + AllocaInst *Args = Builder.CreateAlloca(ArrI8PtrTy); + AllocaInst *ArgSizes = Builder.CreateAlloca(ArrI64Ty); + Builder.restoreIP(Loc.IP); + MapperAllocas.ArgsBase = ArgsBase; + MapperAllocas.Args = Args; + MapperAllocas.ArgSizes = ArgSizes; +} + +void OpenMPIRBuilder::emitMapperCall(const LocationDescription &Loc, + Function *MapperFunc, Value *SrcLocInfo, + Value *MaptypesArg, Value *MapnamesArg, + struct MapperAllocas &MapperAllocas, + int64_t DeviceID, unsigned NumOperands) { + if (!updateToLocation(Loc)) + return; + + auto *ArrI8PtrTy = ArrayType::get(Int8Ptr, NumOperands); + auto *ArrI64Ty = ArrayType::get(Int64, NumOperands); + Value *ArgsBaseGEP = + Builder.CreateInBoundsGEP(ArrI8PtrTy, MapperAllocas.ArgsBase, + {Builder.getInt32(0), Builder.getInt32(0)}); + Value *ArgsGEP = + Builder.CreateInBoundsGEP(ArrI8PtrTy, MapperAllocas.Args, + {Builder.getInt32(0), Builder.getInt32(0)}); + Value *ArgSizesGEP = + Builder.CreateInBoundsGEP(ArrI64Ty, MapperAllocas.ArgSizes, + {Builder.getInt32(0), Builder.getInt32(0)}); + Value *NullPtr = Constant::getNullValue(Int8Ptr->getPointerTo()); + Builder.CreateCall(MapperFunc, + {SrcLocInfo, Builder.getInt64(DeviceID), + Builder.getInt32(NumOperands), ArgsBaseGEP, ArgsGEP, + ArgSizesGEP, MaptypesArg, MapnamesArg, NullPtr}); +} + bool OpenMPIRBuilder::checkAndEmitFlushAfterAtomic( const LocationDescription &Loc, llvm::AtomicOrdering AO, AtomicKind AK) { assert(!(AO == AtomicOrdering::NotAtomic || diff --git a/unittests/Frontend/OpenMPIRBuilderTest.cpp b/unittests/Frontend/OpenMPIRBuilderTest.cpp index 0df6fe531e3..50887611eaf 100644 --- a/unittests/Frontend/OpenMPIRBuilderTest.cpp +++ b/unittests/Frontend/OpenMPIRBuilderTest.cpp @@ -2703,4 +2703,110 @@ TEST_F(OpenMPIRBuilderTest, CreateOffloadMapnames) { EXPECT_EQ(Initializer->getType()->getArrayNumElements(), Names.size()); } +TEST_F(OpenMPIRBuilderTest, CreateMapperAllocas) { + OpenMPIRBuilder OMPBuilder(*M); + OMPBuilder.initialize(); + F->setName("func"); + IRBuilder<> Builder(BB); + + OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL}); + + unsigned TotalNbOperand = 2; + + OpenMPIRBuilder::MapperAllocas MapperAllocas; + IRBuilder<>::InsertPoint AllocaIP(&F->getEntryBlock(), + F->getEntryBlock().getFirstInsertionPt()); + OMPBuilder.createMapperAllocas(Loc, AllocaIP, TotalNbOperand, MapperAllocas); + EXPECT_NE(MapperAllocas.ArgsBase, nullptr); + EXPECT_NE(MapperAllocas.Args, nullptr); + EXPECT_NE(MapperAllocas.ArgSizes, nullptr); + EXPECT_TRUE(MapperAllocas.ArgsBase->getAllocatedType()->isArrayTy()); + ArrayType *ArrType = + dyn_cast(MapperAllocas.ArgsBase->getAllocatedType()); + EXPECT_EQ(ArrType->getNumElements(), TotalNbOperand); + EXPECT_TRUE(MapperAllocas.ArgsBase->getAllocatedType() + ->getArrayElementType() + ->isPointerTy()); + EXPECT_TRUE(MapperAllocas.ArgsBase->getAllocatedType() + ->getArrayElementType() + ->getPointerElementType() + ->isIntegerTy(8)); + + EXPECT_TRUE(MapperAllocas.Args->getAllocatedType()->isArrayTy()); + ArrType = dyn_cast(MapperAllocas.Args->getAllocatedType()); + EXPECT_EQ(ArrType->getNumElements(), TotalNbOperand); + EXPECT_TRUE(MapperAllocas.Args->getAllocatedType() + ->getArrayElementType() + ->isPointerTy()); + EXPECT_TRUE(MapperAllocas.Args->getAllocatedType() + ->getArrayElementType() + ->getPointerElementType() + ->isIntegerTy(8)); + + EXPECT_TRUE(MapperAllocas.ArgSizes->getAllocatedType()->isArrayTy()); + ArrType = dyn_cast(MapperAllocas.ArgSizes->getAllocatedType()); + EXPECT_EQ(ArrType->getNumElements(), TotalNbOperand); + EXPECT_TRUE(MapperAllocas.ArgSizes->getAllocatedType() + ->getArrayElementType() + ->isIntegerTy(64)); +} + +TEST_F(OpenMPIRBuilderTest, EmitMapperCall) { + OpenMPIRBuilder OMPBuilder(*M); + OMPBuilder.initialize(); + F->setName("func"); + IRBuilder<> Builder(BB); + LLVMContext &Ctx = M->getContext(); + + OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL}); + + unsigned TotalNbOperand = 2; + + OpenMPIRBuilder::MapperAllocas MapperAllocas; + IRBuilder<>::InsertPoint AllocaIP(&F->getEntryBlock(), + F->getEntryBlock().getFirstInsertionPt()); + OMPBuilder.createMapperAllocas(Loc, AllocaIP, TotalNbOperand, MapperAllocas); + + auto *BeginMapperFunc = OMPBuilder.getOrCreateRuntimeFunctionPtr( + omp::OMPRTL___tgt_target_data_begin_mapper); + + SmallVector Flags = {0, 2}; + + Constant *SrcLocCst = OMPBuilder.getOrCreateSrcLocStr("", "file1", 2, 5); + Value *SrcLocInfo = OMPBuilder.getOrCreateIdent(SrcLocCst); + + Constant *Cst1 = OMPBuilder.getOrCreateSrcLocStr("array1", "file1", 2, 5); + Constant *Cst2 = OMPBuilder.getOrCreateSrcLocStr("array2", "file1", 3, 5); + SmallVector Names = {Cst1, Cst2}; + + GlobalVariable *Maptypes = + OMPBuilder.createOffloadMaptypes(Flags, ".offload_maptypes"); + Value *MaptypesArg = Builder.CreateConstInBoundsGEP2_32( + ArrayType::get(Type::getInt64Ty(Ctx), TotalNbOperand), Maptypes, + /*Idx0=*/0, /*Idx1=*/0); + + GlobalVariable *Mapnames = + OMPBuilder.createOffloadMapnames(Names, ".offload_mapnames"); + Value *MapnamesArg = Builder.CreateConstInBoundsGEP2_32( + ArrayType::get(Type::getInt8PtrTy(Ctx), TotalNbOperand), Mapnames, + /*Idx0=*/0, /*Idx1=*/0); + + OMPBuilder.emitMapperCall(Builder.saveIP(), BeginMapperFunc, SrcLocInfo, + MaptypesArg, MapnamesArg, MapperAllocas, -1, + TotalNbOperand); + + CallInst *MapperCall = dyn_cast(&BB->back()); + EXPECT_NE(MapperCall, nullptr); + EXPECT_EQ(MapperCall->getNumArgOperands(), 9U); + EXPECT_EQ(MapperCall->getCalledFunction()->getName(), + "__tgt_target_data_begin_mapper"); + EXPECT_EQ(MapperCall->getOperand(0), SrcLocInfo); + EXPECT_TRUE(MapperCall->getOperand(1)->getType()->isIntegerTy(64)); + EXPECT_TRUE(MapperCall->getOperand(2)->getType()->isIntegerTy(32)); + + EXPECT_EQ(MapperCall->getOperand(6), MaptypesArg); + EXPECT_EQ(MapperCall->getOperand(7), MapnamesArg); + EXPECT_TRUE(MapperCall->getOperand(8)->getType()->isPointerTy()); +} + } // namespace