MLIR  17.0.0git
ModuleImport.cpp
Go to the documentation of this file.
1 //===- ModuleImport.cpp - LLVM to MLIR conversion ---------------*- C++ -*-===//
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 import of an LLVM IR module into an LLVM dialect
10 // module.
11 //
12 //===----------------------------------------------------------------------===//
13 
16 
17 #include "AttrKindDetail.h"
18 #include "DebugImporter.h"
19 #include "LoopAnnotationImporter.h"
20 
21 #include "mlir/Dialect/DLTI/DLTI.h"
23 #include "mlir/IR/Builders.h"
24 #include "mlir/IR/Matchers.h"
27 
28 #include "llvm/ADT/PostOrderIterator.h"
29 #include "llvm/ADT/ScopeExit.h"
30 #include "llvm/ADT/StringSet.h"
31 #include "llvm/IR/Constants.h"
32 #include "llvm/IR/InlineAsm.h"
33 #include "llvm/IR/InstIterator.h"
34 #include "llvm/IR/Instructions.h"
35 #include "llvm/IR/IntrinsicInst.h"
36 #include "llvm/IR/Metadata.h"
37 #include "llvm/IR/Operator.h"
38 #include "llvm/Support/ModRef.h"
39 
40 using namespace mlir;
41 using namespace mlir::LLVM;
42 using namespace mlir::LLVM::detail;
43 
44 #include "mlir/Dialect/LLVMIR/LLVMConversionEnumsFromLLVM.inc"
45 
46 // Utility to print an LLVM value as a string for passing to emitError().
47 // FIXME: Diagnostic should be able to natively handle types that have
48 // operator << (raw_ostream&) defined.
49 static std::string diag(const llvm::Value &value) {
50  std::string str;
51  llvm::raw_string_ostream os(str);
52  os << value;
53  return os.str();
54 }
55 
56 // Utility to print an LLVM metadata node as a string for passing
57 // to emitError(). The module argument is needed to print the nodes
58 // canonically numbered.
59 static std::string diagMD(const llvm::Metadata *node,
60  const llvm::Module *module) {
61  std::string str;
62  llvm::raw_string_ostream os(str);
63  node->print(os, module, /*IsForDebug=*/true);
64  return os.str();
65 }
66 
67 /// Returns the name of the global_ctors global variables.
68 static constexpr StringRef getGlobalCtorsVarName() {
69  return "llvm.global_ctors";
70 }
71 
72 /// Returns the name of the global_dtors global variables.
73 static constexpr StringRef getGlobalDtorsVarName() {
74  return "llvm.global_dtors";
75 }
76 
77 /// Returns the symbol name for the module-level metadata operation. It must not
78 /// conflict with the user namespace.
79 static constexpr StringRef getGlobalMetadataOpName() {
80  return "__llvm_global_metadata";
81 }
82 
83 /// Returns a supported MLIR floating point type of the given bit width or null
84 /// if the bit width is not supported.
85 static FloatType getDLFloatType(MLIRContext &ctx, int32_t bitwidth) {
86  switch (bitwidth) {
87  case 16:
88  return FloatType::getF16(&ctx);
89  case 32:
90  return FloatType::getF32(&ctx);
91  case 64:
92  return FloatType::getF64(&ctx);
93  case 80:
94  return FloatType::getF80(&ctx);
95  case 128:
96  return FloatType::getF128(&ctx);
97  default:
98  return nullptr;
99  }
100 }
101 
102 /// Converts the sync scope identifier of `inst` to the string representation
103 /// necessary to build an atomic LLVM dialect operation. Returns the empty
104 /// string if the operation has either no sync scope or the default system-level
105 /// sync scope attached. The atomic operations only set their sync scope
106 /// attribute if they have a non-default sync scope attached.
107 static StringRef getLLVMSyncScope(llvm::Instruction *inst) {
108  std::optional<llvm::SyncScope::ID> syncScopeID =
109  llvm::getAtomicSyncScopeID(inst);
110  if (!syncScopeID)
111  return "";
112 
113  // Search the sync scope name for the given identifier. The default
114  // system-level sync scope thereby maps to the empty string.
115  SmallVector<StringRef> syncScopeName;
116  llvm::LLVMContext &llvmContext = inst->getContext();
117  llvmContext.getSyncScopeNames(syncScopeName);
118  auto *it = llvm::find_if(syncScopeName, [&](StringRef name) {
119  return *syncScopeID == llvmContext.getOrInsertSyncScopeID(name);
120  });
121  if (it != syncScopeName.end())
122  return *it;
123  llvm_unreachable("incorrect sync scope identifier");
124 }
125 
126 /// Converts an array of unsigned indices to a signed integer position array.
128  SmallVector<int64_t> position;
129  llvm::append_range(position, indices);
130  return position;
131 }
132 
133 /// Converts the LLVM instructions that have a generated MLIR builder. Using a
134 /// static implementation method called from the module import ensures the
135 /// builders have to use the `moduleImport` argument and cannot directly call
136 /// import methods. As a result, both the intrinsic and the instruction MLIR
137 /// builders have to use the `moduleImport` argument and none of them has direct
138 /// access to the private module import methods.
140  llvm::Instruction *inst,
141  ModuleImport &moduleImport) {
142  // Copy the operands to an LLVM operands array reference for conversion.
143  SmallVector<llvm::Value *> operands(inst->operands());
144  ArrayRef<llvm::Value *> llvmOperands(operands);
145 
146  // Convert all instructions that provide an MLIR builder.
147 #include "mlir/Dialect/LLVMIR/LLVMOpFromLLVMIRConversions.inc"
148  return failure();
149 }
150 
151 /// Creates an attribute containing ABI and preferred alignment numbers parsed
152 /// a string. The string may be either "abi:preferred" or just "abi". In the
153 /// latter case, the preferred alignment is considered equal to ABI alignment.
155  StringRef spec) {
156  auto i32 = IntegerType::get(&ctx, 32);
157 
158  StringRef abiString, preferredString;
159  std::tie(abiString, preferredString) = spec.split(':');
160  int abi, preferred;
161  if (abiString.getAsInteger(/*Radix=*/10, abi))
162  return nullptr;
163 
164  if (preferredString.empty())
165  preferred = abi;
166  else if (preferredString.getAsInteger(/*Radix=*/10, preferred))
167  return nullptr;
168 
169  return DenseIntElementsAttr::get(VectorType::get({2}, i32), {abi, preferred});
170 }
171 
172 /// Translate the given LLVM data layout into an MLIR equivalent using the DLTI
173 /// dialect.
174 DataLayoutSpecInterface
175 mlir::translateDataLayout(const llvm::DataLayout &dataLayout,
176  MLIRContext *context) {
177  assert(context && "expected MLIR context");
178  std::string layoutstr = dataLayout.getStringRepresentation();
179 
180  // Remaining unhandled default layout defaults
181  // e (little endian if not set)
182  // p[n]:64:64:64 (non zero address spaces have 64-bit properties)
183  // Alloca address space defaults to 0.
184  std::string append =
185  "p:64:64:64-S0-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f16:16:16-f64:"
186  "64:64-f128:128:128-v64:64:64-v128:128:128-a:0:64-A0";
187  if (layoutstr.empty())
188  layoutstr = append;
189  else
190  layoutstr = layoutstr + "-" + append;
191 
192  StringRef layout(layoutstr);
193 
195  StringSet<> seen;
196  while (!layout.empty()) {
197  // Split at '-'.
198  std::pair<StringRef, StringRef> split = layout.split('-');
199  StringRef current;
200  std::tie(current, layout) = split;
201 
202  // Split at ':'.
203  StringRef kind, spec;
204  std::tie(kind, spec) = current.split(':');
205  if (seen.contains(kind))
206  continue;
207  seen.insert(kind);
208 
209  char symbol = kind.front();
210  StringRef parameter = kind.substr(1);
211 
212  if (symbol == 'i' || symbol == 'f') {
213  unsigned bitwidth;
214  if (parameter.getAsInteger(/*Radix=*/10, bitwidth))
215  return nullptr;
216  DenseIntElementsAttr params = parseDataLayoutAlignment(*context, spec);
217  if (!params)
218  return nullptr;
219  auto entry = DataLayoutEntryAttr::get(
220  symbol == 'i' ? static_cast<Type>(IntegerType::get(context, bitwidth))
221  : getDLFloatType(*context, bitwidth),
222  params);
223  entries.emplace_back(entry);
224  } else if (symbol == 'e' || symbol == 'E') {
225  auto value = StringAttr::get(
226  context, symbol == 'e' ? DLTIDialect::kDataLayoutEndiannessLittle
227  : DLTIDialect::kDataLayoutEndiannessBig);
228  auto entry = DataLayoutEntryAttr::get(
229  StringAttr::get(context, DLTIDialect::kDataLayoutEndiannessKey),
230  value);
231  entries.emplace_back(entry);
232  } else if (symbol == 'A') {
233  unsigned addressSpace;
234  if (parameter.getAsInteger(/*Radix=*/10, addressSpace))
235  return nullptr;
236  // Skip storing if generic address space is defined.
237  if (addressSpace != 0) {
238  auto entry = DataLayoutEntryAttr::get(
239  StringAttr::get(context,
240  DLTIDialect::kDataLayoutAllocaMemorySpaceKey),
241  mlir::Builder(context).getUI32IntegerAttr(addressSpace));
242  entries.emplace_back(entry);
243  }
244  }
245  }
246 
247  return DataLayoutSpecAttr::get(context, entries);
248 }
249 
250 /// Get a topologically sorted list of blocks for the given function.
252 getTopologicallySortedBlocks(llvm::Function *func) {
254  for (llvm::BasicBlock &bb : *func) {
255  if (blocks.count(&bb) == 0) {
256  llvm::ReversePostOrderTraversal<llvm::BasicBlock *> traversal(&bb);
257  blocks.insert(traversal.begin(), traversal.end());
258  }
259  }
260  assert(blocks.size() == func->size() && "some blocks are not sorted");
261 
262  return blocks;
263 }
264 
265 ModuleImport::ModuleImport(ModuleOp mlirModule,
266  std::unique_ptr<llvm::Module> llvmModule)
267  : builder(mlirModule->getContext()), context(mlirModule->getContext()),
268  mlirModule(mlirModule), llvmModule(std::move(llvmModule)),
269  iface(mlirModule->getContext()),
270  typeTranslator(*mlirModule->getContext()),
271  debugImporter(std::make_unique<DebugImporter>(mlirModule)),
272  loopAnnotationImporter(
273  std::make_unique<LoopAnnotationImporter>(builder)) {
274  builder.setInsertionPointToStart(mlirModule.getBody());
275 }
276 
277 MetadataOp ModuleImport::getGlobalMetadataOp() {
278  if (globalMetadataOp)
279  return globalMetadataOp;
280 
281  OpBuilder::InsertionGuard guard(builder);
282  builder.setInsertionPointToEnd(mlirModule.getBody());
283  return globalMetadataOp = builder.create<MetadataOp>(
284  mlirModule.getLoc(), getGlobalMetadataOpName());
285 }
286 
287 LogicalResult ModuleImport::processTBAAMetadata(const llvm::MDNode *node) {
288  Location loc = mlirModule.getLoc();
290  SetVector<const llvm::MDNode *> nodesToConvert;
291  workList.push_back(node);
292  while (!workList.empty()) {
293  const llvm::MDNode *current = workList.pop_back_val();
294  if (tbaaMapping.count(current))
295  continue;
296  // Allow cycles in TBAA metadata. Just import it as-is,
297  // and diagnose the problem during LLVMIR dialect verification.
298  if (!nodesToConvert.insert(current))
299  continue;
300  for (const llvm::MDOperand &operand : current->operands())
301  if (auto *opNode = dyn_cast_or_null<const llvm::MDNode>(operand.get()))
302  workList.push_back(opNode);
303  }
304 
305  // If `node` is a valid TBAA root node, then return its identity
306  // string, otherwise return std::nullopt.
307  auto getIdentityIfRootNode =
308  [&](const llvm::MDNode *node) -> std::optional<StringRef> {
309  // Root node, e.g.:
310  // !0 = !{!"Simple C/C++ TBAA"}
311  if (node->getNumOperands() != 1)
312  return std::nullopt;
313  // If the operand is MDString, then assume that this is a root node.
314  if (const auto *op0 = dyn_cast<const llvm::MDString>(node->getOperand(0)))
315  return op0->getString();
316  return std::nullopt;
317  };
318 
319  // If `node` looks like a TBAA type descriptor metadata,
320  // then return true, if it is a valid node, and false otherwise.
321  // If it does not look like a TBAA type descriptor metadata, then
322  // return std::nullopt.
323  // If `identity` and `memberTypes/Offsets` are non-null, then they will
324  // contain the converted metadata operands for a valid TBAA node (i.e. when
325  // true is returned).
326  auto isTypeDescriptorNode =
327  [&](const llvm::MDNode *node, StringRef *identity = nullptr,
328  SmallVectorImpl<Attribute> *memberTypes = nullptr,
329  SmallVectorImpl<int64_t> *memberOffsets =
330  nullptr) -> std::optional<bool> {
331  unsigned numOperands = node->getNumOperands();
332  // Type descriptor, e.g.:
333  // !1 = !{!"int", !0, /*optional*/i64 0} /* scalar int type */
334  // !2 = !{!"agg_t", !1, i64 0} /* struct agg_t { int x; } */
335  if (numOperands < 2)
336  return std::nullopt;
337 
338  // TODO: support "new" format (D41501) for type descriptors,
339  // where the first operand is an MDNode.
340  const auto *identityNode =
341  dyn_cast<const llvm::MDString>(node->getOperand(0));
342  if (!identityNode)
343  return std::nullopt;
344 
345  // This should be a type descriptor node.
346  if (identity)
347  *identity = identityNode->getString();
348 
349  for (unsigned pairNum = 0, e = numOperands / 2; pairNum < e; ++pairNum) {
350  const auto *memberNode =
351  dyn_cast<const llvm::MDNode>(node->getOperand(2 * pairNum + 1));
352  if (!memberNode) {
353  emitError(loc) << "operand '" << 2 * pairNum + 1 << "' must be MDNode: "
354  << diagMD(node, llvmModule.get());
355  return false;
356  }
357  int64_t offset = 0;
358  if (2 * pairNum + 2 >= numOperands) {
359  // Allow for optional 0 offset in 2-operand nodes.
360  if (numOperands != 2) {
361  emitError(loc) << "missing member offset: "
362  << diagMD(node, llvmModule.get());
363  return false;
364  }
365  } else {
366  auto *offsetCI = llvm::mdconst::dyn_extract<llvm::ConstantInt>(
367  node->getOperand(2 * pairNum + 2));
368  if (!offsetCI) {
369  emitError(loc) << "operand '" << 2 * pairNum + 2
370  << "' must be ConstantInt: "
371  << diagMD(node, llvmModule.get());
372  return false;
373  }
374  offset = offsetCI->getZExtValue();
375  }
376 
377  if (memberTypes)
378  memberTypes->push_back(tbaaMapping.lookup(memberNode));
379  if (memberOffsets)
380  memberOffsets->push_back(offset);
381  }
382 
383  return true;
384  };
385 
386  // If `node` looks like a TBAA access tag metadata,
387  // then return true, if it is a valid node, and false otherwise.
388  // If it does not look like a TBAA access tag metadata, then
389  // return std::nullopt.
390  // If the other arguments are non-null, then they will contain
391  // the converted metadata operands for a valid TBAA node (i.e. when true is
392  // returned).
393  auto isTagNode =
394  [&](const llvm::MDNode *node, SymbolRefAttr *baseSymRef = nullptr,
395  SymbolRefAttr *accessSymRef = nullptr, int64_t *offset = nullptr,
396  bool *isConstant = nullptr) -> std::optional<bool> {
397  // Access tag, e.g.:
398  // !3 = !{!1, !1, i64 0} /* scalar int access */
399  // !4 = !{!2, !1, i64 0} /* agg_t::x access */
400  //
401  // Optional 4th argument is ConstantInt 0/1 identifying whether
402  // the location being accessed is "constant" (see for details:
403  // https://llvm.org/docs/LangRef.html#representation).
404  unsigned numOperands = node->getNumOperands();
405  if (numOperands != 3 && numOperands != 4)
406  return std::nullopt;
407  const auto *baseMD = dyn_cast<const llvm::MDNode>(node->getOperand(0));
408  const auto *accessMD = dyn_cast<const llvm::MDNode>(node->getOperand(1));
409  auto *offsetCI =
410  llvm::mdconst::dyn_extract<llvm::ConstantInt>(node->getOperand(2));
411  if (!baseMD || !accessMD || !offsetCI)
412  return std::nullopt;
413  // TODO: support "new" TBAA format, if needed (see D41501).
414  // In the "old" format the first operand of the access type
415  // metadata is MDString. We have to distinguish the formats,
416  // because access tags have the same structure, but different
417  // meaning for the operands.
418  if (accessMD->getNumOperands() < 1 ||
419  !isa<llvm::MDString>(accessMD->getOperand(0)))
420  return std::nullopt;
421  bool isConst = false;
422  if (numOperands == 4) {
423  auto *isConstantCI =
424  llvm::mdconst::dyn_extract<llvm::ConstantInt>(node->getOperand(3));
425  if (!isConstantCI) {
426  emitError(loc) << "operand '3' must be ConstantInt: "
427  << diagMD(node, llvmModule.get());
428  return false;
429  }
430  isConst = isConstantCI->getValue()[0];
431  }
432  if (baseSymRef)
433  *baseSymRef = tbaaMapping.lookup(baseMD);
434  if (accessSymRef)
435  *accessSymRef = tbaaMapping.lookup(accessMD);
436  if (offset)
437  *offset = offsetCI->getZExtValue();
438  if (isConstant)
439  *isConstant = isConst;
440  return true;
441  };
442 
443  // Helper to compute a unique symbol name that includes the given `baseName`.
444  // Uses the size of the mapping to unique the symbol name.
445  auto getUniqueSymbolName = [&](StringRef baseName) {
446  return (Twine("tbaa_") + Twine(baseName) + Twine('_') +
447  Twine(tbaaMapping.size()))
448  .str();
449  };
450 
451  // Insert new operations at the end of the MetadataOp.
452  OpBuilder::InsertionGuard guard(builder);
453  builder.setInsertionPointToEnd(&getGlobalMetadataOp().getBody().back());
454  StringAttr metadataOpName = SymbolTable::getSymbolName(getGlobalMetadataOp());
455 
456  // On the first walk, create SymbolRefAttr's and map them
457  // to nodes in `nodesToConvert`.
458  for (const auto *current : nodesToConvert) {
459  if (std::optional<StringRef> identity = getIdentityIfRootNode(current)) {
460  if (identity.value().empty())
461  return emitError(loc) << "TBAA root node must have non-empty identity: "
462  << diagMD(current, llvmModule.get());
463 
464  // The root nodes do not have operands, so we can create
465  // the TBAARootMetadataOp on the first walk.
466  auto rootNode = builder.create<TBAARootMetadataOp>(
467  loc, getUniqueSymbolName("root"), identity.value());
468  tbaaMapping.try_emplace(current, FlatSymbolRefAttr::get(rootNode));
469  continue;
470  }
471  if (std::optional<bool> isValid = isTypeDescriptorNode(current)) {
472  if (!isValid.value())
473  return failure();
474  tbaaMapping.try_emplace(
475  current, FlatSymbolRefAttr::get(builder.getContext(),
476  getUniqueSymbolName("type_desc")));
477  continue;
478  }
479  if (std::optional<bool> isValid = isTagNode(current)) {
480  if (!isValid.value())
481  return failure();
482  // TBAATagOp symbols must be referred by their fully qualified
483  // names, so create a path to TBAATagOp symbol.
484  tbaaMapping.try_emplace(
485  current, SymbolRefAttr::get(
486  builder.getContext(), metadataOpName,
488  getUniqueSymbolName("tag"))));
489  continue;
490  }
491  return emitError(loc) << "unsupported TBAA node format: "
492  << diagMD(current, llvmModule.get());
493  }
494 
495  // On the second walk, create TBAA operations using the symbol names from the
496  // map.
497  for (const auto *current : nodesToConvert) {
498  StringRef identity;
499  SmallVector<Attribute> memberTypes;
500  SmallVector<int64_t> memberOffsets;
501  if (std::optional<bool> isValid = isTypeDescriptorNode(
502  current, &identity, &memberTypes, &memberOffsets)) {
503  assert(isValid.value() && "type descriptor node must be valid");
504 
505  builder.create<TBAATypeDescriptorOp>(
506  loc, tbaaMapping.lookup(current).getLeafReference(),
507  builder.getStringAttr(identity), builder.getArrayAttr(memberTypes),
508  memberOffsets);
509  continue;
510  }
511  SymbolRefAttr baseSymRef, accessSymRef;
512  int64_t offset;
513  bool isConstant;
514  if (std::optional<bool> isValid = isTagNode(
515  current, &baseSymRef, &accessSymRef, &offset, &isConstant)) {
516  assert(isValid.value() && "access tag node must be valid");
517  builder.create<TBAATagOp>(
518  loc, tbaaMapping.lookup(current).getLeafReference(),
519  baseSymRef.getLeafReference(), accessSymRef.getLeafReference(),
520  offset, isConstant);
521  continue;
522  }
523  }
524 
525  return success();
526 }
527 
529 ModuleImport::processAccessGroupMetadata(const llvm::MDNode *node) {
530  Location loc = mlirModule.getLoc();
531  if (failed(loopAnnotationImporter->translateAccessGroup(
532  node, loc, getGlobalMetadataOp())))
533  return emitError(loc) << "unsupported access group node: "
534  << diagMD(node, llvmModule.get());
535  return success();
536 }
537 
539 ModuleImport::processAliasScopeMetadata(const llvm::MDNode *node) {
540  Location loc = mlirModule.getLoc();
541  // Helper that verifies the node has a self reference operand.
542  auto verifySelfRef = [](const llvm::MDNode *node) {
543  return node->getNumOperands() != 0 &&
544  node == dyn_cast<llvm::MDNode>(node->getOperand(0));
545  };
546  // Helper that verifies the given operand is a string or does not exist.
547  auto verifyDescription = [](const llvm::MDNode *node, unsigned idx) {
548  return idx >= node->getNumOperands() ||
549  isa<llvm::MDString>(node->getOperand(idx));
550  };
551  // Helper that creates an alias scope domain operation.
552  auto createAliasScopeDomainOp = [&](const llvm::MDNode *aliasDomain) {
553  StringAttr description = nullptr;
554  if (aliasDomain->getNumOperands() >= 2)
555  if (auto *operand = dyn_cast<llvm::MDString>(aliasDomain->getOperand(1)))
556  description = builder.getStringAttr(operand->getString());
557  std::string name = llvm::formatv("domain_{0}", aliasScopeMapping.size());
558  return builder.create<AliasScopeDomainMetadataOp>(loc, name, description);
559  };
560 
561  // Collect the alias scopes and domains to translate them.
562  for (const llvm::MDOperand &operand : node->operands()) {
563  if (const auto *scope = dyn_cast<llvm::MDNode>(operand)) {
564  llvm::AliasScopeNode aliasScope(scope);
565  const llvm::MDNode *domain = aliasScope.getDomain();
566 
567  // Verify the scope node points to valid scope metadata which includes
568  // verifying its domain. Perform the verification before looking it up in
569  // the alias scope mapping since it could have been inserted as a domain
570  // node before.
571  if (!verifySelfRef(scope) || !domain || !verifyDescription(scope, 2))
572  return emitError(loc) << "unsupported alias scope node: "
573  << diagMD(scope, llvmModule.get());
574  if (!verifySelfRef(domain) || !verifyDescription(domain, 1))
575  return emitError(loc) << "unsupported alias domain node: "
576  << diagMD(domain, llvmModule.get());
577 
578  if (aliasScopeMapping.count(scope))
579  continue;
580 
581  // Set the insertion point to the end of the global metadata operation.
582  MetadataOp metadataOp = getGlobalMetadataOp();
583  StringAttr metadataOpName =
584  SymbolTable::getSymbolName(getGlobalMetadataOp());
585  OpBuilder::InsertionGuard guard(builder);
586  builder.setInsertionPointToEnd(&metadataOp.getBody().back());
587 
588  // Convert the domain metadata node if it has not been translated before.
589  auto it = aliasScopeMapping.find(aliasScope.getDomain());
590  if (it == aliasScopeMapping.end()) {
591  auto aliasScopeDomainOp = createAliasScopeDomainOp(domain);
592  auto symbolRef = SymbolRefAttr::get(
593  builder.getContext(), metadataOpName,
595  aliasScopeDomainOp.getSymName()));
596  it = aliasScopeMapping.try_emplace(domain, symbolRef).first;
597  }
598 
599  // Convert the scope metadata node if it has not been converted before.
600  StringAttr description = nullptr;
601  if (!aliasScope.getName().empty())
602  description = builder.getStringAttr(aliasScope.getName());
603  std::string name = llvm::formatv("scope_{0}", aliasScopeMapping.size());
604  auto aliasScopeOp = builder.create<AliasScopeMetadataOp>(
605  loc, name, it->getSecond().getLeafReference().getValue(),
606  description);
607  auto symbolRef =
608  SymbolRefAttr::get(builder.getContext(), metadataOpName,
610  aliasScopeOp.getSymName()));
611  aliasScopeMapping.try_emplace(aliasScope.getNode(), symbolRef);
612  }
613  }
614  return success();
615 }
616 
618 ModuleImport::lookupAliasScopeAttrs(const llvm::MDNode *node) const {
619  SmallVector<SymbolRefAttr> aliasScopes;
620  aliasScopes.reserve(node->getNumOperands());
621  for (const llvm::MDOperand &operand : node->operands()) {
622  auto *node = cast<llvm::MDNode>(operand.get());
623  aliasScopes.push_back(aliasScopeMapping.lookup(node));
624  }
625  // Return failure if one of the alias scope lookups failed.
626  if (llvm::is_contained(aliasScopes, nullptr))
627  return failure();
628  return aliasScopes;
629 }
630 
632  OpBuilder::InsertionGuard guard(builder);
633  builder.setInsertionPointToEnd(mlirModule.getBody());
634  for (const llvm::Function &func : llvmModule->functions()) {
635  for (const llvm::Instruction &inst : llvm::instructions(func)) {
636  // Convert access group metadata nodes.
637  if (llvm::MDNode *node =
638  inst.getMetadata(llvm::LLVMContext::MD_access_group))
639  if (failed(processAccessGroupMetadata(node)))
640  return failure();
641 
642  // Convert alias analysis metadata nodes.
643  llvm::AAMDNodes aliasAnalysisNodes = inst.getAAMetadata();
644  if (!aliasAnalysisNodes)
645  continue;
646  if (aliasAnalysisNodes.TBAA)
647  if (failed(processTBAAMetadata(aliasAnalysisNodes.TBAA)))
648  return failure();
649  if (aliasAnalysisNodes.Scope)
650  if (failed(processAliasScopeMetadata(aliasAnalysisNodes.Scope)))
651  return failure();
652  if (aliasAnalysisNodes.NoAlias)
653  if (failed(processAliasScopeMetadata(aliasAnalysisNodes.NoAlias)))
654  return failure();
655  }
656  }
657  return success();
658 }
659 
661  for (llvm::GlobalVariable &globalVar : llvmModule->globals()) {
662  if (globalVar.getName() == getGlobalCtorsVarName() ||
663  globalVar.getName() == getGlobalDtorsVarName()) {
664  if (failed(convertGlobalCtorsAndDtors(&globalVar))) {
665  return emitError(mlirModule.getLoc())
666  << "unhandled global variable: " << diag(globalVar);
667  }
668  continue;
669  }
670  if (failed(convertGlobal(&globalVar))) {
671  return emitError(mlirModule.getLoc())
672  << "unhandled global variable: " << diag(globalVar);
673  }
674  }
675  return success();
676 }
677 
679  for (llvm::Function &func : llvmModule->functions())
680  if (failed(processFunction(&func)))
681  return failure();
682  return success();
683 }
684 
685 void ModuleImport::setNonDebugMetadataAttrs(llvm::Instruction *inst,
686  Operation *op) {
688  inst->getAllMetadataOtherThanDebugLoc(allMetadata);
689  for (auto &[kind, node] : allMetadata) {
690  if (!iface.isConvertibleMetadata(kind))
691  continue;
692  if (failed(iface.setMetadataAttrs(builder, kind, node, op, *this))) {
693  Location loc = debugImporter->translateLoc(inst->getDebugLoc());
694  emitWarning(loc) << "unhandled metadata: "
695  << diagMD(node, llvmModule.get()) << " on "
696  << diag(*inst);
697  }
698  }
699 }
700 
701 void ModuleImport::setFastmathFlagsAttr(llvm::Instruction *inst,
702  Operation *op) const {
703  auto iface = cast<FastmathFlagsInterface>(op);
704 
705  // Even if the imported operation implements the fastmath interface, the
706  // original instruction may not have fastmath flags set. Exit if an
707  // instruction, such as a non floating-point function call, does not have
708  // fastmath flags.
709  if (!isa<llvm::FPMathOperator>(inst))
710  return;
711  llvm::FastMathFlags flags = inst->getFastMathFlags();
712 
713  // Set the fastmath bits flag-by-flag.
714  FastmathFlags value = {};
715  value = bitEnumSet(value, FastmathFlags::nnan, flags.noNaNs());
716  value = bitEnumSet(value, FastmathFlags::ninf, flags.noInfs());
717  value = bitEnumSet(value, FastmathFlags::nsz, flags.noSignedZeros());
718  value = bitEnumSet(value, FastmathFlags::arcp, flags.allowReciprocal());
719  value = bitEnumSet(value, FastmathFlags::contract, flags.allowContract());
720  value = bitEnumSet(value, FastmathFlags::afn, flags.approxFunc());
721  value = bitEnumSet(value, FastmathFlags::reassoc, flags.allowReassoc());
722  FastmathFlagsAttr attr = FastmathFlagsAttr::get(builder.getContext(), value);
723  iface->setAttr(iface.getFastmathAttrName(), attr);
724 }
725 
726 // We only need integers, floats, doubles, and vectors and tensors thereof for
727 // attributes. Scalar and vector types are converted to the standard
728 // equivalents. Array types are converted to ranked tensors; nested array types
729 // are converted to multi-dimensional tensors or vectors, depending on the
730 // innermost type being a scalar or a vector.
731 Type ModuleImport::getStdTypeForAttr(Type type) {
732  if (!type)
733  return nullptr;
734 
735  if (type.isa<IntegerType, FloatType>())
736  return type;
737 
738  // LLVM vectors can only contain scalars.
739  if (LLVM::isCompatibleVectorType(type)) {
740  llvm::ElementCount numElements = LLVM::getVectorNumElements(type);
741  if (numElements.isScalable()) {
742  emitError(UnknownLoc::get(context)) << "scalable vectors not supported";
743  return nullptr;
744  }
745  Type elementType = getStdTypeForAttr(LLVM::getVectorElementType(type));
746  if (!elementType)
747  return nullptr;
748  return VectorType::get(numElements.getKnownMinValue(), elementType);
749  }
750 
751  // LLVM arrays can contain other arrays or vectors.
752  if (auto arrayType = type.dyn_cast<LLVMArrayType>()) {
753  // Recover the nested array shape.
755  shape.push_back(arrayType.getNumElements());
756  while (arrayType.getElementType().isa<LLVMArrayType>()) {
757  arrayType = arrayType.getElementType().cast<LLVMArrayType>();
758  shape.push_back(arrayType.getNumElements());
759  }
760 
761  // If the innermost type is a vector, use the multi-dimensional vector as
762  // attribute type.
763  if (LLVM::isCompatibleVectorType(arrayType.getElementType())) {
764  llvm::ElementCount numElements =
765  LLVM::getVectorNumElements(arrayType.getElementType());
766  if (numElements.isScalable()) {
767  emitError(UnknownLoc::get(context)) << "scalable vectors not supported";
768  return nullptr;
769  }
770  shape.push_back(numElements.getKnownMinValue());
771 
772  Type elementType = getStdTypeForAttr(
773  LLVM::getVectorElementType(arrayType.getElementType()));
774  if (!elementType)
775  return nullptr;
776  return VectorType::get(shape, elementType);
777  }
778 
779  // Otherwise use a tensor.
780  Type elementType = getStdTypeForAttr(arrayType.getElementType());
781  if (!elementType)
782  return nullptr;
783  return RankedTensorType::get(shape, elementType);
784  }
785 
786  return nullptr;
787 }
788 
789 // Get the given constant as an attribute. Not all constants can be represented
790 // as attributes.
791 Attribute ModuleImport::getConstantAsAttr(llvm::Constant *value) {
792  if (auto *ci = dyn_cast<llvm::ConstantInt>(value))
793  return builder.getIntegerAttr(
794  IntegerType::get(context, ci->getType()->getBitWidth()),
795  ci->getValue());
796  if (auto *c = dyn_cast<llvm::ConstantDataArray>(value))
797  if (c->isString())
798  return builder.getStringAttr(c->getAsString());
799  if (auto *c = dyn_cast<llvm::ConstantFP>(value)) {
800  llvm::Type *type = c->getType();
801  FloatType floatTy;
802  if (type->isBFloatTy())
803  floatTy = FloatType::getBF16(context);
804  else
805  floatTy = getDLFloatType(*context, type->getScalarSizeInBits());
806  assert(floatTy && "unsupported floating point type");
807  return builder.getFloatAttr(floatTy, c->getValueAPF());
808  }
809  if (auto *f = dyn_cast<llvm::Function>(value))
810  return SymbolRefAttr::get(builder.getContext(), f->getName());
811 
812  // Convert constant data to a dense elements attribute.
813  if (auto *cd = dyn_cast<llvm::ConstantDataSequential>(value)) {
814  Type type = convertType(cd->getElementType());
815  auto attrType = getStdTypeForAttr(convertType(cd->getType()))
816  .dyn_cast_or_null<ShapedType>();
817  if (!attrType)
818  return nullptr;
819 
820  if (type.isa<IntegerType>()) {
821  SmallVector<APInt, 8> values;
822  values.reserve(cd->getNumElements());
823  for (unsigned i = 0, e = cd->getNumElements(); i < e; ++i)
824  values.push_back(cd->getElementAsAPInt(i));
825  return DenseElementsAttr::get(attrType, values);
826  }
827 
828  if (type.isa<Float32Type, Float64Type>()) {
830  values.reserve(cd->getNumElements());
831  for (unsigned i = 0, e = cd->getNumElements(); i < e; ++i)
832  values.push_back(cd->getElementAsAPFloat(i));
833  return DenseElementsAttr::get(attrType, values);
834  }
835 
836  return nullptr;
837  }
838 
839  // Unpack constant aggregates to create dense elements attribute whenever
840  // possible. Return nullptr (failure) otherwise.
841  if (isa<llvm::ConstantAggregate>(value)) {
842  auto outerType = getStdTypeForAttr(convertType(value->getType()))
843  .dyn_cast_or_null<ShapedType>();
844  if (!outerType)
845  return nullptr;
846 
849 
850  for (unsigned i = 0, e = value->getNumOperands(); i < e; ++i) {
851  auto nested = getConstantAsAttr(value->getAggregateElement(i))
853  if (!nested)
854  return nullptr;
855 
856  values.append(nested.value_begin<Attribute>(),
857  nested.value_end<Attribute>());
858  }
859 
860  return DenseElementsAttr::get(outerType, values);
861  }
862 
863  return nullptr;
864 }
865 
866 LogicalResult ModuleImport::convertGlobal(llvm::GlobalVariable *globalVar) {
867  // Insert the global after the last one or at the start of the module.
868  OpBuilder::InsertionGuard guard(builder);
869  if (!globalInsertionOp)
870  builder.setInsertionPointToStart(mlirModule.getBody());
871  else
872  builder.setInsertionPointAfter(globalInsertionOp);
873 
874  Attribute valueAttr;
875  if (globalVar->hasInitializer())
876  valueAttr = getConstantAsAttr(globalVar->getInitializer());
877  Type type = convertType(globalVar->getValueType());
878 
879  uint64_t alignment = 0;
880  llvm::MaybeAlign maybeAlign = globalVar->getAlign();
881  if (maybeAlign.has_value()) {
882  llvm::Align align = *maybeAlign;
883  alignment = align.value();
884  }
885 
886  GlobalOp globalOp = builder.create<GlobalOp>(
887  mlirModule.getLoc(), type, globalVar->isConstant(),
888  convertLinkageFromLLVM(globalVar->getLinkage()), globalVar->getName(),
889  valueAttr, alignment, /*addr_space=*/globalVar->getAddressSpace(),
890  /*dso_local=*/globalVar->isDSOLocal(),
891  /*thread_local=*/globalVar->isThreadLocal());
892  globalInsertionOp = globalOp;
893 
894  if (globalVar->hasInitializer() && !valueAttr) {
895  clearBlockAndValueMapping();
896  Block *block = builder.createBlock(&globalOp.getInitializerRegion());
897  setConstantInsertionPointToStart(block);
898  FailureOr<Value> initializer =
899  convertConstantExpr(globalVar->getInitializer());
900  if (failed(initializer))
901  return failure();
902  builder.create<ReturnOp>(globalOp.getLoc(), *initializer);
903  }
904  if (globalVar->hasAtLeastLocalUnnamedAddr()) {
905  globalOp.setUnnamedAddr(
906  convertUnnamedAddrFromLLVM(globalVar->getUnnamedAddr()));
907  }
908  if (globalVar->hasSection())
909  globalOp.setSection(globalVar->getSection());
910  globalOp.setVisibility_(
911  convertVisibilityFromLLVM(globalVar->getVisibility()));
912 
913  return success();
914 }
915 
917 ModuleImport::convertGlobalCtorsAndDtors(llvm::GlobalVariable *globalVar) {
918  if (!globalVar->hasInitializer() || !globalVar->hasAppendingLinkage())
919  return failure();
920  auto *initializer =
921  dyn_cast<llvm::ConstantArray>(globalVar->getInitializer());
922  if (!initializer)
923  return failure();
924 
926  SmallVector<int32_t> priorities;
927  for (llvm::Value *operand : initializer->operands()) {
928  auto *aggregate = dyn_cast<llvm::ConstantAggregate>(operand);
929  if (!aggregate || aggregate->getNumOperands() != 3)
930  return failure();
931 
932  auto *priority = dyn_cast<llvm::ConstantInt>(aggregate->getOperand(0));
933  auto *func = dyn_cast<llvm::Function>(aggregate->getOperand(1));
934  auto *data = dyn_cast<llvm::Constant>(aggregate->getOperand(2));
935  if (!priority || !func || !data)
936  return failure();
937 
938  // GlobalCtorsOps and GlobalDtorsOps do not support non-null data fields.
939  if (!data->isNullValue())
940  return failure();
941 
942  funcs.push_back(FlatSymbolRefAttr::get(context, func->getName()));
943  priorities.push_back(priority->getValue().getZExtValue());
944  }
945 
946  OpBuilder::InsertionGuard guard(builder);
947  if (!globalInsertionOp)
948  builder.setInsertionPointToStart(mlirModule.getBody());
949  else
950  builder.setInsertionPointAfter(globalInsertionOp);
951 
952  if (globalVar->getName() == getGlobalCtorsVarName()) {
953  globalInsertionOp = builder.create<LLVM::GlobalCtorsOp>(
954  mlirModule.getLoc(), builder.getArrayAttr(funcs),
955  builder.getI32ArrayAttr(priorities));
956  return success();
957  }
958  globalInsertionOp = builder.create<LLVM::GlobalDtorsOp>(
959  mlirModule.getLoc(), builder.getArrayAttr(funcs),
960  builder.getI32ArrayAttr(priorities));
961  return success();
962 }
963 
965 ModuleImport::getConstantsToConvert(llvm::Constant *constant) {
966  // Return the empty set if the constant has been translated before.
967  if (valueMapping.count(constant))
968  return {};
969 
970  // Traverse the constants in post-order and stop the traversal if a constant
971  // already has a `valueMapping` from an earlier constant translation or if the
972  // constant is traversed a second time.
973  SetVector<llvm::Constant *> orderedSet;
976  workList.insert(constant);
977  while (!workList.empty()) {
978  llvm::Constant *current = workList.back();
979  // Collect all dependencies of the current constant and add them to the
980  // adjacency list if none has been computed before.
981  auto adjacencyIt = adjacencyLists.find(current);
982  if (adjacencyIt == adjacencyLists.end()) {
983  adjacencyIt = adjacencyLists.try_emplace(current).first;
984  // Add all constant operands to the adjacency list and skip any other
985  // values such as basic block addresses.
986  for (llvm::Value *operand : current->operands())
987  if (auto *constDependency = dyn_cast<llvm::Constant>(operand))
988  adjacencyIt->getSecond().push_back(constDependency);
989  // Use the getElementValue method to add the dependencies of zero
990  // initialized aggregate constants since they do not take any operands.
991  if (auto *constAgg = dyn_cast<llvm::ConstantAggregateZero>(current)) {
992  unsigned numElements = constAgg->getElementCount().getFixedValue();
993  for (unsigned i = 0, e = numElements; i != e; ++i)
994  adjacencyIt->getSecond().push_back(constAgg->getElementValue(i));
995  }
996  }
997  // Add the current constant to the `orderedSet` of the traversed nodes if
998  // all its dependencies have been traversed before. Additionally, remove the
999  // constant from the `workList` and continue the traversal.
1000  if (adjacencyIt->getSecond().empty()) {
1001  orderedSet.insert(current);
1002  workList.pop_back();
1003  continue;
1004  }
1005  // Add the next dependency from the adjacency list to the `workList` and
1006  // continue the traversal. Remove the dependency from the adjacency list to
1007  // mark that it has been processed. Only enqueue the dependency if it has no
1008  // `valueMapping` from an earlier translation and if it has not been
1009  // enqueued before.
1010  llvm::Constant *dependency = adjacencyIt->getSecond().pop_back_val();
1011  if (valueMapping.count(dependency) || workList.count(dependency) ||
1012  orderedSet.count(dependency))
1013  continue;
1014  workList.insert(dependency);
1015  }
1016 
1017  return orderedSet;
1018 }
1019 
1020 FailureOr<Value> ModuleImport::convertConstant(llvm::Constant *constant) {
1021  Location loc = mlirModule.getLoc();
1022 
1023  // Convert constants that can be represented as attributes.
1024  if (Attribute attr = getConstantAsAttr(constant)) {
1025  Type type = convertType(constant->getType());
1026  if (auto symbolRef = attr.dyn_cast<FlatSymbolRefAttr>()) {
1027  return builder.create<AddressOfOp>(loc, type, symbolRef.getValue())
1028  .getResult();
1029  }
1030  return builder.create<ConstantOp>(loc, type, attr).getResult();
1031  }
1032 
1033  // Convert null pointer constants.
1034  if (auto *nullPtr = dyn_cast<llvm::ConstantPointerNull>(constant)) {
1035  Type type = convertType(nullPtr->getType());
1036  return builder.create<NullOp>(loc, type).getResult();
1037  }
1038 
1039  // Convert poison.
1040  if (auto *poisonVal = dyn_cast<llvm::PoisonValue>(constant)) {
1041  Type type = convertType(poisonVal->getType());
1042  return builder.create<PoisonOp>(loc, type).getResult();
1043  }
1044 
1045  // Convert undef.
1046  if (auto *undefVal = dyn_cast<llvm::UndefValue>(constant)) {
1047  Type type = convertType(undefVal->getType());
1048  return builder.create<UndefOp>(loc, type).getResult();
1049  }
1050 
1051  // Convert global variable accesses.
1052  if (auto *globalVar = dyn_cast<llvm::GlobalVariable>(constant)) {
1053  Type type = convertType(globalVar->getType());
1054  auto symbolRef = FlatSymbolRefAttr::get(context, globalVar->getName());
1055  return builder.create<AddressOfOp>(loc, type, symbolRef).getResult();
1056  }
1057 
1058  // Convert constant expressions.
1059  if (auto *constExpr = dyn_cast<llvm::ConstantExpr>(constant)) {
1060  // Convert the constant expression to a temporary LLVM instruction and
1061  // translate it using the `processInstruction` method. Delete the
1062  // instruction after the translation and remove it from `valueMapping`,
1063  // since later calls to `getAsInstruction` may return the same address
1064  // resulting in a conflicting `valueMapping` entry.
1065  llvm::Instruction *inst = constExpr->getAsInstruction();
1066  auto guard = llvm::make_scope_exit([&]() {
1067  assert(!noResultOpMapping.contains(inst) &&
1068  "expected constant expression to return a result");
1069  valueMapping.erase(inst);
1070  inst->deleteValue();
1071  });
1072  // Note: `processInstruction` does not call `convertConstant` recursively
1073  // since all constant dependencies have been converted before.
1074  assert(llvm::all_of(inst->operands(), [&](llvm::Value *value) {
1075  return valueMapping.count(value);
1076  }));
1077  if (failed(processInstruction(inst)))
1078  return failure();
1079  return lookupValue(inst);
1080  }
1081 
1082  // Convert aggregate constants.
1083  if (isa<llvm::ConstantAggregate>(constant) ||
1084  isa<llvm::ConstantAggregateZero>(constant)) {
1085  // Lookup the aggregate elements that have been converted before.
1086  SmallVector<Value> elementValues;
1087  if (auto *constAgg = dyn_cast<llvm::ConstantAggregate>(constant)) {
1088  elementValues.reserve(constAgg->getNumOperands());
1089  for (llvm::Value *operand : constAgg->operands())
1090  elementValues.push_back(lookupValue(operand));
1091  }
1092  if (auto *constAgg = dyn_cast<llvm::ConstantAggregateZero>(constant)) {
1093  unsigned numElements = constAgg->getElementCount().getFixedValue();
1094  elementValues.reserve(numElements);
1095  for (unsigned i = 0, e = numElements; i != e; ++i)
1096  elementValues.push_back(lookupValue(constAgg->getElementValue(i)));
1097  }
1098  assert(llvm::count(elementValues, nullptr) == 0 &&
1099  "expected all elements have been converted before");
1100 
1101  // Generate an UndefOp as root value and insert the aggregate elements.
1102  Type rootType = convertType(constant->getType());
1103  bool isArrayOrStruct = rootType.isa<LLVMArrayType, LLVMStructType>();
1104  assert((isArrayOrStruct || LLVM::isCompatibleVectorType(rootType)) &&
1105  "unrecognized aggregate type");
1106  Value root = builder.create<UndefOp>(loc, rootType);
1107  for (const auto &it : llvm::enumerate(elementValues)) {
1108  if (isArrayOrStruct) {
1109  root = builder.create<InsertValueOp>(loc, root, it.value(), it.index());
1110  } else {
1111  Attribute indexAttr = builder.getI32IntegerAttr(it.index());
1112  Value indexValue =
1113  builder.create<ConstantOp>(loc, builder.getI32Type(), indexAttr);
1114  root = builder.create<InsertElementOp>(loc, rootType, root, it.value(),
1115  indexValue);
1116  }
1117  }
1118  return root;
1119  }
1120 
1121  if (isa<llvm::BlockAddress>(constant)) {
1122  return emitError(loc)
1123  << "blockaddress is not implemented in the LLVM dialect";
1124  }
1125 
1126  return emitError(loc) << "unhandled constant: " << diag(*constant);
1127 }
1128 
1129 FailureOr<Value> ModuleImport::convertConstantExpr(llvm::Constant *constant) {
1130  assert(constantInsertionBlock &&
1131  "expected the constant insertion block to be non-null");
1132 
1133  // Insert the constant after the last one or at the start or the entry block.
1134  OpBuilder::InsertionGuard guard(builder);
1135  if (!constantInsertionOp)
1136  builder.setInsertionPointToStart(constantInsertionBlock);
1137  else
1138  builder.setInsertionPointAfter(constantInsertionOp);
1139 
1140  // Convert all constants of the expression and add them to `valueMapping`.
1141  SetVector<llvm::Constant *> constantsToConvert =
1142  getConstantsToConvert(constant);
1143  for (llvm::Constant *constantToConvert : constantsToConvert) {
1144  FailureOr<Value> converted = convertConstant(constantToConvert);
1145  if (failed(converted))
1146  return failure();
1147  mapValue(constantToConvert, *converted);
1148  }
1149 
1150  // Update the constant insertion point and return the converted constant.
1151  Value result = lookupValue(constant);
1152  constantInsertionOp = result.getDefiningOp();
1153  return result;
1154 }
1155 
1157  assert(!isa<llvm::MetadataAsValue>(value) &&
1158  "expected value to not be metadata");
1159 
1160  // Return the mapped value if it has been converted before.
1161  if (valueMapping.count(value))
1162  return lookupValue(value);
1163 
1164  // Convert constants such as immediate values that have no mapping yet.
1165  if (auto *constant = dyn_cast<llvm::Constant>(value))
1166  return convertConstantExpr(constant);
1167 
1168  Location loc = mlirModule.getLoc();
1169  if (auto *inst = dyn_cast<llvm::Instruction>(value))
1170  loc = translateLoc(inst->getDebugLoc());
1171  return emitError(loc) << "unhandled value: " << diag(*value);
1172 }
1173 
1175  // A value may be wrapped as metadata, for example, when passed to a debug
1176  // intrinsic. Unwrap these values before the conversion.
1177  auto *nodeAsVal = dyn_cast<llvm::MetadataAsValue>(value);
1178  if (!nodeAsVal)
1179  return failure();
1180  auto *node = dyn_cast<llvm::ValueAsMetadata>(nodeAsVal->getMetadata());
1181  if (!node)
1182  return failure();
1183  value = node->getValue();
1184 
1185  // Return the mapped value if it has been converted before.
1186  if (valueMapping.count(value))
1187  return lookupValue(value);
1188 
1189  // Convert constants such as immediate values that have no mapping yet.
1190  if (auto *constant = dyn_cast<llvm::Constant>(value))
1191  return convertConstantExpr(constant);
1192  return failure();
1193 }
1194 
1197  SmallVector<Value> remapped;
1198  remapped.reserve(values.size());
1199  for (llvm::Value *value : values) {
1200  FailureOr<Value> converted = convertValue(value);
1201  if (failed(converted))
1202  return failure();
1203  remapped.push_back(*converted);
1204  }
1205  return remapped;
1206 }
1207 
1208 IntegerAttr ModuleImport::matchIntegerAttr(llvm::Value *value) {
1209  IntegerAttr integerAttr;
1210  FailureOr<Value> converted = convertValue(value);
1211  bool success = succeeded(converted) &&
1212  matchPattern(*converted, m_Constant(&integerAttr));
1213  assert(success && "expected a constant value");
1214  (void)success;
1215  return integerAttr;
1216 }
1217 
1218 DILocalVariableAttr ModuleImport::matchLocalVariableAttr(llvm::Value *value) {
1219  auto *nodeAsVal = cast<llvm::MetadataAsValue>(value);
1220  auto *node = cast<llvm::DILocalVariable>(nodeAsVal->getMetadata());
1221  return debugImporter->translate(node);
1222 }
1223 
1226  auto *nodeAsVal = cast<llvm::MetadataAsValue>(value);
1227  auto *node = cast<llvm::MDNode>(nodeAsVal->getMetadata());
1228  return lookupAliasScopeAttrs(node);
1229 }
1230 
1231 Location ModuleImport::translateLoc(llvm::DILocation *loc) {
1232  return debugImporter->translateLoc(loc);
1233 }
1234 
1236 ModuleImport::convertBranchArgs(llvm::Instruction *branch,
1237  llvm::BasicBlock *target,
1238  SmallVectorImpl<Value> &blockArguments) {
1239  for (auto inst = target->begin(); isa<llvm::PHINode>(inst); ++inst) {
1240  auto *phiInst = cast<llvm::PHINode>(&*inst);
1241  llvm::Value *value = phiInst->getIncomingValueForBlock(branch->getParent());
1242  FailureOr<Value> converted = convertValue(value);
1243  if (failed(converted))
1244  return failure();
1245  blockArguments.push_back(*converted);
1246  }
1247  return success();
1248 }
1249 
1251 ModuleImport::convertCallTypeAndOperands(llvm::CallBase *callInst,
1252  SmallVectorImpl<Type> &types,
1253  SmallVectorImpl<Value> &operands) {
1254  if (!callInst->getType()->isVoidTy())
1255  types.push_back(convertType(callInst->getType()));
1256 
1257  if (!callInst->getCalledFunction()) {
1258  FailureOr<Value> called = convertValue(callInst->getCalledOperand());
1259  if (failed(called))
1260  return failure();
1261  operands.push_back(*called);
1262  }
1263  SmallVector<llvm::Value *> args(callInst->args());
1264  FailureOr<SmallVector<Value>> arguments = convertValues(args);
1265  if (failed(arguments))
1266  return failure();
1267  llvm::append_range(operands, *arguments);
1268  return success();
1269 }
1270 
1271 LogicalResult ModuleImport::convertIntrinsic(llvm::CallInst *inst) {
1272  if (succeeded(iface.convertIntrinsic(builder, inst, *this)))
1273  return success();
1274 
1275  Location loc = translateLoc(inst->getDebugLoc());
1276  return emitError(loc) << "unhandled intrinsic: " << diag(*inst);
1277 }
1278 
1279 LogicalResult ModuleImport::convertInstruction(llvm::Instruction *inst) {
1280  // Convert all instructions that do not provide an MLIR builder.
1281  Location loc = translateLoc(inst->getDebugLoc());
1282  if (inst->getOpcode() == llvm::Instruction::Br) {
1283  auto *brInst = cast<llvm::BranchInst>(inst);
1284 
1285  SmallVector<Block *> succBlocks;
1286  SmallVector<SmallVector<Value>> succBlockArgs;
1287  for (auto i : llvm::seq<unsigned>(0, brInst->getNumSuccessors())) {
1288  llvm::BasicBlock *succ = brInst->getSuccessor(i);
1289  SmallVector<Value> blockArgs;
1290  if (failed(convertBranchArgs(brInst, succ, blockArgs)))
1291  return failure();
1292  succBlocks.push_back(lookupBlock(succ));
1293  succBlockArgs.push_back(blockArgs);
1294  }
1295 
1296  if (!brInst->isConditional()) {
1297  auto brOp = builder.create<LLVM::BrOp>(loc, succBlockArgs.front(),
1298  succBlocks.front());
1299  mapNoResultOp(inst, brOp);
1300  return success();
1301  }
1302  FailureOr<Value> condition = convertValue(brInst->getCondition());
1303  if (failed(condition))
1304  return failure();
1305  auto condBrOp = builder.create<LLVM::CondBrOp>(
1306  loc, *condition, succBlocks.front(), succBlockArgs.front(),
1307  succBlocks.back(), succBlockArgs.back());
1308  mapNoResultOp(inst, condBrOp);
1309  return success();
1310  }
1311  if (inst->getOpcode() == llvm::Instruction::Switch) {
1312  auto *swInst = cast<llvm::SwitchInst>(inst);
1313  // Process the condition value.
1314  FailureOr<Value> condition = convertValue(swInst->getCondition());
1315  if (failed(condition))
1316  return failure();
1317  SmallVector<Value> defaultBlockArgs;
1318  // Process the default case.
1319  llvm::BasicBlock *defaultBB = swInst->getDefaultDest();
1320  if (failed(convertBranchArgs(swInst, defaultBB, defaultBlockArgs)))
1321  return failure();
1322 
1323  // Process the cases.
1324  unsigned numCases = swInst->getNumCases();
1325  SmallVector<SmallVector<Value>> caseOperands(numCases);
1326  SmallVector<ValueRange> caseOperandRefs(numCases);
1327  SmallVector<int32_t> caseValues(numCases);
1328  SmallVector<Block *> caseBlocks(numCases);
1329  for (const auto &it : llvm::enumerate(swInst->cases())) {
1330  const llvm::SwitchInst::CaseHandle &caseHandle = it.value();
1331  llvm::BasicBlock *succBB = caseHandle.getCaseSuccessor();
1332  if (failed(convertBranchArgs(swInst, succBB, caseOperands[it.index()])))
1333  return failure();
1334  caseOperandRefs[it.index()] = caseOperands[it.index()];
1335  caseValues[it.index()] = caseHandle.getCaseValue()->getSExtValue();
1336  caseBlocks[it.index()] = lookupBlock(succBB);
1337  }
1338 
1339  auto switchOp = builder.create<SwitchOp>(
1340  loc, *condition, lookupBlock(defaultBB), defaultBlockArgs, caseValues,
1341  caseBlocks, caseOperandRefs);
1342  mapNoResultOp(inst, switchOp);
1343  return success();
1344  }
1345  if (inst->getOpcode() == llvm::Instruction::PHI) {
1346  Type type = convertType(inst->getType());
1347  mapValue(inst, builder.getInsertionBlock()->addArgument(
1348  type, translateLoc(inst->getDebugLoc())));
1349  return success();
1350  }
1351  if (inst->getOpcode() == llvm::Instruction::Call) {
1352  auto *callInst = cast<llvm::CallInst>(inst);
1353 
1354  SmallVector<Type> types;
1355  SmallVector<Value> operands;
1356  if (failed(convertCallTypeAndOperands(callInst, types, operands)))
1357  return failure();
1358 
1359  CallOp callOp;
1360  if (llvm::Function *callee = callInst->getCalledFunction()) {
1361  callOp = builder.create<CallOp>(
1362  loc, types, SymbolRefAttr::get(context, callee->getName()), operands);
1363  } else {
1364  callOp = builder.create<CallOp>(loc, types, operands);
1365  }
1366  setFastmathFlagsAttr(inst, callOp);
1367  if (!callInst->getType()->isVoidTy())
1368  mapValue(inst, callOp.getResult());
1369  else
1370  mapNoResultOp(inst, callOp);
1371  return success();
1372  }
1373  if (inst->getOpcode() == llvm::Instruction::LandingPad) {
1374  auto *lpInst = cast<llvm::LandingPadInst>(inst);
1375 
1376  SmallVector<Value> operands;
1377  operands.reserve(lpInst->getNumClauses());
1378  for (auto i : llvm::seq<unsigned>(0, lpInst->getNumClauses())) {
1379  FailureOr<Value> operand = convertConstantExpr(lpInst->getClause(i));
1380  if (failed(operand))
1381  return failure();
1382  operands.push_back(*operand);
1383  }
1384 
1385  Type type = convertType(lpInst->getType());
1386  auto lpOp =
1387  builder.create<LandingpadOp>(loc, type, lpInst->isCleanup(), operands);
1388  mapValue(inst, lpOp);
1389  return success();
1390  }
1391  if (inst->getOpcode() == llvm::Instruction::Invoke) {
1392  auto *invokeInst = cast<llvm::InvokeInst>(inst);
1393 
1394  SmallVector<Type> types;
1395  SmallVector<Value> operands;
1396  if (failed(convertCallTypeAndOperands(invokeInst, types, operands)))
1397  return failure();
1398 
1399  SmallVector<Value> normalArgs, unwindArgs;
1400  (void)convertBranchArgs(invokeInst, invokeInst->getNormalDest(),
1401  normalArgs);
1402  (void)convertBranchArgs(invokeInst, invokeInst->getUnwindDest(),
1403  unwindArgs);
1404 
1405  InvokeOp invokeOp;
1406  if (llvm::Function *callee = invokeInst->getCalledFunction()) {
1407  invokeOp = builder.create<InvokeOp>(
1408  loc, types,
1409  SymbolRefAttr::get(builder.getContext(), callee->getName()), operands,
1410  lookupBlock(invokeInst->getNormalDest()), normalArgs,
1411  lookupBlock(invokeInst->getUnwindDest()), unwindArgs);
1412  } else {
1413  invokeOp = builder.create<InvokeOp>(
1414  loc, types, operands, lookupBlock(invokeInst->getNormalDest()),
1415  normalArgs, lookupBlock(invokeInst->getUnwindDest()), unwindArgs);
1416  }
1417  if (!invokeInst->getType()->isVoidTy())
1418  mapValue(inst, invokeOp.getResults().front());
1419  else
1420  mapNoResultOp(inst, invokeOp);
1421  return success();
1422  }
1423  if (inst->getOpcode() == llvm::Instruction::GetElementPtr) {
1424  auto *gepInst = cast<llvm::GetElementPtrInst>(inst);
1425  Type sourceElementType = convertType(gepInst->getSourceElementType());
1426  FailureOr<Value> basePtr = convertValue(gepInst->getOperand(0));
1427  if (failed(basePtr))
1428  return failure();
1429 
1430  // Treat every indices as dynamic since GEPOp::build will refine those
1431  // indices into static attributes later. One small downside of this
1432  // approach is that many unused `llvm.mlir.constant` would be emitted
1433  // at first place.
1434  SmallVector<GEPArg> indices;
1435  for (llvm::Value *operand : llvm::drop_begin(gepInst->operand_values())) {
1436  FailureOr<Value> index = convertValue(operand);
1437  if (failed(index))
1438  return failure();
1439  indices.push_back(*index);
1440  }
1441 
1442  Type type = convertType(inst->getType());
1443  auto gepOp = builder.create<GEPOp>(loc, type, sourceElementType, *basePtr,
1444  indices, gepInst->isInBounds());
1445  mapValue(inst, gepOp);
1446  return success();
1447  }
1448 
1449  // Convert all instructions that have an mlirBuilder.
1450  if (succeeded(convertInstructionImpl(builder, inst, *this)))
1451  return success();
1452 
1453  return emitError(loc) << "unhandled instruction: " << diag(*inst);
1454 }
1455 
1456 LogicalResult ModuleImport::processInstruction(llvm::Instruction *inst) {
1457  // FIXME: Support uses of SubtargetData.
1458  // FIXME: Add support for call / operand attributes.
1459  // FIXME: Add support for the indirectbr, cleanupret, catchret, catchswitch,
1460  // callbr, vaarg, landingpad, catchpad, cleanuppad instructions.
1461 
1462  // Convert LLVM intrinsics calls to MLIR intrinsics.
1463  if (auto *callInst = dyn_cast<llvm::CallInst>(inst)) {
1464  llvm::Function *callee = callInst->getCalledFunction();
1465  if (callee && callee->isIntrinsic())
1466  return convertIntrinsic(callInst);
1467  }
1468 
1469  // Convert all remaining LLVM instructions to MLIR operations.
1470  return convertInstruction(inst);
1471 }
1472 
1473 FlatSymbolRefAttr ModuleImport::getPersonalityAsAttr(llvm::Function *f) {
1474  if (!f->hasPersonalityFn())
1475  return nullptr;
1476 
1477  llvm::Constant *pf = f->getPersonalityFn();
1478 
1479  // If it directly has a name, we can use it.
1480  if (pf->hasName())
1481  return SymbolRefAttr::get(builder.getContext(), pf->getName());
1482 
1483  // If it doesn't have a name, currently, only function pointers that are
1484  // bitcast to i8* are parsed.
1485  if (auto *ce = dyn_cast<llvm::ConstantExpr>(pf)) {
1486  if (ce->getOpcode() == llvm::Instruction::BitCast &&
1487  ce->getType() == llvm::Type::getInt8PtrTy(f->getContext())) {
1488  if (auto *func = dyn_cast<llvm::Function>(ce->getOperand(0)))
1489  return SymbolRefAttr::get(builder.getContext(), func->getName());
1490  }
1491  }
1492  return FlatSymbolRefAttr();
1493 }
1494 
1495 static void processMemoryEffects(llvm::Function *func, LLVMFuncOp funcOp) {
1496  llvm::MemoryEffects memEffects = func->getMemoryEffects();
1497 
1498  auto othermem = convertModRefInfoFromLLVM(
1499  memEffects.getModRef(llvm::MemoryEffects::Location::Other));
1500  auto argMem = convertModRefInfoFromLLVM(
1501  memEffects.getModRef(llvm::MemoryEffects::Location::ArgMem));
1502  auto inaccessibleMem = convertModRefInfoFromLLVM(
1503  memEffects.getModRef(llvm::MemoryEffects::Location::InaccessibleMem));
1504  auto memAttr = MemoryEffectsAttr::get(funcOp.getContext(), othermem, argMem,
1505  inaccessibleMem);
1506  // Only set the attr when it does not match the default value.
1507  if (memAttr.isReadWrite())
1508  return;
1509  funcOp.setMemoryAttr(memAttr);
1510 }
1511 
1512 static void processPassthroughAttrs(llvm::Function *func, LLVMFuncOp funcOp) {
1513  MLIRContext *context = funcOp.getContext();
1514  SmallVector<Attribute> passthroughs;
1515  llvm::AttributeSet funcAttrs = func->getAttributes().getAttributes(
1516  llvm::AttributeList::AttrIndex::FunctionIndex);
1517  for (llvm::Attribute attr : funcAttrs) {
1518  // Skip the memory attribute since the LLVMFuncOp has an explicit memory
1519  // attribute.
1520  if (attr.hasAttribute(llvm::Attribute::Memory))
1521  continue;
1522 
1523  // Skip invalid type attributes.
1524  if (attr.isTypeAttribute()) {
1525  emitWarning(funcOp.getLoc(),
1526  "type attributes on a function are invalid, skipping it");
1527  continue;
1528  }
1529 
1530  StringRef attrName;
1531  if (attr.isStringAttribute())
1532  attrName = attr.getKindAsString();
1533  else
1534  attrName = llvm::Attribute::getNameFromAttrKind(attr.getKindAsEnum());
1535  auto keyAttr = StringAttr::get(context, attrName);
1536 
1537  if (attr.isStringAttribute()) {
1538  StringRef val = attr.getValueAsString();
1539  if (val.empty()) {
1540  passthroughs.push_back(keyAttr);
1541  continue;
1542  }
1543  passthroughs.push_back(
1544  ArrayAttr::get(context, {keyAttr, StringAttr::get(context, val)}));
1545  continue;
1546  }
1547  if (attr.isIntAttribute()) {
1548  auto val = std::to_string(attr.getValueAsInt());
1549  passthroughs.push_back(
1550  ArrayAttr::get(context, {keyAttr, StringAttr::get(context, val)}));
1551  continue;
1552  }
1553  if (attr.isEnumAttribute()) {
1554  passthroughs.push_back(keyAttr);
1555  continue;
1556  }
1557 
1558  llvm_unreachable("unexpected attribute kind");
1559  }
1560 
1561  if (!passthroughs.empty())
1562  funcOp.setPassthroughAttr(ArrayAttr::get(context, passthroughs));
1563 }
1564 
1566  LLVMFuncOp funcOp) {
1567  processMemoryEffects(func, funcOp);
1568  processPassthroughAttrs(func, funcOp);
1569 }
1570 
1571 DictionaryAttr
1572 ModuleImport::convertParameterAttribute(llvm::AttributeSet llvmParamAttrs,
1573  OpBuilder &builder) {
1574  SmallVector<NamedAttribute> paramAttrs;
1575  for (auto [llvmKind, mlirName] : getAttrKindToNameMapping()) {
1576  auto llvmAttr = llvmParamAttrs.getAttribute(llvmKind);
1577  // Skip attributes that are not attached.
1578  if (!llvmAttr.isValid())
1579  continue;
1580  Attribute mlirAttr;
1581  if (llvmAttr.isTypeAttribute())
1582  mlirAttr = TypeAttr::get(convertType(llvmAttr.getValueAsType()));
1583  else if (llvmAttr.isIntAttribute())
1584  mlirAttr = builder.getI64IntegerAttr(llvmAttr.getValueAsInt());
1585  else if (llvmAttr.isEnumAttribute())
1586  mlirAttr = builder.getUnitAttr();
1587  else
1588  llvm_unreachable("unexpected parameter attribute kind");
1589  paramAttrs.push_back(builder.getNamedAttr(mlirName, mlirAttr));
1590  }
1591 
1592  return builder.getDictionaryAttr(paramAttrs);
1593 }
1594 
1595 void ModuleImport::convertParameterAttributes(llvm::Function *func,
1596  LLVMFuncOp funcOp,
1597  OpBuilder &builder) {
1598  auto llvmAttrs = func->getAttributes();
1599  for (size_t i = 0, e = funcOp.getNumArguments(); i < e; ++i) {
1600  llvm::AttributeSet llvmArgAttrs = llvmAttrs.getParamAttrs(i);
1601  funcOp.setArgAttrs(i, convertParameterAttribute(llvmArgAttrs, builder));
1602  }
1603  // Convert the result attributes and attach them wrapped in an ArrayAttribute
1604  // to the funcOp.
1605  llvm::AttributeSet llvmResAttr = llvmAttrs.getRetAttrs();
1606  funcOp.setResAttrsAttr(
1607  builder.getArrayAttr(convertParameterAttribute(llvmResAttr, builder)));
1608 }
1609 
1611  clearBlockAndValueMapping();
1612 
1613  auto functionType =
1614  convertType(func->getFunctionType()).dyn_cast<LLVMFunctionType>();
1615  if (func->isIntrinsic() &&
1616  iface.isConvertibleIntrinsic(func->getIntrinsicID()))
1617  return success();
1618 
1619  bool dsoLocal = func->hasLocalLinkage();
1620  CConv cconv = convertCConvFromLLVM(func->getCallingConv());
1621 
1622  // Insert the function at the end of the module.
1623  OpBuilder::InsertionGuard guard(builder);
1624  builder.setInsertionPoint(mlirModule.getBody(), mlirModule.getBody()->end());
1625 
1626  LLVMFuncOp funcOp = builder.create<LLVMFuncOp>(
1627  mlirModule.getLoc(), func->getName(), functionType,
1628  convertLinkageFromLLVM(func->getLinkage()), dsoLocal, cconv);
1629 
1630  // Set the function debug information if available.
1631  debugImporter->translate(func, funcOp);
1632 
1633  convertParameterAttributes(func, funcOp, builder);
1634 
1635  if (FlatSymbolRefAttr personality = getPersonalityAsAttr(func))
1636  funcOp.setPersonalityAttr(personality);
1637  else if (func->hasPersonalityFn())
1638  emitWarning(funcOp.getLoc(), "could not deduce personality, skipping it");
1639 
1640  if (func->hasGC())
1641  funcOp.setGarbageCollector(StringRef(func->getGC()));
1642 
1643  funcOp.setVisibility_(convertVisibilityFromLLVM(func->getVisibility()));
1644 
1645  // Handle Function attributes.
1646  processFunctionAttributes(func, funcOp);
1647 
1648  // Convert non-debug metadata by using the dialect interface.
1650  func->getAllMetadata(allMetadata);
1651  for (auto &[kind, node] : allMetadata) {
1652  if (!iface.isConvertibleMetadata(kind))
1653  continue;
1654  if (failed(iface.setMetadataAttrs(builder, kind, node, funcOp, *this))) {
1655  emitWarning(funcOp.getLoc())
1656  << "unhandled function metadata: " << diagMD(node, llvmModule.get())
1657  << " on " << diag(*func);
1658  }
1659  }
1660 
1661  if (func->isDeclaration())
1662  return success();
1663 
1664  // Eagerly create all blocks.
1665  for (llvm::BasicBlock &bb : *func) {
1666  Block *block =
1667  builder.createBlock(&funcOp.getBody(), funcOp.getBody().end());
1668  mapBlock(&bb, block);
1669  }
1670 
1671  // Add function arguments to the entry block.
1672  for (const auto &it : llvm::enumerate(func->args())) {
1673  BlockArgument blockArg = funcOp.getFunctionBody().addArgument(
1674  functionType.getParamType(it.index()), funcOp.getLoc());
1675  mapValue(&it.value(), blockArg);
1676  }
1677 
1678  // Process the blocks in topological order. The ordered traversal ensures
1679  // operands defined in a dominating block have a valid mapping to an MLIR
1680  // value once a block is translated.
1682  setConstantInsertionPointToStart(lookupBlock(blocks.front()));
1683  for (llvm::BasicBlock *bb : blocks) {
1684  if (failed(processBasicBlock(bb, lookupBlock(bb))))
1685  return failure();
1686  }
1687 
1688  return success();
1689 }
1690 
1691 LogicalResult ModuleImport::processBasicBlock(llvm::BasicBlock *bb,
1692  Block *block) {
1693  builder.setInsertionPointToStart(block);
1694  for (llvm::Instruction &inst : *bb) {
1695  if (failed(processInstruction(&inst)))
1696  return failure();
1697 
1698  // Set the non-debug metadata attributes on the imported operation and emit
1699  // a warning if an instruction other than a phi instruction is dropped
1700  // during the import.
1701  if (Operation *op = lookupOperation(&inst)) {
1702  setNonDebugMetadataAttrs(&inst, op);
1703  } else if (inst.getOpcode() != llvm::Instruction::PHI) {
1704  Location loc = debugImporter->translateLoc(inst.getDebugLoc());
1705  emitWarning(loc) << "dropped instruction: " << diag(inst);
1706  }
1707  }
1708  return success();
1709 }
1710 
1712 ModuleImport::lookupAccessGroupAttrs(const llvm::MDNode *node) const {
1713  return loopAnnotationImporter->lookupAccessGroupAttrs(node);
1714 }
1715 
1716 LoopAnnotationAttr
1718  Location loc) const {
1719  return loopAnnotationImporter->translateLoopAnnotation(node, loc);
1720 }
1721 
1723 mlir::translateLLVMIRToModule(std::unique_ptr<llvm::Module> llvmModule,
1724  MLIRContext *context) {
1725  // Preload all registered dialects to allow the import to iterate the
1726  // registered LLVMImportDialectInterface implementations and query the
1727  // supported LLVM IR constructs before starting the translation. Assumes the
1728  // LLVM and DLTI dialects that convert the core LLVM IR constructs have been
1729  // registered before.
1730  assert(llvm::is_contained(context->getAvailableDialects(),
1731  LLVMDialect::getDialectNamespace()));
1732  assert(llvm::is_contained(context->getAvailableDialects(),
1733  DLTIDialect::getDialectNamespace()));
1734  context->loadAllAvailableDialects();
1735 
1736  OwningOpRef<ModuleOp> module(ModuleOp::create(FileLineColLoc::get(
1737  StringAttr::get(context, llvmModule->getSourceFileName()), /*line=*/0,
1738  /*column=*/0)));
1739 
1740  DataLayoutSpecInterface dlSpec =
1741  translateDataLayout(llvmModule->getDataLayout(), context);
1742  if (!dlSpec) {
1743  emitError(UnknownLoc::get(context), "can't translate data layout");
1744  return {};
1745  }
1746  module.get()->setAttr(DLTIDialect::kDataLayoutAttrName, dlSpec);
1747 
1748  ModuleImport moduleImport(module.get(), std::move(llvmModule));
1749  if (failed(moduleImport.initializeImportInterface()))
1750  return {};
1751  if (failed(moduleImport.convertMetadata()))
1752  return {};
1753  if (failed(moduleImport.convertGlobals()))
1754  return {};
1755  if (failed(moduleImport.convertFunctions()))
1756  return {};
1757 
1758  return module;
1759 }
static SmallVector< int64_t > getPositionFromIndices(ArrayRef< unsigned > indices)
Converts an array of unsigned indices to a signed integer position array.
static StringRef getLLVMSyncScope(llvm::Instruction *inst)
Converts the sync scope identifier of inst to the string representation necessary to build an atomic ...
static std::string diag(const llvm::Value &value)
static void processPassthroughAttrs(llvm::Function *func, LLVMFuncOp funcOp)
static void processMemoryEffects(llvm::Function *func, LLVMFuncOp funcOp)
static FloatType getDLFloatType(MLIRContext &ctx, int32_t bitwidth)
Returns a supported MLIR floating point type of the given bit width or null if the bit width is not s...
static constexpr StringRef getGlobalMetadataOpName()
Returns the symbol name for the module-level metadata operation.
static constexpr StringRef getGlobalDtorsVarName()
Returns the name of the global_dtors global variables.
static DenseIntElementsAttr parseDataLayoutAlignment(MLIRContext &ctx, StringRef spec)
Creates an attribute containing ABI and preferred alignment numbers parsed a string.
static LogicalResult convertInstructionImpl(OpBuilder &odsBuilder, llvm::Instruction *inst, ModuleImport &moduleImport)
Converts the LLVM instructions that have a generated MLIR builder.
static constexpr StringRef getGlobalCtorsVarName()
Returns the name of the global_ctors global variables.
static std::string diagMD(const llvm::Metadata *node, const llvm::Module *module)
static SetVector< llvm::BasicBlock * > getTopologicallySortedBlocks(llvm::Function *func)
Get a topologically sorted list of blocks for the given function.
static void contract(RootOrderingGraph &graph, ArrayRef< Value > cycle, const DenseMap< Value, unsigned > &parentDepths, DenseMap< Value, Value > &actualSource, DenseMap< Value, Value > &actualTarget)
Contracts the specified cycle in the given graph in-place.
Attributes are known-constant values of operations.
Definition: Attributes.h:25
U dyn_cast_or_null() const
Definition: Attributes.h:171
This class represents an argument of a Block.
Definition: Value.h:304
Block represents an ordered list of Operations.
Definition: Block.h:30
BlockArgument addArgument(Type type, Location loc)
Add one value to the argument list.
Definition: Block.cpp:141
This class is a general helper class for creating context-global objects like types,...
Definition: Builders.h:50
UnitAttr getUnitAttr()
Definition: Builders.cpp:111
IntegerAttr getI32IntegerAttr(int32_t value)
Definition: Builders.cpp:202
IntegerAttr getIntegerAttr(Type type, int64_t value)
Definition: Builders.cpp:224
ArrayAttr getI32ArrayAttr(ArrayRef< int32_t > values)
Definition: Builders.cpp:269
FloatAttr getFloatAttr(Type type, double value)
Definition: Builders.cpp:247
IntegerType getI32Type()
Definition: Builders.cpp:80
IntegerAttr getI64IntegerAttr(int64_t value)
Definition: Builders.cpp:125
StringAttr getStringAttr(const Twine &bytes)
Definition: Builders.cpp:255
MLIRContext * getContext() const
Definition: Builders.h:55
ArrayAttr getArrayAttr(ArrayRef< Attribute > value)
Definition: Builders.cpp:259
DictionaryAttr getDictionaryAttr(ArrayRef< NamedAttribute > value)
Definition: Builders.cpp:117
NamedAttribute getNamedAttr(StringRef name, Attribute val)
Definition: Builders.cpp:107
static DataLayoutEntryAttr get(StringAttr key, Attribute value)
Returns the entry with the given key and value.
Definition: DLTI.cpp:52
static DataLayoutSpecAttr get(MLIRContext *ctx, ArrayRef< DataLayoutEntryInterface > entries)
Returns the specification containing the given list of keys.
Definition: DLTI.cpp:135
An attribute that represents a reference to a dense vector or tensor object.
static DenseElementsAttr get(ShapedType type, ArrayRef< Attribute > values)
Constructs a dense elements attribute from an array of element values.
An attribute that represents a reference to a dense integer vector or tensor object.
static DenseIntElementsAttr get(const ShapedType &type, Arg &&arg)
Get an instance of a DenseIntElementsAttr with the given arguments.
This class provides support for representing a failure result, or a valid value of type T.
Definition: LogicalResult.h:78
A symbol reference with a reference path containing a single element.
static FlatSymbolRefAttr get(StringAttr value)
Construct a symbol reference for the given value name.
static FloatType getF64(MLIRContext *ctx)
Definition: BuiltinTypes.h:418
static FloatType getF80(MLIRContext *ctx)
Definition: BuiltinTypes.h:422
static FloatType getF16(MLIRContext *ctx)
Definition: BuiltinTypes.h:410
static FloatType getBF16(MLIRContext *ctx)
Definition: BuiltinTypes.h:406
static FloatType getF128(MLIRContext *ctx)
Definition: BuiltinTypes.h:426
static FloatType getF32(MLIRContext *ctx)
Definition: BuiltinTypes.h:414
LogicalResult convertIntrinsic(OpBuilder &builder, llvm::CallInst *inst, LLVM::ModuleImport &moduleImport) const
Converts the LLVM intrinsic to an MLIR operation if a conversion exists.
LogicalResult setMetadataAttrs(OpBuilder &builder, unsigned kind, llvm::MDNode *node, Operation *op, LLVM::ModuleImport &moduleImport) const
Attaches the given LLVM metadata to the imported operation if a conversion to one or more MLIR dialec...
bool isConvertibleMetadata(unsigned kind)
Returns true if the given LLVM IR metadata is convertible to an MLIR attribute.
bool isConvertibleIntrinsic(llvm::Intrinsic::ID id)
Returns true if the given LLVM IR intrinsic is convertible to an MLIR operation.
LLVM dialect structure type representing a collection of different-typed elements manipulated togethe...
Definition: LLVMTypes.h:106
Module import implementation class that provides methods to import globals and functions from an LLVM...
Definition: ModuleImport.h:45
Location translateLoc(llvm::DILocation *loc)
Translates the debug location.
LogicalResult convertFunctions()
Converts all functions of the LLVM module to MLIR functions.
FailureOr< SmallVector< Value > > convertValues(ArrayRef< llvm::Value * > values)
Converts a range of LLVM values to a range of MLIR values using the convertValue method,...
DILocalVariableAttr matchLocalVariableAttr(llvm::Value *value)
Converts value to a local variable attribute.
void mapBlock(llvm::BasicBlock *llvm, Block *mlir)
Stores the mapping between an LLVM block and its MLIR counterpart.
Definition: ModuleImport.h:106
void processFunctionAttributes(llvm::Function *func, LLVMFuncOp funcOp)
Converts function attributes of LLVM Function func into LLVM dialect attributes of LLVMFuncOp funcOp.
LogicalResult convertMetadata()
Converts all LLVM metadata nodes that translate to operations nested in a global metadata operation,...
FailureOr< Value > convertValue(llvm::Value *value)
Converts an LLVM value to an MLIR value, or returns failure if the conversion fails.
LogicalResult initializeImportInterface()
Calls the LLVMImportInterface initialization that queries the registered dialect interfaces for the s...
Definition: ModuleImport.h:53
Block * lookupBlock(llvm::BasicBlock *block) const
Returns the MLIR block mapped to the given LLVM block.
Definition: ModuleImport.h:113
FailureOr< Value > convertMetadataValue(llvm::Value *value)
Converts an LLVM metadata value to an MLIR value, or returns failure if the conversion fails.
void mapNoResultOp(llvm::Instruction *llvm, Operation *mlir)
Stores a mapping between an LLVM instruction and the imported MLIR operation if the operation returns...
Definition: ModuleImport.h:79
Type convertType(llvm::Type *type)
Converts the type from LLVM to MLIR LLVM dialect.
Definition: ModuleImport.h:147
Operation * lookupOperation(llvm::Instruction *inst)
Returns the MLIR operation mapped to the given LLVM instruction.
Definition: ModuleImport.h:99
LoopAnnotationAttr translateLoopAnnotationAttr(const llvm::MDNode *node, Location loc) const
Returns the loop annotation attribute that corresponds to the given LLVM loop metadata node.
void setFastmathFlagsAttr(llvm::Instruction *inst, Operation *op) const
Sets the fastmath flags attribute for the imported operation op given the original instruction inst.
FailureOr< SmallVector< SymbolRefAttr > > lookupAccessGroupAttrs(const llvm::MDNode *node) const
Returns the symbol references pointing to the access group operations that map to the access group no...
Value lookupValue(llvm::Value *value)
Returns the MLIR value mapped to the given LLVM value.
Definition: ModuleImport.h:74
LogicalResult processFunction(llvm::Function *func)
Imports func into the current module.
ModuleImport(ModuleOp mlirModule, std::unique_ptr< llvm::Module > llvmModule)
void mapValue(llvm::Value *llvm, Value mlir)
Stores the mapping between an LLVM value and its MLIR counterpart.
Definition: ModuleImport.h:62
FailureOr< SmallVector< SymbolRefAttr > > matchAliasScopeAttrs(llvm::Value *value)
Converts value to an array of symbol references pointing to alias scope operations,...
LogicalResult convertGlobals()
Converts all global variables of the LLVM module to MLIR global variables.
FailureOr< SmallVector< SymbolRefAttr > > lookupAliasScopeAttrs(const llvm::MDNode *node) const
Returns the symbol references pointing to the alias scope operations that map to the alias scope node...
IntegerAttr matchIntegerAttr(llvm::Value *value)
Converts value to an integer attribute. Asserts if the matching fails.
A helper class that converts llvm.loop metadata nodes into corresponding LoopAnnotationAttrs and llvm...
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition: Location.h:63
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:60
std::vector< StringRef > getAvailableDialects()
Return information about all available dialects in the registry in this context.
void loadAllAvailableDialects()
Load all dialects available in the registry in this context.
RAII guard to reset the insertion point of the builder when destroyed.
Definition: Builders.h:329
This class helps build Operations.
Definition: Builders.h:202
void setInsertionPointToStart(Block *block)
Sets the insertion point to the start of the specified block.
Definition: Builders.h:412
void setInsertionPoint(Block *block, Block::iterator insertPoint)
Set the insertion point to the specified location.
Definition: Builders.h:379
void setInsertionPointToEnd(Block *block)
Sets the insertion point to the end of the specified block.
Definition: Builders.h:417
Block * createBlock(Region *parent, Region::iterator insertPt={}, TypeRange argTypes=std::nullopt, ArrayRef< Location > locs=std::nullopt)
Add new block with 'argTypes' arguments and set the insertion point to the end of it.
Definition: Builders.cpp:405
Operation * create(const OperationState &state)
Creates an operation given the fields represented as an OperationState.
Definition: Builders.cpp:432
void setInsertionPointAfter(Operation *op)
Sets the insertion point to the node after the specified operation, which will cause subsequent inser...
Definition: Builders.h:393
Block * getInsertionBlock() const
Return the block the current insertion point belongs to.
Definition: Builders.h:423
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:75
OpTy get() const
Allow accessing the internal op.
Definition: OwningOpRef.h:50
static StringAttr getSymbolName(Operation *symbol)
Returns the name of the given symbol operation, aborting if no symbol is present.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:74
U dyn_cast_or_null() const
Definition: Types.h:316
U dyn_cast() const
Definition: Types.h:311
bool isa() const
Definition: Types.h:301
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:93
Operation * getDefiningOp() const
If this value is the result of an operation, return the operation that defines it.
Definition: Value.cpp:20
static llvm::ArrayRef< std::pair< llvm::Attribute::AttrKind, llvm::StringRef > > getAttrKindToNameMapping()
Returns a list of pairs that each hold a mapping from LLVM attribute kinds to their corresponding str...
SetVector< Block * > getTopologicallySortedBlocks(Region &region)
Get a topologically sorted list of blocks of the given region.
bool isCompatibleVectorType(Type type)
Returns true if the given type is a vector type compatible with the LLVM dialect.
Definition: LLVMTypes.cpp:842
llvm::ElementCount getVectorNumElements(Type type)
Returns the element count of any LLVM-compatible vector type.
Definition: LLVMTypes.cpp:867
Type getVectorElementType(Type type)
Returns the element type of any vector type compatible with the LLVM dialect.
Definition: LLVMTypes.cpp:858
constexpr void enumerate(std::tuple< Tys... > &tuple, CallbackT &&callback)
Definition: Matchers.h:223
This header declares functions that assit transformations in the MemRef dialect.
bool matchPattern(Value value, const Pattern &pattern)
Entry point for matching a pattern over a Value.
Definition: Matchers.h:322
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:62
InFlightDiagnostic emitWarning(Location loc)
Utility method to emit a warning message using this location.
DataLayoutSpecInterface translateDataLayout(const llvm::DataLayout &dataLayout, MLIRContext *context)
Translate the given LLVM data layout into an MLIR equivalent using the DLTI dialect.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
bool succeeded(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a success value.
Definition: LogicalResult.h:68
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:56
detail::constant_op_matcher m_Constant()
Matches a constant foldable operation.
Definition: Matchers.h:248
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value.
Definition: LogicalResult.h:72
OwningOpRef< ModuleOp > translateLLVMIRToModule(std::unique_ptr< llvm::Module > llvmModule, MLIRContext *context)
Translates the LLVM module into an MLIR module living in the given context.
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26