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 if (auto *c = dyn_cast<llvm::ConstantFP>(value)) { 207 if (c->getType()->isDoubleTy()) 208 return b.getFloatAttr(FloatType::getF64(context), c->getValueAPF()); 209 else if (c->getType()->isFloatingPointTy()) 210 return b.getFloatAttr(FloatType::getF32(context), c->getValueAPF()); 211 } 212 return Attribute(); 213 } 214 215 /// Converts LLVM global variable linkage type into the LLVM dialect predicate. 216 static LLVM::Linkage 217 processLinkage(llvm::GlobalVariable::LinkageTypes linkage) { 218 switch (linkage) { 219 case llvm::GlobalValue::PrivateLinkage: 220 return LLVM::Linkage::Private; 221 case llvm::GlobalValue::InternalLinkage: 222 return LLVM::Linkage::Internal; 223 case llvm::GlobalValue::AvailableExternallyLinkage: 224 return LLVM::Linkage::AvailableExternally; 225 case llvm::GlobalValue::LinkOnceAnyLinkage: 226 return LLVM::Linkage::Linkonce; 227 case llvm::GlobalValue::WeakAnyLinkage: 228 return LLVM::Linkage::Weak; 229 case llvm::GlobalValue::CommonLinkage: 230 return LLVM::Linkage::Common; 231 case llvm::GlobalValue::AppendingLinkage: 232 return LLVM::Linkage::Appending; 233 case llvm::GlobalValue::ExternalWeakLinkage: 234 return LLVM::Linkage::ExternWeak; 235 case llvm::GlobalValue::LinkOnceODRLinkage: 236 return LLVM::Linkage::LinkonceODR; 237 case llvm::GlobalValue::WeakODRLinkage: 238 return LLVM::Linkage::WeakODR; 239 case llvm::GlobalValue::ExternalLinkage: 240 return LLVM::Linkage::External; 241 } 242 243 llvm_unreachable("unhandled linkage type"); 244 } 245 246 GlobalOp Importer::processGlobal(llvm::GlobalVariable *GV) { 247 auto it = globals.find(GV); 248 if (it != globals.end()) 249 return it->second; 250 251 OpBuilder b(module.getBody(), getGlobalInsertPt()); 252 Attribute valueAttr; 253 if (GV->hasInitializer()) 254 valueAttr = getConstantAsAttr(GV->getInitializer()); 255 GlobalOp op = b.create<GlobalOp>( 256 UnknownLoc::get(context), processType(GV->getValueType()), 257 GV->isConstant(), processLinkage(GV->getLinkage()), GV->getName(), 258 valueAttr); 259 if (GV->hasInitializer() && !valueAttr) { 260 Region &r = op.getInitializerRegion(); 261 currentEntryBlock = b.createBlock(&r); 262 b.setInsertionPoint(currentEntryBlock, currentEntryBlock->begin()); 263 Value v = processConstant(GV->getInitializer()); 264 b.create<ReturnOp>(op.getLoc(), ArrayRef<Value>({v})); 265 } 266 return globals[GV] = op; 267 } 268 269 Value Importer::processConstant(llvm::Constant *c) { 270 if (Attribute attr = getConstantAsAttr(c)) { 271 // These constants can be represented as attributes. 272 OpBuilder b(currentEntryBlock, currentEntryBlock->begin()); 273 return instMap[c] = b.create<ConstantOp>(unknownLoc, 274 processType(c->getType()), attr); 275 } 276 if (auto *cn = dyn_cast<llvm::ConstantPointerNull>(c)) { 277 OpBuilder b(currentEntryBlock, currentEntryBlock->begin()); 278 return instMap[c] = 279 b.create<NullOp>(unknownLoc, processType(cn->getType())); 280 } 281 if (auto *ce = dyn_cast<llvm::ConstantExpr>(c)) { 282 llvm::Instruction *i = ce->getAsInstruction(); 283 OpBuilder::InsertionGuard guard(b); 284 b.setInsertionPoint(currentEntryBlock, currentEntryBlock->begin()); 285 if (failed(processInstruction(i))) 286 return nullptr; 287 assert(instMap.count(i)); 288 289 // Remove this zombie LLVM instruction now, leaving us only with the MLIR 290 // op. 291 i->deleteValue(); 292 return instMap[c] = instMap[i]; 293 } 294 emitError(unknownLoc) << "unhandled constant: " << diag(*c); 295 return nullptr; 296 } 297 298 Value Importer::processValue(llvm::Value *value) { 299 auto it = instMap.find(value); 300 if (it != instMap.end()) 301 return it->second; 302 303 // We don't expect to see instructions in dominator order. If we haven't seen 304 // this instruction yet, create an unknown op and remap it later. 305 if (isa<llvm::Instruction>(value)) { 306 OperationState state(UnknownLoc::get(context), "unknown"); 307 state.addTypes({processType(value->getType())}); 308 unknownInstMap[value] = b.createOperation(state); 309 return unknownInstMap[value]->getResult(0); 310 } 311 312 if (auto *GV = dyn_cast<llvm::GlobalVariable>(value)) { 313 return b.create<AddressOfOp>(UnknownLoc::get(context), processGlobal(GV), 314 ArrayRef<NamedAttribute>()); 315 } 316 317 // Note, constant global variables are both GlobalVariables and Constants, 318 // so we handle GlobalVariables first above. 319 if (auto *c = dyn_cast<llvm::Constant>(value)) 320 return processConstant(c); 321 322 emitError(unknownLoc) << "unhandled value: " << diag(*value); 323 return nullptr; 324 } 325 326 // Maps from LLVM opcode to MLIR OperationName. This is deliberately ordered 327 // as in llvm/IR/Instructions.def to aid comprehension and spot missing 328 // instructions. 329 #define INST(llvm_n, mlir_n) \ 330 { llvm::Instruction::llvm_n, LLVM::mlir_n##Op::getOperationName() } 331 static const DenseMap<unsigned, StringRef> opcMap = { 332 // Ret is handled specially. 333 // Br is handled specially. 334 // FIXME: switch 335 // FIXME: indirectbr 336 // FIXME: invoke 337 // FIXME: resume 338 // FIXME: unreachable 339 // FIXME: cleanupret 340 // FIXME: catchret 341 // FIXME: catchswitch 342 // FIXME: callbr 343 // FIXME: fneg 344 INST(Add, Add), INST(FAdd, FAdd), INST(Sub, Sub), INST(FSub, FSub), 345 INST(Mul, Mul), INST(FMul, FMul), INST(UDiv, UDiv), INST(SDiv, SDiv), 346 INST(FDiv, FDiv), INST(URem, URem), INST(SRem, SRem), INST(FRem, FRem), 347 INST(Shl, Shl), INST(LShr, LShr), INST(AShr, AShr), INST(And, And), 348 INST(Or, Or), INST(Xor, XOr), INST(Alloca, Alloca), INST(Load, Load), 349 INST(Store, Store), 350 // Getelementptr is handled specially. 351 INST(Ret, Return), 352 // FIXME: fence 353 // FIXME: atomiccmpxchg 354 // FIXME: atomicrmw 355 INST(Trunc, Trunc), INST(ZExt, ZExt), INST(SExt, SExt), 356 INST(FPToUI, FPToUI), INST(FPToSI, FPToSI), INST(UIToFP, UIToFP), 357 INST(SIToFP, SIToFP), INST(FPTrunc, FPTrunc), INST(FPExt, FPExt), 358 INST(PtrToInt, PtrToInt), INST(IntToPtr, IntToPtr), INST(BitCast, Bitcast), 359 INST(AddrSpaceCast, AddrSpaceCast), 360 // FIXME: cleanuppad 361 // FIXME: catchpad 362 // ICmp is handled specially. 363 // FIXME: fcmp 364 // PHI is handled specially. 365 INST(Call, Call), 366 // FIXME: select 367 // FIXME: vaarg 368 // FIXME: extractelement 369 // FIXME: insertelement 370 // FIXME: shufflevector 371 // FIXME: extractvalue 372 // FIXME: insertvalue 373 // FIXME: landingpad 374 }; 375 #undef INST 376 377 static ICmpPredicate getICmpPredicate(llvm::CmpInst::Predicate p) { 378 switch (p) { 379 default: 380 llvm_unreachable("incorrect comparison predicate"); 381 case llvm::CmpInst::Predicate::ICMP_EQ: 382 return LLVM::ICmpPredicate::eq; 383 case llvm::CmpInst::Predicate::ICMP_NE: 384 return LLVM::ICmpPredicate::ne; 385 case llvm::CmpInst::Predicate::ICMP_SLT: 386 return LLVM::ICmpPredicate::slt; 387 case llvm::CmpInst::Predicate::ICMP_SLE: 388 return LLVM::ICmpPredicate::sle; 389 case llvm::CmpInst::Predicate::ICMP_SGT: 390 return LLVM::ICmpPredicate::sgt; 391 case llvm::CmpInst::Predicate::ICMP_SGE: 392 return LLVM::ICmpPredicate::sge; 393 case llvm::CmpInst::Predicate::ICMP_ULT: 394 return LLVM::ICmpPredicate::ult; 395 case llvm::CmpInst::Predicate::ICMP_ULE: 396 return LLVM::ICmpPredicate::ule; 397 case llvm::CmpInst::Predicate::ICMP_UGT: 398 return LLVM::ICmpPredicate::ugt; 399 case llvm::CmpInst::Predicate::ICMP_UGE: 400 return LLVM::ICmpPredicate::uge; 401 } 402 llvm_unreachable("incorrect comparison predicate"); 403 } 404 405 // `br` branches to `target`. Return the branch arguments to `br`, in the 406 // same order of the PHIs in `target`. 407 SmallVector<Value, 4> Importer::processBranchArgs(llvm::BranchInst *br, 408 llvm::BasicBlock *target) { 409 SmallVector<Value, 4> v; 410 for (auto inst = target->begin(); isa<llvm::PHINode>(inst); ++inst) { 411 auto *PN = cast<llvm::PHINode>(&*inst); 412 v.push_back(processValue(PN->getIncomingValueForBlock(br->getParent()))); 413 } 414 return v; 415 } 416 417 LogicalResult Importer::processInstruction(llvm::Instruction *inst) { 418 // FIXME: Support uses of SubtargetData. Currently inbounds GEPs, fast-math 419 // flags and call / operand attributes are not supported. 420 Location loc = processDebugLoc(inst->getDebugLoc(), inst); 421 Value &v = instMap[inst]; 422 assert(!v && "processInstruction must be called only once per instruction!"); 423 switch (inst->getOpcode()) { 424 default: 425 return emitError(loc) << "unknown instruction: " << diag(*inst); 426 case llvm::Instruction::Add: 427 case llvm::Instruction::FAdd: 428 case llvm::Instruction::Sub: 429 case llvm::Instruction::FSub: 430 case llvm::Instruction::Mul: 431 case llvm::Instruction::FMul: 432 case llvm::Instruction::UDiv: 433 case llvm::Instruction::SDiv: 434 case llvm::Instruction::FDiv: 435 case llvm::Instruction::URem: 436 case llvm::Instruction::SRem: 437 case llvm::Instruction::FRem: 438 case llvm::Instruction::Shl: 439 case llvm::Instruction::LShr: 440 case llvm::Instruction::AShr: 441 case llvm::Instruction::And: 442 case llvm::Instruction::Or: 443 case llvm::Instruction::Xor: 444 case llvm::Instruction::Alloca: 445 case llvm::Instruction::Load: 446 case llvm::Instruction::Store: 447 case llvm::Instruction::Ret: 448 case llvm::Instruction::Trunc: 449 case llvm::Instruction::ZExt: 450 case llvm::Instruction::SExt: 451 case llvm::Instruction::FPToUI: 452 case llvm::Instruction::FPToSI: 453 case llvm::Instruction::UIToFP: 454 case llvm::Instruction::SIToFP: 455 case llvm::Instruction::FPTrunc: 456 case llvm::Instruction::FPExt: 457 case llvm::Instruction::PtrToInt: 458 case llvm::Instruction::IntToPtr: 459 case llvm::Instruction::AddrSpaceCast: 460 case llvm::Instruction::BitCast: { 461 OperationState state(loc, opcMap.lookup(inst->getOpcode())); 462 SmallVector<Value, 4> ops; 463 ops.reserve(inst->getNumOperands()); 464 for (auto *op : inst->operand_values()) 465 ops.push_back(processValue(op)); 466 state.addOperands(ops); 467 if (!inst->getType()->isVoidTy()) 468 state.addTypes(ArrayRef<Type>({processType(inst->getType())})); 469 Operation *op = b.createOperation(state); 470 if (!inst->getType()->isVoidTy()) 471 v = op->getResult(0); 472 return success(); 473 } 474 case llvm::Instruction::ICmp: { 475 v = b.create<ICmpOp>( 476 loc, getICmpPredicate(cast<llvm::ICmpInst>(inst)->getPredicate()), 477 processValue(inst->getOperand(0)), processValue(inst->getOperand(1))); 478 return success(); 479 } 480 case llvm::Instruction::Br: { 481 auto *brInst = cast<llvm::BranchInst>(inst); 482 OperationState state(loc, 483 brInst->isConditional() ? "llvm.cond_br" : "llvm.br"); 484 SmallVector<Value, 4> ops; 485 if (brInst->isConditional()) 486 ops.push_back(processValue(brInst->getCondition())); 487 state.addOperands(ops); 488 SmallVector<Block *, 4> succs; 489 for (auto *succ : llvm::reverse(brInst->successors())) 490 state.addSuccessor(blocks[succ], processBranchArgs(brInst, succ)); 491 b.createOperation(state); 492 return success(); 493 } 494 case llvm::Instruction::PHI: { 495 v = b.getInsertionBlock()->addArgument(processType(inst->getType())); 496 return success(); 497 } 498 case llvm::Instruction::Call: { 499 llvm::CallInst *ci = cast<llvm::CallInst>(inst); 500 SmallVector<Value, 4> ops; 501 ops.reserve(inst->getNumOperands()); 502 for (auto &op : ci->arg_operands()) 503 ops.push_back(processValue(op.get())); 504 505 SmallVector<Type, 2> tys; 506 if (!ci->getType()->isVoidTy()) 507 tys.push_back(processType(inst->getType())); 508 Operation *op; 509 if (llvm::Function *callee = ci->getCalledFunction()) { 510 op = b.create<CallOp>(loc, tys, b.getSymbolRefAttr(callee->getName()), 511 ops); 512 } else { 513 ops.insert(ops.begin(), processValue(ci->getCalledValue())); 514 op = b.create<CallOp>(loc, tys, ops, ArrayRef<NamedAttribute>()); 515 } 516 if (!ci->getType()->isVoidTy()) 517 v = op->getResult(0); 518 return success(); 519 } 520 case llvm::Instruction::GetElementPtr: { 521 // FIXME: Support inbounds GEPs. 522 llvm::GetElementPtrInst *gep = cast<llvm::GetElementPtrInst>(inst); 523 SmallVector<Value, 4> ops; 524 for (auto *op : gep->operand_values()) 525 ops.push_back(processValue(op)); 526 v = b.create<GEPOp>(loc, processType(inst->getType()), ops, 527 ArrayRef<NamedAttribute>()); 528 return success(); 529 } 530 } 531 } 532 533 LogicalResult Importer::processFunction(llvm::Function *f) { 534 blocks.clear(); 535 instMap.clear(); 536 unknownInstMap.clear(); 537 538 b.setInsertionPoint(module.getBody(), getFuncInsertPt()); 539 LLVMFuncOp fop = b.create<LLVMFuncOp>(UnknownLoc::get(context), f->getName(), 540 processType(f->getFunctionType())); 541 if (f->isDeclaration()) 542 return success(); 543 544 // Eagerly create all blocks. 545 SmallVector<Block *, 4> blockList; 546 for (llvm::BasicBlock &bb : *f) { 547 blockList.push_back(b.createBlock(&fop.body(), fop.body().end())); 548 blocks[&bb] = blockList.back(); 549 } 550 currentEntryBlock = blockList[0]; 551 552 // Add function arguments to the entry block. 553 for (auto &arg : f->args()) 554 instMap[&arg] = blockList[0]->addArgument(processType(arg.getType())); 555 556 for (auto bbs : llvm::zip(*f, blockList)) { 557 if (failed(processBasicBlock(&std::get<0>(bbs), std::get<1>(bbs)))) 558 return failure(); 559 } 560 561 // Now that all instructions are guaranteed to have been visited, ensure 562 // any unknown uses we encountered are remapped. 563 for (auto &llvmAndUnknown : unknownInstMap) { 564 assert(instMap.count(llvmAndUnknown.first)); 565 Value newValue = instMap[llvmAndUnknown.first]; 566 Value oldValue = llvmAndUnknown.second->getResult(0); 567 oldValue->replaceAllUsesWith(newValue); 568 llvmAndUnknown.second->erase(); 569 } 570 return success(); 571 } 572 573 LogicalResult Importer::processBasicBlock(llvm::BasicBlock *bb, Block *block) { 574 b.setInsertionPointToStart(block); 575 for (llvm::Instruction &inst : *bb) { 576 if (failed(processInstruction(&inst))) 577 return failure(); 578 } 579 return success(); 580 } 581 582 OwningModuleRef 583 mlir::translateLLVMIRToModule(std::unique_ptr<llvm::Module> llvmModule, 584 MLIRContext *context) { 585 OwningModuleRef module(ModuleOp::create( 586 FileLineColLoc::get("", /*line=*/0, /*column=*/0, context))); 587 588 Importer deserializer(context, module.get()); 589 for (llvm::GlobalVariable &gv : llvmModule->globals()) { 590 if (!deserializer.processGlobal(&gv)) 591 return {}; 592 } 593 for (llvm::Function &f : llvmModule->functions()) { 594 if (failed(deserializer.processFunction(&f))) 595 return {}; 596 } 597 598 return module; 599 } 600 601 // Deserializes the LLVM bitcode stored in `input` into an MLIR module in the 602 // LLVM dialect. 603 OwningModuleRef translateLLVMIRToModule(llvm::SourceMgr &sourceMgr, 604 MLIRContext *context) { 605 LLVMDialect *dialect = context->getRegisteredDialect<LLVMDialect>(); 606 assert(dialect && "Could not find LLVMDialect?"); 607 608 llvm::SMDiagnostic err; 609 std::unique_ptr<llvm::Module> llvmModule = 610 llvm::parseIR(*sourceMgr.getMemoryBuffer(sourceMgr.getMainFileID()), err, 611 dialect->getLLVMContext(), 612 /*UpgradeDebugInfo=*/true, 613 /*DataLayoutString=*/""); 614 if (!llvmModule) { 615 std::string errStr; 616 llvm::raw_string_ostream errStream(errStr); 617 err.print(/*ProgName=*/"", errStream); 618 emitError(UnknownLoc::get(context)) << errStream.str(); 619 return {}; 620 } 621 return translateLLVMIRToModule(std::move(llvmModule), context); 622 } 623 624 static TranslateToMLIRRegistration 625 fromLLVM("import-llvm", 626 [](llvm::SourceMgr &sourceMgr, MLIRContext *context) { 627 return translateLLVMIRToModule(sourceMgr, context); 628 }); 629