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(type); 651 return success(); 652 } 653 case llvm::Instruction::Call: { 654 llvm::CallInst *ci = cast<llvm::CallInst>(inst); 655 SmallVector<Value, 4> ops; 656 ops.reserve(inst->getNumOperands()); 657 for (auto &op : ci->args()) { 658 Value arg = processValue(op.get()); 659 if (!arg) 660 return failure(); 661 ops.push_back(arg); 662 } 663 664 SmallVector<Type, 2> tys; 665 if (!ci->getType()->isVoidTy()) { 666 Type type = processType(inst->getType()); 667 if (!type) 668 return failure(); 669 tys.push_back(type); 670 } 671 Operation *op; 672 if (llvm::Function *callee = ci->getCalledFunction()) { 673 op = b.create<CallOp>( 674 loc, tys, SymbolRefAttr::get(b.getContext(), callee->getName()), ops); 675 } else { 676 Value calledValue = processValue(ci->getCalledOperand()); 677 if (!calledValue) 678 return failure(); 679 ops.insert(ops.begin(), calledValue); 680 op = b.create<CallOp>(loc, tys, ops); 681 } 682 if (!ci->getType()->isVoidTy()) 683 v = op->getResult(0); 684 return success(); 685 } 686 case llvm::Instruction::LandingPad: { 687 llvm::LandingPadInst *lpi = cast<llvm::LandingPadInst>(inst); 688 SmallVector<Value, 4> ops; 689 690 for (unsigned i = 0, ie = lpi->getNumClauses(); i < ie; i++) 691 ops.push_back(processConstant(lpi->getClause(i))); 692 693 Type ty = processType(lpi->getType()); 694 if (!ty) 695 return failure(); 696 697 v = b.create<LandingpadOp>(loc, ty, lpi->isCleanup(), ops); 698 return success(); 699 } 700 case llvm::Instruction::Invoke: { 701 llvm::InvokeInst *ii = cast<llvm::InvokeInst>(inst); 702 703 SmallVector<Type, 2> tys; 704 if (!ii->getType()->isVoidTy()) 705 tys.push_back(processType(inst->getType())); 706 707 SmallVector<Value, 4> ops; 708 ops.reserve(inst->getNumOperands() + 1); 709 for (auto &op : ii->args()) 710 ops.push_back(processValue(op.get())); 711 712 SmallVector<Value, 4> normalArgs, unwindArgs; 713 (void)processBranchArgs(ii, ii->getNormalDest(), normalArgs); 714 (void)processBranchArgs(ii, ii->getUnwindDest(), unwindArgs); 715 716 Operation *op; 717 if (llvm::Function *callee = ii->getCalledFunction()) { 718 op = b.create<InvokeOp>( 719 loc, tys, SymbolRefAttr::get(b.getContext(), callee->getName()), ops, 720 blocks[ii->getNormalDest()], normalArgs, blocks[ii->getUnwindDest()], 721 unwindArgs); 722 } else { 723 ops.insert(ops.begin(), processValue(ii->getCalledOperand())); 724 op = b.create<InvokeOp>(loc, tys, ops, blocks[ii->getNormalDest()], 725 normalArgs, blocks[ii->getUnwindDest()], 726 unwindArgs); 727 } 728 729 if (!ii->getType()->isVoidTy()) 730 v = op->getResult(0); 731 return success(); 732 } 733 case llvm::Instruction::Fence: { 734 StringRef syncscope; 735 SmallVector<StringRef, 4> ssNs; 736 llvm::LLVMContext &llvmContext = inst->getContext(); 737 llvm::FenceInst *fence = cast<llvm::FenceInst>(inst); 738 llvmContext.getSyncScopeNames(ssNs); 739 int fenceSyncScopeID = fence->getSyncScopeID(); 740 for (unsigned i = 0, e = ssNs.size(); i != e; i++) { 741 if (fenceSyncScopeID == llvmContext.getOrInsertSyncScopeID(ssNs[i])) { 742 syncscope = ssNs[i]; 743 break; 744 } 745 } 746 b.create<FenceOp>(loc, getLLVMAtomicOrdering(fence->getOrdering()), 747 syncscope); 748 return success(); 749 } 750 case llvm::Instruction::GetElementPtr: { 751 // FIXME: Support inbounds GEPs. 752 llvm::GetElementPtrInst *gep = cast<llvm::GetElementPtrInst>(inst); 753 SmallVector<Value, 4> ops; 754 for (auto *op : gep->operand_values()) { 755 Value value = processValue(op); 756 if (!value) 757 return failure(); 758 ops.push_back(value); 759 } 760 Type type = processType(inst->getType()); 761 if (!type) 762 return failure(); 763 v = b.create<GEPOp>(loc, type, ops[0], 764 llvm::makeArrayRef(ops).drop_front()); 765 return success(); 766 } 767 } 768 } 769 770 FlatSymbolRefAttr Importer::getPersonalityAsAttr(llvm::Function *f) { 771 if (!f->hasPersonalityFn()) 772 return nullptr; 773 774 llvm::Constant *pf = f->getPersonalityFn(); 775 776 // If it directly has a name, we can use it. 777 if (pf->hasName()) 778 return SymbolRefAttr::get(b.getContext(), pf->getName()); 779 780 // If it doesn't have a name, currently, only function pointers that are 781 // bitcast to i8* are parsed. 782 if (auto *ce = dyn_cast<llvm::ConstantExpr>(pf)) { 783 if (ce->getOpcode() == llvm::Instruction::BitCast && 784 ce->getType() == llvm::Type::getInt8PtrTy(f->getContext())) { 785 if (auto *func = dyn_cast<llvm::Function>(ce->getOperand(0))) 786 return SymbolRefAttr::get(b.getContext(), func->getName()); 787 } 788 } 789 return FlatSymbolRefAttr(); 790 } 791 792 LogicalResult Importer::processFunction(llvm::Function *f) { 793 blocks.clear(); 794 instMap.clear(); 795 unknownInstMap.clear(); 796 797 auto functionType = 798 processType(f->getFunctionType()).dyn_cast<LLVMFunctionType>(); 799 if (!functionType) 800 return failure(); 801 802 b.setInsertionPoint(module.getBody(), getFuncInsertPt()); 803 LLVMFuncOp fop = 804 b.create<LLVMFuncOp>(UnknownLoc::get(context), f->getName(), functionType, 805 convertLinkageFromLLVM(f->getLinkage())); 806 807 if (FlatSymbolRefAttr personality = getPersonalityAsAttr(f)) 808 fop->setAttr(b.getStringAttr("personality"), personality); 809 else if (f->hasPersonalityFn()) 810 emitWarning(UnknownLoc::get(context), 811 "could not deduce personality, skipping it"); 812 813 if (f->isDeclaration()) 814 return success(); 815 816 // Eagerly create all blocks. 817 SmallVector<Block *, 4> blockList; 818 for (llvm::BasicBlock &bb : *f) { 819 blockList.push_back(b.createBlock(&fop.getBody(), fop.getBody().end())); 820 blocks[&bb] = blockList.back(); 821 } 822 currentEntryBlock = blockList[0]; 823 824 // Add function arguments to the entry block. 825 for (const auto &kv : llvm::enumerate(f->args())) 826 instMap[&kv.value()] = 827 blockList[0]->addArgument(functionType.getParamType(kv.index())); 828 829 for (auto bbs : llvm::zip(*f, blockList)) { 830 if (failed(processBasicBlock(&std::get<0>(bbs), std::get<1>(bbs)))) 831 return failure(); 832 } 833 834 // Now that all instructions are guaranteed to have been visited, ensure 835 // any unknown uses we encountered are remapped. 836 for (auto &llvmAndUnknown : unknownInstMap) { 837 assert(instMap.count(llvmAndUnknown.first)); 838 Value newValue = instMap[llvmAndUnknown.first]; 839 Value oldValue = llvmAndUnknown.second->getResult(0); 840 oldValue.replaceAllUsesWith(newValue); 841 llvmAndUnknown.second->erase(); 842 } 843 return success(); 844 } 845 846 LogicalResult Importer::processBasicBlock(llvm::BasicBlock *bb, Block *block) { 847 b.setInsertionPointToStart(block); 848 for (llvm::Instruction &inst : *bb) { 849 if (failed(processInstruction(&inst))) 850 return failure(); 851 } 852 return success(); 853 } 854 855 OwningModuleRef 856 mlir::translateLLVMIRToModule(std::unique_ptr<llvm::Module> llvmModule, 857 MLIRContext *context) { 858 context->loadDialect<LLVMDialect>(); 859 OwningModuleRef module(ModuleOp::create( 860 FileLineColLoc::get(context, "", /*line=*/0, /*column=*/0))); 861 862 Importer deserializer(context, module.get()); 863 for (llvm::GlobalVariable &gv : llvmModule->globals()) { 864 if (!deserializer.processGlobal(&gv)) 865 return {}; 866 } 867 for (llvm::Function &f : llvmModule->functions()) { 868 if (failed(deserializer.processFunction(&f))) 869 return {}; 870 } 871 872 return module; 873 } 874 875 // Deserializes the LLVM bitcode stored in `input` into an MLIR module in the 876 // LLVM dialect. 877 OwningModuleRef translateLLVMIRToModule(llvm::SourceMgr &sourceMgr, 878 MLIRContext *context) { 879 llvm::SMDiagnostic err; 880 llvm::LLVMContext llvmContext; 881 std::unique_ptr<llvm::Module> llvmModule = llvm::parseIR( 882 *sourceMgr.getMemoryBuffer(sourceMgr.getMainFileID()), err, llvmContext); 883 if (!llvmModule) { 884 std::string errStr; 885 llvm::raw_string_ostream errStream(errStr); 886 err.print(/*ProgName=*/"", errStream); 887 emitError(UnknownLoc::get(context)) << errStream.str(); 888 return {}; 889 } 890 return translateLLVMIRToModule(std::move(llvmModule), context); 891 } 892 893 namespace mlir { 894 void registerFromLLVMIRTranslation() { 895 TranslateToMLIRRegistration fromLLVM( 896 "import-llvm", [](llvm::SourceMgr &sourceMgr, MLIRContext *context) { 897 return ::translateLLVMIRToModule(sourceMgr, context); 898 }); 899 } 900 } // namespace mlir 901