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