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