diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.h b/clang/lib/CodeGen/CGOpenMPRuntime.h --- a/clang/lib/CodeGen/CGOpenMPRuntime.h +++ b/clang/lib/CodeGen/CGOpenMPRuntime.h @@ -1654,65 +1654,16 @@ /// Struct that keeps all the relevant information that should be kept /// throughout a 'target data' region. - class TargetDataInfo { - /// Set to true if device pointer information have to be obtained. - bool RequiresDevicePointerInfo = false; - /// Set to true if Clang emits separate runtime calls for the beginning and - /// end of the region. These calls might have separate map type arrays. - bool SeparateBeginEndCalls = false; - + class TargetDataInfo : public llvm::OpenMPIRBuilder::TargetDataInfo { public: - /// The array of base pointer passed to the runtime library. - llvm::Value *BasePointersArray = nullptr; - /// The array of section pointers passed to the runtime library. - llvm::Value *PointersArray = nullptr; - /// The array of sizes passed to the runtime library. - llvm::Value *SizesArray = nullptr; - /// The array of map types passed to the runtime library for the beginning - /// of the region or for the entire region if there are no separate map - /// types for the region end. - llvm::Value *MapTypesArray = nullptr; - /// The array of map types passed to the runtime library for the end of the - /// region, or nullptr if there are no separate map types for the region - /// end. - llvm::Value *MapTypesArrayEnd = nullptr; - /// The array of user-defined mappers passed to the runtime library. - llvm::Value *MappersArray = nullptr; - /// The array of original declaration names of mapped pointers sent to the - /// runtime library for debugging - llvm::Value *MapNamesArray = nullptr; - /// Indicate whether any user-defined mapper exists. - bool HasMapper = false; - /// The total number of pointers passed to the runtime library. - unsigned NumberOfPtrs = 0u; + explicit TargetDataInfo() : llvm::OpenMPIRBuilder::TargetDataInfo() {} + explicit TargetDataInfo(bool RequiresDevicePointerInfo, + bool SeparateBeginEndCalls) + : llvm::OpenMPIRBuilder::TargetDataInfo(RequiresDevicePointerInfo, + SeparateBeginEndCalls) {} /// Map between the a declaration of a capture and the corresponding base /// pointer address where the runtime returns the device pointers. llvm::DenseMap CaptureDeviceAddrMap; - - explicit TargetDataInfo() {} - explicit TargetDataInfo(bool RequiresDevicePointerInfo, - bool SeparateBeginEndCalls) - : RequiresDevicePointerInfo(RequiresDevicePointerInfo), - SeparateBeginEndCalls(SeparateBeginEndCalls) {} - /// Clear information about the data arrays. - void clearArrayInfo() { - BasePointersArray = nullptr; - PointersArray = nullptr; - SizesArray = nullptr; - MapTypesArray = nullptr; - MapTypesArrayEnd = nullptr; - MapNamesArray = nullptr; - MappersArray = nullptr; - HasMapper = false; - NumberOfPtrs = 0u; - } - /// Return true if the current target data information has valid arrays. - bool isValid() { - return BasePointersArray && PointersArray && SizesArray && - MapTypesArray && (!HasMapper || MappersArray) && NumberOfPtrs; - } - bool requiresDevicePointerInfo() { return RequiresDevicePointerInfo; } - bool separateBeginEndCalls() { return SeparateBeginEndCalls; } }; /// Emit the target data mapping code associated with \a D. @@ -1727,7 +1678,7 @@ const OMPExecutableDirective &D, const Expr *IfCond, const Expr *Device, const RegionCodeGenTy &CodeGen, - TargetDataInfo &Info); + CGOpenMPRuntime::TargetDataInfo &Info); /// Emit the data mapping/movement code associated with the directive /// \a D that should be of the form 'target [{enter|exit} data | update]'. @@ -2487,7 +2438,7 @@ void emitTargetDataCalls(CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *IfCond, const Expr *Device, const RegionCodeGenTy &CodeGen, - TargetDataInfo &Info) override; + CGOpenMPRuntime::TargetDataInfo &Info) override; /// Emit the data mapping/movement code associated with the directive /// \a D that should be of the form 'target [{enter|exit} data | update]'. 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 @@ -9442,7 +9442,7 @@ DimsAddr, CGM.Int8PtrTy, CGM.Int8Ty); llvm::Value *P = CGF.Builder.CreateConstInBoundsGEP2_32( llvm::ArrayType::get(CGM.VoidPtrTy, Info.NumberOfPtrs), - Info.PointersArray, 0, I); + Info.RTArgs.PointersArray, 0, I); Address PAddr(P, CGM.VoidPtrTy, CGF.getPointerAlign()); CGF.Builder.CreateStore(DAddr.getPointer(), PAddr); ++L; @@ -9520,13 +9520,13 @@ Ctx.VoidPtrTy, PointerNumAP, nullptr, ArrayType::Normal, /*IndexTypeQuals=*/0); - Info.BasePointersArray = + Info.RTArgs.BasePointersArray = CGF.CreateMemTemp(PointerArrayType, ".offload_baseptrs").getPointer(); - Info.PointersArray = + Info.RTArgs.PointersArray = CGF.CreateMemTemp(PointerArrayType, ".offload_ptrs").getPointer(); Address MappersArray = CGF.CreateMemTemp(PointerArrayType, ".offload_mappers"); - Info.MappersArray = MappersArray.getPointer(); + Info.RTArgs.MappersArray = MappersArray.getPointer(); // If we don't have any VLA types or other types that require runtime // evaluation, we can use a constant array for the map sizes, otherwise we @@ -9555,7 +9555,7 @@ QualType SizeArrayType = Ctx.getConstantArrayType( Int64Ty, PointerNumAP, nullptr, ArrayType::Normal, /*IndexTypeQuals=*/0); - Info.SizesArray = + Info.RTArgs.SizesArray = CGF.CreateMemTemp(SizeArrayType, ".offload_sizes").getPointer(); } else { auto *SizesArrayInit = llvm::ConstantArray::get( @@ -9579,9 +9579,9 @@ CGM.getNaturalTypeAlignment(Ctx.getIntTypeForBitwidth( /*DestWidth=*/64, /*Signed=*/false))), CGF.getTypeSize(SizeArrayType)); - Info.SizesArray = Buffer.getPointer(); + Info.RTArgs.SizesArray = Buffer.getPointer(); } else { - Info.SizesArray = SizesArrayGbl; + Info.RTArgs.SizesArray = SizesArrayGbl; } } @@ -9593,12 +9593,12 @@ CGM.getOpenMPRuntime().getName({"offload_maptypes"}); auto *MapTypesArrayGbl = OMPBuilder.createOffloadMaptypes(Mapping, MaptypesName); - Info.MapTypesArray = MapTypesArrayGbl; + Info.RTArgs.MapTypesArray = MapTypesArrayGbl; // The information types are only built if there is debug information // requested. if (CGM.getCodeGenOpts().getDebugInfo() == codegenoptions::NoDebugInfo) { - Info.MapNamesArray = llvm::Constant::getNullValue( + Info.RTArgs.MapNamesArray = llvm::Constant::getNullValue( llvm::Type::getInt8Ty(CGF.Builder.getContext())->getPointerTo()); } else { auto fillInfoMap = [&](MappableExprsHandler::MappingExprInfo &MapExpr) { @@ -9610,7 +9610,7 @@ CGM.getOpenMPRuntime().getName({"offload_mapnames"}); auto *MapNamesArrayGbl = OMPBuilder.createOffloadMapnames(InfoMap, MapnamesName); - Info.MapNamesArray = MapNamesArrayGbl; + Info.RTArgs.MapNamesArray = MapNamesArrayGbl; } // If there's a present map type modifier, it must not be applied to the end @@ -9626,7 +9626,7 @@ if (EndMapTypesDiffer) { MapTypesArrayGbl = OMPBuilder.createOffloadMaptypes(Mapping, MaptypesName); - Info.MapTypesArrayEnd = MapTypesArrayGbl; + Info.RTArgs.MapTypesArrayEnd = MapTypesArrayGbl; } } @@ -9634,7 +9634,7 @@ llvm::Value *BPVal = *CombinedInfo.BasePointers[I]; llvm::Value *BP = CGF.Builder.CreateConstInBoundsGEP2_32( llvm::ArrayType::get(CGM.VoidPtrTy, Info.NumberOfPtrs), - Info.BasePointersArray, 0, I); + Info.RTArgs.BasePointersArray, 0, I); BP = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( BP, BPVal->getType()->getPointerTo(/*AddrSpace=*/0)); Address BPAddr(BP, BPVal->getType(), @@ -9649,7 +9649,7 @@ llvm::Value *PVal = CombinedInfo.Pointers[I]; llvm::Value *P = CGF.Builder.CreateConstInBoundsGEP2_32( llvm::ArrayType::get(CGM.VoidPtrTy, Info.NumberOfPtrs), - Info.PointersArray, 0, I); + Info.RTArgs.PointersArray, 0, I); P = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( P, PVal->getType()->getPointerTo(/*AddrSpace=*/0)); Address PAddr(P, PVal->getType(), Ctx.getTypeAlignInChars(Ctx.VoidPtrTy)); @@ -9658,7 +9658,7 @@ if (RuntimeSizes.test(I)) { llvm::Value *S = CGF.Builder.CreateConstInBoundsGEP2_32( llvm::ArrayType::get(CGM.Int64Ty, Info.NumberOfPtrs), - Info.SizesArray, + Info.RTArgs.SizesArray, /*Idx0=*/0, /*Idx1=*/I); Address SAddr(S, CGM.Int64Ty, Ctx.getTypeAlignInChars(Int64Ty)); @@ -9688,76 +9688,6 @@ emitNonContiguousDescriptor(CGF, CombinedInfo, Info); } -namespace { -/// Additional arguments for emitOffloadingArraysArgument function. -struct ArgumentsOptions { - bool ForEndCall = false; - ArgumentsOptions() = default; - ArgumentsOptions(bool ForEndCall) : ForEndCall(ForEndCall) {} -}; -} // namespace - -/// Emit the arguments to be passed to the runtime library based on the -/// arrays of base pointers, pointers, sizes, map types, and mappers. If -/// ForEndCall, emit map types to be passed for the end of the region instead of -/// the beginning. -static void emitOffloadingArraysArgument( - CodeGenFunction &CGF, llvm::Value *&BasePointersArrayArg, - llvm::Value *&PointersArrayArg, llvm::Value *&SizesArrayArg, - llvm::Value *&MapTypesArrayArg, llvm::Value *&MapNamesArrayArg, - llvm::Value *&MappersArrayArg, CGOpenMPRuntime::TargetDataInfo &Info, - const ArgumentsOptions &Options = ArgumentsOptions()) { - assert((!Options.ForEndCall || Info.separateBeginEndCalls()) && - "expected region end call to runtime only when end call is separate"); - CodeGenModule &CGM = CGF.CGM; - if (Info.NumberOfPtrs) { - BasePointersArrayArg = CGF.Builder.CreateConstInBoundsGEP2_32( - llvm::ArrayType::get(CGM.VoidPtrTy, Info.NumberOfPtrs), - Info.BasePointersArray, - /*Idx0=*/0, /*Idx1=*/0); - PointersArrayArg = CGF.Builder.CreateConstInBoundsGEP2_32( - llvm::ArrayType::get(CGM.VoidPtrTy, Info.NumberOfPtrs), - Info.PointersArray, - /*Idx0=*/0, - /*Idx1=*/0); - SizesArrayArg = CGF.Builder.CreateConstInBoundsGEP2_32( - llvm::ArrayType::get(CGM.Int64Ty, Info.NumberOfPtrs), Info.SizesArray, - /*Idx0=*/0, /*Idx1=*/0); - MapTypesArrayArg = CGF.Builder.CreateConstInBoundsGEP2_32( - llvm::ArrayType::get(CGM.Int64Ty, Info.NumberOfPtrs), - Options.ForEndCall && Info.MapTypesArrayEnd ? Info.MapTypesArrayEnd - : Info.MapTypesArray, - /*Idx0=*/0, - /*Idx1=*/0); - - // Only emit the mapper information arrays if debug information is - // requested. - if (CGF.CGM.getCodeGenOpts().getDebugInfo() == codegenoptions::NoDebugInfo) - MapNamesArrayArg = llvm::ConstantPointerNull::get(CGM.VoidPtrPtrTy); - else - MapNamesArrayArg = CGF.Builder.CreateConstInBoundsGEP2_32( - llvm::ArrayType::get(CGM.VoidPtrTy, Info.NumberOfPtrs), - Info.MapNamesArray, - /*Idx0=*/0, - /*Idx1=*/0); - // If there is no user-defined mapper, set the mapper array to nullptr to - // avoid an unnecessary data privatization - if (!Info.HasMapper) - MappersArrayArg = llvm::ConstantPointerNull::get(CGM.VoidPtrPtrTy); - else - MappersArrayArg = - CGF.Builder.CreatePointerCast(Info.MappersArray, CGM.VoidPtrPtrTy); - } else { - BasePointersArrayArg = llvm::ConstantPointerNull::get(CGM.VoidPtrPtrTy); - PointersArrayArg = llvm::ConstantPointerNull::get(CGM.VoidPtrPtrTy); - SizesArrayArg = llvm::ConstantPointerNull::get(CGM.Int64Ty->getPointerTo()); - MapTypesArrayArg = - llvm::ConstantPointerNull::get(CGM.Int64Ty->getPointerTo()); - MapNamesArrayArg = llvm::ConstantPointerNull::get(CGM.VoidPtrPtrTy); - MappersArrayArg = llvm::ConstantPointerNull::get(CGM.VoidPtrPtrTy); - } -} - /// Check for inner distribute directive. static const OMPExecutableDirective * getNestedDistributeDirective(ASTContext &Ctx, const OMPExecutableDirective &D) { @@ -10479,25 +10409,26 @@ // weren't referenced within the construct. MEHandler.generateAllInfo(CombinedInfo, MappedVarSet); - TargetDataInfo Info; + CGOpenMPRuntime::TargetDataInfo Info; // Fill up the arrays and create the arguments. emitOffloadingArrays(CGF, CombinedInfo, Info, OMPBuilder); - emitOffloadingArraysArgument( - CGF, Info.BasePointersArray, Info.PointersArray, Info.SizesArray, - Info.MapTypesArray, Info.MapNamesArray, Info.MappersArray, Info, - {/*ForEndCall=*/false}); + bool EmitDebug = + CGF.CGM.getCodeGenOpts().getDebugInfo() != codegenoptions::NoDebugInfo; + OMPBuilder.emitOffloadingArraysArgument(CGF.Builder, Info.RTArgs, Info, + EmitDebug, + /*ForEndCall=*/false); InputInfo.NumberOfTargetItems = Info.NumberOfPtrs; - InputInfo.BasePointersArray = - Address(Info.BasePointersArray, CGF.VoidPtrTy, CGM.getPointerAlign()); - InputInfo.PointersArray = - Address(Info.PointersArray, CGF.VoidPtrTy, CGM.getPointerAlign()); + InputInfo.BasePointersArray = Address(Info.RTArgs.BasePointersArray, + CGF.VoidPtrTy, CGM.getPointerAlign()); + InputInfo.PointersArray = Address(Info.RTArgs.PointersArray, CGF.VoidPtrTy, + CGM.getPointerAlign()); InputInfo.SizesArray = - Address(Info.SizesArray, CGF.Int64Ty, CGM.getPointerAlign()); + Address(Info.RTArgs.SizesArray, CGF.Int64Ty, CGM.getPointerAlign()); InputInfo.MappersArray = - Address(Info.MappersArray, CGF.VoidPtrTy, CGM.getPointerAlign()); - MapTypesArray = Info.MapTypesArray; - MapNamesArray = Info.MapNamesArray; + Address(Info.RTArgs.MappersArray, CGF.VoidPtrTy, CGM.getPointerAlign()); + MapTypesArray = Info.RTArgs.MapTypesArray; + MapNamesArray = Info.RTArgs.MapNamesArray; if (RequiresOuterTask) CGF.EmitOMPTargetTaskBasedDirective(D, ThenGen, InputInfo); else @@ -11063,7 +10994,8 @@ void CGOpenMPRuntime::emitTargetDataCalls( CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *IfCond, - const Expr *Device, const RegionCodeGenTy &CodeGen, TargetDataInfo &Info) { + const Expr *Device, const RegionCodeGenTy &CodeGen, + CGOpenMPRuntime::TargetDataInfo &Info) { if (!CGF.HaveInsertPoint()) return; @@ -11087,15 +11019,11 @@ emitOffloadingArrays(CGF, CombinedInfo, Info, OMPBuilder, /*IsNonContiguous=*/true); - llvm::Value *BasePointersArrayArg = nullptr; - llvm::Value *PointersArrayArg = nullptr; - llvm::Value *SizesArrayArg = nullptr; - llvm::Value *MapTypesArrayArg = nullptr; - llvm::Value *MapNamesArrayArg = nullptr; - llvm::Value *MappersArrayArg = nullptr; - emitOffloadingArraysArgument(CGF, BasePointersArrayArg, PointersArrayArg, - SizesArrayArg, MapTypesArrayArg, - MapNamesArrayArg, MappersArrayArg, Info); + llvm::OpenMPIRBuilder::TargetDataRTArgs RTArgs; + bool EmitDebug = + CGF.CGM.getCodeGenOpts().getDebugInfo() != codegenoptions::NoDebugInfo; + OMPBuilder.emitOffloadingArraysArgument(CGF.Builder, RTArgs, Info, + EmitDebug); // Emit device ID if any. llvm::Value *DeviceID = nullptr; @@ -11115,12 +11043,12 @@ llvm::Value *OffloadingArgs[] = {RTLoc, DeviceID, PointerNum, - BasePointersArrayArg, - PointersArrayArg, - SizesArrayArg, - MapTypesArrayArg, - MapNamesArrayArg, - MappersArrayArg}; + RTArgs.BasePointersArray, + RTArgs.PointersArray, + RTArgs.SizesArray, + RTArgs.MapTypesArray, + RTArgs.MapNamesArray, + RTArgs.MappersArray}; CGF.EmitRuntimeCall( OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___tgt_target_data_begin_mapper), @@ -11137,16 +11065,12 @@ PrePostActionTy &) { assert(Info.isValid() && "Invalid data environment closing arguments."); - llvm::Value *BasePointersArrayArg = nullptr; - llvm::Value *PointersArrayArg = nullptr; - llvm::Value *SizesArrayArg = nullptr; - llvm::Value *MapTypesArrayArg = nullptr; - llvm::Value *MapNamesArrayArg = nullptr; - llvm::Value *MappersArrayArg = nullptr; - emitOffloadingArraysArgument(CGF, BasePointersArrayArg, PointersArrayArg, - SizesArrayArg, MapTypesArrayArg, - MapNamesArrayArg, MappersArrayArg, Info, - {/*ForEndCall=*/true}); + llvm::OpenMPIRBuilder::TargetDataRTArgs RTArgs; + bool EmitDebug = + CGF.CGM.getCodeGenOpts().getDebugInfo() != codegenoptions::NoDebugInfo; + OMPBuilder.emitOffloadingArraysArgument(CGF.Builder, RTArgs, Info, + EmitDebug, + /*ForEndCall=*/true); // Emit device ID if any. llvm::Value *DeviceID = nullptr; @@ -11166,12 +11090,12 @@ llvm::Value *OffloadingArgs[] = {RTLoc, DeviceID, PointerNum, - BasePointersArrayArg, - PointersArrayArg, - SizesArrayArg, - MapTypesArrayArg, - MapNamesArrayArg, - MappersArrayArg}; + RTArgs.BasePointersArray, + RTArgs.PointersArray, + RTArgs.SizesArray, + RTArgs.MapTypesArray, + RTArgs.MapNamesArray, + RTArgs.MappersArray}; CGF.EmitRuntimeCall( OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___tgt_target_data_end_mapper), @@ -11360,27 +11284,28 @@ MappableExprsHandler MEHandler(D, CGF); MEHandler.generateAllInfo(CombinedInfo); - TargetDataInfo Info; + CGOpenMPRuntime::TargetDataInfo Info; // Fill up the arrays and create the arguments. emitOffloadingArrays(CGF, CombinedInfo, Info, OMPBuilder, /*IsNonContiguous=*/true); bool RequiresOuterTask = D.hasClausesOfKind() || D.hasClausesOfKind(); - emitOffloadingArraysArgument( - CGF, Info.BasePointersArray, Info.PointersArray, Info.SizesArray, - Info.MapTypesArray, Info.MapNamesArray, Info.MappersArray, Info, - {/*ForEndCall=*/false}); + bool EmitDebug = + CGF.CGM.getCodeGenOpts().getDebugInfo() != codegenoptions::NoDebugInfo; + OMPBuilder.emitOffloadingArraysArgument(CGF.Builder, Info.RTArgs, Info, + EmitDebug, + /*ForEndCall=*/false); InputInfo.NumberOfTargetItems = Info.NumberOfPtrs; - InputInfo.BasePointersArray = - Address(Info.BasePointersArray, CGF.VoidPtrTy, CGM.getPointerAlign()); - InputInfo.PointersArray = - Address(Info.PointersArray, CGF.VoidPtrTy, CGM.getPointerAlign()); + InputInfo.BasePointersArray = Address(Info.RTArgs.BasePointersArray, + CGF.VoidPtrTy, CGM.getPointerAlign()); + InputInfo.PointersArray = Address(Info.RTArgs.PointersArray, CGF.VoidPtrTy, + CGM.getPointerAlign()); InputInfo.SizesArray = - Address(Info.SizesArray, CGF.Int64Ty, CGM.getPointerAlign()); + Address(Info.RTArgs.SizesArray, CGF.Int64Ty, CGM.getPointerAlign()); InputInfo.MappersArray = - Address(Info.MappersArray, CGF.VoidPtrTy, CGM.getPointerAlign()); - MapTypesArray = Info.MapTypesArray; - MapNamesArray = Info.MapNamesArray; + Address(Info.RTArgs.MappersArray, CGF.VoidPtrTy, CGM.getPointerAlign()); + MapTypesArray = Info.RTArgs.MapTypesArray; + MapNamesArray = Info.RTArgs.MapNamesArray; if (RequiresOuterTask) CGF.EmitOMPTargetTaskBasedDirective(D, ThenGen, InputInfo); else @@ -13075,7 +13000,8 @@ void CGOpenMPSIMDRuntime::emitTargetDataCalls( CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *IfCond, - const Expr *Device, const RegionCodeGenTy &CodeGen, TargetDataInfo &Info) { + const Expr *Device, const RegionCodeGenTy &CodeGen, + CGOpenMPRuntime::TargetDataInfo &Info) { llvm_unreachable("Not supported in SIMD-only mode"); } 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 @@ -1002,6 +1002,78 @@ struct MapperAllocas &MapperAllocas, int64_t DeviceID, unsigned NumOperands); + /// Container for the arguments used to pass data to the runtime library. + struct TargetDataRTArgs { + explicit TargetDataRTArgs() {} + /// The array of base pointer passed to the runtime library. + Value *BasePointersArray = nullptr; + /// The array of section pointers passed to the runtime library. + Value *PointersArray = nullptr; + /// The array of sizes passed to the runtime library. + Value *SizesArray = nullptr; + /// The array of map types passed to the runtime library for the beginning + /// of the region or for the entire region if there are no separate map + /// types for the region end. + Value *MapTypesArray = nullptr; + /// The array of map types passed to the runtime library for the end of the + /// region, or nullptr if there are no separate map types for the region + /// end. + Value *MapTypesArrayEnd = nullptr; + /// The array of user-defined mappers passed to the runtime library. + Value *MappersArray = nullptr; + /// The array of original declaration names of mapped pointers sent to the + /// runtime library for debugging + Value *MapNamesArray = nullptr; + }; + + /// Struct that keeps the information that should be kept throughout + /// a 'target data' region. + class TargetDataInfo { + /// Set to true if device pointer information have to be obtained. + bool RequiresDevicePointerInfo = false; + /// Set to true if Clang emits separate runtime calls for the beginning and + /// end of the region. These calls might have separate map type arrays. + bool SeparateBeginEndCalls = false; + + public: + TargetDataRTArgs RTArgs; + + /// Indicate whether any user-defined mapper exists. + bool HasMapper = false; + /// The total number of pointers passed to the runtime library. + unsigned NumberOfPtrs = 0u; + + explicit TargetDataInfo() {} + explicit TargetDataInfo(bool RequiresDevicePointerInfo, + bool SeparateBeginEndCalls) + : RequiresDevicePointerInfo(RequiresDevicePointerInfo), + SeparateBeginEndCalls(SeparateBeginEndCalls) {} + /// Clear information about the data arrays. + void clearArrayInfo() { + RTArgs = TargetDataRTArgs(); + HasMapper = false; + NumberOfPtrs = 0u; + } + /// Return true if the current target data information has valid arrays. + bool isValid() { + return RTArgs.BasePointersArray && RTArgs.PointersArray && + RTArgs.SizesArray && RTArgs.MapTypesArray && + (!HasMapper || RTArgs.MappersArray) && NumberOfPtrs; + } + bool requiresDevicePointerInfo() { return RequiresDevicePointerInfo; } + bool separateBeginEndCalls() { return SeparateBeginEndCalls; } + }; + + /// Emit the arguments to be passed to the runtime library based on the + /// arrays of base pointers, pointers, sizes, map types, and mappers. If + /// ForEndCall, emit map types to be passed for the end of the region instead + /// of the beginning. + void emitOffloadingArraysArgument(IRBuilderBase &Builder, + OpenMPIRBuilder::TargetDataRTArgs &RTArgs, + OpenMPIRBuilder::TargetDataInfo &Info, + bool EmitDebug = false, + bool ForEndCall = false); + 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 @@ -3990,6 +3990,64 @@ ArgSizesGEP, MaptypesArg, MapnamesArg, NullPtr}); } +void OpenMPIRBuilder::emitOffloadingArraysArgument(IRBuilderBase &Builder, + TargetDataRTArgs &RTArgs, + TargetDataInfo &Info, + bool EmitDebug, + bool ForEndCall) { + assert((!ForEndCall || Info.separateBeginEndCalls()) && + "expected region end call to runtime only when end call is separate"); + auto VoidPtrTy = Type::getInt8PtrTy(M.getContext()); + auto VoidPtrPtrTy = VoidPtrTy->getPointerTo(0); + auto Int64Ty = Type::getInt64Ty(M.getContext()); + auto Int64PtrTy = Type::getInt64PtrTy(M.getContext()); + + if (!Info.NumberOfPtrs) { + RTArgs.BasePointersArray = ConstantPointerNull::get(VoidPtrPtrTy); + RTArgs.PointersArray = ConstantPointerNull::get(VoidPtrPtrTy); + RTArgs.SizesArray = ConstantPointerNull::get(Int64PtrTy); + RTArgs.MapTypesArray = ConstantPointerNull::get(Int64PtrTy); + RTArgs.MapNamesArray = ConstantPointerNull::get(VoidPtrPtrTy); + RTArgs.MappersArray = ConstantPointerNull::get(VoidPtrPtrTy); + return; + } + + RTArgs.BasePointersArray = Builder.CreateConstInBoundsGEP2_32( + ArrayType::get(VoidPtrTy, Info.NumberOfPtrs), + Info.RTArgs.BasePointersArray, + /*Idx0=*/0, /*Idx1=*/0); + RTArgs.PointersArray = Builder.CreateConstInBoundsGEP2_32( + ArrayType::get(VoidPtrTy, Info.NumberOfPtrs), Info.RTArgs.PointersArray, + /*Idx0=*/0, + /*Idx1=*/0); + RTArgs.SizesArray = Builder.CreateConstInBoundsGEP2_32( + ArrayType::get(Int64Ty, Info.NumberOfPtrs), Info.RTArgs.SizesArray, + /*Idx0=*/0, /*Idx1=*/0); + RTArgs.MapTypesArray = Builder.CreateConstInBoundsGEP2_32( + ArrayType::get(Int64Ty, Info.NumberOfPtrs), + ForEndCall && Info.RTArgs.MapTypesArrayEnd ? Info.RTArgs.MapTypesArrayEnd + : Info.RTArgs.MapTypesArray, + /*Idx0=*/0, + /*Idx1=*/0); + + // Only emit the mapper information arrays if debug information is + // requested. + if (!EmitDebug) + RTArgs.MapNamesArray = ConstantPointerNull::get(VoidPtrPtrTy); + else + RTArgs.MapNamesArray = Builder.CreateConstInBoundsGEP2_32( + ArrayType::get(VoidPtrTy, Info.NumberOfPtrs), Info.RTArgs.MapNamesArray, + /*Idx0=*/0, + /*Idx1=*/0); + // If there is no user-defined mapper, set the mapper array to nullptr to + // avoid an unnecessary data privatization + if (!Info.HasMapper) + RTArgs.MappersArray = ConstantPointerNull::get(VoidPtrPtrTy); + else + RTArgs.MappersArray = + Builder.CreatePointerCast(Info.RTArgs.MappersArray, VoidPtrPtrTy); +} + bool OpenMPIRBuilder::checkAndEmitFlushAfterAtomic( const LocationDescription &Loc, llvm::AtomicOrdering AO, AtomicKind AK) { assert(!(AO == AtomicOrdering::NotAtomic || 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 @@ -5312,4 +5312,55 @@ verifyDFSOrder(F, RefOrder); } +TEST_F(OpenMPIRBuilderTest, EmitOffloadingArraysArguments) { + OpenMPIRBuilder OMPBuilder(*M); + OMPBuilder.initialize(); + + IRBuilder<> Builder(BB); + + OpenMPIRBuilder::TargetDataRTArgs RTArgs; + OpenMPIRBuilder::TargetDataInfo Info(true, false); + + auto VoidPtrTy = Type::getInt8PtrTy(Builder.getContext()); + auto VoidPtrPtrTy = VoidPtrTy->getPointerTo(0); + auto Int64Ty = Type::getInt64Ty(Builder.getContext()); + auto Int64PtrTy = Type::getInt64PtrTy(Builder.getContext()); + auto Array4VoidPtrTy = ArrayType::get(VoidPtrTy, 4); + auto Array4Int64PtrTy = ArrayType::get(Int64Ty, 4); + + Info.RTArgs.BasePointersArray = + ConstantPointerNull::get(Array4VoidPtrTy->getPointerTo(0)); + Info.RTArgs.PointersArray = + ConstantPointerNull::get(Array4VoidPtrTy->getPointerTo()); + Info.RTArgs.SizesArray = + ConstantPointerNull::get(Array4Int64PtrTy->getPointerTo()); + Info.RTArgs.MapTypesArray = + ConstantPointerNull::get(Array4Int64PtrTy->getPointerTo()); + Info.RTArgs.MapNamesArray = + ConstantPointerNull::get(Array4VoidPtrTy->getPointerTo()); + Info.RTArgs.MappersArray = + ConstantPointerNull::get(Array4VoidPtrTy->getPointerTo()); + Info.NumberOfPtrs = 4; + + OMPBuilder.emitOffloadingArraysArgument(Builder, RTArgs, Info, false, false); + + EXPECT_NE(RTArgs.BasePointersArray, nullptr); + EXPECT_NE(RTArgs.PointersArray, nullptr); + EXPECT_NE(RTArgs.SizesArray, nullptr); + EXPECT_NE(RTArgs.MapTypesArray, nullptr); + EXPECT_NE(RTArgs.MappersArray, nullptr); + EXPECT_NE(RTArgs.MapNamesArray, nullptr); + EXPECT_EQ(RTArgs.MapTypesArrayEnd, nullptr); + + EXPECT_EQ(RTArgs.BasePointersArray->getType(), VoidPtrPtrTy); + RTArgs.BasePointersArray->getType()->dump(); + VoidPtrTy->dump(); + EXPECT_EQ(RTArgs.PointersArray->getType(), VoidPtrPtrTy); + EXPECT_EQ(RTArgs.SizesArray->getType(), Int64PtrTy); + RTArgs.SizesArray->getType()->dump(); + Int64PtrTy->dump(); + EXPECT_EQ(RTArgs.MapTypesArray->getType(), Int64PtrTy); + EXPECT_EQ(RTArgs.MappersArray->getType(), VoidPtrPtrTy); + EXPECT_EQ(RTArgs.MapNamesArray->getType(), VoidPtrPtrTy); +} } // namespace