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); 764 return success(); 765 } 766 } 767 } 768 769 FlatSymbolRefAttr Importer::getPersonalityAsAttr(llvm::Function *f) { 770 if (!f->hasPersonalityFn()) 771 return nullptr; 772 773 llvm::Constant *pf = f->getPersonalityFn(); 774 775 // If it directly has a name, we can use it. 776 if (pf->hasName()) 777 return SymbolRefAttr::get(b.getContext(), pf->getName()); 778 779 // If it doesn't have a name, currently, only function pointers that are 780 // bitcast to i8* are parsed. 781 if (auto *ce = dyn_cast<llvm::ConstantExpr>(pf)) { 782 if (ce->getOpcode() == llvm::Instruction::BitCast && 783 ce->getType() == llvm::Type::getInt8PtrTy(f->getContext())) { 784 if (auto *func = dyn_cast<llvm::Function>(ce->getOperand(0))) 785 return SymbolRefAttr::get(b.getContext(), func->getName()); 786 } 787 } 788 return FlatSymbolRefAttr(); 789 } 790 791 LogicalResult Importer::processFunction(llvm::Function *f) { 792 blocks.clear(); 793 instMap.clear(); 794 unknownInstMap.clear(); 795 796 auto functionType = 797 processType(f->getFunctionType()).dyn_cast<LLVMFunctionType>(); 798 if (!functionType) 799 return failure(); 800 801 b.setInsertionPoint(module.getBody(), getFuncInsertPt()); 802 LLVMFuncOp fop = 803 b.create<LLVMFuncOp>(UnknownLoc::get(context), f->getName(), functionType, 804 convertLinkageFromLLVM(f->getLinkage())); 805 806 if (FlatSymbolRefAttr personality = getPersonalityAsAttr(f)) 807 fop->setAttr(b.getStringAttr("personality"), personality); 808 else if (f->hasPersonalityFn()) 809 emitWarning(UnknownLoc::get(context), 810 "could not deduce personality, skipping it"); 811 812 if (f->isDeclaration()) 813 return success(); 814 815 // Eagerly create all blocks. 816 SmallVector<Block *, 4> blockList; 817 for (llvm::BasicBlock &bb : *f) { 818 blockList.push_back(b.createBlock(&fop.getBody(), fop.getBody().end())); 819 blocks[&bb] = blockList.back(); 820 } 821 currentEntryBlock = blockList[0]; 822 823 // Add function arguments to the entry block. 824 for (const auto &kv : llvm::enumerate(f->args())) 825 instMap[&kv.value()] = 826 blockList[0]->addArgument(functionType.getParamType(kv.index())); 827 828 for (auto bbs : llvm::zip(*f, blockList)) { 829 if (failed(processBasicBlock(&std::get<0>(bbs), std::get<1>(bbs)))) 830 return failure(); 831 } 832 833 // Now that all instructions are guaranteed to have been visited, ensure 834 // any unknown uses we encountered are remapped. 835 for (auto &llvmAndUnknown : unknownInstMap) { 836 assert(instMap.count(llvmAndUnknown.first)); 837 Value newValue = instMap[llvmAndUnknown.first]; 838 Value oldValue = llvmAndUnknown.second->getResult(0); 839 oldValue.replaceAllUsesWith(newValue); 840 llvmAndUnknown.second->erase(); 841 } 842 return success(); 843 } 844 845 LogicalResult Importer::processBasicBlock(llvm::BasicBlock *bb, Block *block) { 846 b.setInsertionPointToStart(block); 847 for (llvm::Instruction &inst : *bb) { 848 if (failed(processInstruction(&inst))) 849 return failure(); 850 } 851 return success(); 852 } 853 854 OwningModuleRef 855 mlir::translateLLVMIRToModule(std::unique_ptr<llvm::Module> llvmModule, 856 MLIRContext *context) { 857 context->loadDialect<LLVMDialect>(); 858 OwningModuleRef module(ModuleOp::create( 859 FileLineColLoc::get(context, "", /*line=*/0, /*column=*/0))); 860 861 Importer deserializer(context, module.get()); 862 for (llvm::GlobalVariable &gv : llvmModule->globals()) { 863 if (!deserializer.processGlobal(&gv)) 864 return {}; 865 } 866 for (llvm::Function &f : llvmModule->functions()) { 867 if (failed(deserializer.processFunction(&f))) 868 return {}; 869 } 870 871 return module; 872 } 873 874 // Deserializes the LLVM bitcode stored in `input` into an MLIR module in the 875 // LLVM dialect. 876 OwningModuleRef translateLLVMIRToModule(llvm::SourceMgr &sourceMgr, 877 MLIRContext *context) { 878 llvm::SMDiagnostic err; 879 llvm::LLVMContext llvmContext; 880 std::unique_ptr<llvm::Module> llvmModule = llvm::parseIR( 881 *sourceMgr.getMemoryBuffer(sourceMgr.getMainFileID()), err, llvmContext); 882 if (!llvmModule) { 883 std::string errStr; 884 llvm::raw_string_ostream errStream(errStr); 885 err.print(/*ProgName=*/"", errStream); 886 emitError(UnknownLoc::get(context)) << errStream.str(); 887 return {}; 888 } 889 return translateLLVMIRToModule(std::move(llvmModule), context); 890 } 891 892 namespace mlir { 893 void registerFromLLVMIRTranslation() { 894 TranslateToMLIRRegistration fromLLVM( 895 "import-llvm", [](llvm::SourceMgr &sourceMgr, MLIRContext *context) { 896 return ::translateLLVMIRToModule(sourceMgr, context); 897 }); 898 } 899 } // namespace mlir 900