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