MLIR 23.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
12#include "mlir/IR/MLIRContext.h"
13
14#include "llvm/ADT/TypeSwitch.h"
15#include "llvm/IR/DerivedTypes.h"
16#include "llvm/IR/Type.h"
17
18using namespace mlir;
19
20namespace mlir {
21namespace LLVM {
22namespace detail {
23/// Support for translating LLVM IR types to MLIR LLVM dialect types.
25public:
26 /// Constructs a class creating types in the given MLIR context.
28 bool importStructsAsLiterals)
29 : context(context), importStructsAsLiterals(importStructsAsLiterals) {}
30
31 /// Translates the given type.
32 Type translateType(llvm::Type *type) {
33 if (knownTranslations.count(type))
34 return knownTranslations.lookup(type);
35
36 Type translated =
38 .Case<llvm::ArrayType, llvm::FunctionType, llvm::IntegerType,
39 llvm::ByteType, llvm::PointerType, llvm::StructType,
40 llvm::FixedVectorType, llvm::ScalableVectorType,
41 llvm::TargetExtType>(
42 [this](auto *type) { return this->translate(type); })
43 .Default([this](llvm::Type *type) {
44 return translatePrimitiveType(type);
45 });
46 knownTranslations.try_emplace(type, translated);
47 return translated;
48 }
49
50private:
51 /// Translates the given primitive, i.e. non-parametric in MLIR nomenclature,
52 /// type.
53 Type translatePrimitiveType(llvm::Type *type) {
54 if (type->isVoidTy())
55 return LLVM::LLVMVoidType::get(&context);
56 if (type->isHalfTy())
57 return Float16Type::get(&context);
58 if (type->isBFloatTy())
59 return BFloat16Type::get(&context);
60 if (type->isFloatTy())
61 return Float32Type::get(&context);
62 if (type->isDoubleTy())
63 return Float64Type::get(&context);
64 if (type->isFP128Ty())
65 return Float128Type::get(&context);
66 if (type->isX86_FP80Ty())
67 return Float80Type::get(&context);
68 if (type->isX86_AMXTy())
69 return LLVM::LLVMX86AMXType::get(&context);
70 if (type->isPPC_FP128Ty())
71 return LLVM::LLVMPPCFP128Type::get(&context);
72 if (type->isLabelTy())
73 return LLVM::LLVMLabelType::get(&context);
74 if (type->isMetadataTy())
75 return LLVM::LLVMMetadataType::get(&context);
76 if (type->isTokenTy())
77 return TokenType::get(&context);
78 llvm_unreachable("not a primitive type");
79 }
80
81 /// Translates the given array type.
82 Type translate(llvm::ArrayType *type) {
83 return LLVM::LLVMArrayType::get(translateType(type->getElementType()),
84 type->getNumElements());
85 }
86
87 /// Translates the given function type.
88 Type translate(llvm::FunctionType *type) {
89 SmallVector<Type, 8> paramTypes;
90 translateTypes(type->params(), paramTypes);
91 return LLVM::LLVMFunctionType::get(translateType(type->getReturnType()),
92 paramTypes, type->isVarArg());
93 }
94
95 /// Translates the given integer type.
96 Type translate(llvm::IntegerType *type) {
97 return IntegerType::get(&context, type->getBitWidth());
98 }
99
100 /// Translates the given byte type.
101 Type translate(llvm::ByteType *type) {
102 return LLVM::LLVMByteType::get(&context, type->getBitWidth());
103 }
104
105 /// Translates the given pointer type.
106 Type translate(llvm::PointerType *type) {
107 return LLVM::LLVMPointerType::get(&context, type->getAddressSpace());
108 }
109
110 /// Translates the given structure type.
111 Type translate(llvm::StructType *type) {
112 SmallVector<Type, 8> subtypes;
113 if (type->isLiteral() || importStructsAsLiterals) {
114 translateTypes(type->subtypes(), subtypes);
115 return LLVM::LLVMStructType::getLiteral(&context, subtypes,
116 type->isPacked());
117 }
118
119 if (type->isOpaque())
120 return LLVM::LLVMStructType::getOpaque(type->getName(), &context);
121
122 // With opaque pointers, types in LLVM can't be recursive anymore. Note that
123 // using getIdentified is not possible, as type names in LLVM are not
124 // guaranteed to be unique.
125 translateTypes(type->subtypes(), subtypes);
126 LLVM::LLVMStructType translated = LLVM::LLVMStructType::getNewIdentified(
127 &context, type->getName(), subtypes, type->isPacked());
128 knownTranslations.try_emplace(type, translated);
129 return translated;
130 }
131
132 /// Translates the given fixed-vector type.
133 Type translate(llvm::FixedVectorType *type) {
134 return VectorType::get(type->getNumElements(),
135 translateType(type->getElementType()));
136 }
137
138 /// Translates the given scalable-vector type.
139 Type translate(llvm::ScalableVectorType *type) {
140 return VectorType::get(type->getMinNumElements(),
141 translateType(type->getElementType()),
142 /*scalableDims=*/true);
143 }
144
145 /// Translates the given target extension type.
146 Type translate(llvm::TargetExtType *type) {
147 SmallVector<Type> typeParams;
148 translateTypes(type->type_params(), typeParams);
149
150 return LLVM::LLVMTargetExtType::get(&context, type->getName(), typeParams,
151 type->int_params());
152 }
153
154 /// Translates a list of types.
155 void translateTypes(ArrayRef<llvm::Type *> types,
156 SmallVectorImpl<Type> &result) {
157 result.reserve(result.size() + types.size());
158 for (llvm::Type *type : types)
159 result.push_back(translateType(type));
160 }
161
162 /// Map of known translations. Serves as a cache and as recursion stopper for
163 /// translating recursive structs.
164 llvm::DenseMap<llvm::Type *, Type> knownTranslations;
165
166 /// The context in which MLIR types are created.
167 MLIRContext &context;
168
169 /// Controls if structs should be imported as literal structs, i.e., nameless
170 /// structs.
171 bool importStructsAsLiterals;
172};
173
174} // namespace detail
175} // namespace LLVM
176} // namespace mlir
177
179 MLIRContext &context, bool importStructsAsLiterals)
180 : impl(std::make_unique<detail::TypeFromLLVMIRTranslatorImpl>(
181 context, importStructsAsLiterals)) {}
182
184
186 return impl->translateType(type);
187}
TypeFromLLVMIRTranslator(MLIRContext &context, bool importStructsAsLiterals=false)
Type translateType(llvm::Type *type)
Translates the given LLVM IR type to the MLIR LLVM dialect.
Type translateType(llvm::Type *type)
Translates the given type.
TypeFromLLVMIRTranslatorImpl(MLIRContext &context, bool importStructsAsLiterals)
Constructs a class creating types in the given MLIR context.
MLIRContext is the top-level object for a collection of MLIR operations.
Definition MLIRContext.h:63
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition Types.h:74
Include the generated interface declarations.