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