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