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