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 @@ -9222,7 +9222,7 @@ std::string MaptypesName = CGM.getOpenMPRuntime().getName({"offload_maptypes"}); auto *MapTypesArrayGbl = - OMPBuilder.createOffloadMaptypes(Mapping, MaptypesName); + OMPBuilder.createOffloadMapGlobals(Mapping, MaptypesName); Info.RTArgs.MapTypesArray = MapTypesArrayGbl; // The information types are only built if there is debug information @@ -9260,7 +9260,7 @@ } if (EndMapTypesDiffer) { MapTypesArrayGbl = - OMPBuilder.createOffloadMaptypes(Mapping, MaptypesName); + OMPBuilder.createOffloadMapGlobals(Mapping, MaptypesName); Info.RTArgs.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 @@ -1346,12 +1346,9 @@ /// variables. StringMap InternalVars; - /// Computes the size of type in bytes. - Value *getSizeInBytes(Value *BasePtr); - /// Create the global variable holding the offload mappings information. - GlobalVariable *createOffloadMaptypes(SmallVectorImpl &Mappings, - std::string VarName); + GlobalVariable *createOffloadMapGlobals(SmallVectorImpl &Mappings, + std::string VarName); /// Create the global variable holding the offload names information. GlobalVariable * @@ -1367,7 +1364,8 @@ /// Create the allocas instruction used in call to mapper functions. void createMapperAllocas(const LocationDescription &Loc, InsertPointTy AllocaIP, unsigned NumOperands, - struct MapperAllocas &MapperAllocas); + struct MapperAllocas &MapperAllocas, + bool CreateSizes = true); /// Create the call for the target mapper function. /// \param Loc The source location description. @@ -1378,10 +1376,13 @@ /// \param MapperAllocas The AllocaInst used for the call. /// \param DeviceID Device ID for the call. /// \param NumOperands Number of operands in the call. + /// \param MapsizesArg Optional parameter, if provided then + /// use this as the map size argument instead of creating + /// a new GEP instruction. void emitMapperCall(const LocationDescription &Loc, Function *MapperFunc, Value *SrcLocInfo, Value *MaptypesArg, Value *MapnamesArg, struct MapperAllocas &MapperAllocas, int64_t DeviceID, - unsigned NumOperands); + unsigned NumOperands, Value *MapsizesArg = nullptr); /// Container for the arguments used to pass data to the runtime library. struct TargetDataRTArgs { @@ -1801,28 +1802,34 @@ StringRef EntryFnIDName, int32_t NumTeams, int32_t NumThreads); + /// This structure contains combined information generated for mappable + /// clauses, including base pointers, pointers, names, sizes and map types. + struct MapInfo { + Constant *Name = nullptr; + uint64_t Type = 0x00; + uint64_t Size = 0; + Value *BasePtr = nullptr; + Value *Ptr = nullptr; + }; + /// Generator for '#omp target data' /// /// \param Loc The location where the target data construct was encountered. + /// \param AllocaIP The insertion points to be used for alloca instructions. /// \param CodeGenIP The insertion point at which the target directive code /// should be placed. - /// \param MapTypeFlags BitVector storing the mapType flags for the - /// mapOperands. - /// \param MapNames Names for the mapOperands. - /// \param MapperAllocas Pointers to the AllocInsts for the map clause. /// \param IsBegin If true then emits begin mapper call otherwise emits /// end mapper call. /// \param DeviceID Stores the DeviceID from the device clause. /// \param IfCond Value which corresponds to the if clause condition. - /// \param ProcessMapOpCB Callback that generates code for the map clause. - /// \param BodyGenCB Callback that will generate the region code. - OpenMPIRBuilder::InsertPointTy createTargetData( - const LocationDescription &Loc, OpenMPIRBuilder::InsertPointTy CodeGenIP, - SmallVectorImpl &MapTypeFlags, - SmallVectorImpl &MapNames, - struct MapperAllocas &MapperAllocas, bool IsBegin, int64_t DeviceID, - Value *IfCond, BodyGenCallbackTy ProcessMapOpCB, - BodyGenCallbackTy BodyGenCB = {}); + /// \param MapInfos Map from a 'map' Value* to its corresponding MapInfo. + /// \param BodyGenCB Callback that will generate the region body code. + InsertPointTy createTargetData(const LocationDescription &Loc, + InsertPointTy AllocaIP, + InsertPointTy CodeGenIP, bool IsBegin, + int64_t DeviceID, Value *IfCond, + SmallMapVector &MapInfos, + BodyGenCallbackTy BodyGenCB = {}); /// Declarations for LLVM-IR types (simple, array, function and structure) are /// generated below. Their names are defined and used in OpenMPKinds.def. Here @@ -1935,6 +1942,25 @@ using AtomicUpdateCallbackTy = const function_ref &IRB)>; + /// Generator for map clauses + /// + /// \param Loc The location where the target data construct was encountered. + /// \param AllocaIP The insertion points to be used for alloca instructions. + /// \param CodeGenIP The insertion point at which the target directive code + /// should be placed. + /// \param MapInfos Map from a 'map' Value* to its corresponding MapInfo. + /// \param BodyGenCB Callback that will generate the region body code. + /// \param MapperAllocas Return param for the Alloca pointers from + /// BasePtr, Ptr and Size ptr. + /// \param MapNamesGV Return param for the MapNames Global. + /// \param MapTypesGV Return param for the MapTypes Global. + /// \param MapSizesGV Return param for the MapSizes Global. + void ProcessMapInfo(const LocationDescription &Loc, InsertPointTy AllocaIP, + InsertPointTy CodeGenIP, + SmallMapVector &MapInfos, + struct MapperAllocas &MapperAllocas, Value **MapNamesGV, + Value **MapTypesGV, Value **MapSizesGV); + private: enum AtomicKind { Read, Write, Update, Capture, Compare }; 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 @@ -4040,12 +4040,73 @@ return OutlinedFnID; } +void OpenMPIRBuilder::ProcessMapInfo( + const LocationDescription &Loc, InsertPointTy AllocaIP, + InsertPointTy CodeGenIP, SmallMapVector &MapInfos, + struct MapperAllocas &MapperAllocas, Value **MapNamesArg, + Value **MapTypesArg, Value **MapSizesArg) { + auto NumMapOperands = MapInfos.size(); + + createMapperAllocas(Loc, AllocaIP, NumMapOperands, MapperAllocas, false); + + Builder.restoreIP(CodeGenIP); + + ArrayType *ArrPtrTy = ArrayType::get(Builder.getPtrTy(), NumMapOperands); + + unsigned Index = 0; + for (auto &MapOp : MapInfos) { + auto &MapInfo = MapOp.second; + Value *MapOpPtrBase, *MapOpPtr; + MapOpPtrBase = MapOpPtr = MapOp.first; + + Value *BaseGEPPtr = Builder.CreateInBoundsGEP( + ArrPtrTy, MapperAllocas.ArgsBase, + {Builder.getInt32(0), Builder.getInt32(Index)}); + Builder.CreateStore(MapOpPtrBase, BaseGEPPtr); + MapInfo.BasePtr = BaseGEPPtr; + + Value *GEPPtr = Builder.CreateInBoundsGEP( + ArrPtrTy, MapperAllocas.Args, + {Builder.getInt32(0), Builder.getInt32(Index)}); + Builder.CreateStore(MapOpPtr, GEPPtr); + + MapInfo.BasePtr = BaseGEPPtr; + MapInfo.Ptr = GEPPtr; + Index++; + } + + SmallVector MapNames; + SmallVector MapTypes; + SmallVector MapSizes; + + for (const auto &MapInfoIter : MapInfos) { + const auto &MapInfo = MapInfoIter.second; + MapNames.emplace_back(MapInfo.Name); + MapTypes.emplace_back(MapInfo.Type); + MapSizes.emplace_back(MapInfo.Size); + } + + Value *MapNamesGV = createOffloadMapnames(MapNames, ".offload_mapnames"); + *MapNamesArg = Builder.CreateConstInBoundsGEP2_32( + ArrayType::get(Builder.getInt8PtrTy(), NumMapOperands), MapNamesGV, + /*Idx0=*/0, /*Idx1=*/0); + + Value *MapTypesGV = createOffloadMapGlobals(MapTypes, ".offload_maptypes"); + *MapTypesArg = Builder.CreateConstInBoundsGEP2_32( + ArrayType::get(Builder.getInt64Ty(), NumMapOperands), MapTypesGV, + /*Idx0=*/0, /*Idx1=*/0); + + Value *MapSizesGV = createOffloadMapGlobals(MapSizes, ".offload_sizes"); + *MapSizesArg = Builder.CreateConstInBoundsGEP2_32( + ArrayType::get(Builder.getInt64Ty(), NumMapOperands), MapSizesGV, + /*Idx0=*/0, /*Idx1=*/0); +} + OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::createTargetData( - const LocationDescription &Loc, OpenMPIRBuilder::InsertPointTy CodeGenIP, - SmallVectorImpl &MapTypeFlags, - SmallVectorImpl &MapNames, struct MapperAllocas &MapperAllocas, - bool IsBegin, int64_t DeviceID, Value *IfCond, - BodyGenCallbackTy ProcessMapOpCB, BodyGenCallbackTy BodyGenCB) { + const LocationDescription &Loc, InsertPointTy AllocaIP, + InsertPointTy CodeGenIP, bool IsBegin, int64_t DeviceID, Value *IfCond, + SmallMapVector &MapInfos, + BodyGenCallbackTy BodyGenCB) { if (!updateToLocation(Loc)) return InsertPointTy(); @@ -4063,24 +4124,15 @@ Builder.SetInsertPoint(UI); } - ProcessMapOpCB(Builder.saveIP(), Builder.saveIP()); + struct MapperAllocas MapperAllocas; + Value *MapNamesArg = nullptr, *MapTypesArg = nullptr, *MapSizesArg = nullptr; + ProcessMapInfo(Loc, AllocaIP, Builder.saveIP(), MapInfos, MapperAllocas, + &MapNamesArg, &MapTypesArg, &MapSizesArg); uint32_t SrcLocStrSize; Constant *SrcLocStr = getOrCreateSrcLocStr(Loc, SrcLocStrSize); Value *srcLocInfo = getOrCreateIdent(SrcLocStr, SrcLocStrSize); - GlobalVariable *MapTypesGV = - createOffloadMaptypes(MapTypeFlags, ".offload_maptypes"); - Value *MapTypesArg = Builder.CreateConstInBoundsGEP2_32( - ArrayType::get(Builder.getInt64Ty(), MapTypeFlags.size()), MapTypesGV, - /*Idx0=*/0, /*Idx1=*/0); - - GlobalVariable *MapNamesGV = - createOffloadMapnames(MapNames, ".offload_mapnames"); - Value *MapNamesArg = Builder.CreateConstInBoundsGEP2_32( - ArrayType::get(Builder.getInt8PtrTy(), MapNames.size()), MapNamesGV, - /*Idx0=*/0, /*Idx1=*/0); - Function *beginMapperFunc = getOrCreateRuntimeFunctionPtr(omp::OMPRTL___tgt_target_data_begin_mapper); Function *endMapperFunc = @@ -4089,18 +4141,20 @@ if (BodyGenCB) { // Create call to start the data region. emitMapperCall(Builder.saveIP(), beginMapperFunc, srcLocInfo, MapTypesArg, - MapNamesArg, MapperAllocas, DeviceID, MapTypeFlags.size()); + MapNamesArg, MapperAllocas, DeviceID, MapInfos.size(), + MapSizesArg); BodyGenCB(Builder.saveIP(), Builder.saveIP()); Builder.SetInsertPoint(UI->getParent()); // Create call to end the data region. emitMapperCall(Builder.saveIP(), endMapperFunc, srcLocInfo, MapTypesArg, - MapNamesArg, MapperAllocas, DeviceID, MapTypeFlags.size()); + MapNamesArg, MapperAllocas, DeviceID, MapInfos.size(), + MapSizesArg); } else { emitMapperCall(Builder.saveIP(), IsBegin ? beginMapperFunc : endMapperFunc, srcLocInfo, MapTypesArg, MapNamesArg, MapperAllocas, - DeviceID, MapTypeFlags.size()); + DeviceID, MapInfos.size(), MapSizesArg); } // Update the insertion point and remove the terminator we introduced. @@ -4158,18 +4212,9 @@ return getOrCreateInternalVariable(KmpCriticalNameTy, Name); } -Value *OpenMPIRBuilder::getSizeInBytes(Value *BasePtr) { - LLVMContext &Ctx = Builder.getContext(); - Value *Null = Constant::getNullValue(BasePtr->getType()->getPointerTo()); - Value *SizeGep = - Builder.CreateGEP(BasePtr->getType(), Null, Builder.getInt32(1)); - Value *SizePtrToInt = Builder.CreatePtrToInt(SizeGep, Type::getInt64Ty(Ctx)); - return SizePtrToInt; -} - GlobalVariable * -OpenMPIRBuilder::createOffloadMaptypes(SmallVectorImpl &Mappings, - std::string VarName) { +OpenMPIRBuilder::createOffloadMapGlobals(SmallVectorImpl &Mappings, + std::string VarName) { llvm::Constant *MaptypesArrayInit = llvm::ConstantDataArray::get(M.getContext(), Mappings); auto *MaptypesArrayGlobal = new llvm::GlobalVariable( @@ -4183,7 +4228,8 @@ void OpenMPIRBuilder::createMapperAllocas(const LocationDescription &Loc, InsertPointTy AllocaIP, unsigned NumOperands, - struct MapperAllocas &MapperAllocas) { + struct MapperAllocas &MapperAllocas, + bool CreateSizes) { if (!updateToLocation(Loc)) return; @@ -4194,19 +4240,23 @@ ArrI8PtrTy, /* ArraySize = */ nullptr, ".offload_baseptrs"); AllocaInst *Args = Builder.CreateAlloca(ArrI8PtrTy, /* ArraySize = */ nullptr, ".offload_ptrs"); - AllocaInst *ArgSizes = Builder.CreateAlloca( - ArrI64Ty, /* ArraySize = */ nullptr, ".offload_sizes"); - Builder.restoreIP(Loc.IP); MapperAllocas.ArgsBase = ArgsBase; MapperAllocas.Args = Args; - MapperAllocas.ArgSizes = ArgSizes; + + if (CreateSizes) { + AllocaInst *ArgSizes = Builder.CreateAlloca( + ArrI64Ty, /* ArraySize = */ nullptr, ".offload_sizes"); + MapperAllocas.ArgSizes = ArgSizes; + } + Builder.restoreIP(Loc.IP); } void OpenMPIRBuilder::emitMapperCall(const LocationDescription &Loc, Function *MapperFunc, Value *SrcLocInfo, Value *MaptypesArg, Value *MapnamesArg, struct MapperAllocas &MapperAllocas, - int64_t DeviceID, unsigned NumOperands) { + int64_t DeviceID, unsigned NumOperands, + Value *MapsizesArg) { if (!updateToLocation(Loc)) return; @@ -4218,9 +4268,14 @@ 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 *ArgSizesGEP; + if (MapsizesArg) { + ArgSizesGEP = MapsizesArg; + } else { + 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), 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 @@ -4712,7 +4712,7 @@ SmallVector Mappings = {0, 1}; GlobalVariable *OffloadMaptypesGlobal = - OMPBuilder.createOffloadMaptypes(Mappings, "offload_maptypes"); + OMPBuilder.createOffloadMapGlobals(Mappings, "offload_maptypes"); EXPECT_FALSE(M->global_empty()); EXPECT_EQ(OffloadMaptypesGlobal->getName(), "offload_maptypes"); EXPECT_TRUE(OffloadMaptypesGlobal->isConstant()); @@ -4851,7 +4851,7 @@ SmallVector Names = {Cst1, Cst2}; GlobalVariable *Maptypes = - OMPBuilder.createOffloadMaptypes(Flags, ".offload_maptypes"); + OMPBuilder.createOffloadMapGlobals(Flags, ".offload_maptypes"); Value *MaptypesArg = Builder.CreateConstInBoundsGEP2_32( ArrayType::get(Type::getInt64Ty(Ctx), TotalNbOperand), Maptypes, /*Idx0=*/0, /*Idx1=*/0); @@ -4885,18 +4885,8 @@ OMPBuilder.initialize(); F->setName("func"); IRBuilder<> Builder(BB); - OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL}); - - unsigned NumDataOperands = 1; int64_t DeviceID = 2; - struct OpenMPIRBuilder::MapperAllocas MapperAllocas; - SmallVector MapTypeFlagsTo = {1}; - SmallVector MapNames; - auto *I8PtrTy = Builder.getInt8PtrTy(); - auto *ArrI8PtrTy = ArrayType::get(I8PtrTy, NumDataOperands); - auto *I64Ty = Builder.getInt64Ty(); - auto *ArrI64Ty = ArrayType::get(I64Ty, NumDataOperands); AllocaInst *Val1 = Builder.CreateAlloca(Builder.getInt32Ty(), Builder.getInt64(1)); @@ -4904,44 +4894,18 @@ IRBuilder<>::InsertPoint AllocaIP(&F->getEntryBlock(), F->getEntryBlock().getFirstInsertionPt()); - OMPBuilder.createMapperAllocas(Builder.saveIP(), AllocaIP, NumDataOperands, - MapperAllocas); - using InsertPointTy = OpenMPIRBuilder::InsertPointTy; - auto ProcessMapOpCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP) { - Value *DataValue = Val1; - Value *DataPtrBase; - Value *DataPtr; - DataPtrBase = DataValue; - DataPtr = DataValue; - Builder.restoreIP(CodeGenIP); + llvm::SmallMapVector + MapInfos; - Value *Null = Constant::getNullValue(DataValue->getType()->getPointerTo()); - Value *SizeGep = - Builder.CreateGEP(DataValue->getType(), Null, Builder.getInt32(1)); - Value *SizePtrToInt = Builder.CreatePtrToInt(SizeGep, I64Ty); - - Value *PtrBaseGEP = - Builder.CreateInBoundsGEP(ArrI8PtrTy, MapperAllocas.ArgsBase, - {Builder.getInt32(0), Builder.getInt32(0)}); - Value *PtrBaseCast = Builder.CreateBitCast( - PtrBaseGEP, DataPtrBase->getType()->getPointerTo()); - Builder.CreateStore(DataPtrBase, PtrBaseCast); - Value *PtrGEP = - Builder.CreateInBoundsGEP(ArrI8PtrTy, MapperAllocas.Args, - {Builder.getInt32(0), Builder.getInt32(0)}); - Value *PtrCast = - Builder.CreateBitCast(PtrGEP, DataPtr->getType()->getPointerTo()); - Builder.CreateStore(DataPtr, PtrCast); - Value *SizeGEP = - Builder.CreateInBoundsGEP(ArrI64Ty, MapperAllocas.ArgSizes, - {Builder.getInt32(0), Builder.getInt32(0)}); - Builder.CreateStore(SizePtrToInt, SizeGEP); - }; + uint32_t temp; + MapInfos[Val1].Name = OMPBuilder.getOrCreateSrcLocStr("unknown", temp); + MapInfos[Val1].Size = 4; + MapInfos[Val1].Type = 1; Builder.restoreIP(OMPBuilder.createTargetData( - Loc, Builder.saveIP(), MapTypeFlagsTo, MapNames, MapperAllocas, - /* IsBegin= */ true, DeviceID, /* IfCond= */ nullptr, ProcessMapOpCB)); + Loc, AllocaIP, Builder.saveIP(), /* IsBegin= */ true, DeviceID, + /* IfCond= */ nullptr, MapInfos)); CallInst *TargetDataCall = dyn_cast(&BB->back()); EXPECT_NE(TargetDataCall, nullptr); @@ -4961,18 +4925,8 @@ OMPBuilder.initialize(); F->setName("func"); IRBuilder<> Builder(BB); - OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL}); - - unsigned NumDataOperands = 1; int64_t DeviceID = 2; - struct OpenMPIRBuilder::MapperAllocas MapperAllocas; - SmallVector MapTypeFlagsFrom = {2}; - SmallVector MapNames; - auto *I8PtrTy = Builder.getInt8PtrTy(); - auto *ArrI8PtrTy = ArrayType::get(I8PtrTy, NumDataOperands); - auto *I64Ty = Builder.getInt64Ty(); - auto *ArrI64Ty = ArrayType::get(I64Ty, NumDataOperands); AllocaInst *Val1 = Builder.CreateAlloca(Builder.getInt32Ty(), Builder.getInt64(1)); @@ -4980,44 +4934,18 @@ IRBuilder<>::InsertPoint AllocaIP(&F->getEntryBlock(), F->getEntryBlock().getFirstInsertionPt()); - OMPBuilder.createMapperAllocas(Builder.saveIP(), AllocaIP, NumDataOperands, - MapperAllocas); - using InsertPointTy = OpenMPIRBuilder::InsertPointTy; - auto ProcessMapOpCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP) { - Value *DataValue = Val1; - Value *DataPtrBase; - Value *DataPtr; - DataPtrBase = DataValue; - DataPtr = DataValue; - Builder.restoreIP(CodeGenIP); + llvm::SmallMapVector + MapInfos; - Value *Null = Constant::getNullValue(DataValue->getType()->getPointerTo()); - Value *SizeGep = - Builder.CreateGEP(DataValue->getType(), Null, Builder.getInt32(1)); - Value *SizePtrToInt = Builder.CreatePtrToInt(SizeGep, I64Ty); - - Value *PtrBaseGEP = - Builder.CreateInBoundsGEP(ArrI8PtrTy, MapperAllocas.ArgsBase, - {Builder.getInt32(0), Builder.getInt32(0)}); - Value *PtrBaseCast = Builder.CreateBitCast( - PtrBaseGEP, DataPtrBase->getType()->getPointerTo()); - Builder.CreateStore(DataPtrBase, PtrBaseCast); - Value *PtrGEP = - Builder.CreateInBoundsGEP(ArrI8PtrTy, MapperAllocas.Args, - {Builder.getInt32(0), Builder.getInt32(0)}); - Value *PtrCast = - Builder.CreateBitCast(PtrGEP, DataPtr->getType()->getPointerTo()); - Builder.CreateStore(DataPtr, PtrCast); - Value *SizeGEP = - Builder.CreateInBoundsGEP(ArrI64Ty, MapperAllocas.ArgSizes, - {Builder.getInt32(0), Builder.getInt32(0)}); - Builder.CreateStore(SizePtrToInt, SizeGEP); - }; + uint32_t temp; + MapInfos[Val1].Name = OMPBuilder.getOrCreateSrcLocStr("unknown", temp); + MapInfos[Val1].Size = 4; + MapInfos[Val1].Type = 2; Builder.restoreIP(OMPBuilder.createTargetData( - Loc, Builder.saveIP(), MapTypeFlagsFrom, MapNames, MapperAllocas, - /* IsBegin= */ false, DeviceID, /* IfCond= */ nullptr, ProcessMapOpCB)); + Loc, AllocaIP, Builder.saveIP(), /* IsBegin= */ false, DeviceID, + /* IfCond= */ nullptr, MapInfos)); CallInst *TargetDataCall = dyn_cast(&BB->back()); EXPECT_NE(TargetDataCall, nullptr); @@ -5037,18 +4965,8 @@ OMPBuilder.initialize(); F->setName("func"); IRBuilder<> Builder(BB); - OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL}); - - unsigned NumDataOperands = 1; int64_t DeviceID = 2; - struct OpenMPIRBuilder::MapperAllocas MapperAllocas; - SmallVector MapTypeFlagsToFrom = {3}; - SmallVector MapNames; - auto *I8PtrTy = Builder.getInt8PtrTy(); - auto *ArrI8PtrTy = ArrayType::get(I8PtrTy, NumDataOperands); - auto *I64Ty = Builder.getInt64Ty(); - auto *ArrI64Ty = ArrayType::get(I64Ty, NumDataOperands); AllocaInst *Val1 = Builder.CreateAlloca(Builder.getInt32Ty(), Builder.getInt64(1)); @@ -5056,57 +4974,34 @@ IRBuilder<>::InsertPoint AllocaIP(&F->getEntryBlock(), F->getEntryBlock().getFirstInsertionPt()); - OMPBuilder.createMapperAllocas(Builder.saveIP(), AllocaIP, NumDataOperands, - MapperAllocas); - using InsertPointTy = OpenMPIRBuilder::InsertPointTy; - auto ProcessMapOpCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP) { - Value *DataValue = Val1; - Value *DataPtrBase; - Value *DataPtr; - DataPtrBase = DataValue; - DataPtr = DataValue; - Builder.restoreIP(CodeGenIP); + llvm::SmallMapVector + MapInfos; - Value *Null = Constant::getNullValue(DataValue->getType()->getPointerTo()); - Value *SizeGep = - Builder.CreateGEP(DataValue->getType(), Null, Builder.getInt32(1)); - Value *SizePtrToInt = Builder.CreatePtrToInt(SizeGep, I64Ty); - - Value *PtrBaseGEP = - Builder.CreateInBoundsGEP(ArrI8PtrTy, MapperAllocas.ArgsBase, - {Builder.getInt32(0), Builder.getInt32(0)}); - Value *PtrBaseCast = Builder.CreateBitCast( - PtrBaseGEP, DataPtrBase->getType()->getPointerTo()); - Builder.CreateStore(DataPtrBase, PtrBaseCast); - Value *PtrGEP = - Builder.CreateInBoundsGEP(ArrI8PtrTy, MapperAllocas.Args, - {Builder.getInt32(0), Builder.getInt32(0)}); - Value *PtrCast = - Builder.CreateBitCast(PtrGEP, DataPtr->getType()->getPointerTo()); - Builder.CreateStore(DataPtr, PtrCast); - Value *SizeGEP = - Builder.CreateInBoundsGEP(ArrI64Ty, MapperAllocas.ArgSizes, - {Builder.getInt32(0), Builder.getInt32(0)}); - Builder.CreateStore(SizePtrToInt, SizeGEP); - }; + uint32_t temp; + MapInfos[Val1].Name = OMPBuilder.getOrCreateSrcLocStr("unknown", temp); + MapInfos[Val1].Size = 4; + MapInfos[Val1].Type = 3; + using InsertPointTy = OpenMPIRBuilder::InsertPointTy; auto BodyCB = [&](InsertPointTy allocaIP, InsertPointTy codeGenIP) { + CallInst *TargetDataCall = dyn_cast(BB->back().getPrevNode()); + EXPECT_NE(TargetDataCall, nullptr); + EXPECT_EQ(TargetDataCall->arg_size(), 9U); + EXPECT_EQ(TargetDataCall->getCalledFunction()->getName(), + "__tgt_target_data_begin_mapper"); + EXPECT_TRUE(TargetDataCall->getOperand(1)->getType()->isIntegerTy(64)); + EXPECT_TRUE(TargetDataCall->getOperand(2)->getType()->isIntegerTy(32)); + EXPECT_TRUE(TargetDataCall->getOperand(8)->getType()->isPointerTy()); Builder.restoreIP(codeGenIP); - auto *SI = Builder.CreateStore(Builder.getInt32(99), Val1); - auto *newBB = SplitBlock(Builder.GetInsertBlock(), SI); - Builder.SetInsertPoint(newBB); - auto *UI = &Builder.GetInsertBlock()->back(); - SplitBlock(Builder.GetInsertBlock(), UI); + Builder.CreateStore(Builder.getInt32(99), Val1); }; Builder.restoreIP(OMPBuilder.createTargetData( - Loc, Builder.saveIP(), MapTypeFlagsToFrom, MapNames, MapperAllocas, - /* IsBegin= */ false, DeviceID, /* IfCond= */ nullptr, ProcessMapOpCB, - BodyCB)); + Loc, AllocaIP, Builder.saveIP(), /* IsBegin= */ false, DeviceID, + /* IfCond= */ nullptr, MapInfos, BodyCB)); - CallInst *TargetDataCall = - dyn_cast(&Builder.GetInsertBlock()->back()); + CallInst *TargetDataCall = dyn_cast(&BB->back()); EXPECT_NE(TargetDataCall, nullptr); EXPECT_EQ(TargetDataCall->arg_size(), 9U); EXPECT_EQ(TargetDataCall->getCalledFunction()->getName(), diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.cpp --- a/mlir/lib/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.cpp @@ -78,6 +78,19 @@ llvm_unreachable("Unknown OpenACC operation"); } +/// Computes the size of type in bytes. +static llvm::Value *getSizeInBytes(llvm::IRBuilderBase &builder, + llvm::Value *basePtr) { + llvm::LLVMContext &ctx = builder.getContext(); + llvm::Value *null = + llvm::Constant::getNullValue(basePtr->getType()->getPointerTo()); + llvm::Value *sizeGep = + builder.CreateGEP(basePtr->getType(), null, builder.getInt32(1)); + llvm::Value *sizePtrToInt = + builder.CreatePtrToInt(sizeGep, llvm::Type::getInt64Ty(ctx)); + return sizePtrToInt; +} + /// Extract pointer, size and mapping information from operands /// to populate the future functions arguments. static LogicalResult @@ -111,7 +124,7 @@ } else if (data.getType().isa()) { dataPtrBase = dataValue; dataPtr = dataValue; - dataSize = accBuilder->getSizeInBytes(dataValue); + dataSize = getSizeInBytes(builder, dataValue); } else { return op->emitOpError() << "Data operand must be legalized before translation." @@ -323,7 +336,7 @@ return failure(); llvm::GlobalVariable *maptypes = - accBuilder->createOffloadMaptypes(flags, ".offload_maptypes"); + accBuilder->createOffloadMapGlobals(flags, ".offload_maptypes"); llvm::Value *maptypesArg = builder.CreateConstInBoundsGEP2_32( llvm::ArrayType::get(llvm::Type::getInt64Ty(ctx), totalNbOperand), maptypes, /*Idx0=*/0, /*Idx1=*/0); @@ -421,7 +434,7 @@ return failure(); llvm::GlobalVariable *maptypes = - accBuilder->createOffloadMaptypes(flags, ".offload_maptypes"); + accBuilder->createOffloadMapGlobals(flags, ".offload_maptypes"); llvm::Value *maptypesArg = builder.CreateConstInBoundsGEP2_32( llvm::ArrayType::get(llvm::Type::getInt64Ty(ctx), totalNbOperand), maptypes, /*Idx0=*/0, /*Idx1=*/0); diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp --- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp @@ -1353,67 +1353,33 @@ return success(); } -/// Process MapOperands for Target Data directives. -static LogicalResult processMapOperand( - llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation, - const SmallVector &mapOperands, const ArrayAttr &mapTypes, - SmallVector &mapTypeFlags, - SmallVectorImpl &mapNames, - struct llvm::OpenMPIRBuilder::MapperAllocas &mapperAllocas) { - auto numMapOperands = mapOperands.size(); - llvm::OpenMPIRBuilder *ompBuilder = moduleTranslation.getOpenMPBuilder(); - llvm::PointerType *i8PtrTy = builder.getInt8PtrTy(); - llvm::ArrayType *arrI8PtrTy = llvm::ArrayType::get(i8PtrTy, numMapOperands); - llvm::IntegerType *i64Ty = builder.getInt64Ty(); - llvm::ArrayType *arrI64Ty = llvm::ArrayType::get(i64Ty, numMapOperands); +/// Get size in Bytes for an mlir::Type +int64_t getSizeInBytes(DataLayout &DL, const mlir::Type &type) { + if (isa(type)) + return DL.getTypeSize(cast(type).getElementType()); + + return -1; +} +/// Gather Type and Name and other information for the map operands. +static LogicalResult gatherMapInfo( + LLVM::ModuleTranslation &moduleTranslation, DataLayout &DL, + const SmallVectorImpl &mapOperands, const ArrayAttr &mapTypes, + llvm::SmallMapVector + &mapInfos) { + llvm::OpenMPIRBuilder *ompBuilder = moduleTranslation.getOpenMPBuilder(); unsigned index = 0; for (const auto &mapOp : mapOperands) { - const auto &mapTypeOp = mapTypes[index]; - - llvm::Value *mapOpValue = moduleTranslation.lookupValue(mapOp); - llvm::Value *mapOpPtrBase; - llvm::Value *mapOpPtr; - llvm::Value *mapOpSize; - - if (mapOp.getType().isa()) { - mapOpPtrBase = mapOpValue; - mapOpPtr = mapOpValue; - mapOpSize = ompBuilder->getSizeInBytes(mapOpValue); - } else { + if (!mapOp.getType().isa()) return failure(); - } - - // Store base pointer extracted from operand into the i-th position of - // argBase. - llvm::Value *ptrBaseGEP = builder.CreateInBoundsGEP( - arrI8PtrTy, mapperAllocas.ArgsBase, - {builder.getInt32(0), builder.getInt32(index)}); - llvm::Value *ptrBaseCast = builder.CreateBitCast( - ptrBaseGEP, mapOpPtrBase->getType()->getPointerTo()); - builder.CreateStore(mapOpPtrBase, ptrBaseCast); - - // Store pointer extracted from operand into the i-th position of args. - llvm::Value *ptrGEP = builder.CreateInBoundsGEP( - arrI8PtrTy, mapperAllocas.Args, - {builder.getInt32(0), builder.getInt32(index)}); - llvm::Value *ptrCast = - builder.CreateBitCast(ptrGEP, mapOpPtr->getType()->getPointerTo()); - builder.CreateStore(mapOpPtr, ptrCast); - - // Store size extracted from operand into the i-th position of argSizes. - llvm::Value *sizeGEP = builder.CreateInBoundsGEP( - arrI64Ty, mapperAllocas.ArgSizes, - {builder.getInt32(0), builder.getInt32(index)}); - builder.CreateStore(mapOpSize, sizeGEP); - - mapTypeFlags.push_back(mapTypeOp.dyn_cast().getInt()); - llvm::Constant *mapName = + llvm::Value *mapOpValue = moduleTranslation.lookupValue(mapOp); + mapInfos[mapOpValue].Name = mlir::LLVM::createMappingInformation(mapOp.getLoc(), *ompBuilder); - mapNames.push_back(mapName); - ++index; + mapInfos[mapOpValue].Type = + mapTypes[index].dyn_cast().getInt(); + mapInfos[mapOpValue].Size = getSizeInBytes(DL, mapOp.getType()); + index++; } - return success(); } @@ -1421,11 +1387,13 @@ convertOmpTargetData(Operation *op, llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation) { unsigned numMapOperands; - bool mapperFunc = false; llvm::Value *ifCond = nullptr; int64_t deviceID = llvm::omp::OMP_DEVICEID_UNDEF; SmallVector mapOperands; ArrayAttr mapTypes; + llvm::SmallMapVector + mapInfos; + DataLayout DL = DataLayout(op->getParentOfType()); llvm::OpenMPIRBuilder *ompBuilder = moduleTranslation.getOpenMPBuilder(); @@ -1468,7 +1436,6 @@ numMapOperands = enterDataOp.getMapOperands().size(); mapOperands = enterDataOp.getMapOperands(); mapTypes = enterDataOp.getMapTypes(); - mapperFunc = true; return success(); }) .Case([&](omp::ExitDataOp exitDataOp) { @@ -1498,46 +1465,34 @@ if (failed(result)) return failure(); - llvm::OpenMPIRBuilder::LocationDescription ompLoc(builder); - llvm::OpenMPIRBuilder::InsertPointTy allocaIP = - findAllocaInsertPoint(builder, moduleTranslation); - - struct llvm::OpenMPIRBuilder::MapperAllocas mapperAllocas; - SmallVector mapTypeFlags; - SmallVector mapNames; - ompBuilder->createMapperAllocas(builder.saveIP(), allocaIP, numMapOperands, - mapperAllocas); - - using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy; - LogicalResult processMapOpStatus = success(); - auto processMapOpCB = [&](InsertPointTy allocaIP, InsertPointTy codeGenIP) { - builder.restoreIP(codeGenIP); - processMapOpStatus = - processMapOperand(builder, moduleTranslation, mapOperands, mapTypes, - mapTypeFlags, mapNames, mapperAllocas); - }; - LogicalResult bodyGenStatus = success(); + using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy; auto bodyCB = [&](InsertPointTy allocaIP, InsertPointTy codeGenIP) { // DataOp has only one region associated with it. auto ®ion = cast(op).getRegion(); builder.restoreIP(codeGenIP); - convertOmpOpRegions(region, "omp.data.region", builder, moduleTranslation, - bodyGenStatus); + bodyGenStatus = inlineConvertOmpRegions(region, "omp.data.region", builder, + moduleTranslation); }; + if (failed(gatherMapInfo(moduleTranslation, DL, mapOperands, mapTypes, + mapInfos))) + return failure(); + + llvm::OpenMPIRBuilder::LocationDescription ompLoc(builder); + llvm::OpenMPIRBuilder::InsertPointTy allocaIP = + findAllocaInsertPoint(builder, moduleTranslation); + if (isa(op)) { builder.restoreIP(ompBuilder->createTargetData( - ompLoc, builder.saveIP(), mapTypeFlags, mapNames, mapperAllocas, - mapperFunc, deviceID, ifCond, processMapOpCB, bodyCB)); + ompLoc, allocaIP, builder.saveIP(), /*IsBegin=*/false, deviceID, ifCond, + mapInfos, bodyCB)); } else { builder.restoreIP(ompBuilder->createTargetData( - ompLoc, builder.saveIP(), mapTypeFlags, mapNames, mapperAllocas, - mapperFunc, deviceID, ifCond, processMapOpCB)); + ompLoc, allocaIP, builder.saveIP(), isa(op), deviceID, + ifCond, mapInfos)); } - if (failed(processMapOpStatus)) - return processMapOpStatus; return bodyGenStatus; } diff --git a/mlir/test/Target/LLVMIR/omptarget-llvm.mlir b/mlir/test/Target/LLVMIR/omptarget-llvm.mlir --- a/mlir/test/Target/LLVMIR/omptarget-llvm.mlir +++ b/mlir/test/Target/LLVMIR/omptarget-llvm.mlir @@ -12,32 +12,24 @@ } // CHECK: @.offload_maptypes = private unnamed_addr constant [1 x i64] [i64 3] +// CHECK: @.offload_sizes = private unnamed_addr constant [1 x i64] [i64 4] // CHECK-LABEL: define void @_QPopenmp_target_data() { // CHECK: %[[VAL_0:.*]] = alloca [1 x ptr], align 8 // CHECK: %[[VAL_1:.*]] = alloca [1 x ptr], align 8 -// CHECK: %[[VAL_2:.*]] = alloca [1 x i64], align 8 -// CHECK: %[[VAL_3:.*]] = alloca i32, i64 1, align 4 -// CHECK: br label %[[VAL_4:.*]] -// CHECK: entry: ; preds = %[[VAL_5:.*]] -// CHECK: %[[VAL_6:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0 -// CHECK: store ptr %[[VAL_3]], ptr %[[VAL_6]], align 8 -// CHECK: %[[VAL_7:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0 -// CHECK: store ptr %[[VAL_3]], ptr %[[VAL_7]], align 8 -// CHECK: %[[VAL_8:.*]] = getelementptr inbounds [1 x i64], ptr %[[VAL_2]], i32 0, i32 0 -// CHECK: store i64 ptrtoint (ptr getelementptr (ptr, ptr null, i32 1) to i64), ptr %[[VAL_8]], align 4 +// CHECK: %[[VAL_2:.*]] = alloca i32, i64 1, align 4 +// CHECK: br label %[[VAL_3:.*]] +// CHECK: entry: ; preds = %[[VAL_4:.*]] +// CHECK: %[[VAL_5:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0 +// CHECK: store ptr %[[VAL_2]], ptr %[[VAL_5]], align 8 +// CHECK: %[[VAL_6:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0 +// CHECK: store ptr %[[VAL_2]], ptr %[[VAL_6]], align 8 +// CHECK: %[[VAL_7:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0 +// CHECK: %[[VAL_8:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0 +// CHECK: call void @__tgt_target_data_begin_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_7]], ptr %[[VAL_8]], ptr @.offload_sizes, ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null) +// CHECK: store i32 99, ptr %[[VAL_2]], align 4 // CHECK: %[[VAL_9:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0 // CHECK: %[[VAL_10:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0 -// CHECK: %[[VAL_11:.*]] = getelementptr inbounds [1 x i64], ptr %[[VAL_2]], i32 0, i32 0 -// CHECK: call void @__tgt_target_data_begin_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_9]], ptr %[[VAL_10]], ptr %[[VAL_11]], ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null) -// CHECK: br label %[[VAL_12:.*]] -// CHECK: omp.data.region: ; preds = %[[VAL_4]] -// CHECK: store i32 99, ptr %[[VAL_3]], align 4 -// CHECK: br label %[[VAL_13:.*]] -// CHECK: omp.region.cont: ; preds = %[[VAL_12]] -// CHECK: %[[VAL_14:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0 -// CHECK: %[[VAL_15:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0 -// CHECK: %[[VAL_16:.*]] = getelementptr inbounds [1 x i64], ptr %[[VAL_2]], i32 0, i32 0 -// CHECK: call void @__tgt_target_data_end_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_14]], ptr %[[VAL_15]], ptr %[[VAL_16]], ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null) +// CHECK: call void @__tgt_target_data_end_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_9]], ptr %[[VAL_10]], ptr @.offload_sizes, ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null) // CHECK: ret void // ----- @@ -56,38 +48,30 @@ } // CHECK: @.offload_maptypes = private unnamed_addr constant [1 x i64] [i64 2] +// CHECK: @.offload_sizes = private unnamed_addr constant [1 x i64] [i64 4096] // CHECK-LABEL: define void @_QPopenmp_target_data_region // CHECK: (ptr %[[ARG_0:.*]]) { // CHECK: %[[VAL_0:.*]] = alloca [1 x ptr], align 8 // CHECK: %[[VAL_1:.*]] = alloca [1 x ptr], align 8 -// CHECK: %[[VAL_2:.*]] = alloca [1 x i64], align 8 -// CHECK: br label %[[VAL_3:.*]] -// CHECK: entry: ; preds = %[[VAL_4:.*]] -// CHECK: %[[VAL_5:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0 -// CHECK: store ptr %[[VAL_6:.*]], ptr %[[VAL_5]], align 8 -// CHECK: %[[VAL_7:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0 -// CHECK: store ptr %[[VAL_6]], ptr %[[VAL_7]], align 8 -// CHECK: %[[VAL_8:.*]] = getelementptr inbounds [1 x i64], ptr %[[VAL_2]], i32 0, i32 0 -// CHECK: store i64 ptrtoint (ptr getelementptr (ptr, ptr null, i32 1) to i64), ptr %[[VAL_8]], align 4 -// CHECK: %[[VAL_9:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0 -// CHECK: %[[VAL_10:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0 -// CHECK: %[[VAL_11:.*]] = getelementptr inbounds [1 x i64], ptr %[[VAL_2]], i32 0, i32 0 -// CHECK: call void @__tgt_target_data_begin_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_9]], ptr %[[VAL_10]], ptr %[[VAL_11]], ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null) -// CHECK: br label %[[VAL_12:.*]] -// CHECK: omp.data.region: ; preds = %[[VAL_3]] -// CHECK: %[[VAL_13:.*]] = getelementptr [1024 x i32], ptr %[[VAL_6]], i32 0, i64 0 -// CHECK: store i32 99, ptr %[[VAL_13]], align 4 -// CHECK: br label %[[VAL_14:.*]] -// CHECK: omp.region.cont: ; preds = %[[VAL_12]] -// CHECK: %[[VAL_15:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0 -// CHECK: %[[VAL_16:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0 -// CHECK: %[[VAL_17:.*]] = getelementptr inbounds [1 x i64], ptr %[[VAL_2]], i32 0, i32 0 -// CHECK: call void @__tgt_target_data_end_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_15]], ptr %[[VAL_16]], ptr %[[VAL_17]], ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null) +// CHECK: br label %[[VAL_2:.*]] +// CHECK: entry: ; preds = %[[VAL_3:.*]] +// CHECK: %[[VAL_4:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0 +// CHECK: store ptr %[[ARG_0]], ptr %[[VAL_4]], align 8 +// CHECK: %[[VAL_6:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0 +// CHECK: store ptr %[[ARG_0]], ptr %[[VAL_6]], align 8 +// CHECK: %[[VAL_7:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0 +// CHECK: %[[VAL_8:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0 +// CHECK: call void @__tgt_target_data_begin_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_7]], ptr %[[VAL_8]], ptr @.offload_sizes, ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null) +// CHECK: %[[VAL_9:.*]] = getelementptr [1024 x i32], ptr %[[ARG_0]], i32 0, i64 0 +// CHECK: store i32 99, ptr %[[VAL_9]], align 4 +// CHECK: %[[VAL_10:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0 +// CHECK: %[[VAL_11:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0 +// CHECK: call void @__tgt_target_data_end_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_10]], ptr %[[VAL_11]], ptr @.offload_sizes, ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null) // CHECK: ret void // ----- -llvm.func @_QPomp_target_enter_exit(%1 : !llvm.ptr>, %3 : !llvm.ptr>) { +llvm.func @_QPomp_target_enter_exit(%1 : !llvm.ptr>, %3 : !llvm.ptr>) { %4 = llvm.mlir.constant(1 : i64) : i64 %5 = llvm.alloca %4 x i32 {bindc_name = "dvc", in_type = i32, operand_segment_sizes = array, uniq_name = "_QFomp_target_enter_exitEdvc"} : (i64) -> !llvm.ptr %6 = llvm.mlir.constant(1 : i64) : i64 @@ -100,77 +84,67 @@ %11 = llvm.mlir.constant(10 : i32) : i32 %12 = llvm.icmp "slt" %10, %11 : i32 %13 = llvm.load %5 : !llvm.ptr - omp.target_enter_data if(%12 : i1) device(%13 : i32) map((to -> %1 : !llvm.ptr>), (alloc -> %3 : !llvm.ptr>)) + omp.target_enter_data if(%12 : i1) device(%13 : i32) map((to -> %1 : !llvm.ptr>), (alloc -> %3 : !llvm.ptr>)) %14 = llvm.load %7 : !llvm.ptr %15 = llvm.mlir.constant(10 : i32) : i32 %16 = llvm.icmp "sgt" %14, %15 : i32 %17 = llvm.load %5 : !llvm.ptr - omp.target_exit_data if(%16 : i1) device(%17 : i32) map((from -> %1 : !llvm.ptr>), (release -> %3 : !llvm.ptr>)) + omp.target_exit_data if(%16 : i1) device(%17 : i32) map((from -> %1 : !llvm.ptr>), (release -> %3 : !llvm.ptr>)) llvm.return } // CHECK: @.offload_maptypes = private unnamed_addr constant [2 x i64] [i64 1, i64 0] -// CHECK: @.offload_maptypes.1 = private unnamed_addr constant [2 x i64] [i64 2, i64 0] +// CHECK: @.offload_sizes = private unnamed_addr constant [2 x i64] [i64 4096, i64 2048] +// CHECK: @.offload_maptypes.2 = private unnamed_addr constant [2 x i64] [i64 2, i64 0] +// CHECK: @.offload_sizes.3 = private unnamed_addr constant [2 x i64] [i64 4096, i64 2048] // CHECK-LABEL: define void @_QPomp_target_enter_exit // CHECK: (ptr %[[ARG_0:.*]], ptr %[[ARG_1:.*]]) { // CHECK: %[[VAL_0:.*]] = alloca [2 x ptr], align 8 // CHECK: %[[VAL_1:.*]] = alloca [2 x ptr], align 8 -// CHECK: %[[VAL_2:.*]] = alloca [2 x i64], align 8 +// CHECK: %[[VAL_2:.*]] = alloca [2 x ptr], align 8 // CHECK: %[[VAL_3:.*]] = alloca [2 x ptr], align 8 -// CHECK: %[[VAL_4:.*]] = alloca [2 x ptr], align 8 -// CHECK: %[[VAL_5:.*]] = alloca [2 x i64], align 8 -// CHECK: %[[VAL_6:.*]] = alloca i32, i64 1, align 4 -// CHECK: %[[VAL_7:.*]] = alloca i32, i64 1, align 4 -// CHECK: store i32 5, ptr %[[VAL_7]], align 4 -// CHECK: store i32 2, ptr %[[VAL_6]], align 4 -// CHECK: %[[VAL_8:.*]] = load i32, ptr %[[VAL_7]], align 4 -// CHECK: %[[VAL_9:.*]] = icmp slt i32 %[[VAL_8]], 10 -// CHECK: %[[VAL_10:.*]] = load i32, ptr %[[VAL_6]], align 4 -// CHECK: br label %[[VAL_11:.*]] -// CHECK: entry: ; preds = %[[VAL_12:.*]] -// CHECK: br i1 %[[VAL_9]], label %[[VAL_13:.*]], label %[[VAL_14:.*]] -// CHECK: omp_if.then: ; preds = %[[VAL_11]] +// CHECK: %[[VAL_4:.*]] = alloca i32, i64 1, align 4 +// CHECK: %[[VAL_5:.*]] = alloca i32, i64 1, align 4 +// CHECK: store i32 5, ptr %[[VAL_5]], align 4 +// CHECK: store i32 2, ptr %[[VAL_4]], align 4 +// CHECK: %[[VAL_6:.*]] = load i32, ptr %[[VAL_5]], align 4 +// CHECK: %[[VAL_7:.*]] = icmp slt i32 %[[VAL_6]], 10 +// CHECK: %[[VAL_8:.*]] = load i32, ptr %[[VAL_4]], align 4 +// CHECK: br label %[[VAL_9:.*]] +// CHECK: entry: ; preds = %[[VAL_10:.*]] +// CHECK: br i1 %[[VAL_7]], label %[[VAL_11:.*]], label %[[VAL_12:.*]] +// CHECK: omp_if.then: ; preds = %[[VAL_9]] +// CHECK: %[[VAL_13:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_2]], i32 0, i32 0 +// CHECK: store ptr %[[ARG_0]], ptr %[[VAL_13]], align 8 // CHECK: %[[VAL_15:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_3]], i32 0, i32 0 -// CHECK: store ptr %[[VAL_16:.*]], ptr %[[VAL_15]], align 8 -// CHECK: %[[VAL_17:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_4]], i32 0, i32 0 -// CHECK: store ptr %[[VAL_16]], ptr %[[VAL_17]], align 8 -// CHECK: %[[VAL_18:.*]] = getelementptr inbounds [2 x i64], ptr %[[VAL_5]], i32 0, i32 0 -// CHECK: store i64 ptrtoint (ptr getelementptr (ptr, ptr null, i32 1) to i64), ptr %[[VAL_18]], align 4 -// CHECK: %[[VAL_19:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_3]], i32 0, i32 1 -// CHECK: store ptr %[[VAL_20:.*]], ptr %[[VAL_19]], align 8 -// CHECK: %[[VAL_21:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_4]], i32 0, i32 1 -// CHECK: store ptr %[[VAL_20]], ptr %[[VAL_21]], align 8 -// CHECK: %[[VAL_22:.*]] = getelementptr inbounds [2 x i64], ptr %[[VAL_5]], i32 0, i32 1 -// CHECK: store i64 ptrtoint (ptr getelementptr (ptr, ptr null, i32 1) to i64), ptr %[[VAL_22]], align 4 -// CHECK: %[[VAL_23:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_3]], i32 0, i32 0 -// CHECK: %[[VAL_24:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_4]], i32 0, i32 0 -// CHECK: %[[VAL_25:.*]] = getelementptr inbounds [2 x i64], ptr %[[VAL_5]], i32 0, i32 0 -// CHECK: call void @__tgt_target_data_begin_mapper(ptr @3, i64 -1, i32 2, ptr %[[VAL_23]], ptr %[[VAL_24]], ptr %[[VAL_25]], ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null) -// CHECK: br label %[[VAL_14]] -// CHECK: omp_if.end: ; preds = %[[VAL_11]], %[[VAL_13]] -// CHECK: %[[VAL_26:.*]] = load i32, ptr %[[VAL_7]], align 4 -// CHECK: %[[VAL_27:.*]] = icmp sgt i32 %[[VAL_26]], 10 -// CHECK: %[[VAL_28:.*]] = load i32, ptr %[[VAL_6]], align 4 -// CHECK: br i1 %[[VAL_27]], label %[[VAL_29:.*]], label %[[VAL_30:.*]] -// CHECK: omp_if.then4: ; preds = %[[VAL_14]] -// CHECK: %[[VAL_31:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_0]], i32 0, i32 0 -// CHECK: store ptr %[[VAL_16]], ptr %[[VAL_31]], align 8 -// CHECK: %[[VAL_32:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_1]], i32 0, i32 0 -// CHECK: store ptr %[[VAL_16]], ptr %[[VAL_32]], align 8 -// CHECK: %[[VAL_33:.*]] = getelementptr inbounds [2 x i64], ptr %[[VAL_2]], i32 0, i32 0 -// CHECK: store i64 ptrtoint (ptr getelementptr (ptr, ptr null, i32 1) to i64), ptr %[[VAL_33]], align 4 -// CHECK: %[[VAL_34:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_0]], i32 0, i32 1 -// CHECK: store ptr %[[VAL_20]], ptr %[[VAL_34]], align 8 -// CHECK: %[[VAL_35:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_1]], i32 0, i32 1 -// CHECK: store ptr %[[VAL_20]], ptr %[[VAL_35]], align 8 -// CHECK: %[[VAL_36:.*]] = getelementptr inbounds [2 x i64], ptr %[[VAL_2]], i32 0, i32 1 -// CHECK: store i64 ptrtoint (ptr getelementptr (ptr, ptr null, i32 1) to i64), ptr %[[VAL_36]], align 4 -// CHECK: %[[VAL_37:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_0]], i32 0, i32 0 -// CHECK: %[[VAL_38:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_1]], i32 0, i32 0 -// CHECK: %[[VAL_39:.*]] = getelementptr inbounds [2 x i64], ptr %[[VAL_2]], i32 0, i32 0 -// CHECK: call void @__tgt_target_data_end_mapper(ptr @3, i64 -1, i32 2, ptr %[[VAL_37]], ptr %[[VAL_38]], ptr %[[VAL_39]], ptr @.offload_maptypes.1, ptr @.offload_mapnames.2, ptr null) -// CHECK: br label %[[VAL_30]] -// CHECK: omp_if.end5: ; preds = %[[VAL_14]], %[[VAL_29]] +// CHECK: store ptr %[[ARG_0]], ptr %[[VAL_15]], align 8 +// CHECK: %[[VAL_16:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_2]], i32 0, i32 1 +// CHECK: store ptr %[[ARG_1]], ptr %[[VAL_16]], align 8 +// CHECK: %[[VAL_18:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_3]], i32 0, i32 1 +// CHECK: store ptr %[[ARG_1]], ptr %[[VAL_18]], align 8 +// CHECK: %[[VAL_19:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_2]], i32 0, i32 0 +// CHECK: %[[VAL_20:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_3]], i32 0, i32 0 +// CHECK: call void @__tgt_target_data_begin_mapper(ptr @3, i64 -1, i32 2, ptr %[[VAL_19]], ptr %[[VAL_20]], ptr @.offload_sizes, ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null) +// CHECK: br label %[[VAL_12]] +// CHECK: omp_if.end: ; preds = %[[VAL_9]], %[[VAL_11]] +// CHECK: %[[VAL_21:.*]] = load i32, ptr %[[VAL_5]], align 4 +// CHECK: %[[VAL_22:.*]] = icmp sgt i32 %[[VAL_21]], 10 +// CHECK: %[[VAL_23:.*]] = load i32, ptr %[[VAL_4]], align 4 +// CHECK: br i1 %[[VAL_22]], label %[[VAL_24:.*]], label %[[VAL_25:.*]] +// CHECK: omp_if.then1: ; preds = %[[VAL_12]] +// CHECK: %[[VAL_26:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_0]], i32 0, i32 0 +// CHECK: store ptr %[[ARG_0]], ptr %[[VAL_26]], align 8 +// CHECK: %[[VAL_27:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_1]], i32 0, i32 0 +// CHECK: store ptr %[[ARG_0]], ptr %[[VAL_27]], align 8 +// CHECK: %[[VAL_28:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_0]], i32 0, i32 1 +// CHECK: store ptr %[[ARG_1]], ptr %[[VAL_28]], align 8 +// CHECK: %[[VAL_29:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_1]], i32 0, i32 1 +// CHECK: store ptr %[[ARG_1]], ptr %[[VAL_29]], align 8 +// CHECK: %[[VAL_30:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_0]], i32 0, i32 0 +// CHECK: %[[VAL_31:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_1]], i32 0, i32 0 +// CHECK: call void @__tgt_target_data_end_mapper(ptr @3, i64 -1, i32 2, ptr %[[VAL_30]], ptr %[[VAL_31]], ptr @.offload_sizes.3, ptr @.offload_maptypes.2, ptr @.offload_mapnames.1, ptr null) +// CHECK: br label %[[VAL_25]] +// CHECK: omp_if.end4: ; preds = %[[VAL_12]], %[[VAL_24]] // CHECK: ret void // -----