1 //===- ConvertFromLLVMIR.cpp - MLIR to LLVM IR conversion -----------------===// 2 // 3 // Part of the MLIR 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 a translation between LLVM IR and the MLIR LLVM dialect. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "mlir/Dialect/LLVMIR/LLVMDialect.h" 14 #include "mlir/IR/Builders.h" 15 #include "mlir/IR/MLIRContext.h" 16 #include "mlir/IR/Module.h" 17 #include "mlir/IR/StandardTypes.h" 18 #include "mlir/Target/LLVMIR.h" 19 #include "mlir/Translation.h" 20 21 #include "llvm/IR/Attributes.h" 22 #include "llvm/IR/Constants.h" 23 #include "llvm/IR/Function.h" 24 #include "llvm/IR/Instructions.h" 25 #include "llvm/IR/Type.h" 26 #include "llvm/IRReader/IRReader.h" 27 #include "llvm/Support/Error.h" 28 #include "llvm/Support/SourceMgr.h" 29 30 using namespace mlir; 31 using namespace mlir::LLVM; 32 33 // Utility to print an LLVM value as a string for passing to emitError(). 34 // FIXME: Diagnostic should be able to natively handle types that have 35 // operator << (raw_ostream&) defined. 36 static std::string diag(llvm::Value &v) { 37 std::string s; 38 llvm::raw_string_ostream os(s); 39 os << v; 40 return os.str(); 41 } 42 43 // Handles importing globals and functions from an LLVM module. 44 namespace { 45 class Importer { 46 public: 47 Importer(MLIRContext *context, ModuleOp module) 48 : b(context), context(context), module(module), 49 unknownLoc(FileLineColLoc::get("imported-bitcode", 0, 0, context)) { 50 b.setInsertionPointToStart(module.getBody()); 51 dialect = context->getRegisteredDialect<LLVMDialect>(); 52 } 53 54 /// Imports `f` into the current module. 55 LogicalResult processFunction(llvm::Function *f); 56 57 /// Imports GV as a GlobalOp, creating it if it doesn't exist. 58 GlobalOp processGlobal(llvm::GlobalVariable *GV); 59 60 private: 61 /// Imports `bb` into `block`, which must be initially empty. 62 LogicalResult processBasicBlock(llvm::BasicBlock *bb, Block *block); 63 /// Imports `inst` and populates instMap[inst] with the imported Value. 64 LogicalResult processInstruction(llvm::Instruction *inst); 65 /// Creates an LLVMType for `type`. 66 LLVMType processType(llvm::Type *type); 67 /// `value` is an SSA-use. Return the remapped version of `value` or a 68 /// placeholder that will be remapped later if this is an instruction that 69 /// has not yet been visited. 70 Value processValue(llvm::Value *value); 71 /// Create the most accurate Location possible using a llvm::DebugLoc and 72 /// possibly an llvm::Instruction to narrow the Location if debug information 73 /// is unavailable. 74 Location processDebugLoc(const llvm::DebugLoc &loc, 75 llvm::Instruction *inst = nullptr); 76 /// `br` branches to `target`. Return the block arguments to attach to the 77 /// generated branch op. These should be in the same order as the PHIs in 78 /// `target`. 79 SmallVector<Value, 4> processBranchArgs(llvm::BranchInst *br, 80 llvm::BasicBlock *target); 81 /// Return `value` as an attribute to attach to a GlobalOp. 82 Attribute getConstantAsAttr(llvm::Constant *value); 83 /// Return `c` as an MLIR Value. This could either be a ConstantOp, or 84 /// an expanded sequence of ops in the current function's entry block (for 85 /// ConstantExprs or ConstantGEPs). 86 Value processConstant(llvm::Constant *c); 87 88 /// The current builder, pointing at where the next Instruction should be 89 /// generated. 90 OpBuilder b; 91 /// The current context. 92 MLIRContext *context; 93 /// The current module being created. 94 ModuleOp module; 95 /// The entry block of the current function being processed. 96 Block *currentEntryBlock; 97 98 /// Globals are inserted before the first function, if any. 99 Block::iterator getGlobalInsertPt() { 100 auto i = module.getBody()->begin(); 101 while (!isa<LLVMFuncOp>(i) && !isa<ModuleTerminatorOp>(i)) 102 ++i; 103 return i; 104 } 105 106 /// Functions are always inserted before the module terminator. 107 Block::iterator getFuncInsertPt() { 108 return std::prev(module.getBody()->end()); 109 } 110 111 /// Remapped blocks, for the current function. 112 DenseMap<llvm::BasicBlock *, Block *> blocks; 113 /// Remapped values. These are function-local. 114 DenseMap<llvm::Value *, Value> instMap; 115 /// Instructions that had not been defined when first encountered as a use. 116 /// Maps to the dummy Operation that was created in processValue(). 117 DenseMap<llvm::Value *, Operation *> unknownInstMap; 118 /// Uniquing map of GlobalVariables. 119 DenseMap<llvm::GlobalVariable *, GlobalOp> globals; 120 /// Cached FileLineColLoc::get("imported-bitcode", 0, 0). 121 Location unknownLoc; 122 /// Cached dialect. 123 LLVMDialect *dialect; 124 }; 125 } // namespace 126 127 Location Importer::processDebugLoc(const llvm::DebugLoc &loc, 128 llvm::Instruction *inst) { 129 if (!loc && inst) { 130 std::string s; 131 llvm::raw_string_ostream os(s); 132 os << "llvm-imported-inst-%"; 133 inst->printAsOperand(os, /*PrintType=*/false); 134 return FileLineColLoc::get(os.str(), 0, 0, context); 135 } else if (!loc) { 136 return unknownLoc; 137 } 138 // FIXME: Obtain the filename from DILocationInfo. 139 return FileLineColLoc::get("imported-bitcode", loc.getLine(), loc.getCol(), 140 context); 141 } 142 143 LLVMType Importer::processType(llvm::Type *type) { 144 switch (type->getTypeID()) { 145 case llvm::Type::FloatTyID: 146 return LLVMType::getFloatTy(dialect); 147 case llvm::Type::DoubleTyID: 148 return LLVMType::getDoubleTy(dialect); 149 case llvm::Type::IntegerTyID: 150 return LLVMType::getIntNTy(dialect, type->getIntegerBitWidth()); 151 case llvm::Type::PointerTyID: 152 return processType(type->getPointerElementType()) 153 .getPointerTo(type->getPointerAddressSpace()); 154 case llvm::Type::ArrayTyID: 155 return LLVMType::getArrayTy(processType(type->getArrayElementType()), 156 type->getArrayNumElements()); 157 case llvm::Type::VectorTyID: { 158 if (type->getVectorIsScalable()) 159 emitError(unknownLoc) << "scalable vector types not supported"; 160 return LLVMType::getVectorTy(processType(type->getVectorElementType()), 161 type->getVectorNumElements()); 162 } 163 case llvm::Type::VoidTyID: 164 return LLVMType::getVoidTy(dialect); 165 case llvm::Type::FP128TyID: 166 return LLVMType::getFP128Ty(dialect); 167 case llvm::Type::X86_FP80TyID: 168 return LLVMType::getX86_FP80Ty(dialect); 169 case llvm::Type::StructTyID: { 170 SmallVector<LLVMType, 4> elementTypes; 171 for (unsigned i = 0, e = type->getStructNumElements(); i != e; ++i) 172 elementTypes.push_back(processType(type->getStructElementType(i))); 173 return LLVMType::getStructTy(dialect, elementTypes, 174 cast<llvm::StructType>(type)->isPacked()); 175 } 176 case llvm::Type::FunctionTyID: { 177 llvm::FunctionType *fty = cast<llvm::FunctionType>(type); 178 SmallVector<LLVMType, 4> paramTypes; 179 for (unsigned i = 0, e = fty->getNumParams(); i != e; ++i) 180 paramTypes.push_back(processType(fty->getParamType(i))); 181 return LLVMType::getFunctionTy(processType(fty->getReturnType()), 182 paramTypes, fty->isVarArg()); 183 } 184 default: { 185 // FIXME: Diagnostic should be able to natively handle types that have 186 // operator<<(raw_ostream&) defined. 187 std::string s; 188 llvm::raw_string_ostream os(s); 189 os << *type; 190 emitError(unknownLoc) << "unhandled type: " << os.str(); 191 return {}; 192 } 193 } 194 } 195 196 // Get the given constant as an attribute. Not all constants can be represented 197 // as attributes. 198 Attribute Importer::getConstantAsAttr(llvm::Constant *value) { 199 if (auto *ci = dyn_cast<llvm::ConstantInt>(value)) 200 return b.getIntegerAttr( 201 IntegerType::get(ci->getType()->getBitWidth(), context), 202 ci->getValue()); 203 if (auto *c = dyn_cast<llvm::ConstantDataArray>(value)) 204 if (c->isString()) 205 return b.getStringAttr(c->getAsString()); 206 return Attribute(); 207 } 208 209 /// Converts LLVM global variable linkage type into the LLVM dialect predicate. 210 static LLVM::Linkage 211 processLinkage(llvm::GlobalVariable::LinkageTypes linkage) { 212 switch (linkage) { 213 case llvm::GlobalValue::PrivateLinkage: 214 return LLVM::Linkage::Private; 215 case llvm::GlobalValue::InternalLinkage: 216 return LLVM::Linkage::Internal; 217 case llvm::GlobalValue::AvailableExternallyLinkage: 218 return LLVM::Linkage::AvailableExternally; 219 case llvm::GlobalValue::LinkOnceAnyLinkage: 220 return LLVM::Linkage::Linkonce; 221 case llvm::GlobalValue::WeakAnyLinkage: 222 return LLVM::Linkage::Weak; 223 case llvm::GlobalValue::CommonLinkage: 224 return LLVM::Linkage::Common; 225 case llvm::GlobalValue::AppendingLinkage: 226 return LLVM::Linkage::Appending; 227 case llvm::GlobalValue::ExternalWeakLinkage: 228 return LLVM::Linkage::ExternWeak; 229 case llvm::GlobalValue::LinkOnceODRLinkage: 230 return LLVM::Linkage::LinkonceODR; 231 case llvm::GlobalValue::WeakODRLinkage: 232 return LLVM::Linkage::WeakODR; 233 case llvm::GlobalValue::ExternalLinkage: 234 return LLVM::Linkage::External; 235 } 236 237 llvm_unreachable("unhandled linkage type"); 238 } 239 240 GlobalOp Importer::processGlobal(llvm::GlobalVariable *GV) { 241 auto it = globals.find(GV); 242 if (it != globals.end()) 243 return it->second; 244 245 OpBuilder b(module.getBody(), getGlobalInsertPt()); 246 Attribute valueAttr; 247 if (GV->hasInitializer()) 248 valueAttr = getConstantAsAttr(GV->getInitializer()); 249 GlobalOp op = b.create<GlobalOp>( 250 UnknownLoc::get(context), processType(GV->getValueType()), 251 GV->isConstant(), processLinkage(GV->getLinkage()), GV->getName(), 252 valueAttr); 253 if (GV->hasInitializer() && !valueAttr) { 254 Region &r = op.getInitializerRegion(); 255 currentEntryBlock = b.createBlock(&r); 256 b.setInsertionPoint(currentEntryBlock, currentEntryBlock->begin()); 257 Value v = processConstant(GV->getInitializer()); 258 b.create<ReturnOp>(op.getLoc(), ArrayRef<Value>({v})); 259 } 260 return globals[GV] = op; 261 } 262 263 Value Importer::processConstant(llvm::Constant *c) { 264 if (Attribute attr = getConstantAsAttr(c)) { 265 // These constants can be represented as attributes. 266 OpBuilder b(currentEntryBlock, currentEntryBlock->begin()); 267 return instMap[c] = b.create<ConstantOp>(unknownLoc, 268 processType(c->getType()), attr); 269 } 270 if (auto *cn = dyn_cast<llvm::ConstantPointerNull>(c)) { 271 OpBuilder b(currentEntryBlock, currentEntryBlock->begin()); 272 return instMap[c] = 273 b.create<NullOp>(unknownLoc, processType(cn->getType())); 274 } 275 if (auto *ce = dyn_cast<llvm::ConstantExpr>(c)) { 276 llvm::Instruction *i = ce->getAsInstruction(); 277 OpBuilder::InsertionGuard guard(b); 278 b.setInsertionPoint(currentEntryBlock, currentEntryBlock->begin()); 279 if (failed(processInstruction(i))) 280 return nullptr; 281 assert(instMap.count(i)); 282 283 // Remove this zombie LLVM instruction now, leaving us only with the MLIR 284 // op. 285 i->deleteValue(); 286 return instMap[c] = instMap[i]; 287 } 288 emitError(unknownLoc) << "unhandled constant: " << diag(*c); 289 return nullptr; 290 } 291 292 Value Importer::processValue(llvm::Value *value) { 293 auto it = instMap.find(value); 294 if (it != instMap.end()) 295 return it->second; 296 297 // We don't expect to see instructions in dominator order. If we haven't seen 298 // this instruction yet, create an unknown op and remap it later. 299 if (isa<llvm::Instruction>(value)) { 300 OperationState state(UnknownLoc::get(context), "unknown"); 301 state.addTypes({processType(value->getType())}); 302 unknownInstMap[value] = b.createOperation(state); 303 return unknownInstMap[value]->getResult(0); 304 } 305 306 if (auto *GV = dyn_cast<llvm::GlobalVariable>(value)) { 307 return b.create<AddressOfOp>(UnknownLoc::get(context), processGlobal(GV), 308 ArrayRef<NamedAttribute>()); 309 } 310 311 // Note, constant global variables are both GlobalVariables and Constants, 312 // so we handle GlobalVariables first above. 313 if (auto *c = dyn_cast<llvm::Constant>(value)) 314 return processConstant(c); 315 316 emitError(unknownLoc) << "unhandled value: " << diag(*value); 317 return nullptr; 318 } 319 320 // Maps from LLVM opcode to MLIR OperationName. This is deliberately ordered 321 // as in llvm/IR/Instructions.def to aid comprehension and spot missing 322 // instructions. 323 #define INST(llvm_n, mlir_n) \ 324 { llvm::Instruction::llvm_n, LLVM::mlir_n##Op::getOperationName() } 325 static const DenseMap<unsigned, StringRef> opcMap = { 326 // Ret is handled specially. 327 // Br is handled specially. 328 // FIXME: switch 329 // FIXME: indirectbr 330 // FIXME: invoke 331 // FIXME: resume 332 // FIXME: unreachable 333 // FIXME: cleanupret 334 // FIXME: catchret 335 // FIXME: catchswitch 336 // FIXME: callbr 337 // FIXME: fneg 338 INST(Add, Add), INST(FAdd, FAdd), INST(Sub, Sub), INST(FSub, FSub), 339 INST(Mul, Mul), INST(FMul, FMul), INST(UDiv, UDiv), INST(SDiv, SDiv), 340 INST(FDiv, FDiv), INST(URem, URem), INST(SRem, SRem), INST(FRem, FRem), 341 INST(Shl, Shl), INST(LShr, LShr), INST(AShr, AShr), INST(And, And), 342 INST(Or, Or), INST(Xor, XOr), INST(Alloca, Alloca), INST(Load, Load), 343 INST(Store, Store), 344 // Getelementptr is handled specially. 345 INST(Ret, Return), 346 // FIXME: fence 347 // FIXME: atomiccmpxchg 348 // FIXME: atomicrmw 349 INST(Trunc, Trunc), INST(ZExt, ZExt), INST(SExt, SExt), 350 INST(FPToUI, FPToUI), INST(FPToSI, FPToSI), INST(UIToFP, UIToFP), 351 INST(SIToFP, SIToFP), INST(FPTrunc, FPTrunc), INST(FPExt, FPExt), 352 INST(PtrToInt, PtrToInt), INST(IntToPtr, IntToPtr), INST(BitCast, Bitcast), 353 INST(AddrSpaceCast, AddrSpaceCast), 354 // FIXME: cleanuppad 355 // FIXME: catchpad 356 // ICmp is handled specially. 357 // FIXME: fcmp 358 // PHI is handled specially. 359 INST(Call, Call), 360 // FIXME: select 361 // FIXME: vaarg 362 // FIXME: extractelement 363 // FIXME: insertelement 364 // FIXME: shufflevector 365 // FIXME: extractvalue 366 // FIXME: insertvalue 367 // FIXME: landingpad 368 }; 369 #undef INST 370 371 static ICmpPredicate getICmpPredicate(llvm::CmpInst::Predicate p) { 372 switch (p) { 373 default: 374 llvm_unreachable("incorrect comparison predicate"); 375 case llvm::CmpInst::Predicate::ICMP_EQ: 376 return LLVM::ICmpPredicate::eq; 377 case llvm::CmpInst::Predicate::ICMP_NE: 378 return LLVM::ICmpPredicate::ne; 379 case llvm::CmpInst::Predicate::ICMP_SLT: 380 return LLVM::ICmpPredicate::slt; 381 case llvm::CmpInst::Predicate::ICMP_SLE: 382 return LLVM::ICmpPredicate::sle; 383 case llvm::CmpInst::Predicate::ICMP_SGT: 384 return LLVM::ICmpPredicate::sgt; 385 case llvm::CmpInst::Predicate::ICMP_SGE: 386 return LLVM::ICmpPredicate::sge; 387 case llvm::CmpInst::Predicate::ICMP_ULT: 388 return LLVM::ICmpPredicate::ult; 389 case llvm::CmpInst::Predicate::ICMP_ULE: 390 return LLVM::ICmpPredicate::ule; 391 case llvm::CmpInst::Predicate::ICMP_UGT: 392 return LLVM::ICmpPredicate::ugt; 393 case llvm::CmpInst::Predicate::ICMP_UGE: 394 return LLVM::ICmpPredicate::uge; 395 } 396 llvm_unreachable("incorrect comparison predicate"); 397 } 398 399 // `br` branches to `target`. Return the branch arguments to `br`, in the 400 // same order of the PHIs in `target`. 401 SmallVector<Value, 4> Importer::processBranchArgs(llvm::BranchInst *br, 402 llvm::BasicBlock *target) { 403 SmallVector<Value, 4> v; 404 for (auto inst = target->begin(); isa<llvm::PHINode>(inst); ++inst) { 405 auto *PN = cast<llvm::PHINode>(&*inst); 406 v.push_back(processValue(PN->getIncomingValueForBlock(br->getParent()))); 407 } 408 return v; 409 } 410 411 LogicalResult Importer::processInstruction(llvm::Instruction *inst) { 412 // FIXME: Support uses of SubtargetData. Currently inbounds GEPs, fast-math 413 // flags and call / operand attributes are not supported. 414 Location loc = processDebugLoc(inst->getDebugLoc(), inst); 415 Value &v = instMap[inst]; 416 assert(!v && "processInstruction must be called only once per instruction!"); 417 switch (inst->getOpcode()) { 418 default: 419 return emitError(loc) << "unknown instruction: " << diag(*inst); 420 case llvm::Instruction::Add: 421 case llvm::Instruction::FAdd: 422 case llvm::Instruction::Sub: 423 case llvm::Instruction::FSub: 424 case llvm::Instruction::Mul: 425 case llvm::Instruction::FMul: 426 case llvm::Instruction::UDiv: 427 case llvm::Instruction::SDiv: 428 case llvm::Instruction::FDiv: 429 case llvm::Instruction::URem: 430 case llvm::Instruction::SRem: 431 case llvm::Instruction::FRem: 432 case llvm::Instruction::Shl: 433 case llvm::Instruction::LShr: 434 case llvm::Instruction::AShr: 435 case llvm::Instruction::And: 436 case llvm::Instruction::Or: 437 case llvm::Instruction::Xor: 438 case llvm::Instruction::Alloca: 439 case llvm::Instruction::Load: 440 case llvm::Instruction::Store: 441 case llvm::Instruction::Ret: 442 case llvm::Instruction::Trunc: 443 case llvm::Instruction::ZExt: 444 case llvm::Instruction::SExt: 445 case llvm::Instruction::FPToUI: 446 case llvm::Instruction::FPToSI: 447 case llvm::Instruction::UIToFP: 448 case llvm::Instruction::SIToFP: 449 case llvm::Instruction::FPTrunc: 450 case llvm::Instruction::FPExt: 451 case llvm::Instruction::PtrToInt: 452 case llvm::Instruction::IntToPtr: 453 case llvm::Instruction::AddrSpaceCast: 454 case llvm::Instruction::BitCast: { 455 OperationState state(loc, opcMap.lookup(inst->getOpcode())); 456 SmallVector<Value, 4> ops; 457 ops.reserve(inst->getNumOperands()); 458 for (auto *op : inst->operand_values()) 459 ops.push_back(processValue(op)); 460 state.addOperands(ops); 461 if (!inst->getType()->isVoidTy()) 462 state.addTypes(ArrayRef<Type>({processType(inst->getType())})); 463 Operation *op = b.createOperation(state); 464 if (!inst->getType()->isVoidTy()) 465 v = op->getResult(0); 466 return success(); 467 } 468 case llvm::Instruction::ICmp: { 469 v = b.create<ICmpOp>( 470 loc, getICmpPredicate(cast<llvm::ICmpInst>(inst)->getPredicate()), 471 processValue(inst->getOperand(0)), processValue(inst->getOperand(1))); 472 return success(); 473 } 474 case llvm::Instruction::Br: { 475 auto *brInst = cast<llvm::BranchInst>(inst); 476 OperationState state(loc, 477 brInst->isConditional() ? "llvm.cond_br" : "llvm.br"); 478 SmallVector<Value, 4> ops; 479 if (brInst->isConditional()) 480 ops.push_back(processValue(brInst->getCondition())); 481 state.addOperands(ops); 482 SmallVector<Block *, 4> succs; 483 for (auto *succ : llvm::reverse(brInst->successors())) 484 state.addSuccessor(blocks[succ], processBranchArgs(brInst, succ)); 485 b.createOperation(state); 486 return success(); 487 } 488 case llvm::Instruction::PHI: { 489 v = b.getInsertionBlock()->addArgument(processType(inst->getType())); 490 return success(); 491 } 492 case llvm::Instruction::Call: { 493 llvm::CallInst *ci = cast<llvm::CallInst>(inst); 494 SmallVector<Value, 4> ops; 495 ops.reserve(inst->getNumOperands()); 496 for (auto &op : ci->arg_operands()) 497 ops.push_back(processValue(op.get())); 498 499 SmallVector<Type, 2> tys; 500 if (!ci->getType()->isVoidTy()) 501 tys.push_back(processType(inst->getType())); 502 Operation *op; 503 if (llvm::Function *callee = ci->getCalledFunction()) { 504 op = b.create<CallOp>(loc, tys, b.getSymbolRefAttr(callee->getName()), 505 ops); 506 } else { 507 ops.insert(ops.begin(), processValue(ci->getCalledValue())); 508 op = b.create<CallOp>(loc, tys, ops, ArrayRef<NamedAttribute>()); 509 } 510 if (!ci->getType()->isVoidTy()) 511 v = op->getResult(0); 512 return success(); 513 } 514 case llvm::Instruction::GetElementPtr: { 515 // FIXME: Support inbounds GEPs. 516 llvm::GetElementPtrInst *gep = cast<llvm::GetElementPtrInst>(inst); 517 SmallVector<Value, 4> ops; 518 for (auto *op : gep->operand_values()) 519 ops.push_back(processValue(op)); 520 v = b.create<GEPOp>(loc, processType(inst->getType()), ops, 521 ArrayRef<NamedAttribute>()); 522 return success(); 523 } 524 } 525 } 526 527 LogicalResult Importer::processFunction(llvm::Function *f) { 528 blocks.clear(); 529 instMap.clear(); 530 unknownInstMap.clear(); 531 532 b.setInsertionPoint(module.getBody(), getFuncInsertPt()); 533 LLVMFuncOp fop = b.create<LLVMFuncOp>(UnknownLoc::get(context), f->getName(), 534 processType(f->getFunctionType())); 535 if (f->isDeclaration()) 536 return success(); 537 538 // Eagerly create all blocks. 539 SmallVector<Block *, 4> blockList; 540 for (llvm::BasicBlock &bb : *f) { 541 blockList.push_back(b.createBlock(&fop.body(), fop.body().end())); 542 blocks[&bb] = blockList.back(); 543 } 544 currentEntryBlock = blockList[0]; 545 546 // Add function arguments to the entry block. 547 for (auto &arg : f->args()) 548 instMap[&arg] = blockList[0]->addArgument(processType(arg.getType())); 549 550 for (auto bbs : llvm::zip(*f, blockList)) { 551 if (failed(processBasicBlock(&std::get<0>(bbs), std::get<1>(bbs)))) 552 return failure(); 553 } 554 555 // Now that all instructions are guaranteed to have been visited, ensure 556 // any unknown uses we encountered are remapped. 557 for (auto &llvmAndUnknown : unknownInstMap) { 558 assert(instMap.count(llvmAndUnknown.first)); 559 Value newValue = instMap[llvmAndUnknown.first]; 560 Value oldValue = llvmAndUnknown.second->getResult(0); 561 oldValue->replaceAllUsesWith(newValue); 562 llvmAndUnknown.second->erase(); 563 } 564 return success(); 565 } 566 567 LogicalResult Importer::processBasicBlock(llvm::BasicBlock *bb, Block *block) { 568 b.setInsertionPointToStart(block); 569 for (llvm::Instruction &inst : *bb) { 570 if (failed(processInstruction(&inst))) 571 return failure(); 572 } 573 return success(); 574 } 575 576 OwningModuleRef 577 mlir::translateLLVMIRToModule(std::unique_ptr<llvm::Module> llvmModule, 578 MLIRContext *context) { 579 OwningModuleRef module(ModuleOp::create( 580 FileLineColLoc::get("", /*line=*/0, /*column=*/0, context))); 581 582 Importer deserializer(context, module.get()); 583 for (llvm::GlobalVariable &gv : llvmModule->globals()) { 584 if (!deserializer.processGlobal(&gv)) 585 return {}; 586 } 587 for (llvm::Function &f : llvmModule->functions()) { 588 if (failed(deserializer.processFunction(&f))) 589 return {}; 590 } 591 592 return module; 593 } 594 595 // Deserializes the LLVM bitcode stored in `input` into an MLIR module in the 596 // LLVM dialect. 597 OwningModuleRef translateLLVMIRToModule(llvm::SourceMgr &sourceMgr, 598 MLIRContext *context) { 599 LLVMDialect *dialect = context->getRegisteredDialect<LLVMDialect>(); 600 assert(dialect && "Could not find LLVMDialect?"); 601 602 llvm::SMDiagnostic err; 603 std::unique_ptr<llvm::Module> llvmModule = 604 llvm::parseIR(*sourceMgr.getMemoryBuffer(sourceMgr.getMainFileID()), err, 605 dialect->getLLVMContext(), 606 /*UpgradeDebugInfo=*/true, 607 /*DataLayoutString=*/""); 608 if (!llvmModule) { 609 std::string errStr; 610 llvm::raw_string_ostream errStream(errStr); 611 err.print(/*ProgName=*/"", errStream); 612 emitError(UnknownLoc::get(context)) << errStream.str(); 613 return {}; 614 } 615 return translateLLVMIRToModule(std::move(llvmModule), context); 616 } 617 618 static TranslateToMLIRRegistration 619 fromLLVM("import-llvm", 620 [](llvm::SourceMgr &sourceMgr, MLIRContext *context) { 621 return translateLLVMIRToModule(sourceMgr, context); 622 }); 623