MLIR  21.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 "AttrKindDetail.h"
17 #include "DebugTranslation.h"
20 #include "mlir/Dialect/DLTI/DLTI.h"
28 #include "mlir/IR/Attributes.h"
29 #include "mlir/IR/BuiltinOps.h"
30 #include "mlir/IR/BuiltinTypes.h"
33 #include "mlir/Support/LLVM.h"
36 
37 #include "llvm/ADT/PostOrderIterator.h"
38 #include "llvm/ADT/SetVector.h"
39 #include "llvm/ADT/StringExtras.h"
40 #include "llvm/ADT/TypeSwitch.h"
41 #include "llvm/Analysis/TargetFolder.h"
42 #include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
43 #include "llvm/IR/BasicBlock.h"
44 #include "llvm/IR/CFG.h"
45 #include "llvm/IR/Constants.h"
46 #include "llvm/IR/DerivedTypes.h"
47 #include "llvm/IR/IRBuilder.h"
48 #include "llvm/IR/InlineAsm.h"
49 #include "llvm/IR/IntrinsicsNVPTX.h"
50 #include "llvm/IR/LLVMContext.h"
51 #include "llvm/IR/MDBuilder.h"
52 #include "llvm/IR/Module.h"
53 #include "llvm/IR/Verifier.h"
54 #include "llvm/Support/Debug.h"
55 #include "llvm/Support/raw_ostream.h"
56 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
57 #include "llvm/Transforms/Utils/Cloning.h"
58 #include "llvm/Transforms/Utils/ModuleUtils.h"
59 #include <numeric>
60 #include <optional>
61 
62 #define DEBUG_TYPE "llvm-dialect-to-llvm-ir"
63 
64 using namespace mlir;
65 using namespace mlir::LLVM;
66 using namespace mlir::LLVM::detail;
67 
68 extern llvm::cl::opt<bool> UseNewDbgInfoFormat;
69 
70 #include "mlir/Dialect/LLVMIR/LLVMConversionEnumsToLLVM.inc"
71 
72 namespace {
73 /// A customized inserter for LLVM's IRBuilder that captures all LLVM IR
74 /// instructions that are created for future reference.
75 ///
76 /// This is intended to be used with the `CollectionScope` RAII object:
77 ///
78 /// llvm::IRBuilder<..., InstructionCapturingInserter> builder;
79 /// {
80 /// InstructionCapturingInserter::CollectionScope scope(builder);
81 /// // Call IRBuilder methods as usual.
82 ///
83 /// // This will return a list of all instructions created by the builder,
84 /// // in order of creation.
85 /// builder.getInserter().getCapturedInstructions();
86 /// }
87 /// // This will return an empty list.
88 /// builder.getInserter().getCapturedInstructions();
89 ///
90 /// The capturing functionality is _disabled_ by default for performance
91 /// consideration. It needs to be explicitly enabled, which is achieved by
92 /// creating a `CollectionScope`.
93 class InstructionCapturingInserter : public llvm::IRBuilderCallbackInserter {
94 public:
95  /// Constructs the inserter.
96  InstructionCapturingInserter()
97  : llvm::IRBuilderCallbackInserter([this](llvm::Instruction *instruction) {
98  if (LLVM_LIKELY(enabled))
99  capturedInstructions.push_back(instruction);
100  }) {}
101 
102  /// Returns the list of LLVM IR instructions captured since the last cleanup.
103  ArrayRef<llvm::Instruction *> getCapturedInstructions() const {
104  return capturedInstructions;
105  }
106 
107  /// Clears the list of captured LLVM IR instructions.
108  void clearCapturedInstructions() { capturedInstructions.clear(); }
109 
110  /// RAII object enabling the capture of created LLVM IR instructions.
111  class CollectionScope {
112  public:
113  /// Creates the scope for the given inserter.
114  CollectionScope(llvm::IRBuilderBase &irBuilder, bool isBuilderCapturing);
115 
116  /// Ends the scope.
117  ~CollectionScope();
118 
119  ArrayRef<llvm::Instruction *> getCapturedInstructions() {
120  if (!inserter)
121  return {};
122  return inserter->getCapturedInstructions();
123  }
124 
125  private:
126  /// Back reference to the inserter.
127  InstructionCapturingInserter *inserter = nullptr;
128 
129  /// List of instructions in the inserter prior to this scope.
130  SmallVector<llvm::Instruction *> previouslyCollectedInstructions;
131 
132  /// Whether the inserter was enabled prior to this scope.
133  bool wasEnabled;
134  };
135 
136  /// Enable or disable the capturing mechanism.
137  void setEnabled(bool enabled = true) { this->enabled = enabled; }
138 
139 private:
140  /// List of captured instructions.
141  SmallVector<llvm::Instruction *> capturedInstructions;
142 
143  /// Whether the collection is enabled.
144  bool enabled = false;
145 };
146 
147 using CapturingIRBuilder =
148  llvm::IRBuilder<llvm::TargetFolder, InstructionCapturingInserter>;
149 } // namespace
150 
151 InstructionCapturingInserter::CollectionScope::CollectionScope(
152  llvm::IRBuilderBase &irBuilder, bool isBuilderCapturing) {
153 
154  if (!isBuilderCapturing)
155  return;
156 
157  auto &capturingIRBuilder = static_cast<CapturingIRBuilder &>(irBuilder);
158  inserter = &capturingIRBuilder.getInserter();
159  wasEnabled = inserter->enabled;
160  if (wasEnabled)
161  previouslyCollectedInstructions.swap(inserter->capturedInstructions);
162  inserter->setEnabled(true);
163 }
164 
165 InstructionCapturingInserter::CollectionScope::~CollectionScope() {
166  if (!inserter)
167  return;
168 
169  previouslyCollectedInstructions.swap(inserter->capturedInstructions);
170  // If collection was enabled (likely in another, surrounding scope), keep
171  // the instructions collected in this scope.
172  if (wasEnabled) {
173  llvm::append_range(inserter->capturedInstructions,
174  previouslyCollectedInstructions);
175  }
176  inserter->setEnabled(wasEnabled);
177 }
178 
179 /// Translates the given data layout spec attribute to the LLVM IR data layout.
180 /// Only integer, float, pointer and endianness entries are currently supported.
181 static FailureOr<llvm::DataLayout>
182 translateDataLayout(DataLayoutSpecInterface attribute,
183  const DataLayout &dataLayout,
184  std::optional<Location> loc = std::nullopt) {
185  if (!loc)
186  loc = UnknownLoc::get(attribute.getContext());
187 
188  // Translate the endianness attribute.
189  std::string llvmDataLayout;
190  llvm::raw_string_ostream layoutStream(llvmDataLayout);
191  for (DataLayoutEntryInterface entry : attribute.getEntries()) {
192  auto key = llvm::dyn_cast_if_present<StringAttr>(entry.getKey());
193  if (!key)
194  continue;
195  if (key.getValue() == DLTIDialect::kDataLayoutEndiannessKey) {
196  auto value = cast<StringAttr>(entry.getValue());
197  bool isLittleEndian =
198  value.getValue() == DLTIDialect::kDataLayoutEndiannessLittle;
199  layoutStream << "-" << (isLittleEndian ? "e" : "E");
200  continue;
201  }
202  if (key.getValue() == DLTIDialect::kDataLayoutProgramMemorySpaceKey) {
203  auto value = cast<IntegerAttr>(entry.getValue());
204  uint64_t space = value.getValue().getZExtValue();
205  // Skip the default address space.
206  if (space == 0)
207  continue;
208  layoutStream << "-P" << space;
209  continue;
210  }
211  if (key.getValue() == DLTIDialect::kDataLayoutGlobalMemorySpaceKey) {
212  auto value = cast<IntegerAttr>(entry.getValue());
213  uint64_t space = value.getValue().getZExtValue();
214  // Skip the default address space.
215  if (space == 0)
216  continue;
217  layoutStream << "-G" << space;
218  continue;
219  }
220  if (key.getValue() == DLTIDialect::kDataLayoutAllocaMemorySpaceKey) {
221  auto value = cast<IntegerAttr>(entry.getValue());
222  uint64_t space = value.getValue().getZExtValue();
223  // Skip the default address space.
224  if (space == 0)
225  continue;
226  layoutStream << "-A" << space;
227  continue;
228  }
229  if (key.getValue() == DLTIDialect::kDataLayoutStackAlignmentKey) {
230  auto value = cast<IntegerAttr>(entry.getValue());
231  uint64_t alignment = value.getValue().getZExtValue();
232  // Skip the default stack alignment.
233  if (alignment == 0)
234  continue;
235  layoutStream << "-S" << alignment;
236  continue;
237  }
238  emitError(*loc) << "unsupported data layout key " << key;
239  return failure();
240  }
241 
242  // Go through the list of entries to check which types are explicitly
243  // specified in entries. Where possible, data layout queries are used instead
244  // of directly inspecting the entries.
245  for (DataLayoutEntryInterface entry : attribute.getEntries()) {
246  auto type = llvm::dyn_cast_if_present<Type>(entry.getKey());
247  if (!type)
248  continue;
249  // Data layout for the index type is irrelevant at this point.
250  if (isa<IndexType>(type))
251  continue;
252  layoutStream << "-";
253  LogicalResult result =
255  .Case<IntegerType, Float16Type, Float32Type, Float64Type,
256  Float80Type, Float128Type>([&](Type type) -> LogicalResult {
257  if (auto intType = dyn_cast<IntegerType>(type)) {
258  if (intType.getSignedness() != IntegerType::Signless)
259  return emitError(*loc)
260  << "unsupported data layout for non-signless integer "
261  << intType;
262  layoutStream << "i";
263  } else {
264  layoutStream << "f";
265  }
266  uint64_t size = dataLayout.getTypeSizeInBits(type);
267  uint64_t abi = dataLayout.getTypeABIAlignment(type) * 8u;
268  uint64_t preferred =
269  dataLayout.getTypePreferredAlignment(type) * 8u;
270  layoutStream << size << ":" << abi;
271  if (abi != preferred)
272  layoutStream << ":" << preferred;
273  return success();
274  })
275  .Case([&](LLVMPointerType type) {
276  layoutStream << "p" << type.getAddressSpace() << ":";
277  uint64_t size = dataLayout.getTypeSizeInBits(type);
278  uint64_t abi = dataLayout.getTypeABIAlignment(type) * 8u;
279  uint64_t preferred =
280  dataLayout.getTypePreferredAlignment(type) * 8u;
281  uint64_t index = *dataLayout.getTypeIndexBitwidth(type);
282  layoutStream << size << ":" << abi << ":" << preferred << ":"
283  << index;
284  return success();
285  })
286  .Default([loc](Type type) {
287  return emitError(*loc)
288  << "unsupported type in data layout: " << type;
289  });
290  if (failed(result))
291  return failure();
292  }
293  StringRef layoutSpec(llvmDataLayout);
294  if (layoutSpec.starts_with("-"))
295  layoutSpec = layoutSpec.drop_front();
296 
297  return llvm::DataLayout(layoutSpec);
298 }
299 
300 /// Builds a constant of a sequential LLVM type `type`, potentially containing
301 /// other sequential types recursively, from the individual constant values
302 /// provided in `constants`. `shape` contains the number of elements in nested
303 /// sequential types. Reports errors at `loc` and returns nullptr on error.
304 static llvm::Constant *
306  ArrayRef<int64_t> shape, llvm::Type *type,
307  Location loc) {
308  if (shape.empty()) {
309  llvm::Constant *result = constants.front();
310  constants = constants.drop_front();
311  return result;
312  }
313 
314  llvm::Type *elementType;
315  if (auto *arrayTy = dyn_cast<llvm::ArrayType>(type)) {
316  elementType = arrayTy->getElementType();
317  } else if (auto *vectorTy = dyn_cast<llvm::VectorType>(type)) {
318  elementType = vectorTy->getElementType();
319  } else {
320  emitError(loc) << "expected sequential LLVM types wrapping a scalar";
321  return nullptr;
322  }
323 
325  nested.reserve(shape.front());
326  for (int64_t i = 0; i < shape.front(); ++i) {
327  nested.push_back(buildSequentialConstant(constants, shape.drop_front(),
328  elementType, loc));
329  if (!nested.back())
330  return nullptr;
331  }
332 
333  if (shape.size() == 1 && type->isVectorTy())
334  return llvm::ConstantVector::get(nested);
336  llvm::ArrayType::get(elementType, shape.front()), nested);
337 }
338 
339 /// Returns the first non-sequential type nested in sequential types.
340 static llvm::Type *getInnermostElementType(llvm::Type *type) {
341  do {
342  if (auto *arrayTy = dyn_cast<llvm::ArrayType>(type)) {
343  type = arrayTy->getElementType();
344  } else if (auto *vectorTy = dyn_cast<llvm::VectorType>(type)) {
345  type = vectorTy->getElementType();
346  } else {
347  return type;
348  }
349  } while (true);
350 }
351 
352 /// Convert a dense elements attribute to an LLVM IR constant using its raw data
353 /// storage if possible. This supports elements attributes of tensor or vector
354 /// type and avoids constructing separate objects for individual values of the
355 /// innermost dimension. Constants for other dimensions are still constructed
356 /// recursively. Returns null if constructing from raw data is not supported for
357 /// this type, e.g., element type is not a power-of-two-sized primitive. Reports
358 /// other errors at `loc`.
359 static llvm::Constant *
361  llvm::Type *llvmType,
362  const ModuleTranslation &moduleTranslation) {
363  if (!denseElementsAttr)
364  return nullptr;
365 
366  llvm::Type *innermostLLVMType = getInnermostElementType(llvmType);
367  if (!llvm::ConstantDataSequential::isElementTypeCompatible(innermostLLVMType))
368  return nullptr;
369 
370  ShapedType type = denseElementsAttr.getType();
371  if (type.getNumElements() == 0)
372  return nullptr;
373 
374  // Check that the raw data size matches what is expected for the scalar size.
375  // TODO: in theory, we could repack the data here to keep constructing from
376  // raw data.
377  // TODO: we may also need to consider endianness when cross-compiling to an
378  // architecture where it is different.
379  int64_t elementByteSize = denseElementsAttr.getRawData().size() /
380  denseElementsAttr.getNumElements();
381  if (8 * elementByteSize != innermostLLVMType->getScalarSizeInBits())
382  return nullptr;
383 
384  // Compute the shape of all dimensions but the innermost. Note that the
385  // innermost dimension may be that of the vector element type.
386  bool hasVectorElementType = isa<VectorType>(type.getElementType());
387  int64_t numAggregates =
388  denseElementsAttr.getNumElements() /
389  (hasVectorElementType ? 1
390  : denseElementsAttr.getType().getShape().back());
391  ArrayRef<int64_t> outerShape = type.getShape();
392  if (!hasVectorElementType)
393  outerShape = outerShape.drop_back();
394 
395  // Handle the case of vector splat, LLVM has special support for it.
396  if (denseElementsAttr.isSplat() &&
397  (isa<VectorType>(type) || hasVectorElementType)) {
398  llvm::Constant *splatValue = LLVM::detail::getLLVMConstant(
399  innermostLLVMType, denseElementsAttr.getSplatValue<Attribute>(), loc,
400  moduleTranslation);
401  llvm::Constant *splatVector =
402  llvm::ConstantDataVector::getSplat(0, splatValue);
403  SmallVector<llvm::Constant *> constants(numAggregates, splatVector);
404  ArrayRef<llvm::Constant *> constantsRef = constants;
405  return buildSequentialConstant(constantsRef, outerShape, llvmType, loc);
406  }
407  if (denseElementsAttr.isSplat())
408  return nullptr;
409 
410  // In case of non-splat, create a constructor for the innermost constant from
411  // a piece of raw data.
412  std::function<llvm::Constant *(StringRef)> buildCstData;
413  if (isa<TensorType>(type)) {
414  auto vectorElementType = dyn_cast<VectorType>(type.getElementType());
415  if (vectorElementType && vectorElementType.getRank() == 1) {
416  buildCstData = [&](StringRef data) {
417  return llvm::ConstantDataVector::getRaw(
418  data, vectorElementType.getShape().back(), innermostLLVMType);
419  };
420  } else if (!vectorElementType) {
421  buildCstData = [&](StringRef data) {
422  return llvm::ConstantDataArray::getRaw(data, type.getShape().back(),
423  innermostLLVMType);
424  };
425  }
426  } else if (isa<VectorType>(type)) {
427  buildCstData = [&](StringRef data) {
428  return llvm::ConstantDataVector::getRaw(data, type.getShape().back(),
429  innermostLLVMType);
430  };
431  }
432  if (!buildCstData)
433  return nullptr;
434 
435  // Create innermost constants and defer to the default constant creation
436  // mechanism for other dimensions.
438  int64_t aggregateSize = denseElementsAttr.getType().getShape().back() *
439  (innermostLLVMType->getScalarSizeInBits() / 8);
440  constants.reserve(numAggregates);
441  for (unsigned i = 0; i < numAggregates; ++i) {
442  StringRef data(denseElementsAttr.getRawData().data() + i * aggregateSize,
443  aggregateSize);
444  constants.push_back(buildCstData(data));
445  }
446 
447  ArrayRef<llvm::Constant *> constantsRef = constants;
448  return buildSequentialConstant(constantsRef, outerShape, llvmType, loc);
449 }
450 
451 /// Convert a dense resource elements attribute to an LLVM IR constant using its
452 /// raw data storage if possible. This supports elements attributes of tensor or
453 /// vector type and avoids constructing separate objects for individual values
454 /// of the innermost dimension. Constants for other dimensions are still
455 /// constructed recursively. Returns nullptr on failure and emits errors at
456 /// `loc`.
457 static llvm::Constant *convertDenseResourceElementsAttr(
458  Location loc, DenseResourceElementsAttr denseResourceAttr,
459  llvm::Type *llvmType, const ModuleTranslation &moduleTranslation) {
460  assert(denseResourceAttr && "expected non-null attribute");
461 
462  llvm::Type *innermostLLVMType = getInnermostElementType(llvmType);
463  if (!llvm::ConstantDataSequential::isElementTypeCompatible(
464  innermostLLVMType)) {
465  emitError(loc, "no known conversion for innermost element type");
466  return nullptr;
467  }
468 
469  ShapedType type = denseResourceAttr.getType();
470  assert(type.getNumElements() > 0 && "Expected non-empty elements attribute");
471 
472  AsmResourceBlob *blob = denseResourceAttr.getRawHandle().getBlob();
473  if (!blob) {
474  emitError(loc, "resource does not exist");
475  return nullptr;
476  }
477 
478  ArrayRef<char> rawData = blob->getData();
479 
480  // Check that the raw data size matches what is expected for the scalar size.
481  // TODO: in theory, we could repack the data here to keep constructing from
482  // raw data.
483  // TODO: we may also need to consider endianness when cross-compiling to an
484  // architecture where it is different.
485  int64_t numElements = denseResourceAttr.getType().getNumElements();
486  int64_t elementByteSize = rawData.size() / numElements;
487  if (8 * elementByteSize != innermostLLVMType->getScalarSizeInBits()) {
488  emitError(loc, "raw data size does not match element type size");
489  return nullptr;
490  }
491 
492  // Compute the shape of all dimensions but the innermost. Note that the
493  // innermost dimension may be that of the vector element type.
494  bool hasVectorElementType = isa<VectorType>(type.getElementType());
495  int64_t numAggregates =
496  numElements / (hasVectorElementType
497  ? 1
498  : denseResourceAttr.getType().getShape().back());
499  ArrayRef<int64_t> outerShape = type.getShape();
500  if (!hasVectorElementType)
501  outerShape = outerShape.drop_back();
502 
503  // Create a constructor for the innermost constant from a piece of raw data.
504  std::function<llvm::Constant *(StringRef)> buildCstData;
505  if (isa<TensorType>(type)) {
506  auto vectorElementType = dyn_cast<VectorType>(type.getElementType());
507  if (vectorElementType && vectorElementType.getRank() == 1) {
508  buildCstData = [&](StringRef data) {
509  return llvm::ConstantDataVector::getRaw(
510  data, vectorElementType.getShape().back(), innermostLLVMType);
511  };
512  } else if (!vectorElementType) {
513  buildCstData = [&](StringRef data) {
514  return llvm::ConstantDataArray::getRaw(data, type.getShape().back(),
515  innermostLLVMType);
516  };
517  }
518  } else if (isa<VectorType>(type)) {
519  buildCstData = [&](StringRef data) {
520  return llvm::ConstantDataVector::getRaw(data, type.getShape().back(),
521  innermostLLVMType);
522  };
523  }
524  if (!buildCstData) {
525  emitError(loc, "unsupported dense_resource type");
526  return nullptr;
527  }
528 
529  // Create innermost constants and defer to the default constant creation
530  // mechanism for other dimensions.
532  int64_t aggregateSize = denseResourceAttr.getType().getShape().back() *
533  (innermostLLVMType->getScalarSizeInBits() / 8);
534  constants.reserve(numAggregates);
535  for (unsigned i = 0; i < numAggregates; ++i) {
536  StringRef data(rawData.data() + i * aggregateSize, aggregateSize);
537  constants.push_back(buildCstData(data));
538  }
539 
540  ArrayRef<llvm::Constant *> constantsRef = constants;
541  return buildSequentialConstant(constantsRef, outerShape, llvmType, loc);
542 }
543 
544 /// Create an LLVM IR constant of `llvmType` from the MLIR attribute `attr`.
545 /// This currently supports integer, floating point, splat and dense element
546 /// attributes and combinations thereof. Also, an array attribute with two
547 /// elements is supported to represent a complex constant. In case of error,
548 /// report it to `loc` and return nullptr.
550  llvm::Type *llvmType, Attribute attr, Location loc,
551  const ModuleTranslation &moduleTranslation) {
552  if (!attr)
553  return llvm::UndefValue::get(llvmType);
554  if (auto *structType = dyn_cast<::llvm::StructType>(llvmType)) {
555  auto arrayAttr = dyn_cast<ArrayAttr>(attr);
556  if (!arrayAttr) {
557  emitError(loc, "expected an array attribute for a struct constant");
558  return nullptr;
559  }
560  SmallVector<llvm::Constant *> structElements;
561  structElements.reserve(structType->getNumElements());
562  for (auto [elemType, elemAttr] :
563  zip_equal(structType->elements(), arrayAttr)) {
564  llvm::Constant *element =
565  getLLVMConstant(elemType, elemAttr, loc, moduleTranslation);
566  if (!element)
567  return nullptr;
568  structElements.push_back(element);
569  }
570  return llvm::ConstantStruct::get(structType, structElements);
571  }
572  // For integer types, we allow a mismatch in sizes as the index type in
573  // MLIR might have a different size than the index type in the LLVM module.
574  if (auto intAttr = dyn_cast<IntegerAttr>(attr))
575  return llvm::ConstantInt::get(
576  llvmType,
577  intAttr.getValue().sextOrTrunc(llvmType->getIntegerBitWidth()));
578  if (auto floatAttr = dyn_cast<FloatAttr>(attr)) {
579  const llvm::fltSemantics &sem = floatAttr.getValue().getSemantics();
580  // Special case for 8-bit floats, which are represented by integers due to
581  // the lack of native fp8 types in LLVM at the moment. Additionally, handle
582  // targets (like AMDGPU) that don't implement bfloat and convert all bfloats
583  // to i16.
584  unsigned floatWidth = APFloat::getSizeInBits(sem);
585  if (llvmType->isIntegerTy(floatWidth))
586  return llvm::ConstantInt::get(llvmType,
587  floatAttr.getValue().bitcastToAPInt());
588  if (llvmType !=
589  llvm::Type::getFloatingPointTy(llvmType->getContext(),
590  floatAttr.getValue().getSemantics())) {
591  emitError(loc, "FloatAttr does not match expected type of the constant");
592  return nullptr;
593  }
594  return llvm::ConstantFP::get(llvmType, floatAttr.getValue());
595  }
596  if (auto funcAttr = dyn_cast<FlatSymbolRefAttr>(attr))
597  return llvm::ConstantExpr::getBitCast(
598  moduleTranslation.lookupFunction(funcAttr.getValue()), llvmType);
599  if (auto splatAttr = dyn_cast<SplatElementsAttr>(attr)) {
600  llvm::Type *elementType;
601  uint64_t numElements;
602  bool isScalable = false;
603  if (auto *arrayTy = dyn_cast<llvm::ArrayType>(llvmType)) {
604  elementType = arrayTy->getElementType();
605  numElements = arrayTy->getNumElements();
606  } else if (auto *fVectorTy = dyn_cast<llvm::FixedVectorType>(llvmType)) {
607  elementType = fVectorTy->getElementType();
608  numElements = fVectorTy->getNumElements();
609  } else if (auto *sVectorTy = dyn_cast<llvm::ScalableVectorType>(llvmType)) {
610  elementType = sVectorTy->getElementType();
611  numElements = sVectorTy->getMinNumElements();
612  isScalable = true;
613  } else {
614  llvm_unreachable("unrecognized constant vector type");
615  }
616  // Splat value is a scalar. Extract it only if the element type is not
617  // another sequence type. The recursion terminates because each step removes
618  // one outer sequential type.
619  bool elementTypeSequential =
620  isa<llvm::ArrayType, llvm::VectorType>(elementType);
621  llvm::Constant *child = getLLVMConstant(
622  elementType,
623  elementTypeSequential ? splatAttr
624  : splatAttr.getSplatValue<Attribute>(),
625  loc, moduleTranslation);
626  if (!child)
627  return nullptr;
628  if (llvmType->isVectorTy())
629  return llvm::ConstantVector::getSplat(
630  llvm::ElementCount::get(numElements, /*Scalable=*/isScalable), child);
631  if (llvmType->isArrayTy()) {
632  auto *arrayType = llvm::ArrayType::get(elementType, numElements);
633  if (child->isZeroValue()) {
634  return llvm::ConstantAggregateZero::get(arrayType);
635  } else {
636  if (llvm::ConstantDataSequential::isElementTypeCompatible(
637  elementType)) {
638  // TODO: Handle all compatible types. This code only handles integer.
639  if (isa<llvm::IntegerType>(elementType)) {
640  if (llvm::ConstantInt *ci = dyn_cast<llvm::ConstantInt>(child)) {
641  if (ci->getBitWidth() == 8) {
642  SmallVector<int8_t> constants(numElements, ci->getZExtValue());
643  return llvm::ConstantDataArray::get(elementType->getContext(),
644  constants);
645  }
646  if (ci->getBitWidth() == 16) {
647  SmallVector<int16_t> constants(numElements, ci->getZExtValue());
648  return llvm::ConstantDataArray::get(elementType->getContext(),
649  constants);
650  }
651  if (ci->getBitWidth() == 32) {
652  SmallVector<int32_t> constants(numElements, ci->getZExtValue());
653  return llvm::ConstantDataArray::get(elementType->getContext(),
654  constants);
655  }
656  if (ci->getBitWidth() == 64) {
657  SmallVector<int64_t> constants(numElements, ci->getZExtValue());
658  return llvm::ConstantDataArray::get(elementType->getContext(),
659  constants);
660  }
661  }
662  }
663  }
664  // std::vector is used here to accomodate large number of elements that
665  // exceed SmallVector capacity.
666  std::vector<llvm::Constant *> constants(numElements, child);
667  return llvm::ConstantArray::get(arrayType, constants);
668  }
669  }
670  }
671 
672  // Try using raw elements data if possible.
673  if (llvm::Constant *result =
674  convertDenseElementsAttr(loc, dyn_cast<DenseElementsAttr>(attr),
675  llvmType, moduleTranslation)) {
676  return result;
677  }
678 
679  if (auto denseResourceAttr = dyn_cast<DenseResourceElementsAttr>(attr)) {
680  return convertDenseResourceElementsAttr(loc, denseResourceAttr, llvmType,
681  moduleTranslation);
682  }
683 
684  // Fall back to element-by-element construction otherwise.
685  if (auto elementsAttr = dyn_cast<ElementsAttr>(attr)) {
686  assert(elementsAttr.getShapedType().hasStaticShape());
687  assert(!elementsAttr.getShapedType().getShape().empty() &&
688  "unexpected empty elements attribute shape");
689 
691  constants.reserve(elementsAttr.getNumElements());
692  llvm::Type *innermostType = getInnermostElementType(llvmType);
693  for (auto n : elementsAttr.getValues<Attribute>()) {
694  constants.push_back(
695  getLLVMConstant(innermostType, n, loc, moduleTranslation));
696  if (!constants.back())
697  return nullptr;
698  }
699  ArrayRef<llvm::Constant *> constantsRef = constants;
700  llvm::Constant *result = buildSequentialConstant(
701  constantsRef, elementsAttr.getShapedType().getShape(), llvmType, loc);
702  assert(constantsRef.empty() && "did not consume all elemental constants");
703  return result;
704  }
705 
706  if (auto stringAttr = dyn_cast<StringAttr>(attr)) {
708  moduleTranslation.getLLVMContext(),
709  ArrayRef<char>{stringAttr.getValue().data(),
710  stringAttr.getValue().size()});
711  }
712  emitError(loc, "unsupported constant value");
713  return nullptr;
714 }
715 
716 ModuleTranslation::ModuleTranslation(Operation *module,
717  std::unique_ptr<llvm::Module> llvmModule)
718  : mlirModule(module), llvmModule(std::move(llvmModule)),
719  debugTranslation(
720  std::make_unique<DebugTranslation>(module, *this->llvmModule)),
721  loopAnnotationTranslation(std::make_unique<LoopAnnotationTranslation>(
722  *this, *this->llvmModule)),
723  typeTranslator(this->llvmModule->getContext()),
724  iface(module->getContext()) {
725  assert(satisfiesLLVMModule(mlirModule) &&
726  "mlirModule should honor LLVM's module semantics.");
727 }
728 
729 ModuleTranslation::~ModuleTranslation() {
730  if (ompBuilder)
731  ompBuilder->finalize();
732 }
733 
735  SmallVector<Region *> toProcess;
736  toProcess.push_back(&region);
737  while (!toProcess.empty()) {
738  Region *current = toProcess.pop_back_val();
739  for (Block &block : *current) {
740  blockMapping.erase(&block);
741  for (Value arg : block.getArguments())
742  valueMapping.erase(arg);
743  for (Operation &op : block) {
744  for (Value value : op.getResults())
745  valueMapping.erase(value);
746  if (op.hasSuccessors())
747  branchMapping.erase(&op);
748  if (isa<LLVM::GlobalOp>(op))
749  globalsMapping.erase(&op);
750  if (isa<LLVM::AliasOp>(op))
751  aliasesMapping.erase(&op);
752  if (isa<LLVM::CallOp>(op))
753  callMapping.erase(&op);
754  llvm::append_range(
755  toProcess,
756  llvm::map_range(op.getRegions(), [](Region &r) { return &r; }));
757  }
758  }
759  }
760 }
761 
762 /// Get the SSA value passed to the current block from the terminator operation
763 /// of its predecessor.
764 static Value getPHISourceValue(Block *current, Block *pred,
765  unsigned numArguments, unsigned index) {
766  Operation &terminator = *pred->getTerminator();
767  if (isa<LLVM::BrOp>(terminator))
768  return terminator.getOperand(index);
769 
770 #ifndef NDEBUG
771  llvm::SmallPtrSet<Block *, 4> seenSuccessors;
772  for (unsigned i = 0, e = terminator.getNumSuccessors(); i < e; ++i) {
773  Block *successor = terminator.getSuccessor(i);
774  auto branch = cast<BranchOpInterface>(terminator);
775  SuccessorOperands successorOperands = branch.getSuccessorOperands(i);
776  assert(
777  (!seenSuccessors.contains(successor) || successorOperands.empty()) &&
778  "successors with arguments in LLVM branches must be different blocks");
779  seenSuccessors.insert(successor);
780  }
781 #endif
782 
783  // For instructions that branch based on a condition value, we need to take
784  // the operands for the branch that was taken.
785  if (auto condBranchOp = dyn_cast<LLVM::CondBrOp>(terminator)) {
786  // For conditional branches, we take the operands from either the "true" or
787  // the "false" branch.
788  return condBranchOp.getSuccessor(0) == current
789  ? condBranchOp.getTrueDestOperands()[index]
790  : condBranchOp.getFalseDestOperands()[index];
791  }
792 
793  if (auto switchOp = dyn_cast<LLVM::SwitchOp>(terminator)) {
794  // For switches, we take the operands from either the default case, or from
795  // the case branch that was taken.
796  if (switchOp.getDefaultDestination() == current)
797  return switchOp.getDefaultOperands()[index];
798  for (const auto &i : llvm::enumerate(switchOp.getCaseDestinations()))
799  if (i.value() == current)
800  return switchOp.getCaseOperands(i.index())[index];
801  }
802 
803  if (auto invokeOp = dyn_cast<LLVM::InvokeOp>(terminator)) {
804  return invokeOp.getNormalDest() == current
805  ? invokeOp.getNormalDestOperands()[index]
806  : invokeOp.getUnwindDestOperands()[index];
807  }
808 
809  llvm_unreachable(
810  "only branch, switch or invoke operations can be terminators "
811  "of a block that has successors");
812 }
813 
814 /// Connect the PHI nodes to the results of preceding blocks.
816  const ModuleTranslation &state) {
817  // Skip the first block, it cannot be branched to and its arguments correspond
818  // to the arguments of the LLVM function.
819  for (Block &bb : llvm::drop_begin(region)) {
820  llvm::BasicBlock *llvmBB = state.lookupBlock(&bb);
821  auto phis = llvmBB->phis();
822  auto numArguments = bb.getNumArguments();
823  assert(numArguments == std::distance(phis.begin(), phis.end()));
824  for (auto [index, phiNode] : llvm::enumerate(phis)) {
825  for (auto *pred : bb.getPredecessors()) {
826  // Find the LLVM IR block that contains the converted terminator
827  // instruction and use it in the PHI node. Note that this block is not
828  // necessarily the same as state.lookupBlock(pred), some operations
829  // (in particular, OpenMP operations using OpenMPIRBuilder) may have
830  // split the blocks.
831  llvm::Instruction *terminator =
832  state.lookupBranch(pred->getTerminator());
833  assert(terminator && "missing the mapping for a terminator");
834  phiNode.addIncoming(state.lookupValue(getPHISourceValue(
835  &bb, pred, numArguments, index)),
836  terminator->getParent());
837  }
838  }
839  }
840 }
841 
843  llvm::IRBuilderBase &builder, llvm::Intrinsic::ID intrinsic,
845  llvm::Module *module = builder.GetInsertBlock()->getModule();
846  llvm::Function *fn =
847  llvm::Intrinsic::getOrInsertDeclaration(module, intrinsic, tys);
848  return builder.CreateCall(fn, args);
849 }
850 
852  llvm::IRBuilderBase &builder, ModuleTranslation &moduleTranslation,
853  Operation *intrOp, llvm::Intrinsic::ID intrinsic, unsigned numResults,
854  ArrayRef<unsigned> overloadedResults, ArrayRef<unsigned> overloadedOperands,
855  ArrayRef<unsigned> immArgPositions,
856  ArrayRef<StringLiteral> immArgAttrNames) {
857  assert(immArgPositions.size() == immArgAttrNames.size() &&
858  "LLVM `immArgPositions` and MLIR `immArgAttrNames` should have equal "
859  "length");
860 
862  size_t numOpBundleOperands = 0;
863  auto opBundleSizesAttr = cast_if_present<DenseI32ArrayAttr>(
864  intrOp->getAttr(LLVMDialect::getOpBundleSizesAttrName()));
865  auto opBundleTagsAttr = cast_if_present<ArrayAttr>(
866  intrOp->getAttr(LLVMDialect::getOpBundleTagsAttrName()));
867 
868  if (opBundleSizesAttr && opBundleTagsAttr) {
869  ArrayRef<int> opBundleSizes = opBundleSizesAttr.asArrayRef();
870  assert(opBundleSizes.size() == opBundleTagsAttr.size() &&
871  "operand bundles and tags do not match");
872 
873  numOpBundleOperands =
874  std::accumulate(opBundleSizes.begin(), opBundleSizes.end(), size_t(0));
875  assert(numOpBundleOperands <= intrOp->getNumOperands() &&
876  "operand bundle operands is more than the number of operands");
877 
878  ValueRange operands = intrOp->getOperands().take_back(numOpBundleOperands);
879  size_t nextOperandIdx = 0;
880  opBundles.reserve(opBundleSizesAttr.size());
881 
882  for (auto [opBundleTagAttr, bundleSize] :
883  llvm::zip(opBundleTagsAttr, opBundleSizes)) {
884  auto bundleTag = cast<StringAttr>(opBundleTagAttr).str();
885  auto bundleOperands = moduleTranslation.lookupValues(
886  operands.slice(nextOperandIdx, bundleSize));
887  opBundles.emplace_back(std::move(bundleTag), std::move(bundleOperands));
888  nextOperandIdx += bundleSize;
889  }
890  }
891 
892  // Map operands and attributes to LLVM values.
893  auto opOperands = intrOp->getOperands().drop_back(numOpBundleOperands);
894  auto operands = moduleTranslation.lookupValues(opOperands);
895  SmallVector<llvm::Value *> args(immArgPositions.size() + operands.size());
896  for (auto [immArgPos, immArgName] :
897  llvm::zip(immArgPositions, immArgAttrNames)) {
898  auto attr = llvm::cast<TypedAttr>(intrOp->getAttr(immArgName));
899  assert(attr.getType().isIntOrFloat() && "expected int or float immarg");
900  auto *type = moduleTranslation.convertType(attr.getType());
901  args[immArgPos] = LLVM::detail::getLLVMConstant(
902  type, attr, intrOp->getLoc(), moduleTranslation);
903  }
904  unsigned opArg = 0;
905  for (auto &arg : args) {
906  if (!arg)
907  arg = operands[opArg++];
908  }
909 
910  // Resolve overloaded intrinsic declaration.
911  SmallVector<llvm::Type *> overloadedTypes;
912  for (unsigned overloadedResultIdx : overloadedResults) {
913  if (numResults > 1) {
914  // More than one result is mapped to an LLVM struct.
915  overloadedTypes.push_back(moduleTranslation.convertType(
916  llvm::cast<LLVM::LLVMStructType>(intrOp->getResult(0).getType())
917  .getBody()[overloadedResultIdx]));
918  } else {
919  overloadedTypes.push_back(
920  moduleTranslation.convertType(intrOp->getResult(0).getType()));
921  }
922  }
923  for (unsigned overloadedOperandIdx : overloadedOperands)
924  overloadedTypes.push_back(args[overloadedOperandIdx]->getType());
925  llvm::Module *module = builder.GetInsertBlock()->getModule();
926  llvm::Function *llvmIntr = llvm::Intrinsic::getOrInsertDeclaration(
927  module, intrinsic, overloadedTypes);
928 
929  return builder.CreateCall(llvmIntr, args, opBundles);
930 }
931 
932 /// Given a single MLIR operation, create the corresponding LLVM IR operation
933 /// using the `builder`.
934 LogicalResult ModuleTranslation::convertOperation(Operation &op,
935  llvm::IRBuilderBase &builder,
936  bool recordInsertions) {
937  const LLVMTranslationDialectInterface *opIface = iface.getInterfaceFor(&op);
938  if (!opIface)
939  return op.emitError("cannot be converted to LLVM IR: missing "
940  "`LLVMTranslationDialectInterface` registration for "
941  "dialect for op: ")
942  << op.getName();
943 
944  InstructionCapturingInserter::CollectionScope scope(builder,
945  recordInsertions);
946  if (failed(opIface->convertOperation(&op, builder, *this)))
947  return op.emitError("LLVM Translation failed for operation: ")
948  << op.getName();
949 
950  return convertDialectAttributes(&op, scope.getCapturedInstructions());
951 }
952 
953 /// Convert block to LLVM IR. Unless `ignoreArguments` is set, emit PHI nodes
954 /// to define values corresponding to the MLIR block arguments. These nodes
955 /// are not connected to the source basic blocks, which may not exist yet. Uses
956 /// `builder` to construct the LLVM IR. Expects the LLVM IR basic block to have
957 /// been created for `bb` and included in the block mapping. Inserts new
958 /// instructions at the end of the block and leaves `builder` in a state
959 /// suitable for further insertion into the end of the block.
960 LogicalResult ModuleTranslation::convertBlockImpl(Block &bb,
961  bool ignoreArguments,
962  llvm::IRBuilderBase &builder,
963  bool recordInsertions) {
964  builder.SetInsertPoint(lookupBlock(&bb));
965  auto *subprogram = builder.GetInsertBlock()->getParent()->getSubprogram();
966 
967  // Before traversing operations, make block arguments available through
968  // value remapping and PHI nodes, but do not add incoming edges for the PHI
969  // nodes just yet: those values may be defined by this or following blocks.
970  // This step is omitted if "ignoreArguments" is set. The arguments of the
971  // first block have been already made available through the remapping of
972  // LLVM function arguments.
973  if (!ignoreArguments) {
974  auto predecessors = bb.getPredecessors();
975  unsigned numPredecessors =
976  std::distance(predecessors.begin(), predecessors.end());
977  for (auto arg : bb.getArguments()) {
978  auto wrappedType = arg.getType();
979  if (!isCompatibleType(wrappedType))
980  return emitError(bb.front().getLoc(),
981  "block argument does not have an LLVM type");
982  builder.SetCurrentDebugLocation(
983  debugTranslation->translateLoc(arg.getLoc(), subprogram));
984  llvm::Type *type = convertType(wrappedType);
985  llvm::PHINode *phi = builder.CreatePHI(type, numPredecessors);
986  mapValue(arg, phi);
987  }
988  }
989 
990  // Traverse operations.
991  for (auto &op : bb) {
992  // Set the current debug location within the builder.
993  builder.SetCurrentDebugLocation(
994  debugTranslation->translateLoc(op.getLoc(), subprogram));
995 
996  if (failed(convertOperation(op, builder, recordInsertions)))
997  return failure();
998 
999  // Set the branch weight metadata on the translated instruction.
1000  if (auto iface = dyn_cast<BranchWeightOpInterface>(op))
1001  setBranchWeightsMetadata(iface);
1002  }
1003 
1004  return success();
1005 }
1006 
1007 /// A helper method to get the single Block in an operation honoring LLVM's
1008 /// module requirements.
1009 static Block &getModuleBody(Operation *module) {
1010  return module->getRegion(0).front();
1011 }
1012 
1013 /// A helper method to decide if a constant must not be set as a global variable
1014 /// initializer. For an external linkage variable, the variable with an
1015 /// initializer is considered externally visible and defined in this module, the
1016 /// variable without an initializer is externally available and is defined
1017 /// elsewhere.
1018 static bool shouldDropGlobalInitializer(llvm::GlobalValue::LinkageTypes linkage,
1019  llvm::Constant *cst) {
1020  return (linkage == llvm::GlobalVariable::ExternalLinkage && !cst) ||
1021  linkage == llvm::GlobalVariable::ExternalWeakLinkage;
1022 }
1023 
1024 /// Sets the runtime preemption specifier of `gv` to dso_local if
1025 /// `dsoLocalRequested` is true, otherwise it is left unchanged.
1026 static void addRuntimePreemptionSpecifier(bool dsoLocalRequested,
1027  llvm::GlobalValue *gv) {
1028  if (dsoLocalRequested)
1029  gv->setDSOLocal(true);
1030 }
1031 
1032 LogicalResult ModuleTranslation::convertGlobalsAndAliases() {
1033  // Mapping from compile unit to its respective set of global variables.
1035 
1036  // First, create all global variables and global aliases in LLVM IR. A global
1037  // or alias body may refer to another global/alias or itself, so all the
1038  // mapping needs to happen prior to body conversion.
1039 
1040  // Create all llvm::GlobalVariable
1041  for (auto op : getModuleBody(mlirModule).getOps<LLVM::GlobalOp>()) {
1042  llvm::Type *type = convertType(op.getType());
1043  llvm::Constant *cst = nullptr;
1044  if (op.getValueOrNull()) {
1045  // String attributes are treated separately because they cannot appear as
1046  // in-function constants and are thus not supported by getLLVMConstant.
1047  if (auto strAttr = dyn_cast_or_null<StringAttr>(op.getValueOrNull())) {
1048  cst = llvm::ConstantDataArray::getString(
1049  llvmModule->getContext(), strAttr.getValue(), /*AddNull=*/false);
1050  type = cst->getType();
1051  } else if (!(cst = getLLVMConstant(type, op.getValueOrNull(), op.getLoc(),
1052  *this))) {
1053  return failure();
1054  }
1055  }
1056 
1057  auto linkage = convertLinkageToLLVM(op.getLinkage());
1058 
1059  // LLVM IR requires constant with linkage other than external or weak
1060  // external to have initializers. If MLIR does not provide an initializer,
1061  // default to undef.
1062  bool dropInitializer = shouldDropGlobalInitializer(linkage, cst);
1063  if (!dropInitializer && !cst)
1064  cst = llvm::UndefValue::get(type);
1065  else if (dropInitializer && cst)
1066  cst = nullptr;
1067 
1068  auto *var = new llvm::GlobalVariable(
1069  *llvmModule, type, op.getConstant(), linkage, cst, op.getSymName(),
1070  /*InsertBefore=*/nullptr,
1071  op.getThreadLocal_() ? llvm::GlobalValue::GeneralDynamicTLSModel
1072  : llvm::GlobalValue::NotThreadLocal,
1073  op.getAddrSpace(), op.getExternallyInitialized());
1074 
1075  if (std::optional<mlir::SymbolRefAttr> comdat = op.getComdat()) {
1076  auto selectorOp = cast<ComdatSelectorOp>(
1078  var->setComdat(comdatMapping.lookup(selectorOp));
1079  }
1080 
1081  if (op.getUnnamedAddr().has_value())
1082  var->setUnnamedAddr(convertUnnamedAddrToLLVM(*op.getUnnamedAddr()));
1083 
1084  if (op.getSection().has_value())
1085  var->setSection(*op.getSection());
1086 
1087  addRuntimePreemptionSpecifier(op.getDsoLocal(), var);
1088 
1089  std::optional<uint64_t> alignment = op.getAlignment();
1090  if (alignment.has_value())
1091  var->setAlignment(llvm::MaybeAlign(alignment.value()));
1092 
1093  var->setVisibility(convertVisibilityToLLVM(op.getVisibility_()));
1094 
1095  globalsMapping.try_emplace(op, var);
1096 
1097  // Add debug information if present.
1098  if (op.getDbgExprs()) {
1099  for (auto exprAttr :
1100  op.getDbgExprs()->getAsRange<DIGlobalVariableExpressionAttr>()) {
1101  llvm::DIGlobalVariableExpression *diGlobalExpr =
1102  debugTranslation->translateGlobalVariableExpression(exprAttr);
1103  llvm::DIGlobalVariable *diGlobalVar = diGlobalExpr->getVariable();
1104  var->addDebugInfo(diGlobalExpr);
1105 
1106  // There is no `globals` field in DICompileUnitAttr which can be
1107  // directly assigned to DICompileUnit. We have to build the list by
1108  // looking at the dbgExpr of all the GlobalOps. The scope of the
1109  // variable is used to get the DICompileUnit in which to add it. But
1110  // there are cases where the scope of a global does not directly point
1111  // to the DICompileUnit and we have to do a bit more work to get to
1112  // it. Some of those cases are:
1113  //
1114  // 1. For the languages that support modules, the scope hierarchy can
1115  // be variable -> DIModule -> DICompileUnit
1116  //
1117  // 2. For the Fortran common block variable, the scope hierarchy can
1118  // be variable -> DICommonBlock -> DISubprogram -> DICompileUnit
1119  //
1120  // 3. For entities like static local variables in C or variable with
1121  // SAVE attribute in Fortran, the scope hierarchy can be
1122  // variable -> DISubprogram -> DICompileUnit
1123  llvm::DIScope *scope = diGlobalVar->getScope();
1124  if (auto *mod = dyn_cast_if_present<llvm::DIModule>(scope))
1125  scope = mod->getScope();
1126  else if (auto *cb = dyn_cast_if_present<llvm::DICommonBlock>(scope)) {
1127  if (auto *sp =
1128  dyn_cast_if_present<llvm::DISubprogram>(cb->getScope()))
1129  scope = sp->getUnit();
1130  } else if (auto *sp = dyn_cast_if_present<llvm::DISubprogram>(scope))
1131  scope = sp->getUnit();
1132 
1133  // Get the compile unit (scope) of the the global variable.
1134  if (llvm::DICompileUnit *compileUnit =
1135  dyn_cast_if_present<llvm::DICompileUnit>(scope)) {
1136  // Update the compile unit with this incoming global variable
1137  // expression during the finalizing step later.
1138  allGVars[compileUnit].push_back(diGlobalExpr);
1139  }
1140  }
1141  }
1142  }
1143 
1144  // Create all llvm::GlobalAlias
1145  for (auto op : getModuleBody(mlirModule).getOps<LLVM::AliasOp>()) {
1146  llvm::Type *type = convertType(op.getType());
1147  llvm::Constant *cst = nullptr;
1148  llvm::GlobalValue::LinkageTypes linkage =
1149  convertLinkageToLLVM(op.getLinkage());
1150  llvm::Module &llvmMod = *llvmModule;
1151 
1152  // Note address space and aliasee info isn't set just yet.
1153  llvm::GlobalAlias *var = llvm::GlobalAlias::create(
1154  type, op.getAddrSpace(), linkage, op.getSymName(), /*placeholder*/ cst,
1155  &llvmMod);
1156 
1157  var->setThreadLocalMode(op.getThreadLocal_()
1158  ? llvm::GlobalAlias::GeneralDynamicTLSModel
1159  : llvm::GlobalAlias::NotThreadLocal);
1160 
1161  // Note there is no need to setup the comdat because GlobalAlias calls into
1162  // the aliasee comdat information automatically.
1163 
1164  if (op.getUnnamedAddr().has_value())
1165  var->setUnnamedAddr(convertUnnamedAddrToLLVM(*op.getUnnamedAddr()));
1166 
1167  var->setVisibility(convertVisibilityToLLVM(op.getVisibility_()));
1168 
1169  aliasesMapping.try_emplace(op, var);
1170  }
1171 
1172  // Convert global variable bodies.
1173  for (auto op : getModuleBody(mlirModule).getOps<LLVM::GlobalOp>()) {
1174  if (Block *initializer = op.getInitializerBlock()) {
1175  llvm::IRBuilder<llvm::TargetFolder> builder(
1176  llvmModule->getContext(),
1177  llvm::TargetFolder(llvmModule->getDataLayout()));
1178 
1179  [[maybe_unused]] int numConstantsHit = 0;
1180  [[maybe_unused]] int numConstantsErased = 0;
1181  DenseMap<llvm::ConstantAggregate *, int> constantAggregateUseMap;
1182 
1183  for (auto &op : initializer->without_terminator()) {
1184  if (failed(convertOperation(op, builder)))
1185  return emitError(op.getLoc(), "fail to convert global initializer");
1186  auto *cst = dyn_cast<llvm::Constant>(lookupValue(op.getResult(0)));
1187  if (!cst)
1188  return emitError(op.getLoc(), "unemittable constant value");
1189 
1190  // When emitting an LLVM constant, a new constant is created and the old
1191  // constant may become dangling and take space. We should remove the
1192  // dangling constants to avoid memory explosion especially for constant
1193  // arrays whose number of elements is large.
1194  // Because multiple operations may refer to the same constant, we need
1195  // to count the number of uses of each constant array and remove it only
1196  // when the count becomes zero.
1197  if (auto *agg = dyn_cast<llvm::ConstantAggregate>(cst)) {
1198  numConstantsHit++;
1199  Value result = op.getResult(0);
1200  int numUsers = std::distance(result.use_begin(), result.use_end());
1201  auto [iterator, inserted] =
1202  constantAggregateUseMap.try_emplace(agg, numUsers);
1203  if (!inserted) {
1204  // Key already exists, update the value
1205  iterator->second += numUsers;
1206  }
1207  }
1208  // Scan the operands of the operation to decrement the use count of
1209  // constants. Erase the constant if the use count becomes zero.
1210  for (Value v : op.getOperands()) {
1211  auto cst = dyn_cast<llvm::ConstantAggregate>(lookupValue(v));
1212  if (!cst)
1213  continue;
1214  auto iter = constantAggregateUseMap.find(cst);
1215  assert(iter != constantAggregateUseMap.end() && "constant not found");
1216  iter->second--;
1217  if (iter->second == 0) {
1218  // NOTE: cannot call removeDeadConstantUsers() here because it
1219  // may remove the constant which has uses not be converted yet.
1220  if (cst->user_empty()) {
1221  cst->destroyConstant();
1222  numConstantsErased++;
1223  }
1224  constantAggregateUseMap.erase(iter);
1225  }
1226  }
1227  }
1228 
1229  ReturnOp ret = cast<ReturnOp>(initializer->getTerminator());
1230  llvm::Constant *cst =
1231  cast<llvm::Constant>(lookupValue(ret.getOperand(0)));
1232  auto *global = cast<llvm::GlobalVariable>(lookupGlobal(op));
1233  if (!shouldDropGlobalInitializer(global->getLinkage(), cst))
1234  global->setInitializer(cst);
1235 
1236  // Try to remove the dangling constants again after all operations are
1237  // converted.
1238  for (auto it : constantAggregateUseMap) {
1239  auto cst = it.first;
1240  cst->removeDeadConstantUsers();
1241  if (cst->user_empty()) {
1242  cst->destroyConstant();
1243  numConstantsErased++;
1244  }
1245  }
1246 
1247  LLVM_DEBUG(llvm::dbgs()
1248  << "Convert initializer for " << op.getName() << "\n";
1249  llvm::dbgs() << numConstantsHit << " new constants hit\n";
1250  llvm::dbgs()
1251  << numConstantsErased << " dangling constants erased\n";);
1252  }
1253  }
1254 
1255  // Convert llvm.mlir.global_ctors and dtors.
1256  for (Operation &op : getModuleBody(mlirModule)) {
1257  auto ctorOp = dyn_cast<GlobalCtorsOp>(op);
1258  auto dtorOp = dyn_cast<GlobalDtorsOp>(op);
1259  if (!ctorOp && !dtorOp)
1260  continue;
1261  auto range = ctorOp ? llvm::zip(ctorOp.getCtors(), ctorOp.getPriorities())
1262  : llvm::zip(dtorOp.getDtors(), dtorOp.getPriorities());
1263  auto appendGlobalFn =
1264  ctorOp ? llvm::appendToGlobalCtors : llvm::appendToGlobalDtors;
1265  for (auto symbolAndPriority : range) {
1266  llvm::Function *f = lookupFunction(
1267  cast<FlatSymbolRefAttr>(std::get<0>(symbolAndPriority)).getValue());
1268  appendGlobalFn(*llvmModule, f,
1269  cast<IntegerAttr>(std::get<1>(symbolAndPriority)).getInt(),
1270  /*Data=*/nullptr);
1271  }
1272  }
1273 
1274  for (auto op : getModuleBody(mlirModule).getOps<LLVM::GlobalOp>())
1275  if (failed(convertDialectAttributes(op, {})))
1276  return failure();
1277 
1278  // Finally, update the compile units their respective sets of global variables
1279  // created earlier.
1280  for (const auto &[compileUnit, globals] : allGVars) {
1281  compileUnit->replaceGlobalVariables(
1282  llvm::MDTuple::get(getLLVMContext(), globals));
1283  }
1284 
1285  // Convert global alias bodies.
1286  for (auto op : getModuleBody(mlirModule).getOps<LLVM::AliasOp>()) {
1287  Block &initializer = op.getInitializerBlock();
1288  llvm::IRBuilder<llvm::TargetFolder> builder(
1289  llvmModule->getContext(),
1290  llvm::TargetFolder(llvmModule->getDataLayout()));
1291 
1292  for (mlir::Operation &op : initializer.without_terminator()) {
1293  if (failed(convertOperation(op, builder)))
1294  return emitError(op.getLoc(), "fail to convert alias initializer");
1295  if (!isa<llvm::Constant>(lookupValue(op.getResult(0))))
1296  return emitError(op.getLoc(), "unemittable constant value");
1297  }
1298 
1299  auto ret = cast<ReturnOp>(initializer.getTerminator());
1300  auto *cst = cast<llvm::Constant>(lookupValue(ret.getOperand(0)));
1301  assert(aliasesMapping.count(op));
1302  auto *alias = cast<llvm::GlobalAlias>(aliasesMapping[op]);
1303  alias->setAliasee(cst);
1304  }
1305 
1306  for (auto op : getModuleBody(mlirModule).getOps<LLVM::AliasOp>())
1307  if (failed(convertDialectAttributes(op, {})))
1308  return failure();
1309 
1310  return success();
1311 }
1312 
1313 /// Attempts to add an attribute identified by `key`, optionally with the given
1314 /// `value` to LLVM function `llvmFunc`. Reports errors at `loc` if any. If the
1315 /// attribute has a kind known to LLVM IR, create the attribute of this kind,
1316 /// otherwise keep it as a string attribute. Performs additional checks for
1317 /// attributes known to have or not have a value in order to avoid assertions
1318 /// inside LLVM upon construction.
1319 static LogicalResult checkedAddLLVMFnAttribute(Location loc,
1320  llvm::Function *llvmFunc,
1321  StringRef key,
1322  StringRef value = StringRef()) {
1323  auto kind = llvm::Attribute::getAttrKindFromName(key);
1324  if (kind == llvm::Attribute::None) {
1325  llvmFunc->addFnAttr(key, value);
1326  return success();
1327  }
1328 
1329  if (llvm::Attribute::isIntAttrKind(kind)) {
1330  if (value.empty())
1331  return emitError(loc) << "LLVM attribute '" << key << "' expects a value";
1332 
1333  int64_t result;
1334  if (!value.getAsInteger(/*Radix=*/0, result))
1335  llvmFunc->addFnAttr(
1336  llvm::Attribute::get(llvmFunc->getContext(), kind, result));
1337  else
1338  llvmFunc->addFnAttr(key, value);
1339  return success();
1340  }
1341 
1342  if (!value.empty())
1343  return emitError(loc) << "LLVM attribute '" << key
1344  << "' does not expect a value, found '" << value
1345  << "'";
1346 
1347  llvmFunc->addFnAttr(kind);
1348  return success();
1349 }
1350 
1351 /// Return a representation of `value` as metadata.
1352 static llvm::Metadata *convertIntegerToMetadata(llvm::LLVMContext &context,
1353  const llvm::APInt &value) {
1354  llvm::Constant *constant = llvm::ConstantInt::get(context, value);
1355  return llvm::ConstantAsMetadata::get(constant);
1356 }
1357 
1358 /// Return a representation of `value` as an MDNode.
1359 static llvm::MDNode *convertIntegerToMDNode(llvm::LLVMContext &context,
1360  const llvm::APInt &value) {
1361  return llvm::MDNode::get(context, convertIntegerToMetadata(context, value));
1362 }
1363 
1364 /// Return an MDNode encoding `vec_type_hint` metadata.
1365 static llvm::MDNode *convertVecTypeHintToMDNode(llvm::LLVMContext &context,
1366  llvm::Type *type,
1367  bool isSigned) {
1368  llvm::Metadata *typeMD =
1370  llvm::Metadata *isSignedMD =
1371  convertIntegerToMetadata(context, llvm::APInt(32, isSigned ? 1 : 0));
1372  return llvm::MDNode::get(context, {typeMD, isSignedMD});
1373 }
1374 
1375 /// Return an MDNode with a tuple given by the values in `values`.
1376 static llvm::MDNode *convertIntegerArrayToMDNode(llvm::LLVMContext &context,
1377  ArrayRef<int32_t> values) {
1379  llvm::transform(
1380  values, std::back_inserter(mdValues), [&context](int32_t value) {
1381  return convertIntegerToMetadata(context, llvm::APInt(32, value));
1382  });
1383  return llvm::MDNode::get(context, mdValues);
1384 }
1385 
1386 /// Attaches the attributes listed in the given array attribute to `llvmFunc`.
1387 /// Reports error to `loc` if any and returns immediately. Expects `attributes`
1388 /// to be an array attribute containing either string attributes, treated as
1389 /// value-less LLVM attributes, or array attributes containing two string
1390 /// attributes, with the first string being the name of the corresponding LLVM
1391 /// attribute and the second string beings its value. Note that even integer
1392 /// attributes are expected to have their values expressed as strings.
1393 static LogicalResult
1394 forwardPassthroughAttributes(Location loc, std::optional<ArrayAttr> attributes,
1395  llvm::Function *llvmFunc) {
1396  if (!attributes)
1397  return success();
1398 
1399  for (Attribute attr : *attributes) {
1400  if (auto stringAttr = dyn_cast<StringAttr>(attr)) {
1401  if (failed(
1402  checkedAddLLVMFnAttribute(loc, llvmFunc, stringAttr.getValue())))
1403  return failure();
1404  continue;
1405  }
1406 
1407  auto arrayAttr = dyn_cast<ArrayAttr>(attr);
1408  if (!arrayAttr || arrayAttr.size() != 2)
1409  return emitError(loc)
1410  << "expected 'passthrough' to contain string or array attributes";
1411 
1412  auto keyAttr = dyn_cast<StringAttr>(arrayAttr[0]);
1413  auto valueAttr = dyn_cast<StringAttr>(arrayAttr[1]);
1414  if (!keyAttr || !valueAttr)
1415  return emitError(loc)
1416  << "expected arrays within 'passthrough' to contain two strings";
1417 
1418  if (failed(checkedAddLLVMFnAttribute(loc, llvmFunc, keyAttr.getValue(),
1419  valueAttr.getValue())))
1420  return failure();
1421  }
1422  return success();
1423 }
1424 
1425 LogicalResult ModuleTranslation::convertOneFunction(LLVMFuncOp func) {
1426  // Clear the block, branch value mappings, they are only relevant within one
1427  // function.
1428  blockMapping.clear();
1429  valueMapping.clear();
1430  branchMapping.clear();
1431  llvm::Function *llvmFunc = lookupFunction(func.getName());
1432 
1433  // Add function arguments to the value remapping table.
1434  for (auto [mlirArg, llvmArg] :
1435  llvm::zip(func.getArguments(), llvmFunc->args()))
1436  mapValue(mlirArg, &llvmArg);
1437 
1438  // Check the personality and set it.
1439  if (func.getPersonality()) {
1440  llvm::Type *ty = llvm::PointerType::getUnqual(llvmFunc->getContext());
1441  if (llvm::Constant *pfunc = getLLVMConstant(ty, func.getPersonalityAttr(),
1442  func.getLoc(), *this))
1443  llvmFunc->setPersonalityFn(pfunc);
1444  }
1445 
1446  if (std::optional<StringRef> section = func.getSection())
1447  llvmFunc->setSection(*section);
1448 
1449  if (func.getArmStreaming())
1450  llvmFunc->addFnAttr("aarch64_pstate_sm_enabled");
1451  else if (func.getArmLocallyStreaming())
1452  llvmFunc->addFnAttr("aarch64_pstate_sm_body");
1453  else if (func.getArmStreamingCompatible())
1454  llvmFunc->addFnAttr("aarch64_pstate_sm_compatible");
1455 
1456  if (func.getArmNewZa())
1457  llvmFunc->addFnAttr("aarch64_new_za");
1458  else if (func.getArmInZa())
1459  llvmFunc->addFnAttr("aarch64_in_za");
1460  else if (func.getArmOutZa())
1461  llvmFunc->addFnAttr("aarch64_out_za");
1462  else if (func.getArmInoutZa())
1463  llvmFunc->addFnAttr("aarch64_inout_za");
1464  else if (func.getArmPreservesZa())
1465  llvmFunc->addFnAttr("aarch64_preserves_za");
1466 
1467  if (auto targetCpu = func.getTargetCpu())
1468  llvmFunc->addFnAttr("target-cpu", *targetCpu);
1469 
1470  if (auto tuneCpu = func.getTuneCpu())
1471  llvmFunc->addFnAttr("tune-cpu", *tuneCpu);
1472 
1473  if (auto targetFeatures = func.getTargetFeatures())
1474  llvmFunc->addFnAttr("target-features", targetFeatures->getFeaturesString());
1475 
1476  if (auto attr = func.getVscaleRange())
1477  llvmFunc->addFnAttr(llvm::Attribute::getWithVScaleRangeArgs(
1478  getLLVMContext(), attr->getMinRange().getInt(),
1479  attr->getMaxRange().getInt()));
1480 
1481  if (auto unsafeFpMath = func.getUnsafeFpMath())
1482  llvmFunc->addFnAttr("unsafe-fp-math", llvm::toStringRef(*unsafeFpMath));
1483 
1484  if (auto noInfsFpMath = func.getNoInfsFpMath())
1485  llvmFunc->addFnAttr("no-infs-fp-math", llvm::toStringRef(*noInfsFpMath));
1486 
1487  if (auto noNansFpMath = func.getNoNansFpMath())
1488  llvmFunc->addFnAttr("no-nans-fp-math", llvm::toStringRef(*noNansFpMath));
1489 
1490  if (auto approxFuncFpMath = func.getApproxFuncFpMath())
1491  llvmFunc->addFnAttr("approx-func-fp-math",
1492  llvm::toStringRef(*approxFuncFpMath));
1493 
1494  if (auto noSignedZerosFpMath = func.getNoSignedZerosFpMath())
1495  llvmFunc->addFnAttr("no-signed-zeros-fp-math",
1496  llvm::toStringRef(*noSignedZerosFpMath));
1497 
1498  if (auto denormalFpMath = func.getDenormalFpMath())
1499  llvmFunc->addFnAttr("denormal-fp-math", *denormalFpMath);
1500 
1501  if (auto denormalFpMathF32 = func.getDenormalFpMathF32())
1502  llvmFunc->addFnAttr("denormal-fp-math-f32", *denormalFpMathF32);
1503 
1504  if (auto fpContract = func.getFpContract())
1505  llvmFunc->addFnAttr("fp-contract", *fpContract);
1506 
1507  // Add function attribute frame-pointer, if found.
1508  if (FramePointerKindAttr attr = func.getFramePointerAttr())
1509  llvmFunc->addFnAttr("frame-pointer",
1510  LLVM::framePointerKind::stringifyFramePointerKind(
1511  (attr.getFramePointerKind())));
1512 
1513  // First, create all blocks so we can jump to them.
1514  llvm::LLVMContext &llvmContext = llvmFunc->getContext();
1515  for (auto &bb : func) {
1516  auto *llvmBB = llvm::BasicBlock::Create(llvmContext);
1517  llvmBB->insertInto(llvmFunc);
1518  mapBlock(&bb, llvmBB);
1519  }
1520 
1521  // Then, convert blocks one by one in topological order to ensure defs are
1522  // converted before uses.
1523  auto blocks = getBlocksSortedByDominance(func.getBody());
1524  for (Block *bb : blocks) {
1525  CapturingIRBuilder builder(llvmContext,
1526  llvm::TargetFolder(llvmModule->getDataLayout()));
1527  if (failed(convertBlockImpl(*bb, bb->isEntryBlock(), builder,
1528  /*recordInsertions=*/true)))
1529  return failure();
1530  }
1531 
1532  // After all blocks have been traversed and values mapped, connect the PHI
1533  // nodes to the results of preceding blocks.
1534  detail::connectPHINodes(func.getBody(), *this);
1535 
1536  // Finally, convert dialect attributes attached to the function.
1537  return convertDialectAttributes(func, {});
1538 }
1539 
1540 LogicalResult ModuleTranslation::convertDialectAttributes(
1541  Operation *op, ArrayRef<llvm::Instruction *> instructions) {
1542  for (NamedAttribute attribute : op->getDialectAttrs())
1543  if (failed(iface.amendOperation(op, instructions, attribute, *this)))
1544  return failure();
1545  return success();
1546 }
1547 
1548 /// Converts memory effect attributes from `func` and attaches them to
1549 /// `llvmFunc`.
1550 static void convertFunctionMemoryAttributes(LLVMFuncOp func,
1551  llvm::Function *llvmFunc) {
1552  if (!func.getMemoryEffects())
1553  return;
1554 
1555  MemoryEffectsAttr memEffects = func.getMemoryEffectsAttr();
1556 
1557  // Add memory effects incrementally.
1558  llvm::MemoryEffects newMemEffects =
1559  llvm::MemoryEffects(llvm::MemoryEffects::Location::ArgMem,
1560  convertModRefInfoToLLVM(memEffects.getArgMem()));
1561  newMemEffects |= llvm::MemoryEffects(
1562  llvm::MemoryEffects::Location::InaccessibleMem,
1563  convertModRefInfoToLLVM(memEffects.getInaccessibleMem()));
1564  newMemEffects |=
1565  llvm::MemoryEffects(llvm::MemoryEffects::Location::Other,
1566  convertModRefInfoToLLVM(memEffects.getOther()));
1567  llvmFunc->setMemoryEffects(newMemEffects);
1568 }
1569 
1570 /// Converts function attributes from `func` and attaches them to `llvmFunc`.
1571 static void convertFunctionAttributes(LLVMFuncOp func,
1572  llvm::Function *llvmFunc) {
1573  if (func.getNoInlineAttr())
1574  llvmFunc->addFnAttr(llvm::Attribute::NoInline);
1575  if (func.getAlwaysInlineAttr())
1576  llvmFunc->addFnAttr(llvm::Attribute::AlwaysInline);
1577  if (func.getOptimizeNoneAttr())
1578  llvmFunc->addFnAttr(llvm::Attribute::OptimizeNone);
1579  if (func.getConvergentAttr())
1580  llvmFunc->addFnAttr(llvm::Attribute::Convergent);
1581  if (func.getNoUnwindAttr())
1582  llvmFunc->addFnAttr(llvm::Attribute::NoUnwind);
1583  if (func.getWillReturnAttr())
1584  llvmFunc->addFnAttr(llvm::Attribute::WillReturn);
1585  convertFunctionMemoryAttributes(func, llvmFunc);
1586 }
1587 
1588 /// Converts function attributes from `func` and attaches them to `llvmFunc`.
1589 static void convertFunctionKernelAttributes(LLVMFuncOp func,
1590  llvm::Function *llvmFunc,
1591  ModuleTranslation &translation) {
1592  llvm::LLVMContext &llvmContext = llvmFunc->getContext();
1593 
1594  if (VecTypeHintAttr vecTypeHint = func.getVecTypeHintAttr()) {
1595  Type type = vecTypeHint.getHint().getValue();
1596  llvm::Type *llvmType = translation.convertType(type);
1597  bool isSigned = vecTypeHint.getIsSigned();
1598  llvmFunc->setMetadata(
1599  func.getVecTypeHintAttrName(),
1600  convertVecTypeHintToMDNode(llvmContext, llvmType, isSigned));
1601  }
1602 
1603  if (std::optional<ArrayRef<int32_t>> workGroupSizeHint =
1604  func.getWorkGroupSizeHint()) {
1605  llvmFunc->setMetadata(
1606  func.getWorkGroupSizeHintAttrName(),
1607  convertIntegerArrayToMDNode(llvmContext, *workGroupSizeHint));
1608  }
1609 
1610  if (std::optional<ArrayRef<int32_t>> reqdWorkGroupSize =
1611  func.getReqdWorkGroupSize()) {
1612  llvmFunc->setMetadata(
1613  func.getReqdWorkGroupSizeAttrName(),
1614  convertIntegerArrayToMDNode(llvmContext, *reqdWorkGroupSize));
1615  }
1616 
1617  if (std::optional<uint32_t> intelReqdSubGroupSize =
1618  func.getIntelReqdSubGroupSize()) {
1619  llvmFunc->setMetadata(
1620  func.getIntelReqdSubGroupSizeAttrName(),
1621  convertIntegerToMDNode(llvmContext,
1622  llvm::APInt(32, *intelReqdSubGroupSize)));
1623  }
1624 }
1625 
1626 static LogicalResult convertParameterAttr(llvm::AttrBuilder &attrBuilder,
1627  llvm::Attribute::AttrKind llvmKind,
1628  NamedAttribute namedAttr,
1629  ModuleTranslation &moduleTranslation,
1630  Location loc) {
1632  .Case<TypeAttr>([&](auto typeAttr) {
1633  attrBuilder.addTypeAttr(
1634  llvmKind, moduleTranslation.convertType(typeAttr.getValue()));
1635  return success();
1636  })
1637  .Case<IntegerAttr>([&](auto intAttr) {
1638  attrBuilder.addRawIntAttr(llvmKind, intAttr.getInt());
1639  return success();
1640  })
1641  .Case<UnitAttr>([&](auto) {
1642  attrBuilder.addAttribute(llvmKind);
1643  return success();
1644  })
1645  .Case<LLVM::ConstantRangeAttr>([&](auto rangeAttr) {
1646  attrBuilder.addConstantRangeAttr(
1647  llvmKind,
1648  llvm::ConstantRange(rangeAttr.getLower(), rangeAttr.getUpper()));
1649  return success();
1650  })
1651  .Default([loc](auto) {
1652  return emitError(loc, "unsupported parameter attribute type");
1653  });
1654 }
1655 
1656 FailureOr<llvm::AttrBuilder>
1657 ModuleTranslation::convertParameterAttrs(LLVMFuncOp func, int argIdx,
1658  DictionaryAttr paramAttrs) {
1659  llvm::AttrBuilder attrBuilder(llvmModule->getContext());
1660  auto attrNameToKindMapping = getAttrNameToKindMapping();
1661  Location loc = func.getLoc();
1662 
1663  for (auto namedAttr : paramAttrs) {
1664  auto it = attrNameToKindMapping.find(namedAttr.getName());
1665  if (it != attrNameToKindMapping.end()) {
1666  llvm::Attribute::AttrKind llvmKind = it->second;
1667  if (failed(convertParameterAttr(attrBuilder, llvmKind, namedAttr, *this,
1668  loc)))
1669  return failure();
1670  } else if (namedAttr.getNameDialect()) {
1671  if (failed(iface.convertParameterAttr(func, argIdx, namedAttr, *this)))
1672  return failure();
1673  }
1674  }
1675 
1676  return attrBuilder;
1677 }
1678 
1679 FailureOr<llvm::AttrBuilder>
1681  DictionaryAttr paramAttrs) {
1682  llvm::AttrBuilder attrBuilder(llvmModule->getContext());
1683  Location loc = callOp.getLoc();
1684  auto attrNameToKindMapping = getAttrNameToKindMapping();
1685 
1686  for (auto namedAttr : paramAttrs) {
1687  auto it = attrNameToKindMapping.find(namedAttr.getName());
1688  if (it != attrNameToKindMapping.end()) {
1689  llvm::Attribute::AttrKind llvmKind = it->second;
1690  if (failed(convertParameterAttr(attrBuilder, llvmKind, namedAttr, *this,
1691  loc)))
1692  return failure();
1693  }
1694  }
1695 
1696  return attrBuilder;
1697 }
1698 
1699 LogicalResult ModuleTranslation::convertFunctionSignatures() {
1700  // Declare all functions first because there may be function calls that form a
1701  // call graph with cycles, or global initializers that reference functions.
1702  for (auto function : getModuleBody(mlirModule).getOps<LLVMFuncOp>()) {
1703  llvm::FunctionCallee llvmFuncCst = llvmModule->getOrInsertFunction(
1704  function.getName(),
1705  cast<llvm::FunctionType>(convertType(function.getFunctionType())));
1706  llvm::Function *llvmFunc = cast<llvm::Function>(llvmFuncCst.getCallee());
1707  llvmFunc->setLinkage(convertLinkageToLLVM(function.getLinkage()));
1708  llvmFunc->setCallingConv(convertCConvToLLVM(function.getCConv()));
1709  mapFunction(function.getName(), llvmFunc);
1710  addRuntimePreemptionSpecifier(function.getDsoLocal(), llvmFunc);
1711 
1712  // Convert function attributes.
1713  convertFunctionAttributes(function, llvmFunc);
1714 
1715  // Convert function kernel attributes to metadata.
1716  convertFunctionKernelAttributes(function, llvmFunc, *this);
1717 
1718  // Convert function_entry_count attribute to metadata.
1719  if (std::optional<uint64_t> entryCount = function.getFunctionEntryCount())
1720  llvmFunc->setEntryCount(entryCount.value());
1721 
1722  // Convert result attributes.
1723  if (ArrayAttr allResultAttrs = function.getAllResultAttrs()) {
1724  DictionaryAttr resultAttrs = cast<DictionaryAttr>(allResultAttrs[0]);
1725  FailureOr<llvm::AttrBuilder> attrBuilder =
1726  convertParameterAttrs(function, -1, resultAttrs);
1727  if (failed(attrBuilder))
1728  return failure();
1729  llvmFunc->addRetAttrs(*attrBuilder);
1730  }
1731 
1732  // Convert argument attributes.
1733  for (auto [argIdx, llvmArg] : llvm::enumerate(llvmFunc->args())) {
1734  if (DictionaryAttr argAttrs = function.getArgAttrDict(argIdx)) {
1735  FailureOr<llvm::AttrBuilder> attrBuilder =
1736  convertParameterAttrs(function, argIdx, argAttrs);
1737  if (failed(attrBuilder))
1738  return failure();
1739  llvmArg.addAttrs(*attrBuilder);
1740  }
1741  }
1742 
1743  // Forward the pass-through attributes to LLVM.
1744  if (failed(forwardPassthroughAttributes(
1745  function.getLoc(), function.getPassthrough(), llvmFunc)))
1746  return failure();
1747 
1748  // Convert visibility attribute.
1749  llvmFunc->setVisibility(convertVisibilityToLLVM(function.getVisibility_()));
1750 
1751  // Convert the comdat attribute.
1752  if (std::optional<mlir::SymbolRefAttr> comdat = function.getComdat()) {
1753  auto selectorOp = cast<ComdatSelectorOp>(
1754  SymbolTable::lookupNearestSymbolFrom(function, *comdat));
1755  llvmFunc->setComdat(comdatMapping.lookup(selectorOp));
1756  }
1757 
1758  if (auto gc = function.getGarbageCollector())
1759  llvmFunc->setGC(gc->str());
1760 
1761  if (auto unnamedAddr = function.getUnnamedAddr())
1762  llvmFunc->setUnnamedAddr(convertUnnamedAddrToLLVM(*unnamedAddr));
1763 
1764  if (auto alignment = function.getAlignment())
1765  llvmFunc->setAlignment(llvm::MaybeAlign(*alignment));
1766 
1767  // Translate the debug information for this function.
1768  debugTranslation->translate(function, *llvmFunc);
1769  }
1770 
1771  return success();
1772 }
1773 
1774 LogicalResult ModuleTranslation::convertFunctions() {
1775  // Convert functions.
1776  for (auto function : getModuleBody(mlirModule).getOps<LLVMFuncOp>()) {
1777  // Do not convert external functions, but do process dialect attributes
1778  // attached to them.
1779  if (function.isExternal()) {
1780  if (failed(convertDialectAttributes(function, {})))
1781  return failure();
1782  continue;
1783  }
1784 
1785  if (failed(convertOneFunction(function)))
1786  return failure();
1787  }
1788 
1789  return success();
1790 }
1791 
1792 LogicalResult ModuleTranslation::convertComdats() {
1793  for (auto comdatOp : getModuleBody(mlirModule).getOps<ComdatOp>()) {
1794  for (auto selectorOp : comdatOp.getOps<ComdatSelectorOp>()) {
1795  llvm::Module *module = getLLVMModule();
1796  if (module->getComdatSymbolTable().contains(selectorOp.getSymName()))
1797  return emitError(selectorOp.getLoc())
1798  << "comdat selection symbols must be unique even in different "
1799  "comdat regions";
1800  llvm::Comdat *comdat = module->getOrInsertComdat(selectorOp.getSymName());
1801  comdat->setSelectionKind(convertComdatToLLVM(selectorOp.getComdat()));
1802  comdatMapping.try_emplace(selectorOp, comdat);
1803  }
1804  }
1805  return success();
1806 }
1807 
1808 void ModuleTranslation::setAccessGroupsMetadata(AccessGroupOpInterface op,
1809  llvm::Instruction *inst) {
1810  if (llvm::MDNode *node = loopAnnotationTranslation->getAccessGroups(op))
1811  inst->setMetadata(llvm::LLVMContext::MD_access_group, node);
1812 }
1813 
1814 llvm::MDNode *
1815 ModuleTranslation::getOrCreateAliasScope(AliasScopeAttr aliasScopeAttr) {
1816  auto [scopeIt, scopeInserted] =
1817  aliasScopeMetadataMapping.try_emplace(aliasScopeAttr, nullptr);
1818  if (!scopeInserted)
1819  return scopeIt->second;
1820  llvm::LLVMContext &ctx = llvmModule->getContext();
1821  auto dummy = llvm::MDNode::getTemporary(ctx, std::nullopt);
1822  // Convert the domain metadata node if necessary.
1823  auto [domainIt, insertedDomain] = aliasDomainMetadataMapping.try_emplace(
1824  aliasScopeAttr.getDomain(), nullptr);
1825  if (insertedDomain) {
1827  // Placeholder for potential self-reference.
1828  operands.push_back(dummy.get());
1829  if (StringAttr description = aliasScopeAttr.getDomain().getDescription())
1830  operands.push_back(llvm::MDString::get(ctx, description));
1831  domainIt->second = llvm::MDNode::get(ctx, operands);
1832  // Self-reference for uniqueness.
1833  llvm::Metadata *replacement;
1834  if (auto stringAttr =
1835  dyn_cast<StringAttr>(aliasScopeAttr.getDomain().getId()))
1836  replacement = llvm::MDString::get(ctx, stringAttr.getValue());
1837  else
1838  replacement = domainIt->second;
1839  domainIt->second->replaceOperandWith(0, replacement);
1840  }
1841  // Convert the scope metadata node.
1842  assert(domainIt->second && "Scope's domain should already be valid");
1844  // Placeholder for potential self-reference.
1845  operands.push_back(dummy.get());
1846  operands.push_back(domainIt->second);
1847  if (StringAttr description = aliasScopeAttr.getDescription())
1848  operands.push_back(llvm::MDString::get(ctx, description));
1849  scopeIt->second = llvm::MDNode::get(ctx, operands);
1850  // Self-reference for uniqueness.
1851  llvm::Metadata *replacement;
1852  if (auto stringAttr = dyn_cast<StringAttr>(aliasScopeAttr.getId()))
1853  replacement = llvm::MDString::get(ctx, stringAttr.getValue());
1854  else
1855  replacement = scopeIt->second;
1856  scopeIt->second->replaceOperandWith(0, replacement);
1857  return scopeIt->second;
1858 }
1859 
1861  ArrayRef<AliasScopeAttr> aliasScopeAttrs) {
1863  nodes.reserve(aliasScopeAttrs.size());
1864  for (AliasScopeAttr aliasScopeAttr : aliasScopeAttrs)
1865  nodes.push_back(getOrCreateAliasScope(aliasScopeAttr));
1866  return llvm::MDNode::get(getLLVMContext(), nodes);
1867 }
1868 
1869 void ModuleTranslation::setAliasScopeMetadata(AliasAnalysisOpInterface op,
1870  llvm::Instruction *inst) {
1871  auto populateScopeMetadata = [&](ArrayAttr aliasScopeAttrs, unsigned kind) {
1872  if (!aliasScopeAttrs || aliasScopeAttrs.empty())
1873  return;
1874  llvm::MDNode *node = getOrCreateAliasScopes(
1875  llvm::to_vector(aliasScopeAttrs.getAsRange<AliasScopeAttr>()));
1876  inst->setMetadata(kind, node);
1877  };
1878 
1879  populateScopeMetadata(op.getAliasScopesOrNull(),
1880  llvm::LLVMContext::MD_alias_scope);
1881  populateScopeMetadata(op.getNoAliasScopesOrNull(),
1882  llvm::LLVMContext::MD_noalias);
1883 }
1884 
1885 llvm::MDNode *ModuleTranslation::getTBAANode(TBAATagAttr tbaaAttr) const {
1886  return tbaaMetadataMapping.lookup(tbaaAttr);
1887 }
1888 
1889 void ModuleTranslation::setTBAAMetadata(AliasAnalysisOpInterface op,
1890  llvm::Instruction *inst) {
1891  ArrayAttr tagRefs = op.getTBAATagsOrNull();
1892  if (!tagRefs || tagRefs.empty())
1893  return;
1894 
1895  // LLVM IR currently does not support attaching more than one TBAA access tag
1896  // to a memory accessing instruction. It may be useful to support this in
1897  // future, but for the time being just ignore the metadata if MLIR operation
1898  // has multiple access tags.
1899  if (tagRefs.size() > 1) {
1900  op.emitWarning() << "TBAA access tags were not translated, because LLVM "
1901  "IR only supports a single tag per instruction";
1902  return;
1903  }
1904 
1905  llvm::MDNode *node = getTBAANode(cast<TBAATagAttr>(tagRefs[0]));
1906  inst->setMetadata(llvm::LLVMContext::MD_tbaa, node);
1907 }
1908 
1909 void ModuleTranslation::setBranchWeightsMetadata(BranchWeightOpInterface op) {
1910  DenseI32ArrayAttr weightsAttr = op.getBranchWeightsOrNull();
1911  if (!weightsAttr)
1912  return;
1913 
1914  llvm::Instruction *inst = isa<CallOp>(op) ? lookupCall(op) : lookupBranch(op);
1915  assert(inst && "expected the operation to have a mapping to an instruction");
1916  SmallVector<uint32_t> weights(weightsAttr.asArrayRef());
1917  inst->setMetadata(
1918  llvm::LLVMContext::MD_prof,
1919  llvm::MDBuilder(getLLVMContext()).createBranchWeights(weights));
1920 }
1921 
1922 LogicalResult ModuleTranslation::createTBAAMetadata() {
1923  llvm::LLVMContext &ctx = llvmModule->getContext();
1924  llvm::IntegerType *offsetTy = llvm::IntegerType::get(ctx, 64);
1925 
1926  // Walk the entire module and create all metadata nodes for the TBAA
1927  // attributes. The code below relies on two invariants of the
1928  // `AttrTypeWalker`:
1929  // 1. Attributes are visited in post-order: Since the attributes create a DAG,
1930  // this ensures that any lookups into `tbaaMetadataMapping` for child
1931  // attributes succeed.
1932  // 2. Attributes are only ever visited once: This way we don't leak any
1933  // LLVM metadata instances.
1934  AttrTypeWalker walker;
1935  walker.addWalk([&](TBAARootAttr root) {
1936  tbaaMetadataMapping.insert(
1937  {root, llvm::MDNode::get(ctx, llvm::MDString::get(ctx, root.getId()))});
1938  });
1939 
1940  walker.addWalk([&](TBAATypeDescriptorAttr descriptor) {
1942  operands.push_back(llvm::MDString::get(ctx, descriptor.getId()));
1943  for (TBAAMemberAttr member : descriptor.getMembers()) {
1944  operands.push_back(tbaaMetadataMapping.lookup(member.getTypeDesc()));
1945  operands.push_back(llvm::ConstantAsMetadata::get(
1946  llvm::ConstantInt::get(offsetTy, member.getOffset())));
1947  }
1948 
1949  tbaaMetadataMapping.insert({descriptor, llvm::MDNode::get(ctx, operands)});
1950  });
1951 
1952  walker.addWalk([&](TBAATagAttr tag) {
1954 
1955  operands.push_back(tbaaMetadataMapping.lookup(tag.getBaseType()));
1956  operands.push_back(tbaaMetadataMapping.lookup(tag.getAccessType()));
1957 
1958  operands.push_back(llvm::ConstantAsMetadata::get(
1959  llvm::ConstantInt::get(offsetTy, tag.getOffset())));
1960  if (tag.getConstant())
1961  operands.push_back(
1963 
1964  tbaaMetadataMapping.insert({tag, llvm::MDNode::get(ctx, operands)});
1965  });
1966 
1967  mlirModule->walk([&](AliasAnalysisOpInterface analysisOpInterface) {
1968  if (auto attr = analysisOpInterface.getTBAATagsOrNull())
1969  walker.walk(attr);
1970  });
1971 
1972  return success();
1973 }
1974 
1975 LogicalResult ModuleTranslation::createIdentMetadata() {
1976  if (auto attr = mlirModule->getAttrOfType<StringAttr>(
1977  LLVMDialect::getIdentAttrName())) {
1978  StringRef ident = attr;
1979  llvm::LLVMContext &ctx = llvmModule->getContext();
1980  llvm::NamedMDNode *namedMd =
1981  llvmModule->getOrInsertNamedMetadata(LLVMDialect::getIdentAttrName());
1982  llvm::MDNode *md = llvm::MDNode::get(ctx, llvm::MDString::get(ctx, ident));
1983  namedMd->addOperand(md);
1984  }
1985 
1986  return success();
1987 }
1988 
1989 LogicalResult ModuleTranslation::createCommandlineMetadata() {
1990  if (auto attr = mlirModule->getAttrOfType<StringAttr>(
1991  LLVMDialect::getCommandlineAttrName())) {
1992  StringRef cmdLine = attr;
1993  llvm::LLVMContext &ctx = llvmModule->getContext();
1994  llvm::NamedMDNode *nmd = llvmModule->getOrInsertNamedMetadata(
1995  LLVMDialect::getCommandlineAttrName());
1996  llvm::MDNode *md =
1997  llvm::MDNode::get(ctx, llvm::MDString::get(ctx, cmdLine));
1998  nmd->addOperand(md);
1999  }
2000 
2001  return success();
2002 }
2003 
2005  llvm::Instruction *inst) {
2006  LoopAnnotationAttr attr =
2008  .Case<LLVM::BrOp, LLVM::CondBrOp>(
2009  [](auto branchOp) { return branchOp.getLoopAnnotationAttr(); });
2010  if (!attr)
2011  return;
2012  llvm::MDNode *loopMD =
2013  loopAnnotationTranslation->translateLoopAnnotation(attr, op);
2014  inst->setMetadata(llvm::LLVMContext::MD_loop, loopMD);
2015 }
2016 
2017 void ModuleTranslation::setDisjointFlag(Operation *op, llvm::Value *value) {
2018  auto iface = cast<DisjointFlagInterface>(op);
2019  // We do a dyn_cast here in case the value got folded into a constant.
2020  if (auto disjointInst = dyn_cast<llvm::PossiblyDisjointInst>(value))
2021  disjointInst->setIsDisjoint(iface.getIsDisjoint());
2022 }
2023 
2025  return typeTranslator.translateType(type);
2026 }
2027 
2028 /// A helper to look up remapped operands in the value remapping table.
2030  SmallVector<llvm::Value *> remapped;
2031  remapped.reserve(values.size());
2032  for (Value v : values)
2033  remapped.push_back(lookupValue(v));
2034  return remapped;
2035 }
2036 
2037 llvm::OpenMPIRBuilder *ModuleTranslation::getOpenMPBuilder() {
2038  if (!ompBuilder) {
2039  ompBuilder = std::make_unique<llvm::OpenMPIRBuilder>(*llvmModule);
2040  ompBuilder->initialize();
2041 
2042  // Flags represented as top-level OpenMP dialect attributes are set in
2043  // `OpenMPDialectLLVMIRTranslationInterface::amendOperation()`. Here we set
2044  // the default configuration.
2045  ompBuilder->setConfig(llvm::OpenMPIRBuilderConfig(
2046  /* IsTargetDevice = */ false, /* IsGPU = */ false,
2047  /* OpenMPOffloadMandatory = */ false,
2048  /* HasRequiresReverseOffload = */ false,
2049  /* HasRequiresUnifiedAddress = */ false,
2050  /* HasRequiresUnifiedSharedMemory = */ false,
2051  /* HasRequiresDynamicAllocators = */ false));
2052  }
2053  return ompBuilder.get();
2054 }
2055 
2057  llvm::DILocalScope *scope) {
2058  return debugTranslation->translateLoc(loc, scope);
2059 }
2060 
2061 llvm::DIExpression *
2062 ModuleTranslation::translateExpression(LLVM::DIExpressionAttr attr) {
2063  return debugTranslation->translateExpression(attr);
2064 }
2065 
2066 llvm::DIGlobalVariableExpression *
2068  LLVM::DIGlobalVariableExpressionAttr attr) {
2069  return debugTranslation->translateGlobalVariableExpression(attr);
2070 }
2071 
2073  return debugTranslation->translate(attr);
2074 }
2075 
2076 llvm::RoundingMode
2077 ModuleTranslation::translateRoundingMode(LLVM::RoundingMode rounding) {
2078  return convertRoundingModeToLLVM(rounding);
2079 }
2080 
2082  LLVM::FPExceptionBehavior exceptionBehavior) {
2083  return convertFPExceptionBehaviorToLLVM(exceptionBehavior);
2084 }
2085 
2086 llvm::NamedMDNode *
2088  return llvmModule->getOrInsertNamedMetadata(name);
2089 }
2090 
2091 void ModuleTranslation::StackFrame::anchor() {}
2092 
2093 static std::unique_ptr<llvm::Module>
2094 prepareLLVMModule(Operation *m, llvm::LLVMContext &llvmContext,
2095  StringRef name) {
2096  m->getContext()->getOrLoadDialect<LLVM::LLVMDialect>();
2097  auto llvmModule = std::make_unique<llvm::Module>(name, llvmContext);
2098  // ModuleTranslation can currently only construct modules in the old debug
2099  // info format, so set the flag accordingly.
2100  llvmModule->setNewDbgInfoFormatFlag(false);
2101  if (auto dataLayoutAttr =
2102  m->getDiscardableAttr(LLVM::LLVMDialect::getDataLayoutAttrName())) {
2103  llvmModule->setDataLayout(cast<StringAttr>(dataLayoutAttr).getValue());
2104  } else {
2105  FailureOr<llvm::DataLayout> llvmDataLayout(llvm::DataLayout(""));
2106  if (auto iface = dyn_cast<DataLayoutOpInterface>(m)) {
2107  if (DataLayoutSpecInterface spec = iface.getDataLayoutSpec()) {
2108  llvmDataLayout =
2109  translateDataLayout(spec, DataLayout(iface), m->getLoc());
2110  }
2111  } else if (auto mod = dyn_cast<ModuleOp>(m)) {
2112  if (DataLayoutSpecInterface spec = mod.getDataLayoutSpec()) {
2113  llvmDataLayout =
2114  translateDataLayout(spec, DataLayout(mod), m->getLoc());
2115  }
2116  }
2117  if (failed(llvmDataLayout))
2118  return nullptr;
2119  llvmModule->setDataLayout(*llvmDataLayout);
2120  }
2121  if (auto targetTripleAttr =
2122  m->getDiscardableAttr(LLVM::LLVMDialect::getTargetTripleAttrName()))
2123  llvmModule->setTargetTriple(cast<StringAttr>(targetTripleAttr).getValue());
2124 
2125  return llvmModule;
2126 }
2127 
2128 std::unique_ptr<llvm::Module>
2129 mlir::translateModuleToLLVMIR(Operation *module, llvm::LLVMContext &llvmContext,
2130  StringRef name, bool disableVerification) {
2131  if (!satisfiesLLVMModule(module)) {
2132  module->emitOpError("can not be translated to an LLVMIR module");
2133  return nullptr;
2134  }
2135 
2136  std::unique_ptr<llvm::Module> llvmModule =
2137  prepareLLVMModule(module, llvmContext, name);
2138  if (!llvmModule)
2139  return nullptr;
2140 
2143 
2144  ModuleTranslation translator(module, std::move(llvmModule));
2145  llvm::IRBuilder<llvm::TargetFolder> llvmBuilder(
2146  llvmContext,
2147  llvm::TargetFolder(translator.getLLVMModule()->getDataLayout()));
2148 
2149  // Convert module before functions and operations inside, so dialect
2150  // attributes can be used to change dialect-specific global configurations via
2151  // `amendOperation()`. These configurations can then influence the translation
2152  // of operations afterwards.
2153  if (failed(translator.convertOperation(*module, llvmBuilder)))
2154  return nullptr;
2155 
2156  if (failed(translator.convertComdats()))
2157  return nullptr;
2158  if (failed(translator.convertFunctionSignatures()))
2159  return nullptr;
2160  if (failed(translator.convertGlobalsAndAliases()))
2161  return nullptr;
2162  if (failed(translator.createTBAAMetadata()))
2163  return nullptr;
2164  if (failed(translator.createIdentMetadata()))
2165  return nullptr;
2166  if (failed(translator.createCommandlineMetadata()))
2167  return nullptr;
2168 
2169  // Convert other top-level operations if possible.
2170  for (Operation &o : getModuleBody(module).getOperations()) {
2171  if (!isa<LLVM::LLVMFuncOp, LLVM::AliasOp, LLVM::GlobalOp,
2172  LLVM::GlobalCtorsOp, LLVM::GlobalDtorsOp, LLVM::ComdatOp>(&o) &&
2173  !o.hasTrait<OpTrait::IsTerminator>() &&
2174  failed(translator.convertOperation(o, llvmBuilder))) {
2175  return nullptr;
2176  }
2177  }
2178 
2179  // Operations in function bodies with symbolic references must be converted
2180  // after the top-level operations they refer to are declared, so we do it
2181  // last.
2182  if (failed(translator.convertFunctions()))
2183  return nullptr;
2184 
2185  // Once we've finished constructing elements in the module, we should convert
2186  // it to use the debug info format desired by LLVM.
2187  // See https://llvm.org/docs/RemoveDIsDebugInfo.html
2188  translator.llvmModule->setIsNewDbgInfoFormat(UseNewDbgInfoFormat);
2189 
2190  if (!disableVerification &&
2191  llvm::verifyModule(*translator.llvmModule, &llvm::errs()))
2192  return nullptr;
2193 
2194  return std::move(translator.llvmModule);
2195 }
static MLIRContext * getContext(OpFoldResult val)
@ None
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.
static llvm::MDNode * convertIntegerToMDNode(llvm::LLVMContext &context, const llvm::APInt &value)
Return a representation of value as an MDNode.
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.
static llvm::MDNode * convertVecTypeHintToMDNode(llvm::LLVMContext &context, llvm::Type *type, bool isSigned)
Return an MDNode encoding vec_type_hint metadata.
static Block & getModuleBody(Operation *module)
A helper method to get the single Block in an operation honoring LLVM's module requirements.
static llvm::MDNode * convertIntegerArrayToMDNode(llvm::LLVMContext &context, ArrayRef< int32_t > values)
Return an MDNode with a tuple given by the values in values.
static llvm::Metadata * convertIntegerToMetadata(llvm::LLVMContext &context, const llvm::APInt &value)
Return a representation of value as metadata.
static void addRuntimePreemptionSpecifier(bool dsoLocalRequested, llvm::GlobalValue *gv)
Sets the runtime preemption specifier of gv to dso_local if dsoLocalRequested is true,...
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...
static void convertFunctionAttributes(LLVMFuncOp func, llvm::Function *llvmFunc)
Converts function attributes from func and attaches them to llvmFunc.
llvm::cl::opt< bool > UseNewDbgInfoFormat
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.
static llvm::Type * getInnermostElementType(llvm::Type *type)
Returns the first non-sequential type nested in sequential types.
static void convertFunctionKernelAttributes(LLVMFuncOp func, llvm::Function *llvmFunc, ModuleTranslation &translation)
Converts function attributes from func and attaches them to llvmFunc.
static std::unique_ptr< llvm::Module > prepareLLVMModule(Operation *m, llvm::LLVMContext &llvmContext, StringRef name)
static llvm::Constant * convertDenseResourceElementsAttr(Location loc, DenseResourceElementsAttr denseResourceAttr, llvm::Type *llvmType, const ModuleTranslation &moduleTranslation)
Convert a dense resource elements attribute to an LLVM IR constant using its raw data storage if poss...
static LogicalResult convertParameterAttr(llvm::AttrBuilder &attrBuilder, llvm::Attribute::AttrKind llvmKind, NamedAttribute namedAttr, ModuleTranslation &moduleTranslation, Location loc)
static void convertFunctionMemoryAttributes(LLVMFuncOp func, llvm::Function *llvmFunc)
Converts memory effect attributes from func and attaches them to llvmFunc.
static LogicalResult forwardPassthroughAttributes(Location loc, std::optional< ArrayAttr > attributes, llvm::Function *llvmFunc)
Attaches the attributes listed in the given array attribute to llvmFunc.
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...
This class represents a processed binary blob of data.
Definition: AsmState.h:90
ArrayRef< char > getData() const
Return the raw underlying data of this blob.
Definition: AsmState.h:144
void addWalk(WalkFn< Attribute > &&fn)
Register a walk function for a given attribute or type.
WalkResult walk(T element)
Walk the given attribute/type, and recursively walk any sub elements.
Attributes are known-constant values of operations.
Definition: Attributes.h:25
Block represents an ordered list of Operations.
Definition: Block.h:33
Operation * getTerminator()
Get the terminator operation of this block.
Definition: Block.cpp:246
iterator_range< pred_iterator > getPredecessors()
Definition: Block.h:237
BlockArgListType getArguments()
Definition: Block.h:87
Operation & front()
Definition: Block.h:153
iterator_range< iterator > without_terminator()
Return an iterator range over the operation within this block excluding the terminator operation at t...
Definition: Block.h:209
The main mechanism for performing data layout queries.
std::optional< uint64_t > getTypeIndexBitwidth(Type t) const
Returns the bitwidth that should be used when performing index computations for the given pointer-lik...
uint64_t getTypePreferredAlignment(Type t) const
Returns the preferred of the given type in the current scope.
uint64_t getTypeABIAlignment(Type t) const
Returns the required alignment of the given type in the current scope.
llvm::TypeSize getTypeSizeInBits(Type t) const
Returns the size in bits of the given type in the current scope.
An attribute that represents a reference to a dense vector or tensor object.
std::enable_if_t<!std::is_base_of< Attribute, T >::value||std::is_same< Attribute, T >::value, T > getSplatValue() const
Return the splat value for this attribute.
int64_t getNumElements() const
Returns the number of elements held by this attribute.
bool isSplat() const
Returns true if this attribute corresponds to a splat, i.e.
ArrayRef< char > getRawData() const
Return the raw storage data held by this attribute.
ShapedType getType() const
Return the type of this ElementsAttr, guaranteed to be a vector or tensor with static shape.
const InterfaceType * getInterfaceFor(Object *obj) const
Get the interface for a given object, or null if one is not registered.
Base class for dialect interfaces providing translation to LLVM IR.
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.
virtual LogicalResult convertParameterAttr(LLVM::LLVMFuncOp function, int argIdx, NamedAttribute attribute, LLVM::ModuleTranslation &moduleTranslation) const
Acts on the given function operation using the interface implemented by the dialect of one of the fun...
virtual LogicalResult amendOperation(Operation *op, ArrayRef< llvm::Instruction * > instructions, NamedAttribute attribute, LLVM::ModuleTranslation &moduleTranslation) const
Acts on the given operation using the interface implemented by the dialect of one of the operation's ...
This class represents the base attribute for all debug info attributes.
Definition: LLVMAttrs.h:27
Implementation class for module translation.
llvm::fp::ExceptionBehavior translateFPExceptionBehavior(LLVM::FPExceptionBehavior exceptionBehavior)
Translates the given LLVM FP exception behavior metadata.
llvm::Value * lookupValue(Value value) const
Finds an LLVM IR value corresponding to the given MLIR value.
llvm::DIGlobalVariableExpression * translateGlobalVariableExpression(LLVM::DIGlobalVariableExpressionAttr attr)
Translates the given LLVM global variable expression metadata.
llvm::NamedMDNode * getOrInsertNamedModuleMetadata(StringRef name)
Gets the named metadata in the LLVM IR module being constructed, creating it if it does not exist.
llvm::Instruction * lookupBranch(Operation *op) const
Finds an LLVM IR instruction that corresponds to the given MLIR operation with successors.
SmallVector< llvm::Value * > lookupValues(ValueRange values)
Looks up remapped a list of remapped values.
void mapFunction(StringRef name, llvm::Function *func)
Stores the mapping between a function name and its LLVM IR representation.
llvm::DILocation * translateLoc(Location loc, llvm::DILocalScope *scope)
Translates the given location.
llvm::BasicBlock * lookupBlock(Block *block) const
Finds an LLVM IR basic block that corresponds to the given MLIR block.
void setBranchWeightsMetadata(BranchWeightOpInterface op)
Sets LLVM profiling metadata for operations that have branch weights.
llvm::Type * convertType(Type type)
Converts the type from MLIR LLVM dialect to LLVM.
llvm::RoundingMode translateRoundingMode(LLVM::RoundingMode rounding)
Translates the given LLVM rounding mode metadata.
void setTBAAMetadata(AliasAnalysisOpInterface op, llvm::Instruction *inst)
Sets LLVM TBAA metadata for memory operations that have TBAA attributes.
llvm::DIExpression * translateExpression(LLVM::DIExpressionAttr attr)
Translates the given LLVM DWARF expression metadata.
llvm::OpenMPIRBuilder * getOpenMPBuilder()
Returns the OpenMP IR builder associated with the LLVM IR module being constructed.
llvm::CallInst * lookupCall(Operation *op) const
Finds an LLVM call instruction that corresponds to the given MLIR call operation.
llvm::Metadata * translateDebugInfo(LLVM::DINodeAttr attr)
Translates the given LLVM debug info metadata.
void setDisjointFlag(Operation *op, llvm::Value *value)
Sets the disjoint flag attribute for the exported instruction value given the original operation op.
llvm::LLVMContext & getLLVMContext() const
Returns the LLVM context in which the IR is being constructed.
llvm::GlobalValue * lookupGlobal(Operation *op)
Finds an LLVM IR global value that corresponds to the given MLIR operation defining a global value.
llvm::Module * getLLVMModule()
Returns the LLVM module in which the IR is being constructed.
llvm::Function * lookupFunction(StringRef name) const
Finds an LLVM IR function by its name.
llvm::MDNode * getOrCreateAliasScopes(ArrayRef< AliasScopeAttr > aliasScopeAttrs)
Returns the LLVM metadata corresponding to an array of mlir LLVM dialect alias scope attributes.
void mapBlock(Block *mlir, llvm::BasicBlock *llvm)
Stores the mapping between an MLIR block and LLVM IR basic block.
llvm::MDNode * getOrCreateAliasScope(AliasScopeAttr aliasScopeAttr)
Returns the LLVM metadata corresponding to a mlir LLVM dialect alias scope attribute.
void forgetMapping(Region &region)
Removes the mapping for blocks contained in the region and values defined in these blocks.
void setAliasScopeMetadata(AliasAnalysisOpInterface op, llvm::Instruction *inst)
void setAccessGroupsMetadata(AccessGroupOpInterface op, llvm::Instruction *inst)
void mapValue(Value mlir, llvm::Value *llvm)
Stores the mapping between an MLIR value and its LLVM IR counterpart.
FailureOr< llvm::AttrBuilder > convertParameterAttrs(CallOpInterface callOp, DictionaryAttr paramAttrs)
Translates parameter attributes of a call and adds them to the returned AttrBuilder.
void setLoopMetadata(Operation *op, llvm::Instruction *inst)
Sets LLVM loop metadata for branch operations that have a loop annotation attribute.
llvm::Type * translateType(Type type)
Translates the given MLIR LLVM dialect type to LLVM IR.
Definition: TypeToLLVM.cpp:192
A helper class that converts LoopAnnotationAttrs and AccessGroupAttrs into corresponding llvm::MDNode...
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition: Location.h:66
NamedAttribute represents a combination of a name and an Attribute value.
Definition: Attributes.h:207
Attribute getValue() const
Return the value of the attribute.
Definition: Attributes.h:222
This class provides the API for ops that are known to be terminators.
Definition: OpDefinition.h:765
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:88
Value getOperand(unsigned idx)
Definition: Operation.h:350
AttrClass getAttrOfType(StringAttr name)
Definition: Operation.h:550
Attribute getAttr(StringAttr name)
Return the specified attribute if present, null otherwise.
Definition: Operation.h:534
Block * getSuccessor(unsigned index)
Definition: Operation.h:709
unsigned getNumSuccessors()
Definition: Operation.h:707
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
Definition: Operation.h:407
std::enable_if_t< llvm::function_traits< std::decay_t< FnT > >::num_args==1, RetT > walk(FnT &&callback)
Walk the operation by calling the callback for each nested operation (including this one),...
Definition: Operation.h:798
Location getLoc()
The source location the operation was defined or derived from.
Definition: Operation.h:223
InFlightDiagnostic emitError(const Twine &message={})
Emit an error about fatal conditions with this operation, reporting up to any diagnostic handlers tha...
Definition: Operation.cpp:268
Region & getRegion(unsigned index)
Returns the region held by this operation at position 'index'.
Definition: Operation.h:687
OperationName getName()
The name of an operation is the key identifier for it.
Definition: Operation.h:119
dialect_attr_range getDialectAttrs()
Return a range corresponding to the dialect attributes for this operation.
Definition: Operation.h:637
operand_range getOperands()
Returns an iterator on the underlying Value's.
Definition: Operation.h:378
InFlightDiagnostic emitOpError(const Twine &message={})
Emit an error with the op name prefixed, like "'dim' op " which is convenient for verifiers.
Definition: Operation.cpp:671
This class contains a list of basic blocks and a link to the parent operation it is attached to.
Definition: Region.h:26
Block & front()
Definition: Region.h:65
This class models how operands are forwarded to block arguments in control flow.
bool empty() const
Returns true if there are no successor operands.
static Operation * lookupNearestSymbolFrom(Operation *from, StringAttr symbol)
Returns the operation registered with the given symbol name within the closest parent operation of,...
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:74
This class provides an abstraction over the different types of ranges over Values.
Definition: ValueRange.h:381
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:96
use_iterator use_end() const
Definition: Value.h:209
Type getType() const
Return the type of this value.
Definition: Value.h:129
use_iterator use_begin() const
Definition: Value.h:208
The OpAsmOpInterface, see OpAsmInterface.td for more details.
Definition: CallGraph.h:229
void connectPHINodes(Region &region, const ModuleTranslation &state)
For all blocks in the region that were converted to LLVM IR using the given ModuleTranslation,...
llvm::CallInst * 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.
static llvm::DenseMap< llvm::StringRef, llvm::Attribute::AttrKind > getAttrNameToKindMapping()
Returns a dense map from LLVM attribute name to their kind in LLVM IR dialect.
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.
bool satisfiesLLVMModule(Operation *op)
LLVM requires some operations to be inside of a Module operation.
void legalizeDIExpressionsRecursively(Operation *op)
Register all known legalization patterns declared here and apply them to all ops in op.
bool isCompatibleType(Type type)
Returns true if the given type is compatible with the LLVM dialect.
Definition: LLVMTypes.cpp:860
void ensureDistinctSuccessors(Operation *op)
Make argument-taking successors of each block distinct.
constexpr void enumerate(std::tuple< Tys... > &tuple, CallbackT &&callback)
Definition: Matchers.h:344
DictionaryAttr getArgAttrDict(FunctionOpInterface op, unsigned index)
Returns the dictionary attribute corresponding to the argument at 'index'.
Include the generated interface declarations.
std::unique_ptr< llvm::Module > translateModuleToLLVMIR(Operation *module, llvm::LLVMContext &llvmContext, llvm::StringRef name="LLVMDialectModule", bool disableVerification=false)
Translates a given LLVM dialect module into an LLVM IR module living in the given context.
SetVector< Block * > getBlocksSortedByDominance(Region &region)
Gets a list of blocks that is sorted according to dominance.
DataLayoutSpecInterface translateDataLayout(const llvm::DataLayout &dataLayout, MLIRContext *context)
Translate the given LLVM data layout into an MLIR equivalent using the DLTI dialect.
Type getType(OpFoldResult ofr)
Returns the int type of the integer in ofr.
Definition: Utils.cpp:305
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...