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 @@ -498,11 +498,6 @@ LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/OMP_REQ_DYNAMIC_ALLOCATORS) }; -enum OpenMPOffloadingReservedDeviceIDs { - /// Device ID if the device was not defined, runtime should get it - /// from environment variables in the spec. - OMP_DEVICEID_UNDEF = -1, -}; } // anonymous namespace /// Describes ident structure that describes a source location. diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h b/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h --- a/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h +++ b/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h @@ -241,6 +241,12 @@ LLVM_MARK_AS_BITMASK_ENUM(/* LargestFlag = */ OMP_MAP_MEMBER_OF) }; +enum OpenMPOffloadingReservedDeviceIDs { + /// Device ID if the device was not defined, runtime should get it + /// from environment variables in the spec. + OMP_DEVICEID_UNDEF = -1 +}; + enum class AddressSpace : unsigned { Generic = 0, Global = 1, 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 @@ -1095,6 +1095,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); @@ -1550,6 +1553,29 @@ StringRef EntryFnIDName, int32_t NumTeams, int32_t NumThreads); + /// Generator for '#omp target data' + /// + /// \param Loc The location where the target data construct was encountered. + /// \param CodeGenIP The insertion point at which the target directive code + /// should be placed. + /// \param HasRegion True if the op has a region associated with it, false + /// otherwise + /// \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 MapperFunc Mapper Fucntion to be called for the Target Data op + /// \param DeviceID Stores the DeviceID from the device clause + /// \param IfCond Value which corresponds to the if clause condition. + /// \param ProcessMapOpCB Callback that will generate the mapOperand code. + /// \param BodyGenCB Callback that will generate the region code. + OpenMPIRBuilder::InsertPointTy createTargetData( + const LocationDescription &Loc, OpenMPIRBuilder::InsertPointTy CodeGenIP, + bool HasRegion, SmallVector &MapTypeFlags, + SmallVector &MapNames, struct MapperAllocas &MapperAllocas, + Function *MapperFunc, int64_t DeviceID, Value *IfCond, + BodyGenCallbackTy ProcessMapOpCB, 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 /// we provide the declarations, the initializeTypes function will provide the 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 @@ -4038,6 +4038,74 @@ return OutlinedFnID; } +OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::createTargetData( + const LocationDescription &Loc, OpenMPIRBuilder::InsertPointTy CodeGenIP, + bool HasRegion, SmallVector &MapTypeFlags, + SmallVector &MapNames, struct MapperAllocas &MapperAllocas, + Function *MapperFunc, int64_t DeviceID, Value *IfCond, + BodyGenCallbackTy ProcessMapOpCB, BodyGenCallbackTy BodyGenCB) { + if (!updateToLocation(Loc)) + return InsertPointTy(); + + Builder.restoreIP(CodeGenIP); + + // LLVM utilities like blocks with terminators. + auto *UI = Builder.CreateUnreachable(); + + Instruction *ThenTI = UI, *ElseTI = nullptr; + if (IfCond) { + SplitBlockAndInsertIfThenElse(IfCond, UI, &ThenTI, &ElseTI); + ThenTI->getParent()->setName("omp_if.then"); + ElseTI->getParent()->setName("omp_if.else"); + } + Builder.SetInsertPoint(ThenTI); + + ProcessMapOpCB(Builder.saveIP(), Builder.saveIP()); + + 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); + + if (HasRegion) { + Function *beginMapperFunc = getOrCreateRuntimeFunctionPtr( + omp::OMPRTL___tgt_target_data_begin_mapper); + Function *endMapperFunc = + getOrCreateRuntimeFunctionPtr(omp::OMPRTL___tgt_target_data_end_mapper); + + // Create call to start the data region. + emitMapperCall(Builder.saveIP(), beginMapperFunc, srcLocInfo, MapTypesArg, + MapNamesArg, MapperAllocas, DeviceID, MapTypeFlags.size()); + + ProcessMapOpCB(Builder.saveIP(), Builder.saveIP()); + + // Create call to end the data region. + emitMapperCall(Builder.saveIP(), endMapperFunc, srcLocInfo, MapTypesArg, + MapNamesArg, MapperAllocas, DeviceID, MapTypeFlags.size()); + } else { + emitMapperCall(Builder.saveIP(), MapperFunc, srcLocInfo, MapTypesArg, + MapNamesArg, MapperAllocas, DeviceID, MapTypeFlags.size()); + } + + // Update the insertion point and remove the terminator we introduced. + Builder.SetInsertPoint(UI->getParent()); + if (IfCond) + UI->getParent()->setName("omp_if.end"); + UI->eraseFromParent(); + return Builder.saveIP(); +} + std::string OpenMPIRBuilder::getNameWithSeparators(ArrayRef Parts, StringRef FirstSeparator, StringRef Separator) { @@ -4085,6 +4153,16 @@ 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) { 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 @@ -4912,6 +4912,84 @@ EXPECT_TRUE(MapperCall->getOperand(8)->getType()->isPointerTy()); } +TEST_F(OpenMPIRBuilderTest, TargetEnterData) { + OpenMPIRBuilder OMPBuilder(*M); + 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 MapTypeflags = {5}; + 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)); + ASSERT_NE(Val1, nullptr); + + 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); + + 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); + }; + auto BodyCB = [&](InsertPointTy AllocaIP, InsertPointTy codeGenIP) {}; + + Builder.restoreIP(OMPBuilder.createTargetData( + Loc, Builder.saveIP(), /*hasRegion=*/false, MapTypeflags, MapNames, + MapperAllocas, + OMPBuilder.getOrCreateRuntimeFunctionPtr( + OMPRTL___tgt_target_data_begin_mapper), + DeviceID, /*ifCond=*/nullptr, ProcessMapOpCB, BodyCB)); + + CallInst *TargetDataCall = dyn_cast(&BB->back()); + BB->dump(); + 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()); +} + TEST_F(OpenMPIRBuilderTest, CreateTask) { using InsertPointTy = OpenMPIRBuilder::InsertPointTy; OpenMPIRBuilder OMPBuilder(*M); diff --git a/mlir/include/mlir/Target/LLVMIR/Dialect/Utils.h b/mlir/include/mlir/Target/LLVMIR/Dialect/Utils.h new file mode 100644 --- /dev/null +++ b/mlir/include/mlir/Target/LLVMIR/Dialect/Utils.h @@ -0,0 +1,40 @@ +//===- Utils.h - General Utilities for translating MLIR dialect to LLVM IR-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines general utilities for MLIR Dialect translations to LLVM IR. +// +//===----------------------------------------------------------------------===// + +#ifndef MLIR_TARGET_LLVMIR_DIALECT_UTILS_H +#define MLIR_TARGET_LLVMIR_DIALECT_UTILS_H + +#include "mlir/IR/BuiltinAttributes.h" +#include "mlir/IR/Location.h" +#include "mlir/Support/LLVM.h" + +#include "llvm/Frontend/OpenMP/OMPIRBuilder.h" +#include "llvm/IR/IRBuilder.h" + +namespace mlir { +namespace LLVM { + +/// Create a constant string location from the MLIR Location information. +llvm::Constant *createSourceLocStrFromLocation(Location loc, + llvm::OpenMPIRBuilder &builder, + StringRef name, + uint32_t &strLen); + +/// Create a constant string representing the mapping information extracted from +/// the MLIR location information. +llvm::Constant *createMappingInformation(Location loc, + llvm::OpenMPIRBuilder &builder); + +} // namespace LLVM +} // namespace mlir + +#endif // MLIR_TARGET_LLVMIR_DIALECT_UTILS_H diff --git a/mlir/lib/Target/LLVMIR/CMakeLists.txt b/mlir/lib/Target/LLVMIR/CMakeLists.txt --- a/mlir/lib/Target/LLVMIR/CMakeLists.txt +++ b/mlir/lib/Target/LLVMIR/CMakeLists.txt @@ -19,6 +19,7 @@ LoopAnnotationTranslation.cpp ModuleTranslation.cpp TypeToLLVM.cpp + Dialect/Utils.cpp ADDITIONAL_HEADER_DIRS ${MLIR_MAIN_INCLUDE_DIR}/mlir/Target/LLVMIR 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 @@ -18,6 +18,7 @@ #include "mlir/IR/BuiltinOps.h" #include "mlir/IR/Operation.h" #include "mlir/Support/LLVM.h" +#include "mlir/Target/LLVMIR/Dialect/Utils.h" #include "mlir/Target/LLVMIR/ModuleTranslation.h" #include "llvm/ADT/TypeSwitch.h" @@ -46,23 +47,6 @@ /// Default value for the device id static constexpr int64_t kDefaultDevice = -1; -/// Create a constant string location from the MLIR Location information. -static llvm::Constant *createSourceLocStrFromLocation(Location loc, - OpenACCIRBuilder &builder, - StringRef name, - uint32_t &strLen) { - if (auto fileLoc = loc.dyn_cast()) { - StringRef fileName = fileLoc.getFilename(); - unsigned lineNo = fileLoc.getLine(); - unsigned colNo = fileLoc.getColumn(); - return builder.getOrCreateSrcLocStr(name, fileName, lineNo, colNo, strLen); - } - std::string locStr; - llvm::raw_string_ostream locOS(locStr); - locOS << loc; - return builder.getOrCreateSrcLocStr(locOS.str(), strLen); -} - /// Create the location struct from the operation location information. static llvm::Value *createSourceLocationInfo(OpenACCIRBuilder &builder, Operation *op) { @@ -70,24 +54,11 @@ auto funcOp = op->getParentOfType(); StringRef funcName = funcOp ? funcOp.getName() : "unknown"; uint32_t strLen; - llvm::Constant *locStr = - createSourceLocStrFromLocation(loc, builder, funcName, strLen); + llvm::Constant *locStr = mlir::LLVM::createSourceLocStrFromLocation( + loc, builder, funcName, strLen); return builder.getOrCreateIdent(locStr, strLen); } -/// Create a constant string representing the mapping information extracted from -/// the MLIR location information. -static llvm::Constant *createMappingInformation(Location loc, - OpenACCIRBuilder &builder) { - uint32_t strLen; - if (auto nameLoc = loc.dyn_cast()) { - StringRef name = nameLoc.getName(); - return createSourceLocStrFromLocation(nameLoc.getChildLoc(), builder, name, - strLen); - } - return createSourceLocStrFromLocation(loc, builder, "unknown", strLen); -} - /// Return the runtime function used to lower the given operation. static llvm::Function *getAssociatedFunction(OpenACCIRBuilder &builder, Operation *op) { @@ -107,19 +78,6 @@ 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 @@ -153,7 +111,7 @@ } else if (data.getType().isa()) { dataPtrBase = dataValue; dataPtr = dataValue; - dataSize = getSizeInBytes(builder, dataValue); + dataSize = accBuilder->getSizeInBytes(dataValue); } else { return op->emitOpError() << "Data operand must be legalized before translation." @@ -185,7 +143,7 @@ flags.push_back(operandFlag); llvm::Constant *mapName = - createMappingInformation(data.getLoc(), *accBuilder); + mlir::LLVM::createMappingInformation(data.getLoc(), *accBuilder); names.push_back(mapName); ++index; } 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 @@ -15,10 +15,12 @@ #include "mlir/IR/IRMapping.h" #include "mlir/IR/Operation.h" #include "mlir/Support/LLVM.h" +#include "mlir/Target/LLVMIR/Dialect/Utils.h" #include "mlir/Target/LLVMIR/ModuleTranslation.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/TypeSwitch.h" +#include "llvm/Frontend/OpenMP/OMPConstants.h" #include "llvm/Frontend/OpenMP/OMPIRBuilder.h" #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/IRBuilder.h" @@ -1325,6 +1327,191 @@ 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); + + 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 { + 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 = + mlir::LLVM::createMappingInformation(mapOp.getLoc(), *ompBuilder); + mapNames.push_back(mapName); + ++index; + } + + return success(); +} + +static LogicalResult +convertOmpTargetData(Operation *op, llvm::IRBuilderBase &builder, + LLVM::ModuleTranslation &moduleTranslation) { + unsigned numMapOperands; + llvm::Function *mapperFunc; + llvm::Value *ifCond = nullptr; + int64_t deviceID = llvm::omp::OMP_DEVICEID_UNDEF; + SmallVector mapOperands; + ArrayAttr mapTypes; + + llvm::OpenMPIRBuilder *ompBuilder = moduleTranslation.getOpenMPBuilder(); + + LogicalResult result = + llvm::TypeSwitch(op) + .Case([&](omp::DataOp dataOp) { + if (dataOp.getUseDeviceAddr().size() || + dataOp.getUseDevicePtr().size()) + return failure(); + + if (auto ifExprVar = dataOp.getIfExpr()) + ifCond = moduleTranslation.lookupValue(ifExprVar); + + if (auto devId = dataOp.getDevice()) + if (auto constOp = mlir::dyn_cast( + devId.getDefiningOp())) + if (auto intAttr = + constOp.getValue().dyn_cast()) + deviceID = intAttr.getInt(); + + numMapOperands = dataOp.getMapOperands().size(); + mapOperands = dataOp.getMapOperands(); + mapTypes = dataOp.getMapTypes(); + return success(); + }) + .Case([&](omp::EnterDataOp enterDataOp) { + if (enterDataOp.getNowait()) + return failure(); + + if (auto ifExprVar = enterDataOp.getIfExpr()) + ifCond = moduleTranslation.lookupValue(ifExprVar); + + if (auto devId = enterDataOp.getDevice()) + if (auto constOp = mlir::dyn_cast( + devId.getDefiningOp())) + if (auto intAttr = + constOp.getValue().dyn_cast()) + deviceID = intAttr.getInt(); + + numMapOperands = enterDataOp.getMapOperands().size(); + mapOperands = enterDataOp.getMapOperands(); + mapTypes = enterDataOp.getMapTypes(); + mapperFunc = ompBuilder->getOrCreateRuntimeFunctionPtr( + llvm::omp::OMPRTL___tgt_target_data_begin_mapper); + return success(); + }) + .Case([&](omp::ExitDataOp exitDataOp) { + if (exitDataOp.getNowait()) + return failure(); + + if (auto ifExprVar = exitDataOp.getIfExpr()) + ifCond = moduleTranslation.lookupValue(ifExprVar); + + if (auto devId = exitDataOp.getDevice()) + if (auto constOp = mlir::dyn_cast( + devId.getDefiningOp())) + if (auto intAttr = + constOp.getValue().dyn_cast()) + deviceID = intAttr.getInt(); + + numMapOperands = exitDataOp.getMapOperands().size(); + mapOperands = exitDataOp.getMapOperands(); + mapTypes = exitDataOp.getMapTypes(); + mapperFunc = ompBuilder->getOrCreateRuntimeFunctionPtr( + llvm::omp::OMPRTL___tgt_target_data_end_mapper); + return success(); + }) + .Default([&](Operation *op) { + return op->emitError("unsupported OpenMP operation: ") + << op->getName(); + }); + + 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(); + 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); + }; + + builder.restoreIP(ompBuilder->createTargetData( + ompLoc, builder.saveIP(), isa(op), mapTypeFlags, mapNames, + mapperAllocas, mapperFunc, deviceID, ifCond, processMapOpCB, bodyCB)); + + if (failed(processMapOpStatus)) + return processMapOpStatus; + return bodyGenStatus; +} + namespace { /// Implementation of the dialect interface that converts operations belonging @@ -1439,6 +1626,9 @@ .Case([&](omp::ThreadprivateOp) { return convertOmpThreadprivate(*op, builder, moduleTranslation); }) + .Case([&](auto op) { + return convertOmpTargetData(op, builder, moduleTranslation); + }) .Default([&](Operation *inst) { return inst->emitError("unsupported OpenMP operation: ") << inst->getName(); diff --git a/mlir/lib/Target/LLVMIR/Dialect/Utils.cpp b/mlir/lib/Target/LLVMIR/Dialect/Utils.cpp new file mode 100644 --- /dev/null +++ b/mlir/lib/Target/LLVMIR/Dialect/Utils.cpp @@ -0,0 +1,41 @@ +//===- Utils.cpp - General Utils for translating MLIR dialect to LLVM IR---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines general utilities for MLIR Dialect translations to LLVM IR. +// +//===----------------------------------------------------------------------===// + +#include "mlir/Target/LLVMIR/Dialect/Utils.h" + +llvm::Constant * +mlir::LLVM::createSourceLocStrFromLocation(Location loc, + llvm::OpenMPIRBuilder &builder, + StringRef name, uint32_t &strLen) { + if (auto fileLoc = loc.dyn_cast()) { + StringRef fileName = fileLoc.getFilename(); + unsigned lineNo = fileLoc.getLine(); + unsigned colNo = fileLoc.getColumn(); + return builder.getOrCreateSrcLocStr(name, fileName, lineNo, colNo, strLen); + } + std::string locStr; + llvm::raw_string_ostream locOS(locStr); + locOS << loc; + return builder.getOrCreateSrcLocStr(locOS.str(), strLen); +} + +llvm::Constant * +mlir::LLVM::createMappingInformation(Location loc, + llvm::OpenMPIRBuilder &builder) { + uint32_t strLen; + if (auto nameLoc = loc.dyn_cast()) { + StringRef name = nameLoc.getName(); + return createSourceLocStrFromLocation(nameLoc.getChildLoc(), builder, name, + strLen); + } + return createSourceLocStrFromLocation(loc, builder, "unknown", strLen); +}