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