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