MLIR  15.0.0git
TypeToLLVM.cpp
Go to the documentation of this file.
1 //===- TypeToLLVM.cpp - type translation from MLIR to LLVM 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 MLIR LLVM dialect types to LLVM IR.
26 public:
27  /// Constructs a class creating types in the given LLVM context.
28  TypeToLLVMIRTranslatorImpl(llvm::LLVMContext &context) : context(context) {}
29 
30  /// Translates a single type.
31  llvm::Type *translateType(Type type) {
32  // If the conversion is already known, just return it.
33  if (knownTranslations.count(type))
34  return knownTranslations.lookup(type);
35 
36  // Dispatch to an appropriate function.
37  llvm::Type *translated =
39  .Case([this](LLVM::LLVMVoidType) {
40  return llvm::Type::getVoidTy(context);
41  })
42  .Case(
43  [this](Float16Type) { return llvm::Type::getHalfTy(context); })
44  .Case([this](BFloat16Type) {
45  return llvm::Type::getBFloatTy(context);
46  })
47  .Case(
48  [this](Float32Type) { return llvm::Type::getFloatTy(context); })
49  .Case([this](Float64Type) {
50  return llvm::Type::getDoubleTy(context);
51  })
52  .Case([this](Float80Type) {
53  return llvm::Type::getX86_FP80Ty(context);
54  })
55  .Case([this](Float128Type) {
56  return llvm::Type::getFP128Ty(context);
57  })
58  .Case([this](LLVM::LLVMPPCFP128Type) {
59  return llvm::Type::getPPC_FP128Ty(context);
60  })
61  .Case([this](LLVM::LLVMX86MMXType) {
62  return llvm::Type::getX86_MMXTy(context);
63  })
64  .Case([this](LLVM::LLVMTokenType) {
65  return llvm::Type::getTokenTy(context);
66  })
67  .Case([this](LLVM::LLVMLabelType) {
68  return llvm::Type::getLabelTy(context);
69  })
70  .Case([this](LLVM::LLVMMetadataType) {
71  return llvm::Type::getMetadataTy(context);
72  })
73  .Case<LLVM::LLVMArrayType, IntegerType, LLVM::LLVMFunctionType,
76  VectorType>(
77  [this](auto type) { return this->translate(type); })
78  .Default([](Type t) -> llvm::Type * {
79  llvm_unreachable("unknown LLVM dialect type");
80  });
81 
82  // Cache the result of the conversion and return.
83  knownTranslations.try_emplace(type, translated);
84  return translated;
85  }
86 
87 private:
88  /// Translates the given array type.
89  llvm::Type *translate(LLVM::LLVMArrayType type) {
90  return llvm::ArrayType::get(translateType(type.getElementType()),
91  type.getNumElements());
92  }
93 
94  /// Translates the given function type.
95  llvm::Type *translate(LLVM::LLVMFunctionType type) {
97  translateTypes(type.getParams(), paramTypes);
98  return llvm::FunctionType::get(translateType(type.getReturnType()),
99  paramTypes, type.isVarArg());
100  }
101 
102  /// Translates the given integer type.
103  llvm::Type *translate(IntegerType type) {
104  return llvm::IntegerType::get(context, type.getWidth());
105  }
106 
107  /// Translates the given pointer type.
108  llvm::Type *translate(LLVM::LLVMPointerType type) {
109  if (type.isOpaque())
110  return llvm::PointerType::get(context, type.getAddressSpace());
111  return llvm::PointerType::get(translateType(type.getElementType()),
112  type.getAddressSpace());
113  }
114 
115  /// Translates the given structure type, supports both identified and literal
116  /// structs. This will _create_ a new identified structure every time, use
117  /// `convertType` if a structure with the same name must be looked up instead.
118  llvm::Type *translate(LLVM::LLVMStructType type) {
120  if (!type.isIdentified()) {
121  translateTypes(type.getBody(), subtypes);
122  return llvm::StructType::get(context, subtypes, type.isPacked());
123  }
124 
125  llvm::StructType *structType =
126  llvm::StructType::create(context, type.getName());
127  // Mark the type we just created as known so that recursive calls can pick
128  // it up and use directly.
129  knownTranslations.try_emplace(type, structType);
130  if (type.isOpaque())
131  return structType;
132 
133  translateTypes(type.getBody(), subtypes);
134  structType->setBody(subtypes, type.isPacked());
135  return structType;
136  }
137 
138  /// Translates the given built-in vector type compatible with LLVM.
139  llvm::Type *translate(VectorType type) {
140  assert(LLVM::isCompatibleVectorType(type) &&
141  "expected compatible with LLVM vector type");
142  if (type.isScalable())
143  return llvm::ScalableVectorType::get(translateType(type.getElementType()),
144  type.getNumElements());
145  return llvm::FixedVectorType::get(translateType(type.getElementType()),
146  type.getNumElements());
147  }
148 
149  /// Translates the given fixed-vector type.
150  llvm::Type *translate(LLVM::LLVMFixedVectorType type) {
151  return llvm::FixedVectorType::get(translateType(type.getElementType()),
152  type.getNumElements());
153  }
154 
155  /// Translates the given scalable-vector type.
156  llvm::Type *translate(LLVM::LLVMScalableVectorType type) {
157  return llvm::ScalableVectorType::get(translateType(type.getElementType()),
158  type.getMinNumElements());
159  }
160 
161  /// Translates a list of types.
162  void translateTypes(ArrayRef<Type> types,
164  result.reserve(result.size() + types.size());
165  for (auto type : types)
166  result.push_back(translateType(type));
167  }
168 
169  /// Reference to the context in which the LLVM IR types are created.
170  llvm::LLVMContext &context;
171 
172  /// Map of known translation. This serves a double purpose: caches translation
173  /// results to avoid repeated recursive calls and makes sure identified
174  /// structs with the same name (that is, equal) are resolved to an existing
175  /// type instead of creating a new type.
176  llvm::DenseMap<Type, llvm::Type *> knownTranslations;
177 };
178 } // namespace detail
179 } // namespace LLVM
180 } // namespace mlir
181 
183  : impl(new detail::TypeToLLVMIRTranslatorImpl(context)) {}
184 
186 
188  return impl->translateType(type);
189 }
190 
192  Type type, const llvm::DataLayout &layout) {
193  return layout.getPrefTypeAlignment(translateType(type));
194 }
TODO: Remove this file when SCCP and integer range analysis have been ported to the new framework...
LLVM dialect scalable vector type, represents a sequence of elements of unknown length that is known ...
Definition: LLVMTypes.h:428
unsigned getMinNumElements()
Returns the scaling factor of the number of elements in the vector.
Definition: LLVMTypes.cpp:699
StringRef getName()
Returns the name of an identified struct.
Definition: LLVMTypes.cpp:450
llvm::Type * translateType(Type type)
Translates a single type.
Definition: TypeToLLVM.cpp:31
TypeToLLVMIRTranslator(llvm::LLVMContext &context)
Definition: TypeToLLVM.cpp:182
Support for translating MLIR LLVM dialect types to LLVM IR.
Definition: TypeToLLVM.cpp:25
LLVM dialect function type.
Definition: LLVMTypes.h:128
bool isOpaque() const
Returns true if this type is the opaque pointer type, i.e., it has no pointed-to type.
Definition: LLVMTypes.cpp:208
unsigned getAddressSpace() const
Returns the address space of the pointer.
Definition: LLVMTypes.cpp:210
bool isOpaque()
Checks if a struct is opaque.
Definition: LLVMTypes.cpp:445
Type getElementType() const
Returns the element type of the vector.
Definition: LLVMTypes.cpp:695
bool isVarArg() const
Returns whether the function is variadic.
Definition: LLVMTypes.cpp:143
Type getElementType() const
Returns the element type of the array.
Definition: LLVMTypes.cpp:52
Type getElementType() const
Returns the element type of the vector.
Definition: LLVMTypes.cpp:652
unsigned getNumElements()
Returns the number of elements in the fixed vector.
Definition: LLVMTypes.cpp:656
ArrayRef< Type > getBody() const
Returns the list of element types contained in a non-opaque struct.
Definition: LLVMTypes.cpp:451
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:72
ArrayRef< Type > getParams() const
Returns a list of argument types of the function.
Definition: LLVMTypes.cpp:145
LLVM dialect array type.
Definition: LLVMTypes.h:75
unsigned getNumElements() const
Returns the number of elements in the array type.
Definition: LLVMTypes.cpp:54
bool isPacked() const
Checks if a struct is packed.
Definition: LLVMTypes.cpp:443
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
TypeToLLVMIRTranslatorImpl(llvm::LLVMContext &context)
Constructs a class creating types in the given LLVM context.
Definition: TypeToLLVM.cpp:28
bool isIdentified() const
Checks if a struct is identified.
Definition: LLVMTypes.cpp:444
LLVM dialect pointer type.
Definition: LLVMTypes.h:190
llvm::Type * translateType(Type type)
Translates the given MLIR LLVM dialect type to LLVM IR.
Definition: TypeToLLVM.cpp:187
Type getReturnType() const
Returns the result type of the function.
Definition: LLVMTypes.cpp:128
unsigned getPreferredAlignment(Type type, const llvm::DataLayout &layout)
Returns the preferred alignment for the type given the data layout.
Definition: TypeToLLVM.cpp:191
LLVM dialect fixed vector type, represents a sequence of elements of known length that can be process...
Definition: LLVMTypes.h:386
Type getElementType() const
Returns the pointed-to type. It may be null if the pointer is opaque.
Definition: LLVMTypes.cpp:206