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