MLIR 22.0.0git
OpenACCToLLVMIRTranslation.cpp
Go to the documentation of this file.
1//===- OpenACCToLLVMIRTranslation.cpp -------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements a translation between the MLIR OpenACC dialect and LLVM
10// IR.
11//
12//===----------------------------------------------------------------------===//
13
18#include "mlir/IR/Operation.h"
19#include "mlir/Support/LLVM.h"
22
23#include "llvm/ADT/TypeSwitch.h"
24#include "llvm/Frontend/OpenMP/OMPConstants.h"
25
26using namespace mlir;
27
28using OpenACCIRBuilder = llvm::OpenMPIRBuilder;
29
30//===----------------------------------------------------------------------===//
31// Utility functions
32//===----------------------------------------------------------------------===//
33
34/// Flag values are extracted from openmp/libomptarget/include/omptarget.h and
35/// mapped to corresponding OpenACC flags.
36static constexpr uint64_t kCreateFlag = 0x000;
37static constexpr uint64_t kDeviceCopyinFlag = 0x001;
38static constexpr uint64_t kHostCopyoutFlag = 0x002;
39static constexpr uint64_t kPresentFlag = 0x1000;
40static constexpr uint64_t kDeleteFlag = 0x008;
41// Runtime extension to implement the OpenACC second reference counter.
42static constexpr uint64_t kHoldFlag = 0x2000;
43
44/// Default value for the device id
45static constexpr int64_t kDefaultDevice = -1;
46
47/// Create the location struct from the operation location information.
48static llvm::Value *createSourceLocationInfo(OpenACCIRBuilder &builder,
49 Operation *op) {
50 auto loc = op->getLoc();
51 auto funcOp = op->getParentOfType<LLVM::LLVMFuncOp>();
52 StringRef funcName = funcOp ? funcOp.getName() : "unknown";
53 uint32_t strLen;
54 llvm::Constant *locStr = mlir::LLVM::createSourceLocStrFromLocation(
55 loc, builder, funcName, strLen);
56 return builder.getOrCreateIdent(locStr, strLen);
57}
58
59/// Return the runtime function used to lower the given operation.
60static llvm::Function *getAssociatedFunction(OpenACCIRBuilder &builder,
61 Operation *op) {
63 .Case([&](acc::EnterDataOp) {
64 return builder.getOrCreateRuntimeFunctionPtr(
65 llvm::omp::OMPRTL___tgt_target_data_begin_mapper);
66 })
67 .Case([&](acc::ExitDataOp) {
68 return builder.getOrCreateRuntimeFunctionPtr(
69 llvm::omp::OMPRTL___tgt_target_data_end_mapper);
70 })
71 .Case([&](acc::UpdateOp) {
72 return builder.getOrCreateRuntimeFunctionPtr(
73 llvm::omp::OMPRTL___tgt_target_data_update_mapper);
74 });
75 llvm_unreachable("Unknown OpenACC operation");
76}
77
78/// Extract pointer, size and mapping information from operands
79/// to populate the future functions arguments.
80static LogicalResult
81processOperands(llvm::IRBuilderBase &builder,
82 LLVM::ModuleTranslation &moduleTranslation, Operation *op,
83 ValueRange operands, unsigned totalNbOperand,
84 uint64_t operandFlag, SmallVector<uint64_t> &flags,
86 struct OpenACCIRBuilder::MapperAllocas &mapperAllocas) {
87 OpenACCIRBuilder *accBuilder = moduleTranslation.getOpenMPBuilder();
88 llvm::LLVMContext &ctx = builder.getContext();
89 auto *i8PtrTy = llvm::PointerType::getUnqual(ctx);
90 auto *arrI8PtrTy = llvm::ArrayType::get(i8PtrTy, totalNbOperand);
91 auto *i64Ty = llvm::Type::getInt64Ty(ctx);
92 auto *arrI64Ty = llvm::ArrayType::get(i64Ty, totalNbOperand);
93
94 for (Value data : operands) {
95 llvm::Value *dataValue = moduleTranslation.lookupValue(data);
96
97 llvm::Value *dataPtrBase;
98 llvm::Value *dataPtr;
99 llvm::Value *dataSize;
100
101 if (isa<LLVM::LLVMPointerType>(data.getType())) {
102 dataPtrBase = dataValue;
103 dataPtr = dataValue;
104 dataSize = accBuilder->getSizeInBytes(dataValue);
105 } else {
106 return op->emitOpError()
107 << "Data operand must be legalized before translation."
108 << "Unsupported type: " << data.getType();
109 }
110
111 // Store base pointer extracted from operand into the i-th position of
112 // argBase.
113 llvm::Value *ptrBaseGEP = builder.CreateInBoundsGEP(
114 arrI8PtrTy, mapperAllocas.ArgsBase,
115 {builder.getInt32(0), builder.getInt32(index)});
116 builder.CreateStore(dataPtrBase, ptrBaseGEP);
117
118 // Store pointer extracted from operand into the i-th position of args.
119 llvm::Value *ptrGEP = builder.CreateInBoundsGEP(
120 arrI8PtrTy, mapperAllocas.Args,
121 {builder.getInt32(0), builder.getInt32(index)});
122 builder.CreateStore(dataPtr, ptrGEP);
123
124 // Store size extracted from operand into the i-th position of argSizes.
125 llvm::Value *sizeGEP = builder.CreateInBoundsGEP(
126 arrI64Ty, mapperAllocas.ArgSizes,
127 {builder.getInt32(0), builder.getInt32(index)});
128 builder.CreateStore(dataSize, sizeGEP);
129
130 flags.push_back(operandFlag);
131 llvm::Constant *mapName =
132 mlir::LLVM::createMappingInformation(data.getLoc(), *accBuilder);
133 names.push_back(mapName);
134 ++index;
135 }
136 return success();
137}
138
139/// Process data operands from acc::EnterDataOp
140static LogicalResult
141processDataOperands(llvm::IRBuilderBase &builder,
142 LLVM::ModuleTranslation &moduleTranslation,
143 acc::EnterDataOp op, SmallVector<uint64_t> &flags,
145 struct OpenACCIRBuilder::MapperAllocas &mapperAllocas) {
146 // TODO add `create_zero` and `attach` operands
147
148 unsigned index = 0;
149
150 // Create operands are handled as `alloc` call.
151 // Copyin operands are handled as `to` call.
152 llvm::SmallVector<mlir::Value> create, copyin;
153 for (mlir::Value dataOp : op.getDataClauseOperands()) {
154 if (auto createOp = dataOp.getDefiningOp<acc::CreateOp>()) {
155 create.push_back(createOp.getVarPtr());
156 } else if (auto copyinOp = mlir::dyn_cast_or_null<acc::CopyinOp>(
157 dataOp.getDefiningOp())) {
158 copyin.push_back(copyinOp.getVarPtr());
159 }
160 }
161
162 auto nbTotalOperands = create.size() + copyin.size();
163
164 // Create operands are handled as `alloc` call.
165 if (failed(processOperands(builder, moduleTranslation, op, create,
166 nbTotalOperands, kCreateFlag, flags, names, index,
167 mapperAllocas)))
168 return failure();
169
170 // Copyin operands are handled as `to` call.
171 if (failed(processOperands(builder, moduleTranslation, op, copyin,
172 nbTotalOperands, kDeviceCopyinFlag, flags, names,
173 index, mapperAllocas)))
174 return failure();
175
176 return success();
177}
178
179/// Process data operands from acc::ExitDataOp
180static LogicalResult
181processDataOperands(llvm::IRBuilderBase &builder,
182 LLVM::ModuleTranslation &moduleTranslation,
183 acc::ExitDataOp op, SmallVector<uint64_t> &flags,
185 struct OpenACCIRBuilder::MapperAllocas &mapperAllocas) {
186 // TODO add `detach` operands
187
188 unsigned index = 0;
189
190 llvm::SmallVector<mlir::Value> deleteOperands, copyoutOperands;
191 for (mlir::Value dataOp : op.getDataClauseOperands()) {
192 if (auto devicePtrOp = mlir::dyn_cast_or_null<acc::GetDevicePtrOp>(
193 dataOp.getDefiningOp())) {
194 for (auto &u : devicePtrOp.getAccPtr().getUses()) {
195 if (mlir::dyn_cast_or_null<acc::DeleteOp>(u.getOwner()))
196 deleteOperands.push_back(devicePtrOp.getVarPtr());
197 else if (mlir::dyn_cast_or_null<acc::CopyoutOp>(u.getOwner()))
198 copyoutOperands.push_back(devicePtrOp.getVarPtr());
199 }
200 }
201 }
202
203 auto nbTotalOperands = deleteOperands.size() + copyoutOperands.size();
204
205 // Delete operands are handled as `delete` call.
206 if (failed(processOperands(builder, moduleTranslation, op, deleteOperands,
207 nbTotalOperands, kDeleteFlag, flags, names, index,
208 mapperAllocas)))
209 return failure();
210
211 // Copyout operands are handled as `from` call.
212 if (failed(processOperands(builder, moduleTranslation, op, copyoutOperands,
213 nbTotalOperands, kHostCopyoutFlag, flags, names,
214 index, mapperAllocas)))
215 return failure();
216
217 return success();
218}
219
220/// Process data operands from acc::UpdateOp
221static LogicalResult
222processDataOperands(llvm::IRBuilderBase &builder,
223 LLVM::ModuleTranslation &moduleTranslation,
224 acc::UpdateOp op, SmallVector<uint64_t> &flags,
226 struct OpenACCIRBuilder::MapperAllocas &mapperAllocas) {
227 unsigned index = 0;
228
229 // Host operands are handled as `from` call.
230 // Device operands are handled as `to` call.
232 for (mlir::Value dataOp : op.getDataClauseOperands()) {
233 if (auto getDevicePtrOp = mlir::dyn_cast_or_null<acc::GetDevicePtrOp>(
234 dataOp.getDefiningOp())) {
235 from.push_back(getDevicePtrOp.getVarPtr());
236 } else if (auto updateDeviceOp =
237 mlir::dyn_cast_or_null<acc::UpdateDeviceOp>(
238 dataOp.getDefiningOp())) {
239 to.push_back(updateDeviceOp.getVarPtr());
240 }
241 }
242
243 if (failed(processOperands(builder, moduleTranslation, op, from, from.size(),
244 kHostCopyoutFlag, flags, names, index,
245 mapperAllocas)))
246 return failure();
247
248 if (failed(processOperands(builder, moduleTranslation, op, to, to.size(),
249 kDeviceCopyinFlag, flags, names, index,
250 mapperAllocas)))
251 return failure();
252 return success();
253}
254
255//===----------------------------------------------------------------------===//
256// Conversion functions
257//===----------------------------------------------------------------------===//
258
259/// Converts an OpenACC data operation into LLVM IR.
260static LogicalResult convertDataOp(acc::DataOp &op,
261 llvm::IRBuilderBase &builder,
262 LLVM::ModuleTranslation &moduleTranslation) {
263 llvm::LLVMContext &ctx = builder.getContext();
264 auto enclosingFuncOp = op.getOperation()->getParentOfType<LLVM::LLVMFuncOp>();
265 llvm::Function *enclosingFunction =
266 moduleTranslation.lookupFunction(enclosingFuncOp.getName());
267
268 OpenACCIRBuilder *accBuilder = moduleTranslation.getOpenMPBuilder();
269
270 llvm::Value *srcLocInfo = createSourceLocationInfo(*accBuilder, op);
271
272 llvm::Function *beginMapperFunc = accBuilder->getOrCreateRuntimeFunctionPtr(
273 llvm::omp::OMPRTL___tgt_target_data_begin_mapper);
274
275 llvm::Function *endMapperFunc = accBuilder->getOrCreateRuntimeFunctionPtr(
276 llvm::omp::OMPRTL___tgt_target_data_end_mapper);
277
278 // Number of arguments in the data operation.
279 unsigned totalNbOperand = op.getNumDataOperands();
280
281 struct OpenACCIRBuilder::MapperAllocas mapperAllocas;
282 OpenACCIRBuilder::InsertPointTy allocaIP(
283 &enclosingFunction->getEntryBlock(),
284 enclosingFunction->getEntryBlock().getFirstInsertionPt());
285 accBuilder->createMapperAllocas(builder.saveIP(), allocaIP, totalNbOperand,
286 mapperAllocas);
287
290 unsigned index = 0;
291
292 // TODO handle no_create, deviceptr and attach operands.
293
294 llvm::SmallVector<mlir::Value> copyin, copyout, create, present,
295 deleteOperands;
296 for (mlir::Value dataOp : op.getDataClauseOperands()) {
297 if (auto devicePtrOp = mlir::dyn_cast_or_null<acc::GetDevicePtrOp>(
298 dataOp.getDefiningOp())) {
299 for (auto &u : devicePtrOp.getAccPtr().getUses()) {
300 if (mlir::dyn_cast_or_null<acc::DeleteOp>(u.getOwner())) {
301 deleteOperands.push_back(devicePtrOp.getVarPtr());
302 } else if (mlir::dyn_cast_or_null<acc::CopyoutOp>(u.getOwner())) {
303 // TODO copyout zero currenlty handled as copyout. Update when
304 // extension available.
305 copyout.push_back(devicePtrOp.getVarPtr());
306 }
307 }
308 } else if (auto copyinOp = mlir::dyn_cast_or_null<acc::CopyinOp>(
309 dataOp.getDefiningOp())) {
310 // TODO copyin readonly currenlty handled as copyin. Update when extension
311 // available.
312 copyin.push_back(copyinOp.getVarPtr());
313 } else if (auto createOp = mlir::dyn_cast_or_null<acc::CreateOp>(
314 dataOp.getDefiningOp())) {
315 // TODO create zero currenlty handled as create. Update when extension
316 // available.
317 create.push_back(createOp.getVarPtr());
318 } else if (auto presentOp = mlir::dyn_cast_or_null<acc::PresentOp>(
319 dataOp.getDefiningOp())) {
320 present.push_back(createOp.getVarPtr());
321 }
322 }
323
324 auto nbTotalOperands = copyin.size() + copyout.size() + create.size() +
325 present.size() + deleteOperands.size();
326
327 // Copyin operands are handled as `to` call.
328 if (failed(processOperands(builder, moduleTranslation, op, copyin,
329 nbTotalOperands, kDeviceCopyinFlag | kHoldFlag,
330 flags, names, index, mapperAllocas)))
331 return failure();
332
333 // Delete operands are handled as `delete` call.
334 if (failed(processOperands(builder, moduleTranslation, op, deleteOperands,
335 nbTotalOperands, kDeleteFlag, flags, names, index,
336 mapperAllocas)))
337 return failure();
338
339 // Copyout operands are handled as `from` call.
340 if (failed(processOperands(builder, moduleTranslation, op, copyout,
341 nbTotalOperands, kHostCopyoutFlag | kHoldFlag,
342 flags, names, index, mapperAllocas)))
343 return failure();
344
345 // Create operands are handled as `alloc` call.
346 if (failed(processOperands(builder, moduleTranslation, op, create,
347 nbTotalOperands, kCreateFlag | kHoldFlag, flags,
348 names, index, mapperAllocas)))
349 return failure();
350
351 if (failed(processOperands(builder, moduleTranslation, op, present,
352 nbTotalOperands, kPresentFlag | kHoldFlag, flags,
353 names, index, mapperAllocas)))
354 return failure();
355
356 llvm::GlobalVariable *maptypes =
357 accBuilder->createOffloadMaptypes(flags, ".offload_maptypes");
358 llvm::Value *maptypesArg = builder.CreateConstInBoundsGEP2_32(
359 llvm::ArrayType::get(llvm::Type::getInt64Ty(ctx), totalNbOperand),
360 maptypes, /*Idx0=*/0, /*Idx1=*/0);
361
362 llvm::GlobalVariable *mapnames =
363 accBuilder->createOffloadMapnames(names, ".offload_mapnames");
364 llvm::Value *mapnamesArg = builder.CreateConstInBoundsGEP2_32(
365 llvm::ArrayType::get(llvm::PointerType::getUnqual(ctx), totalNbOperand),
366 mapnames, /*Idx0=*/0, /*Idx1=*/0);
367
368 // Create call to start the data region.
369 accBuilder->emitMapperCall(builder.saveIP(), beginMapperFunc, srcLocInfo,
370 maptypesArg, mapnamesArg, mapperAllocas,
371 kDefaultDevice, totalNbOperand);
372
373 // Convert the region.
374 llvm::BasicBlock *entryBlock = nullptr;
375
376 for (Block &bb : op.getRegion()) {
377 llvm::BasicBlock *llvmBB = llvm::BasicBlock::Create(
378 ctx, "acc.data", builder.GetInsertBlock()->getParent());
379 if (entryBlock == nullptr)
380 entryBlock = llvmBB;
381 moduleTranslation.mapBlock(&bb, llvmBB);
382 }
383
384 auto afterDataRegion = builder.saveIP();
385
386 llvm::BranchInst *sourceTerminator = builder.CreateBr(entryBlock);
387
388 builder.restoreIP(afterDataRegion);
389 llvm::BasicBlock *endDataBlock = llvm::BasicBlock::Create(
390 ctx, "acc.end_data", builder.GetInsertBlock()->getParent());
391
392 SetVector<Block *> blocks = getBlocksSortedByDominance(op.getRegion());
393 for (Block *bb : blocks) {
394 llvm::BasicBlock *llvmBB = moduleTranslation.lookupBlock(bb);
395 if (bb->isEntryBlock()) {
396 assert(sourceTerminator->getNumSuccessors() == 1 &&
397 "provided entry block has multiple successors");
398 sourceTerminator->setSuccessor(0, llvmBB);
399 }
400
401 if (failed(
402 moduleTranslation.convertBlock(*bb, bb->isEntryBlock(), builder))) {
403 return failure();
404 }
405
406 if (isa<acc::TerminatorOp, acc::YieldOp>(bb->getTerminator()))
407 builder.CreateBr(endDataBlock);
408 }
409
410 // Create call to end the data region.
411 builder.SetInsertPoint(endDataBlock);
412 accBuilder->emitMapperCall(builder.saveIP(), endMapperFunc, srcLocInfo,
413 maptypesArg, mapnamesArg, mapperAllocas,
414 kDefaultDevice, totalNbOperand);
415
416 return success();
417}
418
419/// Converts an OpenACC standalone data operation into LLVM IR.
420template <typename OpTy>
421static LogicalResult
422convertStandaloneDataOp(OpTy &op, llvm::IRBuilderBase &builder,
423 LLVM::ModuleTranslation &moduleTranslation) {
424 auto enclosingFuncOp =
425 op.getOperation()->template getParentOfType<LLVM::LLVMFuncOp>();
426 llvm::Function *enclosingFunction =
427 moduleTranslation.lookupFunction(enclosingFuncOp.getName());
428
429 OpenACCIRBuilder *accBuilder = moduleTranslation.getOpenMPBuilder();
430
431 auto *srcLocInfo = createSourceLocationInfo(*accBuilder, op);
432 auto *mapperFunc = getAssociatedFunction(*accBuilder, op);
433
434 // Number of arguments in the enter_data operation.
435 unsigned totalNbOperand = op.getNumDataOperands();
436
437 llvm::LLVMContext &ctx = builder.getContext();
438
439 struct OpenACCIRBuilder::MapperAllocas mapperAllocas;
440 OpenACCIRBuilder::InsertPointTy allocaIP(
441 &enclosingFunction->getEntryBlock(),
442 enclosingFunction->getEntryBlock().getFirstInsertionPt());
443 accBuilder->createMapperAllocas(builder.saveIP(), allocaIP, totalNbOperand,
444 mapperAllocas);
445
448
449 if (failed(processDataOperands(builder, moduleTranslation, op, flags, names,
450 mapperAllocas)))
451 return failure();
452
453 llvm::GlobalVariable *maptypes =
454 accBuilder->createOffloadMaptypes(flags, ".offload_maptypes");
455 llvm::Value *maptypesArg = builder.CreateConstInBoundsGEP2_32(
456 llvm::ArrayType::get(llvm::Type::getInt64Ty(ctx), totalNbOperand),
457 maptypes, /*Idx0=*/0, /*Idx1=*/0);
458
459 llvm::GlobalVariable *mapnames =
460 accBuilder->createOffloadMapnames(names, ".offload_mapnames");
461 llvm::Value *mapnamesArg = builder.CreateConstInBoundsGEP2_32(
462 llvm::ArrayType::get(llvm::PointerType::getUnqual(ctx), totalNbOperand),
463 mapnames, /*Idx0=*/0, /*Idx1=*/0);
464
465 accBuilder->emitMapperCall(builder.saveIP(), mapperFunc, srcLocInfo,
466 maptypesArg, mapnamesArg, mapperAllocas,
467 kDefaultDevice, totalNbOperand);
468
469 return success();
470}
471
472namespace {
473
474/// Implementation of the dialect interface that converts operations belonging
475/// to the OpenACC dialect to LLVM IR.
476class OpenACCDialectLLVMIRTranslationInterface
477 : public LLVMTranslationDialectInterface {
478public:
480
481 /// Translates the given operation to LLVM IR using the provided IR builder
482 /// and saving the state in `moduleTranslation`.
483 LogicalResult
484 convertOperation(Operation *op, llvm::IRBuilderBase &builder,
485 LLVM::ModuleTranslation &moduleTranslation) const final;
486};
487
488} // namespace
489
490/// Given an OpenACC MLIR operation, create the corresponding LLVM IR
491/// (including OpenACC runtime calls).
492LogicalResult OpenACCDialectLLVMIRTranslationInterface::convertOperation(
493 Operation *op, llvm::IRBuilderBase &builder,
494 LLVM::ModuleTranslation &moduleTranslation) const {
495
496 return llvm::TypeSwitch<Operation *, LogicalResult>(op)
497 .Case([&](acc::DataOp dataOp) {
498 return convertDataOp(dataOp, builder, moduleTranslation);
499 })
500 .Case([&](acc::EnterDataOp enterDataOp) {
501 return convertStandaloneDataOp<acc::EnterDataOp>(enterDataOp, builder,
502 moduleTranslation);
503 })
504 .Case([&](acc::ExitDataOp exitDataOp) {
505 return convertStandaloneDataOp<acc::ExitDataOp>(exitDataOp, builder,
506 moduleTranslation);
507 })
508 .Case([&](acc::UpdateOp updateOp) {
510 moduleTranslation);
511 })
512 .Case<acc::TerminatorOp, acc::YieldOp>([](auto op) {
513 // `yield` and `terminator` can be just omitted. The block structure was
514 // created in the function that handles their parent operation.
515 assert(op->getNumOperands() == 0 &&
516 "unexpected OpenACC terminator with operands");
517 return success();
518 })
519 .Case<acc::CreateOp, acc::CopyinOp, acc::CopyoutOp, acc::DeleteOp,
520 acc::UpdateDeviceOp, acc::GetDevicePtrOp>([](auto op) {
521 // NOP
522 return success();
523 })
524 .Default([&](Operation *op) {
525 return op->emitError("unsupported OpenACC operation: ")
526 << op->getName();
527 });
528}
529
531 registry.insert<acc::OpenACCDialect>();
532 registry.addExtension(+[](MLIRContext *ctx, acc::OpenACCDialect *dialect) {
533 dialect->addInterfaces<OpenACCDialectLLVMIRTranslationInterface>();
534 });
535}
536
return success()
static constexpr uint64_t kDeleteFlag
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.
static llvm::Function * getAssociatedFunction(OpenACCIRBuilder &builder, Operation *op)
Return the runtime function used to lower the given operation.
static constexpr uint64_t kPresentFlag
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 kHostCopyoutFlag
static constexpr int64_t kDefaultDevice
Default value for the device id.
llvm::OpenMPIRBuilder OpenACCIRBuilder
static LogicalResult convertDataOp(acc::DataOp &op, llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation)
Converts an OpenACC data operation into LLVM IR.
static constexpr uint64_t kCreateFlag
Flag values are extracted from openmp/libomptarget/include/omptarget.h and mapped to corresponding Op...
static constexpr uint64_t kHoldFlag
static constexpr uint64_t kDeviceCopyinFlag
static LogicalResult convertStandaloneDataOp(OpTy &op, llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation)
Converts an OpenACC standalone data operation into LLVM IR.
static llvm::Value * createSourceLocationInfo(OpenACCIRBuilder &builder, Operation *op)
Create the location struct from the operation location information.
static LogicalResult updateOp(mlir::OpBuilder &builder, mlir::Operation *op, GetLayoutFnTy getLayoutOfValue)
Update an operation with the layout of its results.
Block represents an ordered list of Operations.
Definition Block.h:33
The DialectRegistry maps a dialect namespace to a constructor for the matching dialect.
bool addExtension(TypeID extensionID, std::unique_ptr< DialectExtensionBase > extension)
Add the given extension to the registry.
Implementation class for module translation.
llvm::BasicBlock * lookupBlock(Block *block) const
Finds an LLVM IR basic block that corresponds to the given MLIR block.
LogicalResult convertBlock(Block &bb, bool ignoreArguments, llvm::IRBuilderBase &builder)
Translates the contents of the given block to LLVM IR using this translator.
llvm::Value * lookupValue(Value value) const
Finds an LLVM IR value corresponding to the given MLIR value.
llvm::OpenMPIRBuilder * getOpenMPBuilder()
Returns the OpenMP IR builder associated with the LLVM IR module being constructed.
llvm::Function * lookupFunction(StringRef name) const
Finds an LLVM IR function by its name.
void mapBlock(Block *mlir, llvm::BasicBlock *llvm)
Stores the mapping between an MLIR block and LLVM IR basic block.
MLIRContext is the top-level object for a collection of MLIR operations.
Definition MLIRContext.h:63
void appendDialectRegistry(const DialectRegistry &registry)
Append the contents of the given dialect registry to the registry associated with this context.
Operation is the basic unit of execution within MLIR.
Definition Operation.h:88
Location getLoc()
The source location the operation was defined or derived from.
Definition Operation.h:223
unsigned getNumOperands()
Definition Operation.h:346
InFlightDiagnostic emitError(const Twine &message={})
Emit an error about fatal conditions with this operation, reporting up to any diagnostic handlers tha...
OpTy getParentOfType()
Return the closest surrounding parent operation that is of type 'OpTy'.
Definition Operation.h:238
OperationName getName()
The name of an operation is the key identifier for it.
Definition Operation.h:119
InFlightDiagnostic emitOpError(const Twine &message={})
Emit an error with the op name prefixed, like "'dim' op " which is convenient for verifiers.
This class provides an abstraction over the different types of ranges over Values.
Definition ValueRange.h:387
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition Value.h:96
llvm::Constant * createMappingInformation(Location loc, llvm::OpenMPIRBuilder &builder)
Create a constant string representing the mapping information extracted from the MLIR location inform...
llvm::Constant * createSourceLocStrFromLocation(Location loc, llvm::OpenMPIRBuilder &builder, StringRef name, uint32_t &strLen)
Create a constant string location from the MLIR Location information.
Include the generated interface declarations.
SetVector< Block * > getBlocksSortedByDominance(Region &region)
Gets a list of blocks that is sorted according to dominance.
llvm::SetVector< T, Vector, Set, N > SetVector
Definition LLVM.h:131
void registerOpenACCDialectTranslation(DialectRegistry &registry)
Register the OpenACC dialect and the translation to the LLVM IR in the given registry;.