MLIR  15.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 
15 #include "mlir/Dialect/DLTI/DLTI.h"
17 #include "mlir/IR/Builders.h"
18 #include "mlir/IR/BuiltinOps.h"
19 #include "mlir/IR/BuiltinTypes.h"
20 #include "mlir/IR/MLIRContext.h"
24 
25 #include "llvm/ADT/StringSet.h"
26 #include "llvm/ADT/TypeSwitch.h"
27 #include "llvm/IR/Attributes.h"
28 #include "llvm/IR/Constants.h"
29 #include "llvm/IR/DerivedTypes.h"
30 #include "llvm/IR/Function.h"
31 #include "llvm/IR/InlineAsm.h"
32 #include "llvm/IR/Instructions.h"
33 #include "llvm/IR/Intrinsics.h"
34 #include "llvm/IR/Type.h"
35 #include "llvm/IRReader/IRReader.h"
36 #include "llvm/Support/Error.h"
37 #include "llvm/Support/SourceMgr.h"
38 
39 using namespace mlir;
40 using namespace mlir::LLVM;
41 
42 #include "mlir/Dialect/LLVMIR/LLVMConversionEnumsFromLLVM.inc"
43 
44 // Utility to print an LLVM value as a string for passing to emitError().
45 // FIXME: Diagnostic should be able to natively handle types that have
46 // operator << (raw_ostream&) defined.
47 static std::string diag(llvm::Value &v) {
48  std::string s;
49  llvm::raw_string_ostream os(s);
50  os << v;
51  return os.str();
52 }
53 
54 /// Creates an attribute containing ABI and preferred alignment numbers parsed
55 /// a string. The string may be either "abi:preferred" or just "abi". In the
56 /// latter case, the prefrred alignment is considered equal to ABI alignment.
58  StringRef spec) {
59  auto i32 = IntegerType::get(&ctx, 32);
60 
61  StringRef abiString, preferredString;
62  std::tie(abiString, preferredString) = spec.split(':');
63  int abi, preferred;
64  if (abiString.getAsInteger(/*Radix=*/10, abi))
65  return nullptr;
66 
67  if (preferredString.empty())
68  preferred = abi;
69  else if (preferredString.getAsInteger(/*Radix=*/10, preferred))
70  return nullptr;
71 
72  return DenseIntElementsAttr::get(VectorType::get({2}, i32), {abi, preferred});
73 }
74 
75 /// Returns a supported MLIR floating point type of the given bit width or null
76 /// if the bit width is not supported.
77 static FloatType getDLFloatType(MLIRContext &ctx, int32_t bitwidth) {
78  switch (bitwidth) {
79  case 16:
80  return FloatType::getF16(&ctx);
81  case 32:
82  return FloatType::getF32(&ctx);
83  case 64:
84  return FloatType::getF64(&ctx);
85  case 80:
86  return FloatType::getF80(&ctx);
87  case 128:
88  return FloatType::getF128(&ctx);
89  default:
90  return nullptr;
91  }
92 }
93 
94 DataLayoutSpecInterface
95 mlir::translateDataLayout(const llvm::DataLayout &dataLayout,
96  MLIRContext *context) {
97  assert(context && "expected MLIR context");
98  std::string layoutstr = dataLayout.getStringRepresentation();
99 
100  // Remaining unhandled default layout defaults
101  // e (little endian if not set)
102  // p[n]:64:64:64 (non zero address spaces have 64-bit properties)
103  std::string append =
104  "p:64:64:64-S0-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f16:16:16-f64:"
105  "64:64-f128:128:128-v64:64:64-v128:128:128-a:0:64";
106  if (layoutstr.empty())
107  layoutstr = append;
108  else
109  layoutstr = layoutstr + "-" + append;
110 
111  StringRef layout(layoutstr);
112 
114  StringSet<> seen;
115  while (!layout.empty()) {
116  // Split at '-'.
117  std::pair<StringRef, StringRef> split = layout.split('-');
118  StringRef current;
119  std::tie(current, layout) = split;
120 
121  // Split at ':'.
122  StringRef kind, spec;
123  std::tie(kind, spec) = current.split(':');
124  if (seen.contains(kind))
125  continue;
126  seen.insert(kind);
127 
128  char symbol = kind.front();
129  StringRef parameter = kind.substr(1);
130 
131  if (symbol == 'i' || symbol == 'f') {
132  unsigned bitwidth;
133  if (parameter.getAsInteger(/*Radix=*/10, bitwidth))
134  return nullptr;
135  DenseIntElementsAttr params = parseDataLayoutAlignment(*context, spec);
136  if (!params)
137  return nullptr;
138  auto entry = DataLayoutEntryAttr::get(
139  symbol == 'i' ? static_cast<Type>(IntegerType::get(context, bitwidth))
140  : getDLFloatType(*context, bitwidth),
141  params);
142  entries.emplace_back(entry);
143  } else if (symbol == 'e' || symbol == 'E') {
144  auto value = StringAttr::get(
145  context, symbol == 'e' ? DLTIDialect::kDataLayoutEndiannessLittle
146  : DLTIDialect::kDataLayoutEndiannessBig);
147  auto entry = DataLayoutEntryAttr::get(
148  StringAttr::get(context, DLTIDialect::kDataLayoutEndiannessKey),
149  value);
150  entries.emplace_back(entry);
151  }
152  }
153 
154  return DataLayoutSpecAttr::get(context, entries);
155 }
156 
157 // Handles importing globals and functions from an LLVM module.
158 namespace {
159 class Importer {
160 public:
161  Importer(MLIRContext *context, ModuleOp module)
162  : b(context), context(context), module(module),
163  unknownLoc(FileLineColLoc::get(context, "imported-bitcode", 0, 0)),
164  typeTranslator(*context) {
165  b.setInsertionPointToStart(module.getBody());
166  }
167 
168  /// Imports `f` into the current module.
169  LogicalResult processFunction(llvm::Function *f);
170 
171  /// Imports GV as a GlobalOp, creating it if it doesn't exist.
172  GlobalOp processGlobal(llvm::GlobalVariable *gv);
173 
174 private:
175  /// Returns personality of `f` as a FlatSymbolRefAttr.
176  FlatSymbolRefAttr getPersonalityAsAttr(llvm::Function *f);
177  /// Imports `bb` into `block`, which must be initially empty.
178  LogicalResult processBasicBlock(llvm::BasicBlock *bb, Block *block);
179  /// Imports `inst` and populates instMap[inst] with the imported Value.
180  LogicalResult processInstruction(llvm::Instruction *inst);
181  /// Creates an LLVM-compatible MLIR type for `type`.
182  Type processType(llvm::Type *type);
183  /// `value` is an SSA-use. Return the remapped version of `value` or a
184  /// placeholder that will be remapped later if this is an instruction that
185  /// has not yet been visited.
186  Value processValue(llvm::Value *value);
187  /// Create the most accurate Location possible using a llvm::DebugLoc and
188  /// possibly an llvm::Instruction to narrow the Location if debug information
189  /// is unavailable.
190  Location processDebugLoc(const llvm::DebugLoc &loc,
191  llvm::Instruction *inst = nullptr);
192  /// `br` branches to `target`. Append the block arguments to attach to the
193  /// generated branch op to `blockArguments`. These should be in the same order
194  /// as the PHIs in `target`.
195  LogicalResult processBranchArgs(llvm::Instruction *br,
196  llvm::BasicBlock *target,
197  SmallVectorImpl<Value> &blockArguments);
198  /// Returns the builtin type equivalent to be used in attributes for the given
199  /// LLVM IR dialect type.
200  Type getStdTypeForAttr(Type type);
201  /// Return `value` as an attribute to attach to a GlobalOp.
202  Attribute getConstantAsAttr(llvm::Constant *value);
203  /// Return `c` as an MLIR Value. This could either be a ConstantOp, or
204  /// an expanded sequence of ops in the current function's entry block (for
205  /// ConstantExprs or ConstantGEPs).
206  Value processConstant(llvm::Constant *c);
207 
208  /// The current builder, pointing at where the next Instruction should be
209  /// generated.
210  OpBuilder b;
211  /// The current context.
212  MLIRContext *context;
213  /// The current module being created.
214  ModuleOp module;
215  /// The entry block of the current function being processed.
216  Block *currentEntryBlock = nullptr;
217 
218  /// Globals are inserted before the first function, if any.
219  Block::iterator getGlobalInsertPt() {
220  auto it = module.getBody()->begin();
221  auto endIt = module.getBody()->end();
222  while (it != endIt && !isa<LLVMFuncOp>(it))
223  ++it;
224  return it;
225  }
226 
227  /// Functions are always inserted before the module terminator.
228  Block::iterator getFuncInsertPt() {
229  return std::prev(module.getBody()->end());
230  }
231 
232  /// Remapped blocks, for the current function.
234  /// Remapped values. These are function-local.
236  /// Instructions that had not been defined when first encountered as a use.
237  /// Maps to the dummy Operation that was created in processValue().
239  /// Uniquing map of GlobalVariables.
241  /// Cached FileLineColLoc::get("imported-bitcode", 0, 0).
242  Location unknownLoc;
243  /// The stateful type translator (contains named structs).
244  LLVM::TypeFromLLVMIRTranslator typeTranslator;
245 };
246 } // namespace
247 
248 Location Importer::processDebugLoc(const llvm::DebugLoc &loc,
249  llvm::Instruction *inst) {
250  if (!loc && inst) {
251  std::string s;
252  llvm::raw_string_ostream os(s);
253  os << "llvm-imported-inst-%";
254  inst->printAsOperand(os, /*PrintType=*/false);
255  return FileLineColLoc::get(context, os.str(), 0, 0);
256  }
257  if (!loc) {
258  return unknownLoc;
259  }
260  // FIXME: Obtain the filename from DILocationInfo.
261  return FileLineColLoc::get(context, "imported-bitcode", loc.getLine(),
262  loc.getCol());
263 }
264 
265 Type Importer::processType(llvm::Type *type) {
266  if (Type result = typeTranslator.translateType(type))
267  return result;
268 
269  // FIXME: Diagnostic should be able to natively handle types that have
270  // operator<<(raw_ostream&) defined.
271  std::string s;
272  llvm::raw_string_ostream os(s);
273  os << *type;
274  emitError(unknownLoc) << "unhandled type: " << os.str();
275  return nullptr;
276 }
277 
278 // We only need integers, floats, doubles, and vectors and tensors thereof for
279 // attributes. Scalar and vector types are converted to the standard
280 // equivalents. Array types are converted to ranked tensors; nested array types
281 // are converted to multi-dimensional tensors or vectors, depending on the
282 // innermost type being a scalar or a vector.
283 Type Importer::getStdTypeForAttr(Type type) {
284  if (!type)
285  return nullptr;
286 
287  if (type.isa<IntegerType, FloatType>())
288  return type;
289 
290  // LLVM vectors can only contain scalars.
291  if (LLVM::isCompatibleVectorType(type)) {
292  auto numElements = LLVM::getVectorNumElements(type);
293  if (numElements.isScalable()) {
294  emitError(unknownLoc) << "scalable vectors not supported";
295  return nullptr;
296  }
297  Type elementType = getStdTypeForAttr(LLVM::getVectorElementType(type));
298  if (!elementType)
299  return nullptr;
300  return VectorType::get(numElements.getKnownMinValue(), elementType);
301  }
302 
303  // LLVM arrays can contain other arrays or vectors.
304  if (auto arrayType = type.dyn_cast<LLVMArrayType>()) {
305  // Recover the nested array shape.
307  shape.push_back(arrayType.getNumElements());
308  while (arrayType.getElementType().isa<LLVMArrayType>()) {
309  arrayType = arrayType.getElementType().cast<LLVMArrayType>();
310  shape.push_back(arrayType.getNumElements());
311  }
312 
313  // If the innermost type is a vector, use the multi-dimensional vector as
314  // attribute type.
315  if (LLVM::isCompatibleVectorType(arrayType.getElementType())) {
316  auto numElements = LLVM::getVectorNumElements(arrayType.getElementType());
317  if (numElements.isScalable()) {
318  emitError(unknownLoc) << "scalable vectors not supported";
319  return nullptr;
320  }
321  shape.push_back(numElements.getKnownMinValue());
322 
323  Type elementType = getStdTypeForAttr(
324  LLVM::getVectorElementType(arrayType.getElementType()));
325  if (!elementType)
326  return nullptr;
327  return VectorType::get(shape, elementType);
328  }
329 
330  // Otherwise use a tensor.
331  Type elementType = getStdTypeForAttr(arrayType.getElementType());
332  if (!elementType)
333  return nullptr;
334  return RankedTensorType::get(shape, elementType);
335  }
336 
337  return nullptr;
338 }
339 
340 // Get the given constant as an attribute. Not all constants can be represented
341 // as attributes.
342 Attribute Importer::getConstantAsAttr(llvm::Constant *value) {
343  if (auto *ci = dyn_cast<llvm::ConstantInt>(value))
344  return b.getIntegerAttr(
345  IntegerType::get(context, ci->getType()->getBitWidth()),
346  ci->getValue());
347  if (auto *c = dyn_cast<llvm::ConstantDataArray>(value))
348  if (c->isString())
349  return b.getStringAttr(c->getAsString());
350  if (auto *c = dyn_cast<llvm::ConstantFP>(value)) {
351  auto *type = c->getType();
352  FloatType floatTy;
353  if (type->isBFloatTy())
354  floatTy = FloatType::getBF16(context);
355  else
356  floatTy = getDLFloatType(*context, type->getScalarSizeInBits());
357  assert(floatTy && "unsupported floating point type");
358  return b.getFloatAttr(floatTy, c->getValueAPF());
359  }
360  if (auto *f = dyn_cast<llvm::Function>(value))
361  return SymbolRefAttr::get(b.getContext(), f->getName());
362 
363  // Convert constant data to a dense elements attribute.
364  if (auto *cd = dyn_cast<llvm::ConstantDataSequential>(value)) {
365  Type type = processType(cd->getElementType());
366  if (!type)
367  return nullptr;
368 
369  auto attrType = getStdTypeForAttr(processType(cd->getType()))
370  .dyn_cast_or_null<ShapedType>();
371  if (!attrType)
372  return nullptr;
373 
374  if (type.isa<IntegerType>()) {
375  SmallVector<APInt, 8> values;
376  values.reserve(cd->getNumElements());
377  for (unsigned i = 0, e = cd->getNumElements(); i < e; ++i)
378  values.push_back(cd->getElementAsAPInt(i));
379  return DenseElementsAttr::get(attrType, values);
380  }
381 
382  if (type.isa<Float32Type, Float64Type>()) {
384  values.reserve(cd->getNumElements());
385  for (unsigned i = 0, e = cd->getNumElements(); i < e; ++i)
386  values.push_back(cd->getElementAsAPFloat(i));
387  return DenseElementsAttr::get(attrType, values);
388  }
389 
390  return nullptr;
391  }
392 
393  // Unpack constant aggregates to create dense elements attribute whenever
394  // possible. Return nullptr (failure) otherwise.
395  if (isa<llvm::ConstantAggregate>(value)) {
396  auto outerType = getStdTypeForAttr(processType(value->getType()))
397  .dyn_cast_or_null<ShapedType>();
398  if (!outerType)
399  return nullptr;
400 
403 
404  for (unsigned i = 0, e = value->getNumOperands(); i < e; ++i) {
405  auto nested = getConstantAsAttr(value->getAggregateElement(i))
406  .dyn_cast_or_null<DenseElementsAttr>();
407  if (!nested)
408  return nullptr;
409 
410  values.append(nested.value_begin<Attribute>(),
411  nested.value_end<Attribute>());
412  }
413 
414  return DenseElementsAttr::get(outerType, values);
415  }
416 
417  return nullptr;
418 }
419 
420 GlobalOp Importer::processGlobal(llvm::GlobalVariable *gv) {
421  auto it = globals.find(gv);
422  if (it != globals.end())
423  return it->second;
424 
425  OpBuilder b(module.getBody(), getGlobalInsertPt());
426  Attribute valueAttr;
427  if (gv->hasInitializer())
428  valueAttr = getConstantAsAttr(gv->getInitializer());
429  Type type = processType(gv->getValueType());
430  if (!type)
431  return nullptr;
432 
433  uint64_t alignment = 0;
434  llvm::MaybeAlign maybeAlign = gv->getAlign();
435  if (maybeAlign.hasValue()) {
436  llvm::Align align = maybeAlign.getValue();
437  alignment = align.value();
438  }
439 
440  GlobalOp op = b.create<GlobalOp>(
441  UnknownLoc::get(context), type, gv->isConstant(),
442  convertLinkageFromLLVM(gv->getLinkage()), gv->getName(), valueAttr,
443  alignment, /*addr_space=*/gv->getAddressSpace(),
444  /*dso_local=*/gv->isDSOLocal(), /*thread_local=*/gv->isThreadLocal());
445 
446  if (gv->hasInitializer() && !valueAttr) {
447  Region &r = op.getInitializerRegion();
448  currentEntryBlock = b.createBlock(&r);
449  b.setInsertionPoint(currentEntryBlock, currentEntryBlock->begin());
450  Value v = processConstant(gv->getInitializer());
451  if (!v)
452  return nullptr;
453  b.create<ReturnOp>(op.getLoc(), ArrayRef<Value>({v}));
454  }
455  if (gv->hasAtLeastLocalUnnamedAddr())
456  op.setUnnamedAddrAttr(UnnamedAddrAttr::get(
457  context, convertUnnamedAddrFromLLVM(gv->getUnnamedAddr())));
458  if (gv->hasSection())
459  op.setSectionAttr(b.getStringAttr(gv->getSection()));
460 
461  return globals[gv] = op;
462 }
463 
464 Value Importer::processConstant(llvm::Constant *c) {
465  OpBuilder bEntry(currentEntryBlock, currentEntryBlock->begin());
466  if (Attribute attr = getConstantAsAttr(c)) {
467  // These constants can be represented as attributes.
468  OpBuilder b(currentEntryBlock, currentEntryBlock->begin());
469  Type type = processType(c->getType());
470  if (!type)
471  return nullptr;
472  if (auto symbolRef = attr.dyn_cast<FlatSymbolRefAttr>())
473  return bEntry.create<AddressOfOp>(unknownLoc, type, symbolRef.getValue());
474  return bEntry.create<ConstantOp>(unknownLoc, type, attr);
475  }
476  if (auto *cn = dyn_cast<llvm::ConstantPointerNull>(c)) {
477  Type type = processType(cn->getType());
478  if (!type)
479  return nullptr;
480  return bEntry.create<NullOp>(unknownLoc, type);
481  }
482  if (auto *gv = dyn_cast<llvm::GlobalVariable>(c))
483  return bEntry.create<AddressOfOp>(UnknownLoc::get(context),
484  processGlobal(gv));
485 
486  if (auto *ce = dyn_cast<llvm::ConstantExpr>(c)) {
487  llvm::Instruction *i = ce->getAsInstruction();
488  OpBuilder::InsertionGuard guard(b);
489  b.setInsertionPoint(currentEntryBlock, currentEntryBlock->begin());
490  if (failed(processInstruction(i)))
491  return nullptr;
492  assert(instMap.count(i));
493 
494  // If we don't remove entry of `i` here, it's totally possible that the
495  // next time llvm::ConstantExpr::getAsInstruction is called again, which
496  // always allocates a new Instruction, memory address of the newly
497  // created Instruction might be the same as `i`. Making processInstruction
498  // falsely believe that the new Instruction has been processed before
499  // and raised an assertion error.
500  Value value = instMap[i];
501  instMap.erase(i);
502  // Remove this zombie LLVM instruction now, leaving us only with the MLIR
503  // op.
504  i->deleteValue();
505  return value;
506  }
507  if (auto *ue = dyn_cast<llvm::UndefValue>(c)) {
508  Type type = processType(ue->getType());
509  if (!type)
510  return nullptr;
511  return bEntry.create<UndefOp>(UnknownLoc::get(context), type);
512  }
513 
514  if (isa<llvm::ConstantAggregate>(c) || isa<llvm::ConstantAggregateZero>(c)) {
515  unsigned numElements = c->getNumOperands();
516  std::function<llvm::Constant *(unsigned)> getElement =
517  [&](unsigned index) -> llvm::Constant * {
518  return c->getAggregateElement(index);
519  };
520  // llvm::ConstantAggregateZero doesn't take any operand
521  // so its getNumOperands is always zero.
522  if (auto *caz = dyn_cast<llvm::ConstantAggregateZero>(c)) {
523  numElements = caz->getElementCount().getFixedValue();
524  // We want to capture the pointer rather than reference
525  // to the pointer since the latter will become dangling upon
526  // exiting the scope.
527  getElement = [=](unsigned index) -> llvm::Constant * {
528  return caz->getElementValue(index);
529  };
530  }
531 
532  // Generate a llvm.undef as the root value first.
533  Type rootType = processType(c->getType());
534  if (!rootType)
535  return nullptr;
536  bool useInsertValue = rootType.isa<LLVMArrayType, LLVMStructType>();
537  assert((useInsertValue || LLVM::isCompatibleVectorType(rootType)) &&
538  "unrecognized aggregate type");
539  Value root = bEntry.create<UndefOp>(unknownLoc, rootType);
540  for (unsigned i = 0; i < numElements; ++i) {
541  llvm::Constant *element = getElement(i);
542  Value elementValue = processConstant(element);
543  if (!elementValue)
544  return nullptr;
545  if (useInsertValue) {
546  ArrayAttr indexAttr = bEntry.getI32ArrayAttr({static_cast<int32_t>(i)});
547  root = bEntry.create<InsertValueOp>(UnknownLoc::get(context), rootType,
548  root, elementValue, indexAttr);
549  } else {
550  Attribute indexAttr = bEntry.getI32IntegerAttr(static_cast<int32_t>(i));
551  Value indexValue = bEntry.create<ConstantOp>(
552  unknownLoc, bEntry.getI32Type(), indexAttr);
553  if (!indexValue)
554  return nullptr;
555  root = bEntry.create<InsertElementOp>(
556  UnknownLoc::get(context), rootType, root, elementValue, indexValue);
557  }
558  }
559  return root;
560  }
561 
562  emitError(unknownLoc) << "unhandled constant: " << diag(*c);
563  return nullptr;
564 }
565 
566 Value Importer::processValue(llvm::Value *value) {
567  auto it = instMap.find(value);
568  if (it != instMap.end())
569  return it->second;
570 
571  // We don't expect to see instructions in dominator order. If we haven't seen
572  // this instruction yet, create an unknown op and remap it later.
573  if (isa<llvm::Instruction>(value)) {
574  Type type = processType(value->getType());
575  if (!type)
576  return nullptr;
577  unknownInstMap[value] =
578  b.create(UnknownLoc::get(context), b.getStringAttr("llvm.unknown"),
579  /*operands=*/{}, type);
580  return unknownInstMap[value]->getResult(0);
581  }
582 
583  if (auto *c = dyn_cast<llvm::Constant>(value))
584  return processConstant(c);
585 
586  emitError(unknownLoc) << "unhandled value: " << diag(*value);
587  return nullptr;
588 }
589 
590 /// Return the MLIR OperationName for the given LLVM opcode.
591 static StringRef lookupOperationNameFromOpcode(unsigned opcode) {
592 // Maps from LLVM opcode to MLIR OperationName. This is deliberately ordered
593 // as in llvm/IR/Instructions.def to aid comprehension and spot missing
594 // instructions.
595 #define INST(llvm_n, mlir_n) \
596  { llvm::Instruction::llvm_n, LLVM::mlir_n##Op::getOperationName() }
597  static const DenseMap<unsigned, StringRef> opcMap = {
598  // clang-format off
599  INST(Ret, Return),
600  // Br is handled specially.
601  // Switch is handled specially.
602  // FIXME: indirectbr
603  // Invoke is handled specially.
604  INST(Resume, Resume),
605  INST(Unreachable, Unreachable),
606  // FIXME: cleanupret
607  // FIXME: catchret
608  // FIXME: catchswitch
609  // FIXME: callbr
610  INST(FNeg, FNeg),
611  INST(Add, Add),
612  INST(FAdd, FAdd),
613  INST(Sub, Sub),
614  INST(FSub, FSub),
615  INST(Mul, Mul),
616  INST(FMul, FMul),
617  INST(UDiv, UDiv),
618  INST(SDiv, SDiv),
619  INST(FDiv, FDiv),
620  INST(URem, URem),
621  INST(SRem, SRem),
622  INST(FRem, FRem),
623  INST(Shl, Shl),
624  INST(LShr, LShr),
625  INST(AShr, AShr),
626  INST(And, And),
627  INST(Or, Or),
628  INST(Xor, XOr),
629  INST(ExtractElement, ExtractElement),
630  INST(InsertElement, InsertElement),
631  // ShuffleVector is handled specially.
632  // ExtractValue is handled specially.
633  // InsertValue is handled specially.
634  INST(Alloca, Alloca),
635  INST(Load, Load),
636  INST(Store, Store),
637  INST(Fence, Fence),
638  // FIXME: atomiccmpxchg
639  // FIXME: atomicrmw
640  // Getelementptr is handled specially.
641  INST(Trunc, Trunc),
642  INST(ZExt, ZExt),
643  INST(SExt, SExt),
644  INST(FPToUI, FPToUI),
645  INST(FPToSI, FPToSI),
646  INST(UIToFP, UIToFP),
647  INST(SIToFP, SIToFP),
648  INST(FPTrunc, FPTrunc),
649  INST(FPExt, FPExt),
650  INST(PtrToInt, PtrToInt),
651  INST(IntToPtr, IntToPtr),
652  INST(BitCast, Bitcast),
653  INST(AddrSpaceCast, AddrSpaceCast),
654  // ICmp is handled specially.
655  // FCmp is handled specially.
656  // PHI is handled specially.
657  INST(Select, Select),
658  INST(Freeze, Freeze),
659  INST(Call, Call),
660  // FIXME: vaarg
661  // FIXME: landingpad
662  // FIXME: catchpad
663  // FIXME: cleanuppad
664  // clang-format on
665  };
666 #undef INST
667 
668  return opcMap.lookup(opcode);
669 }
670 
671 /// Return the MLIR OperationName for the given LLVM intrinsic ID.
672 static StringRef lookupOperationNameFromIntrinsicID(unsigned id) {
673  // Maps from LLVM intrinsic ID to MLIR OperationName.
674  static const DenseMap<unsigned, StringRef> intrMap = {
675 #include "mlir/Dialect/LLVMIR/LLVMIntrinsicToLLVMIROpPairs.inc"
676  };
677  return intrMap.lookup(id);
678 }
679 
680 static ICmpPredicate getICmpPredicate(llvm::CmpInst::Predicate p) {
681  switch (p) {
682  default:
683  llvm_unreachable("incorrect comparison predicate");
684  case llvm::CmpInst::Predicate::ICMP_EQ:
685  return LLVM::ICmpPredicate::eq;
686  case llvm::CmpInst::Predicate::ICMP_NE:
687  return LLVM::ICmpPredicate::ne;
688  case llvm::CmpInst::Predicate::ICMP_SLT:
689  return LLVM::ICmpPredicate::slt;
690  case llvm::CmpInst::Predicate::ICMP_SLE:
691  return LLVM::ICmpPredicate::sle;
692  case llvm::CmpInst::Predicate::ICMP_SGT:
693  return LLVM::ICmpPredicate::sgt;
694  case llvm::CmpInst::Predicate::ICMP_SGE:
695  return LLVM::ICmpPredicate::sge;
696  case llvm::CmpInst::Predicate::ICMP_ULT:
697  return LLVM::ICmpPredicate::ult;
698  case llvm::CmpInst::Predicate::ICMP_ULE:
699  return LLVM::ICmpPredicate::ule;
700  case llvm::CmpInst::Predicate::ICMP_UGT:
701  return LLVM::ICmpPredicate::ugt;
702  case llvm::CmpInst::Predicate::ICMP_UGE:
703  return LLVM::ICmpPredicate::uge;
704  }
705  llvm_unreachable("incorrect integer comparison predicate");
706 }
707 
708 static FCmpPredicate getFCmpPredicate(llvm::CmpInst::Predicate p) {
709  switch (p) {
710  default:
711  llvm_unreachable("incorrect comparison predicate");
712  case llvm::CmpInst::Predicate::FCMP_FALSE:
713  return LLVM::FCmpPredicate::_false;
714  case llvm::CmpInst::Predicate::FCMP_TRUE:
715  return LLVM::FCmpPredicate::_true;
716  case llvm::CmpInst::Predicate::FCMP_OEQ:
717  return LLVM::FCmpPredicate::oeq;
718  case llvm::CmpInst::Predicate::FCMP_ONE:
719  return LLVM::FCmpPredicate::one;
720  case llvm::CmpInst::Predicate::FCMP_OLT:
721  return LLVM::FCmpPredicate::olt;
722  case llvm::CmpInst::Predicate::FCMP_OLE:
723  return LLVM::FCmpPredicate::ole;
724  case llvm::CmpInst::Predicate::FCMP_OGT:
725  return LLVM::FCmpPredicate::ogt;
726  case llvm::CmpInst::Predicate::FCMP_OGE:
727  return LLVM::FCmpPredicate::oge;
728  case llvm::CmpInst::Predicate::FCMP_ORD:
729  return LLVM::FCmpPredicate::ord;
730  case llvm::CmpInst::Predicate::FCMP_ULT:
731  return LLVM::FCmpPredicate::ult;
732  case llvm::CmpInst::Predicate::FCMP_ULE:
733  return LLVM::FCmpPredicate::ule;
734  case llvm::CmpInst::Predicate::FCMP_UGT:
735  return LLVM::FCmpPredicate::ugt;
736  case llvm::CmpInst::Predicate::FCMP_UGE:
737  return LLVM::FCmpPredicate::uge;
738  case llvm::CmpInst::Predicate::FCMP_UNO:
739  return LLVM::FCmpPredicate::uno;
740  case llvm::CmpInst::Predicate::FCMP_UEQ:
741  return LLVM::FCmpPredicate::ueq;
742  case llvm::CmpInst::Predicate::FCMP_UNE:
743  return LLVM::FCmpPredicate::une;
744  }
745  llvm_unreachable("incorrect floating point comparison predicate");
746 }
747 
748 static AtomicOrdering getLLVMAtomicOrdering(llvm::AtomicOrdering ordering) {
749  switch (ordering) {
750  case llvm::AtomicOrdering::NotAtomic:
751  return LLVM::AtomicOrdering::not_atomic;
752  case llvm::AtomicOrdering::Unordered:
753  return LLVM::AtomicOrdering::unordered;
754  case llvm::AtomicOrdering::Monotonic:
755  return LLVM::AtomicOrdering::monotonic;
756  case llvm::AtomicOrdering::Acquire:
757  return LLVM::AtomicOrdering::acquire;
758  case llvm::AtomicOrdering::Release:
759  return LLVM::AtomicOrdering::release;
760  case llvm::AtomicOrdering::AcquireRelease:
761  return LLVM::AtomicOrdering::acq_rel;
762  case llvm::AtomicOrdering::SequentiallyConsistent:
763  return LLVM::AtomicOrdering::seq_cst;
764  }
765  llvm_unreachable("incorrect atomic ordering");
766 }
767 
768 // `br` branches to `target`. Return the branch arguments to `br`, in the
769 // same order of the PHIs in `target`.
771 Importer::processBranchArgs(llvm::Instruction *br, llvm::BasicBlock *target,
772  SmallVectorImpl<Value> &blockArguments) {
773  for (auto inst = target->begin(); isa<llvm::PHINode>(inst); ++inst) {
774  auto *pn = cast<llvm::PHINode>(&*inst);
775  Value value = processValue(pn->getIncomingValueForBlock(br->getParent()));
776  if (!value)
777  return failure();
778  blockArguments.push_back(value);
779  }
780  return success();
781 }
782 
783 LogicalResult Importer::processInstruction(llvm::Instruction *inst) {
784  // FIXME: Support uses of SubtargetData. Currently inbounds GEPs, fast-math
785  // flags and call / operand attributes are not supported.
786  Location loc = processDebugLoc(inst->getDebugLoc(), inst);
787  assert(!instMap.count(inst) &&
788  "processInstruction must be called only once per instruction!");
789  switch (inst->getOpcode()) {
790  default:
791  return emitError(loc) << "unknown instruction: " << diag(*inst);
792  case llvm::Instruction::Add:
793  case llvm::Instruction::FAdd:
794  case llvm::Instruction::Sub:
795  case llvm::Instruction::FSub:
796  case llvm::Instruction::Mul:
797  case llvm::Instruction::FMul:
798  case llvm::Instruction::UDiv:
799  case llvm::Instruction::SDiv:
800  case llvm::Instruction::FDiv:
801  case llvm::Instruction::URem:
802  case llvm::Instruction::SRem:
803  case llvm::Instruction::FRem:
804  case llvm::Instruction::Shl:
805  case llvm::Instruction::LShr:
806  case llvm::Instruction::AShr:
807  case llvm::Instruction::And:
808  case llvm::Instruction::Or:
809  case llvm::Instruction::Xor:
810  case llvm::Instruction::Load:
811  case llvm::Instruction::Store:
812  case llvm::Instruction::Ret:
813  case llvm::Instruction::Resume:
814  case llvm::Instruction::Trunc:
815  case llvm::Instruction::ZExt:
816  case llvm::Instruction::SExt:
817  case llvm::Instruction::FPToUI:
818  case llvm::Instruction::FPToSI:
819  case llvm::Instruction::UIToFP:
820  case llvm::Instruction::SIToFP:
821  case llvm::Instruction::FPTrunc:
822  case llvm::Instruction::FPExt:
823  case llvm::Instruction::PtrToInt:
824  case llvm::Instruction::IntToPtr:
825  case llvm::Instruction::AddrSpaceCast:
826  case llvm::Instruction::Freeze:
827  case llvm::Instruction::BitCast:
828  case llvm::Instruction::ExtractElement:
829  case llvm::Instruction::InsertElement:
830  case llvm::Instruction::Select:
831  case llvm::Instruction::FNeg:
832  case llvm::Instruction::Unreachable: {
833  OperationState state(loc, lookupOperationNameFromOpcode(inst->getOpcode()));
835  ops.reserve(inst->getNumOperands());
836  for (auto *op : inst->operand_values()) {
837  Value value = processValue(op);
838  if (!value)
839  return failure();
840  ops.push_back(value);
841  }
842  state.addOperands(ops);
843  if (!inst->getType()->isVoidTy()) {
844  Type type = processType(inst->getType());
845  if (!type)
846  return failure();
847  state.addTypes(type);
848  }
849  Operation *op = b.create(state);
850  if (!inst->getType()->isVoidTy())
851  instMap[inst] = op->getResult(0);
852  return success();
853  }
854  case llvm::Instruction::Alloca: {
855  Value size = processValue(inst->getOperand(0));
856  if (!size)
857  return failure();
858 
859  auto *allocaInst = cast<llvm::AllocaInst>(inst);
860  instMap[inst] =
861  b.create<AllocaOp>(loc, processType(inst->getType()),
862  processType(allocaInst->getAllocatedType()), size,
863  allocaInst->getAlign().value());
864  return success();
865  }
866  case llvm::Instruction::ICmp: {
867  Value lhs = processValue(inst->getOperand(0));
868  Value rhs = processValue(inst->getOperand(1));
869  if (!lhs || !rhs)
870  return failure();
871  instMap[inst] = b.create<ICmpOp>(
872  loc, getICmpPredicate(cast<llvm::ICmpInst>(inst)->getPredicate()), lhs,
873  rhs);
874  return success();
875  }
876  case llvm::Instruction::FCmp: {
877  Value lhs = processValue(inst->getOperand(0));
878  Value rhs = processValue(inst->getOperand(1));
879  if (!lhs || !rhs)
880  return failure();
881  instMap[inst] = b.create<FCmpOp>(
882  loc, b.getI1Type(),
883  getFCmpPredicate(cast<llvm::FCmpInst>(inst)->getPredicate()), lhs, rhs);
884  return success();
885  }
886  case llvm::Instruction::Br: {
887  auto *brInst = cast<llvm::BranchInst>(inst);
888  OperationState state(loc,
889  brInst->isConditional() ? "llvm.cond_br" : "llvm.br");
890  if (brInst->isConditional()) {
891  Value condition = processValue(brInst->getCondition());
892  if (!condition)
893  return failure();
894  state.addOperands(condition);
895  }
896 
897  std::array<int32_t, 3> operandSegmentSizes = {1, 0, 0};
898  for (int i : llvm::seq<int>(0, brInst->getNumSuccessors())) {
899  auto *succ = brInst->getSuccessor(i);
900  SmallVector<Value, 4> blockArguments;
901  if (failed(processBranchArgs(brInst, succ, blockArguments)))
902  return failure();
903  state.addSuccessors(blocks[succ]);
904  state.addOperands(blockArguments);
905  operandSegmentSizes[i + 1] = blockArguments.size();
906  }
907 
908  if (brInst->isConditional()) {
909  state.addAttribute(LLVM::CondBrOp::getOperandSegmentSizeAttr(),
910  b.getI32VectorAttr(operandSegmentSizes));
911  }
912 
913  b.create(state);
914  return success();
915  }
916  case llvm::Instruction::Switch: {
917  auto *swInst = cast<llvm::SwitchInst>(inst);
918  // Process the condition value.
919  Value condition = processValue(swInst->getCondition());
920  if (!condition)
921  return failure();
922 
923  SmallVector<Value> defaultBlockArgs;
924  // Process the default case.
925  llvm::BasicBlock *defaultBB = swInst->getDefaultDest();
926  if (failed(processBranchArgs(swInst, defaultBB, defaultBlockArgs)))
927  return failure();
928 
929  // Process the cases.
930  unsigned numCases = swInst->getNumCases();
931  SmallVector<SmallVector<Value>> caseOperands(numCases);
932  SmallVector<ValueRange> caseOperandRefs(numCases);
933  SmallVector<int32_t> caseValues(numCases);
934  SmallVector<Block *> caseBlocks(numCases);
935  for (const auto &en : llvm::enumerate(swInst->cases())) {
936  const llvm::SwitchInst::CaseHandle &caseHandle = en.value();
937  unsigned i = en.index();
938  llvm::BasicBlock *succBB = caseHandle.getCaseSuccessor();
939  if (failed(processBranchArgs(swInst, succBB, caseOperands[i])))
940  return failure();
941  caseOperandRefs[i] = caseOperands[i];
942  caseValues[i] = caseHandle.getCaseValue()->getSExtValue();
943  caseBlocks[i] = blocks[succBB];
944  }
945 
946  b.create<SwitchOp>(loc, condition, blocks[defaultBB], defaultBlockArgs,
947  caseValues, caseBlocks, caseOperandRefs);
948  return success();
949  }
950  case llvm::Instruction::PHI: {
951  Type type = processType(inst->getType());
952  if (!type)
953  return failure();
954  instMap[inst] = b.getInsertionBlock()->addArgument(
955  type, processDebugLoc(inst->getDebugLoc(), inst));
956  return success();
957  }
958  case llvm::Instruction::Call: {
959  llvm::CallInst *ci = cast<llvm::CallInst>(inst);
961  ops.reserve(inst->getNumOperands());
962  for (auto &op : ci->args()) {
963  Value arg = processValue(op.get());
964  if (!arg)
965  return failure();
966  ops.push_back(arg);
967  }
968 
970  if (!ci->getType()->isVoidTy()) {
971  Type type = processType(inst->getType());
972  if (!type)
973  return failure();
974  tys.push_back(type);
975  }
976  Operation *op;
977  if (llvm::Function *callee = ci->getCalledFunction()) {
978  // For all intrinsics, try to generate to the corresponding op.
979  if (callee->isIntrinsic()) {
980  auto id = callee->getIntrinsicID();
981  StringRef opName = lookupOperationNameFromIntrinsicID(id);
982  if (!opName.empty()) {
983  OperationState state(loc, opName);
984  state.addOperands(ops);
985  state.addTypes(tys);
986  Operation *op = b.create(state);
987  if (!inst->getType()->isVoidTy())
988  instMap[inst] = op->getResult(0);
989  return success();
990  }
991  }
992  op = b.create<CallOp>(
993  loc, tys, SymbolRefAttr::get(b.getContext(), callee->getName()), ops);
994  } else {
995  Value calledValue = processValue(ci->getCalledOperand());
996  if (!calledValue)
997  return failure();
998  ops.insert(ops.begin(), calledValue);
999  op = b.create<CallOp>(loc, tys, ops);
1000  }
1001  if (!ci->getType()->isVoidTy())
1002  instMap[inst] = op->getResult(0);
1003  return success();
1004  }
1005  case llvm::Instruction::LandingPad: {
1006  llvm::LandingPadInst *lpi = cast<llvm::LandingPadInst>(inst);
1008 
1009  for (unsigned i = 0, ie = lpi->getNumClauses(); i < ie; i++)
1010  ops.push_back(processConstant(lpi->getClause(i)));
1011 
1012  Type ty = processType(lpi->getType());
1013  if (!ty)
1014  return failure();
1015 
1016  instMap[inst] = b.create<LandingpadOp>(loc, ty, lpi->isCleanup(), ops);
1017  return success();
1018  }
1019  case llvm::Instruction::Invoke: {
1020  llvm::InvokeInst *ii = cast<llvm::InvokeInst>(inst);
1021 
1023  if (!ii->getType()->isVoidTy())
1024  tys.push_back(processType(inst->getType()));
1025 
1027  ops.reserve(inst->getNumOperands() + 1);
1028  for (auto &op : ii->args())
1029  ops.push_back(processValue(op.get()));
1030 
1031  SmallVector<Value, 4> normalArgs, unwindArgs;
1032  (void)processBranchArgs(ii, ii->getNormalDest(), normalArgs);
1033  (void)processBranchArgs(ii, ii->getUnwindDest(), unwindArgs);
1034 
1035  Operation *op;
1036  if (llvm::Function *callee = ii->getCalledFunction()) {
1037  op = b.create<InvokeOp>(
1038  loc, tys, SymbolRefAttr::get(b.getContext(), callee->getName()), ops,
1039  blocks[ii->getNormalDest()], normalArgs, blocks[ii->getUnwindDest()],
1040  unwindArgs);
1041  } else {
1042  ops.insert(ops.begin(), processValue(ii->getCalledOperand()));
1043  op = b.create<InvokeOp>(loc, tys, ops, blocks[ii->getNormalDest()],
1044  normalArgs, blocks[ii->getUnwindDest()],
1045  unwindArgs);
1046  }
1047 
1048  if (!ii->getType()->isVoidTy())
1049  instMap[inst] = op->getResult(0);
1050  return success();
1051  }
1052  case llvm::Instruction::Fence: {
1053  StringRef syncscope;
1055  llvm::LLVMContext &llvmContext = inst->getContext();
1056  llvm::FenceInst *fence = cast<llvm::FenceInst>(inst);
1057  llvmContext.getSyncScopeNames(ssNs);
1058  int fenceSyncScopeID = fence->getSyncScopeID();
1059  for (unsigned i = 0, e = ssNs.size(); i != e; i++) {
1060  if (fenceSyncScopeID == llvmContext.getOrInsertSyncScopeID(ssNs[i])) {
1061  syncscope = ssNs[i];
1062  break;
1063  }
1064  }
1065  b.create<FenceOp>(loc, getLLVMAtomicOrdering(fence->getOrdering()),
1066  syncscope);
1067  return success();
1068  }
1069  case llvm::Instruction::GetElementPtr: {
1070  // FIXME: Support inbounds GEPs.
1071  llvm::GetElementPtrInst *gep = cast<llvm::GetElementPtrInst>(inst);
1072  Value basePtr = processValue(gep->getOperand(0));
1073  Type sourceElementType = processType(gep->getSourceElementType());
1074 
1075  SmallVector<Value> indices;
1076  for (llvm::Value *operand : llvm::drop_begin(gep->operand_values())) {
1077  indices.push_back(processValue(operand));
1078  if (!indices.back())
1079  return failure();
1080  }
1081  // Treat every indices as dynamic since GEPOp::build will refine those
1082  // indices into static attributes later. One small downside of this
1083  // approach is that many unused `llvm.mlir.constant` would be emitted
1084  // at first place.
1085  SmallVector<int32_t> structIndices(indices.size(),
1086  LLVM::GEPOp::kDynamicIndex);
1087 
1088  Type type = processType(inst->getType());
1089  if (!type)
1090  return failure();
1091  instMap[inst] = b.create<GEPOp>(loc, type, sourceElementType, basePtr,
1092  indices, structIndices);
1093  return success();
1094  }
1095  case llvm::Instruction::InsertValue: {
1096  auto *ivInst = cast<llvm::InsertValueInst>(inst);
1097  Value inserted = processValue(ivInst->getInsertedValueOperand());
1098  if (!inserted)
1099  return failure();
1100  Value aggOperand = processValue(ivInst->getAggregateOperand());
1101  if (!aggOperand)
1102  return failure();
1103 
1104  SmallVector<int32_t> idxValues;
1105  for (unsigned idx : ivInst->getIndices())
1106  idxValues.push_back(static_cast<int32_t>(idx));
1107  ArrayAttr indices = b.getI32ArrayAttr(idxValues);
1108 
1109  instMap[inst] = b.create<InsertValueOp>(loc, aggOperand, inserted, indices);
1110  return success();
1111  }
1112  case llvm::Instruction::ExtractValue: {
1113  auto *evInst = cast<llvm::ExtractValueInst>(inst);
1114  Value aggOperand = processValue(evInst->getAggregateOperand());
1115  if (!aggOperand)
1116  return failure();
1117 
1118  Type type = processType(inst->getType());
1119  if (!type)
1120  return failure();
1121 
1122  SmallVector<int32_t> idxValues;
1123  for (unsigned idx : evInst->getIndices())
1124  idxValues.push_back(static_cast<int32_t>(idx));
1125  ArrayAttr indices = b.getI32ArrayAttr(idxValues);
1126 
1127  instMap[inst] = b.create<ExtractValueOp>(loc, type, aggOperand, indices);
1128  return success();
1129  }
1130  case llvm::Instruction::ShuffleVector: {
1131  auto *svInst = cast<llvm::ShuffleVectorInst>(inst);
1132  Value vec1 = processValue(svInst->getOperand(0));
1133  if (!vec1)
1134  return failure();
1135  Value vec2 = processValue(svInst->getOperand(1));
1136  if (!vec2)
1137  return failure();
1138 
1139  ArrayAttr mask = b.getI32ArrayAttr(svInst->getShuffleMask());
1140 
1141  instMap[inst] = b.create<ShuffleVectorOp>(loc, vec1, vec2, mask);
1142  return success();
1143  }
1144  }
1145 }
1146 
1147 FlatSymbolRefAttr Importer::getPersonalityAsAttr(llvm::Function *f) {
1148  if (!f->hasPersonalityFn())
1149  return nullptr;
1150 
1151  llvm::Constant *pf = f->getPersonalityFn();
1152 
1153  // If it directly has a name, we can use it.
1154  if (pf->hasName())
1155  return SymbolRefAttr::get(b.getContext(), pf->getName());
1156 
1157  // If it doesn't have a name, currently, only function pointers that are
1158  // bitcast to i8* are parsed.
1159  if (auto *ce = dyn_cast<llvm::ConstantExpr>(pf)) {
1160  if (ce->getOpcode() == llvm::Instruction::BitCast &&
1161  ce->getType() == llvm::Type::getInt8PtrTy(f->getContext())) {
1162  if (auto *func = dyn_cast<llvm::Function>(ce->getOperand(0)))
1163  return SymbolRefAttr::get(b.getContext(), func->getName());
1164  }
1165  }
1166  return FlatSymbolRefAttr();
1167 }
1168 
1169 LogicalResult Importer::processFunction(llvm::Function *f) {
1170  blocks.clear();
1171  instMap.clear();
1172  unknownInstMap.clear();
1173 
1174  auto functionType =
1175  processType(f->getFunctionType()).dyn_cast<LLVMFunctionType>();
1176  if (!functionType)
1177  return failure();
1178 
1179  if (f->isIntrinsic()) {
1180  StringRef opName = lookupOperationNameFromIntrinsicID(f->getIntrinsicID());
1181  // Skip the intrinsic decleration if we could found a corresponding op.
1182  if (!opName.empty())
1183  return success();
1184  }
1185 
1186  bool dsoLocal = f->hasLocalLinkage();
1187  CConv cconv = convertCConvFromLLVM(f->getCallingConv());
1188 
1189  b.setInsertionPoint(module.getBody(), getFuncInsertPt());
1190  LLVMFuncOp fop = b.create<LLVMFuncOp>(
1191  UnknownLoc::get(context), f->getName(), functionType,
1192  convertLinkageFromLLVM(f->getLinkage()), dsoLocal, cconv);
1193 
1194  if (FlatSymbolRefAttr personality = getPersonalityAsAttr(f))
1195  fop->setAttr(b.getStringAttr("personality"), personality);
1196  else if (f->hasPersonalityFn())
1197  emitWarning(UnknownLoc::get(context),
1198  "could not deduce personality, skipping it");
1199 
1200  if (f->hasGC())
1201  fop.setGarbageCollectorAttr(b.getStringAttr(f->getGC()));
1202 
1203  if (f->isDeclaration())
1204  return success();
1205 
1206  // Eagerly create all blocks.
1207  SmallVector<Block *, 4> blockList;
1208  for (llvm::BasicBlock &bb : *f) {
1209  blockList.push_back(b.createBlock(&fop.getBody(), fop.getBody().end()));
1210  blocks[&bb] = blockList.back();
1211  }
1212  currentEntryBlock = blockList[0];
1213 
1214  // Add function arguments to the entry block.
1215  for (const auto &kv : llvm::enumerate(f->args())) {
1216  instMap[&kv.value()] = blockList[0]->addArgument(
1217  functionType.getParamType(kv.index()), fop.getLoc());
1218  }
1219 
1220  for (auto bbs : llvm::zip(*f, blockList)) {
1221  if (failed(processBasicBlock(&std::get<0>(bbs), std::get<1>(bbs))))
1222  return failure();
1223  }
1224 
1225  // Now that all instructions are guaranteed to have been visited, ensure
1226  // any unknown uses we encountered are remapped.
1227  for (auto &llvmAndUnknown : unknownInstMap) {
1228  assert(instMap.count(llvmAndUnknown.first));
1229  Value newValue = instMap[llvmAndUnknown.first];
1230  Value oldValue = llvmAndUnknown.second->getResult(0);
1231  oldValue.replaceAllUsesWith(newValue);
1232  llvmAndUnknown.second->erase();
1233  }
1234  return success();
1235 }
1236 
1237 LogicalResult Importer::processBasicBlock(llvm::BasicBlock *bb, Block *block) {
1238  b.setInsertionPointToStart(block);
1239  for (llvm::Instruction &inst : *bb) {
1240  if (failed(processInstruction(&inst)))
1241  return failure();
1242  }
1243  return success();
1244 }
1245 
1247 mlir::translateLLVMIRToModule(std::unique_ptr<llvm::Module> llvmModule,
1248  MLIRContext *context) {
1249  context->loadDialect<LLVMDialect>();
1250  context->loadDialect<DLTIDialect>();
1251  OwningOpRef<ModuleOp> module(ModuleOp::create(
1252  FileLineColLoc::get(context, "", /*line=*/0, /*column=*/0)));
1253 
1254  DataLayoutSpecInterface dlSpec =
1255  translateDataLayout(llvmModule->getDataLayout(), context);
1256  if (!dlSpec) {
1257  emitError(UnknownLoc::get(context), "can't translate data layout");
1258  return {};
1259  }
1260 
1261  module.get()->setAttr(DLTIDialect::kDataLayoutAttrName, dlSpec);
1262 
1263  Importer deserializer(context, module.get());
1264  for (llvm::GlobalVariable &gv : llvmModule->globals()) {
1265  if (!deserializer.processGlobal(&gv))
1266  return {};
1267  }
1268  for (llvm::Function &f : llvmModule->functions()) {
1269  if (failed(deserializer.processFunction(&f)))
1270  return {};
1271  }
1272 
1273  return module;
1274 }
1275 
1276 // Deserializes the LLVM bitcode stored in `input` into an MLIR module in the
1277 // LLVM dialect.
1279  MLIRContext *context) {
1280  llvm::SMDiagnostic err;
1281  llvm::LLVMContext llvmContext;
1282  std::unique_ptr<llvm::Module> llvmModule = llvm::parseIR(
1283  *sourceMgr.getMemoryBuffer(sourceMgr.getMainFileID()), err, llvmContext);
1284  if (!llvmModule) {
1285  std::string errStr;
1286  llvm::raw_string_ostream errStream(errStr);
1287  err.print(/*ProgName=*/"", errStream);
1288  emitError(UnknownLoc::get(context)) << errStream.str();
1289  return {};
1290  }
1291  return translateLLVMIRToModule(std::move(llvmModule), context);
1292 }
1293 
1294 namespace mlir {
1296  TranslateToMLIRRegistration fromLLVM(
1297  "import-llvm", [](llvm::SourceMgr &sourceMgr, MLIRContext *context) {
1298  return ::translateLLVMIRToModule(sourceMgr, context);
1299  });
1300 }
1301 } // namespace mlir
Use Translate[ToMLIR|FromMLIR]Registration as an initializer that registers a function and associates...
Definition: Translation.h:73
TODO: Remove this file when SCCP and integer range analysis have been ported to the new framework...
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:865
iterator begin()
Definition: Block.h:134
static std::string diag(llvm::Value &v)
OwningOpRef< ModuleOp > translateLLVMIRToModule(llvm::SourceMgr &sourceMgr, MLIRContext *context)
Operation is a basic unit of execution within MLIR.
Definition: Operation.h:28
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 FCmpPredicate getFCmpPredicate(llvm::CmpInst::Predicate p)
static StringRef lookupOperationNameFromOpcode(unsigned opcode)
Return the MLIR OperationName for the given LLVM opcode.
static FloatType getF32(MLIRContext *ctx)
Definition: BuiltinTypes.h:392
void loadDialect()
Load a dialect in the context.
Definition: MLIRContext.h:102
static FloatType getDLFloatType(MLIRContext &ctx, int32_t bitwidth)
Returns a supported MLIR floating point type of the given bit width or null if the bit width is not s...
static FloatType getBF16(MLIRContext *ctx)
Definition: BuiltinTypes.h:384
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:162
InFlightDiagnostic emitWarning(Location loc)
Utility method to emit a warning message using this location.
static constexpr const bool value
static DenseIntElementsAttr parseDataLayoutAlignment(MLIRContext &ctx, StringRef spec)
Creates an attribute containing ABI and preferred alignment numbers parsed a string.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition: Location.h:48
static DataLayoutEntryAttr get(StringAttr key, Attribute value)
Returns the entry with the given key and value.
Definition: DLTI.cpp:52
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:259
U dyn_cast() const
Definition: Types.h:256
Attributes are known-constant values of operations.
Definition: Attributes.h:24
constexpr void enumerate(std::tuple< Tys... > &tuple, CallbackT &&callback)
Definition: Matchers.h:234
static DenseIntElementsAttr get(const ShapedType &type, Arg &&arg)
Get an instance of a DenseIntElementsAttr with the given arguments.
OpResult getResult(unsigned idx)
Get the &#39;idx&#39;th result of this operation.
Definition: Operation.h:331
RHS of mul is always a constant or a symbolic expression.
static FloatType getF128(MLIRContext *ctx)
Definition: BuiltinTypes.h:404
void addTypes(ArrayRef< Type > newTypes)
static StringRef lookupOperationNameFromIntrinsicID(unsigned id)
Return the MLIR OperationName for the given LLVM intrinsic ID.
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:85
LLVM dialect array type.
Definition: LLVMTypes.h:75
RAII guard to reset the insertion point of the builder when destroyed.
Definition: Builders.h:286
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
LLVM dialect structure type representing a collection of different-typed elements manipulated togethe...
Definition: LLVMTypes.h:277
bool isCompatibleVectorType(Type type)
Returns true if the given type is a vector type compatible with the LLVM dialect. ...
Definition: LLVMTypes.cpp:840
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:55
static FloatType getF80(MLIRContext *ctx)
Definition: BuiltinTypes.h:400
static FloatType getF16(MLIRContext *ctx)
Definition: BuiltinTypes.h:388
OwningOpRef< ModuleOp > translateLLVMIRToModule(std::unique_ptr< llvm::Module > llvmModule, MLIRContext *context)
Convert the given LLVM module into MLIR&#39;s LLVM dialect.
static DataLayoutSpecAttr get(MLIRContext *ctx, ArrayRef< DataLayoutEntryInterface > entries)
Returns the specification containing the given list of keys.
Definition: DLTI.cpp:133
bool isa() const
Definition: Types.h:246
static AtomicOrdering getLLVMAtomicOrdering(llvm::AtomicOrdering ordering)
This class helps build Operations.
Definition: Builders.h:184
DataLayoutSpecInterface translateDataLayout(const llvm::DataLayout &dataLayout, MLIRContext *context)
Translate the given LLVM data layout into an MLIR equivalent using the DLTI dialect.
Type getVectorElementType(Type type)
Returns the element type of any vector type compatible with the LLVM dialect.
Definition: LLVMTypes.cpp:856
static FloatType getF64(MLIRContext *ctx)
Definition: BuiltinTypes.h:396
#define INST(llvm_n, mlir_n)
static void processValue(Value value, LiveMap &liveMap)
An attribute that represents a reference to a dense integer vector or tensor object.