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