MLIR  20.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 "DataLayoutImporter.h"
19 #include "DebugImporter.h"
20 #include "LoopAnnotationImporter.h"
21 
22 #include "mlir/Dialect/DLTI/DLTI.h"
24 #include "mlir/IR/Builders.h"
25 #include "mlir/IR/Matchers.h"
28 
29 #include "llvm/ADT/DepthFirstIterator.h"
30 #include "llvm/ADT/PostOrderIterator.h"
31 #include "llvm/ADT/ScopeExit.h"
32 #include "llvm/ADT/StringSet.h"
33 #include "llvm/ADT/TypeSwitch.h"
34 #include "llvm/IR/Comdat.h"
35 #include "llvm/IR/Constants.h"
36 #include "llvm/IR/InlineAsm.h"
37 #include "llvm/IR/InstIterator.h"
38 #include "llvm/IR/Instructions.h"
39 #include "llvm/IR/IntrinsicInst.h"
40 #include "llvm/IR/Metadata.h"
41 #include "llvm/IR/Operator.h"
42 #include "llvm/Support/ModRef.h"
43 
44 using namespace mlir;
45 using namespace mlir::LLVM;
46 using namespace mlir::LLVM::detail;
47 
48 #include "mlir/Dialect/LLVMIR/LLVMConversionEnumsFromLLVM.inc"
49 
50 // Utility to print an LLVM value as a string for passing to emitError().
51 // FIXME: Diagnostic should be able to natively handle types that have
52 // operator << (raw_ostream&) defined.
53 static std::string diag(const llvm::Value &value) {
54  std::string str;
55  llvm::raw_string_ostream os(str);
56  os << value;
57  return os.str();
58 }
59 
60 // Utility to print an LLVM metadata node as a string for passing
61 // to emitError(). The module argument is needed to print the nodes
62 // canonically numbered.
63 static std::string diagMD(const llvm::Metadata *node,
64  const llvm::Module *module) {
65  std::string str;
66  llvm::raw_string_ostream os(str);
67  node->print(os, module, /*IsForDebug=*/true);
68  return os.str();
69 }
70 
71 /// Returns the name of the global_ctors global variables.
72 static constexpr StringRef getGlobalCtorsVarName() {
73  return "llvm.global_ctors";
74 }
75 
76 /// Returns the name of the global_dtors global variables.
77 static constexpr StringRef getGlobalDtorsVarName() {
78  return "llvm.global_dtors";
79 }
80 
81 /// Returns the symbol name for the module-level comdat operation. It must not
82 /// conflict with the user namespace.
83 static constexpr StringRef getGlobalComdatOpName() {
84  return "__llvm_global_comdat";
85 }
86 
87 /// Converts the sync scope identifier of `inst` to the string representation
88 /// necessary to build an atomic LLVM dialect operation. Returns the empty
89 /// string if the operation has either no sync scope or the default system-level
90 /// sync scope attached. The atomic operations only set their sync scope
91 /// attribute if they have a non-default sync scope attached.
92 static StringRef getLLVMSyncScope(llvm::Instruction *inst) {
93  std::optional<llvm::SyncScope::ID> syncScopeID =
94  llvm::getAtomicSyncScopeID(inst);
95  if (!syncScopeID)
96  return "";
97 
98  // Search the sync scope name for the given identifier. The default
99  // system-level sync scope thereby maps to the empty string.
100  SmallVector<StringRef> syncScopeName;
101  llvm::LLVMContext &llvmContext = inst->getContext();
102  llvmContext.getSyncScopeNames(syncScopeName);
103  auto *it = llvm::find_if(syncScopeName, [&](StringRef name) {
104  return *syncScopeID == llvmContext.getOrInsertSyncScopeID(name);
105  });
106  if (it != syncScopeName.end())
107  return *it;
108  llvm_unreachable("incorrect sync scope identifier");
109 }
110 
111 /// Converts an array of unsigned indices to a signed integer position array.
113  SmallVector<int64_t> position;
114  llvm::append_range(position, indices);
115  return position;
116 }
117 
118 /// Converts the LLVM instructions that have a generated MLIR builder. Using a
119 /// static implementation method called from the module import ensures the
120 /// builders have to use the `moduleImport` argument and cannot directly call
121 /// import methods. As a result, both the intrinsic and the instruction MLIR
122 /// builders have to use the `moduleImport` argument and none of them has direct
123 /// access to the private module import methods.
124 static LogicalResult convertInstructionImpl(OpBuilder &odsBuilder,
125  llvm::Instruction *inst,
126  ModuleImport &moduleImport,
127  LLVMImportInterface &iface) {
128  // Copy the operands to an LLVM operands array reference for conversion.
129  SmallVector<llvm::Value *> operands(inst->operands());
130  ArrayRef<llvm::Value *> llvmOperands(operands);
131 
132  // Convert all instructions that provide an MLIR builder.
133  if (iface.isConvertibleInstruction(inst->getOpcode()))
134  return iface.convertInstruction(odsBuilder, inst, llvmOperands,
135  moduleImport);
136  // TODO: Implement the `convertInstruction` hooks in the
137  // `LLVMDialectLLVMIRImportInterface` and move the following include there.
138 #include "mlir/Dialect/LLVMIR/LLVMOpFromLLVMIRConversions.inc"
139  return failure();
140 }
141 
142 /// Get a topologically sorted list of blocks for the given basic blocks.
146  for (llvm::BasicBlock *basicBlock : basicBlocks) {
147  if (!blocks.contains(basicBlock)) {
148  llvm::ReversePostOrderTraversal<llvm::BasicBlock *> traversal(basicBlock);
149  blocks.insert(traversal.begin(), traversal.end());
150  }
151  }
152  assert(blocks.size() == basicBlocks.size() && "some blocks are not sorted");
153  return blocks;
154 }
155 
156 ModuleImport::ModuleImport(ModuleOp mlirModule,
157  std::unique_ptr<llvm::Module> llvmModule,
158  bool emitExpensiveWarnings,
159  bool importEmptyDICompositeTypes)
160  : builder(mlirModule->getContext()), context(mlirModule->getContext()),
161  mlirModule(mlirModule), llvmModule(std::move(llvmModule)),
162  iface(mlirModule->getContext()),
163  typeTranslator(*mlirModule->getContext()),
164  debugImporter(std::make_unique<DebugImporter>(
165  mlirModule, importEmptyDICompositeTypes)),
166  loopAnnotationImporter(
167  std::make_unique<LoopAnnotationImporter>(*this, builder)),
168  emitExpensiveWarnings(emitExpensiveWarnings) {
169  builder.setInsertionPointToStart(mlirModule.getBody());
170 }
171 
172 ComdatOp ModuleImport::getGlobalComdatOp() {
173  if (globalComdatOp)
174  return globalComdatOp;
175 
176  OpBuilder::InsertionGuard guard(builder);
177  builder.setInsertionPointToEnd(mlirModule.getBody());
178  globalComdatOp =
179  builder.create<ComdatOp>(mlirModule.getLoc(), getGlobalComdatOpName());
180  globalInsertionOp = globalComdatOp;
181  return globalComdatOp;
182 }
183 
184 LogicalResult ModuleImport::processTBAAMetadata(const llvm::MDNode *node) {
185  Location loc = mlirModule.getLoc();
186 
187  // If `node` is a valid TBAA root node, then return its optional identity
188  // string, otherwise return failure.
189  auto getIdentityIfRootNode =
190  [&](const llvm::MDNode *node) -> FailureOr<std::optional<StringRef>> {
191  // Root node, e.g.:
192  // !0 = !{!"Simple C/C++ TBAA"}
193  // !1 = !{}
194  if (node->getNumOperands() > 1)
195  return failure();
196  // If the operand is MDString, then assume that this is a root node.
197  if (node->getNumOperands() == 1)
198  if (const auto *op0 = dyn_cast<const llvm::MDString>(node->getOperand(0)))
199  return std::optional<StringRef>{op0->getString()};
200  return std::optional<StringRef>{};
201  };
202 
203  // If `node` looks like a TBAA type descriptor metadata,
204  // then return true, if it is a valid node, and false otherwise.
205  // If it does not look like a TBAA type descriptor metadata, then
206  // return std::nullopt.
207  // If `identity` and `memberTypes/Offsets` are non-null, then they will
208  // contain the converted metadata operands for a valid TBAA node (i.e. when
209  // true is returned).
210  auto isTypeDescriptorNode = [&](const llvm::MDNode *node,
211  StringRef *identity = nullptr,
213  nullptr) -> std::optional<bool> {
214  unsigned numOperands = node->getNumOperands();
215  // Type descriptor, e.g.:
216  // !1 = !{!"int", !0, /*optional*/i64 0} /* scalar int type */
217  // !2 = !{!"agg_t", !1, i64 0} /* struct agg_t { int x; } */
218  if (numOperands < 2)
219  return std::nullopt;
220 
221  // TODO: support "new" format (D41501) for type descriptors,
222  // where the first operand is an MDNode.
223  const auto *identityNode =
224  dyn_cast<const llvm::MDString>(node->getOperand(0));
225  if (!identityNode)
226  return std::nullopt;
227 
228  // This should be a type descriptor node.
229  if (identity)
230  *identity = identityNode->getString();
231 
232  for (unsigned pairNum = 0, e = numOperands / 2; pairNum < e; ++pairNum) {
233  const auto *memberNode =
234  dyn_cast<const llvm::MDNode>(node->getOperand(2 * pairNum + 1));
235  if (!memberNode) {
236  emitError(loc) << "operand '" << 2 * pairNum + 1 << "' must be MDNode: "
237  << diagMD(node, llvmModule.get());
238  return false;
239  }
240  int64_t offset = 0;
241  if (2 * pairNum + 2 >= numOperands) {
242  // Allow for optional 0 offset in 2-operand nodes.
243  if (numOperands != 2) {
244  emitError(loc) << "missing member offset: "
245  << diagMD(node, llvmModule.get());
246  return false;
247  }
248  } else {
249  auto *offsetCI = llvm::mdconst::dyn_extract<llvm::ConstantInt>(
250  node->getOperand(2 * pairNum + 2));
251  if (!offsetCI) {
252  emitError(loc) << "operand '" << 2 * pairNum + 2
253  << "' must be ConstantInt: "
254  << diagMD(node, llvmModule.get());
255  return false;
256  }
257  offset = offsetCI->getZExtValue();
258  }
259 
260  if (members)
261  members->push_back(TBAAMemberAttr::get(
262  cast<TBAANodeAttr>(tbaaMapping.lookup(memberNode)), offset));
263  }
264 
265  return true;
266  };
267 
268  // If `node` looks like a TBAA access tag metadata,
269  // then return true, if it is a valid node, and false otherwise.
270  // If it does not look like a TBAA access tag metadata, then
271  // return std::nullopt.
272  // If the other arguments are non-null, then they will contain
273  // the converted metadata operands for a valid TBAA node (i.e. when true is
274  // returned).
275  auto isTagNode = [&](const llvm::MDNode *node,
276  TBAATypeDescriptorAttr *baseAttr = nullptr,
277  TBAATypeDescriptorAttr *accessAttr = nullptr,
278  int64_t *offset = nullptr,
279  bool *isConstant = nullptr) -> std::optional<bool> {
280  // Access tag, e.g.:
281  // !3 = !{!1, !1, i64 0} /* scalar int access */
282  // !4 = !{!2, !1, i64 0} /* agg_t::x access */
283  //
284  // Optional 4th argument is ConstantInt 0/1 identifying whether
285  // the location being accessed is "constant" (see for details:
286  // https://llvm.org/docs/LangRef.html#representation).
287  unsigned numOperands = node->getNumOperands();
288  if (numOperands != 3 && numOperands != 4)
289  return std::nullopt;
290  const auto *baseMD = dyn_cast<const llvm::MDNode>(node->getOperand(0));
291  const auto *accessMD = dyn_cast<const llvm::MDNode>(node->getOperand(1));
292  auto *offsetCI =
293  llvm::mdconst::dyn_extract<llvm::ConstantInt>(node->getOperand(2));
294  if (!baseMD || !accessMD || !offsetCI)
295  return std::nullopt;
296  // TODO: support "new" TBAA format, if needed (see D41501).
297  // In the "old" format the first operand of the access type
298  // metadata is MDString. We have to distinguish the formats,
299  // because access tags have the same structure, but different
300  // meaning for the operands.
301  if (accessMD->getNumOperands() < 1 ||
302  !isa<llvm::MDString>(accessMD->getOperand(0)))
303  return std::nullopt;
304  bool isConst = false;
305  if (numOperands == 4) {
306  auto *isConstantCI =
307  llvm::mdconst::dyn_extract<llvm::ConstantInt>(node->getOperand(3));
308  if (!isConstantCI) {
309  emitError(loc) << "operand '3' must be ConstantInt: "
310  << diagMD(node, llvmModule.get());
311  return false;
312  }
313  isConst = isConstantCI->getValue()[0];
314  }
315  if (baseAttr)
316  *baseAttr = cast<TBAATypeDescriptorAttr>(tbaaMapping.lookup(baseMD));
317  if (accessAttr)
318  *accessAttr = cast<TBAATypeDescriptorAttr>(tbaaMapping.lookup(accessMD));
319  if (offset)
320  *offset = offsetCI->getZExtValue();
321  if (isConstant)
322  *isConstant = isConst;
323  return true;
324  };
325 
326  // Do a post-order walk over the TBAA Graph. Since a correct TBAA Graph is a
327  // DAG, a post-order walk guarantees that we convert any metadata node we
328  // depend on, prior to converting the current node.
331  workList.push_back(node);
332  while (!workList.empty()) {
333  const llvm::MDNode *current = workList.back();
334  if (tbaaMapping.contains(current)) {
335  // Already converted. Just pop from the worklist.
336  workList.pop_back();
337  continue;
338  }
339 
340  // If any child of this node is not yet converted, don't pop the current
341  // node from the worklist but push the not-yet-converted children in the
342  // front of the worklist.
343  bool anyChildNotConverted = false;
344  for (const llvm::MDOperand &operand : current->operands())
345  if (auto *childNode = dyn_cast_or_null<const llvm::MDNode>(operand.get()))
346  if (!tbaaMapping.contains(childNode)) {
347  workList.push_back(childNode);
348  anyChildNotConverted = true;
349  }
350 
351  if (anyChildNotConverted) {
352  // If this is the second time we failed to convert an element in the
353  // worklist it must be because a child is dependent on it being converted
354  // and we have a cycle in the graph. Cycles are not allowed in TBAA
355  // graphs.
356  if (!seen.insert(current).second)
357  return emitError(loc) << "has cycle in TBAA graph: "
358  << diagMD(current, llvmModule.get());
359 
360  continue;
361  }
362 
363  // Otherwise simply import the current node.
364  workList.pop_back();
365 
366  FailureOr<std::optional<StringRef>> rootNodeIdentity =
367  getIdentityIfRootNode(current);
368  if (succeeded(rootNodeIdentity)) {
369  StringAttr stringAttr = *rootNodeIdentity
370  ? builder.getStringAttr(**rootNodeIdentity)
371  : nullptr;
372  // The root nodes do not have operands, so we can create
373  // the TBAARootAttr on the first walk.
374  tbaaMapping.insert({current, builder.getAttr<TBAARootAttr>(stringAttr)});
375  continue;
376  }
377 
378  StringRef identity;
380  if (std::optional<bool> isValid =
381  isTypeDescriptorNode(current, &identity, &members)) {
382  assert(isValid.value() && "type descriptor node must be valid");
383 
384  tbaaMapping.insert({current, builder.getAttr<TBAATypeDescriptorAttr>(
385  identity, members)});
386  continue;
387  }
388 
389  TBAATypeDescriptorAttr baseAttr, accessAttr;
390  int64_t offset;
391  bool isConstant;
392  if (std::optional<bool> isValid =
393  isTagNode(current, &baseAttr, &accessAttr, &offset, &isConstant)) {
394  assert(isValid.value() && "access tag node must be valid");
395  tbaaMapping.insert(
396  {current, builder.getAttr<TBAATagAttr>(baseAttr, accessAttr, offset,
397  isConstant)});
398  continue;
399  }
400 
401  return emitError(loc) << "unsupported TBAA node format: "
402  << diagMD(current, llvmModule.get());
403  }
404  return success();
405 }
406 
407 LogicalResult
408 ModuleImport::processAccessGroupMetadata(const llvm::MDNode *node) {
409  Location loc = mlirModule.getLoc();
410  if (failed(loopAnnotationImporter->translateAccessGroup(node, loc)))
411  return emitError(loc) << "unsupported access group node: "
412  << diagMD(node, llvmModule.get());
413  return success();
414 }
415 
416 LogicalResult
417 ModuleImport::processAliasScopeMetadata(const llvm::MDNode *node) {
418  Location loc = mlirModule.getLoc();
419  // Helper that verifies the node has a self reference operand.
420  auto verifySelfRef = [](const llvm::MDNode *node) {
421  return node->getNumOperands() != 0 &&
422  node == dyn_cast<llvm::MDNode>(node->getOperand(0));
423  };
424  // Helper that verifies the given operand is a string or does not exist.
425  auto verifyDescription = [](const llvm::MDNode *node, unsigned idx) {
426  return idx >= node->getNumOperands() ||
427  isa<llvm::MDString>(node->getOperand(idx));
428  };
429  // Helper that creates an alias scope domain attribute.
430  auto createAliasScopeDomainOp = [&](const llvm::MDNode *aliasDomain) {
431  StringAttr description = nullptr;
432  if (aliasDomain->getNumOperands() >= 2)
433  if (auto *operand = dyn_cast<llvm::MDString>(aliasDomain->getOperand(1)))
434  description = builder.getStringAttr(operand->getString());
435  return builder.getAttr<AliasScopeDomainAttr>(
436  DistinctAttr::create(builder.getUnitAttr()), description);
437  };
438 
439  // Collect the alias scopes and domains to translate them.
440  for (const llvm::MDOperand &operand : node->operands()) {
441  if (const auto *scope = dyn_cast<llvm::MDNode>(operand)) {
442  llvm::AliasScopeNode aliasScope(scope);
443  const llvm::MDNode *domain = aliasScope.getDomain();
444 
445  // Verify the scope node points to valid scope metadata which includes
446  // verifying its domain. Perform the verification before looking it up in
447  // the alias scope mapping since it could have been inserted as a domain
448  // node before.
449  if (!verifySelfRef(scope) || !domain || !verifyDescription(scope, 2))
450  return emitError(loc) << "unsupported alias scope node: "
451  << diagMD(scope, llvmModule.get());
452  if (!verifySelfRef(domain) || !verifyDescription(domain, 1))
453  return emitError(loc) << "unsupported alias domain node: "
454  << diagMD(domain, llvmModule.get());
455 
456  if (aliasScopeMapping.contains(scope))
457  continue;
458 
459  // Convert the domain metadata node if it has not been translated before.
460  auto it = aliasScopeMapping.find(aliasScope.getDomain());
461  if (it == aliasScopeMapping.end()) {
462  auto aliasScopeDomainOp = createAliasScopeDomainOp(domain);
463  it = aliasScopeMapping.try_emplace(domain, aliasScopeDomainOp).first;
464  }
465 
466  // Convert the scope metadata node if it has not been converted before.
467  StringAttr description = nullptr;
468  if (!aliasScope.getName().empty())
469  description = builder.getStringAttr(aliasScope.getName());
470  auto aliasScopeOp = builder.getAttr<AliasScopeAttr>(
472  cast<AliasScopeDomainAttr>(it->second), description);
473  aliasScopeMapping.try_emplace(aliasScope.getNode(), aliasScopeOp);
474  }
475  }
476  return success();
477 }
478 
479 FailureOr<SmallVector<AliasScopeAttr>>
480 ModuleImport::lookupAliasScopeAttrs(const llvm::MDNode *node) const {
481  SmallVector<AliasScopeAttr> aliasScopes;
482  aliasScopes.reserve(node->getNumOperands());
483  for (const llvm::MDOperand &operand : node->operands()) {
484  auto *node = cast<llvm::MDNode>(operand.get());
485  aliasScopes.push_back(
486  dyn_cast_or_null<AliasScopeAttr>(aliasScopeMapping.lookup(node)));
487  }
488  // Return failure if one of the alias scope lookups failed.
489  if (llvm::is_contained(aliasScopes, nullptr))
490  return failure();
491  return aliasScopes;
492 }
493 
494 void ModuleImport::addDebugIntrinsic(llvm::CallInst *intrinsic) {
495  debugIntrinsics.insert(intrinsic);
496 }
497 
499  for (const llvm::NamedMDNode &named : llvmModule->named_metadata()) {
500  if (named.getName() != "llvm.linker.options")
501  continue;
502  // llvm.linker.options operands are lists of strings.
503  for (const llvm::MDNode *md : named.operands()) {
505  options.reserve(md->getNumOperands());
506  for (const llvm::MDOperand &option : md->operands())
507  options.push_back(cast<llvm::MDString>(option)->getString());
508  builder.create<LLVM::LinkerOptionsOp>(mlirModule.getLoc(),
509  builder.getStrArrayAttr(options));
510  }
511  }
512  return success();
513 }
514 
516  OpBuilder::InsertionGuard guard(builder);
517  builder.setInsertionPointToEnd(mlirModule.getBody());
518  for (const llvm::Function &func : llvmModule->functions()) {
519  for (const llvm::Instruction &inst : llvm::instructions(func)) {
520  // Convert access group metadata nodes.
521  if (llvm::MDNode *node =
522  inst.getMetadata(llvm::LLVMContext::MD_access_group))
523  if (failed(processAccessGroupMetadata(node)))
524  return failure();
525 
526  // Convert alias analysis metadata nodes.
527  llvm::AAMDNodes aliasAnalysisNodes = inst.getAAMetadata();
528  if (!aliasAnalysisNodes)
529  continue;
530  if (aliasAnalysisNodes.TBAA)
531  if (failed(processTBAAMetadata(aliasAnalysisNodes.TBAA)))
532  return failure();
533  if (aliasAnalysisNodes.Scope)
534  if (failed(processAliasScopeMetadata(aliasAnalysisNodes.Scope)))
535  return failure();
536  if (aliasAnalysisNodes.NoAlias)
537  if (failed(processAliasScopeMetadata(aliasAnalysisNodes.NoAlias)))
538  return failure();
539  }
540  }
541  if (failed(convertLinkerOptionsMetadata()))
542  return failure();
543  return success();
544 }
545 
546 void ModuleImport::processComdat(const llvm::Comdat *comdat) {
547  if (comdatMapping.contains(comdat))
548  return;
549 
550  ComdatOp comdatOp = getGlobalComdatOp();
551  OpBuilder::InsertionGuard guard(builder);
552  builder.setInsertionPointToEnd(&comdatOp.getBody().back());
553  auto selectorOp = builder.create<ComdatSelectorOp>(
554  mlirModule.getLoc(), comdat->getName(),
555  convertComdatFromLLVM(comdat->getSelectionKind()));
556  auto symbolRef =
558  FlatSymbolRefAttr::get(selectorOp.getSymNameAttr()));
559  comdatMapping.try_emplace(comdat, symbolRef);
560 }
561 
563  for (llvm::GlobalVariable &globalVar : llvmModule->globals())
564  if (globalVar.hasComdat())
565  processComdat(globalVar.getComdat());
566  for (llvm::Function &func : llvmModule->functions())
567  if (func.hasComdat())
568  processComdat(func.getComdat());
569  return success();
570 }
571 
573  for (llvm::GlobalVariable &globalVar : llvmModule->globals()) {
574  if (globalVar.getName() == getGlobalCtorsVarName() ||
575  globalVar.getName() == getGlobalDtorsVarName()) {
576  if (failed(convertGlobalCtorsAndDtors(&globalVar))) {
577  return emitError(UnknownLoc::get(context))
578  << "unhandled global variable: " << diag(globalVar);
579  }
580  continue;
581  }
582  if (failed(convertGlobal(&globalVar))) {
583  return emitError(UnknownLoc::get(context))
584  << "unhandled global variable: " << diag(globalVar);
585  }
586  }
587  return success();
588 }
589 
591  Location loc = mlirModule.getLoc();
592  DataLayoutImporter dataLayoutImporter(context, llvmModule->getDataLayout());
593  if (!dataLayoutImporter.getDataLayout())
594  return emitError(loc, "cannot translate data layout: ")
595  << dataLayoutImporter.getLastToken();
596 
597  for (StringRef token : dataLayoutImporter.getUnhandledTokens())
598  emitWarning(loc, "unhandled data layout token: ") << token;
599 
600  mlirModule->setAttr(DLTIDialect::kDataLayoutAttrName,
601  dataLayoutImporter.getDataLayout());
602  return success();
603 }
604 
606  for (llvm::Function &func : llvmModule->functions())
607  if (failed(processFunction(&func)))
608  return failure();
609  return success();
610 }
611 
612 void ModuleImport::setNonDebugMetadataAttrs(llvm::Instruction *inst,
613  Operation *op) {
615  inst->getAllMetadataOtherThanDebugLoc(allMetadata);
616  for (auto &[kind, node] : allMetadata) {
617  if (!iface.isConvertibleMetadata(kind))
618  continue;
619  if (failed(iface.setMetadataAttrs(builder, kind, node, op, *this))) {
620  if (emitExpensiveWarnings) {
621  Location loc = debugImporter->translateLoc(inst->getDebugLoc());
622  emitWarning(loc) << "unhandled metadata: "
623  << diagMD(node, llvmModule.get()) << " on "
624  << diag(*inst);
625  }
626  }
627  }
628 }
629 
630 void ModuleImport::setIntegerOverflowFlags(llvm::Instruction *inst,
631  Operation *op) const {
632  auto iface = cast<IntegerOverflowFlagsInterface>(op);
633 
634  IntegerOverflowFlags value = {};
635  value = bitEnumSet(value, IntegerOverflowFlags::nsw, inst->hasNoSignedWrap());
636  value =
637  bitEnumSet(value, IntegerOverflowFlags::nuw, inst->hasNoUnsignedWrap());
638 
639  iface.setOverflowFlags(value);
640 }
641 
642 void ModuleImport::setFastmathFlagsAttr(llvm::Instruction *inst,
643  Operation *op) const {
644  auto iface = cast<FastmathFlagsInterface>(op);
645 
646  // Even if the imported operation implements the fastmath interface, the
647  // original instruction may not have fastmath flags set. Exit if an
648  // instruction, such as a non floating-point function call, does not have
649  // fastmath flags.
650  if (!isa<llvm::FPMathOperator>(inst))
651  return;
652  llvm::FastMathFlags flags = inst->getFastMathFlags();
653 
654  // Set the fastmath bits flag-by-flag.
655  FastmathFlags value = {};
656  value = bitEnumSet(value, FastmathFlags::nnan, flags.noNaNs());
657  value = bitEnumSet(value, FastmathFlags::ninf, flags.noInfs());
658  value = bitEnumSet(value, FastmathFlags::nsz, flags.noSignedZeros());
659  value = bitEnumSet(value, FastmathFlags::arcp, flags.allowReciprocal());
660  value = bitEnumSet(value, FastmathFlags::contract, flags.allowContract());
661  value = bitEnumSet(value, FastmathFlags::afn, flags.approxFunc());
662  value = bitEnumSet(value, FastmathFlags::reassoc, flags.allowReassoc());
663  FastmathFlagsAttr attr = FastmathFlagsAttr::get(builder.getContext(), value);
664  iface->setAttr(iface.getFastmathAttrName(), attr);
665 }
666 
667 /// Returns if `type` is a scalar integer or floating-point type.
668 static bool isScalarType(Type type) {
669  return isa<IntegerType, FloatType>(type);
670 }
671 
672 /// Returns `type` if it is a builtin integer or floating-point vector type that
673 /// can be used to create an attribute or nullptr otherwise. If provided,
674 /// `arrayShape` is added to the shape of the vector to create an attribute that
675 /// matches an array of vectors.
676 static Type getVectorTypeForAttr(Type type, ArrayRef<int64_t> arrayShape = {}) {
677  if (!LLVM::isCompatibleVectorType(type))
678  return {};
679 
680  llvm::ElementCount numElements = LLVM::getVectorNumElements(type);
681  if (numElements.isScalable()) {
683  << "scalable vectors not supported";
684  return {};
685  }
686 
687  // An LLVM dialect vector can only contain scalars.
688  Type elementType = LLVM::getVectorElementType(type);
689  if (!isScalarType(elementType))
690  return {};
691 
692  SmallVector<int64_t> shape(arrayShape.begin(), arrayShape.end());
693  shape.push_back(numElements.getKnownMinValue());
694  return VectorType::get(shape, elementType);
695 }
696 
697 Type ModuleImport::getBuiltinTypeForAttr(Type type) {
698  if (!type)
699  return {};
700 
701  // Return builtin integer and floating-point types as is.
702  if (isScalarType(type))
703  return type;
704 
705  // Return builtin vectors of integer and floating-point types as is.
706  if (Type vectorType = getVectorTypeForAttr(type))
707  return vectorType;
708 
709  // Multi-dimensional array types are converted to tensors or vectors,
710  // depending on the innermost type being a scalar or a vector.
711  SmallVector<int64_t> arrayShape;
712  while (auto arrayType = dyn_cast<LLVMArrayType>(type)) {
713  arrayShape.push_back(arrayType.getNumElements());
714  type = arrayType.getElementType();
715  }
716  if (isScalarType(type))
717  return RankedTensorType::get(arrayShape, type);
718  return getVectorTypeForAttr(type, arrayShape);
719 }
720 
721 /// Returns an integer or float attribute for the provided scalar constant
722 /// `constScalar` or nullptr if the conversion fails.
723 static TypedAttr getScalarConstantAsAttr(OpBuilder &builder,
724  llvm::Constant *constScalar) {
725  MLIRContext *context = builder.getContext();
726 
727  // Convert scalar intergers.
728  if (auto *constInt = dyn_cast<llvm::ConstantInt>(constScalar)) {
729  return builder.getIntegerAttr(
730  IntegerType::get(context, constInt->getBitWidth()),
731  constInt->getValue());
732  }
733 
734  // Convert scalar floats.
735  if (auto *constFloat = dyn_cast<llvm::ConstantFP>(constScalar)) {
736  llvm::Type *type = constFloat->getType();
737  FloatType floatType =
738  type->isBFloatTy()
739  ? FloatType::getBF16(context)
740  : LLVM::detail::getFloatType(context, type->getScalarSizeInBits());
741  if (!floatType) {
743  << "unexpected floating-point type";
744  return {};
745  }
746  return builder.getFloatAttr(floatType, constFloat->getValueAPF());
747  }
748  return {};
749 }
750 
751 /// Returns an integer or float attribute array for the provided constant
752 /// sequence `constSequence` or nullptr if the conversion fails.
755  llvm::ConstantDataSequential *constSequence) {
756  SmallVector<Attribute> elementAttrs;
757  elementAttrs.reserve(constSequence->getNumElements());
758  for (auto idx : llvm::seq<int64_t>(0, constSequence->getNumElements())) {
759  llvm::Constant *constElement = constSequence->getElementAsConstant(idx);
760  elementAttrs.push_back(getScalarConstantAsAttr(builder, constElement));
761  }
762  return elementAttrs;
763 }
764 
765 Attribute ModuleImport::getConstantAsAttr(llvm::Constant *constant) {
766  // Convert scalar constants.
767  if (Attribute scalarAttr = getScalarConstantAsAttr(builder, constant))
768  return scalarAttr;
769 
770  // Convert function references.
771  if (auto *func = dyn_cast<llvm::Function>(constant))
772  return SymbolRefAttr::get(builder.getContext(), func->getName());
773 
774  // Returns the static shape of the provided type if possible.
775  auto getConstantShape = [&](llvm::Type *type) {
776  return llvm::dyn_cast_if_present<ShapedType>(
777  getBuiltinTypeForAttr(convertType(type)));
778  };
779 
780  // Convert one-dimensional constant arrays or vectors that store 1/2/4/8-byte
781  // integer or half/bfloat/float/double values.
782  if (auto *constArray = dyn_cast<llvm::ConstantDataSequential>(constant)) {
783  if (constArray->isString())
784  return builder.getStringAttr(constArray->getAsString());
785  auto shape = getConstantShape(constArray->getType());
786  if (!shape)
787  return {};
788  // Convert splat constants to splat elements attributes.
789  auto *constVector = dyn_cast<llvm::ConstantDataVector>(constant);
790  if (constVector && constVector->isSplat()) {
791  // A vector is guaranteed to have at least size one.
793  builder, constVector->getElementAsConstant(0));
794  return SplatElementsAttr::get(shape, splatAttr);
795  }
796  // Convert non-splat constants to dense elements attributes.
797  SmallVector<Attribute> elementAttrs =
798  getSequenceConstantAsAttrs(builder, constArray);
799  return DenseElementsAttr::get(shape, elementAttrs);
800  }
801 
802  // Convert multi-dimensional constant aggregates that store all kinds of
803  // integer and floating-point types.
804  if (auto *constAggregate = dyn_cast<llvm::ConstantAggregate>(constant)) {
805  auto shape = getConstantShape(constAggregate->getType());
806  if (!shape)
807  return {};
808  // Collect the aggregate elements in depths first order.
809  SmallVector<Attribute> elementAttrs;
810  SmallVector<llvm::Constant *> workList = {constAggregate};
811  while (!workList.empty()) {
812  llvm::Constant *current = workList.pop_back_val();
813  // Append any nested aggregates in reverse order to ensure the head
814  // element of the nested aggregates is at the back of the work list.
815  if (auto *constAggregate = dyn_cast<llvm::ConstantAggregate>(current)) {
816  for (auto idx :
817  reverse(llvm::seq<int64_t>(0, constAggregate->getNumOperands())))
818  workList.push_back(constAggregate->getAggregateElement(idx));
819  continue;
820  }
821  // Append the elements of nested constant arrays or vectors that store
822  // 1/2/4/8-byte integer or half/bfloat/float/double values.
823  if (auto *constArray = dyn_cast<llvm::ConstantDataSequential>(current)) {
824  SmallVector<Attribute> attrs =
825  getSequenceConstantAsAttrs(builder, constArray);
826  elementAttrs.append(attrs.begin(), attrs.end());
827  continue;
828  }
829  // Append nested scalar constants that store all kinds of integer and
830  // floating-point types.
831  if (Attribute scalarAttr = getScalarConstantAsAttr(builder, current)) {
832  elementAttrs.push_back(scalarAttr);
833  continue;
834  }
835  // Bail if the aggregate contains a unsupported constant type such as a
836  // constant expression.
837  return {};
838  }
839  return DenseElementsAttr::get(shape, elementAttrs);
840  }
841 
842  // Convert zero aggregates.
843  if (auto *constZero = dyn_cast<llvm::ConstantAggregateZero>(constant)) {
844  auto shape = llvm::dyn_cast_if_present<ShapedType>(
845  getBuiltinTypeForAttr(convertType(constZero->getType())));
846  if (!shape)
847  return {};
848  // Convert zero aggregates with a static shape to splat elements attributes.
849  Attribute splatAttr = builder.getZeroAttr(shape.getElementType());
850  assert(splatAttr && "expected non-null zero attribute for scalar types");
851  return SplatElementsAttr::get(shape, splatAttr);
852  }
853  return {};
854 }
855 
856 LogicalResult ModuleImport::convertGlobal(llvm::GlobalVariable *globalVar) {
857  // Insert the global after the last one or at the start of the module.
858  OpBuilder::InsertionGuard guard(builder);
859  if (!globalInsertionOp)
860  builder.setInsertionPointToStart(mlirModule.getBody());
861  else
862  builder.setInsertionPointAfter(globalInsertionOp);
863 
864  Attribute valueAttr;
865  if (globalVar->hasInitializer())
866  valueAttr = getConstantAsAttr(globalVar->getInitializer());
867  Type type = convertType(globalVar->getValueType());
868 
869  uint64_t alignment = 0;
870  llvm::MaybeAlign maybeAlign = globalVar->getAlign();
871  if (maybeAlign.has_value()) {
872  llvm::Align align = *maybeAlign;
873  alignment = align.value();
874  }
875 
876  // Get the global expression associated with this global variable and convert
877  // it.
878  DIGlobalVariableExpressionAttr globalExpressionAttr;
880  globalVar->getDebugInfo(globalExpressions);
881 
882  // There should only be a single global expression.
883  if (!globalExpressions.empty())
884  globalExpressionAttr =
885  debugImporter->translateGlobalVariableExpression(globalExpressions[0]);
886 
887  GlobalOp globalOp = builder.create<GlobalOp>(
888  mlirModule.getLoc(), type, globalVar->isConstant(),
889  convertLinkageFromLLVM(globalVar->getLinkage()), globalVar->getName(),
890  valueAttr, alignment, /*addr_space=*/globalVar->getAddressSpace(),
891  /*dso_local=*/globalVar->isDSOLocal(),
892  /*thread_local=*/globalVar->isThreadLocal(), /*comdat=*/SymbolRefAttr(),
893  /*attrs=*/ArrayRef<NamedAttribute>(), /*dbgExpr=*/globalExpressionAttr);
894  globalInsertionOp = globalOp;
895 
896  if (globalVar->hasInitializer() && !valueAttr) {
897  clearRegionState();
898  Block *block = builder.createBlock(&globalOp.getInitializerRegion());
899  setConstantInsertionPointToStart(block);
900  FailureOr<Value> initializer =
901  convertConstantExpr(globalVar->getInitializer());
902  if (failed(initializer))
903  return failure();
904  builder.create<ReturnOp>(globalOp.getLoc(), *initializer);
905  }
906  if (globalVar->hasAtLeastLocalUnnamedAddr()) {
907  globalOp.setUnnamedAddr(
908  convertUnnamedAddrFromLLVM(globalVar->getUnnamedAddr()));
909  }
910  if (globalVar->hasSection())
911  globalOp.setSection(globalVar->getSection());
912  globalOp.setVisibility_(
913  convertVisibilityFromLLVM(globalVar->getVisibility()));
914 
915  if (globalVar->hasComdat())
916  globalOp.setComdatAttr(comdatMapping.lookup(globalVar->getComdat()));
917 
918  return success();
919 }
920 
921 LogicalResult
922 ModuleImport::convertGlobalCtorsAndDtors(llvm::GlobalVariable *globalVar) {
923  if (!globalVar->hasInitializer() || !globalVar->hasAppendingLinkage())
924  return failure();
925  auto *initializer =
926  dyn_cast<llvm::ConstantArray>(globalVar->getInitializer());
927  if (!initializer)
928  return failure();
929 
931  SmallVector<int32_t> priorities;
932  for (llvm::Value *operand : initializer->operands()) {
933  auto *aggregate = dyn_cast<llvm::ConstantAggregate>(operand);
934  if (!aggregate || aggregate->getNumOperands() != 3)
935  return failure();
936 
937  auto *priority = dyn_cast<llvm::ConstantInt>(aggregate->getOperand(0));
938  auto *func = dyn_cast<llvm::Function>(aggregate->getOperand(1));
939  auto *data = dyn_cast<llvm::Constant>(aggregate->getOperand(2));
940  if (!priority || !func || !data)
941  return failure();
942 
943  // GlobalCtorsOps and GlobalDtorsOps do not support non-null data fields.
944  if (!data->isNullValue())
945  return failure();
946 
947  funcs.push_back(FlatSymbolRefAttr::get(context, func->getName()));
948  priorities.push_back(priority->getValue().getZExtValue());
949  }
950 
951  OpBuilder::InsertionGuard guard(builder);
952  if (!globalInsertionOp)
953  builder.setInsertionPointToStart(mlirModule.getBody());
954  else
955  builder.setInsertionPointAfter(globalInsertionOp);
956 
957  if (globalVar->getName() == getGlobalCtorsVarName()) {
958  globalInsertionOp = builder.create<LLVM::GlobalCtorsOp>(
959  mlirModule.getLoc(), builder.getArrayAttr(funcs),
960  builder.getI32ArrayAttr(priorities));
961  return success();
962  }
963  globalInsertionOp = builder.create<LLVM::GlobalDtorsOp>(
964  mlirModule.getLoc(), builder.getArrayAttr(funcs),
965  builder.getI32ArrayAttr(priorities));
966  return success();
967 }
968 
970 ModuleImport::getConstantsToConvert(llvm::Constant *constant) {
971  // Return the empty set if the constant has been translated before.
972  if (valueMapping.contains(constant))
973  return {};
974 
975  // Traverse the constants in post-order and stop the traversal if a constant
976  // already has a `valueMapping` from an earlier constant translation or if the
977  // constant is traversed a second time.
978  SetVector<llvm::Constant *> orderedSet;
981  workList.insert(constant);
982  while (!workList.empty()) {
983  llvm::Constant *current = workList.back();
984  // Collect all dependencies of the current constant and add them to the
985  // adjacency list if none has been computed before.
986  auto adjacencyIt = adjacencyLists.find(current);
987  if (adjacencyIt == adjacencyLists.end()) {
988  adjacencyIt = adjacencyLists.try_emplace(current).first;
989  // Add all constant operands to the adjacency list and skip any other
990  // values such as basic block addresses.
991  for (llvm::Value *operand : current->operands())
992  if (auto *constDependency = dyn_cast<llvm::Constant>(operand))
993  adjacencyIt->getSecond().push_back(constDependency);
994  // Use the getElementValue method to add the dependencies of zero
995  // initialized aggregate constants since they do not take any operands.
996  if (auto *constAgg = dyn_cast<llvm::ConstantAggregateZero>(current)) {
997  unsigned numElements = constAgg->getElementCount().getFixedValue();
998  for (unsigned i = 0, e = numElements; i != e; ++i)
999  adjacencyIt->getSecond().push_back(constAgg->getElementValue(i));
1000  }
1001  }
1002  // Add the current constant to the `orderedSet` of the traversed nodes if
1003  // all its dependencies have been traversed before. Additionally, remove the
1004  // constant from the `workList` and continue the traversal.
1005  if (adjacencyIt->getSecond().empty()) {
1006  orderedSet.insert(current);
1007  workList.pop_back();
1008  continue;
1009  }
1010  // Add the next dependency from the adjacency list to the `workList` and
1011  // continue the traversal. Remove the dependency from the adjacency list to
1012  // mark that it has been processed. Only enqueue the dependency if it has no
1013  // `valueMapping` from an earlier translation and if it has not been
1014  // enqueued before.
1015  llvm::Constant *dependency = adjacencyIt->getSecond().pop_back_val();
1016  if (valueMapping.contains(dependency) || workList.contains(dependency) ||
1017  orderedSet.contains(dependency))
1018  continue;
1019  workList.insert(dependency);
1020  }
1021 
1022  return orderedSet;
1023 }
1024 
1025 FailureOr<Value> ModuleImport::convertConstant(llvm::Constant *constant) {
1026  Location loc = UnknownLoc::get(context);
1027 
1028  // Convert constants that can be represented as attributes.
1029  if (Attribute attr = getConstantAsAttr(constant)) {
1030  Type type = convertType(constant->getType());
1031  if (auto symbolRef = dyn_cast<FlatSymbolRefAttr>(attr)) {
1032  return builder.create<AddressOfOp>(loc, type, symbolRef.getValue())
1033  .getResult();
1034  }
1035  return builder.create<ConstantOp>(loc, type, attr).getResult();
1036  }
1037 
1038  // Convert null pointer constants.
1039  if (auto *nullPtr = dyn_cast<llvm::ConstantPointerNull>(constant)) {
1040  Type type = convertType(nullPtr->getType());
1041  return builder.create<ZeroOp>(loc, type).getResult();
1042  }
1043 
1044  // Convert none token constants.
1045  if (isa<llvm::ConstantTokenNone>(constant)) {
1046  return builder.create<NoneTokenOp>(loc).getResult();
1047  }
1048 
1049  // Convert poison.
1050  if (auto *poisonVal = dyn_cast<llvm::PoisonValue>(constant)) {
1051  Type type = convertType(poisonVal->getType());
1052  return builder.create<PoisonOp>(loc, type).getResult();
1053  }
1054 
1055  // Convert undef.
1056  if (auto *undefVal = dyn_cast<llvm::UndefValue>(constant)) {
1057  Type type = convertType(undefVal->getType());
1058  return builder.create<UndefOp>(loc, type).getResult();
1059  }
1060 
1061  // Convert global variable accesses.
1062  if (auto *globalVar = dyn_cast<llvm::GlobalVariable>(constant)) {
1063  Type type = convertType(globalVar->getType());
1064  auto symbolRef = FlatSymbolRefAttr::get(context, globalVar->getName());
1065  return builder.create<AddressOfOp>(loc, type, symbolRef).getResult();
1066  }
1067 
1068  // Convert constant expressions.
1069  if (auto *constExpr = dyn_cast<llvm::ConstantExpr>(constant)) {
1070  // Convert the constant expression to a temporary LLVM instruction and
1071  // translate it using the `processInstruction` method. Delete the
1072  // instruction after the translation and remove it from `valueMapping`,
1073  // since later calls to `getAsInstruction` may return the same address
1074  // resulting in a conflicting `valueMapping` entry.
1075  llvm::Instruction *inst = constExpr->getAsInstruction();
1076  auto guard = llvm::make_scope_exit([&]() {
1077  assert(!noResultOpMapping.contains(inst) &&
1078  "expected constant expression to return a result");
1079  valueMapping.erase(inst);
1080  inst->deleteValue();
1081  });
1082  // Note: `processInstruction` does not call `convertConstant` recursively
1083  // since all constant dependencies have been converted before.
1084  assert(llvm::all_of(inst->operands(), [&](llvm::Value *value) {
1085  return valueMapping.contains(value);
1086  }));
1087  if (failed(processInstruction(inst)))
1088  return failure();
1089  return lookupValue(inst);
1090  }
1091 
1092  // Convert aggregate constants.
1093  if (isa<llvm::ConstantAggregate>(constant) ||
1094  isa<llvm::ConstantAggregateZero>(constant)) {
1095  // Lookup the aggregate elements that have been converted before.
1096  SmallVector<Value> elementValues;
1097  if (auto *constAgg = dyn_cast<llvm::ConstantAggregate>(constant)) {
1098  elementValues.reserve(constAgg->getNumOperands());
1099  for (llvm::Value *operand : constAgg->operands())
1100  elementValues.push_back(lookupValue(operand));
1101  }
1102  if (auto *constAgg = dyn_cast<llvm::ConstantAggregateZero>(constant)) {
1103  unsigned numElements = constAgg->getElementCount().getFixedValue();
1104  elementValues.reserve(numElements);
1105  for (unsigned i = 0, e = numElements; i != e; ++i)
1106  elementValues.push_back(lookupValue(constAgg->getElementValue(i)));
1107  }
1108  assert(llvm::count(elementValues, nullptr) == 0 &&
1109  "expected all elements have been converted before");
1110 
1111  // Generate an UndefOp as root value and insert the aggregate elements.
1112  Type rootType = convertType(constant->getType());
1113  bool isArrayOrStruct = isa<LLVMArrayType, LLVMStructType>(rootType);
1114  assert((isArrayOrStruct || LLVM::isCompatibleVectorType(rootType)) &&
1115  "unrecognized aggregate type");
1116  Value root = builder.create<UndefOp>(loc, rootType);
1117  for (const auto &it : llvm::enumerate(elementValues)) {
1118  if (isArrayOrStruct) {
1119  root = builder.create<InsertValueOp>(loc, root, it.value(), it.index());
1120  } else {
1121  Attribute indexAttr = builder.getI32IntegerAttr(it.index());
1122  Value indexValue =
1123  builder.create<ConstantOp>(loc, builder.getI32Type(), indexAttr);
1124  root = builder.create<InsertElementOp>(loc, rootType, root, it.value(),
1125  indexValue);
1126  }
1127  }
1128  return root;
1129  }
1130 
1131  if (auto *constTargetNone = dyn_cast<llvm::ConstantTargetNone>(constant)) {
1132  LLVMTargetExtType targetExtType =
1133  cast<LLVMTargetExtType>(convertType(constTargetNone->getType()));
1134  assert(targetExtType.hasProperty(LLVMTargetExtType::HasZeroInit) &&
1135  "target extension type does not support zero-initialization");
1136  // Create llvm.mlir.zero operation to represent zero-initialization of
1137  // target extension type.
1138  return builder.create<LLVM::ZeroOp>(loc, targetExtType).getRes();
1139  }
1140 
1141  StringRef error = "";
1142  if (isa<llvm::BlockAddress>(constant))
1143  error = " since blockaddress(...) is unsupported";
1144 
1145  return emitError(loc) << "unhandled constant: " << diag(*constant) << error;
1146 }
1147 
1148 FailureOr<Value> ModuleImport::convertConstantExpr(llvm::Constant *constant) {
1149  // Only call the function for constants that have not been translated before
1150  // since it updates the constant insertion point assuming the converted
1151  // constant has been introduced at the end of the constant section.
1152  assert(!valueMapping.contains(constant) &&
1153  "expected constant has not been converted before");
1154  assert(constantInsertionBlock &&
1155  "expected the constant insertion block to be non-null");
1156 
1157  // Insert the constant after the last one or at the start of the entry block.
1158  OpBuilder::InsertionGuard guard(builder);
1159  if (!constantInsertionOp)
1160  builder.setInsertionPointToStart(constantInsertionBlock);
1161  else
1162  builder.setInsertionPointAfter(constantInsertionOp);
1163 
1164  // Convert all constants of the expression and add them to `valueMapping`.
1165  SetVector<llvm::Constant *> constantsToConvert =
1166  getConstantsToConvert(constant);
1167  for (llvm::Constant *constantToConvert : constantsToConvert) {
1168  FailureOr<Value> converted = convertConstant(constantToConvert);
1169  if (failed(converted))
1170  return failure();
1171  mapValue(constantToConvert, *converted);
1172  }
1173 
1174  // Update the constant insertion point and return the converted constant.
1175  Value result = lookupValue(constant);
1176  constantInsertionOp = result.getDefiningOp();
1177  return result;
1178 }
1179 
1180 FailureOr<Value> ModuleImport::convertValue(llvm::Value *value) {
1181  assert(!isa<llvm::MetadataAsValue>(value) &&
1182  "expected value to not be metadata");
1183 
1184  // Return the mapped value if it has been converted before.
1185  auto it = valueMapping.find(value);
1186  if (it != valueMapping.end())
1187  return it->getSecond();
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 
1193  Location loc = UnknownLoc::get(context);
1194  if (auto *inst = dyn_cast<llvm::Instruction>(value))
1195  loc = translateLoc(inst->getDebugLoc());
1196  return emitError(loc) << "unhandled value: " << diag(*value);
1197 }
1198 
1199 FailureOr<Value> ModuleImport::convertMetadataValue(llvm::Value *value) {
1200  // A value may be wrapped as metadata, for example, when passed to a debug
1201  // intrinsic. Unwrap these values before the conversion.
1202  auto *nodeAsVal = dyn_cast<llvm::MetadataAsValue>(value);
1203  if (!nodeAsVal)
1204  return failure();
1205  auto *node = dyn_cast<llvm::ValueAsMetadata>(nodeAsVal->getMetadata());
1206  if (!node)
1207  return failure();
1208  value = node->getValue();
1209 
1210  // Return the mapped value if it has been converted before.
1211  auto it = valueMapping.find(value);
1212  if (it != valueMapping.end())
1213  return it->getSecond();
1214 
1215  // Convert constants such as immediate values that have no mapping yet.
1216  if (auto *constant = dyn_cast<llvm::Constant>(value))
1217  return convertConstantExpr(constant);
1218  return failure();
1219 }
1220 
1221 FailureOr<SmallVector<Value>>
1223  SmallVector<Value> remapped;
1224  remapped.reserve(values.size());
1225  for (llvm::Value *value : values) {
1226  FailureOr<Value> converted = convertValue(value);
1227  if (failed(converted))
1228  return failure();
1229  remapped.push_back(*converted);
1230  }
1231  return remapped;
1232 }
1233 
1235  ArrayRef<llvm::Value *> values, ArrayRef<unsigned> immArgPositions,
1236  ArrayRef<StringLiteral> immArgAttrNames, SmallVectorImpl<Value> &valuesOut,
1237  SmallVectorImpl<NamedAttribute> &attrsOut) {
1238  assert(immArgPositions.size() == immArgAttrNames.size() &&
1239  "LLVM `immArgPositions` and MLIR `immArgAttrNames` should have equal "
1240  "length");
1241 
1242  SmallVector<llvm::Value *> operands(values);
1243  for (auto [immArgPos, immArgName] :
1244  llvm::zip(immArgPositions, immArgAttrNames)) {
1245  auto &value = operands[immArgPos];
1246  auto *constant = llvm::cast<llvm::Constant>(value);
1247  auto attr = getScalarConstantAsAttr(builder, constant);
1248  assert(attr && attr.getType().isIntOrFloat() &&
1249  "expected immarg to be float or integer constant");
1250  auto nameAttr = StringAttr::get(attr.getContext(), immArgName);
1251  attrsOut.push_back({nameAttr, attr});
1252  // Mark matched attribute values as null (so they can be removed below).
1253  value = nullptr;
1254  }
1255 
1256  for (llvm::Value *value : operands) {
1257  if (!value)
1258  continue;
1259  auto mlirValue = convertValue(value);
1260  if (failed(mlirValue))
1261  return failure();
1262  valuesOut.push_back(*mlirValue);
1263  }
1264 
1265  return success();
1266 }
1267 
1268 IntegerAttr ModuleImport::matchIntegerAttr(llvm::Value *value) {
1269  IntegerAttr integerAttr;
1270  FailureOr<Value> converted = convertValue(value);
1271  bool success = succeeded(converted) &&
1272  matchPattern(*converted, m_Constant(&integerAttr));
1273  assert(success && "expected a constant integer value");
1274  (void)success;
1275  return integerAttr;
1276 }
1277 
1278 FloatAttr ModuleImport::matchFloatAttr(llvm::Value *value) {
1279  FloatAttr floatAttr;
1280  FailureOr<Value> converted = convertValue(value);
1281  bool success =
1282  succeeded(converted) && matchPattern(*converted, m_Constant(&floatAttr));
1283  assert(success && "expected a constant float value");
1284  (void)success;
1285  return floatAttr;
1286 }
1287 
1288 DILocalVariableAttr ModuleImport::matchLocalVariableAttr(llvm::Value *value) {
1289  auto *nodeAsVal = cast<llvm::MetadataAsValue>(value);
1290  auto *node = cast<llvm::DILocalVariable>(nodeAsVal->getMetadata());
1291  return debugImporter->translate(node);
1292 }
1293 
1294 DILabelAttr ModuleImport::matchLabelAttr(llvm::Value *value) {
1295  auto *nodeAsVal = cast<llvm::MetadataAsValue>(value);
1296  auto *node = cast<llvm::DILabel>(nodeAsVal->getMetadata());
1297  return debugImporter->translate(node);
1298 }
1299 
1300 FPExceptionBehaviorAttr
1302  auto *metadata = cast<llvm::MetadataAsValue>(value);
1303  auto *mdstr = cast<llvm::MDString>(metadata->getMetadata());
1304  std::optional<llvm::fp::ExceptionBehavior> optLLVM =
1305  llvm::convertStrToExceptionBehavior(mdstr->getString());
1306  assert(optLLVM && "Expecting FP exception behavior");
1307  return builder.getAttr<FPExceptionBehaviorAttr>(
1308  convertFPExceptionBehaviorFromLLVM(*optLLVM));
1309 }
1310 
1311 RoundingModeAttr ModuleImport::matchRoundingModeAttr(llvm::Value *value) {
1312  auto *metadata = cast<llvm::MetadataAsValue>(value);
1313  auto *mdstr = cast<llvm::MDString>(metadata->getMetadata());
1314  std::optional<llvm::RoundingMode> optLLVM =
1315  llvm::convertStrToRoundingMode(mdstr->getString());
1316  assert(optLLVM && "Expecting rounding mode");
1317  return builder.getAttr<RoundingModeAttr>(
1318  convertRoundingModeFromLLVM(*optLLVM));
1319 }
1320 
1321 FailureOr<SmallVector<AliasScopeAttr>>
1323  auto *nodeAsVal = cast<llvm::MetadataAsValue>(value);
1324  auto *node = cast<llvm::MDNode>(nodeAsVal->getMetadata());
1325  return lookupAliasScopeAttrs(node);
1326 }
1327 
1328 Location ModuleImport::translateLoc(llvm::DILocation *loc) {
1329  return debugImporter->translateLoc(loc);
1330 }
1331 
1332 LogicalResult
1333 ModuleImport::convertBranchArgs(llvm::Instruction *branch,
1334  llvm::BasicBlock *target,
1335  SmallVectorImpl<Value> &blockArguments) {
1336  for (auto inst = target->begin(); isa<llvm::PHINode>(inst); ++inst) {
1337  auto *phiInst = cast<llvm::PHINode>(&*inst);
1338  llvm::Value *value = phiInst->getIncomingValueForBlock(branch->getParent());
1339  FailureOr<Value> converted = convertValue(value);
1340  if (failed(converted))
1341  return failure();
1342  blockArguments.push_back(*converted);
1343  }
1344  return success();
1345 }
1346 
1347 LogicalResult
1348 ModuleImport::convertCallTypeAndOperands(llvm::CallBase *callInst,
1349  SmallVectorImpl<Type> &types,
1350  SmallVectorImpl<Value> &operands) {
1351  if (!callInst->getType()->isVoidTy())
1352  types.push_back(convertType(callInst->getType()));
1353 
1354  if (!callInst->getCalledFunction()) {
1355  FailureOr<Value> called = convertValue(callInst->getCalledOperand());
1356  if (failed(called))
1357  return failure();
1358  operands.push_back(*called);
1359  }
1360  SmallVector<llvm::Value *> args(callInst->args());
1361  FailureOr<SmallVector<Value>> arguments = convertValues(args);
1362  if (failed(arguments))
1363  return failure();
1364  llvm::append_range(operands, *arguments);
1365  return success();
1366 }
1367 
1368 LogicalResult ModuleImport::convertIntrinsic(llvm::CallInst *inst) {
1369  if (succeeded(iface.convertIntrinsic(builder, inst, *this)))
1370  return success();
1371 
1372  Location loc = translateLoc(inst->getDebugLoc());
1373  return emitError(loc) << "unhandled intrinsic: " << diag(*inst);
1374 }
1375 
1376 LogicalResult ModuleImport::convertInstruction(llvm::Instruction *inst) {
1377  // Convert all instructions that do not provide an MLIR builder.
1378  Location loc = translateLoc(inst->getDebugLoc());
1379  if (inst->getOpcode() == llvm::Instruction::Br) {
1380  auto *brInst = cast<llvm::BranchInst>(inst);
1381 
1382  SmallVector<Block *> succBlocks;
1383  SmallVector<SmallVector<Value>> succBlockArgs;
1384  for (auto i : llvm::seq<unsigned>(0, brInst->getNumSuccessors())) {
1385  llvm::BasicBlock *succ = brInst->getSuccessor(i);
1386  SmallVector<Value> blockArgs;
1387  if (failed(convertBranchArgs(brInst, succ, blockArgs)))
1388  return failure();
1389  succBlocks.push_back(lookupBlock(succ));
1390  succBlockArgs.push_back(blockArgs);
1391  }
1392 
1393  if (!brInst->isConditional()) {
1394  auto brOp = builder.create<LLVM::BrOp>(loc, succBlockArgs.front(),
1395  succBlocks.front());
1396  mapNoResultOp(inst, brOp);
1397  return success();
1398  }
1399  FailureOr<Value> condition = convertValue(brInst->getCondition());
1400  if (failed(condition))
1401  return failure();
1402  auto condBrOp = builder.create<LLVM::CondBrOp>(
1403  loc, *condition, succBlocks.front(), succBlockArgs.front(),
1404  succBlocks.back(), succBlockArgs.back());
1405  mapNoResultOp(inst, condBrOp);
1406  return success();
1407  }
1408  if (inst->getOpcode() == llvm::Instruction::Switch) {
1409  auto *swInst = cast<llvm::SwitchInst>(inst);
1410  // Process the condition value.
1411  FailureOr<Value> condition = convertValue(swInst->getCondition());
1412  if (failed(condition))
1413  return failure();
1414  SmallVector<Value> defaultBlockArgs;
1415  // Process the default case.
1416  llvm::BasicBlock *defaultBB = swInst->getDefaultDest();
1417  if (failed(convertBranchArgs(swInst, defaultBB, defaultBlockArgs)))
1418  return failure();
1419 
1420  // Process the cases.
1421  unsigned numCases = swInst->getNumCases();
1422  SmallVector<SmallVector<Value>> caseOperands(numCases);
1423  SmallVector<ValueRange> caseOperandRefs(numCases);
1424  SmallVector<APInt> caseValues(numCases);
1425  SmallVector<Block *> caseBlocks(numCases);
1426  for (const auto &it : llvm::enumerate(swInst->cases())) {
1427  const llvm::SwitchInst::CaseHandle &caseHandle = it.value();
1428  llvm::BasicBlock *succBB = caseHandle.getCaseSuccessor();
1429  if (failed(convertBranchArgs(swInst, succBB, caseOperands[it.index()])))
1430  return failure();
1431  caseOperandRefs[it.index()] = caseOperands[it.index()];
1432  caseValues[it.index()] = caseHandle.getCaseValue()->getValue();
1433  caseBlocks[it.index()] = lookupBlock(succBB);
1434  }
1435 
1436  auto switchOp = builder.create<SwitchOp>(
1437  loc, *condition, lookupBlock(defaultBB), defaultBlockArgs, caseValues,
1438  caseBlocks, caseOperandRefs);
1439  mapNoResultOp(inst, switchOp);
1440  return success();
1441  }
1442  if (inst->getOpcode() == llvm::Instruction::PHI) {
1443  Type type = convertType(inst->getType());
1444  mapValue(inst, builder.getInsertionBlock()->addArgument(
1445  type, translateLoc(inst->getDebugLoc())));
1446  return success();
1447  }
1448  if (inst->getOpcode() == llvm::Instruction::Call) {
1449  auto *callInst = cast<llvm::CallInst>(inst);
1450 
1451  SmallVector<Type> types;
1452  SmallVector<Value> operands;
1453  if (failed(convertCallTypeAndOperands(callInst, types, operands)))
1454  return failure();
1455 
1456  auto funcTy =
1457  dyn_cast<LLVMFunctionType>(convertType(callInst->getFunctionType()));
1458  if (!funcTy)
1459  return failure();
1460 
1461  CallOp callOp;
1462 
1463  if (llvm::Function *callee = callInst->getCalledFunction()) {
1464  callOp = builder.create<CallOp>(
1465  loc, funcTy, SymbolRefAttr::get(context, callee->getName()),
1466  operands);
1467  } else {
1468  callOp = builder.create<CallOp>(loc, funcTy, operands);
1469  }
1470  callOp.setCConv(convertCConvFromLLVM(callInst->getCallingConv()));
1471  callOp.setTailCallKind(
1472  convertTailCallKindFromLLVM(callInst->getTailCallKind()));
1473  setFastmathFlagsAttr(inst, callOp);
1474 
1475  // Handle function attributes.
1476  if (callInst->hasFnAttr(llvm::Attribute::Convergent))
1477  callOp.setConvergent(true);
1478  if (callInst->hasFnAttr(llvm::Attribute::NoUnwind))
1479  callOp.setNoUnwind(true);
1480  if (callInst->hasFnAttr(llvm::Attribute::WillReturn))
1481  callOp.setWillReturn(true);
1482 
1483  llvm::MemoryEffects memEffects = callInst->getMemoryEffects();
1484  ModRefInfo othermem = convertModRefInfoFromLLVM(
1485  memEffects.getModRef(llvm::MemoryEffects::Location::Other));
1486  ModRefInfo argMem = convertModRefInfoFromLLVM(
1487  memEffects.getModRef(llvm::MemoryEffects::Location::ArgMem));
1488  ModRefInfo inaccessibleMem = convertModRefInfoFromLLVM(
1489  memEffects.getModRef(llvm::MemoryEffects::Location::InaccessibleMem));
1490  auto memAttr = MemoryEffectsAttr::get(callOp.getContext(), othermem, argMem,
1491  inaccessibleMem);
1492  // Only set the attribute when it does not match the default value.
1493  if (!memAttr.isReadWrite())
1494  callOp.setMemoryEffectsAttr(memAttr);
1495 
1496  if (!callInst->getType()->isVoidTy())
1497  mapValue(inst, callOp.getResult());
1498  else
1499  mapNoResultOp(inst, callOp);
1500  return success();
1501  }
1502  if (inst->getOpcode() == llvm::Instruction::LandingPad) {
1503  auto *lpInst = cast<llvm::LandingPadInst>(inst);
1504 
1505  SmallVector<Value> operands;
1506  operands.reserve(lpInst->getNumClauses());
1507  for (auto i : llvm::seq<unsigned>(0, lpInst->getNumClauses())) {
1508  FailureOr<Value> operand = convertValue(lpInst->getClause(i));
1509  if (failed(operand))
1510  return failure();
1511  operands.push_back(*operand);
1512  }
1513 
1514  Type type = convertType(lpInst->getType());
1515  auto lpOp =
1516  builder.create<LandingpadOp>(loc, type, lpInst->isCleanup(), operands);
1517  mapValue(inst, lpOp);
1518  return success();
1519  }
1520  if (inst->getOpcode() == llvm::Instruction::Invoke) {
1521  auto *invokeInst = cast<llvm::InvokeInst>(inst);
1522 
1523  SmallVector<Type> types;
1524  SmallVector<Value> operands;
1525  if (failed(convertCallTypeAndOperands(invokeInst, types, operands)))
1526  return failure();
1527 
1528  // Check whether the invoke result is an argument to the normal destination
1529  // block.
1530  bool invokeResultUsedInPhi = llvm::any_of(
1531  invokeInst->getNormalDest()->phis(), [&](const llvm::PHINode &phi) {
1532  return phi.getIncomingValueForBlock(invokeInst->getParent()) ==
1533  invokeInst;
1534  });
1535 
1536  Block *normalDest = lookupBlock(invokeInst->getNormalDest());
1537  Block *directNormalDest = normalDest;
1538  if (invokeResultUsedInPhi) {
1539  // The invoke result cannot be an argument to the normal destination
1540  // block, as that would imply using the invoke operation result in its
1541  // definition, so we need to create a dummy block to serve as an
1542  // intermediate destination.
1543  OpBuilder::InsertionGuard g(builder);
1544  directNormalDest = builder.createBlock(normalDest);
1545  }
1546 
1547  SmallVector<Value> unwindArgs;
1548  if (failed(convertBranchArgs(invokeInst, invokeInst->getUnwindDest(),
1549  unwindArgs)))
1550  return failure();
1551 
1552  auto funcTy =
1553  dyn_cast<LLVMFunctionType>(convertType(invokeInst->getFunctionType()));
1554  if (!funcTy)
1555  return failure();
1556 
1557  // Create the invoke operation. Normal destination block arguments will be
1558  // added later on to handle the case in which the operation result is
1559  // included in this list.
1560  InvokeOp invokeOp;
1561  if (llvm::Function *callee = invokeInst->getCalledFunction()) {
1562  invokeOp = builder.create<InvokeOp>(
1563  loc, funcTy,
1564  SymbolRefAttr::get(builder.getContext(), callee->getName()), operands,
1565  directNormalDest, ValueRange(),
1566  lookupBlock(invokeInst->getUnwindDest()), unwindArgs);
1567  } else {
1568  invokeOp = builder.create<InvokeOp>(
1569  loc, funcTy, /*callee=*/nullptr, operands, directNormalDest,
1570  ValueRange(), lookupBlock(invokeInst->getUnwindDest()), unwindArgs);
1571  }
1572  invokeOp.setCConv(convertCConvFromLLVM(invokeInst->getCallingConv()));
1573  if (!invokeInst->getType()->isVoidTy())
1574  mapValue(inst, invokeOp.getResults().front());
1575  else
1576  mapNoResultOp(inst, invokeOp);
1577 
1578  SmallVector<Value> normalArgs;
1579  if (failed(convertBranchArgs(invokeInst, invokeInst->getNormalDest(),
1580  normalArgs)))
1581  return failure();
1582 
1583  if (invokeResultUsedInPhi) {
1584  // The dummy normal dest block will just host an unconditional branch
1585  // instruction to the normal destination block passing the required block
1586  // arguments (including the invoke operation's result).
1587  OpBuilder::InsertionGuard g(builder);
1588  builder.setInsertionPointToStart(directNormalDest);
1589  builder.create<LLVM::BrOp>(loc, normalArgs, normalDest);
1590  } else {
1591  // If the invoke operation's result is not a block argument to the normal
1592  // destination block, just add the block arguments as usual.
1593  assert(llvm::none_of(
1594  normalArgs,
1595  [&](Value val) { return val.getDefiningOp() == invokeOp; }) &&
1596  "An llvm.invoke operation cannot pass its result as a block "
1597  "argument.");
1598  invokeOp.getNormalDestOperandsMutable().append(normalArgs);
1599  }
1600 
1601  return success();
1602  }
1603  if (inst->getOpcode() == llvm::Instruction::GetElementPtr) {
1604  auto *gepInst = cast<llvm::GetElementPtrInst>(inst);
1605  Type sourceElementType = convertType(gepInst->getSourceElementType());
1606  FailureOr<Value> basePtr = convertValue(gepInst->getOperand(0));
1607  if (failed(basePtr))
1608  return failure();
1609 
1610  // Treat every indices as dynamic since GEPOp::build will refine those
1611  // indices into static attributes later. One small downside of this
1612  // approach is that many unused `llvm.mlir.constant` would be emitted
1613  // at first place.
1614  SmallVector<GEPArg> indices;
1615  for (llvm::Value *operand : llvm::drop_begin(gepInst->operand_values())) {
1616  FailureOr<Value> index = convertValue(operand);
1617  if (failed(index))
1618  return failure();
1619  indices.push_back(*index);
1620  }
1621 
1622  Type type = convertType(inst->getType());
1623  auto gepOp = builder.create<GEPOp>(loc, type, sourceElementType, *basePtr,
1624  indices, gepInst->isInBounds());
1625  mapValue(inst, gepOp);
1626  return success();
1627  }
1628 
1629  // Convert all instructions that have an mlirBuilder.
1630  if (succeeded(convertInstructionImpl(builder, inst, *this, iface)))
1631  return success();
1632 
1633  return emitError(loc) << "unhandled instruction: " << diag(*inst);
1634 }
1635 
1636 LogicalResult ModuleImport::processInstruction(llvm::Instruction *inst) {
1637  // FIXME: Support uses of SubtargetData.
1638  // FIXME: Add support for call / operand attributes.
1639  // FIXME: Add support for the indirectbr, cleanupret, catchret, catchswitch,
1640  // callbr, vaarg, catchpad, cleanuppad instructions.
1641 
1642  // Convert LLVM intrinsics calls to MLIR intrinsics.
1643  if (auto *intrinsic = dyn_cast<llvm::IntrinsicInst>(inst))
1644  return convertIntrinsic(intrinsic);
1645 
1646  // Convert all remaining LLVM instructions to MLIR operations.
1647  return convertInstruction(inst);
1648 }
1649 
1650 FlatSymbolRefAttr ModuleImport::getPersonalityAsAttr(llvm::Function *f) {
1651  if (!f->hasPersonalityFn())
1652  return nullptr;
1653 
1654  llvm::Constant *pf = f->getPersonalityFn();
1655 
1656  // If it directly has a name, we can use it.
1657  if (pf->hasName())
1658  return SymbolRefAttr::get(builder.getContext(), pf->getName());
1659 
1660  // If it doesn't have a name, currently, only function pointers that are
1661  // bitcast to i8* are parsed.
1662  if (auto *ce = dyn_cast<llvm::ConstantExpr>(pf)) {
1663  if (ce->getOpcode() == llvm::Instruction::BitCast &&
1664  ce->getType() == llvm::PointerType::getUnqual(f->getContext())) {
1665  if (auto *func = dyn_cast<llvm::Function>(ce->getOperand(0)))
1666  return SymbolRefAttr::get(builder.getContext(), func->getName());
1667  }
1668  }
1669  return FlatSymbolRefAttr();
1670 }
1671 
1672 static void processMemoryEffects(llvm::Function *func, LLVMFuncOp funcOp) {
1673  llvm::MemoryEffects memEffects = func->getMemoryEffects();
1674 
1675  auto othermem = convertModRefInfoFromLLVM(
1676  memEffects.getModRef(llvm::MemoryEffects::Location::Other));
1677  auto argMem = convertModRefInfoFromLLVM(
1678  memEffects.getModRef(llvm::MemoryEffects::Location::ArgMem));
1679  auto inaccessibleMem = convertModRefInfoFromLLVM(
1680  memEffects.getModRef(llvm::MemoryEffects::Location::InaccessibleMem));
1681  auto memAttr = MemoryEffectsAttr::get(funcOp.getContext(), othermem, argMem,
1682  inaccessibleMem);
1683  // Only set the attr when it does not match the default value.
1684  if (memAttr.isReadWrite())
1685  return;
1686  funcOp.setMemoryEffectsAttr(memAttr);
1687 }
1688 
1689 // List of LLVM IR attributes that map to an explicit attribute on the MLIR
1690 // LLVMFuncOp.
1691 static constexpr std::array kExplicitAttributes{
1692  StringLiteral("aarch64_in_za"),
1693  StringLiteral("aarch64_inout_za"),
1694  StringLiteral("aarch64_new_za"),
1695  StringLiteral("aarch64_out_za"),
1696  StringLiteral("aarch64_preserves_za"),
1697  StringLiteral("aarch64_pstate_sm_body"),
1698  StringLiteral("aarch64_pstate_sm_compatible"),
1699  StringLiteral("aarch64_pstate_sm_enabled"),
1700  StringLiteral("alwaysinline"),
1701  StringLiteral("approx-func-fp-math"),
1702  StringLiteral("convergent"),
1703  StringLiteral("denormal-fp-math"),
1704  StringLiteral("denormal-fp-math-f32"),
1705  StringLiteral("fp-contract"),
1706  StringLiteral("frame-pointer"),
1707  StringLiteral("no-infs-fp-math"),
1708  StringLiteral("no-nans-fp-math"),
1709  StringLiteral("no-signed-zeros-fp-math"),
1710  StringLiteral("noinline"),
1711  StringLiteral("nounwind"),
1712  StringLiteral("optnone"),
1713  StringLiteral("target-features"),
1714  StringLiteral("tune-cpu"),
1715  StringLiteral("unsafe-fp-math"),
1716  StringLiteral("vscale_range"),
1717  StringLiteral("willreturn"),
1718 };
1719 
1720 static void processPassthroughAttrs(llvm::Function *func, LLVMFuncOp funcOp) {
1721  MLIRContext *context = funcOp.getContext();
1722  SmallVector<Attribute> passthroughs;
1723  llvm::AttributeSet funcAttrs = func->getAttributes().getAttributes(
1724  llvm::AttributeList::AttrIndex::FunctionIndex);
1725  for (llvm::Attribute attr : funcAttrs) {
1726  // Skip the memory attribute since the LLVMFuncOp has an explicit memory
1727  // attribute.
1728  if (attr.hasAttribute(llvm::Attribute::Memory))
1729  continue;
1730 
1731  // Skip invalid type attributes.
1732  if (attr.isTypeAttribute()) {
1733  emitWarning(funcOp.getLoc(),
1734  "type attributes on a function are invalid, skipping it");
1735  continue;
1736  }
1737 
1738  StringRef attrName;
1739  if (attr.isStringAttribute())
1740  attrName = attr.getKindAsString();
1741  else
1742  attrName = llvm::Attribute::getNameFromAttrKind(attr.getKindAsEnum());
1743  auto keyAttr = StringAttr::get(context, attrName);
1744 
1745  // Skip attributes that map to an explicit attribute on the LLVMFuncOp.
1746  if (llvm::is_contained(kExplicitAttributes, attrName))
1747  continue;
1748 
1749  if (attr.isStringAttribute()) {
1750  StringRef val = attr.getValueAsString();
1751  if (val.empty()) {
1752  passthroughs.push_back(keyAttr);
1753  continue;
1754  }
1755  passthroughs.push_back(
1756  ArrayAttr::get(context, {keyAttr, StringAttr::get(context, val)}));
1757  continue;
1758  }
1759  if (attr.isIntAttribute()) {
1760  auto val = std::to_string(attr.getValueAsInt());
1761  passthroughs.push_back(
1762  ArrayAttr::get(context, {keyAttr, StringAttr::get(context, val)}));
1763  continue;
1764  }
1765  if (attr.isEnumAttribute()) {
1766  passthroughs.push_back(keyAttr);
1767  continue;
1768  }
1769 
1770  llvm_unreachable("unexpected attribute kind");
1771  }
1772 
1773  if (!passthroughs.empty())
1774  funcOp.setPassthroughAttr(ArrayAttr::get(context, passthroughs));
1775 }
1776 
1778  LLVMFuncOp funcOp) {
1779  processMemoryEffects(func, funcOp);
1780  processPassthroughAttrs(func, funcOp);
1781 
1782  if (func->hasFnAttribute(llvm::Attribute::NoInline))
1783  funcOp.setNoInline(true);
1784  if (func->hasFnAttribute(llvm::Attribute::AlwaysInline))
1785  funcOp.setAlwaysInline(true);
1786  if (func->hasFnAttribute(llvm::Attribute::OptimizeNone))
1787  funcOp.setOptimizeNone(true);
1788  if (func->hasFnAttribute(llvm::Attribute::Convergent))
1789  funcOp.setConvergent(true);
1790  if (func->hasFnAttribute(llvm::Attribute::NoUnwind))
1791  funcOp.setNoUnwind(true);
1792  if (func->hasFnAttribute(llvm::Attribute::WillReturn))
1793  funcOp.setWillReturn(true);
1794 
1795  if (func->hasFnAttribute("aarch64_pstate_sm_enabled"))
1796  funcOp.setArmStreaming(true);
1797  else if (func->hasFnAttribute("aarch64_pstate_sm_body"))
1798  funcOp.setArmLocallyStreaming(true);
1799  else if (func->hasFnAttribute("aarch64_pstate_sm_compatible"))
1800  funcOp.setArmStreamingCompatible(true);
1801 
1802  if (func->hasFnAttribute("aarch64_new_za"))
1803  funcOp.setArmNewZa(true);
1804  else if (func->hasFnAttribute("aarch64_in_za"))
1805  funcOp.setArmInZa(true);
1806  else if (func->hasFnAttribute("aarch64_out_za"))
1807  funcOp.setArmOutZa(true);
1808  else if (func->hasFnAttribute("aarch64_inout_za"))
1809  funcOp.setArmInoutZa(true);
1810  else if (func->hasFnAttribute("aarch64_preserves_za"))
1811  funcOp.setArmPreservesZa(true);
1812 
1813  llvm::Attribute attr = func->getFnAttribute(llvm::Attribute::VScaleRange);
1814  if (attr.isValid()) {
1815  MLIRContext *context = funcOp.getContext();
1816  auto intTy = IntegerType::get(context, 32);
1817  funcOp.setVscaleRangeAttr(LLVM::VScaleRangeAttr::get(
1818  context, IntegerAttr::get(intTy, attr.getVScaleRangeMin()),
1819  IntegerAttr::get(intTy, attr.getVScaleRangeMax().value_or(0))));
1820  }
1821 
1822  // Process frame-pointer attribute.
1823  if (func->hasFnAttribute("frame-pointer")) {
1824  StringRef stringRefFramePointerKind =
1825  func->getFnAttribute("frame-pointer").getValueAsString();
1826  funcOp.setFramePointerAttr(LLVM::FramePointerKindAttr::get(
1827  funcOp.getContext(), LLVM::framePointerKind::symbolizeFramePointerKind(
1828  stringRefFramePointerKind)
1829  .value()));
1830  }
1831 
1832  if (llvm::Attribute attr = func->getFnAttribute("target-cpu");
1833  attr.isStringAttribute())
1834  funcOp.setTargetCpuAttr(StringAttr::get(context, attr.getValueAsString()));
1835 
1836  if (llvm::Attribute attr = func->getFnAttribute("tune-cpu");
1837  attr.isStringAttribute())
1838  funcOp.setTuneCpuAttr(StringAttr::get(context, attr.getValueAsString()));
1839 
1840  if (llvm::Attribute attr = func->getFnAttribute("target-features");
1841  attr.isStringAttribute())
1842  funcOp.setTargetFeaturesAttr(
1843  LLVM::TargetFeaturesAttr::get(context, attr.getValueAsString()));
1844 
1845  if (llvm::Attribute attr = func->getFnAttribute("unsafe-fp-math");
1846  attr.isStringAttribute())
1847  funcOp.setUnsafeFpMath(attr.getValueAsBool());
1848 
1849  if (llvm::Attribute attr = func->getFnAttribute("no-infs-fp-math");
1850  attr.isStringAttribute())
1851  funcOp.setNoInfsFpMath(attr.getValueAsBool());
1852 
1853  if (llvm::Attribute attr = func->getFnAttribute("no-nans-fp-math");
1854  attr.isStringAttribute())
1855  funcOp.setNoNansFpMath(attr.getValueAsBool());
1856 
1857  if (llvm::Attribute attr = func->getFnAttribute("approx-func-fp-math");
1858  attr.isStringAttribute())
1859  funcOp.setApproxFuncFpMath(attr.getValueAsBool());
1860 
1861  if (llvm::Attribute attr = func->getFnAttribute("no-signed-zeros-fp-math");
1862  attr.isStringAttribute())
1863  funcOp.setNoSignedZerosFpMath(attr.getValueAsBool());
1864 
1865  if (llvm::Attribute attr = func->getFnAttribute("denormal-fp-math");
1866  attr.isStringAttribute())
1867  funcOp.setDenormalFpMathAttr(
1868  StringAttr::get(context, attr.getValueAsString()));
1869 
1870  if (llvm::Attribute attr = func->getFnAttribute("denormal-fp-math-f32");
1871  attr.isStringAttribute())
1872  funcOp.setDenormalFpMathF32Attr(
1873  StringAttr::get(context, attr.getValueAsString()));
1874 
1875  if (llvm::Attribute attr = func->getFnAttribute("fp-contract");
1876  attr.isStringAttribute())
1877  funcOp.setFpContractAttr(StringAttr::get(context, attr.getValueAsString()));
1878 }
1879 
1880 DictionaryAttr
1881 ModuleImport::convertParameterAttribute(llvm::AttributeSet llvmParamAttrs,
1882  OpBuilder &builder) {
1883  SmallVector<NamedAttribute> paramAttrs;
1884  for (auto [llvmKind, mlirName] : getAttrKindToNameMapping()) {
1885  auto llvmAttr = llvmParamAttrs.getAttribute(llvmKind);
1886  // Skip attributes that are not attached.
1887  if (!llvmAttr.isValid())
1888  continue;
1889  Attribute mlirAttr;
1890  if (llvmAttr.isTypeAttribute())
1891  mlirAttr = TypeAttr::get(convertType(llvmAttr.getValueAsType()));
1892  else if (llvmAttr.isIntAttribute())
1893  mlirAttr = builder.getI64IntegerAttr(llvmAttr.getValueAsInt());
1894  else if (llvmAttr.isEnumAttribute())
1895  mlirAttr = builder.getUnitAttr();
1896  else
1897  llvm_unreachable("unexpected parameter attribute kind");
1898  paramAttrs.push_back(builder.getNamedAttr(mlirName, mlirAttr));
1899  }
1900 
1901  return builder.getDictionaryAttr(paramAttrs);
1902 }
1903 
1904 void ModuleImport::convertParameterAttributes(llvm::Function *func,
1905  LLVMFuncOp funcOp,
1906  OpBuilder &builder) {
1907  auto llvmAttrs = func->getAttributes();
1908  for (size_t i = 0, e = funcOp.getNumArguments(); i < e; ++i) {
1909  llvm::AttributeSet llvmArgAttrs = llvmAttrs.getParamAttrs(i);
1910  funcOp.setArgAttrs(i, convertParameterAttribute(llvmArgAttrs, builder));
1911  }
1912  // Convert the result attributes and attach them wrapped in an ArrayAttribute
1913  // to the funcOp.
1914  llvm::AttributeSet llvmResAttr = llvmAttrs.getRetAttrs();
1915  if (!llvmResAttr.hasAttributes())
1916  return;
1917  funcOp.setResAttrsAttr(
1918  builder.getArrayAttr(convertParameterAttribute(llvmResAttr, builder)));
1919 }
1920 
1921 LogicalResult ModuleImport::processFunction(llvm::Function *func) {
1922  clearRegionState();
1923 
1924  auto functionType =
1925  dyn_cast<LLVMFunctionType>(convertType(func->getFunctionType()));
1926  if (func->isIntrinsic() &&
1927  iface.isConvertibleIntrinsic(func->getIntrinsicID()))
1928  return success();
1929 
1930  bool dsoLocal = func->hasLocalLinkage();
1931  CConv cconv = convertCConvFromLLVM(func->getCallingConv());
1932 
1933  // Insert the function at the end of the module.
1934  OpBuilder::InsertionGuard guard(builder);
1935  builder.setInsertionPoint(mlirModule.getBody(), mlirModule.getBody()->end());
1936 
1937  Location loc = debugImporter->translateFuncLocation(func);
1938  LLVMFuncOp funcOp = builder.create<LLVMFuncOp>(
1939  loc, func->getName(), functionType,
1940  convertLinkageFromLLVM(func->getLinkage()), dsoLocal, cconv);
1941 
1942  convertParameterAttributes(func, funcOp, builder);
1943 
1944  if (FlatSymbolRefAttr personality = getPersonalityAsAttr(func))
1945  funcOp.setPersonalityAttr(personality);
1946  else if (func->hasPersonalityFn())
1947  emitWarning(funcOp.getLoc(), "could not deduce personality, skipping it");
1948 
1949  if (func->hasGC())
1950  funcOp.setGarbageCollector(StringRef(func->getGC()));
1951 
1952  if (func->hasAtLeastLocalUnnamedAddr())
1953  funcOp.setUnnamedAddr(convertUnnamedAddrFromLLVM(func->getUnnamedAddr()));
1954 
1955  if (func->hasSection())
1956  funcOp.setSection(StringRef(func->getSection()));
1957 
1958  funcOp.setVisibility_(convertVisibilityFromLLVM(func->getVisibility()));
1959 
1960  if (func->hasComdat())
1961  funcOp.setComdatAttr(comdatMapping.lookup(func->getComdat()));
1962 
1963  if (llvm::MaybeAlign maybeAlign = func->getAlign())
1964  funcOp.setAlignment(maybeAlign->value());
1965 
1966  // Handle Function attributes.
1967  processFunctionAttributes(func, funcOp);
1968 
1969  // Convert non-debug metadata by using the dialect interface.
1971  func->getAllMetadata(allMetadata);
1972  for (auto &[kind, node] : allMetadata) {
1973  if (!iface.isConvertibleMetadata(kind))
1974  continue;
1975  if (failed(iface.setMetadataAttrs(builder, kind, node, funcOp, *this))) {
1976  emitWarning(funcOp.getLoc())
1977  << "unhandled function metadata: " << diagMD(node, llvmModule.get())
1978  << " on " << diag(*func);
1979  }
1980  }
1981 
1982  if (func->isDeclaration())
1983  return success();
1984 
1985  // Collect the set of basic blocks reachable from the function's entry block.
1986  // This step is crucial as LLVM IR can contain unreachable blocks that
1987  // self-dominate. As a result, an operation might utilize a variable it
1988  // defines, which the import does not support. Given that MLIR lacks block
1989  // label support, we can safely remove unreachable blocks, as there are no
1990  // indirect branch instructions that could potentially target these blocks.
1991  llvm::df_iterator_default_set<llvm::BasicBlock *> reachable;
1992  for (llvm::BasicBlock *basicBlock : llvm::depth_first_ext(func, reachable))
1993  (void)basicBlock;
1994 
1995  // Eagerly create all reachable blocks.
1996  SmallVector<llvm::BasicBlock *> reachableBasicBlocks;
1997  for (llvm::BasicBlock &basicBlock : *func) {
1998  // Skip unreachable blocks.
1999  if (!reachable.contains(&basicBlock))
2000  continue;
2001  Region &body = funcOp.getBody();
2002  Block *block = builder.createBlock(&body, body.end());
2003  mapBlock(&basicBlock, block);
2004  reachableBasicBlocks.push_back(&basicBlock);
2005  }
2006 
2007  // Add function arguments to the entry block.
2008  for (const auto &it : llvm::enumerate(func->args())) {
2009  BlockArgument blockArg = funcOp.getFunctionBody().addArgument(
2010  functionType.getParamType(it.index()), funcOp.getLoc());
2011  mapValue(&it.value(), blockArg);
2012  }
2013 
2014  // Process the blocks in topological order. The ordered traversal ensures
2015  // operands defined in a dominating block have a valid mapping to an MLIR
2016  // value once a block is translated.
2018  getTopologicallySortedBlocks(reachableBasicBlocks);
2019  setConstantInsertionPointToStart(lookupBlock(blocks.front()));
2020  for (llvm::BasicBlock *basicBlock : blocks)
2021  if (failed(processBasicBlock(basicBlock, lookupBlock(basicBlock))))
2022  return failure();
2023 
2024  // Process the debug intrinsics that require a delayed conversion after
2025  // everything else was converted.
2026  if (failed(processDebugIntrinsics()))
2027  return failure();
2028 
2029  return success();
2030 }
2031 
2032 /// Checks if `dbgIntr` is a kill location that holds metadata instead of an SSA
2033 /// value.
2034 static bool isMetadataKillLocation(llvm::DbgVariableIntrinsic *dbgIntr) {
2035  if (!dbgIntr->isKillLocation())
2036  return false;
2037  llvm::Value *value = dbgIntr->getArgOperand(0);
2038  auto *nodeAsVal = dyn_cast<llvm::MetadataAsValue>(value);
2039  if (!nodeAsVal)
2040  return false;
2041  return !isa<llvm::ValueAsMetadata>(nodeAsVal->getMetadata());
2042 }
2043 
2044 LogicalResult
2045 ModuleImport::processDebugIntrinsic(llvm::DbgVariableIntrinsic *dbgIntr,
2046  DominanceInfo &domInfo) {
2047  Location loc = translateLoc(dbgIntr->getDebugLoc());
2048  auto emitUnsupportedWarning = [&]() {
2049  if (emitExpensiveWarnings)
2050  emitWarning(loc) << "dropped intrinsic: " << diag(*dbgIntr);
2051  return success();
2052  };
2053  // Drop debug intrinsics with arg lists.
2054  // TODO: Support debug intrinsics that have arg lists.
2055  if (dbgIntr->hasArgList())
2056  return emitUnsupportedWarning();
2057  // Kill locations can have metadata nodes as location operand. This
2058  // cannot be converted to poison as the type cannot be reconstructed.
2059  // TODO: find a way to support this case.
2060  if (isMetadataKillLocation(dbgIntr))
2061  return emitUnsupportedWarning();
2062  // Drop debug intrinsics if the associated variable information cannot be
2063  // translated due to cyclic debug metadata.
2064  // TODO: Support cyclic debug metadata.
2065  DILocalVariableAttr localVariableAttr =
2066  matchLocalVariableAttr(dbgIntr->getArgOperand(1));
2067  if (!localVariableAttr)
2068  return emitUnsupportedWarning();
2069  FailureOr<Value> argOperand = convertMetadataValue(dbgIntr->getArgOperand(0));
2070  if (failed(argOperand))
2071  return emitError(loc) << "failed to convert a debug intrinsic operand: "
2072  << diag(*dbgIntr);
2073 
2074  // Ensure that the debug instrinsic is inserted right after its operand is
2075  // defined. Otherwise, the operand might not necessarily dominate the
2076  // intrinsic. If the defining operation is a terminator, insert the intrinsic
2077  // into a dominated block.
2078  OpBuilder::InsertionGuard guard(builder);
2079  if (Operation *op = argOperand->getDefiningOp();
2080  op && op->hasTrait<OpTrait::IsTerminator>()) {
2081  // Find a dominated block that can hold the debug intrinsic.
2082  auto dominatedBlocks = domInfo.getNode(op->getBlock())->children();
2083  // If no block is dominated by the terminator, this intrinisc cannot be
2084  // converted.
2085  if (dominatedBlocks.empty())
2086  return emitUnsupportedWarning();
2087  // Set insertion point before the terminator, to avoid inserting something
2088  // before landingpads.
2089  Block *dominatedBlock = (*dominatedBlocks.begin())->getBlock();
2090  builder.setInsertionPoint(dominatedBlock->getTerminator());
2091  } else {
2092  builder.setInsertionPointAfterValue(*argOperand);
2093  }
2094  auto locationExprAttr =
2095  debugImporter->translateExpression(dbgIntr->getExpression());
2096  Operation *op =
2098  .Case([&](llvm::DbgDeclareInst *) {
2099  return builder.create<LLVM::DbgDeclareOp>(
2100  loc, *argOperand, localVariableAttr, locationExprAttr);
2101  })
2102  .Case([&](llvm::DbgValueInst *) {
2103  return builder.create<LLVM::DbgValueOp>(
2104  loc, *argOperand, localVariableAttr, locationExprAttr);
2105  });
2106  mapNoResultOp(dbgIntr, op);
2107  setNonDebugMetadataAttrs(dbgIntr, op);
2108  return success();
2109 }
2110 
2111 LogicalResult ModuleImport::processDebugIntrinsics() {
2112  DominanceInfo domInfo;
2113  for (llvm::Instruction *inst : debugIntrinsics) {
2114  auto *intrCall = cast<llvm::DbgVariableIntrinsic>(inst);
2115  if (failed(processDebugIntrinsic(intrCall, domInfo)))
2116  return failure();
2117  }
2118  return success();
2119 }
2120 
2121 LogicalResult ModuleImport::processBasicBlock(llvm::BasicBlock *bb,
2122  Block *block) {
2123  builder.setInsertionPointToStart(block);
2124  for (llvm::Instruction &inst : *bb) {
2125  if (failed(processInstruction(&inst)))
2126  return failure();
2127 
2128  // Skip additional processing when the instructions is a debug intrinsics
2129  // that was not yet converted.
2130  if (debugIntrinsics.contains(&inst))
2131  continue;
2132 
2133  // Set the non-debug metadata attributes on the imported operation and emit
2134  // a warning if an instruction other than a phi instruction is dropped
2135  // during the import.
2136  if (Operation *op = lookupOperation(&inst)) {
2137  setNonDebugMetadataAttrs(&inst, op);
2138  } else if (inst.getOpcode() != llvm::Instruction::PHI) {
2139  if (emitExpensiveWarnings) {
2140  Location loc = debugImporter->translateLoc(inst.getDebugLoc());
2141  emitWarning(loc) << "dropped instruction: " << diag(inst);
2142  }
2143  }
2144  }
2145  return success();
2146 }
2147 
2148 FailureOr<SmallVector<AccessGroupAttr>>
2149 ModuleImport::lookupAccessGroupAttrs(const llvm::MDNode *node) const {
2150  return loopAnnotationImporter->lookupAccessGroupAttrs(node);
2151 }
2152 
2153 LoopAnnotationAttr
2155  Location loc) const {
2156  return loopAnnotationImporter->translateLoopAnnotation(node, loc);
2157 }
2158 
2160 mlir::translateLLVMIRToModule(std::unique_ptr<llvm::Module> llvmModule,
2161  MLIRContext *context, bool emitExpensiveWarnings,
2162  bool dropDICompositeTypeElements) {
2163  // Preload all registered dialects to allow the import to iterate the
2164  // registered LLVMImportDialectInterface implementations and query the
2165  // supported LLVM IR constructs before starting the translation. Assumes the
2166  // LLVM and DLTI dialects that convert the core LLVM IR constructs have been
2167  // registered before.
2168  assert(llvm::is_contained(context->getAvailableDialects(),
2169  LLVMDialect::getDialectNamespace()));
2170  assert(llvm::is_contained(context->getAvailableDialects(),
2171  DLTIDialect::getDialectNamespace()));
2172  context->loadAllAvailableDialects();
2173  OwningOpRef<ModuleOp> module(ModuleOp::create(FileLineColLoc::get(
2174  StringAttr::get(context, llvmModule->getSourceFileName()), /*line=*/0,
2175  /*column=*/0)));
2176 
2177  ModuleImport moduleImport(module.get(), std::move(llvmModule),
2178  emitExpensiveWarnings, dropDICompositeTypeElements);
2179  if (failed(moduleImport.initializeImportInterface()))
2180  return {};
2181  if (failed(moduleImport.convertDataLayout()))
2182  return {};
2183  if (failed(moduleImport.convertComdats()))
2184  return {};
2185  if (failed(moduleImport.convertMetadata()))
2186  return {};
2187  if (failed(moduleImport.convertGlobals()))
2188  return {};
2189  if (failed(moduleImport.convertFunctions()))
2190  return {};
2191 
2192  return module;
2193 }
static MLIRContext * getContext(OpFoldResult val)
static SmallVector< int64_t > getPositionFromIndices(ArrayRef< unsigned > indices)
Converts an array of unsigned indices to a signed integer position array.
static constexpr std::array kExplicitAttributes
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 constexpr StringRef getGlobalDtorsVarName()
Returns the name of the global_dtors global variables.
static Type getVectorTypeForAttr(Type type, ArrayRef< int64_t > arrayShape={})
Returns type if it is a builtin integer or floating-point vector type that can be used to create an a...
static LogicalResult convertInstructionImpl(OpBuilder &odsBuilder, llvm::Instruction *inst, ModuleImport &moduleImport, LLVMImportInterface &iface)
Converts the LLVM instructions that have a generated MLIR builder.
static constexpr StringRef getGlobalComdatOpName()
Returns the symbol name for the module-level comdat operation.
static constexpr StringRef getGlobalCtorsVarName()
Returns the name of the global_ctors global variables.
static bool isMetadataKillLocation(llvm::DbgVariableIntrinsic *dbgIntr)
Checks if dbgIntr is a kill location that holds metadata instead of an SSA value.
static TypedAttr getScalarConstantAsAttr(OpBuilder &builder, llvm::Constant *constScalar)
Returns an integer or float attribute for the provided scalar constant constScalar or nullptr if the ...
static SetVector< llvm::BasicBlock * > getTopologicallySortedBlocks(ArrayRef< llvm::BasicBlock * > basicBlocks)
Get a topologically sorted list of blocks for the given basic blocks.
static std::string diagMD(const llvm::Metadata *node, const llvm::Module *module)
static bool isScalarType(Type type)
Returns if type is a scalar integer or floating-point type.
static SmallVector< Attribute > getSequenceConstantAsAttrs(OpBuilder &builder, llvm::ConstantDataSequential *constSequence)
Returns an integer or float attribute array for the provided constant sequence constSequence or nullp...
static llvm::ManagedStatic< PassManagerOptions > options
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
This class represents an argument of a Block.
Definition: Value.h:319
Block represents an ordered list of Operations.
Definition: Block.h:31
Operation * getTerminator()
Get the terminator operation of this block.
Definition: Block.cpp:243
BlockArgument addArgument(Type type, Location loc)
Add one value to the argument list.
Definition: Block.cpp:152
UnitAttr getUnitAttr()
Definition: Builders.cpp:118
IntegerAttr getI32IntegerAttr(int32_t value)
Definition: Builders.cpp:220
IntegerAttr getIntegerAttr(Type type, int64_t value)
Definition: Builders.cpp:242
ArrayAttr getI32ArrayAttr(ArrayRef< int32_t > values)
Definition: Builders.cpp:287
FloatAttr getFloatAttr(Type type, double value)
Definition: Builders.cpp:265
IntegerType getI32Type()
Definition: Builders.cpp:87
IntegerAttr getI64IntegerAttr(int64_t value)
Definition: Builders.cpp:132
StringAttr getStringAttr(const Twine &bytes)
Definition: Builders.cpp:273
TypedAttr getZeroAttr(Type type)
Definition: Builders.cpp:335
MLIRContext * getContext() const
Definition: Builders.h:55
ArrayAttr getArrayAttr(ArrayRef< Attribute > value)
Definition: Builders.cpp:277
DictionaryAttr getDictionaryAttr(ArrayRef< NamedAttribute > value)
Definition: Builders.cpp:124
NamedAttribute getNamedAttr(StringRef name, Attribute val)
Definition: Builders.cpp:114
ArrayAttr getStrArrayAttr(ArrayRef< StringRef > values)
Definition: Builders.cpp:317
Attr getAttr(Args &&...args)
Get or construct an instance of the attribute Attr with provided arguments.
Definition: Builders.h:101
static DenseElementsAttr get(ShapedType type, ArrayRef< Attribute > values)
Constructs a dense elements attribute from an array of element values.
static DistinctAttr create(Attribute referencedAttr)
Creates a distinct attribute that associates a referenced attribute with a unique identifier.
A class for computing basic dominance information.
Definition: Dominance.h:136
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 getBF16(MLIRContext *ctx)
Definition: BuiltinTypes.h:444
Interface collection for the import of LLVM IR that dispatches to a concrete dialect interface implem...
LogicalResult convertInstruction(OpBuilder &builder, llvm::Instruction *inst, ArrayRef< llvm::Value * > llvmOperands, LLVM::ModuleImport &moduleImport) const
Converts the LLVM instruction to an MLIR operation if a conversion exists.
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 isConvertibleInstruction(unsigned id)
Returns true if the given LLVM IR instruction is convertible to an MLIR operation.
bool isConvertibleIntrinsic(llvm::Intrinsic::ID id)
Returns true if the given LLVM IR intrinsic is convertible to an MLIR operation.
Module import implementation class that provides methods to import globals and functions from an LLVM...
Definition: ModuleImport.h:47
Location translateLoc(llvm::DILocation *loc)
Translates the debug location.
LogicalResult convertComdats()
Converts all comdat selectors of the LLVM module to MLIR comdat operations.
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.
LogicalResult convertLinkerOptionsMetadata()
Converts !llvm.linker.options metadata to the llvm.linker.options LLVM dialect operation.
void mapBlock(llvm::BasicBlock *llvm, Block *mlir)
Stores the mapping between an LLVM block and its MLIR counterpart.
Definition: ModuleImport.h:117
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 attributes such as alias analysis or access group ...
LogicalResult convertIntrinsicArguments(ArrayRef< llvm::Value * > values, ArrayRef< unsigned > immArgPositions, ArrayRef< StringLiteral > immArgAttrNames, SmallVectorImpl< Value > &valuesOut, SmallVectorImpl< NamedAttribute > &attrsOut)
Converts the LLVM values for an intrinsic to mixed MLIR values and attributes for LLVM_IntrOpBase.
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:56
void addDebugIntrinsic(llvm::CallInst *intrinsic)
Adds a debug intrinsics to the list of intrinsics that should be converted after the function convers...
Block * lookupBlock(llvm::BasicBlock *block) const
Returns the MLIR block mapped to the given LLVM block.
Definition: ModuleImport.h:124
FailureOr< Value > convertMetadataValue(llvm::Value *value)
Converts an LLVM metadata value to an MLIR value, or returns failure if the conversion fails.
FailureOr< SmallVector< AliasScopeAttr > > lookupAliasScopeAttrs(const llvm::MDNode *node) const
Returns the alias scope attributes that map to the alias scope nodes starting from the metadata node.
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:90
Type convertType(llvm::Type *type)
Converts the type from LLVM to MLIR LLVM dialect.
Definition: ModuleImport.h:172
Operation * lookupOperation(llvm::Instruction *inst)
Returns the MLIR operation mapped to the given LLVM instruction.
Definition: ModuleImport.h:110
DILabelAttr matchLabelAttr(llvm::Value *value)
Converts value to a label attribute. Asserts if the matching fails.
FloatAttr matchFloatAttr(llvm::Value *value)
Converts value to a float attribute. Asserts if the matching fails.
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< AliasScopeAttr > > matchAliasScopeAttrs(llvm::Value *value)
Converts value to an array of alias scopes or returns failure if the conversion fails.
Value lookupValue(llvm::Value *value)
Returns the MLIR value mapped to the given LLVM value.
Definition: ModuleImport.h:85
LogicalResult processFunction(llvm::Function *func)
Imports func into the current module.
RoundingModeAttr matchRoundingModeAttr(llvm::Value *value)
Converts value to a rounding mode attribute.
void mapValue(llvm::Value *llvm, Value mlir)
Stores the mapping between an LLVM value and its MLIR counterpart.
Definition: ModuleImport.h:73
ModuleImport(ModuleOp mlirModule, std::unique_ptr< llvm::Module > llvmModule, bool emitExpensiveWarnings, bool importEmptyDICompositeTypes)
FailureOr< SmallVector< AccessGroupAttr > > lookupAccessGroupAttrs(const llvm::MDNode *node) const
Returns the access group attributes that map to the access group nodes starting from the access group...
LogicalResult convertGlobals()
Converts all global variables of the LLVM module to MLIR global variables.
void setIntegerOverflowFlags(llvm::Instruction *inst, Operation *op) const
Sets the integer overflow flags (nsw/nuw) attribute for the imported operation op given the original ...
FPExceptionBehaviorAttr matchFPExceptionBehaviorAttr(llvm::Value *value)
Converts value to a FP exception behavior attribute.
LogicalResult convertDataLayout()
Converts the data layout of the LLVM module to an MLIR data layout specification.
IntegerAttr matchIntegerAttr(llvm::Value *value)
Converts value to an integer attribute. Asserts if the matching fails.
Helper class that translates an LLVM data layout to an MLIR data layout specification.
StringRef getLastToken() const
Returns the last data layout token that has been processed before the data layout translation failed.
DataLayoutSpecInterface getDataLayout() const
Returns the MLIR data layout specification translated from the LLVM data layout.
ArrayRef< StringRef > getUnhandledTokens() const
Returns the data layout tokens that have not been handled during the data layout translation.
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:351
This class helps build Operations.
Definition: Builders.h:210
void setInsertionPointToStart(Block *block)
Sets the insertion point to the start of the specified block.
Definition: Builders.h:434
void setInsertionPoint(Block *block, Block::iterator insertPoint)
Set the insertion point to the specified location.
Definition: Builders.h:401
void setInsertionPointToEnd(Block *block)
Sets the insertion point to the end of the specified block.
Definition: Builders.h:439
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:441
void setInsertionPointAfterValue(Value val)
Sets the insertion point to the node after the specified value.
Definition: Builders.h:424
Operation * create(const OperationState &state)
Creates an operation given the fields represented as an OperationState.
Definition: Builders.cpp:468
void setInsertionPointAfter(Operation *op)
Sets the insertion point to the node after the specified operation, which will cause subsequent inser...
Definition: Builders.h:415
Block * getInsertionBlock() const
Return the block the current insertion point belongs to.
Definition: Builders.h:445
This class provides the API for ops that are known to be terminators.
Definition: OpDefinition.h:764
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:88
bool hasTrait()
Returns true if the operation was registered with a particular trait, e.g.
Definition: Operation.h:745
Block * getBlock()
Returns the operation block that contains this operation.
Definition: Operation.h:213
OpTy get() const
Allow accessing the internal op.
Definition: OwningOpRef.h:51
This class contains a list of basic blocks and a link to the parent operation it is attached to.
Definition: Region.h:26
iterator end()
Definition: Region.h:56
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:74
MLIRContext * getContext() const
Return the MLIRContext in which this type was uniqued.
Definition: Types.cpp:35
This class provides an abstraction over the different types of ranges over Values.
Definition: ValueRange.h:381
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:96
Operation * getDefiningOp() const
If this value is the result of an operation, return the operation that defines it.
Definition: Value.cpp:20
DominanceInfoNode * getNode(Block *a)
Return the dominance node from the Region containing block A.
Definition: Dominance.h:82
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...
FloatType getFloatType(MLIRContext *context, unsigned width)
Returns a supported MLIR floating point type of the given bit width or null if the bit width is not s...
bool isCompatibleVectorType(Type type)
Returns true if the given type is a vector type compatible with the LLVM dialect.
Definition: LLVMTypes.cpp:874
llvm::ElementCount getVectorNumElements(Type type)
Returns the element count of any LLVM-compatible vector type.
Definition: LLVMTypes.cpp:899
Type getVectorElementType(Type type)
Returns the element type of any vector type compatible with the LLVM dialect.
Definition: LLVMTypes.cpp:890
constexpr void enumerate(std::tuple< Tys... > &tuple, CallbackT &&callback)
Definition: Matchers.h:285
Include the generated interface declarations.
bool matchPattern(Value value, const Pattern &pattern)
Entry point for matching a pattern over a Value.
Definition: Matchers.h:401
InFlightDiagnostic emitWarning(Location loc)
Utility method to emit a warning message using this location.
OwningOpRef< ModuleOp > translateLLVMIRToModule(std::unique_ptr< llvm::Module > llvmModule, MLIRContext *context, bool emitExpensiveWarnings=true, bool dropDICompositeTypeElements=false)
Translates the LLVM module into an MLIR module living in the given context.
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...
detail::constant_op_matcher m_Constant()
Matches a constant foldable operation.
Definition: Matchers.h:310