MLIR  21.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 
26 using namespace mlir;
27 
28 using 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.
36 static constexpr uint64_t kCreateFlag = 0x000;
37 static constexpr uint64_t kDeviceCopyinFlag = 0x001;
38 static constexpr uint64_t kHostCopyoutFlag = 0x002;
39 static constexpr uint64_t kPresentFlag = 0x1000;
40 static constexpr uint64_t kDeleteFlag = 0x008;
41 // Runtime extension to implement the OpenACC second reference counter.
42 static constexpr uint64_t kHoldFlag = 0x2000;
43 
44 /// Default value for the device id
45 static constexpr int64_t kDefaultDevice = -1;
46 
47 /// Create the location struct from the operation location information.
48 static 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.
60 static 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.
80 static LogicalResult
81 processOperands(llvm::IRBuilderBase &builder,
82  LLVM::ModuleTranslation &moduleTranslation, Operation *op,
83  ValueRange operands, unsigned totalNbOperand,
84  uint64_t operandFlag, SmallVector<uint64_t> &flags,
85  SmallVectorImpl<llvm::Constant *> &names, unsigned &index,
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
140 static LogicalResult
141 processDataOperands(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 =
155  mlir::dyn_cast_or_null<acc::CreateOp>(dataOp.getDefiningOp())) {
156  create.push_back(createOp.getVarPtr());
157  } else if (auto copyinOp = mlir::dyn_cast_or_null<acc::CopyinOp>(
158  dataOp.getDefiningOp())) {
159  copyin.push_back(copyinOp.getVarPtr());
160  }
161  }
162 
163  auto nbTotalOperands = create.size() + copyin.size();
164 
165  // Create operands are handled as `alloc` call.
166  if (failed(processOperands(builder, moduleTranslation, op, create,
167  nbTotalOperands, kCreateFlag, flags, names, index,
168  mapperAllocas)))
169  return failure();
170 
171  // Copyin operands are handled as `to` call.
172  if (failed(processOperands(builder, moduleTranslation, op, copyin,
173  nbTotalOperands, kDeviceCopyinFlag, flags, names,
174  index, mapperAllocas)))
175  return failure();
176 
177  return success();
178 }
179 
180 /// Process data operands from acc::ExitDataOp
181 static LogicalResult
182 processDataOperands(llvm::IRBuilderBase &builder,
183  LLVM::ModuleTranslation &moduleTranslation,
184  acc::ExitDataOp op, SmallVector<uint64_t> &flags,
186  struct OpenACCIRBuilder::MapperAllocas &mapperAllocas) {
187  // TODO add `detach` operands
188 
189  unsigned index = 0;
190 
191  llvm::SmallVector<mlir::Value> deleteOperands, copyoutOperands;
192  for (mlir::Value dataOp : op.getDataClauseOperands()) {
193  if (auto devicePtrOp = mlir::dyn_cast_or_null<acc::GetDevicePtrOp>(
194  dataOp.getDefiningOp())) {
195  for (auto &u : devicePtrOp.getAccPtr().getUses()) {
196  if (mlir::dyn_cast_or_null<acc::DeleteOp>(u.getOwner()))
197  deleteOperands.push_back(devicePtrOp.getVarPtr());
198  else if (mlir::dyn_cast_or_null<acc::CopyoutOp>(u.getOwner()))
199  copyoutOperands.push_back(devicePtrOp.getVarPtr());
200  }
201  }
202  }
203 
204  auto nbTotalOperands = deleteOperands.size() + copyoutOperands.size();
205 
206  // Delete operands are handled as `delete` call.
207  if (failed(processOperands(builder, moduleTranslation, op, deleteOperands,
208  nbTotalOperands, kDeleteFlag, flags, names, index,
209  mapperAllocas)))
210  return failure();
211 
212  // Copyout operands are handled as `from` call.
213  if (failed(processOperands(builder, moduleTranslation, op, copyoutOperands,
214  nbTotalOperands, kHostCopyoutFlag, flags, names,
215  index, mapperAllocas)))
216  return failure();
217 
218  return success();
219 }
220 
221 /// Process data operands from acc::UpdateOp
222 static LogicalResult
223 processDataOperands(llvm::IRBuilderBase &builder,
224  LLVM::ModuleTranslation &moduleTranslation,
225  acc::UpdateOp op, SmallVector<uint64_t> &flags,
227  struct OpenACCIRBuilder::MapperAllocas &mapperAllocas) {
228  unsigned index = 0;
229 
230  // Host operands are handled as `from` call.
231  // Device operands are handled as `to` call.
233  for (mlir::Value dataOp : op.getDataClauseOperands()) {
234  if (auto getDevicePtrOp = mlir::dyn_cast_or_null<acc::GetDevicePtrOp>(
235  dataOp.getDefiningOp())) {
236  from.push_back(getDevicePtrOp.getVarPtr());
237  } else if (auto updateDeviceOp =
238  mlir::dyn_cast_or_null<acc::UpdateDeviceOp>(
239  dataOp.getDefiningOp())) {
240  to.push_back(updateDeviceOp.getVarPtr());
241  }
242  }
243 
244  if (failed(processOperands(builder, moduleTranslation, op, from, from.size(),
245  kHostCopyoutFlag, flags, names, index,
246  mapperAllocas)))
247  return failure();
248 
249  if (failed(processOperands(builder, moduleTranslation, op, to, to.size(),
250  kDeviceCopyinFlag, flags, names, index,
251  mapperAllocas)))
252  return failure();
253  return success();
254 }
255 
256 //===----------------------------------------------------------------------===//
257 // Conversion functions
258 //===----------------------------------------------------------------------===//
259 
260 /// Converts an OpenACC data operation into LLVM IR.
261 static LogicalResult convertDataOp(acc::DataOp &op,
262  llvm::IRBuilderBase &builder,
263  LLVM::ModuleTranslation &moduleTranslation) {
264  llvm::LLVMContext &ctx = builder.getContext();
265  auto enclosingFuncOp = op.getOperation()->getParentOfType<LLVM::LLVMFuncOp>();
266  llvm::Function *enclosingFunction =
267  moduleTranslation.lookupFunction(enclosingFuncOp.getName());
268 
269  OpenACCIRBuilder *accBuilder = moduleTranslation.getOpenMPBuilder();
270 
271  llvm::Value *srcLocInfo = createSourceLocationInfo(*accBuilder, op);
272 
273  llvm::Function *beginMapperFunc = accBuilder->getOrCreateRuntimeFunctionPtr(
274  llvm::omp::OMPRTL___tgt_target_data_begin_mapper);
275 
276  llvm::Function *endMapperFunc = accBuilder->getOrCreateRuntimeFunctionPtr(
277  llvm::omp::OMPRTL___tgt_target_data_end_mapper);
278 
279  // Number of arguments in the data operation.
280  unsigned totalNbOperand = op.getNumDataOperands();
281 
282  struct OpenACCIRBuilder::MapperAllocas mapperAllocas;
283  OpenACCIRBuilder::InsertPointTy allocaIP(
284  &enclosingFunction->getEntryBlock(),
285  enclosingFunction->getEntryBlock().getFirstInsertionPt());
286  accBuilder->createMapperAllocas(builder.saveIP(), allocaIP, totalNbOperand,
287  mapperAllocas);
288 
289  SmallVector<uint64_t> flags;
291  unsigned index = 0;
292 
293  // TODO handle no_create, deviceptr and attach operands.
294 
295  llvm::SmallVector<mlir::Value> copyin, copyout, create, present,
296  deleteOperands;
297  for (mlir::Value dataOp : op.getDataClauseOperands()) {
298  if (auto devicePtrOp = mlir::dyn_cast_or_null<acc::GetDevicePtrOp>(
299  dataOp.getDefiningOp())) {
300  for (auto &u : devicePtrOp.getAccPtr().getUses()) {
301  if (mlir::dyn_cast_or_null<acc::DeleteOp>(u.getOwner())) {
302  deleteOperands.push_back(devicePtrOp.getVarPtr());
303  } else if (mlir::dyn_cast_or_null<acc::CopyoutOp>(u.getOwner())) {
304  // TODO copyout zero currenlty handled as copyout. Update when
305  // extension available.
306  copyout.push_back(devicePtrOp.getVarPtr());
307  }
308  }
309  } else if (auto copyinOp = mlir::dyn_cast_or_null<acc::CopyinOp>(
310  dataOp.getDefiningOp())) {
311  // TODO copyin readonly currenlty handled as copyin. Update when extension
312  // available.
313  copyin.push_back(copyinOp.getVarPtr());
314  } else if (auto createOp = mlir::dyn_cast_or_null<acc::CreateOp>(
315  dataOp.getDefiningOp())) {
316  // TODO create zero currenlty handled as create. Update when extension
317  // available.
318  create.push_back(createOp.getVarPtr());
319  } else if (auto presentOp = mlir::dyn_cast_or_null<acc::PresentOp>(
320  dataOp.getDefiningOp())) {
321  present.push_back(createOp.getVarPtr());
322  }
323  }
324 
325  auto nbTotalOperands = copyin.size() + copyout.size() + create.size() +
326  present.size() + deleteOperands.size();
327 
328  // Copyin operands are handled as `to` call.
329  if (failed(processOperands(builder, moduleTranslation, op, copyin,
330  nbTotalOperands, kDeviceCopyinFlag | kHoldFlag,
331  flags, names, index, mapperAllocas)))
332  return failure();
333 
334  // Delete operands are handled as `delete` call.
335  if (failed(processOperands(builder, moduleTranslation, op, deleteOperands,
336  nbTotalOperands, kDeleteFlag, flags, names, index,
337  mapperAllocas)))
338  return failure();
339 
340  // Copyout operands are handled as `from` call.
341  if (failed(processOperands(builder, moduleTranslation, op, copyout,
342  nbTotalOperands, kHostCopyoutFlag | kHoldFlag,
343  flags, names, index, mapperAllocas)))
344  return failure();
345 
346  // Create operands are handled as `alloc` call.
347  if (failed(processOperands(builder, moduleTranslation, op, create,
348  nbTotalOperands, kCreateFlag | kHoldFlag, flags,
349  names, index, mapperAllocas)))
350  return failure();
351 
352  if (failed(processOperands(builder, moduleTranslation, op, present,
353  nbTotalOperands, kPresentFlag | kHoldFlag, flags,
354  names, index, mapperAllocas)))
355  return failure();
356 
357  llvm::GlobalVariable *maptypes =
358  accBuilder->createOffloadMaptypes(flags, ".offload_maptypes");
359  llvm::Value *maptypesArg = builder.CreateConstInBoundsGEP2_32(
360  llvm::ArrayType::get(llvm::Type::getInt64Ty(ctx), totalNbOperand),
361  maptypes, /*Idx0=*/0, /*Idx1=*/0);
362 
363  llvm::GlobalVariable *mapnames =
364  accBuilder->createOffloadMapnames(names, ".offload_mapnames");
365  llvm::Value *mapnamesArg = builder.CreateConstInBoundsGEP2_32(
366  llvm::ArrayType::get(llvm::PointerType::getUnqual(ctx), totalNbOperand),
367  mapnames, /*Idx0=*/0, /*Idx1=*/0);
368 
369  // Create call to start the data region.
370  accBuilder->emitMapperCall(builder.saveIP(), beginMapperFunc, srcLocInfo,
371  maptypesArg, mapnamesArg, mapperAllocas,
372  kDefaultDevice, totalNbOperand);
373 
374  // Convert the region.
375  llvm::BasicBlock *entryBlock = nullptr;
376 
377  for (Block &bb : op.getRegion()) {
378  llvm::BasicBlock *llvmBB = llvm::BasicBlock::Create(
379  ctx, "acc.data", builder.GetInsertBlock()->getParent());
380  if (entryBlock == nullptr)
381  entryBlock = llvmBB;
382  moduleTranslation.mapBlock(&bb, llvmBB);
383  }
384 
385  auto afterDataRegion = builder.saveIP();
386 
387  llvm::BranchInst *sourceTerminator = builder.CreateBr(entryBlock);
388 
389  builder.restoreIP(afterDataRegion);
390  llvm::BasicBlock *endDataBlock = llvm::BasicBlock::Create(
391  ctx, "acc.end_data", builder.GetInsertBlock()->getParent());
392 
393  SetVector<Block *> blocks = getBlocksSortedByDominance(op.getRegion());
394  for (Block *bb : blocks) {
395  llvm::BasicBlock *llvmBB = moduleTranslation.lookupBlock(bb);
396  if (bb->isEntryBlock()) {
397  assert(sourceTerminator->getNumSuccessors() == 1 &&
398  "provided entry block has multiple successors");
399  sourceTerminator->setSuccessor(0, llvmBB);
400  }
401 
402  if (failed(
403  moduleTranslation.convertBlock(*bb, bb->isEntryBlock(), builder))) {
404  return failure();
405  }
406 
407  if (isa<acc::TerminatorOp, acc::YieldOp>(bb->getTerminator()))
408  builder.CreateBr(endDataBlock);
409  }
410 
411  // Create call to end the data region.
412  builder.SetInsertPoint(endDataBlock);
413  accBuilder->emitMapperCall(builder.saveIP(), endMapperFunc, srcLocInfo,
414  maptypesArg, mapnamesArg, mapperAllocas,
415  kDefaultDevice, totalNbOperand);
416 
417  return success();
418 }
419 
420 /// Converts an OpenACC standalone data operation into LLVM IR.
421 template <typename OpTy>
422 static LogicalResult
423 convertStandaloneDataOp(OpTy &op, llvm::IRBuilderBase &builder,
424  LLVM::ModuleTranslation &moduleTranslation) {
425  auto enclosingFuncOp =
426  op.getOperation()->template getParentOfType<LLVM::LLVMFuncOp>();
427  llvm::Function *enclosingFunction =
428  moduleTranslation.lookupFunction(enclosingFuncOp.getName());
429 
430  OpenACCIRBuilder *accBuilder = moduleTranslation.getOpenMPBuilder();
431 
432  auto *srcLocInfo = createSourceLocationInfo(*accBuilder, op);
433  auto *mapperFunc = getAssociatedFunction(*accBuilder, op);
434 
435  // Number of arguments in the enter_data operation.
436  unsigned totalNbOperand = op.getNumDataOperands();
437 
438  llvm::LLVMContext &ctx = builder.getContext();
439 
440  struct OpenACCIRBuilder::MapperAllocas mapperAllocas;
441  OpenACCIRBuilder::InsertPointTy allocaIP(
442  &enclosingFunction->getEntryBlock(),
443  enclosingFunction->getEntryBlock().getFirstInsertionPt());
444  accBuilder->createMapperAllocas(builder.saveIP(), allocaIP, totalNbOperand,
445  mapperAllocas);
446 
447  SmallVector<uint64_t> flags;
449 
450  if (failed(processDataOperands(builder, moduleTranslation, op, flags, names,
451  mapperAllocas)))
452  return failure();
453 
454  llvm::GlobalVariable *maptypes =
455  accBuilder->createOffloadMaptypes(flags, ".offload_maptypes");
456  llvm::Value *maptypesArg = builder.CreateConstInBoundsGEP2_32(
457  llvm::ArrayType::get(llvm::Type::getInt64Ty(ctx), totalNbOperand),
458  maptypes, /*Idx0=*/0, /*Idx1=*/0);
459 
460  llvm::GlobalVariable *mapnames =
461  accBuilder->createOffloadMapnames(names, ".offload_mapnames");
462  llvm::Value *mapnamesArg = builder.CreateConstInBoundsGEP2_32(
463  llvm::ArrayType::get(llvm::PointerType::getUnqual(ctx), totalNbOperand),
464  mapnames, /*Idx0=*/0, /*Idx1=*/0);
465 
466  accBuilder->emitMapperCall(builder.saveIP(), mapperFunc, srcLocInfo,
467  maptypesArg, mapnamesArg, mapperAllocas,
468  kDefaultDevice, totalNbOperand);
469 
470  return success();
471 }
472 
473 namespace {
474 
475 /// Implementation of the dialect interface that converts operations belonging
476 /// to the OpenACC dialect to LLVM IR.
477 class OpenACCDialectLLVMIRTranslationInterface
479 public:
481 
482  /// Translates the given operation to LLVM IR using the provided IR builder
483  /// and saving the state in `moduleTranslation`.
484  LogicalResult
485  convertOperation(Operation *op, llvm::IRBuilderBase &builder,
486  LLVM::ModuleTranslation &moduleTranslation) const final;
487 };
488 
489 } // namespace
490 
491 /// Given an OpenACC MLIR operation, create the corresponding LLVM IR
492 /// (including OpenACC runtime calls).
493 LogicalResult OpenACCDialectLLVMIRTranslationInterface::convertOperation(
494  Operation *op, llvm::IRBuilderBase &builder,
495  LLVM::ModuleTranslation &moduleTranslation) const {
496 
498  .Case([&](acc::DataOp dataOp) {
499  return convertDataOp(dataOp, builder, moduleTranslation);
500  })
501  .Case([&](acc::EnterDataOp enterDataOp) {
502  return convertStandaloneDataOp<acc::EnterDataOp>(enterDataOp, builder,
503  moduleTranslation);
504  })
505  .Case([&](acc::ExitDataOp exitDataOp) {
506  return convertStandaloneDataOp<acc::ExitDataOp>(exitDataOp, builder,
507  moduleTranslation);
508  })
509  .Case([&](acc::UpdateOp updateOp) {
510  return convertStandaloneDataOp<acc::UpdateOp>(updateOp, builder,
511  moduleTranslation);
512  })
513  .Case<acc::TerminatorOp, acc::YieldOp>([](auto op) {
514  // `yield` and `terminator` can be just omitted. The block structure was
515  // created in the function that handles their parent operation.
516  assert(op->getNumOperands() == 0 &&
517  "unexpected OpenACC terminator with operands");
518  return success();
519  })
520  .Case<acc::CreateOp, acc::CopyinOp, acc::CopyoutOp, acc::DeleteOp,
521  acc::UpdateDeviceOp, acc::GetDevicePtrOp>([](auto op) {
522  // NOP
523  return success();
524  })
525  .Default([&](Operation *op) {
526  return op->emitError("unsupported OpenACC operation: ")
527  << op->getName();
528  });
529 }
530 
532  registry.insert<acc::OpenACCDialect>();
533  registry.addExtension(+[](MLIRContext *ctx, acc::OpenACCDialect *dialect) {
534  dialect->addInterfaces<OpenACCDialectLLVMIRTranslationInterface>();
535  });
536 }
537 
539  DialectRegistry registry;
541  context.appendDialectRegistry(registry);
542 }
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.
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.
Base class for dialect interfaces providing translation to LLVM IR.
Implementation class for module translation.
llvm::Value * lookupValue(Value value) const
Finds an LLVM IR value corresponding to the given MLIR value.
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.
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
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...
Definition: Operation.cpp:267
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.
Definition: Operation.cpp:672
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.
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;.