MLIR  20.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::LLVMTokenType) {
62  return llvm::Type::getTokenTy(context);
63  })
64  .Case([this](LLVM::LLVMLabelType) {
65  return llvm::Type::getLabelTy(context);
66  })
67  .Case([this](LLVM::LLVMMetadataType) {
68  return llvm::Type::getMetadataTy(context);
69  })
70  .Case<LLVM::LLVMArrayType, IntegerType, LLVM::LLVMFunctionType,
71  LLVM::LLVMPointerType, LLVM::LLVMStructType,
72  LLVM::LLVMFixedVectorType, LLVM::LLVMScalableVectorType,
73  VectorType, LLVM::LLVMTargetExtType>(
74  [this](auto type) { return this->translate(type); })
75  .Default([](Type t) -> llvm::Type * {
76  llvm_unreachable("unknown LLVM dialect type");
77  });
78 
79  // Cache the result of the conversion and return.
80  knownTranslations.try_emplace(type, translated);
81  return translated;
82  }
83 
84 private:
85  /// Translates the given array type.
86  llvm::Type *translate(LLVM::LLVMArrayType type) {
87  return llvm::ArrayType::get(translateType(type.getElementType()),
88  type.getNumElements());
89  }
90 
91  /// Translates the given function type.
92  llvm::Type *translate(LLVM::LLVMFunctionType type) {
94  translateTypes(type.getParams(), paramTypes);
95  return llvm::FunctionType::get(translateType(type.getReturnType()),
96  paramTypes, type.isVarArg());
97  }
98 
99  /// Translates the given integer type.
100  llvm::Type *translate(IntegerType type) {
101  return llvm::IntegerType::get(context, type.getWidth());
102  }
103 
104  /// Translates the given pointer type.
105  llvm::Type *translate(LLVM::LLVMPointerType type) {
106  return llvm::PointerType::get(context, type.getAddressSpace());
107  }
108 
109  /// Translates the given structure type, supports both identified and literal
110  /// structs. This will _create_ a new identified structure every time, use
111  /// `convertType` if a structure with the same name must be looked up instead.
112  llvm::Type *translate(LLVM::LLVMStructType type) {
114  if (!type.isIdentified()) {
115  translateTypes(type.getBody(), subtypes);
116  return llvm::StructType::get(context, subtypes, type.isPacked());
117  }
118 
119  llvm::StructType *structType =
120  llvm::StructType::create(context, type.getName());
121  // Mark the type we just created as known so that recursive calls can pick
122  // it up and use directly.
123  knownTranslations.try_emplace(type, structType);
124  if (type.isOpaque())
125  return structType;
126 
127  translateTypes(type.getBody(), subtypes);
128  structType->setBody(subtypes, type.isPacked());
129  return structType;
130  }
131 
132  /// Translates the given built-in vector type compatible with LLVM.
133  llvm::Type *translate(VectorType type) {
134  assert(LLVM::isCompatibleVectorType(type) &&
135  "expected compatible with LLVM vector type");
136  if (type.isScalable())
137  return llvm::ScalableVectorType::get(translateType(type.getElementType()),
138  type.getNumElements());
139  return llvm::FixedVectorType::get(translateType(type.getElementType()),
140  type.getNumElements());
141  }
142 
143  /// Translates the given fixed-vector type.
144  llvm::Type *translate(LLVM::LLVMFixedVectorType type) {
145  return llvm::FixedVectorType::get(translateType(type.getElementType()),
146  type.getNumElements());
147  }
148 
149  /// Translates the given scalable-vector type.
150  llvm::Type *translate(LLVM::LLVMScalableVectorType type) {
151  return llvm::ScalableVectorType::get(translateType(type.getElementType()),
152  type.getMinNumElements());
153  }
154 
155  /// Translates the given target extension type.
156  llvm::Type *translate(LLVM::LLVMTargetExtType type) {
157  SmallVector<llvm::Type *> typeParams;
158  translateTypes(type.getTypeParams(), typeParams);
159  return llvm::TargetExtType::get(context, type.getExtTypeName(), typeParams,
160  type.getIntParams());
161  }
162 
163  /// Translates a list of types.
164  void translateTypes(ArrayRef<Type> types,
166  result.reserve(result.size() + types.size());
167  for (auto type : types)
168  result.push_back(translateType(type));
169  }
170 
171  /// Reference to the context in which the LLVM IR types are created.
172  llvm::LLVMContext &context;
173 
174  /// Map of known translation. This serves a double purpose: caches translation
175  /// results to avoid repeated recursive calls and makes sure identified
176  /// structs with the same name (that is, equal) are resolved to an existing
177  /// type instead of creating a new type.
178  llvm::DenseMap<Type, llvm::Type *> knownTranslations;
179 };
180 } // namespace detail
181 } // namespace LLVM
182 } // namespace mlir
183 
185  : impl(new detail::TypeToLLVMIRTranslatorImpl(context)) {}
186 
188 
190  return impl->translateType(type);
191 }
192 
194  Type type, const llvm::DataLayout &layout) {
195  return layout.getPrefTypeAlign(translateType(type)).value();
196 }
LLVM dialect structure type representing a collection of different-typed elements manipulated togethe...
Definition: LLVMTypes.h:108
StringRef getName()
Returns the name of an identified struct.
Definition: LLVMTypes.cpp:489
bool isPacked() const
Checks if a struct is packed.
Definition: LLVMTypes.cpp:482
ArrayRef< Type > getBody() const
Returns the list of element types contained in a non-opaque struct.
Definition: LLVMTypes.cpp:490
bool isOpaque()
Checks if a struct is opaque.
Definition: LLVMTypes.cpp:484
bool isIdentified() const
Checks if a struct is identified.
Definition: LLVMTypes.cpp:483
unsigned getPreferredAlignment(Type type, const llvm::DataLayout &layout)
Returns the preferred alignment for the type given the data layout.
Definition: TypeToLLVM.cpp:193
llvm::Type * translateType(Type type)
Translates the given MLIR LLVM dialect type to LLVM IR.
Definition: TypeToLLVM.cpp:189
TypeToLLVMIRTranslator(llvm::LLVMContext &context)
Definition: TypeToLLVM.cpp:184
Support for translating MLIR LLVM dialect types to LLVM IR.
Definition: TypeToLLVM.cpp:25
TypeToLLVMIRTranslatorImpl(llvm::LLVMContext &context)
Constructs a class creating types in the given LLVM context.
Definition: TypeToLLVM.cpp:28
llvm::Type * translateType(Type type)
Translates a single type.
Definition: TypeToLLVM.cpp:31
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:74
bool isCompatibleVectorType(Type type)
Returns true if the given type is a vector type compatible with the LLVM dialect.
Definition: LLVMTypes.cpp:874
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...