LLVM 24.0.0git
IRTypeMapper.cpp
Go to the documentation of this file.
1//===---- IRTypeMapper.cpp - Maps LLVM ABI Types to LLVM IR Types -------===//
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
10#include "llvm/ABI/Types.h"
11#include "llvm/ADT/APFloat.h"
13#include "llvm/IR/DataLayout.h"
15#include "llvm/IR/Type.h"
17
18using namespace llvm::abi;
19
21 assert(ABIType && "convertType requires a non-null ABI type");
22
23 auto It = TypeCache.find(ABIType);
24 if (It != TypeCache.end())
25 return It->second;
26
27 llvm::Type *Result = nullptr;
28
29 switch (ABIType->getKind()) {
31 Result = llvm::Type::getVoidTy(Context);
32 break;
34 Result = convertAtomicType(cast<abi::AtomicType>(ABIType));
35 break;
37 const auto *IT = cast<abi::IntegerType>(ABIType);
38 Result =
39 llvm::IntegerType::get(Context, IT->getSizeInBits().getFixedValue());
40 break;
41 }
43 const llvm::fltSemantics *Semantics =
44 cast<abi::FloatType>(ABIType)->getSemantics();
45 Result = llvm::Type::getFloatingPointTy(Context, *Semantics);
46 break;
47 }
49 // LLVM represents this format as a one-element i8 vector. The ABI
50 // type stays distinct so classification does not treat it as an
51 // integer or a short vector.
53 break;
56 Context, cast<abi::PointerType>(ABIType)->getAddrSpace());
57 break;
59 Result = convertArrayType(cast<abi::ArrayType>(ABIType));
60 break;
62 Result = convertVectorType(cast<abi::VectorType>(ABIType));
63 break;
65 Result = convertTupleType(cast<abi::TupleType>(ABIType));
66 break;
68 Result = convertRecordType(cast<abi::RecordType>(ABIType));
69 break;
71 Result = convertComplexType(cast<abi::ComplexType>(ABIType));
72 break;
74 Result = convertMemberPointerType(cast<abi::MemberPointerType>(ABIType));
75 break;
76 }
77
78 TypeCache[ABIType] = Result;
79 return Result;
80}
81
82llvm::Type *IRTypeMapper::convertAtomicType(const abi::AtomicType *AT) {
84 uint64_t ValueSize = AT->getValueType()->getSizeInBits().getFixedValue();
85 uint64_t AtomicSize = AT->getSizeInBits().getFixedValue();
86 if (ValueSize == AtomicSize)
87 return ValueType;
88
89 assert(ValueSize < AtomicSize && "atomic type cannot shrink its value type");
90 llvm::Type *Fields[] = {ValueType,
92 (AtomicSize - ValueSize) / 8)};
93 return llvm::StructType::get(Context, Fields, /*isPacked=*/false);
94}
95
96llvm::Type *IRTypeMapper::convertArrayType(const abi::ArrayType *AT) {
97 llvm::Type *ElementType = convertType(AT->getElementType());
98 uint64_t NumElements = AT->getNumElements();
99 if (AT->isMatrixType())
100 return llvm::VectorType::get(ElementType,
101 ElementCount::getFixed(NumElements));
102 return llvm::ArrayType::get(ElementType, NumElements);
103}
104
105llvm::Type *IRTypeMapper::convertVectorType(const abi::VectorType *VT) {
106 if (VT->isSVECount())
107 return llvm::TargetExtType::get(Context, "aarch64.svcount");
108
109 llvm::Type *ElementType = convertType(VT->getElementType());
110 return llvm::VectorType::get(ElementType, VT->getNumElements());
111}
112
113llvm::Type *IRTypeMapper::convertTupleType(const abi::TupleType *TT) {
114 llvm::Type *VecTy = convertType(TT->getVectorType());
115 SmallVector<llvm::Type *, 4> Elements(TT->getNumVectors(), VecTy);
116 return llvm::StructType::get(Context, Elements);
117}
118
119llvm::Type *IRTypeMapper::convertRecordType(const abi::RecordType *RT) {
120 // A packed record is a sequence of fields with no alignment padding. Pure
121 // scalable aggregates use one as the unpadded coerce-and-expand type, and
122 // its fields may be scalable vectors.
123 if (RT->getPacking() == StructPacking::Packed) {
124 SmallVector<llvm::Type *, 8> FieldTypes;
125 for (const FieldInfo &Field : RT->getFields())
126 FieldTypes.push_back(convertType(Field.FieldType));
127 return llvm::StructType::get(Context, FieldTypes, /*isPacked=*/true);
128 }
129 return createStructFromFields(RT->getFields(), RT->getSizeInBits(),
130 RT->getAlignment(), RT->isUnion());
131}
132
133llvm::Type *IRTypeMapper::convertComplexType(const abi::ComplexType *CT) {
134 llvm::Type *ElementType = convertType(CT->getElementType());
135 llvm::Type *Fields[] = {ElementType, ElementType};
136 return llvm::StructType::get(Context, Fields, /*isPacked=*/false);
137}
138
139llvm::Type *
140IRTypeMapper::convertMemberPointerType(const abi::MemberPointerType *MPT) {
141 llvm::Type *IntPtrTy = DL.getIntPtrType(Context);
142 if (MPT->isFunctionPointer()) {
143 llvm::Type *Fields[] = {IntPtrTy, IntPtrTy};
144 return llvm::StructType::get(Context, Fields, /*isPacked=*/false);
145 }
146 return IntPtrTy;
147}
148
149llvm::Type *IRTypeMapper::createPaddingType(uint64_t PaddingBits) {
150 if (PaddingBits == 0)
151 return nullptr;
152 assert(PaddingBits % 8 == 0 &&
153 "sub-byte padding cannot be expressed as an llvm::Type");
155 PaddingBits / 8);
156}
157
158llvm::StructType *
159IRTypeMapper::createStructFromFields(ArrayRef<abi::FieldInfo> Fields,
160 TypeSize Size, Align Alignment,
161 bool IsUnion) {
162 SmallVector<llvm::Type *, 16> FieldTypes;
163
164 if (IsUnion) {
165 llvm::Type *LargestFieldType = nullptr;
166 uint64_t LargestFieldSize = 0;
167 for (const auto &Field : Fields) {
168 llvm::Type *FieldType = convertType(Field.FieldType);
169 uint64_t FieldSize = Field.FieldType->getSizeInBits().getFixedValue();
170 if (FieldSize > LargestFieldSize) {
171 LargestFieldSize = FieldSize;
172 LargestFieldType = FieldType;
173 }
174 }
175 if (LargestFieldType) {
176 FieldTypes.push_back(LargestFieldType);
177 uint64_t UnionSizeBits = Size.getFixedValue();
178 if (LargestFieldSize < UnionSizeBits) {
179 if (llvm::Type *PaddingType =
180 createPaddingType(UnionSizeBits - LargestFieldSize))
181 FieldTypes.push_back(PaddingType);
182 }
183 }
184 } else {
185 uint64_t CurrentOffset = 0;
186 for (const auto &Field : Fields) {
187 assert(!Field.IsBitField && "bitfields should not reach IR type mapping");
188 llvm::Type *FieldType = convertType(Field.FieldType);
189 if (Field.OffsetInBits > CurrentOffset) {
190 uint64_t AlignBits = DL.getABITypeAlign(FieldType).value() * 8;
191 uint64_t NaturalNextOffset =
192 AlignBits ? alignTo(CurrentOffset, AlignBits) : CurrentOffset;
193 if (NaturalNextOffset != Field.OffsetInBits) {
194 if (llvm::Type *PaddingType =
195 createPaddingType(Field.OffsetInBits - CurrentOffset))
196 FieldTypes.push_back(PaddingType);
197 }
198 CurrentOffset = Field.OffsetInBits;
199 }
200 FieldTypes.push_back(FieldType);
201 CurrentOffset += Field.FieldType->getSizeInBits().getFixedValue();
202 }
203 uint64_t TotalSizeBits = Size.getFixedValue();
204 if (CurrentOffset < TotalSizeBits) {
205 if (llvm::Type *PaddingType =
206 createPaddingType(TotalSizeBits - CurrentOffset))
207 FieldTypes.push_back(PaddingType);
208 }
209 }
210
211 return StructType::get(Context, FieldTypes, /*isPacked=*/false);
212}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::values(clEnumValN(DefaultIT, "arm-default-it", "Generate any type of IT block"), clEnumValN(RestrictedIT, "arm-restrict-it", "Disallow complex IT blocks")))
Maps LLVM ABI type representations back to corresponding LLVM IR types.
OptimizedStructLayoutField Field
This file defines the SmallVector class.
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition TypeSize.h:306
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition Type.cpp:843
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition Type.cpp:338
static LLVM_ABI PointerType * get(LLVMContext &C, unsigned AddressSpace)
This constructs an opaque pointer to an object in a numbered address space.
Definition Type.cpp:887
void push_back(const T &Elt)
static LLVM_ABI StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Definition Type.cpp:467
static LLVM_ABI TargetExtType * get(LLVMContext &Context, StringRef Name, ArrayRef< Type * > Types={}, ArrayRef< unsigned > Ints={})
Return a target extension type having the specified name and optional type and integer parameters.
Definition Type.cpp:936
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
Definition Type.cpp:272
static LLVM_ABI Type * getFloatingPointTy(LLVMContext &C, const fltSemantics &S)
Definition Type.cpp:115
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Definition Type.cpp:297
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
const Type * getElementType() const
Definition Types.h:284
bool isMatrixType() const
Definition Types.h:286
uint64_t getNumElements() const
Definition Types.h:285
const Type * getValueType() const
Definition Types.h:140
const Type * getElementType() const
Definition Types.h:156
LLVM_ABI llvm::Type * convertType(const abi::Type *ABIType)
bool isFunctionPointer() const
Definition Types.h:263
bool isUnion() const
Definition Types.h:438
ArrayRef< FieldInfo > getFields() const
Definition Types.h:461
StructPacking getPacking() const
Definition Types.h:436
Represents the ABI-specific view of a type in LLVM.
Definition Types.h:48
TypeSize getSizeInBits() const
Definition Types.h:76
Align getAlignment() const
Definition Types.h:96
ElementCount getNumElements() const
Definition Types.h:340
const Type * getElementType() const
Definition Types.h:339
bool isSVECount() const
Definition Types.h:349
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:201
This file defines the type system for the LLVMABI library, which mirrors ABI-relevant aspects of fron...
@ IsUnion
Definition Types.h:411
ElementType
The element type of an SRV or UAV resource.
Definition DXILABI.h:68
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:149
IntPtrTy
Definition InstrProf.h:82
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
PointerUnion< const Value *, const PseudoSourceValue * > ValueType