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