[Reland][Runtimes] Merge 'compile_commands.json' files from runtimes build (#116303)
[llvm-project.git] / mlir / lib / Target / LLVMIR / ModuleImport.cpp
blobb0d5e635248d3f9b81dc7f4244e9a59c7057690c
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.
12 //===----------------------------------------------------------------------===//
14 #include "mlir/Target/LLVMIR/ModuleImport.h"
15 #include "mlir/IR/BuiltinAttributes.h"
16 #include "mlir/Target/LLVMIR/Import.h"
18 #include "AttrKindDetail.h"
19 #include "DataLayoutImporter.h"
20 #include "DebugImporter.h"
21 #include "LoopAnnotationImporter.h"
23 #include "mlir/Dialect/DLTI/DLTI.h"
24 #include "mlir/Dialect/LLVMIR/LLVMDialect.h"
25 #include "mlir/IR/Builders.h"
26 #include "mlir/IR/Matchers.h"
27 #include "mlir/Interfaces/DataLayoutInterfaces.h"
28 #include "mlir/Tools/mlir-translate/Translation.h"
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"
45 using namespace mlir;
46 using namespace mlir::LLVM;
47 using namespace mlir::LLVM::detail;
49 #include "mlir/Dialect/LLVMIR/LLVMConversionEnumsFromLLVM.inc"
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;
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;
72 /// Returns the name of the global_ctors global variables.
73 static constexpr StringRef getGlobalCtorsVarName() {
74 return "llvm.global_ctors";
77 /// Prefix used for symbols of nameless llvm globals.
78 static constexpr StringRef getNamelessGlobalPrefix() {
79 return "mlir.llvm.nameless_global";
82 /// Returns the name of the global_dtors global variables.
83 static constexpr StringRef getGlobalDtorsVarName() {
84 return "llvm.global_dtors";
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";
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 "";
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);
112 if (it != syncScopeName.end())
113 return *it;
114 llvm_unreachable("incorrect sync scope identifier");
117 /// Converts an array of unsigned indices to a signed integer position array.
118 static SmallVector<int64_t> getPositionFromIndices(ArrayRef<unsigned> indices) {
119 SmallVector<int64_t> position;
120 llvm::append_range(position, indices);
121 return position;
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);
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();
148 /// Get a topologically sorted list of blocks for the given basic blocks.
149 static SetVector<llvm::BasicBlock *>
150 getTopologicallySortedBlocks(ArrayRef<llvm::BasicBlock *> basicBlocks) {
151 SetVector<llvm::BasicBlock *> 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());
158 assert(blocks.size() == basicBlocks.size() && "some blocks are not sorted");
159 return blocks;
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());
178 ComdatOp ModuleImport::getGlobalComdatOp() {
179 if (globalComdatOp)
180 return globalComdatOp;
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;
190 LogicalResult ModuleImport::processTBAAMetadata(const llvm::MDNode *node) {
191 Location loc = mlirModule.getLoc();
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>{};
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,
218 SmallVectorImpl<TBAAMemberAttr> *members =
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;
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;
234 // This should be a type descriptor node.
235 if (identity)
236 *identity = identityNode->getString();
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;
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;
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;
263 offset = offsetCI->getZExtValue();
266 if (members)
267 members->push_back(TBAAMemberAttr::get(
268 cast<TBAANodeAttr>(tbaaMapping.lookup(memberNode)), offset));
271 return true;
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 */
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;
319 isConst = isConstantCI->getValue()[0];
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;
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.
335 DenseSet<const llvm::MDNode *> seen;
336 SmallVector<const llvm::MDNode *> workList;
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;
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;
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());
366 continue;
369 // Otherwise simply import the current node.
370 workList.pop_back();
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;
384 StringRef identity;
385 SmallVector<TBAAMemberAttr> members;
386 if (std::optional<bool> isValid =
387 isTypeDescriptorNode(current, &identity, &members)) {
388 assert(isValid.value() && "type descriptor node must be valid");
390 tbaaMapping.insert({current, builder.getAttr<TBAATypeDescriptorAttr>(
391 identity, members)});
392 continue;
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;
407 return emitError(loc) << "unsupported TBAA node format: "
408 << diagMD(current, llvmModule.get());
410 return success();
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();
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));
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));
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);
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();
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());
462 if (aliasScopeMapping.contains(scope))
463 continue;
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;
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>(
477 DistinctAttr::create(builder.getUnitAttr()),
478 cast<AliasScopeDomainAttr>(it->second), description);
479 aliasScopeMapping.try_emplace(aliasScope.getNode(), aliasScopeOp);
482 return success();
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)));
494 // Return failure if one of the alias scope lookups failed.
495 if (llvm::is_contained(aliasScopes, nullptr))
496 return failure();
497 return aliasScopes;
500 void ModuleImport::addDebugIntrinsic(llvm::CallInst *intrinsic) {
501 debugIntrinsics.insert(intrinsic);
504 LogicalResult ModuleImport::convertLinkerOptionsMetadata() {
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()) {
510 SmallVector<StringRef> options;
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));
518 return success();
521 LogicalResult ModuleImport::convertIdentMetadata() {
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;
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()));
535 return success();
538 LogicalResult ModuleImport::convertCommandlineMetadata() {
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;
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()));
552 return success();
555 LogicalResult ModuleImport::convertMetadata() {
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();
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();
581 if (failed(convertLinkerOptionsMetadata()))
582 return failure();
583 if (failed(convertIdentMetadata()))
584 return failure();
585 if (failed(convertCommandlineMetadata()))
586 return failure();
587 return success();
590 void ModuleImport::processComdat(const llvm::Comdat *comdat) {
591 if (comdatMapping.contains(comdat))
592 return;
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 =
601 SymbolRefAttr::get(builder.getContext(), getGlobalComdatOpName(),
602 FlatSymbolRefAttr::get(selectorOp.getSymNameAttr()));
603 comdatMapping.try_emplace(comdat, symbolRef);
606 LogicalResult ModuleImport::convertComdats() {
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();
616 LogicalResult ModuleImport::convertGlobals() {
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);
624 continue;
626 if (failed(convertGlobal(&globalVar))) {
627 return emitError(UnknownLoc::get(context))
628 << "unhandled global variable: " << diag(globalVar);
631 return success();
634 LogicalResult ModuleImport::convertDataLayout() {
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();
641 for (StringRef token : dataLayoutImporter.getUnhandledTokens())
642 emitWarning(loc, "unhandled data layout token: ") << token;
644 mlirModule->setAttr(DLTIDialect::kDataLayoutAttrName,
645 dataLayoutImporter.getDataLayout());
646 return success();
649 LogicalResult ModuleImport::convertFunctions() {
650 for (llvm::Function &func : llvmModule->functions())
651 if (failed(processFunction(&func)))
652 return failure();
653 return success();
656 void ModuleImport::setNonDebugMetadataAttrs(llvm::Instruction *inst,
657 Operation *op) {
658 SmallVector<std::pair<unsigned, llvm::MDNode *>> allMetadata;
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);
674 void ModuleImport::setIntegerOverflowFlags(llvm::Instruction *inst,
675 Operation *op) const {
676 auto iface = cast<IntegerOverflowFlagsInterface>(op);
678 IntegerOverflowFlags value = {};
679 value = bitEnumSet(value, IntegerOverflowFlags::nsw, inst->hasNoSignedWrap());
680 value =
681 bitEnumSet(value, IntegerOverflowFlags::nuw, inst->hasNoUnsignedWrap());
683 iface.setOverflowFlags(value);
686 void ModuleImport::setExactFlag(llvm::Instruction *inst, Operation *op) const {
687 auto iface = cast<ExactFlagInterface>(op);
689 iface.setIsExact(inst->isExact());
692 void ModuleImport::setDisjointFlag(llvm::Instruction *inst,
693 Operation *op) const {
694 auto iface = cast<DisjointFlagInterface>(op);
695 auto instDisjoint = cast<llvm::PossiblyDisjointInst>(inst);
697 iface.setIsDisjoint(instDisjoint->isDisjoint());
700 void ModuleImport::setNonNegFlag(llvm::Instruction *inst, Operation *op) const {
701 auto iface = cast<NonNegFlagInterface>(op);
703 iface.setNonNeg(inst->hasNonNeg());
706 void ModuleImport::setFastmathFlagsAttr(llvm::Instruction *inst,
707 Operation *op) const {
708 auto iface = cast<FastmathFlagsInterface>(op);
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();
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);
731 /// Returns if `type` is a scalar integer or floating-point type.
732 static bool isScalarType(Type type) {
733 return isa<IntegerType, FloatType>(type);
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 {};
744 llvm::ElementCount numElements = LLVM::getVectorNumElements(type);
745 if (numElements.isScalable()) {
746 emitError(UnknownLoc::get(type.getContext()))
747 << "scalable vectors not supported";
748 return {};
751 // An LLVM dialect vector can only contain scalars.
752 Type elementType = LLVM::getVectorElementType(type);
753 if (!isScalarType(elementType))
754 return {};
756 SmallVector<int64_t> shape(arrayShape);
757 shape.push_back(numElements.getKnownMinValue());
758 return VectorType::get(shape, elementType);
761 Type ModuleImport::getBuiltinTypeForAttr(Type type) {
762 if (!type)
763 return {};
765 // Return builtin integer and floating-point types as is.
766 if (isScalarType(type))
767 return type;
769 // Return builtin vectors of integer and floating-point types as is.
770 if (Type vectorType = getVectorTypeForAttr(type))
771 return vectorType;
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();
780 if (isScalarType(type))
781 return RankedTensorType::get(arrayShape, type);
782 return getVectorTypeForAttr(type, arrayShape);
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();
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());
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) {
806 emitError(UnknownLoc::get(builder.getContext()))
807 << "unexpected floating-point type";
808 return {};
810 return builder.getFloatAttr(floatType, constFloat->getValueAPF());
812 return {};
815 /// Returns an integer or float attribute array for the provided constant
816 /// sequence `constSequence` or nullptr if the conversion fails.
817 static SmallVector<Attribute>
818 getSequenceConstantAsAttrs(OpBuilder &builder,
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));
826 return elementAttrs;
829 Attribute ModuleImport::getConstantAsAttr(llvm::Constant *constant) {
830 // Convert scalar constants.
831 if (Attribute scalarAttr = getScalarConstantAsAttr(builder, constant))
832 return scalarAttr;
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)));
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.
852 Attribute splatAttr = getScalarConstantAsAttr(
853 builder, constVector->getElementAsConstant(0));
854 return SplatElementsAttr::get(shape, splatAttr);
856 // Convert non-splat constants to dense elements attributes.
857 SmallVector<Attribute> elementAttrs =
858 getSequenceConstantAsAttrs(builder, constArray);
859 return DenseElementsAttr::get(shape, elementAttrs);
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;
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;
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;
895 // Bail if the aggregate contains a unsupported constant type such as a
896 // constant expression.
897 return {};
899 return DenseElementsAttr::get(shape, elementAttrs);
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);
913 return {};
916 FlatSymbolRefAttr
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;
924 // Make sure the symbol name does not clash with an existing symbol.
925 SmallString<128> globalName = SymbolTable::generateSymbolName<128>(
926 getNamelessGlobalPrefix(),
927 [this](StringRef newName) { return llvmModule->getNamedValue(newName); },
928 namelessGlobalId);
929 auto symbolRef = FlatSymbolRefAttr::get(context, globalName);
930 it->getSecond() = symbolRef;
931 return symbolRef;
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);
942 Attribute valueAttr;
943 if (globalVar->hasInitializer())
944 valueAttr = getConstantAsAttr(globalVar->getInitializer());
945 Type type = convertType(globalVar->getValueType());
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();
954 // Get the global expression associated with this global variable and convert
955 // it.
956 SmallVector<Attribute> globalExpressionAttrs;
957 SmallVector<llvm::DIGlobalVariableExpression *> globalExpressions;
958 globalVar->getDebugInfo(globalExpressions);
960 for (llvm::DIGlobalVariableExpression *expr : globalExpressions) {
961 DIGlobalVariableExpressionAttr globalExpressionAttr =
962 debugImporter->translateGlobalVariableExpression(expr);
963 globalExpressionAttrs.push_back(globalExpressionAttr);
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();
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;
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);
991 if (globalVar->hasAtLeastLocalUnnamedAddr()) {
992 globalOp.setUnnamedAddr(
993 convertUnnamedAddrFromLLVM(globalVar->getUnnamedAddr()));
995 if (globalVar->hasSection())
996 globalOp.setSection(globalVar->getSection());
997 globalOp.setVisibility_(
998 convertVisibilityFromLLVM(globalVar->getVisibility()));
1000 if (globalVar->hasComdat())
1001 globalOp.setComdatAttr(comdatMapping.lookup(globalVar->getComdat()));
1003 return success();
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();
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();
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();
1028 // GlobalCtorsOps and GlobalDtorsOps do not support non-null data fields.
1029 if (!data->isNullValue())
1030 return failure();
1032 funcs.push_back(FlatSymbolRefAttr::get(context, func->getName()));
1033 priorities.push_back(priority->getValue().getZExtValue());
1036 OpBuilder::InsertionGuard guard(builder);
1037 if (!globalInsertionOp)
1038 builder.setInsertionPointToStart(mlirModule.getBody());
1039 else
1040 builder.setInsertionPointAfter(globalInsertionOp);
1042 if (globalVar->getName() == getGlobalCtorsVarName()) {
1043 globalInsertionOp = builder.create<LLVM::GlobalCtorsOp>(
1044 mlirModule.getLoc(), builder.getArrayAttr(funcs),
1045 builder.getI32ArrayAttr(priorities));
1046 return success();
1048 globalInsertionOp = builder.create<LLVM::GlobalDtorsOp>(
1049 mlirModule.getLoc(), builder.getArrayAttr(funcs),
1050 builder.getI32ArrayAttr(priorities));
1051 return success();
1054 SetVector<llvm::Constant *>
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 {};
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;
1065 DenseMap<llvm::Constant *, SmallVector<llvm::Constant *>> adjacencyLists;
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;
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));
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;
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);
1114 return orderedSet;
1117 FailureOr<Value> ModuleImport::convertConstant(llvm::Constant *constant) {
1118 Location loc = UnknownLoc::get(context);
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();
1127 return builder.create<ConstantOp>(loc, type, attr).getResult();
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();
1136 // Convert none token constants.
1137 if (isa<llvm::ConstantTokenNone>(constant)) {
1138 return builder.create<NoneTokenOp>(loc).getResult();
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();
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();
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();
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();
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);
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));
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)));
1207 assert(llvm::count(elementValues, nullptr) == 0 &&
1208 "expected all elements have been converted before");
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);
1227 return root;
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();
1240 StringRef error = "";
1241 if (isa<llvm::BlockAddress>(constant))
1242 error = " since blockaddress(...) is unsupported";
1244 return emitError(loc) << "unhandled constant: " << diag(*constant) << error;
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");
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);
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);
1273 // Update the constant insertion point and return the converted constant.
1274 Value result = lookupValue(constant);
1275 constantInsertionOp = result.getDefiningOp();
1276 return result;
1279 FailureOr<Value> ModuleImport::convertValue(llvm::Value *value) {
1280 assert(!isa<llvm::MetadataAsValue>(value) &&
1281 "expected value to not be metadata");
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();
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);
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);
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();
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();
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();
1320 FailureOr<SmallVector<Value>>
1321 ModuleImport::convertValues(ArrayRef<llvm::Value *> values) {
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);
1330 return remapped;
1333 LogicalResult ModuleImport::convertIntrinsicArguments(
1334 ArrayRef<llvm::Value *> values, ArrayRef<llvm::OperandBundleUse> opBundles,
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");
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;
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);
1365 SmallVector<int> opBundleSizes;
1366 SmallVector<Attribute> opBundleTagAttrs;
1367 if (requiresOpBundles) {
1368 opBundleSizes.reserve(opBundles.size());
1369 opBundleTagAttrs.reserve(opBundles.size());
1371 for (const llvm::OperandBundleUse &bundle : opBundles) {
1372 opBundleSizes.push_back(bundle.Inputs.size());
1373 opBundleTagAttrs.push_back(StringAttr::get(context, bundle.getTagName()));
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);
1383 auto opBundleSizesAttr = DenseI32ArrayAttr::get(context, opBundleSizes);
1384 auto opBundleSizesAttrNameAttr =
1385 StringAttr::get(context, LLVMDialect::getOpBundleSizesAttrName());
1386 attrsOut.push_back({opBundleSizesAttrNameAttr, opBundleSizesAttr});
1388 auto opBundleTagsAttr = ArrayAttr::get(context, opBundleTagAttrs);
1389 auto opBundleTagsAttrNameAttr =
1390 StringAttr::get(context, LLVMDialect::getOpBundleTagsAttrName());
1391 attrsOut.push_back({opBundleTagsAttrNameAttr, opBundleTagsAttr});
1394 return success();
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;
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;
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);
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);
1429 FPExceptionBehaviorAttr
1430 ModuleImport::matchFPExceptionBehaviorAttr(llvm::Value *value) {
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));
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));
1450 FailureOr<SmallVector<AliasScopeAttr>>
1451 ModuleImport::matchAliasScopeAttrs(llvm::Value *value) {
1452 auto *nodeAsVal = cast<llvm::MetadataAsValue>(value);
1453 auto *node = cast<llvm::MDNode>(nodeAsVal->getMetadata());
1454 return lookupAliasScopeAttrs(node);
1457 Location ModuleImport::translateLoc(llvm::DILocation *loc) {
1458 return debugImporter->translateLoc(loc);
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);
1473 return success();
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()));
1483 if (!callInst->getCalledFunction()) {
1484 FailureOr<Value> called = convertValue(callInst->getCalledOperand());
1485 if (failed(called))
1486 return failure();
1487 operands.push_back(*called);
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();
1497 LogicalResult ModuleImport::convertIntrinsic(llvm::CallInst *inst) {
1498 if (succeeded(iface.convertIntrinsic(builder, inst, *this)))
1499 return success();
1501 Location loc = translateLoc(inst->getDebugLoc());
1502 return emitError(loc) << "unhandled intrinsic: " << diag(*inst);
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);
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);
1522 if (!brInst->isConditional()) {
1523 auto brOp = builder.create<LLVM::BrOp>(loc, succBlockArgs.front(),
1524 succBlocks.front());
1525 mapNoResultOp(inst, brOp);
1526 return success();
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();
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();
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);
1565 auto switchOp = builder.create<SwitchOp>(
1566 loc, *condition, lookupBlock(defaultBB), defaultBlockArgs, caseValues,
1567 caseBlocks, caseOperandRefs);
1568 mapNoResultOp(inst, switchOp);
1569 return success();
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();
1577 if (inst->getOpcode() == llvm::Instruction::Call) {
1578 auto *callInst = cast<llvm::CallInst>(inst);
1580 SmallVector<Type> types;
1581 SmallVector<Value> operands;
1582 if (failed(convertCallTypeAndOperands(callInst, types, operands)))
1583 return failure();
1585 auto funcTy =
1586 dyn_cast<LLVMFunctionType>(convertType(callInst->getFunctionType()));
1587 if (!funcTy)
1588 return failure();
1590 CallOp callOp;
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);
1599 callOp.setCConv(convertCConvFromLLVM(callInst->getCallingConv()));
1600 callOp.setTailCallKind(
1601 convertTailCallKindFromLLVM(callInst->getTailCallKind()));
1602 setFastmathFlagsAttr(inst, callOp);
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);
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);
1625 if (!callInst->getType()->isVoidTy())
1626 mapValue(inst, callOp.getResult());
1627 else
1628 mapNoResultOp(inst, callOp);
1629 return success();
1631 if (inst->getOpcode() == llvm::Instruction::LandingPad) {
1632 auto *lpInst = cast<llvm::LandingPadInst>(inst);
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);
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();
1649 if (inst->getOpcode() == llvm::Instruction::Invoke) {
1650 auto *invokeInst = cast<llvm::InvokeInst>(inst);
1652 SmallVector<Type> types;
1653 SmallVector<Value> operands;
1654 if (failed(convertCallTypeAndOperands(invokeInst, types, operands)))
1655 return failure();
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;
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);
1676 SmallVector<Value> unwindArgs;
1677 if (failed(convertBranchArgs(invokeInst, invokeInst->getUnwindDest(),
1678 unwindArgs)))
1679 return failure();
1681 auto funcTy =
1682 dyn_cast<LLVMFunctionType>(convertType(invokeInst->getFunctionType()));
1683 if (!funcTy)
1684 return failure();
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);
1701 invokeOp.setCConv(convertCConvFromLLVM(invokeInst->getCallingConv()));
1702 if (!invokeInst->getType()->isVoidTy())
1703 mapValue(inst, invokeOp.getResults().front());
1704 else
1705 mapNoResultOp(inst, invokeOp);
1707 SmallVector<Value> normalArgs;
1708 if (failed(convertBranchArgs(invokeInst, invokeInst->getNormalDest(),
1709 normalArgs)))
1710 return failure();
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);
1730 return success();
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();
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);
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();
1758 // Convert all instructions that have an mlirBuilder.
1759 if (succeeded(convertInstructionImpl(builder, inst, *this, iface)))
1760 return success();
1762 return emitError(loc) << "unhandled instruction: " << diag(*inst);
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.
1771 // Convert LLVM intrinsics calls to MLIR intrinsics.
1772 if (auto *intrinsic = dyn_cast<llvm::IntrinsicInst>(inst))
1773 return convertIntrinsic(intrinsic);
1775 // Convert all remaining LLVM instructions to MLIR operations.
1776 return convertInstruction(inst);
1779 FlatSymbolRefAttr ModuleImport::getPersonalityAsAttr(llvm::Function *f) {
1780 if (!f->hasPersonalityFn())
1781 return nullptr;
1783 llvm::Constant *pf = f->getPersonalityFn();
1785 // If it directly has a name, we can use it.
1786 if (pf->hasName())
1787 return SymbolRefAttr::get(builder.getContext(), pf->getName());
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());
1798 return FlatSymbolRefAttr();
1801 static void processMemoryEffects(llvm::Function *func, LLVMFuncOp funcOp) {
1802 llvm::MemoryEffects memEffects = func->getMemoryEffects();
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);
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"),
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;
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;
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);
1874 // Skip attributes that map to an explicit attribute on the LLVMFuncOp.
1875 if (llvm::is_contained(kExplicitAttributes, attrName))
1876 continue;
1878 if (attr.isStringAttribute()) {
1879 StringRef val = attr.getValueAsString();
1880 if (val.empty()) {
1881 passthroughs.push_back(keyAttr);
1882 continue;
1884 passthroughs.push_back(
1885 ArrayAttr::get(context, {keyAttr, StringAttr::get(context, val)}));
1886 continue;
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;
1894 if (attr.isEnumAttribute()) {
1895 passthroughs.push_back(keyAttr);
1896 continue;
1899 llvm_unreachable("unexpected attribute kind");
1902 if (!passthroughs.empty())
1903 funcOp.setPassthroughAttr(ArrayAttr::get(context, passthroughs));
1906 void ModuleImport::processFunctionAttributes(llvm::Function *func,
1907 LLVMFuncOp funcOp) {
1908 processMemoryEffects(func, funcOp);
1909 processPassthroughAttrs(func, funcOp);
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);
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);
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);
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))));
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()));
1961 if (llvm::Attribute attr = func->getFnAttribute("target-cpu");
1962 attr.isStringAttribute())
1963 funcOp.setTargetCpuAttr(StringAttr::get(context, attr.getValueAsString()));
1965 if (llvm::Attribute attr = func->getFnAttribute("tune-cpu");
1966 attr.isStringAttribute())
1967 funcOp.setTuneCpuAttr(StringAttr::get(context, attr.getValueAsString()));
1969 if (llvm::Attribute attr = func->getFnAttribute("target-features");
1970 attr.isStringAttribute())
1971 funcOp.setTargetFeaturesAttr(
1972 LLVM::TargetFeaturesAttr::get(context, attr.getValueAsString()));
1974 if (llvm::Attribute attr = func->getFnAttribute("unsafe-fp-math");
1975 attr.isStringAttribute())
1976 funcOp.setUnsafeFpMath(attr.getValueAsBool());
1978 if (llvm::Attribute attr = func->getFnAttribute("no-infs-fp-math");
1979 attr.isStringAttribute())
1980 funcOp.setNoInfsFpMath(attr.getValueAsBool());
1982 if (llvm::Attribute attr = func->getFnAttribute("no-nans-fp-math");
1983 attr.isStringAttribute())
1984 funcOp.setNoNansFpMath(attr.getValueAsBool());
1986 if (llvm::Attribute attr = func->getFnAttribute("approx-func-fp-math");
1987 attr.isStringAttribute())
1988 funcOp.setApproxFuncFpMath(attr.getValueAsBool());
1990 if (llvm::Attribute attr = func->getFnAttribute("no-signed-zeros-fp-math");
1991 attr.isStringAttribute())
1992 funcOp.setNoSignedZerosFpMath(attr.getValueAsBool());
1994 if (llvm::Attribute attr = func->getFnAttribute("denormal-fp-math");
1995 attr.isStringAttribute())
1996 funcOp.setDenormalFpMathAttr(
1997 StringAttr::get(context, attr.getValueAsString()));
1999 if (llvm::Attribute attr = func->getFnAttribute("denormal-fp-math-f32");
2000 attr.isStringAttribute())
2001 funcOp.setDenormalFpMathF32Attr(
2002 StringAttr::get(context, attr.getValueAsString()));
2004 if (llvm::Attribute attr = func->getFnAttribute("fp-contract");
2005 attr.isStringAttribute())
2006 funcOp.setFpContractAttr(StringAttr::get(context, attr.getValueAsString()));
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 if (llvmAttr.isConstantRangeAttribute()) {
2026 const llvm::ConstantRange &value = llvmAttr.getValueAsConstantRange();
2027 mlirAttr = builder.getAttr<LLVM::ConstantRangeAttr>(value.getLower(),
2028 value.getUpper());
2029 } else
2030 llvm_unreachable("unexpected parameter attribute kind");
2031 paramAttrs.push_back(builder.getNamedAttr(mlirName, mlirAttr));
2034 return builder.getDictionaryAttr(paramAttrs);
2037 void ModuleImport::convertParameterAttributes(llvm::Function *func,
2038 LLVMFuncOp funcOp,
2039 OpBuilder &builder) {
2040 auto llvmAttrs = func->getAttributes();
2041 for (size_t i = 0, e = funcOp.getNumArguments(); i < e; ++i) {
2042 llvm::AttributeSet llvmArgAttrs = llvmAttrs.getParamAttrs(i);
2043 funcOp.setArgAttrs(i, convertParameterAttribute(llvmArgAttrs, builder));
2045 // Convert the result attributes and attach them wrapped in an ArrayAttribute
2046 // to the funcOp.
2047 llvm::AttributeSet llvmResAttr = llvmAttrs.getRetAttrs();
2048 if (!llvmResAttr.hasAttributes())
2049 return;
2050 funcOp.setResAttrsAttr(
2051 builder.getArrayAttr(convertParameterAttribute(llvmResAttr, builder)));
2054 LogicalResult ModuleImport::processFunction(llvm::Function *func) {
2055 clearRegionState();
2057 auto functionType =
2058 dyn_cast<LLVMFunctionType>(convertType(func->getFunctionType()));
2059 if (func->isIntrinsic() &&
2060 iface.isConvertibleIntrinsic(func->getIntrinsicID()))
2061 return success();
2063 bool dsoLocal = func->hasLocalLinkage();
2064 CConv cconv = convertCConvFromLLVM(func->getCallingConv());
2066 // Insert the function at the end of the module.
2067 OpBuilder::InsertionGuard guard(builder);
2068 builder.setInsertionPointToEnd(mlirModule.getBody());
2070 Location loc = debugImporter->translateFuncLocation(func);
2071 LLVMFuncOp funcOp = builder.create<LLVMFuncOp>(
2072 loc, func->getName(), functionType,
2073 convertLinkageFromLLVM(func->getLinkage()), dsoLocal, cconv);
2075 convertParameterAttributes(func, funcOp, builder);
2077 if (FlatSymbolRefAttr personality = getPersonalityAsAttr(func))
2078 funcOp.setPersonalityAttr(personality);
2079 else if (func->hasPersonalityFn())
2080 emitWarning(funcOp.getLoc(), "could not deduce personality, skipping it");
2082 if (func->hasGC())
2083 funcOp.setGarbageCollector(StringRef(func->getGC()));
2085 if (func->hasAtLeastLocalUnnamedAddr())
2086 funcOp.setUnnamedAddr(convertUnnamedAddrFromLLVM(func->getUnnamedAddr()));
2088 if (func->hasSection())
2089 funcOp.setSection(StringRef(func->getSection()));
2091 funcOp.setVisibility_(convertVisibilityFromLLVM(func->getVisibility()));
2093 if (func->hasComdat())
2094 funcOp.setComdatAttr(comdatMapping.lookup(func->getComdat()));
2096 if (llvm::MaybeAlign maybeAlign = func->getAlign())
2097 funcOp.setAlignment(maybeAlign->value());
2099 // Handle Function attributes.
2100 processFunctionAttributes(func, funcOp);
2102 // Convert non-debug metadata by using the dialect interface.
2103 SmallVector<std::pair<unsigned, llvm::MDNode *>> allMetadata;
2104 func->getAllMetadata(allMetadata);
2105 for (auto &[kind, node] : allMetadata) {
2106 if (!iface.isConvertibleMetadata(kind))
2107 continue;
2108 if (failed(iface.setMetadataAttrs(builder, kind, node, funcOp, *this))) {
2109 emitWarning(funcOp.getLoc())
2110 << "unhandled function metadata: " << diagMD(node, llvmModule.get())
2111 << " on " << diag(*func);
2115 if (func->isDeclaration())
2116 return success();
2118 // Collect the set of basic blocks reachable from the function's entry block.
2119 // This step is crucial as LLVM IR can contain unreachable blocks that
2120 // self-dominate. As a result, an operation might utilize a variable it
2121 // defines, which the import does not support. Given that MLIR lacks block
2122 // label support, we can safely remove unreachable blocks, as there are no
2123 // indirect branch instructions that could potentially target these blocks.
2124 llvm::df_iterator_default_set<llvm::BasicBlock *> reachable;
2125 for (llvm::BasicBlock *basicBlock : llvm::depth_first_ext(func, reachable))
2126 (void)basicBlock;
2128 // Eagerly create all reachable blocks.
2129 SmallVector<llvm::BasicBlock *> reachableBasicBlocks;
2130 for (llvm::BasicBlock &basicBlock : *func) {
2131 // Skip unreachable blocks.
2132 if (!reachable.contains(&basicBlock))
2133 continue;
2134 Region &body = funcOp.getBody();
2135 Block *block = builder.createBlock(&body, body.end());
2136 mapBlock(&basicBlock, block);
2137 reachableBasicBlocks.push_back(&basicBlock);
2140 // Add function arguments to the entry block.
2141 for (const auto &it : llvm::enumerate(func->args())) {
2142 BlockArgument blockArg = funcOp.getFunctionBody().addArgument(
2143 functionType.getParamType(it.index()), funcOp.getLoc());
2144 mapValue(&it.value(), blockArg);
2147 // Process the blocks in topological order. The ordered traversal ensures
2148 // operands defined in a dominating block have a valid mapping to an MLIR
2149 // value once a block is translated.
2150 SetVector<llvm::BasicBlock *> blocks =
2151 getTopologicallySortedBlocks(reachableBasicBlocks);
2152 setConstantInsertionPointToStart(lookupBlock(blocks.front()));
2153 for (llvm::BasicBlock *basicBlock : blocks)
2154 if (failed(processBasicBlock(basicBlock, lookupBlock(basicBlock))))
2155 return failure();
2157 // Process the debug intrinsics that require a delayed conversion after
2158 // everything else was converted.
2159 if (failed(processDebugIntrinsics()))
2160 return failure();
2162 return success();
2165 /// Checks if `dbgIntr` is a kill location that holds metadata instead of an SSA
2166 /// value.
2167 static bool isMetadataKillLocation(llvm::DbgVariableIntrinsic *dbgIntr) {
2168 if (!dbgIntr->isKillLocation())
2169 return false;
2170 llvm::Value *value = dbgIntr->getArgOperand(0);
2171 auto *nodeAsVal = dyn_cast<llvm::MetadataAsValue>(value);
2172 if (!nodeAsVal)
2173 return false;
2174 return !isa<llvm::ValueAsMetadata>(nodeAsVal->getMetadata());
2177 LogicalResult
2178 ModuleImport::processDebugIntrinsic(llvm::DbgVariableIntrinsic *dbgIntr,
2179 DominanceInfo &domInfo) {
2180 Location loc = translateLoc(dbgIntr->getDebugLoc());
2181 auto emitUnsupportedWarning = [&]() {
2182 if (emitExpensiveWarnings)
2183 emitWarning(loc) << "dropped intrinsic: " << diag(*dbgIntr);
2184 return success();
2186 // Drop debug intrinsics with arg lists.
2187 // TODO: Support debug intrinsics that have arg lists.
2188 if (dbgIntr->hasArgList())
2189 return emitUnsupportedWarning();
2190 // Kill locations can have metadata nodes as location operand. This
2191 // cannot be converted to poison as the type cannot be reconstructed.
2192 // TODO: find a way to support this case.
2193 if (isMetadataKillLocation(dbgIntr))
2194 return emitUnsupportedWarning();
2195 // Drop debug intrinsics if the associated variable information cannot be
2196 // translated due to cyclic debug metadata.
2197 // TODO: Support cyclic debug metadata.
2198 DILocalVariableAttr localVariableAttr =
2199 matchLocalVariableAttr(dbgIntr->getArgOperand(1));
2200 if (!localVariableAttr)
2201 return emitUnsupportedWarning();
2202 FailureOr<Value> argOperand = convertMetadataValue(dbgIntr->getArgOperand(0));
2203 if (failed(argOperand))
2204 return emitError(loc) << "failed to convert a debug intrinsic operand: "
2205 << diag(*dbgIntr);
2207 // Ensure that the debug intrinsic is inserted right after its operand is
2208 // defined. Otherwise, the operand might not necessarily dominate the
2209 // intrinsic. If the defining operation is a terminator, insert the intrinsic
2210 // into a dominated block.
2211 OpBuilder::InsertionGuard guard(builder);
2212 if (Operation *op = argOperand->getDefiningOp();
2213 op && op->hasTrait<OpTrait::IsTerminator>()) {
2214 // Find a dominated block that can hold the debug intrinsic.
2215 auto dominatedBlocks = domInfo.getNode(op->getBlock())->children();
2216 // If no block is dominated by the terminator, this intrinisc cannot be
2217 // converted.
2218 if (dominatedBlocks.empty())
2219 return emitUnsupportedWarning();
2220 // Set insertion point before the terminator, to avoid inserting something
2221 // before landingpads.
2222 Block *dominatedBlock = (*dominatedBlocks.begin())->getBlock();
2223 builder.setInsertionPoint(dominatedBlock->getTerminator());
2224 } else {
2225 builder.setInsertionPointAfterValue(*argOperand);
2227 auto locationExprAttr =
2228 debugImporter->translateExpression(dbgIntr->getExpression());
2229 Operation *op =
2230 llvm::TypeSwitch<llvm::DbgVariableIntrinsic *, Operation *>(dbgIntr)
2231 .Case([&](llvm::DbgDeclareInst *) {
2232 return builder.create<LLVM::DbgDeclareOp>(
2233 loc, *argOperand, localVariableAttr, locationExprAttr);
2235 .Case([&](llvm::DbgValueInst *) {
2236 return builder.create<LLVM::DbgValueOp>(
2237 loc, *argOperand, localVariableAttr, locationExprAttr);
2239 mapNoResultOp(dbgIntr, op);
2240 setNonDebugMetadataAttrs(dbgIntr, op);
2241 return success();
2244 LogicalResult ModuleImport::processDebugIntrinsics() {
2245 DominanceInfo domInfo;
2246 for (llvm::Instruction *inst : debugIntrinsics) {
2247 auto *intrCall = cast<llvm::DbgVariableIntrinsic>(inst);
2248 if (failed(processDebugIntrinsic(intrCall, domInfo)))
2249 return failure();
2251 return success();
2254 LogicalResult ModuleImport::processBasicBlock(llvm::BasicBlock *bb,
2255 Block *block) {
2256 builder.setInsertionPointToStart(block);
2257 for (llvm::Instruction &inst : *bb) {
2258 if (failed(processInstruction(&inst)))
2259 return failure();
2261 // Skip additional processing when the instructions is a debug intrinsics
2262 // that was not yet converted.
2263 if (debugIntrinsics.contains(&inst))
2264 continue;
2266 // Set the non-debug metadata attributes on the imported operation and emit
2267 // a warning if an instruction other than a phi instruction is dropped
2268 // during the import.
2269 if (Operation *op = lookupOperation(&inst)) {
2270 setNonDebugMetadataAttrs(&inst, op);
2271 } else if (inst.getOpcode() != llvm::Instruction::PHI) {
2272 if (emitExpensiveWarnings) {
2273 Location loc = debugImporter->translateLoc(inst.getDebugLoc());
2274 emitWarning(loc) << "dropped instruction: " << diag(inst);
2278 return success();
2281 FailureOr<SmallVector<AccessGroupAttr>>
2282 ModuleImport::lookupAccessGroupAttrs(const llvm::MDNode *node) const {
2283 return loopAnnotationImporter->lookupAccessGroupAttrs(node);
2286 LoopAnnotationAttr
2287 ModuleImport::translateLoopAnnotationAttr(const llvm::MDNode *node,
2288 Location loc) const {
2289 return loopAnnotationImporter->translateLoopAnnotation(node, loc);
2292 OwningOpRef<ModuleOp>
2293 mlir::translateLLVMIRToModule(std::unique_ptr<llvm::Module> llvmModule,
2294 MLIRContext *context, bool emitExpensiveWarnings,
2295 bool dropDICompositeTypeElements) {
2296 // Preload all registered dialects to allow the import to iterate the
2297 // registered LLVMImportDialectInterface implementations and query the
2298 // supported LLVM IR constructs before starting the translation. Assumes the
2299 // LLVM and DLTI dialects that convert the core LLVM IR constructs have been
2300 // registered before.
2301 assert(llvm::is_contained(context->getAvailableDialects(),
2302 LLVMDialect::getDialectNamespace()));
2303 assert(llvm::is_contained(context->getAvailableDialects(),
2304 DLTIDialect::getDialectNamespace()));
2305 context->loadAllAvailableDialects();
2306 OwningOpRef<ModuleOp> module(ModuleOp::create(FileLineColLoc::get(
2307 StringAttr::get(context, llvmModule->getSourceFileName()), /*line=*/0,
2308 /*column=*/0)));
2310 ModuleImport moduleImport(module.get(), std::move(llvmModule),
2311 emitExpensiveWarnings, dropDICompositeTypeElements);
2312 if (failed(moduleImport.initializeImportInterface()))
2313 return {};
2314 if (failed(moduleImport.convertDataLayout()))
2315 return {};
2316 if (failed(moduleImport.convertComdats()))
2317 return {};
2318 if (failed(moduleImport.convertMetadata()))
2319 return {};
2320 if (failed(moduleImport.convertGlobals()))
2321 return {};
2322 if (failed(moduleImport.convertFunctions()))
2323 return {};
2325 return module;