MLIR  20.0.0git
TypeFromLLVM.cpp
Go to the documentation of this file.
1 //===- TypeFromLLVM.cpp - type translation from LLVM to MLIR IR -===//
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 
11 #include "mlir/IR/BuiltinTypes.h"
12 #include "mlir/IR/MLIRContext.h"
13 
14 #include "llvm/ADT/TypeSwitch.h"
15 #include "llvm/IR/DataLayout.h"
16 #include "llvm/IR/DerivedTypes.h"
17 #include "llvm/IR/Type.h"
18 
19 using namespace mlir;
20 
21 namespace mlir {
22 namespace LLVM {
23 namespace detail {
24 /// Support for translating LLVM IR types to MLIR LLVM dialect types.
26 public:
27  /// Constructs a class creating types in the given MLIR context.
28  TypeFromLLVMIRTranslatorImpl(MLIRContext &context) : context(context) {}
29 
30  /// Translates the given type.
31  Type translateType(llvm::Type *type) {
32  if (knownTranslations.count(type))
33  return knownTranslations.lookup(type);
34 
35  Type translated =
37  .Case<llvm::ArrayType, llvm::FunctionType, llvm::IntegerType,
38  llvm::PointerType, llvm::StructType, llvm::FixedVectorType,
39  llvm::ScalableVectorType, llvm::TargetExtType>(
40  [this](auto *type) { return this->translate(type); })
41  .Default([this](llvm::Type *type) {
42  return translatePrimitiveType(type);
43  });
44  knownTranslations.try_emplace(type, translated);
45  return translated;
46  }
47 
48 private:
49  /// Translates the given primitive, i.e. non-parametric in MLIR nomenclature,
50  /// type.
51  Type translatePrimitiveType(llvm::Type *type) {
52  if (type->isVoidTy())
53  return LLVM::LLVMVoidType::get(&context);
54  if (type->isHalfTy())
55  return Float16Type::get(&context);
56  if (type->isBFloatTy())
57  return BFloat16Type::get(&context);
58  if (type->isFloatTy())
59  return Float32Type::get(&context);
60  if (type->isDoubleTy())
61  return Float64Type::get(&context);
62  if (type->isFP128Ty())
63  return Float128Type::get(&context);
64  if (type->isX86_FP80Ty())
65  return Float80Type::get(&context);
66  if (type->isPPC_FP128Ty())
67  return LLVM::LLVMPPCFP128Type::get(&context);
68  if (type->isLabelTy())
69  return LLVM::LLVMLabelType::get(&context);
70  if (type->isMetadataTy())
71  return LLVM::LLVMMetadataType::get(&context);
72  if (type->isTokenTy())
73  return LLVM::LLVMTokenType::get(&context);
74  llvm_unreachable("not a primitive type");
75  }
76 
77  /// Translates the given array type.
78  Type translate(llvm::ArrayType *type) {
79  return LLVM::LLVMArrayType::get(translateType(type->getElementType()),
80  type->getNumElements());
81  }
82 
83  /// Translates the given function type.
84  Type translate(llvm::FunctionType *type) {
85  SmallVector<Type, 8> paramTypes;
86  translateTypes(type->params(), paramTypes);
87  return LLVM::LLVMFunctionType::get(translateType(type->getReturnType()),
88  paramTypes, type->isVarArg());
89  }
90 
91  /// Translates the given integer type.
92  Type translate(llvm::IntegerType *type) {
93  return IntegerType::get(&context, type->getBitWidth());
94  }
95 
96  /// Translates the given pointer type.
97  Type translate(llvm::PointerType *type) {
98  return LLVM::LLVMPointerType::get(&context, type->getAddressSpace());
99  }
100 
101  /// Translates the given structure type.
102  Type translate(llvm::StructType *type) {
103  SmallVector<Type, 8> subtypes;
104  if (type->isLiteral()) {
105  translateTypes(type->subtypes(), subtypes);
106  return LLVM::LLVMStructType::getLiteral(&context, subtypes,
107  type->isPacked());
108  }
109 
110  if (type->isOpaque())
111  return LLVM::LLVMStructType::getOpaque(type->getName(), &context);
112 
113  // With opaque pointers, types in LLVM can't be recursive anymore. Note that
114  // using getIdentified is not possible, as type names in LLVM are not
115  // guaranteed to be unique.
116  translateTypes(type->subtypes(), subtypes);
118  &context, type->getName(), subtypes, type->isPacked());
119  knownTranslations.try_emplace(type, translated);
120  return translated;
121  }
122 
123  /// Translates the given fixed-vector type.
124  Type translate(llvm::FixedVectorType *type) {
125  return LLVM::getFixedVectorType(translateType(type->getElementType()),
126  type->getNumElements());
127  }
128 
129  /// Translates the given scalable-vector type.
130  Type translate(llvm::ScalableVectorType *type) {
132  translateType(type->getElementType()), type->getMinNumElements());
133  }
134 
135  /// Translates the given target extension type.
136  Type translate(llvm::TargetExtType *type) {
137  SmallVector<Type> typeParams;
138  translateTypes(type->type_params(), typeParams);
139 
140  return LLVM::LLVMTargetExtType::get(&context, type->getName(), typeParams,
141  type->int_params());
142  }
143 
144  /// Translates a list of types.
145  void translateTypes(ArrayRef<llvm::Type *> types,
146  SmallVectorImpl<Type> &result) {
147  result.reserve(result.size() + types.size());
148  for (llvm::Type *type : types)
149  result.push_back(translateType(type));
150  }
151 
152  /// Map of known translations. Serves as a cache and as recursion stopper for
153  /// translating recursive structs.
154  llvm::DenseMap<llvm::Type *, Type> knownTranslations;
155 
156  /// The context in which MLIR types are created.
157  MLIRContext &context;
158 };
159 
160 } // namespace detail
161 } // namespace LLVM
162 } // namespace mlir
163 
165  : impl(new detail::TypeFromLLVMIRTranslatorImpl(context)) {}
166 
168 
170  return impl->translateType(type);
171 }
LLVM dialect structure type representing a collection of different-typed elements manipulated togethe...
Definition: LLVMTypes.h:108
static LLVMStructType getLiteral(MLIRContext *context, ArrayRef< Type > types, bool isPacked=false)
Gets or creates a literal struct with the given body in the provided context.
Definition: LLVMTypes.cpp:453
static LLVMStructType getNewIdentified(MLIRContext *context, StringRef name, ArrayRef< Type > elements, bool isPacked=false)
Gets a new identified struct with the given body.
Definition: LLVMTypes.cpp:436
static LLVMStructType getOpaque(StringRef name, MLIRContext *context)
Gets or creates an intentionally-opaque identified struct.
Definition: LLVMTypes.cpp:465
Type translateType(llvm::Type *type)
Translates the given LLVM IR type to the MLIR LLVM dialect.
TypeFromLLVMIRTranslator(MLIRContext &context)
Support for translating LLVM IR types to MLIR LLVM dialect types.
TypeFromLLVMIRTranslatorImpl(MLIRContext &context)
Constructs a class creating types in the given MLIR context.
Type translateType(llvm::Type *type)
Translates the given type.
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:60
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:74
Type getFixedVectorType(Type elementType, unsigned numElements)
Creates an LLVM dialect-compatible type with the given element type and length.
Definition: LLVMTypes.cpp:953
Include the generated interface declarations.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...