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