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