23 #include "llvm/ADT/TypeSwitch.h" 24 #include "llvm/Frontend/OpenMP/OMPConstants.h" 25 #include "llvm/Support/FormatVariadic.h" 54 if (
auto fileLoc = loc.
dyn_cast<FileLineColLoc>()) {
55 StringRef fileName = fileLoc.getFilename();
56 unsigned lineNo = fileLoc.getLine();
57 unsigned colNo = fileLoc.getColumn();
58 return builder.getOrCreateSrcLocStr(name, fileName, lineNo, colNo, strLen);
61 llvm::raw_string_ostream locOS(locStr);
63 return builder.getOrCreateSrcLocStr(locOS.str(), strLen);
71 StringRef funcName = funcOp ? funcOp.getName() :
"unknown";
75 return builder.getOrCreateIdent(locStr, strLen);
83 if (
auto nameLoc = loc.
dyn_cast<NameLoc>()) {
84 StringRef name = nameLoc.getName();
95 .Case([&](acc::EnterDataOp) {
96 return builder.getOrCreateRuntimeFunctionPtr(
97 llvm::omp::OMPRTL___tgt_target_data_begin_mapper);
99 .Case([&](acc::ExitDataOp) {
100 return builder.getOrCreateRuntimeFunctionPtr(
101 llvm::omp::OMPRTL___tgt_target_data_end_mapper);
103 .Case([&](acc::UpdateOp) {
104 return builder.getOrCreateRuntimeFunctionPtr(
105 llvm::omp::OMPRTL___tgt_target_data_update_mapper);
107 llvm_unreachable(
"Unknown OpenACC operation");
112 llvm::Value *basePtr) {
113 llvm::LLVMContext &ctx = builder.getContext();
115 llvm::Constant::getNullValue(basePtr->getType()->getPointerTo());
116 llvm::Value *sizeGep =
117 builder.CreateGEP(basePtr->getType(), null, builder.getInt32(1));
118 llvm::Value *sizePtrToInt =
119 builder.CreatePtrToInt(sizeGep, llvm::Type::getInt64Ty(ctx));
131 struct OpenACCIRBuilder::MapperAllocas &mapperAllocas) {
133 llvm::LLVMContext &ctx = builder.getContext();
134 auto *i8PtrTy = llvm::Type::getInt8PtrTy(ctx);
135 auto *arrI8PtrTy = llvm::ArrayType::get(i8PtrTy, totalNbOperand);
136 auto *i64Ty = llvm::Type::getInt64Ty(ctx);
137 auto *arrI64Ty = llvm::ArrayType::get(i64Ty, totalNbOperand);
139 for (
Value data : operands) {
140 llvm::Value *dataValue = moduleTranslation.
lookupValue(data);
142 llvm::Value *dataPtrBase;
143 llvm::Value *dataPtr;
144 llvm::Value *dataSize;
154 dataPtrBase = dataValue;
159 <<
"Data operand must be legalized before translation." 160 <<
"Unsupported type: " << data.getType();
165 llvm::Value *ptrBaseGEP = builder.CreateInBoundsGEP(
166 arrI8PtrTy, mapperAllocas.ArgsBase,
167 {builder.getInt32(0), builder.getInt32(index)});
168 llvm::Value *ptrBaseCast = builder.CreateBitCast(
169 ptrBaseGEP, dataPtrBase->getType()->getPointerTo());
170 builder.CreateStore(dataPtrBase, ptrBaseCast);
173 llvm::Value *ptrGEP = builder.CreateInBoundsGEP(
174 arrI8PtrTy, mapperAllocas.Args,
175 {builder.getInt32(0), builder.getInt32(index)});
176 llvm::Value *ptrCast =
177 builder.CreateBitCast(ptrGEP, dataPtr->getType()->getPointerTo());
178 builder.CreateStore(dataPtr, ptrCast);
181 llvm::Value *sizeGEP = builder.CreateInBoundsGEP(
182 arrI64Ty, mapperAllocas.ArgSizes,
183 {builder.getInt32(0), builder.getInt32(index)});
184 builder.CreateStore(dataSize, sizeGEP);
186 flags.push_back(operandFlag);
189 names.push_back(mapName);
201 struct OpenACCIRBuilder::MapperAllocas &mapperAllocas) {
208 op.createOperands(), op.getNumDataOperands(),
214 op.copyinOperands(), op.getNumDataOperands(),
228 struct OpenACCIRBuilder::MapperAllocas &mapperAllocas) {
235 op.deleteOperands(), op.getNumDataOperands(),
241 op.copyoutOperands(), op.getNumDataOperands(),
255 struct OpenACCIRBuilder::MapperAllocas &mapperAllocas) {
261 names, index, mapperAllocas)))
266 op.deviceOperands(), op.getNumDataOperands(),
280 llvm::IRBuilderBase &builder,
282 llvm::LLVMContext &ctx = builder.getContext();
283 auto enclosingFuncOp = op.getOperation()->getParentOfType<LLVM::LLVMFuncOp>();
284 llvm::Function *enclosingFunction =
291 llvm::Function *beginMapperFunc = accBuilder->getOrCreateRuntimeFunctionPtr(
292 llvm::omp::OMPRTL___tgt_target_data_begin_mapper);
294 llvm::Function *endMapperFunc = accBuilder->getOrCreateRuntimeFunctionPtr(
295 llvm::omp::OMPRTL___tgt_target_data_end_mapper);
298 unsigned totalNbOperand = op.getNumDataOperands();
300 struct OpenACCIRBuilder::MapperAllocas mapperAllocas;
301 OpenACCIRBuilder::InsertPointTy allocaIP(
302 &enclosingFunction->getEntryBlock(),
303 enclosingFunction->getEntryBlock().getFirstInsertionPt());
304 accBuilder->createMapperAllocas(builder.saveIP(), allocaIP, totalNbOperand,
315 names, index, mapperAllocas)))
319 builder, moduleTranslation, op, op.copyinOperands(), totalNbOperand,
326 op.copyinReadonlyOperands(), totalNbOperand,
332 builder, moduleTranslation, op, op.copyoutOperands(), totalNbOperand,
339 op.copyoutZeroOperands(), totalNbOperand,
345 op.createOperands(), totalNbOperand,
353 op.createZeroOperands(), totalNbOperand,
359 op.presentOperands(), totalNbOperand,
364 llvm::GlobalVariable *maptypes =
365 accBuilder->createOffloadMaptypes(flags,
".offload_maptypes");
366 llvm::Value *maptypesArg = builder.CreateConstInBoundsGEP2_32(
367 llvm::ArrayType::get(llvm::Type::getInt64Ty(ctx), totalNbOperand),
370 llvm::GlobalVariable *mapnames =
371 accBuilder->createOffloadMapnames(names,
".offload_mapnames");
372 llvm::Value *mapnamesArg = builder.CreateConstInBoundsGEP2_32(
373 llvm::ArrayType::get(llvm::Type::getInt8PtrTy(ctx), totalNbOperand),
377 accBuilder->emitMapperCall(builder.saveIP(), beginMapperFunc, srcLocInfo,
378 maptypesArg, mapnamesArg, mapperAllocas,
382 llvm::BasicBlock *entryBlock =
nullptr;
384 for (
Block &bb : op.region()) {
385 llvm::BasicBlock *llvmBB = llvm::BasicBlock::Create(
386 ctx,
"acc.data", builder.GetInsertBlock()->getParent());
387 if (entryBlock ==
nullptr)
389 moduleTranslation.
mapBlock(&bb, llvmBB);
392 auto afterDataRegion = builder.saveIP();
394 llvm::BranchInst *sourceTerminator = builder.CreateBr(entryBlock);
396 builder.restoreIP(afterDataRegion);
397 llvm::BasicBlock *endDataBlock = llvm::BasicBlock::Create(
398 ctx,
"acc.end_data", builder.GetInsertBlock()->getParent());
402 for (
Block *bb : blocks) {
403 llvm::BasicBlock *llvmBB = moduleTranslation.
lookupBlock(bb);
404 if (bb->isEntryBlock()) {
405 assert(sourceTerminator->getNumSuccessors() == 1 &&
406 "provided entry block has multiple successors");
407 sourceTerminator->setSuccessor(0, llvmBB);
411 moduleTranslation.
convertBlock(*bb, bb->isEntryBlock(), builder))) {
415 if (isa<acc::TerminatorOp, acc::YieldOp>(bb->getTerminator()))
416 builder.CreateBr(endDataBlock);
420 builder.SetInsertPoint(endDataBlock);
421 accBuilder->emitMapperCall(builder.saveIP(), endMapperFunc, srcLocInfo,
422 maptypesArg, mapnamesArg, mapperAllocas,
429 template <
typename OpTy>
433 auto enclosingFuncOp =
434 op.getOperation()->template getParentOfType<LLVM::LLVMFuncOp>();
435 llvm::Function *enclosingFunction =
444 unsigned totalNbOperand = op.getNumDataOperands();
446 llvm::LLVMContext &ctx = builder.getContext();
448 struct OpenACCIRBuilder::MapperAllocas mapperAllocas;
449 OpenACCIRBuilder::InsertPointTy allocaIP(
450 &enclosingFunction->getEntryBlock(),
451 enclosingFunction->getEntryBlock().getFirstInsertionPt());
452 accBuilder->createMapperAllocas(builder.saveIP(), allocaIP, totalNbOperand,
462 llvm::GlobalVariable *maptypes =
463 accBuilder->createOffloadMaptypes(flags,
".offload_maptypes");
464 llvm::Value *maptypesArg = builder.CreateConstInBoundsGEP2_32(
465 llvm::ArrayType::get(llvm::Type::getInt64Ty(ctx), totalNbOperand),
468 llvm::GlobalVariable *mapnames =
469 accBuilder->createOffloadMapnames(names,
".offload_mapnames");
470 llvm::Value *mapnamesArg = builder.CreateConstInBoundsGEP2_32(
471 llvm::ArrayType::get(llvm::Type::getInt8PtrTy(ctx), totalNbOperand),
474 accBuilder->emitMapperCall(builder.saveIP(), mapperFunc, srcLocInfo,
475 maptypesArg, mapnamesArg, mapperAllocas,
485 class OpenACCDialectLLVMIRTranslationInterface
493 convertOperation(
Operation *op, llvm::IRBuilderBase &builder,
501 LogicalResult OpenACCDialectLLVMIRTranslationInterface::convertOperation(
502 Operation *op, llvm::IRBuilderBase &builder,
506 .Case([&](acc::DataOp dataOp) {
509 .Case([&](acc::EnterDataOp enterDataOp) {
510 return convertStandaloneDataOp<acc::EnterDataOp>(enterDataOp, builder,
513 .Case([&](acc::ExitDataOp exitDataOp) {
514 return convertStandaloneDataOp<acc::ExitDataOp>(exitDataOp, builder,
517 .Case([&](acc::UpdateOp updateOp) {
518 return convertStandaloneDataOp<acc::UpdateOp>(updateOp, builder,
521 .Case<acc::TerminatorOp, acc::YieldOp>([](
auto op) {
525 "unexpected OpenACC terminator with operands");
529 return op->
emitError(
"unsupported OpenACC operation: ")
535 registry.
insert<acc::OpenACCDialect>();
537 dialect->addInterfaces<OpenACCDialectLLVMIRTranslationInterface>();
Include the generated interface declarations.
Operation is a basic unit of execution within MLIR.
static LogicalResult processDataOperands(llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation, acc::EnterDataOp op, SmallVector< uint64_t > &flags, SmallVectorImpl< llvm::Constant *> &names, struct OpenACCIRBuilder::MapperAllocas &mapperAllocas)
Process data operands from acc::EnterDataOp.
Block represents an ordered list of Operations.
static constexpr unsigned kPtrBasePosInDataDescriptor
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value...
unsigned getNumOperands()
void appendDialectRegistry(const DialectRegistry ®istry)
Append the contents of the given dialect registry to the registry associated with this context...
static llvm::Constant * createSourceLocStrFromLocation(Location loc, OpenACCIRBuilder &builder, StringRef name, uint32_t &strLen)
Create a constant string location from the MLIR Location information.
static LogicalResult convertStandaloneDataOp(OpTy &op, llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation)
Converts an OpenACC standalone data operation into LLVM IR.
LogicalResult convertBlock(Block &bb, bool ignoreArguments, llvm::IRBuilderBase &builder)
Translates the contents of the given block to LLVM IR using this translator.
llvm::BasicBlock * lookupBlock(Block *block) const
Finds an LLVM IR basic block that corresponds to the given MLIR block.
OpTy getParentOfType()
Return the closest surrounding parent operation that is of type 'OpTy'.
void mapBlock(Block *mlir, llvm::BasicBlock *llvm)
Stores the mapping between an MLIR block and LLVM IR basic block.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Implementation class for module translation.
llvm::OpenMPIRBuilder * getOpenMPBuilder()
Returns the OpenMP IR builder associated with the LLVM IR module being constructed.
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
static constexpr unsigned kPtrPosInDataDescriptor
void addExtension(std::unique_ptr< DialectExtensionBase > extension)
Add the given extension to the registry.
This class represents an efficient way to signal success or failure.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
static llvm::Function * getAssociatedFunction(OpenACCIRBuilder &builder, Operation *op)
Return the runtime function used to lower the given operation.
Base class for dialect interfaces providing translation to LLVM IR.
static LogicalResult processOperands(llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation, Operation *op, ValueRange operands, unsigned totalNbOperand, uint64_t operandFlag, SmallVector< uint64_t > &flags, SmallVectorImpl< llvm::Constant *> &names, unsigned &index, struct OpenACCIRBuilder::MapperAllocas &mapperAllocas)
Extract pointer, size and mapping information from operands to populate the future functions argument...
static constexpr uint64_t kDeviceCopyinFlag
static llvm::Value * getSizeInBytes(llvm::IRBuilderBase &builder, llvm::Value *basePtr)
Computes the size of type in bytes.
Location getLoc()
The source location the operation was defined or derived from.
static constexpr uint64_t kPresentFlag
llvm::Value * lookupValue(Value value) const
Finds an LLVM IR value corresponding to the given MLIR value.
static llvm::Constant * createMappingInformation(Location loc, OpenACCIRBuilder &builder)
Create a constant string representing the mapping information extracted from the MLIR location inform...
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
static LogicalResult convertDataOp(acc::DataOp &op, llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation)
Converts an OpenACC data operation into LLVM IR.
static constexpr unsigned kSizePosInDataDescriptor
llvm::Function * lookupFunction(StringRef name) const
Finds an LLVM IR function by its name.
static bool isValid(Value descriptor)
Check whether the type is a valid data descriptor.
SetVector< Block * > getTopologicallySortedBlocks(Region ®ion)
Get a topologically sorted list of blocks of the given region.
The DialectRegistry maps a dialect namespace to a constructor for the matching dialect.
static constexpr uint64_t kCopyFlag
MLIRContext is the top-level object for a collection of MLIR operations.
llvm::OpenMPIRBuilder OpenACCIRBuilder
LLVM dialect pointer type.
LLVMTranslationDialectInterface(Dialect *dialect)
static constexpr uint64_t kCreateFlag
Flag values are extracted from openmp/libomptarget/include/omptarget.h and mapped to corresponding Op...
InFlightDiagnostic emitOpError(const Twine &message={})
Emit an error with the op name prefixed, like "'dim' op " which is convenient for verifiers...
void registerOpenACCDialectTranslation(DialectRegistry ®istry)
Register the OpenACC dialect and the translation to the LLVM IR in the given registry;.
static llvm::Value * createSourceLocationInfo(OpenACCIRBuilder &builder, Operation *op)
Create the location struct from the operation location information.
OperationName getName()
The name of an operation is the key identifier for it.
InFlightDiagnostic emitError(const Twine &message={})
Emit an error about fatal conditions with this operation, reporting up to any diagnostic handlers tha...
This class provides an abstraction over the different types of ranges over Values.
static constexpr int64_t kDefaultDevice
Default value for the device id.
static constexpr uint64_t kHoldFlag
static constexpr uint64_t kHostCopyoutFlag
static constexpr uint64_t kDeleteFlag