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