1 //===- ConvertFromLLVMIR.cpp - MLIR to LLVM IR conversion -----------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements a translation between LLVM IR and the MLIR LLVM dialect. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "mlir/Target/LLVMIR/Import.h" 14 15 #include "mlir/Dialect/LLVMIR/LLVMDialect.h" 16 #include "mlir/IR/Builders.h" 17 #include "mlir/IR/BuiltinOps.h" 18 #include "mlir/IR/BuiltinTypes.h" 19 #include "mlir/IR/MLIRContext.h" 20 #include "mlir/Target/LLVMIR/TypeFromLLVM.h" 21 #include "mlir/Translation.h" 22 23 #include "llvm/ADT/TypeSwitch.h" 24 #include "llvm/IR/Attributes.h" 25 #include "llvm/IR/Constants.h" 26 #include "llvm/IR/DerivedTypes.h" 27 #include "llvm/IR/Function.h" 28 #include "llvm/IR/InlineAsm.h" 29 #include "llvm/IR/Instructions.h" 30 #include "llvm/IR/Type.h" 31 #include "llvm/IRReader/IRReader.h" 32 #include "llvm/Support/Error.h" 33 #include "llvm/Support/SourceMgr.h" 34 35 using namespace mlir; 36 using namespace mlir::LLVM; 37 38 #include "mlir/Dialect/LLVMIR/LLVMConversionEnumsFromLLVM.inc" 39 40 // Utility to print an LLVM value as a string for passing to emitError(). 41 // FIXME: Diagnostic should be able to natively handle types that have 42 // operator << (raw_ostream&) defined. 43 static std::string diag(llvm::Value &v) { 44 std::string s; 45 llvm::raw_string_ostream os(s); 46 os << v; 47 return os.str(); 48 } 49 50 // Handles importing globals and functions from an LLVM module. 51 namespace { 52 class Importer { 53 public: 54 Importer(MLIRContext *context, ModuleOp module) 55 : b(context), context(context), module(module), 56 unknownLoc(FileLineColLoc::get(context, "imported-bitcode", 0, 0)), 57 typeTranslator(*context) { 58 b.setInsertionPointToStart(module.getBody()); 59 } 60 61 /// Imports `f` into the current module. 62 LogicalResult processFunction(llvm::Function *f); 63 64 /// Imports GV as a GlobalOp, creating it if it doesn't exist. 65 GlobalOp processGlobal(llvm::GlobalVariable *gv); 66 67 private: 68 /// Returns personality of `f` as a FlatSymbolRefAttr. 69 FlatSymbolRefAttr getPersonalityAsAttr(llvm::Function *f); 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 LLVM-compatible MLIR type for `type`. 75 Type 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`. Append the block arguments to attach to the 86 /// generated branch op to `blockArguments`. These should be in the same order 87 /// as the PHIs in `target`. 88 LogicalResult processBranchArgs(llvm::Instruction *br, 89 llvm::BasicBlock *target, 90 SmallVectorImpl<Value> &blockArguments); 91 /// Returns the builtin type equivalent to be used in attributes for the given 92 /// LLVM IR dialect type. 93 Type getStdTypeForAttr(Type type); 94 /// Return `value` as an attribute to attach to a GlobalOp. 95 Attribute getConstantAsAttr(llvm::Constant *value); 96 /// Return `c` as an MLIR Value. This could either be a ConstantOp, or 97 /// an expanded sequence of ops in the current function's entry block (for 98 /// ConstantExprs or ConstantGEPs). 99 Value processConstant(llvm::Constant *c); 100 101 /// The current builder, pointing at where the next Instruction should be 102 /// generated. 103 OpBuilder b; 104 /// The current context. 105 MLIRContext *context; 106 /// The current module being created. 107 ModuleOp module; 108 /// The entry block of the current function being processed. 109 Block *currentEntryBlock = nullptr; 110 111 /// Globals are inserted before the first function, if any. 112 Block::iterator getGlobalInsertPt() { 113 auto it = module.getBody()->begin(); 114 auto endIt = module.getBody()->end(); 115 while (it != endIt && !isa<LLVMFuncOp>(it)) 116 ++it; 117 return it; 118 } 119 120 /// Functions are always inserted before the module terminator. 121 Block::iterator getFuncInsertPt() { 122 return std::prev(module.getBody()->end()); 123 } 124 125 /// Remapped blocks, for the current function. 126 DenseMap<llvm::BasicBlock *, Block *> blocks; 127 /// Remapped values. These are function-local. 128 DenseMap<llvm::Value *, Value> instMap; 129 /// Instructions that had not been defined when first encountered as a use. 130 /// Maps to the dummy Operation that was created in processValue(). 131 DenseMap<llvm::Value *, Operation *> unknownInstMap; 132 /// Uniquing map of GlobalVariables. 133 DenseMap<llvm::GlobalVariable *, GlobalOp> globals; 134 /// Cached FileLineColLoc::get("imported-bitcode", 0, 0). 135 Location unknownLoc; 136 /// The stateful type translator (contains named structs). 137 LLVM::TypeFromLLVMIRTranslator typeTranslator; 138 }; 139 } // namespace 140 141 Location Importer::processDebugLoc(const llvm::DebugLoc &loc, 142 llvm::Instruction *inst) { 143 if (!loc && inst) { 144 std::string s; 145 llvm::raw_string_ostream os(s); 146 os << "llvm-imported-inst-%"; 147 inst->printAsOperand(os, /*PrintType=*/false); 148 return FileLineColLoc::get(context, os.str(), 0, 0); 149 } 150 if (!loc) { 151 return unknownLoc; 152 } 153 // FIXME: Obtain the filename from DILocationInfo. 154 return FileLineColLoc::get(context, "imported-bitcode", loc.getLine(), 155 loc.getCol()); 156 } 157 158 Type Importer::processType(llvm::Type *type) { 159 if (Type result = typeTranslator.translateType(type)) 160 return result; 161 162 // FIXME: Diagnostic should be able to natively handle types that have 163 // operator<<(raw_ostream&) defined. 164 std::string s; 165 llvm::raw_string_ostream os(s); 166 os << *type; 167 emitError(unknownLoc) << "unhandled type: " << os.str(); 168 return nullptr; 169 } 170 171 // We only need integers, floats, doubles, and vectors and tensors thereof for 172 // attributes. Scalar and vector types are converted to the standard 173 // equivalents. Array types are converted to ranked tensors; nested array types 174 // are converted to multi-dimensional tensors or vectors, depending on the 175 // innermost type being a scalar or a vector. 176 Type Importer::getStdTypeForAttr(Type type) { 177 if (!type) 178 return nullptr; 179 180 if (type.isa<IntegerType, FloatType>()) 181 return type; 182 183 // LLVM vectors can only contain scalars. 184 if (LLVM::isCompatibleVectorType(type)) { 185 auto numElements = LLVM::getVectorNumElements(type); 186 if (numElements.isScalable()) { 187 emitError(unknownLoc) << "scalable vectors not supported"; 188 return nullptr; 189 } 190 Type elementType = getStdTypeForAttr(LLVM::getVectorElementType(type)); 191 if (!elementType) 192 return nullptr; 193 return VectorType::get(numElements.getKnownMinValue(), elementType); 194 } 195 196 // LLVM arrays can contain other arrays or vectors. 197 if (auto arrayType = type.dyn_cast<LLVMArrayType>()) { 198 // Recover the nested array shape. 199 SmallVector<int64_t, 4> shape; 200 shape.push_back(arrayType.getNumElements()); 201 while (arrayType.getElementType().isa<LLVMArrayType>()) { 202 arrayType = arrayType.getElementType().cast<LLVMArrayType>(); 203 shape.push_back(arrayType.getNumElements()); 204 } 205 206 // If the innermost type is a vector, use the multi-dimensional vector as 207 // attribute type. 208 if (LLVM::isCompatibleVectorType(arrayType.getElementType())) { 209 auto numElements = LLVM::getVectorNumElements(arrayType.getElementType()); 210 if (numElements.isScalable()) { 211 emitError(unknownLoc) << "scalable vectors not supported"; 212 return nullptr; 213 } 214 shape.push_back(numElements.getKnownMinValue()); 215 216 Type elementType = getStdTypeForAttr( 217 LLVM::getVectorElementType(arrayType.getElementType())); 218 if (!elementType) 219 return nullptr; 220 return VectorType::get(shape, elementType); 221 } 222 223 // Otherwise use a tensor. 224 Type elementType = getStdTypeForAttr(arrayType.getElementType()); 225 if (!elementType) 226 return nullptr; 227 return RankedTensorType::get(shape, elementType); 228 } 229 230 return nullptr; 231 } 232 233 // Get the given constant as an attribute. Not all constants can be represented 234 // as attributes. 235 Attribute Importer::getConstantAsAttr(llvm::Constant *value) { 236 if (auto *ci = dyn_cast<llvm::ConstantInt>(value)) 237 return b.getIntegerAttr( 238 IntegerType::get(context, ci->getType()->getBitWidth()), 239 ci->getValue()); 240 if (auto *c = dyn_cast<llvm::ConstantDataArray>(value)) 241 if (c->isString()) 242 return b.getStringAttr(c->getAsString()); 243 if (auto *c = dyn_cast<llvm::ConstantFP>(value)) { 244 if (c->getType()->isDoubleTy()) 245 return b.getFloatAttr(FloatType::getF64(context), c->getValueAPF()); 246 if (c->getType()->isFloatingPointTy()) 247 return b.getFloatAttr(FloatType::getF32(context), c->getValueAPF()); 248 } 249 if (auto *f = dyn_cast<llvm::Function>(value)) 250 return SymbolRefAttr::get(b.getContext(), f->getName()); 251 252 // Convert constant data to a dense elements attribute. 253 if (auto *cd = dyn_cast<llvm::ConstantDataSequential>(value)) { 254 Type type = processType(cd->getElementType()); 255 if (!type) 256 return nullptr; 257 258 auto attrType = getStdTypeForAttr(processType(cd->getType())) 259 .dyn_cast_or_null<ShapedType>(); 260 if (!attrType) 261 return nullptr; 262 263 if (type.isa<IntegerType>()) { 264 SmallVector<APInt, 8> values; 265 values.reserve(cd->getNumElements()); 266 for (unsigned i = 0, e = cd->getNumElements(); i < e; ++i) 267 values.push_back(cd->getElementAsAPInt(i)); 268 return DenseElementsAttr::get(attrType, values); 269 } 270 271 if (type.isa<Float32Type, Float64Type>()) { 272 SmallVector<APFloat, 8> values; 273 values.reserve(cd->getNumElements()); 274 for (unsigned i = 0, e = cd->getNumElements(); i < e; ++i) 275 values.push_back(cd->getElementAsAPFloat(i)); 276 return DenseElementsAttr::get(attrType, values); 277 } 278 279 return nullptr; 280 } 281 282 // Unpack constant aggregates to create dense elements attribute whenever 283 // possible. Return nullptr (failure) otherwise. 284 if (isa<llvm::ConstantAggregate>(value)) { 285 auto outerType = getStdTypeForAttr(processType(value->getType())) 286 .dyn_cast_or_null<ShapedType>(); 287 if (!outerType) 288 return nullptr; 289 290 SmallVector<Attribute, 8> values; 291 SmallVector<int64_t, 8> shape; 292 293 for (unsigned i = 0, e = value->getNumOperands(); i < e; ++i) { 294 auto nested = getConstantAsAttr(value->getAggregateElement(i)) 295 .dyn_cast_or_null<DenseElementsAttr>(); 296 if (!nested) 297 return nullptr; 298 299 values.append(nested.value_begin<Attribute>(), 300 nested.value_end<Attribute>()); 301 } 302 303 return DenseElementsAttr::get(outerType, values); 304 } 305 306 return nullptr; 307 } 308 309 GlobalOp Importer::processGlobal(llvm::GlobalVariable *gv) { 310 auto it = globals.find(gv); 311 if (it != globals.end()) 312 return it->second; 313 314 OpBuilder b(module.getBody(), getGlobalInsertPt()); 315 Attribute valueAttr; 316 if (gv->hasInitializer()) 317 valueAttr = getConstantAsAttr(gv->getInitializer()); 318 Type type = processType(gv->getValueType()); 319 if (!type) 320 return nullptr; 321 322 uint64_t alignment = 0; 323 llvm::MaybeAlign maybeAlign = gv->getAlign(); 324 if (maybeAlign.hasValue()) { 325 llvm::Align align = maybeAlign.getValue(); 326 alignment = align.value(); 327 } 328 329 GlobalOp op = 330 b.create<GlobalOp>(UnknownLoc::get(context), type, gv->isConstant(), 331 convertLinkageFromLLVM(gv->getLinkage()), 332 gv->getName(), valueAttr, alignment); 333 334 if (gv->hasInitializer() && !valueAttr) { 335 Region &r = op.getInitializerRegion(); 336 currentEntryBlock = b.createBlock(&r); 337 b.setInsertionPoint(currentEntryBlock, currentEntryBlock->begin()); 338 Value v = processConstant(gv->getInitializer()); 339 if (!v) 340 return nullptr; 341 b.create<ReturnOp>(op.getLoc(), ArrayRef<Value>({v})); 342 } 343 if (gv->hasAtLeastLocalUnnamedAddr()) 344 op.setUnnamedAddrAttr(UnnamedAddrAttr::get( 345 context, convertUnnamedAddrFromLLVM(gv->getUnnamedAddr()))); 346 if (gv->hasSection()) 347 op.setSectionAttr(b.getStringAttr(gv->getSection())); 348 349 return globals[gv] = op; 350 } 351 352 Value Importer::processConstant(llvm::Constant *c) { 353 OpBuilder bEntry(currentEntryBlock, currentEntryBlock->begin()); 354 if (Attribute attr = getConstantAsAttr(c)) { 355 // These constants can be represented as attributes. 356 OpBuilder b(currentEntryBlock, currentEntryBlock->begin()); 357 Type type = processType(c->getType()); 358 if (!type) 359 return nullptr; 360 if (auto symbolRef = attr.dyn_cast<FlatSymbolRefAttr>()) 361 return instMap[c] = bEntry.create<AddressOfOp>(unknownLoc, type, 362 symbolRef.getValue()); 363 return instMap[c] = bEntry.create<ConstantOp>(unknownLoc, type, attr); 364 } 365 if (auto *cn = dyn_cast<llvm::ConstantPointerNull>(c)) { 366 Type type = processType(cn->getType()); 367 if (!type) 368 return nullptr; 369 return instMap[c] = bEntry.create<NullOp>(unknownLoc, type); 370 } 371 if (auto *gv = dyn_cast<llvm::GlobalVariable>(c)) 372 return bEntry.create<AddressOfOp>(UnknownLoc::get(context), 373 processGlobal(gv)); 374 375 if (auto *ce = dyn_cast<llvm::ConstantExpr>(c)) { 376 llvm::Instruction *i = ce->getAsInstruction(); 377 OpBuilder::InsertionGuard guard(b); 378 b.setInsertionPoint(currentEntryBlock, currentEntryBlock->begin()); 379 if (failed(processInstruction(i))) 380 return nullptr; 381 assert(instMap.count(i)); 382 383 // Remove this zombie LLVM instruction now, leaving us only with the MLIR 384 // op. 385 i->deleteValue(); 386 return instMap[c] = instMap[i]; 387 } 388 if (auto *ue = dyn_cast<llvm::UndefValue>(c)) { 389 Type type = processType(ue->getType()); 390 if (!type) 391 return nullptr; 392 return instMap[c] = bEntry.create<UndefOp>(UnknownLoc::get(context), type); 393 } 394 emitError(unknownLoc) << "unhandled constant: " << diag(*c); 395 return nullptr; 396 } 397 398 Value Importer::processValue(llvm::Value *value) { 399 auto it = instMap.find(value); 400 if (it != instMap.end()) 401 return it->second; 402 403 // We don't expect to see instructions in dominator order. If we haven't seen 404 // this instruction yet, create an unknown op and remap it later. 405 if (isa<llvm::Instruction>(value)) { 406 OperationState state(UnknownLoc::get(context), "llvm.unknown"); 407 Type type = processType(value->getType()); 408 if (!type) 409 return nullptr; 410 state.addTypes(type); 411 unknownInstMap[value] = b.createOperation(state); 412 return unknownInstMap[value]->getResult(0); 413 } 414 415 if (auto *c = dyn_cast<llvm::Constant>(value)) 416 return processConstant(c); 417 418 emitError(unknownLoc) << "unhandled value: " << diag(*value); 419 return nullptr; 420 } 421 422 /// Return the MLIR OperationName for the given LLVM opcode. 423 static StringRef lookupOperationNameFromOpcode(unsigned opcode) { 424 // Maps from LLVM opcode to MLIR OperationName. This is deliberately ordered 425 // as in llvm/IR/Instructions.def to aid comprehension and spot missing 426 // instructions. 427 #define INST(llvm_n, mlir_n) \ 428 { llvm::Instruction::llvm_n, LLVM::mlir_n##Op::getOperationName() } 429 static const DenseMap<unsigned, StringRef> opcMap = { 430 // Ret is handled specially. 431 // Br is handled specially. 432 // FIXME: switch 433 // FIXME: indirectbr 434 // FIXME: invoke 435 INST(Resume, Resume), 436 // FIXME: unreachable 437 // FIXME: cleanupret 438 // FIXME: catchret 439 // FIXME: catchswitch 440 // FIXME: callbr 441 // FIXME: fneg 442 INST(Add, Add), INST(FAdd, FAdd), INST(Sub, Sub), INST(FSub, FSub), 443 INST(Mul, Mul), INST(FMul, FMul), INST(UDiv, UDiv), INST(SDiv, SDiv), 444 INST(FDiv, FDiv), INST(URem, URem), INST(SRem, SRem), INST(FRem, FRem), 445 INST(Shl, Shl), INST(LShr, LShr), INST(AShr, AShr), INST(And, And), 446 INST(Or, Or), INST(Xor, XOr), INST(Alloca, Alloca), INST(Load, Load), 447 INST(Store, Store), 448 // Getelementptr is handled specially. 449 INST(Ret, Return), INST(Fence, Fence), 450 // FIXME: atomiccmpxchg 451 // FIXME: atomicrmw 452 INST(Trunc, Trunc), INST(ZExt, ZExt), INST(SExt, SExt), 453 INST(FPToUI, FPToUI), INST(FPToSI, FPToSI), INST(UIToFP, UIToFP), 454 INST(SIToFP, SIToFP), INST(FPTrunc, FPTrunc), INST(FPExt, FPExt), 455 INST(PtrToInt, PtrToInt), INST(IntToPtr, IntToPtr), 456 INST(BitCast, Bitcast), INST(AddrSpaceCast, AddrSpaceCast), 457 // FIXME: cleanuppad 458 // FIXME: catchpad 459 // ICmp is handled specially. 460 // FIXME: fcmp 461 // PHI is handled specially. 462 INST(Freeze, Freeze), INST(Call, Call), 463 // FIXME: select 464 // FIXME: vaarg 465 // FIXME: extractelement 466 // FIXME: insertelement 467 // FIXME: shufflevector 468 // FIXME: extractvalue 469 // FIXME: insertvalue 470 // FIXME: landingpad 471 }; 472 #undef INST 473 474 return opcMap.lookup(opcode); 475 } 476 477 static ICmpPredicate getICmpPredicate(llvm::CmpInst::Predicate p) { 478 switch (p) { 479 default: 480 llvm_unreachable("incorrect comparison predicate"); 481 case llvm::CmpInst::Predicate::ICMP_EQ: 482 return LLVM::ICmpPredicate::eq; 483 case llvm::CmpInst::Predicate::ICMP_NE: 484 return LLVM::ICmpPredicate::ne; 485 case llvm::CmpInst::Predicate::ICMP_SLT: 486 return LLVM::ICmpPredicate::slt; 487 case llvm::CmpInst::Predicate::ICMP_SLE: 488 return LLVM::ICmpPredicate::sle; 489 case llvm::CmpInst::Predicate::ICMP_SGT: 490 return LLVM::ICmpPredicate::sgt; 491 case llvm::CmpInst::Predicate::ICMP_SGE: 492 return LLVM::ICmpPredicate::sge; 493 case llvm::CmpInst::Predicate::ICMP_ULT: 494 return LLVM::ICmpPredicate::ult; 495 case llvm::CmpInst::Predicate::ICMP_ULE: 496 return LLVM::ICmpPredicate::ule; 497 case llvm::CmpInst::Predicate::ICMP_UGT: 498 return LLVM::ICmpPredicate::ugt; 499 case llvm::CmpInst::Predicate::ICMP_UGE: 500 return LLVM::ICmpPredicate::uge; 501 } 502 llvm_unreachable("incorrect comparison predicate"); 503 } 504 505 static AtomicOrdering getLLVMAtomicOrdering(llvm::AtomicOrdering ordering) { 506 switch (ordering) { 507 case llvm::AtomicOrdering::NotAtomic: 508 return LLVM::AtomicOrdering::not_atomic; 509 case llvm::AtomicOrdering::Unordered: 510 return LLVM::AtomicOrdering::unordered; 511 case llvm::AtomicOrdering::Monotonic: 512 return LLVM::AtomicOrdering::monotonic; 513 case llvm::AtomicOrdering::Acquire: 514 return LLVM::AtomicOrdering::acquire; 515 case llvm::AtomicOrdering::Release: 516 return LLVM::AtomicOrdering::release; 517 case llvm::AtomicOrdering::AcquireRelease: 518 return LLVM::AtomicOrdering::acq_rel; 519 case llvm::AtomicOrdering::SequentiallyConsistent: 520 return LLVM::AtomicOrdering::seq_cst; 521 } 522 llvm_unreachable("incorrect atomic ordering"); 523 } 524 525 // `br` branches to `target`. Return the branch arguments to `br`, in the 526 // same order of the PHIs in `target`. 527 LogicalResult 528 Importer::processBranchArgs(llvm::Instruction *br, llvm::BasicBlock *target, 529 SmallVectorImpl<Value> &blockArguments) { 530 for (auto inst = target->begin(); isa<llvm::PHINode>(inst); ++inst) { 531 auto *pn = cast<llvm::PHINode>(&*inst); 532 Value value = processValue(pn->getIncomingValueForBlock(br->getParent())); 533 if (!value) 534 return failure(); 535 blockArguments.push_back(value); 536 } 537 return success(); 538 } 539 540 LogicalResult Importer::processInstruction(llvm::Instruction *inst) { 541 // FIXME: Support uses of SubtargetData. Currently inbounds GEPs, fast-math 542 // flags and call / operand attributes are not supported. 543 Location loc = processDebugLoc(inst->getDebugLoc(), inst); 544 Value &v = instMap[inst]; 545 assert(!v && "processInstruction must be called only once per instruction!"); 546 switch (inst->getOpcode()) { 547 default: 548 return emitError(loc) << "unknown instruction: " << diag(*inst); 549 case llvm::Instruction::Add: 550 case llvm::Instruction::FAdd: 551 case llvm::Instruction::Sub: 552 case llvm::Instruction::FSub: 553 case llvm::Instruction::Mul: 554 case llvm::Instruction::FMul: 555 case llvm::Instruction::UDiv: 556 case llvm::Instruction::SDiv: 557 case llvm::Instruction::FDiv: 558 case llvm::Instruction::URem: 559 case llvm::Instruction::SRem: 560 case llvm::Instruction::FRem: 561 case llvm::Instruction::Shl: 562 case llvm::Instruction::LShr: 563 case llvm::Instruction::AShr: 564 case llvm::Instruction::And: 565 case llvm::Instruction::Or: 566 case llvm::Instruction::Xor: 567 case llvm::Instruction::Alloca: 568 case llvm::Instruction::Load: 569 case llvm::Instruction::Store: 570 case llvm::Instruction::Ret: 571 case llvm::Instruction::Resume: 572 case llvm::Instruction::Trunc: 573 case llvm::Instruction::ZExt: 574 case llvm::Instruction::SExt: 575 case llvm::Instruction::FPToUI: 576 case llvm::Instruction::FPToSI: 577 case llvm::Instruction::UIToFP: 578 case llvm::Instruction::SIToFP: 579 case llvm::Instruction::FPTrunc: 580 case llvm::Instruction::FPExt: 581 case llvm::Instruction::PtrToInt: 582 case llvm::Instruction::IntToPtr: 583 case llvm::Instruction::AddrSpaceCast: 584 case llvm::Instruction::Freeze: 585 case llvm::Instruction::BitCast: { 586 OperationState state(loc, lookupOperationNameFromOpcode(inst->getOpcode())); 587 SmallVector<Value, 4> ops; 588 ops.reserve(inst->getNumOperands()); 589 for (auto *op : inst->operand_values()) { 590 Value value = processValue(op); 591 if (!value) 592 return failure(); 593 ops.push_back(value); 594 } 595 state.addOperands(ops); 596 if (!inst->getType()->isVoidTy()) { 597 Type type = processType(inst->getType()); 598 if (!type) 599 return failure(); 600 state.addTypes(type); 601 } 602 Operation *op = b.createOperation(state); 603 if (!inst->getType()->isVoidTy()) 604 v = op->getResult(0); 605 return success(); 606 } 607 case llvm::Instruction::ICmp: { 608 Value lhs = processValue(inst->getOperand(0)); 609 Value rhs = processValue(inst->getOperand(1)); 610 if (!lhs || !rhs) 611 return failure(); 612 v = b.create<ICmpOp>( 613 loc, getICmpPredicate(cast<llvm::ICmpInst>(inst)->getPredicate()), lhs, 614 rhs); 615 return success(); 616 } 617 case llvm::Instruction::Br: { 618 auto *brInst = cast<llvm::BranchInst>(inst); 619 OperationState state(loc, 620 brInst->isConditional() ? "llvm.cond_br" : "llvm.br"); 621 if (brInst->isConditional()) { 622 Value condition = processValue(brInst->getCondition()); 623 if (!condition) 624 return failure(); 625 state.addOperands(condition); 626 } 627 628 std::array<int32_t, 3> operandSegmentSizes = {1, 0, 0}; 629 for (int i : llvm::seq<int>(0, brInst->getNumSuccessors())) { 630 auto *succ = brInst->getSuccessor(i); 631 SmallVector<Value, 4> blockArguments; 632 if (failed(processBranchArgs(brInst, succ, blockArguments))) 633 return failure(); 634 state.addSuccessors(blocks[succ]); 635 state.addOperands(blockArguments); 636 operandSegmentSizes[i + 1] = blockArguments.size(); 637 } 638 639 if (brInst->isConditional()) { 640 state.addAttribute(LLVM::CondBrOp::getOperandSegmentSizeAttr(), 641 b.getI32VectorAttr(operandSegmentSizes)); 642 } 643 644 b.createOperation(state); 645 return success(); 646 } 647 case llvm::Instruction::PHI: { 648 Type type = processType(inst->getType()); 649 if (!type) 650 return failure(); 651 v = b.getInsertionBlock()->addArgument( 652 type, processDebugLoc(inst->getDebugLoc(), inst)); 653 return success(); 654 } 655 case llvm::Instruction::Call: { 656 llvm::CallInst *ci = cast<llvm::CallInst>(inst); 657 SmallVector<Value, 4> ops; 658 ops.reserve(inst->getNumOperands()); 659 for (auto &op : ci->args()) { 660 Value arg = processValue(op.get()); 661 if (!arg) 662 return failure(); 663 ops.push_back(arg); 664 } 665 666 SmallVector<Type, 2> tys; 667 if (!ci->getType()->isVoidTy()) { 668 Type type = processType(inst->getType()); 669 if (!type) 670 return failure(); 671 tys.push_back(type); 672 } 673 Operation *op; 674 if (llvm::Function *callee = ci->getCalledFunction()) { 675 op = b.create<CallOp>( 676 loc, tys, SymbolRefAttr::get(b.getContext(), callee->getName()), ops); 677 } else { 678 Value calledValue = processValue(ci->getCalledOperand()); 679 if (!calledValue) 680 return failure(); 681 ops.insert(ops.begin(), calledValue); 682 op = b.create<CallOp>(loc, tys, ops); 683 } 684 if (!ci->getType()->isVoidTy()) 685 v = op->getResult(0); 686 return success(); 687 } 688 case llvm::Instruction::LandingPad: { 689 llvm::LandingPadInst *lpi = cast<llvm::LandingPadInst>(inst); 690 SmallVector<Value, 4> ops; 691 692 for (unsigned i = 0, ie = lpi->getNumClauses(); i < ie; i++) 693 ops.push_back(processConstant(lpi->getClause(i))); 694 695 Type ty = processType(lpi->getType()); 696 if (!ty) 697 return failure(); 698 699 v = b.create<LandingpadOp>(loc, ty, lpi->isCleanup(), ops); 700 return success(); 701 } 702 case llvm::Instruction::Invoke: { 703 llvm::InvokeInst *ii = cast<llvm::InvokeInst>(inst); 704 705 SmallVector<Type, 2> tys; 706 if (!ii->getType()->isVoidTy()) 707 tys.push_back(processType(inst->getType())); 708 709 SmallVector<Value, 4> ops; 710 ops.reserve(inst->getNumOperands() + 1); 711 for (auto &op : ii->args()) 712 ops.push_back(processValue(op.get())); 713 714 SmallVector<Value, 4> normalArgs, unwindArgs; 715 (void)processBranchArgs(ii, ii->getNormalDest(), normalArgs); 716 (void)processBranchArgs(ii, ii->getUnwindDest(), unwindArgs); 717 718 Operation *op; 719 if (llvm::Function *callee = ii->getCalledFunction()) { 720 op = b.create<InvokeOp>( 721 loc, tys, SymbolRefAttr::get(b.getContext(), callee->getName()), ops, 722 blocks[ii->getNormalDest()], normalArgs, blocks[ii->getUnwindDest()], 723 unwindArgs); 724 } else { 725 ops.insert(ops.begin(), processValue(ii->getCalledOperand())); 726 op = b.create<InvokeOp>(loc, tys, ops, blocks[ii->getNormalDest()], 727 normalArgs, blocks[ii->getUnwindDest()], 728 unwindArgs); 729 } 730 731 if (!ii->getType()->isVoidTy()) 732 v = op->getResult(0); 733 return success(); 734 } 735 case llvm::Instruction::Fence: { 736 StringRef syncscope; 737 SmallVector<StringRef, 4> ssNs; 738 llvm::LLVMContext &llvmContext = inst->getContext(); 739 llvm::FenceInst *fence = cast<llvm::FenceInst>(inst); 740 llvmContext.getSyncScopeNames(ssNs); 741 int fenceSyncScopeID = fence->getSyncScopeID(); 742 for (unsigned i = 0, e = ssNs.size(); i != e; i++) { 743 if (fenceSyncScopeID == llvmContext.getOrInsertSyncScopeID(ssNs[i])) { 744 syncscope = ssNs[i]; 745 break; 746 } 747 } 748 b.create<FenceOp>(loc, getLLVMAtomicOrdering(fence->getOrdering()), 749 syncscope); 750 return success(); 751 } 752 case llvm::Instruction::GetElementPtr: { 753 // FIXME: Support inbounds GEPs. 754 llvm::GetElementPtrInst *gep = cast<llvm::GetElementPtrInst>(inst); 755 SmallVector<Value, 4> ops; 756 for (auto *op : gep->operand_values()) { 757 Value value = processValue(op); 758 if (!value) 759 return failure(); 760 ops.push_back(value); 761 } 762 Type type = processType(inst->getType()); 763 if (!type) 764 return failure(); 765 v = b.create<GEPOp>(loc, type, ops[0], 766 llvm::makeArrayRef(ops).drop_front()); 767 return success(); 768 } 769 } 770 } 771 772 FlatSymbolRefAttr Importer::getPersonalityAsAttr(llvm::Function *f) { 773 if (!f->hasPersonalityFn()) 774 return nullptr; 775 776 llvm::Constant *pf = f->getPersonalityFn(); 777 778 // If it directly has a name, we can use it. 779 if (pf->hasName()) 780 return SymbolRefAttr::get(b.getContext(), pf->getName()); 781 782 // If it doesn't have a name, currently, only function pointers that are 783 // bitcast to i8* are parsed. 784 if (auto *ce = dyn_cast<llvm::ConstantExpr>(pf)) { 785 if (ce->getOpcode() == llvm::Instruction::BitCast && 786 ce->getType() == llvm::Type::getInt8PtrTy(f->getContext())) { 787 if (auto *func = dyn_cast<llvm::Function>(ce->getOperand(0))) 788 return SymbolRefAttr::get(b.getContext(), func->getName()); 789 } 790 } 791 return FlatSymbolRefAttr(); 792 } 793 794 LogicalResult Importer::processFunction(llvm::Function *f) { 795 blocks.clear(); 796 instMap.clear(); 797 unknownInstMap.clear(); 798 799 auto functionType = 800 processType(f->getFunctionType()).dyn_cast<LLVMFunctionType>(); 801 if (!functionType) 802 return failure(); 803 804 b.setInsertionPoint(module.getBody(), getFuncInsertPt()); 805 LLVMFuncOp fop = 806 b.create<LLVMFuncOp>(UnknownLoc::get(context), f->getName(), functionType, 807 convertLinkageFromLLVM(f->getLinkage())); 808 809 if (FlatSymbolRefAttr personality = getPersonalityAsAttr(f)) 810 fop->setAttr(b.getStringAttr("personality"), personality); 811 else if (f->hasPersonalityFn()) 812 emitWarning(UnknownLoc::get(context), 813 "could not deduce personality, skipping it"); 814 815 if (f->hasGC()) 816 fop.setGarbageCollectorAttr(b.getStringAttr(f->getGC())); 817 818 if (f->isDeclaration()) 819 return success(); 820 821 // Eagerly create all blocks. 822 SmallVector<Block *, 4> blockList; 823 for (llvm::BasicBlock &bb : *f) { 824 blockList.push_back(b.createBlock(&fop.getBody(), fop.getBody().end())); 825 blocks[&bb] = blockList.back(); 826 } 827 currentEntryBlock = blockList[0]; 828 829 // Add function arguments to the entry block. 830 for (const auto &kv : llvm::enumerate(f->args())) { 831 instMap[&kv.value()] = blockList[0]->addArgument( 832 functionType.getParamType(kv.index()), fop.getLoc()); 833 } 834 835 for (auto bbs : llvm::zip(*f, blockList)) { 836 if (failed(processBasicBlock(&std::get<0>(bbs), std::get<1>(bbs)))) 837 return failure(); 838 } 839 840 // Now that all instructions are guaranteed to have been visited, ensure 841 // any unknown uses we encountered are remapped. 842 for (auto &llvmAndUnknown : unknownInstMap) { 843 assert(instMap.count(llvmAndUnknown.first)); 844 Value newValue = instMap[llvmAndUnknown.first]; 845 Value oldValue = llvmAndUnknown.second->getResult(0); 846 oldValue.replaceAllUsesWith(newValue); 847 llvmAndUnknown.second->erase(); 848 } 849 return success(); 850 } 851 852 LogicalResult Importer::processBasicBlock(llvm::BasicBlock *bb, Block *block) { 853 b.setInsertionPointToStart(block); 854 for (llvm::Instruction &inst : *bb) { 855 if (failed(processInstruction(&inst))) 856 return failure(); 857 } 858 return success(); 859 } 860 861 OwningOpRef<ModuleOp> 862 mlir::translateLLVMIRToModule(std::unique_ptr<llvm::Module> llvmModule, 863 MLIRContext *context) { 864 context->loadDialect<LLVMDialect>(); 865 OwningOpRef<ModuleOp> module(ModuleOp::create( 866 FileLineColLoc::get(context, "", /*line=*/0, /*column=*/0))); 867 868 Importer deserializer(context, module.get()); 869 for (llvm::GlobalVariable &gv : llvmModule->globals()) { 870 if (!deserializer.processGlobal(&gv)) 871 return {}; 872 } 873 for (llvm::Function &f : llvmModule->functions()) { 874 if (failed(deserializer.processFunction(&f))) 875 return {}; 876 } 877 878 return module; 879 } 880 881 // Deserializes the LLVM bitcode stored in `input` into an MLIR module in the 882 // LLVM dialect. 883 OwningOpRef<ModuleOp> translateLLVMIRToModule(llvm::SourceMgr &sourceMgr, 884 MLIRContext *context) { 885 llvm::SMDiagnostic err; 886 llvm::LLVMContext llvmContext; 887 std::unique_ptr<llvm::Module> llvmModule = llvm::parseIR( 888 *sourceMgr.getMemoryBuffer(sourceMgr.getMainFileID()), err, llvmContext); 889 if (!llvmModule) { 890 std::string errStr; 891 llvm::raw_string_ostream errStream(errStr); 892 err.print(/*ProgName=*/"", errStream); 893 emitError(UnknownLoc::get(context)) << errStream.str(); 894 return {}; 895 } 896 return translateLLVMIRToModule(std::move(llvmModule), context); 897 } 898 899 namespace mlir { 900 void registerFromLLVMIRTranslation() { 901 TranslateToMLIRRegistration fromLLVM( 902 "import-llvm", [](llvm::SourceMgr &sourceMgr, MLIRContext *context) { 903 return ::translateLLVMIRToModule(sourceMgr, context); 904 }); 905 } 906 } // namespace mlir 907