MLIR  15.0.0git
ModuleTranslation.cpp
Go to the documentation of this file.
1 //===- ModuleTranslation.cpp - MLIR to LLVM conversion --------------------===//
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 the translation between an MLIR LLVM dialect module and
10 // the corresponding LLVMIR module. It only handles core LLVM IR operations.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 
16 #include "DebugTranslation.h"
17 #include "mlir/Dialect/DLTI/DLTI.h"
21 #include "mlir/IR/Attributes.h"
22 #include "mlir/IR/BuiltinOps.h"
23 #include "mlir/IR/BuiltinTypes.h"
25 #include "mlir/Support/LLVM.h"
28 #include "llvm/ADT/TypeSwitch.h"
29 
30 #include "llvm/ADT/PostOrderIterator.h"
31 #include "llvm/ADT/SetVector.h"
32 #include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
33 #include "llvm/IR/BasicBlock.h"
34 #include "llvm/IR/CFG.h"
35 #include "llvm/IR/Constants.h"
36 #include "llvm/IR/DerivedTypes.h"
37 #include "llvm/IR/IRBuilder.h"
38 #include "llvm/IR/InlineAsm.h"
39 #include "llvm/IR/IntrinsicsNVPTX.h"
40 #include "llvm/IR/LLVMContext.h"
41 #include "llvm/IR/MDBuilder.h"
42 #include "llvm/IR/Module.h"
43 #include "llvm/IR/Verifier.h"
44 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
45 #include "llvm/Transforms/Utils/Cloning.h"
46 #include "llvm/Transforms/Utils/ModuleUtils.h"
47 
48 using namespace mlir;
49 using namespace mlir::LLVM;
50 using namespace mlir::LLVM::detail;
51 
52 #include "mlir/Dialect/LLVMIR/LLVMConversionEnumsToLLVM.inc"
53 
54 /// Translates the given data layout spec attribute to the LLVM IR data layout.
55 /// Only integer, float and endianness entries are currently supported.
57 translateDataLayout(DataLayoutSpecInterface attribute,
58  const DataLayout &dataLayout,
59  Optional<Location> loc = llvm::None) {
60  if (!loc)
61  loc = UnknownLoc::get(attribute.getContext());
62 
63  // Translate the endianness attribute.
64  std::string llvmDataLayout;
65  llvm::raw_string_ostream layoutStream(llvmDataLayout);
66  for (DataLayoutEntryInterface entry : attribute.getEntries()) {
67  auto key = entry.getKey().dyn_cast<StringAttr>();
68  if (!key)
69  continue;
70  if (key.getValue() == DLTIDialect::kDataLayoutEndiannessKey) {
71  auto value = entry.getValue().cast<StringAttr>();
72  bool isLittleEndian =
73  value.getValue() == DLTIDialect::kDataLayoutEndiannessLittle;
74  layoutStream << (isLittleEndian ? "e" : "E");
75  layoutStream.flush();
76  continue;
77  }
78  emitError(*loc) << "unsupported data layout key " << key;
79  return failure();
80  }
81 
82  // Go through the list of entries to check which types are explicitly
83  // specified in entries. Don't use the entries directly though but query the
84  // data from the layout.
85  for (DataLayoutEntryInterface entry : attribute.getEntries()) {
86  auto type = entry.getKey().dyn_cast<Type>();
87  if (!type)
88  continue;
89  // Data layout for the index type is irrelevant at this point.
90  if (type.isa<IndexType>())
91  continue;
92  FailureOr<std::string> prefix =
94  .Case<IntegerType>(
95  [loc](IntegerType integerType) -> FailureOr<std::string> {
96  if (integerType.getSignedness() == IntegerType::Signless)
97  return std::string("i");
98  emitError(*loc)
99  << "unsupported data layout for non-signless integer "
100  << integerType;
101  return failure();
102  })
103  .Case<Float16Type, Float32Type, Float64Type, Float80Type,
104  Float128Type>([](Type) { return std::string("f"); })
105  .Default([loc](Type type) -> FailureOr<std::string> {
106  emitError(*loc) << "unsupported type in data layout: " << type;
107  return failure();
108  });
109  if (failed(prefix))
110  return failure();
111 
112  unsigned size = dataLayout.getTypeSizeInBits(type);
113  unsigned abi = dataLayout.getTypeABIAlignment(type) * 8u;
114  unsigned preferred = dataLayout.getTypePreferredAlignment(type) * 8u;
115  layoutStream << "-" << *prefix << size << ":" << abi;
116  if (abi != preferred)
117  layoutStream << ":" << preferred;
118  }
119  layoutStream.flush();
120  StringRef layoutSpec(llvmDataLayout);
121  if (layoutSpec.startswith("-"))
122  layoutSpec = layoutSpec.drop_front();
123 
124  return llvm::DataLayout(layoutSpec);
125 }
126 
127 /// Builds a constant of a sequential LLVM type `type`, potentially containing
128 /// other sequential types recursively, from the individual constant values
129 /// provided in `constants`. `shape` contains the number of elements in nested
130 /// sequential types. Reports errors at `loc` and returns nullptr on error.
131 static llvm::Constant *
133  ArrayRef<int64_t> shape, llvm::Type *type,
134  Location loc) {
135  if (shape.empty()) {
136  llvm::Constant *result = constants.front();
137  constants = constants.drop_front();
138  return result;
139  }
140 
141  llvm::Type *elementType;
142  if (auto *arrayTy = dyn_cast<llvm::ArrayType>(type)) {
143  elementType = arrayTy->getElementType();
144  } else if (auto *vectorTy = dyn_cast<llvm::VectorType>(type)) {
145  elementType = vectorTy->getElementType();
146  } else {
147  emitError(loc) << "expected sequential LLVM types wrapping a scalar";
148  return nullptr;
149  }
150 
152  nested.reserve(shape.front());
153  for (int64_t i = 0; i < shape.front(); ++i) {
154  nested.push_back(buildSequentialConstant(constants, shape.drop_front(),
155  elementType, loc));
156  if (!nested.back())
157  return nullptr;
158  }
159 
160  if (shape.size() == 1 && type->isVectorTy())
161  return llvm::ConstantVector::get(nested);
162  return llvm::ConstantArray::get(
163  llvm::ArrayType::get(elementType, shape.front()), nested);
164 }
165 
166 /// Returns the first non-sequential type nested in sequential types.
167 static llvm::Type *getInnermostElementType(llvm::Type *type) {
168  do {
169  if (auto *arrayTy = dyn_cast<llvm::ArrayType>(type)) {
170  type = arrayTy->getElementType();
171  } else if (auto *vectorTy = dyn_cast<llvm::VectorType>(type)) {
172  type = vectorTy->getElementType();
173  } else {
174  return type;
175  }
176  } while (true);
177 }
178 
179 /// Convert a dense elements attribute to an LLVM IR constant using its raw data
180 /// storage if possible. This supports elements attributes of tensor or vector
181 /// type and avoids constructing separate objects for individual values of the
182 /// innermost dimension. Constants for other dimensions are still constructed
183 /// recursively. Returns null if constructing from raw data is not supported for
184 /// this type, e.g., element type is not a power-of-two-sized primitive. Reports
185 /// other errors at `loc`.
186 static llvm::Constant *
188  llvm::Type *llvmType,
189  const ModuleTranslation &moduleTranslation) {
190  if (!denseElementsAttr)
191  return nullptr;
192 
193  llvm::Type *innermostLLVMType = getInnermostElementType(llvmType);
194  if (!llvm::ConstantDataSequential::isElementTypeCompatible(innermostLLVMType))
195  return nullptr;
196 
197  ShapedType type = denseElementsAttr.getType();
198  if (type.getNumElements() == 0)
199  return nullptr;
200 
201  // Compute the shape of all dimensions but the innermost. Note that the
202  // innermost dimension may be that of the vector element type.
203  bool hasVectorElementType = type.getElementType().isa<VectorType>();
204  unsigned numAggregates =
205  denseElementsAttr.getNumElements() /
206  (hasVectorElementType ? 1
207  : denseElementsAttr.getType().getShape().back());
208  ArrayRef<int64_t> outerShape = type.getShape();
209  if (!hasVectorElementType)
210  outerShape = outerShape.drop_back();
211 
212  // Handle the case of vector splat, LLVM has special support for it.
213  if (denseElementsAttr.isSplat() &&
214  (type.isa<VectorType>() || hasVectorElementType)) {
216  innermostLLVMType, denseElementsAttr.getSplatValue<Attribute>(), loc,
217  moduleTranslation);
218  llvm::Constant *splatVector =
219  llvm::ConstantDataVector::getSplat(0, splatValue);
220  SmallVector<llvm::Constant *> constants(numAggregates, splatVector);
221  ArrayRef<llvm::Constant *> constantsRef = constants;
222  return buildSequentialConstant(constantsRef, outerShape, llvmType, loc);
223  }
224  if (denseElementsAttr.isSplat())
225  return nullptr;
226 
227  // In case of non-splat, create a constructor for the innermost constant from
228  // a piece of raw data.
229  std::function<llvm::Constant *(StringRef)> buildCstData;
230  if (type.isa<TensorType>()) {
231  auto vectorElementType = type.getElementType().dyn_cast<VectorType>();
232  if (vectorElementType && vectorElementType.getRank() == 1) {
233  buildCstData = [&](StringRef data) {
234  return llvm::ConstantDataVector::getRaw(
235  data, vectorElementType.getShape().back(), innermostLLVMType);
236  };
237  } else if (!vectorElementType) {
238  buildCstData = [&](StringRef data) {
239  return llvm::ConstantDataArray::getRaw(data, type.getShape().back(),
240  innermostLLVMType);
241  };
242  }
243  } else if (type.isa<VectorType>()) {
244  buildCstData = [&](StringRef data) {
245  return llvm::ConstantDataVector::getRaw(data, type.getShape().back(),
246  innermostLLVMType);
247  };
248  }
249  if (!buildCstData)
250  return nullptr;
251 
252  // Create innermost constants and defer to the default constant creation
253  // mechanism for other dimensions.
255  unsigned aggregateSize = denseElementsAttr.getType().getShape().back() *
256  (innermostLLVMType->getScalarSizeInBits() / 8);
257  constants.reserve(numAggregates);
258  for (unsigned i = 0; i < numAggregates; ++i) {
259  StringRef data(denseElementsAttr.getRawData().data() + i * aggregateSize,
260  aggregateSize);
261  constants.push_back(buildCstData(data));
262  }
263 
264  ArrayRef<llvm::Constant *> constantsRef = constants;
265  return buildSequentialConstant(constantsRef, outerShape, llvmType, loc);
266 }
267 
268 /// Create an LLVM IR constant of `llvmType` from the MLIR attribute `attr`.
269 /// This currently supports integer, floating point, splat and dense element
270 /// attributes and combinations thereof. Also, an array attribute with two
271 /// elements is supported to represent a complex constant. In case of error,
272 /// report it to `loc` and return nullptr.
274  llvm::Type *llvmType, Attribute attr, Location loc,
275  const ModuleTranslation &moduleTranslation) {
276  if (!attr)
277  return llvm::UndefValue::get(llvmType);
278  if (auto *structType = dyn_cast<::llvm::StructType>(llvmType)) {
279  auto arrayAttr = attr.dyn_cast<ArrayAttr>();
280  if (!arrayAttr || arrayAttr.size() != 2) {
281  emitError(loc, "expected struct type to be a complex number");
282  return nullptr;
283  }
284  llvm::Type *elementType = structType->getElementType(0);
285  llvm::Constant *real =
286  getLLVMConstant(elementType, arrayAttr[0], loc, moduleTranslation);
287  if (!real)
288  return nullptr;
289  llvm::Constant *imag =
290  getLLVMConstant(elementType, arrayAttr[1], loc, moduleTranslation);
291  if (!imag)
292  return nullptr;
293  return llvm::ConstantStruct::get(structType, {real, imag});
294  }
295  // For integer types, we allow a mismatch in sizes as the index type in
296  // MLIR might have a different size than the index type in the LLVM module.
297  if (auto intAttr = attr.dyn_cast<IntegerAttr>())
298  return llvm::ConstantInt::get(
299  llvmType,
300  intAttr.getValue().sextOrTrunc(llvmType->getIntegerBitWidth()));
301  if (auto floatAttr = attr.dyn_cast<FloatAttr>()) {
302  if (llvmType !=
303  llvm::Type::getFloatingPointTy(llvmType->getContext(),
304  floatAttr.getValue().getSemantics())) {
305  emitError(loc, "FloatAttr does not match expected type of the constant");
306  return nullptr;
307  }
308  return llvm::ConstantFP::get(llvmType, floatAttr.getValue());
309  }
310  if (auto funcAttr = attr.dyn_cast<FlatSymbolRefAttr>())
311  return llvm::ConstantExpr::getBitCast(
312  moduleTranslation.lookupFunction(funcAttr.getValue()), llvmType);
313  if (auto splatAttr = attr.dyn_cast<SplatElementsAttr>()) {
314  llvm::Type *elementType;
315  uint64_t numElements;
316  bool isScalable = false;
317  if (auto *arrayTy = dyn_cast<llvm::ArrayType>(llvmType)) {
318  elementType = arrayTy->getElementType();
319  numElements = arrayTy->getNumElements();
320  } else if (auto *fVectorTy = dyn_cast<llvm::FixedVectorType>(llvmType)) {
321  elementType = fVectorTy->getElementType();
322  numElements = fVectorTy->getNumElements();
323  } else if (auto *sVectorTy = dyn_cast<llvm::ScalableVectorType>(llvmType)) {
324  elementType = sVectorTy->getElementType();
325  numElements = sVectorTy->getMinNumElements();
326  isScalable = true;
327  } else {
328  llvm_unreachable("unrecognized constant vector type");
329  }
330  // Splat value is a scalar. Extract it only if the element type is not
331  // another sequence type. The recursion terminates because each step removes
332  // one outer sequential type.
333  bool elementTypeSequential =
334  isa<llvm::ArrayType, llvm::VectorType>(elementType);
336  elementType,
337  elementTypeSequential ? splatAttr
338  : splatAttr.getSplatValue<Attribute>(),
339  loc, moduleTranslation);
340  if (!child)
341  return nullptr;
342  if (llvmType->isVectorTy())
343  return llvm::ConstantVector::getSplat(
344  llvm::ElementCount::get(numElements, /*Scalable=*/isScalable), child);
345  if (llvmType->isArrayTy()) {
346  auto *arrayType = llvm::ArrayType::get(elementType, numElements);
347  SmallVector<llvm::Constant *, 8> constants(numElements, child);
348  return llvm::ConstantArray::get(arrayType, constants);
349  }
350  }
351 
352  // Try using raw elements data if possible.
353  if (llvm::Constant *result =
355  llvmType, moduleTranslation)) {
356  return result;
357  }
358 
359  // Fall back to element-by-element construction otherwise.
360  if (auto elementsAttr = attr.dyn_cast<ElementsAttr>()) {
361  assert(elementsAttr.getType().hasStaticShape());
362  assert(!elementsAttr.getType().getShape().empty() &&
363  "unexpected empty elements attribute shape");
364 
366  constants.reserve(elementsAttr.getNumElements());
367  llvm::Type *innermostType = getInnermostElementType(llvmType);
368  for (auto n : elementsAttr.getValues<Attribute>()) {
369  constants.push_back(
370  getLLVMConstant(innermostType, n, loc, moduleTranslation));
371  if (!constants.back())
372  return nullptr;
373  }
374  ArrayRef<llvm::Constant *> constantsRef = constants;
376  constantsRef, elementsAttr.getType().getShape(), llvmType, loc);
377  assert(constantsRef.empty() && "did not consume all elemental constants");
378  return result;
379  }
380 
381  if (auto stringAttr = attr.dyn_cast<StringAttr>()) {
382  return llvm::ConstantDataArray::get(
383  moduleTranslation.getLLVMContext(),
384  ArrayRef<char>{stringAttr.getValue().data(),
385  stringAttr.getValue().size()});
386  }
387  emitError(loc, "unsupported constant value");
388  return nullptr;
389 }
390 
391 ModuleTranslation::ModuleTranslation(Operation *module,
392  std::unique_ptr<llvm::Module> llvmModule)
393  : mlirModule(module), llvmModule(std::move(llvmModule)),
394  debugTranslation(
395  std::make_unique<DebugTranslation>(module, *this->llvmModule)),
396  typeTranslator(this->llvmModule->getContext()),
397  iface(module->getContext()) {
398  assert(satisfiesLLVMModule(mlirModule) &&
399  "mlirModule should honor LLVM's module semantics.");
400 }
401 ModuleTranslation::~ModuleTranslation() {
402  if (ompBuilder)
403  ompBuilder->finalize();
404 }
405 
407  SmallVector<Region *> toProcess;
408  toProcess.push_back(&region);
409  while (!toProcess.empty()) {
410  Region *current = toProcess.pop_back_val();
411  for (Block &block : *current) {
412  blockMapping.erase(&block);
413  for (Value arg : block.getArguments())
414  valueMapping.erase(arg);
415  for (Operation &op : block) {
416  for (Value value : op.getResults())
417  valueMapping.erase(value);
418  if (op.hasSuccessors())
419  branchMapping.erase(&op);
420  if (isa<LLVM::GlobalOp>(op))
421  globalsMapping.erase(&op);
422  accessGroupMetadataMapping.erase(&op);
423  llvm::append_range(
424  toProcess,
425  llvm::map_range(op.getRegions(), [](Region &r) { return &r; }));
426  }
427  }
428  }
429 }
430 
431 /// Get the SSA value passed to the current block from the terminator operation
432 /// of its predecessor.
433 static Value getPHISourceValue(Block *current, Block *pred,
434  unsigned numArguments, unsigned index) {
435  Operation &terminator = *pred->getTerminator();
436  if (isa<LLVM::BrOp>(terminator))
437  return terminator.getOperand(index);
438 
439 #ifndef NDEBUG
440  llvm::SmallPtrSet<Block *, 4> seenSuccessors;
441  for (unsigned i = 0, e = terminator.getNumSuccessors(); i < e; ++i) {
442  Block *successor = terminator.getSuccessor(i);
443  auto branch = cast<BranchOpInterface>(terminator);
444  SuccessorOperands successorOperands = branch.getSuccessorOperands(i);
445  assert(
446  (!seenSuccessors.contains(successor) || successorOperands.empty()) &&
447  "successors with arguments in LLVM branches must be different blocks");
448  seenSuccessors.insert(successor);
449  }
450 #endif
451 
452  // For instructions that branch based on a condition value, we need to take
453  // the operands for the branch that was taken.
454  if (auto condBranchOp = dyn_cast<LLVM::CondBrOp>(terminator)) {
455  // For conditional branches, we take the operands from either the "true" or
456  // the "false" branch.
457  return condBranchOp.getSuccessor(0) == current
458  ? condBranchOp.getTrueDestOperands()[index]
459  : condBranchOp.getFalseDestOperands()[index];
460  }
461 
462  if (auto switchOp = dyn_cast<LLVM::SwitchOp>(terminator)) {
463  // For switches, we take the operands from either the default case, or from
464  // the case branch that was taken.
465  if (switchOp.getDefaultDestination() == current)
466  return switchOp.getDefaultOperands()[index];
467  for (const auto &i : llvm::enumerate(switchOp.getCaseDestinations()))
468  if (i.value() == current)
469  return switchOp.getCaseOperands(i.index())[index];
470  }
471 
472  if (auto invokeOp = dyn_cast<LLVM::InvokeOp>(terminator)) {
473  return invokeOp.getNormalDest() == current
474  ? invokeOp.getNormalDestOperands()[index]
475  : invokeOp.getUnwindDestOperands()[index];
476  }
477 
478  llvm_unreachable(
479  "only branch, switch or invoke operations can be terminators "
480  "of a block that has successors");
481 }
482 
483 /// Connect the PHI nodes to the results of preceding blocks.
485  const ModuleTranslation &state) {
486  // Skip the first block, it cannot be branched to and its arguments correspond
487  // to the arguments of the LLVM function.
488  for (auto it = std::next(region.begin()), eit = region.end(); it != eit;
489  ++it) {
490  Block *bb = &*it;
491  llvm::BasicBlock *llvmBB = state.lookupBlock(bb);
492  auto phis = llvmBB->phis();
493  auto numArguments = bb->getNumArguments();
494  assert(numArguments == std::distance(phis.begin(), phis.end()));
495  for (auto &numberedPhiNode : llvm::enumerate(phis)) {
496  auto &phiNode = numberedPhiNode.value();
497  unsigned index = numberedPhiNode.index();
498  for (auto *pred : bb->getPredecessors()) {
499  // Find the LLVM IR block that contains the converted terminator
500  // instruction and use it in the PHI node. Note that this block is not
501  // necessarily the same as state.lookupBlock(pred), some operations
502  // (in particular, OpenMP operations using OpenMPIRBuilder) may have
503  // split the blocks.
504  llvm::Instruction *terminator =
505  state.lookupBranch(pred->getTerminator());
506  assert(terminator && "missing the mapping for a terminator");
507  phiNode.addIncoming(
508  state.lookupValue(getPHISourceValue(bb, pred, numArguments, index)),
509  terminator->getParent());
510  }
511  }
512  }
513 }
514 
515 /// Sort function blocks topologically.
518  // For each block that has not been visited yet (i.e. that has no
519  // predecessors), add it to the list as well as its successors.
520  SetVector<Block *> blocks;
521  for (Block &b : region) {
522  if (blocks.count(&b) == 0) {
523  llvm::ReversePostOrderTraversal<Block *> traversal(&b);
524  blocks.insert(traversal.begin(), traversal.end());
525  }
526  }
527  assert(blocks.size() == region.getBlocks().size() &&
528  "some blocks are not sorted");
529 
530  return blocks;
531 }
532 
534  llvm::IRBuilderBase &builder, llvm::Intrinsic::ID intrinsic,
536  llvm::Module *module = builder.GetInsertBlock()->getModule();
537  llvm::Function *fn = llvm::Intrinsic::getDeclaration(module, intrinsic, tys);
538  return builder.CreateCall(fn, args);
539 }
540 
541 /// Given a single MLIR operation, create the corresponding LLVM IR operation
542 /// using the `builder`.
544 ModuleTranslation::convertOperation(Operation &op,
545  llvm::IRBuilderBase &builder) {
546  const LLVMTranslationDialectInterface *opIface = iface.getInterfaceFor(&op);
547  if (!opIface)
548  return op.emitError("cannot be converted to LLVM IR: missing "
549  "`LLVMTranslationDialectInterface` registration for "
550  "dialect for op: ")
551  << op.getName();
552 
553  if (failed(opIface->convertOperation(&op, builder, *this)))
554  return op.emitError("LLVM Translation failed for operation: ")
555  << op.getName();
556 
557  return convertDialectAttributes(&op);
558 }
559 
560 /// Convert block to LLVM IR. Unless `ignoreArguments` is set, emit PHI nodes
561 /// to define values corresponding to the MLIR block arguments. These nodes
562 /// are not connected to the source basic blocks, which may not exist yet. Uses
563 /// `builder` to construct the LLVM IR. Expects the LLVM IR basic block to have
564 /// been created for `bb` and included in the block mapping. Inserts new
565 /// instructions at the end of the block and leaves `builder` in a state
566 /// suitable for further insertion into the end of the block.
568  llvm::IRBuilderBase &builder) {
569  builder.SetInsertPoint(lookupBlock(&bb));
570  auto *subprogram = builder.GetInsertBlock()->getParent()->getSubprogram();
571 
572  // Before traversing operations, make block arguments available through
573  // value remapping and PHI nodes, but do not add incoming edges for the PHI
574  // nodes just yet: those values may be defined by this or following blocks.
575  // This step is omitted if "ignoreArguments" is set. The arguments of the
576  // first block have been already made available through the remapping of
577  // LLVM function arguments.
578  if (!ignoreArguments) {
579  auto predecessors = bb.getPredecessors();
580  unsigned numPredecessors =
581  std::distance(predecessors.begin(), predecessors.end());
582  for (auto arg : bb.getArguments()) {
583  auto wrappedType = arg.getType();
584  if (!isCompatibleType(wrappedType))
585  return emitError(bb.front().getLoc(),
586  "block argument does not have an LLVM type");
587  llvm::Type *type = convertType(wrappedType);
588  llvm::PHINode *phi = builder.CreatePHI(type, numPredecessors);
589  mapValue(arg, phi);
590  }
591  }
592 
593  // Traverse operations.
594  for (auto &op : bb) {
595  // Set the current debug location within the builder.
596  builder.SetCurrentDebugLocation(
597  debugTranslation->translateLoc(op.getLoc(), subprogram));
598 
599  if (failed(convertOperation(op, builder)))
600  return failure();
601  }
602 
603  return success();
604 }
605 
606 /// A helper method to get the single Block in an operation honoring LLVM's
607 /// module requirements.
608 static Block &getModuleBody(Operation *module) {
609  return module->getRegion(0).front();
610 }
611 
612 /// A helper method to decide if a constant must not be set as a global variable
613 /// initializer. For an external linkage variable, the variable with an
614 /// initializer is considered externally visible and defined in this module, the
615 /// variable without an initializer is externally available and is defined
616 /// elsewhere.
617 static bool shouldDropGlobalInitializer(llvm::GlobalValue::LinkageTypes linkage,
618  llvm::Constant *cst) {
619  return (linkage == llvm::GlobalVariable::ExternalLinkage && !cst) ||
620  linkage == llvm::GlobalVariable::ExternalWeakLinkage;
621 }
622 
623 /// Sets the runtime preemption specifier of `gv` to dso_local if
624 /// `dsoLocalRequested` is true, otherwise it is left unchanged.
625 static void addRuntimePreemptionSpecifier(bool dsoLocalRequested,
626  llvm::GlobalValue *gv) {
627  if (dsoLocalRequested)
628  gv->setDSOLocal(true);
629 }
630 
631 /// Create named global variables that correspond to llvm.mlir.global
632 /// definitions. Convert llvm.global_ctors and global_dtors ops.
633 LogicalResult ModuleTranslation::convertGlobals() {
634  for (auto op : getModuleBody(mlirModule).getOps<LLVM::GlobalOp>()) {
635  llvm::Type *type = convertType(op.getType());
636  llvm::Constant *cst = nullptr;
637  if (op.getValueOrNull()) {
638  // String attributes are treated separately because they cannot appear as
639  // in-function constants and are thus not supported by getLLVMConstant.
640  if (auto strAttr = op.getValueOrNull().dyn_cast_or_null<StringAttr>()) {
641  cst = llvm::ConstantDataArray::getString(
642  llvmModule->getContext(), strAttr.getValue(), /*AddNull=*/false);
643  type = cst->getType();
644  } else if (!(cst = getLLVMConstant(type, op.getValueOrNull(), op.getLoc(),
645  *this))) {
646  return failure();
647  }
648  }
649 
650  auto linkage = convertLinkageToLLVM(op.getLinkage());
651  auto addrSpace = op.getAddrSpace();
652 
653  // LLVM IR requires constant with linkage other than external or weak
654  // external to have initializers. If MLIR does not provide an initializer,
655  // default to undef.
656  bool dropInitializer = shouldDropGlobalInitializer(linkage, cst);
657  if (!dropInitializer && !cst)
658  cst = llvm::UndefValue::get(type);
659  else if (dropInitializer && cst)
660  cst = nullptr;
661 
662  auto *var = new llvm::GlobalVariable(
663  *llvmModule, type, op.getConstant(), linkage, cst, op.getSymName(),
664  /*InsertBefore=*/nullptr,
665  op.getThreadLocal_() ? llvm::GlobalValue::GeneralDynamicTLSModel
666  : llvm::GlobalValue::NotThreadLocal,
667  addrSpace);
668 
669  if (op.getUnnamedAddr().hasValue())
670  var->setUnnamedAddr(convertUnnamedAddrToLLVM(*op.getUnnamedAddr()));
671 
672  if (op.getSection().hasValue())
673  var->setSection(*op.getSection());
674 
675  addRuntimePreemptionSpecifier(op.getDsoLocal(), var);
676 
677  Optional<uint64_t> alignment = op.getAlignment();
678  if (alignment.hasValue())
679  var->setAlignment(llvm::MaybeAlign(alignment.getValue()));
680 
681  globalsMapping.try_emplace(op, var);
682  }
683 
684  // Convert global variable bodies. This is done after all global variables
685  // have been created in LLVM IR because a global body may refer to another
686  // global or itself. So all global variables need to be mapped first.
687  for (auto op : getModuleBody(mlirModule).getOps<LLVM::GlobalOp>()) {
688  if (Block *initializer = op.getInitializerBlock()) {
689  llvm::IRBuilder<> builder(llvmModule->getContext());
690  for (auto &op : initializer->without_terminator()) {
691  if (failed(convertOperation(op, builder)) ||
692  !isa<llvm::Constant>(lookupValue(op.getResult(0))))
693  return emitError(op.getLoc(), "unemittable constant value");
694  }
695  ReturnOp ret = cast<ReturnOp>(initializer->getTerminator());
696  llvm::Constant *cst =
697  cast<llvm::Constant>(lookupValue(ret.getOperand(0)));
698  auto *global = cast<llvm::GlobalVariable>(lookupGlobal(op));
699  if (!shouldDropGlobalInitializer(global->getLinkage(), cst))
700  global->setInitializer(cst);
701  }
702  }
703 
704  // Convert llvm.mlir.global_ctors and dtors.
705  for (Operation &op : getModuleBody(mlirModule)) {
706  auto ctorOp = dyn_cast<GlobalCtorsOp>(op);
707  auto dtorOp = dyn_cast<GlobalDtorsOp>(op);
708  if (!ctorOp && !dtorOp)
709  continue;
710  auto range = ctorOp ? llvm::zip(ctorOp.getCtors(), ctorOp.getPriorities())
711  : llvm::zip(dtorOp.getDtors(), dtorOp.getPriorities());
712  auto appendGlobalFn =
713  ctorOp ? llvm::appendToGlobalCtors : llvm::appendToGlobalDtors;
714  for (auto symbolAndPriority : range) {
715  llvm::Function *f = lookupFunction(
716  std::get<0>(symbolAndPriority).cast<FlatSymbolRefAttr>().getValue());
717  appendGlobalFn(
718  *llvmModule, f,
719  std::get<1>(symbolAndPriority).cast<IntegerAttr>().getInt(),
720  /*Data=*/nullptr);
721  }
722  }
723 
724  return success();
725 }
726 
727 /// Attempts to add an attribute identified by `key`, optionally with the given
728 /// `value` to LLVM function `llvmFunc`. Reports errors at `loc` if any. If the
729 /// attribute has a kind known to LLVM IR, create the attribute of this kind,
730 /// otherwise keep it as a string attribute. Performs additional checks for
731 /// attributes known to have or not have a value in order to avoid assertions
732 /// inside LLVM upon construction.
734  llvm::Function *llvmFunc,
735  StringRef key,
736  StringRef value = StringRef()) {
737  auto kind = llvm::Attribute::getAttrKindFromName(key);
738  if (kind == llvm::Attribute::None) {
739  llvmFunc->addFnAttr(key, value);
740  return success();
741  }
742 
743  if (llvm::Attribute::isIntAttrKind(kind)) {
744  if (value.empty())
745  return emitError(loc) << "LLVM attribute '" << key << "' expects a value";
746 
747  int result;
748  if (!value.getAsInteger(/*Radix=*/0, result))
749  llvmFunc->addFnAttr(
750  llvm::Attribute::get(llvmFunc->getContext(), kind, result));
751  else
752  llvmFunc->addFnAttr(key, value);
753  return success();
754  }
755 
756  if (!value.empty())
757  return emitError(loc) << "LLVM attribute '" << key
758  << "' does not expect a value, found '" << value
759  << "'";
760 
761  llvmFunc->addFnAttr(kind);
762  return success();
763 }
764 
765 /// Attaches the attributes listed in the given array attribute to `llvmFunc`.
766 /// Reports error to `loc` if any and returns immediately. Expects `attributes`
767 /// to be an array attribute containing either string attributes, treated as
768 /// value-less LLVM attributes, or array attributes containing two string
769 /// attributes, with the first string being the name of the corresponding LLVM
770 /// attribute and the second string beings its value. Note that even integer
771 /// attributes are expected to have their values expressed as strings.
772 static LogicalResult
774  llvm::Function *llvmFunc) {
775  if (!attributes)
776  return success();
777 
778  for (Attribute attr : *attributes) {
779  if (auto stringAttr = attr.dyn_cast<StringAttr>()) {
780  if (failed(
781  checkedAddLLVMFnAttribute(loc, llvmFunc, stringAttr.getValue())))
782  return failure();
783  continue;
784  }
785 
786  auto arrayAttr = attr.dyn_cast<ArrayAttr>();
787  if (!arrayAttr || arrayAttr.size() != 2)
788  return emitError(loc)
789  << "expected 'passthrough' to contain string or array attributes";
790 
791  auto keyAttr = arrayAttr[0].dyn_cast<StringAttr>();
792  auto valueAttr = arrayAttr[1].dyn_cast<StringAttr>();
793  if (!keyAttr || !valueAttr)
794  return emitError(loc)
795  << "expected arrays within 'passthrough' to contain two strings";
796 
797  if (failed(checkedAddLLVMFnAttribute(loc, llvmFunc, keyAttr.getValue(),
798  valueAttr.getValue())))
799  return failure();
800  }
801  return success();
802 }
803 
804 LogicalResult ModuleTranslation::convertOneFunction(LLVMFuncOp func) {
805  // Clear the block, branch value mappings, they are only relevant within one
806  // function.
807  blockMapping.clear();
808  valueMapping.clear();
809  branchMapping.clear();
810  llvm::Function *llvmFunc = lookupFunction(func.getName());
811 
812  // Translate the debug information for this function.
813  debugTranslation->translate(func, *llvmFunc);
814 
815  // Add function arguments to the value remapping table.
816  // If there was noalias info then we decorate each argument accordingly.
817  unsigned int argIdx = 0;
818  for (auto kvp : llvm::zip(func.getArguments(), llvmFunc->args())) {
819  llvm::Argument &llvmArg = std::get<1>(kvp);
820  BlockArgument mlirArg = std::get<0>(kvp);
821 
822  if (auto attr = func.getArgAttrOfType<UnitAttr>(
823  argIdx, LLVMDialect::getNoAliasAttrName())) {
824  // NB: Attribute already verified to be boolean, so check if we can indeed
825  // attach the attribute to this argument, based on its type.
826  auto argTy = mlirArg.getType();
827  if (!argTy.isa<LLVM::LLVMPointerType>())
828  return func.emitError(
829  "llvm.noalias attribute attached to LLVM non-pointer argument");
830  llvmArg.addAttr(llvm::Attribute::AttrKind::NoAlias);
831  }
832 
833  if (auto attr = func.getArgAttrOfType<IntegerAttr>(
834  argIdx, LLVMDialect::getAlignAttrName())) {
835  // NB: Attribute already verified to be int, so check if we can indeed
836  // attach the attribute to this argument, based on its type.
837  auto argTy = mlirArg.getType();
838  if (!argTy.isa<LLVM::LLVMPointerType>())
839  return func.emitError(
840  "llvm.align attribute attached to LLVM non-pointer argument");
841  llvmArg.addAttrs(llvm::AttrBuilder(llvmArg.getContext())
842  .addAlignmentAttr(llvm::Align(attr.getInt())));
843  }
844 
845  if (auto attr = func.getArgAttrOfType<UnitAttr>(argIdx, "llvm.sret")) {
846  auto argTy = mlirArg.getType().dyn_cast<LLVM::LLVMPointerType>();
847  if (!argTy)
848  return func.emitError(
849  "llvm.sret attribute attached to LLVM non-pointer argument");
850  llvmArg.addAttrs(
851  llvm::AttrBuilder(llvmArg.getContext())
852  .addStructRetAttr(convertType(argTy.getElementType())));
853  }
854 
855  if (auto attr = func.getArgAttrOfType<UnitAttr>(argIdx, "llvm.byval")) {
856  auto argTy = mlirArg.getType().dyn_cast<LLVM::LLVMPointerType>();
857  if (!argTy)
858  return func.emitError(
859  "llvm.byval attribute attached to LLVM non-pointer argument");
860  llvmArg.addAttrs(llvm::AttrBuilder(llvmArg.getContext())
861  .addByValAttr(convertType(argTy.getElementType())));
862  }
863 
864  if (auto attr = func.getArgAttrOfType<UnitAttr>(argIdx, "llvm.nest")) {
865  auto argTy = mlirArg.getType();
866  if (!argTy.isa<LLVM::LLVMPointerType>())
867  return func.emitError(
868  "llvm.nest attribute attached to LLVM non-pointer argument");
869  llvmArg.addAttrs(llvm::AttrBuilder(llvmArg.getContext())
870  .addAttribute(llvm::Attribute::Nest));
871  }
872 
873  mapValue(mlirArg, &llvmArg);
874  argIdx++;
875  }
876 
877  // Check the personality and set it.
878  if (func.getPersonality().hasValue()) {
879  llvm::Type *ty = llvm::Type::getInt8PtrTy(llvmFunc->getContext());
880  if (llvm::Constant *pfunc = getLLVMConstant(ty, func.getPersonalityAttr(),
881  func.getLoc(), *this))
882  llvmFunc->setPersonalityFn(pfunc);
883  }
884 
885  if (auto gc = func.getGarbageCollector())
886  llvmFunc->setGC(gc->str());
887 
888  // First, create all blocks so we can jump to them.
889  llvm::LLVMContext &llvmContext = llvmFunc->getContext();
890  for (auto &bb : func) {
891  auto *llvmBB = llvm::BasicBlock::Create(llvmContext);
892  llvmBB->insertInto(llvmFunc);
893  mapBlock(&bb, llvmBB);
894  }
895 
896  // Then, convert blocks one by one in topological order to ensure defs are
897  // converted before uses.
898  auto blocks = detail::getTopologicallySortedBlocks(func.getBody());
899  for (Block *bb : blocks) {
900  llvm::IRBuilder<> builder(llvmContext);
901  if (failed(convertBlock(*bb, bb->isEntryBlock(), builder)))
902  return failure();
903  }
904 
905  // After all blocks have been traversed and values mapped, connect the PHI
906  // nodes to the results of preceding blocks.
907  detail::connectPHINodes(func.getBody(), *this);
908 
909  // Finally, convert dialect attributes attached to the function.
910  return convertDialectAttributes(func);
911 }
912 
913 LogicalResult ModuleTranslation::convertDialectAttributes(Operation *op) {
914  for (NamedAttribute attribute : op->getDialectAttrs())
915  if (failed(iface.amendOperation(op, attribute, *this)))
916  return failure();
917  return success();
918 }
919 
920 LogicalResult ModuleTranslation::convertFunctionSignatures() {
921  // Declare all functions first because there may be function calls that form a
922  // call graph with cycles, or global initializers that reference functions.
923  for (auto function : getModuleBody(mlirModule).getOps<LLVMFuncOp>()) {
924  llvm::FunctionCallee llvmFuncCst = llvmModule->getOrInsertFunction(
925  function.getName(),
926  cast<llvm::FunctionType>(convertType(function.getFunctionType())));
927  llvm::Function *llvmFunc = cast<llvm::Function>(llvmFuncCst.getCallee());
928  llvmFunc->setLinkage(convertLinkageToLLVM(function.getLinkage()));
929  mapFunction(function.getName(), llvmFunc);
930  addRuntimePreemptionSpecifier(function.getDsoLocal(), llvmFunc);
931 
932  // Forward the pass-through attributes to LLVM.
934  function.getLoc(), function.getPassthrough(), llvmFunc)))
935  return failure();
936  }
937 
938  return success();
939 }
940 
941 LogicalResult ModuleTranslation::convertFunctions() {
942  // Convert functions.
943  for (auto function : getModuleBody(mlirModule).getOps<LLVMFuncOp>()) {
944  // Ignore external functions.
945  if (function.isExternal())
946  continue;
947 
948  if (failed(convertOneFunction(function)))
949  return failure();
950  }
951 
952  return success();
953 }
954 
955 llvm::MDNode *
957  SymbolRefAttr accessGroupRef) const {
958  auto metadataName = accessGroupRef.getRootReference();
959  auto accessGroupName = accessGroupRef.getLeafReference();
960  auto metadataOp = SymbolTable::lookupNearestSymbolFrom<LLVM::MetadataOp>(
961  opInst.getParentOp(), metadataName);
962  auto *accessGroupOp =
963  SymbolTable::lookupNearestSymbolFrom(metadataOp, accessGroupName);
964  return accessGroupMetadataMapping.lookup(accessGroupOp);
965 }
966 
967 LogicalResult ModuleTranslation::createAccessGroupMetadata() {
968  mlirModule->walk([&](LLVM::MetadataOp metadatas) {
969  metadatas.walk([&](LLVM::AccessGroupMetadataOp op) {
970  llvm::LLVMContext &ctx = llvmModule->getContext();
971  llvm::MDNode *accessGroup = llvm::MDNode::getDistinct(ctx, {});
972  accessGroupMetadataMapping.insert({op, accessGroup});
973  });
974  });
975  return success();
976 }
977 
979  llvm::Instruction *inst) {
980  auto accessGroups =
981  op->getAttrOfType<ArrayAttr>(LLVMDialect::getAccessGroupsAttrName());
982  if (accessGroups && !accessGroups.empty()) {
983  llvm::Module *module = inst->getModule();
985  for (SymbolRefAttr accessGroupRef :
986  accessGroups.getAsRange<SymbolRefAttr>())
987  metadatas.push_back(getAccessGroup(*op, accessGroupRef));
988 
989  llvm::MDNode *unionMD = nullptr;
990  if (metadatas.size() == 1)
991  unionMD = llvm::cast<llvm::MDNode>(metadatas.front());
992  else if (metadatas.size() >= 2)
993  unionMD = llvm::MDNode::get(module->getContext(), metadatas);
994 
995  inst->setMetadata(module->getMDKindID("llvm.access.group"), unionMD);
996  }
997 }
998 
999 LogicalResult ModuleTranslation::createAliasScopeMetadata() {
1000  mlirModule->walk([&](LLVM::MetadataOp metadatas) {
1001  // Create the domains first, so they can be reference below in the scopes.
1002  DenseMap<Operation *, llvm::MDNode *> aliasScopeDomainMetadataMapping;
1003  metadatas.walk([&](LLVM::AliasScopeDomainMetadataOp op) {
1004  llvm::LLVMContext &ctx = llvmModule->getContext();
1006  operands.push_back({}); // Placeholder for self-reference
1007  if (Optional<StringRef> description = op.getDescription())
1008  operands.push_back(llvm::MDString::get(ctx, description.getValue()));
1009  llvm::MDNode *domain = llvm::MDNode::get(ctx, operands);
1010  domain->replaceOperandWith(0, domain); // Self-reference for uniqueness
1011  aliasScopeDomainMetadataMapping.insert({op, domain});
1012  });
1013 
1014  // Now create the scopes, referencing the domains created above.
1015  metadatas.walk([&](LLVM::AliasScopeMetadataOp op) {
1016  llvm::LLVMContext &ctx = llvmModule->getContext();
1017  assert(isa<LLVM::MetadataOp>(op->getParentOp()));
1018  auto metadataOp = dyn_cast<LLVM::MetadataOp>(op->getParentOp());
1019  Operation *domainOp =
1020  SymbolTable::lookupNearestSymbolFrom(metadataOp, op.getDomainAttr());
1021  llvm::MDNode *domain = aliasScopeDomainMetadataMapping.lookup(domainOp);
1022  assert(domain && "Scope's domain should already be valid");
1024  operands.push_back({}); // Placeholder for self-reference
1025  operands.push_back(domain);
1026  if (Optional<StringRef> description = op.getDescription())
1027  operands.push_back(llvm::MDString::get(ctx, description.getValue()));
1028  llvm::MDNode *scope = llvm::MDNode::get(ctx, operands);
1029  scope->replaceOperandWith(0, scope); // Self-reference for uniqueness
1030  aliasScopeMetadataMapping.insert({op, scope});
1031  });
1032  });
1033  return success();
1034 }
1035 
1036 llvm::MDNode *
1038  SymbolRefAttr aliasScopeRef) const {
1039  StringAttr metadataName = aliasScopeRef.getRootReference();
1040  StringAttr scopeName = aliasScopeRef.getLeafReference();
1041  auto metadataOp = SymbolTable::lookupNearestSymbolFrom<LLVM::MetadataOp>(
1042  opInst.getParentOp(), metadataName);
1043  Operation *aliasScopeOp =
1044  SymbolTable::lookupNearestSymbolFrom(metadataOp, scopeName);
1045  return aliasScopeMetadataMapping.lookup(aliasScopeOp);
1046 }
1047 
1049  llvm::Instruction *inst) {
1050  auto populateScopeMetadata = [this, op, inst](StringRef attrName,
1051  StringRef llvmMetadataName) {
1052  auto scopes = op->getAttrOfType<ArrayAttr>(attrName);
1053  if (!scopes || scopes.empty())
1054  return;
1055  llvm::Module *module = inst->getModule();
1057  for (SymbolRefAttr scopeRef : scopes.getAsRange<SymbolRefAttr>())
1058  scopeMDs.push_back(getAliasScope(*op, scopeRef));
1059  llvm::MDNode *unionMD = llvm::MDNode::get(module->getContext(), scopeMDs);
1060  inst->setMetadata(module->getMDKindID(llvmMetadataName), unionMD);
1061  };
1062 
1063  populateScopeMetadata(LLVMDialect::getAliasScopesAttrName(), "alias.scope");
1064  populateScopeMetadata(LLVMDialect::getNoAliasScopesAttrName(), "noalias");
1065 }
1066 
1068  return typeTranslator.translateType(type);
1069 }
1070 
1071 /// A helper to look up remapped operands in the value remapping table.
1073  SmallVector<llvm::Value *> remapped;
1074  remapped.reserve(values.size());
1075  for (Value v : values)
1076  remapped.push_back(lookupValue(v));
1077  return remapped;
1078 }
1079 
1080 const llvm::DILocation *
1081 ModuleTranslation::translateLoc(Location loc, llvm::DILocalScope *scope) {
1082  return debugTranslation->translateLoc(loc, scope);
1083 }
1084 
1085 llvm::NamedMDNode *
1087  return llvmModule->getOrInsertNamedMetadata(name);
1088 }
1089 
1090 void ModuleTranslation::StackFrame::anchor() {}
1091 
1092 static std::unique_ptr<llvm::Module>
1093 prepareLLVMModule(Operation *m, llvm::LLVMContext &llvmContext,
1094  StringRef name) {
1095  m->getContext()->getOrLoadDialect<LLVM::LLVMDialect>();
1096  auto llvmModule = std::make_unique<llvm::Module>(name, llvmContext);
1097  if (auto dataLayoutAttr =
1098  m->getAttr(LLVM::LLVMDialect::getDataLayoutAttrName())) {
1099  llvmModule->setDataLayout(dataLayoutAttr.cast<StringAttr>().getValue());
1100  } else {
1101  FailureOr<llvm::DataLayout> llvmDataLayout(llvm::DataLayout(""));
1102  if (auto iface = dyn_cast<DataLayoutOpInterface>(m)) {
1103  if (DataLayoutSpecInterface spec = iface.getDataLayoutSpec()) {
1104  llvmDataLayout =
1105  translateDataLayout(spec, DataLayout(iface), m->getLoc());
1106  }
1107  } else if (auto mod = dyn_cast<ModuleOp>(m)) {
1108  if (DataLayoutSpecInterface spec = mod.getDataLayoutSpec()) {
1109  llvmDataLayout =
1110  translateDataLayout(spec, DataLayout(mod), m->getLoc());
1111  }
1112  }
1113  if (failed(llvmDataLayout))
1114  return nullptr;
1115  llvmModule->setDataLayout(*llvmDataLayout);
1116  }
1117  if (auto targetTripleAttr =
1118  m->getAttr(LLVM::LLVMDialect::getTargetTripleAttrName()))
1119  llvmModule->setTargetTriple(targetTripleAttr.cast<StringAttr>().getValue());
1120 
1121  // Inject declarations for `malloc` and `free` functions that can be used in
1122  // memref allocation/deallocation coming from standard ops lowering.
1123  llvm::IRBuilder<> builder(llvmContext);
1124  llvmModule->getOrInsertFunction("malloc", builder.getInt8PtrTy(),
1125  builder.getInt64Ty());
1126  llvmModule->getOrInsertFunction("free", builder.getVoidTy(),
1127  builder.getInt8PtrTy());
1128 
1129  return llvmModule;
1130 }
1131 
1132 std::unique_ptr<llvm::Module>
1133 mlir::translateModuleToLLVMIR(Operation *module, llvm::LLVMContext &llvmContext,
1134  StringRef name) {
1135  if (!satisfiesLLVMModule(module))
1136  return nullptr;
1137 
1138  std::unique_ptr<llvm::Module> llvmModule =
1139  prepareLLVMModule(module, llvmContext, name);
1140  if (!llvmModule)
1141  return nullptr;
1142 
1144 
1145  ModuleTranslation translator(module, std::move(llvmModule));
1146  if (failed(translator.convertFunctionSignatures()))
1147  return nullptr;
1148  if (failed(translator.convertGlobals()))
1149  return nullptr;
1150  if (failed(translator.createAccessGroupMetadata()))
1151  return nullptr;
1152  if (failed(translator.createAliasScopeMetadata()))
1153  return nullptr;
1154  if (failed(translator.convertFunctions()))
1155  return nullptr;
1156 
1157  // Convert other top-level operations if possible.
1158  llvm::IRBuilder<> llvmBuilder(llvmContext);
1159  for (Operation &o : getModuleBody(module).getOperations()) {
1160  if (!isa<LLVM::LLVMFuncOp, LLVM::GlobalOp, LLVM::GlobalCtorsOp,
1161  LLVM::GlobalDtorsOp, LLVM::MetadataOp>(&o) &&
1162  !o.hasTrait<OpTrait::IsTerminator>() &&
1163  failed(translator.convertOperation(o, llvmBuilder))) {
1164  return nullptr;
1165  }
1166  }
1167 
1168  if (llvm::verifyModule(*translator.llvmModule, &llvm::errs()))
1169  return nullptr;
1170 
1171  return std::move(translator.llvmModule);
1172 }
Include the generated interface declarations.
This class contains a list of basic blocks and a link to the parent operation it is attached to...
Definition: Region.h:26
Operation is a basic unit of execution within MLIR.
Definition: Operation.h:28
llvm::MDNode * getAliasScope(Operation &opInst, SymbolRefAttr aliasScopeRef) const
Returns the LLVM metadata corresponding to a reference to an mlir LLVM dialect alias scope operation...
Block represents an ordered list of Operations.
Definition: Block.h:29
Block & front()
Definition: Region.h:65
const llvm::DILocation * translateLoc(Location loc, llvm::DILocalScope *scope)
Translates the given location.
llvm::Type * convertType(Type type)
Converts the type from MLIR LLVM dialect to LLVM.
llvm::NamedMDNode * getOrInsertNamedModuleMetadata(StringRef name)
Gets the named metadata in the LLVM IR module being constructed, creating it if it does not exist...
A symbol reference with a reference path containing a single element.
static llvm::Type * getInnermostElementType(llvm::Type *type)
Returns the first non-sequential type nested in sequential types.
Value getOperand(unsigned idx)
Definition: Operation.h:274
AttrClass getAttrOfType(StringAttr name)
Definition: Operation.h:382
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value...
Definition: LogicalResult.h:72
llvm::LLVMContext & getLLVMContext() const
Returns the LLVM context in which the IR is being constructed.
iterator_range< pred_iterator > getPredecessors()
Definition: Block.h:225
ShapedType getType() const
Return the type of this ElementsAttr, guaranteed to be a vector or tensor with static shape...
void setAccessGroupsMetadata(Operation *op, llvm::Instruction *inst)
This class provides the API for ops that are known to be terminators.
Definition: OpDefinition.h:697
SmallVector< llvm::Value * > lookupValues(ValueRange values)
Looks up remapped a list of remapped values.
unsigned getNumSuccessors()
Definition: Operation.h:504
LogicalResult convertBlock(Block &bb, bool ignoreArguments, llvm::IRBuilderBase &builder)
Translates the contents of the given block to LLVM IR using this translator.
Operation & front()
Definition: Block.h:144
llvm::BasicBlock * lookupBlock(Block *block) const
Finds an LLVM IR basic block that corresponds to the given MLIR block.
llvm::PointerUnion< NamedAttribute *, NamedTypeConstraint * > Argument
Definition: Argument.h:62
static constexpr const bool value
void forgetMapping(Region &region)
Removes the mapping for blocks contained in the region and values defined in these blocks...
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition: Location.h:48
NamedAttribute represents a combination of a name and an Attribute value.
Definition: Attributes.h:144
llvm::Value * createIntrinsicCall(llvm::IRBuilderBase &builder, llvm::Intrinsic::ID intrinsic, ArrayRef< llvm::Value *> args={}, ArrayRef< llvm::Type *> tys={})
Creates a call to an LLVM IR intrinsic function with the given arguments.
Implementation class for module translation.
MLIRContext * getContext()
Return the context this operation is associated with.
Definition: Operation.h:154
static LogicalResult forwardPassthroughAttributes(Location loc, Optional< ArrayAttr > attributes, llvm::Function *llvmFunc)
Attaches the attributes listed in the given array attribute to llvmFunc.
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:56
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:62
static LogicalResult checkedAddLLVMFnAttribute(Location loc, llvm::Function *llvmFunc, StringRef key, StringRef value=StringRef())
Attempts to add an attribute identified by key, optionally with the given value to LLVM function llvm...
bool isCompatibleType(Type type)
Returns true if the given type is compatible with the LLVM dialect.
Definition: LLVMTypes.cpp:778
Block * getSuccessor(unsigned index)
Definition: Operation.h:506
static llvm::Constant * buildSequentialConstant(ArrayRef< llvm::Constant *> &constants, ArrayRef< int64_t > shape, llvm::Type *type, Location loc)
Builds a constant of a sequential LLVM type type, potentially containing other sequential types recur...
iterator begin()
Definition: Region.h:55
This class provides support for representing a failure result, or a valid value of type T...
Definition: LogicalResult.h:77
An attribute that represents a reference to a dense vector or tensor object.
static llvm::Constant * convertDenseElementsAttr(Location loc, DenseElementsAttr denseElementsAttr, llvm::Type *llvmType, const ModuleTranslation &moduleTranslation)
Convert a dense elements attribute to an LLVM IR constant using its raw data storage if possible...
Base class for dialect interfaces providing translation to LLVM IR.
llvm::Instruction * lookupBranch(Operation *op) const
Finds an LLVM IR instruction that corresponds to the given MLIR operation with successors.
Type getFunctionType(Builder &builder, ArrayRef< OpAsmParser::Argument > argAttrs, ArrayRef< Type > resultTypes)
Get a function type corresponding to an array of arguments (which have types) and a set of result typ...
U dyn_cast() const
Definition: Types.h:244
unsigned getNumArguments()
Definition: Block.h:119
ArrayRef< char > getRawData() const
Return the raw storage data held by this attribute.
Attributes are known-constant values of operations.
Definition: Attributes.h:24
Operation * getParentOp()
Returns the closest surrounding operation that contains this operation or nullptr if this is a top-le...
Definition: Operation.h:172
constexpr void enumerate(std::tuple< Tys... > &tuple, CallbackT &&callback)
Definition: Matchers.h:234
unsigned getTypeABIAlignment(Type t) const
Returns the required alignment of the given type in the current scope.
OpResult getResult(unsigned idx)
Get the &#39;idx&#39;th result of this operation.
Definition: Operation.h:331
int64_t mod(int64_t lhs, int64_t rhs)
Returns MLIR&#39;s mod operation on constants.
Definition: MathExtras.h:45
Location getLoc()
The source location the operation was defined or derived from.
Definition: Operation.h:161
static void addRuntimePreemptionSpecifier(bool dsoLocalRequested, llvm::GlobalValue *gv)
Sets the runtime preemption specifier of gv to dso_local if dsoLocalRequested is true, otherwise it is left unchanged.
This class models how operands are forwarded to block arguments in control flow.
BlockArgListType getArguments()
Definition: Block.h:76
This class represents an argument of a Block.
Definition: Value.h:300
static Block & getModuleBody(Operation *module)
A helper method to get the single Block in an operation honoring LLVM&#39;s module requirements.
Tensor types represent multi-dimensional arrays, and have two variants: RankedTensorType and Unranked...
Definition: BuiltinTypes.h:77
virtual LogicalResult convertOperation(Operation *op, llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation) const
Hook for derived dialect interface to provide translation of the operations to LLVM IR...
bool satisfiesLLVMModule(Operation *op)
LLVM requires some operations to be inside of a Module operation.
void setAliasScopeMetadata(Operation *op, llvm::Instruction *inst)
llvm::Value * lookupValue(Value value) const
Finds an LLVM IR value corresponding to the given MLIR value.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:72
static Operation * lookupNearestSymbolFrom(Operation *from, StringAttr symbol)
Returns the operation registered with the given symbol name within the closest parent operation of...
static std::unique_ptr< llvm::Module > prepareLLVMModule(Operation *m, llvm::LLVMContext &llvmContext, StringRef name)
unsigned getTypeSizeInBits(Type t) const
Returns the size in bits of the given type in the current scope.
void connectPHINodes(Region &region, const ModuleTranslation &state)
For all blocks in the region that were converted to LLVM IR using the given ModuleTranslation, connect the PHI nodes of the corresponding LLVM IR blocks to the results of preceding blocks.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:85
An attribute that represents a reference to a splat vector or tensor constant, meaning all of the ele...
static Value getPHISourceValue(Block *current, Block *pred, unsigned numArguments, unsigned index)
Get the SSA value passed to the current block from the terminator operation of its predecessor...
Operation * getTerminator()
Get the terminator operation of this block.
Definition: Block.cpp:230
T * getOrLoadDialect()
Get (or create) a dialect for the given derived dialect type.
Definition: MLIRContext.h:92
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
llvm::Function * lookupFunction(StringRef name) const
Finds an LLVM IR function by its name.
Type getType() const
Return the type of this value.
Definition: Value.h:118
iterator end()
Definition: Region.h:56
unsigned getTypePreferredAlignment(Type t) const
Returns the preferred of the given type in the current scope.
U dyn_cast() const
Definition: Attributes.h:124
llvm::MDNode * getAccessGroup(Operation &opInst, SymbolRefAttr accessGroupRef) const
Returns the LLVM metadata corresponding to a reference to an mlir LLVM dialect access group operation...
SetVector< Block * > getTopologicallySortedBlocks(Region &region)
Get a topologically sorted list of blocks of the given region.
std::unique_ptr< llvm::Module > translateModuleToLLVMIR(Operation *module, llvm::LLVMContext &llvmContext, llvm::StringRef name="LLVMDialectModule")
Translate operation that satisfies LLVM dialect module requirements into an LLVM IR module living in ...
LLVM dialect pointer type.
Definition: LLVMTypes.h:182
int64_t getNumElements() const
Returns the number of elements held by this attribute.
dialect_attr_range getDialectAttrs()
Return a range corresponding to the dialect attributes for this operation.
Definition: Operation.h:445
llvm::Constant * getLLVMConstant(llvm::Type *llvmType, Attribute attr, Location loc, const ModuleTranslation &moduleTranslation)
Create an LLVM IR constant of llvmType from the MLIR attribute attr.
void ensureDistinctSuccessors(Operation *op)
Make argument-taking successors of each block distinct.
OperationName getName()
The name of an operation is the key identifier for it.
Definition: Operation.h:57
bool isSplat() const
Returns true if this attribute corresponds to a splat, i.e.
InFlightDiagnostic emitError(const Twine &message={})
Emit an error about fatal conditions with this operation, reporting up to any diagnostic handlers tha...
Definition: Operation.cpp:231
std::enable_if<!std::is_base_of< Attribute, T >::value||std::is_same< Attribute, T >::value, T >::type getSplatValue() const
Return the splat value for this attribute.
This class provides an abstraction over the different types of ranges over Values.
Attribute getAttr(StringAttr name)
Return the specified attribute if present, null otherwise.
Definition: Operation.h:378
DataLayoutSpecInterface translateDataLayout(const llvm::DataLayout &dataLayout, MLIRContext *context)
Translate the given LLVM data layout into an MLIR equivalent using the DLTI dialect.
Region & getRegion(unsigned index)
Returns the region held by this operation at position &#39;index&#39;.
Definition: Operation.h:484
The main mechanism for performing data layout queries.
static bool shouldDropGlobalInitializer(llvm::GlobalValue::LinkageTypes linkage, llvm::Constant *cst)
A helper method to decide if a constant must not be set as a global variable initializer.