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