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