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