10cd79488SEugene Zelenko //===- Type.cpp - Implement the Type class --------------------------------===//
2ef860a24SChandler Carruth //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ef860a24SChandler Carruth //
7ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
8ef860a24SChandler Carruth //
9ef860a24SChandler Carruth // This file implements the Type class for the IR library.
10ef860a24SChandler Carruth //
11ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
12ef860a24SChandler Carruth
136bda14b3SChandler Carruth #include "llvm/IR/Type.h"
14ef860a24SChandler Carruth #include "LLVMContextImpl.h"
150cd79488SEugene Zelenko #include "llvm/ADT/APInt.h"
160cd79488SEugene Zelenko #include "llvm/ADT/None.h"
17ef860a24SChandler Carruth #include "llvm/ADT/SmallString.h"
180cd79488SEugene Zelenko #include "llvm/ADT/StringMap.h"
190cd79488SEugene Zelenko #include "llvm/ADT/StringRef.h"
200cd79488SEugene Zelenko #include "llvm/IR/Constant.h"
210cd79488SEugene Zelenko #include "llvm/IR/Constants.h"
220cd79488SEugene Zelenko #include "llvm/IR/DerivedTypes.h"
230cd79488SEugene Zelenko #include "llvm/IR/LLVMContext.h"
240cd79488SEugene Zelenko #include "llvm/IR/Value.h"
250cd79488SEugene Zelenko #include "llvm/Support/Casting.h"
26b302561bSGraham Hunter #include "llvm/Support/TypeSize.h"
274c8174f5SArthur Eubanks #include "llvm/Support/raw_ostream.h"
280cd79488SEugene Zelenko #include <cassert>
290cd79488SEugene Zelenko #include <utility>
300cd79488SEugene Zelenko
31ef860a24SChandler Carruth using namespace llvm;
32ef860a24SChandler Carruth
33ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
34ef860a24SChandler Carruth // Type Class Implementation
35ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
36ef860a24SChandler Carruth
getPrimitiveType(LLVMContext & C,TypeID IDNumber)37ef860a24SChandler Carruth Type *Type::getPrimitiveType(LLVMContext &C, TypeID IDNumber) {
38ef860a24SChandler Carruth switch (IDNumber) {
39ef860a24SChandler Carruth case VoidTyID : return getVoidTy(C);
40ef860a24SChandler Carruth case HalfTyID : return getHalfTy(C);
418c24f331STies Stuij case BFloatTyID : return getBFloatTy(C);
42ef860a24SChandler Carruth case FloatTyID : return getFloatTy(C);
43ef860a24SChandler Carruth case DoubleTyID : return getDoubleTy(C);
44ef860a24SChandler Carruth case X86_FP80TyID : return getX86_FP80Ty(C);
45ef860a24SChandler Carruth case FP128TyID : return getFP128Ty(C);
46ef860a24SChandler Carruth case PPC_FP128TyID : return getPPC_FP128Ty(C);
47ef860a24SChandler Carruth case LabelTyID : return getLabelTy(C);
48ef860a24SChandler Carruth case MetadataTyID : return getMetadataTy(C);
49ef860a24SChandler Carruth case X86_MMXTyID : return getX86_MMXTy(C);
50981a0bd8SLuo, Yuanke case X86_AMXTyID : return getX86_AMXTy(C);
51b611e3f5SDavid Majnemer case TokenTyID : return getTokenTy(C);
52ef860a24SChandler Carruth default:
53c620761cSCraig Topper return nullptr;
54ef860a24SChandler Carruth }
55ef860a24SChandler Carruth }
56ef860a24SChandler Carruth
isIntegerTy(unsigned Bitwidth) const57ef860a24SChandler Carruth bool Type::isIntegerTy(unsigned Bitwidth) const {
58ef860a24SChandler Carruth return isIntegerTy() && cast<IntegerType>(this)->getBitWidth() == Bitwidth;
59ef860a24SChandler Carruth }
60ef860a24SChandler Carruth
isOpaquePointerTy() const61ad4bb828SNikita Popov bool Type::isOpaquePointerTy() const {
62ad4bb828SNikita Popov if (auto *PTy = dyn_cast<PointerType>(this))
63ad4bb828SNikita Popov return PTy->isOpaque();
64ad4bb828SNikita Popov return false;
65ad4bb828SNikita Popov }
66ad4bb828SNikita Popov
getFltSemantics() const67a94002cdSNikita Popov const fltSemantics &Type::getFltSemantics() const {
68a94002cdSNikita Popov switch (getTypeID()) {
69a94002cdSNikita Popov case HalfTyID: return APFloat::IEEEhalf();
70a94002cdSNikita Popov case BFloatTyID: return APFloat::BFloat();
71a94002cdSNikita Popov case FloatTyID: return APFloat::IEEEsingle();
72a94002cdSNikita Popov case DoubleTyID: return APFloat::IEEEdouble();
73a94002cdSNikita Popov case X86_FP80TyID: return APFloat::x87DoubleExtended();
74a94002cdSNikita Popov case FP128TyID: return APFloat::IEEEquad();
75a94002cdSNikita Popov case PPC_FP128TyID: return APFloat::PPCDoubleDouble();
76a94002cdSNikita Popov default: llvm_unreachable("Invalid floating type");
77a94002cdSNikita Popov }
78a94002cdSNikita Popov }
79a94002cdSNikita Popov
isIEEE() const80a94002cdSNikita Popov bool Type::isIEEE() const {
81a94002cdSNikita Popov return APFloat::getZero(getFltSemantics()).isIEEE();
82a94002cdSNikita Popov }
83a94002cdSNikita Popov
getFloatingPointTy(LLVMContext & C,const fltSemantics & S)84a94002cdSNikita Popov Type *Type::getFloatingPointTy(LLVMContext &C, const fltSemantics &S) {
85a94002cdSNikita Popov Type *Ty;
86a94002cdSNikita Popov if (&S == &APFloat::IEEEhalf())
87a94002cdSNikita Popov Ty = Type::getHalfTy(C);
88a94002cdSNikita Popov else if (&S == &APFloat::BFloat())
89a94002cdSNikita Popov Ty = Type::getBFloatTy(C);
90a94002cdSNikita Popov else if (&S == &APFloat::IEEEsingle())
91a94002cdSNikita Popov Ty = Type::getFloatTy(C);
92a94002cdSNikita Popov else if (&S == &APFloat::IEEEdouble())
93a94002cdSNikita Popov Ty = Type::getDoubleTy(C);
94a94002cdSNikita Popov else if (&S == &APFloat::x87DoubleExtended())
95a94002cdSNikita Popov Ty = Type::getX86_FP80Ty(C);
96a94002cdSNikita Popov else if (&S == &APFloat::IEEEquad())
97a94002cdSNikita Popov Ty = Type::getFP128Ty(C);
98a94002cdSNikita Popov else {
99a94002cdSNikita Popov assert(&S == &APFloat::PPCDoubleDouble() && "Unknown FP format");
100a94002cdSNikita Popov Ty = Type::getPPC_FP128Ty(C);
101a94002cdSNikita Popov }
102a94002cdSNikita Popov return Ty;
103a94002cdSNikita Popov }
104a94002cdSNikita Popov
canLosslesslyBitCastTo(Type * Ty) const105ef860a24SChandler Carruth bool Type::canLosslesslyBitCastTo(Type *Ty) const {
106ef860a24SChandler Carruth // Identity cast means no change so return true
107ef860a24SChandler Carruth if (this == Ty)
108ef860a24SChandler Carruth return true;
109ef860a24SChandler Carruth
110ef860a24SChandler Carruth // They are not convertible unless they are at least first class types
111ef860a24SChandler Carruth if (!this->isFirstClassType() || !Ty->isFirstClassType())
112ef860a24SChandler Carruth return false;
113ef860a24SChandler Carruth
114ef860a24SChandler Carruth // Vector -> Vector conversions are always lossless if the two vector types
1158bec33c0SChristopher Tetreault // have the same size, otherwise not.
1168bec33c0SChristopher Tetreault if (isa<VectorType>(this) && isa<VectorType>(Ty))
1178bec33c0SChristopher Tetreault return getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits();
118ef860a24SChandler Carruth
1198bec33c0SChristopher Tetreault // 64-bit fixed width vector types can be losslessly converted to x86mmx.
1202dea3f12SChristopher Tetreault if (((isa<FixedVectorType>(this)) && Ty->isX86_MMXTy()) &&
1218bec33c0SChristopher Tetreault getPrimitiveSizeInBits().getFixedSize() == 64)
1228bec33c0SChristopher Tetreault return true;
1232dea3f12SChristopher Tetreault if ((isX86_MMXTy() && isa<FixedVectorType>(Ty)) &&
1248bec33c0SChristopher Tetreault Ty->getPrimitiveSizeInBits().getFixedSize() == 64)
125ef860a24SChandler Carruth return true;
126ef860a24SChandler Carruth
127981a0bd8SLuo, Yuanke // 8192-bit fixed width vector types can be losslessly converted to x86amx.
128981a0bd8SLuo, Yuanke if (((isa<FixedVectorType>(this)) && Ty->isX86_AMXTy()) &&
129981a0bd8SLuo, Yuanke getPrimitiveSizeInBits().getFixedSize() == 8192)
130981a0bd8SLuo, Yuanke return true;
131981a0bd8SLuo, Yuanke if ((isX86_AMXTy() && isa<FixedVectorType>(Ty)) &&
132981a0bd8SLuo, Yuanke Ty->getPrimitiveSizeInBits().getFixedSize() == 8192)
133981a0bd8SLuo, Yuanke return true;
134981a0bd8SLuo, Yuanke
135ef860a24SChandler Carruth // At this point we have only various mismatches of the first class types
136ef860a24SChandler Carruth // remaining and ptr->ptr. Just select the lossless conversions. Everything
137a8efaf96SMatt Arsenault // else is not lossless. Conservatively assume we can't losslessly convert
138a8efaf96SMatt Arsenault // between pointers with different address spaces.
139e3dcce97SCraig Topper if (auto *PTy = dyn_cast<PointerType>(this)) {
140bcdaccfeSLuo, Yuanke if (auto *OtherPTy = dyn_cast<PointerType>(Ty))
141a8efaf96SMatt Arsenault return PTy->getAddressSpace() == OtherPTy->getAddressSpace();
142a8efaf96SMatt Arsenault return false;
143a8efaf96SMatt Arsenault }
144ef860a24SChandler Carruth return false; // Other types have no identity values
145ef860a24SChandler Carruth }
146ef860a24SChandler Carruth
isEmptyTy() const147ef860a24SChandler Carruth bool Type::isEmptyTy() const {
148e3dcce97SCraig Topper if (auto *ATy = dyn_cast<ArrayType>(this)) {
149ef860a24SChandler Carruth unsigned NumElements = ATy->getNumElements();
150ef860a24SChandler Carruth return NumElements == 0 || ATy->getElementType()->isEmptyTy();
151ef860a24SChandler Carruth }
152ef860a24SChandler Carruth
153e3dcce97SCraig Topper if (auto *STy = dyn_cast<StructType>(this)) {
154ef860a24SChandler Carruth unsigned NumElements = STy->getNumElements();
155ef860a24SChandler Carruth for (unsigned i = 0; i < NumElements; ++i)
156ef860a24SChandler Carruth if (!STy->getElementType(i)->isEmptyTy())
157ef860a24SChandler Carruth return false;
158ef860a24SChandler Carruth return true;
159ef860a24SChandler Carruth }
160ef860a24SChandler Carruth
161ef860a24SChandler Carruth return false;
162ef860a24SChandler Carruth }
163ef860a24SChandler Carruth
getPrimitiveSizeInBits() const164b302561bSGraham Hunter TypeSize Type::getPrimitiveSizeInBits() const {
165ef860a24SChandler Carruth switch (getTypeID()) {
166b302561bSGraham Hunter case Type::HalfTyID: return TypeSize::Fixed(16);
1678c24f331STies Stuij case Type::BFloatTyID: return TypeSize::Fixed(16);
168b302561bSGraham Hunter case Type::FloatTyID: return TypeSize::Fixed(32);
169b302561bSGraham Hunter case Type::DoubleTyID: return TypeSize::Fixed(64);
170b302561bSGraham Hunter case Type::X86_FP80TyID: return TypeSize::Fixed(80);
171b302561bSGraham Hunter case Type::FP128TyID: return TypeSize::Fixed(128);
172b302561bSGraham Hunter case Type::PPC_FP128TyID: return TypeSize::Fixed(128);
173b302561bSGraham Hunter case Type::X86_MMXTyID: return TypeSize::Fixed(64);
174981a0bd8SLuo, Yuanke case Type::X86_AMXTyID: return TypeSize::Fixed(8192);
175b302561bSGraham Hunter case Type::IntegerTyID:
176b302561bSGraham Hunter return TypeSize::Fixed(cast<IntegerType>(this)->getBitWidth());
1772dea3f12SChristopher Tetreault case Type::FixedVectorTyID:
1782dea3f12SChristopher Tetreault case Type::ScalableVectorTyID: {
179b302561bSGraham Hunter const VectorType *VTy = cast<VectorType>(this);
1808bec33c0SChristopher Tetreault ElementCount EC = VTy->getElementCount();
1818bec33c0SChristopher Tetreault TypeSize ETS = VTy->getElementType()->getPrimitiveSizeInBits();
1828bec33c0SChristopher Tetreault assert(!ETS.isScalable() && "Vector type should have fixed-width elements");
183f4257c58SDavid Sherwood return {ETS.getFixedSize() * EC.getKnownMinValue(), EC.isScalable()};
184b302561bSGraham Hunter }
185b302561bSGraham Hunter default: return TypeSize::Fixed(0);
186ef860a24SChandler Carruth }
187ef860a24SChandler Carruth }
188ef860a24SChandler Carruth
getScalarSizeInBits() const1898c4ac147SCraig Topper unsigned Type::getScalarSizeInBits() const {
1904b3d9405SFrancesco Petrogalli // It is safe to assume that the scalar types have a fixed size.
1914b3d9405SFrancesco Petrogalli return getScalarType()->getPrimitiveSizeInBits().getFixedSize();
192ef860a24SChandler Carruth }
193ef860a24SChandler Carruth
getFPMantissaWidth() const194ef860a24SChandler Carruth int Type::getFPMantissaWidth() const {
195e3dcce97SCraig Topper if (auto *VTy = dyn_cast<VectorType>(this))
196ef860a24SChandler Carruth return VTy->getElementType()->getFPMantissaWidth();
197ef860a24SChandler Carruth assert(isFloatingPointTy() && "Not a floating point type!");
198ef860a24SChandler Carruth if (getTypeID() == HalfTyID) return 11;
1998c24f331STies Stuij if (getTypeID() == BFloatTyID) return 8;
200ef860a24SChandler Carruth if (getTypeID() == FloatTyID) return 24;
201ef860a24SChandler Carruth if (getTypeID() == DoubleTyID) return 53;
202ef860a24SChandler Carruth if (getTypeID() == X86_FP80TyID) return 64;
203ef860a24SChandler Carruth if (getTypeID() == FP128TyID) return 113;
204ef860a24SChandler Carruth assert(getTypeID() == PPC_FP128TyID && "unknown fp type");
205ef860a24SChandler Carruth return -1;
206ef860a24SChandler Carruth }
207ef860a24SChandler Carruth
isSizedDerivedType(SmallPtrSetImpl<Type * > * Visited) const208e3dcce97SCraig Topper bool Type::isSizedDerivedType(SmallPtrSetImpl<Type*> *Visited) const {
209e3dcce97SCraig Topper if (auto *ATy = dyn_cast<ArrayType>(this))
2104e865607SKaelyn Uhrain return ATy->getElementType()->isSized(Visited);
211ef860a24SChandler Carruth
212e3dcce97SCraig Topper if (auto *VTy = dyn_cast<VectorType>(this))
2134e865607SKaelyn Uhrain return VTy->getElementType()->isSized(Visited);
214ef860a24SChandler Carruth
2154e865607SKaelyn Uhrain return cast<StructType>(this)->isSized(Visited);
216ef860a24SChandler Carruth }
217ef860a24SChandler Carruth
218ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
219ef860a24SChandler Carruth // Primitive 'Type' data
220ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
221ef860a24SChandler Carruth
getVoidTy(LLVMContext & C)222ef860a24SChandler Carruth Type *Type::getVoidTy(LLVMContext &C) { return &C.pImpl->VoidTy; }
getLabelTy(LLVMContext & C)223ef860a24SChandler Carruth Type *Type::getLabelTy(LLVMContext &C) { return &C.pImpl->LabelTy; }
getHalfTy(LLVMContext & C)224ef860a24SChandler Carruth Type *Type::getHalfTy(LLVMContext &C) { return &C.pImpl->HalfTy; }
getBFloatTy(LLVMContext & C)2258c24f331STies Stuij Type *Type::getBFloatTy(LLVMContext &C) { return &C.pImpl->BFloatTy; }
getFloatTy(LLVMContext & C)226ef860a24SChandler Carruth Type *Type::getFloatTy(LLVMContext &C) { return &C.pImpl->FloatTy; }
getDoubleTy(LLVMContext & C)227ef860a24SChandler Carruth Type *Type::getDoubleTy(LLVMContext &C) { return &C.pImpl->DoubleTy; }
getMetadataTy(LLVMContext & C)228ef860a24SChandler Carruth Type *Type::getMetadataTy(LLVMContext &C) { return &C.pImpl->MetadataTy; }
getTokenTy(LLVMContext & C)229b611e3f5SDavid Majnemer Type *Type::getTokenTy(LLVMContext &C) { return &C.pImpl->TokenTy; }
getX86_FP80Ty(LLVMContext & C)230ef860a24SChandler Carruth Type *Type::getX86_FP80Ty(LLVMContext &C) { return &C.pImpl->X86_FP80Ty; }
getFP128Ty(LLVMContext & C)231ef860a24SChandler Carruth Type *Type::getFP128Ty(LLVMContext &C) { return &C.pImpl->FP128Ty; }
getPPC_FP128Ty(LLVMContext & C)232ef860a24SChandler Carruth Type *Type::getPPC_FP128Ty(LLVMContext &C) { return &C.pImpl->PPC_FP128Ty; }
getX86_MMXTy(LLVMContext & C)233ef860a24SChandler Carruth Type *Type::getX86_MMXTy(LLVMContext &C) { return &C.pImpl->X86_MMXTy; }
getX86_AMXTy(LLVMContext & C)234981a0bd8SLuo, Yuanke Type *Type::getX86_AMXTy(LLVMContext &C) { return &C.pImpl->X86_AMXTy; }
235ef860a24SChandler Carruth
getInt1Ty(LLVMContext & C)236ef860a24SChandler Carruth IntegerType *Type::getInt1Ty(LLVMContext &C) { return &C.pImpl->Int1Ty; }
getInt8Ty(LLVMContext & C)237ef860a24SChandler Carruth IntegerType *Type::getInt8Ty(LLVMContext &C) { return &C.pImpl->Int8Ty; }
getInt16Ty(LLVMContext & C)238ef860a24SChandler Carruth IntegerType *Type::getInt16Ty(LLVMContext &C) { return &C.pImpl->Int16Ty; }
getInt32Ty(LLVMContext & C)239ef860a24SChandler Carruth IntegerType *Type::getInt32Ty(LLVMContext &C) { return &C.pImpl->Int32Ty; }
getInt64Ty(LLVMContext & C)240ef860a24SChandler Carruth IntegerType *Type::getInt64Ty(LLVMContext &C) { return &C.pImpl->Int64Ty; }
getInt128Ty(LLVMContext & C)24172918025SKit Barton IntegerType *Type::getInt128Ty(LLVMContext &C) { return &C.pImpl->Int128Ty; }
242ef860a24SChandler Carruth
getIntNTy(LLVMContext & C,unsigned N)243ef860a24SChandler Carruth IntegerType *Type::getIntNTy(LLVMContext &C, unsigned N) {
244ef860a24SChandler Carruth return IntegerType::get(C, N);
245ef860a24SChandler Carruth }
246ef860a24SChandler Carruth
getHalfPtrTy(LLVMContext & C,unsigned AS)247ef860a24SChandler Carruth PointerType *Type::getHalfPtrTy(LLVMContext &C, unsigned AS) {
248ef860a24SChandler Carruth return getHalfTy(C)->getPointerTo(AS);
249ef860a24SChandler Carruth }
250ef860a24SChandler Carruth
getBFloatPtrTy(LLVMContext & C,unsigned AS)2518c24f331STies Stuij PointerType *Type::getBFloatPtrTy(LLVMContext &C, unsigned AS) {
2528c24f331STies Stuij return getBFloatTy(C)->getPointerTo(AS);
2538c24f331STies Stuij }
2548c24f331STies Stuij
getFloatPtrTy(LLVMContext & C,unsigned AS)255ef860a24SChandler Carruth PointerType *Type::getFloatPtrTy(LLVMContext &C, unsigned AS) {
256ef860a24SChandler Carruth return getFloatTy(C)->getPointerTo(AS);
257ef860a24SChandler Carruth }
258ef860a24SChandler Carruth
getDoublePtrTy(LLVMContext & C,unsigned AS)259ef860a24SChandler Carruth PointerType *Type::getDoublePtrTy(LLVMContext &C, unsigned AS) {
260ef860a24SChandler Carruth return getDoubleTy(C)->getPointerTo(AS);
261ef860a24SChandler Carruth }
262ef860a24SChandler Carruth
getX86_FP80PtrTy(LLVMContext & C,unsigned AS)263ef860a24SChandler Carruth PointerType *Type::getX86_FP80PtrTy(LLVMContext &C, unsigned AS) {
264ef860a24SChandler Carruth return getX86_FP80Ty(C)->getPointerTo(AS);
265ef860a24SChandler Carruth }
266ef860a24SChandler Carruth
getFP128PtrTy(LLVMContext & C,unsigned AS)267ef860a24SChandler Carruth PointerType *Type::getFP128PtrTy(LLVMContext &C, unsigned AS) {
268ef860a24SChandler Carruth return getFP128Ty(C)->getPointerTo(AS);
269ef860a24SChandler Carruth }
270ef860a24SChandler Carruth
getPPC_FP128PtrTy(LLVMContext & C,unsigned AS)271ef860a24SChandler Carruth PointerType *Type::getPPC_FP128PtrTy(LLVMContext &C, unsigned AS) {
272ef860a24SChandler Carruth return getPPC_FP128Ty(C)->getPointerTo(AS);
273ef860a24SChandler Carruth }
274ef860a24SChandler Carruth
getX86_MMXPtrTy(LLVMContext & C,unsigned AS)275ef860a24SChandler Carruth PointerType *Type::getX86_MMXPtrTy(LLVMContext &C, unsigned AS) {
276ef860a24SChandler Carruth return getX86_MMXTy(C)->getPointerTo(AS);
277ef860a24SChandler Carruth }
278ef860a24SChandler Carruth
getX86_AMXPtrTy(LLVMContext & C,unsigned AS)279981a0bd8SLuo, Yuanke PointerType *Type::getX86_AMXPtrTy(LLVMContext &C, unsigned AS) {
280981a0bd8SLuo, Yuanke return getX86_AMXTy(C)->getPointerTo(AS);
281981a0bd8SLuo, Yuanke }
282981a0bd8SLuo, Yuanke
getIntNPtrTy(LLVMContext & C,unsigned N,unsigned AS)283ef860a24SChandler Carruth PointerType *Type::getIntNPtrTy(LLVMContext &C, unsigned N, unsigned AS) {
284ef860a24SChandler Carruth return getIntNTy(C, N)->getPointerTo(AS);
285ef860a24SChandler Carruth }
286ef860a24SChandler Carruth
getInt1PtrTy(LLVMContext & C,unsigned AS)287ef860a24SChandler Carruth PointerType *Type::getInt1PtrTy(LLVMContext &C, unsigned AS) {
288ef860a24SChandler Carruth return getInt1Ty(C)->getPointerTo(AS);
289ef860a24SChandler Carruth }
290ef860a24SChandler Carruth
getInt8PtrTy(LLVMContext & C,unsigned AS)291ef860a24SChandler Carruth PointerType *Type::getInt8PtrTy(LLVMContext &C, unsigned AS) {
292ef860a24SChandler Carruth return getInt8Ty(C)->getPointerTo(AS);
293ef860a24SChandler Carruth }
294ef860a24SChandler Carruth
getInt16PtrTy(LLVMContext & C,unsigned AS)295ef860a24SChandler Carruth PointerType *Type::getInt16PtrTy(LLVMContext &C, unsigned AS) {
296ef860a24SChandler Carruth return getInt16Ty(C)->getPointerTo(AS);
297ef860a24SChandler Carruth }
298ef860a24SChandler Carruth
getInt32PtrTy(LLVMContext & C,unsigned AS)299ef860a24SChandler Carruth PointerType *Type::getInt32PtrTy(LLVMContext &C, unsigned AS) {
300ef860a24SChandler Carruth return getInt32Ty(C)->getPointerTo(AS);
301ef860a24SChandler Carruth }
302ef860a24SChandler Carruth
getInt64PtrTy(LLVMContext & C,unsigned AS)303ef860a24SChandler Carruth PointerType *Type::getInt64PtrTy(LLVMContext &C, unsigned AS) {
304ef860a24SChandler Carruth return getInt64Ty(C)->getPointerTo(AS);
305ef860a24SChandler Carruth }
306ef860a24SChandler Carruth
307ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
308ef860a24SChandler Carruth // IntegerType Implementation
309ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
310ef860a24SChandler Carruth
get(LLVMContext & C,unsigned NumBits)311ef860a24SChandler Carruth IntegerType *IntegerType::get(LLVMContext &C, unsigned NumBits) {
312ef860a24SChandler Carruth assert(NumBits >= MIN_INT_BITS && "bitwidth too small");
313ef860a24SChandler Carruth assert(NumBits <= MAX_INT_BITS && "bitwidth too large");
314ef860a24SChandler Carruth
315ef860a24SChandler Carruth // Check for the built-in integer types
316ef860a24SChandler Carruth switch (NumBits) {
317ef860a24SChandler Carruth case 1: return cast<IntegerType>(Type::getInt1Ty(C));
318ef860a24SChandler Carruth case 8: return cast<IntegerType>(Type::getInt8Ty(C));
319ef860a24SChandler Carruth case 16: return cast<IntegerType>(Type::getInt16Ty(C));
320ef860a24SChandler Carruth case 32: return cast<IntegerType>(Type::getInt32Ty(C));
321ef860a24SChandler Carruth case 64: return cast<IntegerType>(Type::getInt64Ty(C));
3222f417576SNick Lewycky case 128: return cast<IntegerType>(Type::getInt128Ty(C));
323ef860a24SChandler Carruth default:
324ef860a24SChandler Carruth break;
325ef860a24SChandler Carruth }
326ef860a24SChandler Carruth
327ef860a24SChandler Carruth IntegerType *&Entry = C.pImpl->IntegerTypes[NumBits];
328ef860a24SChandler Carruth
329c620761cSCraig Topper if (!Entry)
33010c548cdSPeter Collingbourne Entry = new (C.pImpl->Alloc) IntegerType(C, NumBits);
331ef860a24SChandler Carruth
332ef860a24SChandler Carruth return Entry;
333ef860a24SChandler Carruth }
334ef860a24SChandler Carruth
getMask() const335735f4671SChris Lattner APInt IntegerType::getMask() const { return APInt::getAllOnes(getBitWidth()); }
336ef860a24SChandler Carruth
337ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
338ef860a24SChandler Carruth // FunctionType Implementation
339ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
340ef860a24SChandler Carruth
FunctionType(Type * Result,ArrayRef<Type * > Params,bool IsVarArgs)341ef860a24SChandler Carruth FunctionType::FunctionType(Type *Result, ArrayRef<Type*> Params,
342ef860a24SChandler Carruth bool IsVarArgs)
343ef860a24SChandler Carruth : Type(Result->getContext(), FunctionTyID) {
344ef860a24SChandler Carruth Type **SubTys = reinterpret_cast<Type**>(this+1);
345ef860a24SChandler Carruth assert(isValidReturnType(Result) && "invalid return type for function");
346ef860a24SChandler Carruth setSubclassData(IsVarArgs);
347ef860a24SChandler Carruth
3487554da2cSCraig Topper SubTys[0] = Result;
349ef860a24SChandler Carruth
350ef860a24SChandler Carruth for (unsigned i = 0, e = Params.size(); i != e; ++i) {
351ef860a24SChandler Carruth assert(isValidArgumentType(Params[i]) &&
352ef860a24SChandler Carruth "Not a valid type for function argument!");
353ef860a24SChandler Carruth SubTys[i+1] = Params[i];
354ef860a24SChandler Carruth }
355ef860a24SChandler Carruth
356ef860a24SChandler Carruth ContainedTys = SubTys;
357ef860a24SChandler Carruth NumContainedTys = Params.size() + 1; // + 1 for result type
358ef860a24SChandler Carruth }
359ef860a24SChandler Carruth
360bc78cdc4SSanjay Patel // This is the factory function for the FunctionType class.
get(Type * ReturnType,ArrayRef<Type * > Params,bool isVarArg)361ef860a24SChandler Carruth FunctionType *FunctionType::get(Type *ReturnType,
362ef860a24SChandler Carruth ArrayRef<Type*> Params, bool isVarArg) {
363ef860a24SChandler Carruth LLVMContextImpl *pImpl = ReturnType->getContext().pImpl;
36409ea2049SKrasimir Georgiev const FunctionTypeKeyInfo::KeyTy Key(ReturnType, Params, isVarArg);
365ef860a24SChandler Carruth FunctionType *FT;
36609ea2049SKrasimir Georgiev // Since we only want to allocate a fresh function type in case none is found
36709ea2049SKrasimir Georgiev // and we don't want to perform two lookups (one for checking if existent and
36809ea2049SKrasimir Georgiev // one for inserting the newly allocated one), here we instead lookup based on
36909ea2049SKrasimir Georgiev // Key and update the reference to the function type in-place to a newly
37009ea2049SKrasimir Georgiev // allocated one if not found.
37109ea2049SKrasimir Georgiev auto Insertion = pImpl->FunctionTypes.insert_as(nullptr, Key);
37209ea2049SKrasimir Georgiev if (Insertion.second) {
37309ea2049SKrasimir Georgiev // The function type was not found. Allocate one and update FunctionTypes
37409ea2049SKrasimir Georgiev // in-place.
37510c548cdSPeter Collingbourne FT = (FunctionType *)pImpl->Alloc.Allocate(
376b2505005SBenjamin Kramer sizeof(FunctionType) + sizeof(Type *) * (Params.size() + 1),
377b2505005SBenjamin Kramer alignof(FunctionType));
378ef860a24SChandler Carruth new (FT) FunctionType(ReturnType, Params, isVarArg);
37909ea2049SKrasimir Georgiev *Insertion.first = FT;
380ef860a24SChandler Carruth } else {
38109ea2049SKrasimir Georgiev // The function type was found. Just return it.
38209ea2049SKrasimir Georgiev FT = *Insertion.first;
383ef860a24SChandler Carruth }
384ef860a24SChandler Carruth return FT;
385ef860a24SChandler Carruth }
386ef860a24SChandler Carruth
get(Type * Result,bool isVarArg)387ef860a24SChandler Carruth FunctionType *FunctionType::get(Type *Result, bool isVarArg) {
3883238fb75SDmitri Gribenko return get(Result, None, isVarArg);
389ef860a24SChandler Carruth }
390ef860a24SChandler Carruth
isValidReturnType(Type * RetTy)391ef860a24SChandler Carruth bool FunctionType::isValidReturnType(Type *RetTy) {
392ef860a24SChandler Carruth return !RetTy->isFunctionTy() && !RetTy->isLabelTy() &&
393ef860a24SChandler Carruth !RetTy->isMetadataTy();
394ef860a24SChandler Carruth }
395ef860a24SChandler Carruth
isValidArgumentType(Type * ArgTy)396ef860a24SChandler Carruth bool FunctionType::isValidArgumentType(Type *ArgTy) {
397ef860a24SChandler Carruth return ArgTy->isFirstClassType();
398ef860a24SChandler Carruth }
399ef860a24SChandler Carruth
400ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
401ef860a24SChandler Carruth // StructType Implementation
402ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
403ef860a24SChandler Carruth
404ef860a24SChandler Carruth // Primitive Constructors.
405ef860a24SChandler Carruth
get(LLVMContext & Context,ArrayRef<Type * > ETypes,bool isPacked)406ef860a24SChandler Carruth StructType *StructType::get(LLVMContext &Context, ArrayRef<Type*> ETypes,
407ef860a24SChandler Carruth bool isPacked) {
408ef860a24SChandler Carruth LLVMContextImpl *pImpl = Context.pImpl;
409142919bcSKrasimir Georgiev const AnonStructTypeKeyInfo::KeyTy Key(ETypes, isPacked);
410ef860a24SChandler Carruth
411142919bcSKrasimir Georgiev StructType *ST;
412142919bcSKrasimir Georgiev // Since we only want to allocate a fresh struct type in case none is found
413142919bcSKrasimir Georgiev // and we don't want to perform two lookups (one for checking if existent and
414142919bcSKrasimir Georgiev // one for inserting the newly allocated one), here we instead lookup based on
415142919bcSKrasimir Georgiev // Key and update the reference to the struct type in-place to a newly
416142919bcSKrasimir Georgiev // allocated one if not found.
417142919bcSKrasimir Georgiev auto Insertion = pImpl->AnonStructTypes.insert_as(nullptr, Key);
418142919bcSKrasimir Georgiev if (Insertion.second) {
419142919bcSKrasimir Georgiev // The struct type was not found. Allocate one and update AnonStructTypes
420142919bcSKrasimir Georgiev // in-place.
42110c548cdSPeter Collingbourne ST = new (Context.pImpl->Alloc) StructType(Context);
422ef860a24SChandler Carruth ST->setSubclassData(SCDB_IsLiteral); // Literal struct.
423ef860a24SChandler Carruth ST->setBody(ETypes, isPacked);
424142919bcSKrasimir Georgiev *Insertion.first = ST;
425ef860a24SChandler Carruth } else {
426142919bcSKrasimir Georgiev // The struct type was found. Just return it.
427142919bcSKrasimir Georgiev ST = *Insertion.first;
428ef860a24SChandler Carruth }
429ef860a24SChandler Carruth
430ef860a24SChandler Carruth return ST;
431ef860a24SChandler Carruth }
432ef860a24SChandler Carruth
containsScalableVectorType() const433cfec6cd5SCraig Topper bool StructType::containsScalableVectorType() const {
434cfec6cd5SCraig Topper for (Type *Ty : elements()) {
435cfec6cd5SCraig Topper if (isa<ScalableVectorType>(Ty))
436cfec6cd5SCraig Topper return true;
437cfec6cd5SCraig Topper if (auto *STy = dyn_cast<StructType>(Ty))
438cfec6cd5SCraig Topper if (STy->containsScalableVectorType())
439cfec6cd5SCraig Topper return true;
440cfec6cd5SCraig Topper }
441cfec6cd5SCraig Topper
442cfec6cd5SCraig Topper return false;
443cfec6cd5SCraig Topper }
444cfec6cd5SCraig Topper
setBody(ArrayRef<Type * > Elements,bool isPacked)445ef860a24SChandler Carruth void StructType::setBody(ArrayRef<Type*> Elements, bool isPacked) {
446ef860a24SChandler Carruth assert(isOpaque() && "Struct body already set!");
447ef860a24SChandler Carruth
448ef860a24SChandler Carruth setSubclassData(getSubclassData() | SCDB_HasBody);
449ef860a24SChandler Carruth if (isPacked)
450ef860a24SChandler Carruth setSubclassData(getSubclassData() | SCDB_Packed);
451ef860a24SChandler Carruth
4529aad5997SBenjamin Kramer NumContainedTys = Elements.size();
4539aad5997SBenjamin Kramer
45477711979SChandler Carruth if (Elements.empty()) {
45577711979SChandler Carruth ContainedTys = nullptr;
45677711979SChandler Carruth return;
45777711979SChandler Carruth }
45877711979SChandler Carruth
45910c548cdSPeter Collingbourne ContainedTys = Elements.copy(getContext().pImpl->Alloc).data();
460ef860a24SChandler Carruth }
461ef860a24SChandler Carruth
setName(StringRef Name)462ef860a24SChandler Carruth void StructType::setName(StringRef Name) {
463ef860a24SChandler Carruth if (Name == getName()) return;
464ef860a24SChandler Carruth
465ef860a24SChandler Carruth StringMap<StructType *> &SymbolTable = getContext().pImpl->NamedStructTypes;
4660cd79488SEugene Zelenko
4670cd79488SEugene Zelenko using EntryTy = StringMap<StructType *>::MapEntryTy;
468ef860a24SChandler Carruth
469ef860a24SChandler Carruth // If this struct already had a name, remove its symbol table entry. Don't
470ef860a24SChandler Carruth // delete the data yet because it may be part of the new name.
471ef860a24SChandler Carruth if (SymbolTableEntry)
472ef860a24SChandler Carruth SymbolTable.remove((EntryTy *)SymbolTableEntry);
473ef860a24SChandler Carruth
474ef860a24SChandler Carruth // If this is just removing the name, we're done.
475ef860a24SChandler Carruth if (Name.empty()) {
476ef860a24SChandler Carruth if (SymbolTableEntry) {
477ef860a24SChandler Carruth // Delete the old string data.
478ef860a24SChandler Carruth ((EntryTy *)SymbolTableEntry)->Destroy(SymbolTable.getAllocator());
479c620761cSCraig Topper SymbolTableEntry = nullptr;
480ef860a24SChandler Carruth }
481ef860a24SChandler Carruth return;
482ef860a24SChandler Carruth }
483ef860a24SChandler Carruth
484ef860a24SChandler Carruth // Look up the entry for the name.
4855106ce78SDavid Blaikie auto IterBool =
4865106ce78SDavid Blaikie getContext().pImpl->NamedStructTypes.insert(std::make_pair(Name, this));
487ef860a24SChandler Carruth
488ef860a24SChandler Carruth // While we have a name collision, try a random rename.
4895106ce78SDavid Blaikie if (!IterBool.second) {
490ef860a24SChandler Carruth SmallString<64> TempStr(Name);
491ef860a24SChandler Carruth TempStr.push_back('.');
492ef860a24SChandler Carruth raw_svector_ostream TmpStream(TempStr);
493ef860a24SChandler Carruth unsigned NameSize = Name.size();
494ef860a24SChandler Carruth
495ef860a24SChandler Carruth do {
496ef860a24SChandler Carruth TempStr.resize(NameSize + 1);
497ef860a24SChandler Carruth TmpStream << getContext().pImpl->NamedStructTypesUniqueID++;
498ef860a24SChandler Carruth
4995106ce78SDavid Blaikie IterBool = getContext().pImpl->NamedStructTypes.insert(
5005106ce78SDavid Blaikie std::make_pair(TmpStream.str(), this));
5015106ce78SDavid Blaikie } while (!IterBool.second);
502ef860a24SChandler Carruth }
503ef860a24SChandler Carruth
504ef860a24SChandler Carruth // Delete the old string data.
505ef860a24SChandler Carruth if (SymbolTableEntry)
506ef860a24SChandler Carruth ((EntryTy *)SymbolTableEntry)->Destroy(SymbolTable.getAllocator());
5075106ce78SDavid Blaikie SymbolTableEntry = &*IterBool.first;
508ef860a24SChandler Carruth }
509ef860a24SChandler Carruth
510ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
511ef860a24SChandler Carruth // StructType Helper functions.
512ef860a24SChandler Carruth
create(LLVMContext & Context,StringRef Name)513ef860a24SChandler Carruth StructType *StructType::create(LLVMContext &Context, StringRef Name) {
51410c548cdSPeter Collingbourne StructType *ST = new (Context.pImpl->Alloc) StructType(Context);
515ef860a24SChandler Carruth if (!Name.empty())
516ef860a24SChandler Carruth ST->setName(Name);
517ef860a24SChandler Carruth return ST;
518ef860a24SChandler Carruth }
519ef860a24SChandler Carruth
get(LLVMContext & Context,bool isPacked)520ef860a24SChandler Carruth StructType *StructType::get(LLVMContext &Context, bool isPacked) {
5213238fb75SDmitri Gribenko return get(Context, None, isPacked);
522ef860a24SChandler Carruth }
523ef860a24SChandler Carruth
create(LLVMContext & Context,ArrayRef<Type * > Elements,StringRef Name,bool isPacked)524ef860a24SChandler Carruth StructType *StructType::create(LLVMContext &Context, ArrayRef<Type*> Elements,
525ef860a24SChandler Carruth StringRef Name, bool isPacked) {
526ef860a24SChandler Carruth StructType *ST = create(Context, Name);
527ef860a24SChandler Carruth ST->setBody(Elements, isPacked);
528ef860a24SChandler Carruth return ST;
529ef860a24SChandler Carruth }
530ef860a24SChandler Carruth
create(LLVMContext & Context,ArrayRef<Type * > Elements)531ef860a24SChandler Carruth StructType *StructType::create(LLVMContext &Context, ArrayRef<Type*> Elements) {
532ef860a24SChandler Carruth return create(Context, Elements, StringRef());
533ef860a24SChandler Carruth }
534ef860a24SChandler Carruth
create(LLVMContext & Context)535ef860a24SChandler Carruth StructType *StructType::create(LLVMContext &Context) {
536ef860a24SChandler Carruth return create(Context, StringRef());
537ef860a24SChandler Carruth }
538ef860a24SChandler Carruth
create(ArrayRef<Type * > Elements,StringRef Name,bool isPacked)539ef860a24SChandler Carruth StructType *StructType::create(ArrayRef<Type*> Elements, StringRef Name,
540ef860a24SChandler Carruth bool isPacked) {
541ef860a24SChandler Carruth assert(!Elements.empty() &&
542ef860a24SChandler Carruth "This method may not be invoked with an empty list");
543ef860a24SChandler Carruth return create(Elements[0]->getContext(), Elements, Name, isPacked);
544ef860a24SChandler Carruth }
545ef860a24SChandler Carruth
create(ArrayRef<Type * > Elements)546ef860a24SChandler Carruth StructType *StructType::create(ArrayRef<Type*> Elements) {
547ef860a24SChandler Carruth assert(!Elements.empty() &&
548ef860a24SChandler Carruth "This method may not be invoked with an empty list");
549ef860a24SChandler Carruth return create(Elements[0]->getContext(), Elements, StringRef());
550ef860a24SChandler Carruth }
551ef860a24SChandler Carruth
isSized(SmallPtrSetImpl<Type * > * Visited) const552e3dcce97SCraig Topper bool StructType::isSized(SmallPtrSetImpl<Type*> *Visited) const {
553ef860a24SChandler Carruth if ((getSubclassData() & SCDB_IsSized) != 0)
554ef860a24SChandler Carruth return true;
555ef860a24SChandler Carruth if (isOpaque())
556ef860a24SChandler Carruth return false;
557ef860a24SChandler Carruth
558e3dcce97SCraig Topper if (Visited && !Visited->insert(const_cast<StructType*>(this)).second)
5594e865607SKaelyn Uhrain return false;
5604e865607SKaelyn Uhrain
561ef860a24SChandler Carruth // Okay, our struct is sized if all of the elements are, but if one of the
562ef860a24SChandler Carruth // elements is opaque, the struct isn't sized *yet*, but may become sized in
563ef860a24SChandler Carruth // the future, so just bail out without caching.
564cfec6cd5SCraig Topper for (Type *Ty : elements()) {
565cfec6cd5SCraig Topper // If the struct contains a scalable vector type, don't consider it sized.
566cfec6cd5SCraig Topper // This prevents it from being used in loads/stores/allocas/GEPs.
567cfec6cd5SCraig Topper if (isa<ScalableVectorType>(Ty))
568ef860a24SChandler Carruth return false;
569cfec6cd5SCraig Topper if (!Ty->isSized(Visited))
570cfec6cd5SCraig Topper return false;
571cfec6cd5SCraig Topper }
572ef860a24SChandler Carruth
573ef860a24SChandler Carruth // Here we cheat a bit and cast away const-ness. The goal is to memoize when
574ef860a24SChandler Carruth // we find a sized type, as types can only move from opaque to sized, not the
575ef860a24SChandler Carruth // other way.
576ef860a24SChandler Carruth const_cast<StructType*>(this)->setSubclassData(
577ef860a24SChandler Carruth getSubclassData() | SCDB_IsSized);
578ef860a24SChandler Carruth return true;
579ef860a24SChandler Carruth }
580ef860a24SChandler Carruth
getName() const581ef860a24SChandler Carruth StringRef StructType::getName() const {
582ef860a24SChandler Carruth assert(!isLiteral() && "Literal structs never have names");
583c620761cSCraig Topper if (!SymbolTableEntry) return StringRef();
584ef860a24SChandler Carruth
585ef860a24SChandler Carruth return ((StringMapEntry<StructType*> *)SymbolTableEntry)->getKey();
586ef860a24SChandler Carruth }
587ef860a24SChandler Carruth
isValidElementType(Type * ElemTy)588ef860a24SChandler Carruth bool StructType::isValidElementType(Type *ElemTy) {
589ef860a24SChandler Carruth return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() &&
590b611e3f5SDavid Majnemer !ElemTy->isMetadataTy() && !ElemTy->isFunctionTy() &&
591cfec6cd5SCraig Topper !ElemTy->isTokenTy();
592ef860a24SChandler Carruth }
593ef860a24SChandler Carruth
isLayoutIdentical(StructType * Other) const594ef860a24SChandler Carruth bool StructType::isLayoutIdentical(StructType *Other) const {
595ef860a24SChandler Carruth if (this == Other) return true;
596ef860a24SChandler Carruth
597dc1d1cbdSBenjamin Kramer if (isPacked() != Other->isPacked())
598ef860a24SChandler Carruth return false;
599ef860a24SChandler Carruth
600dc1d1cbdSBenjamin Kramer return elements() == Other->elements();
601ef860a24SChandler Carruth }
602ef860a24SChandler Carruth
getTypeAtIndex(const Value * V) const603e24e95feSEli Friedman Type *StructType::getTypeAtIndex(const Value *V) const {
604e24e95feSEli Friedman unsigned Idx = (unsigned)cast<Constant>(V)->getUniqueInteger().getZExtValue();
605ef860a24SChandler Carruth assert(indexValid(Idx) && "Invalid structure index!");
606e24e95feSEli Friedman return getElementType(Idx);
607ef860a24SChandler Carruth }
608ef860a24SChandler Carruth
indexValid(const Value * V) const609e24e95feSEli Friedman bool StructType::indexValid(const Value *V) const {
610ef860a24SChandler Carruth // Structure indexes require (vectors of) 32-bit integer constants. In the
611ef860a24SChandler Carruth // vector case all of the indices must be equal.
612fde4723eSCraig Topper if (!V->getType()->isIntOrIntVectorTy(32))
613ef860a24SChandler Carruth return false;
614df1f371eSEli Friedman if (isa<ScalableVectorType>(V->getType()))
615df1f371eSEli Friedman return false;
616ef860a24SChandler Carruth const Constant *C = dyn_cast<Constant>(V);
617ef860a24SChandler Carruth if (C && V->getType()->isVectorTy())
618ef860a24SChandler Carruth C = C->getSplatValue();
619ef860a24SChandler Carruth const ConstantInt *CU = dyn_cast_or_null<ConstantInt>(C);
620e24e95feSEli Friedman return CU && CU->getZExtValue() < getNumElements();
621ef860a24SChandler Carruth }
622ef860a24SChandler Carruth
getTypeByName(LLVMContext & C,StringRef Name)623fe431683SNick Lewycky StructType *StructType::getTypeByName(LLVMContext &C, StringRef Name) {
624fe431683SNick Lewycky return C.pImpl->NamedStructTypes.lookup(Name);
625fe431683SNick Lewycky }
626fe431683SNick Lewycky
627ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
628ef860a24SChandler Carruth // ArrayType Implementation
629ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
630ef860a24SChandler Carruth
ArrayType(Type * ElType,uint64_t NumEl)631ef860a24SChandler Carruth ArrayType::ArrayType(Type *ElType, uint64_t NumEl)
63268b03aeeSEli Friedman : Type(ElType->getContext(), ArrayTyID), ContainedType(ElType),
63368b03aeeSEli Friedman NumElements(NumEl) {
63468b03aeeSEli Friedman ContainedTys = &ContainedType;
63568b03aeeSEli Friedman NumContainedTys = 1;
63668b03aeeSEli Friedman }
637ef860a24SChandler Carruth
get(Type * ElementType,uint64_t NumElements)6387554da2cSCraig Topper ArrayType *ArrayType::get(Type *ElementType, uint64_t NumElements) {
639ef860a24SChandler Carruth assert(isValidElementType(ElementType) && "Invalid type for array element!");
640ef860a24SChandler Carruth
641ef860a24SChandler Carruth LLVMContextImpl *pImpl = ElementType->getContext().pImpl;
642ef860a24SChandler Carruth ArrayType *&Entry =
643ef860a24SChandler Carruth pImpl->ArrayTypes[std::make_pair(ElementType, NumElements)];
644ef860a24SChandler Carruth
645c620761cSCraig Topper if (!Entry)
64610c548cdSPeter Collingbourne Entry = new (pImpl->Alloc) ArrayType(ElementType, NumElements);
647ef860a24SChandler Carruth return Entry;
648ef860a24SChandler Carruth }
649ef860a24SChandler Carruth
isValidElementType(Type * ElemTy)650ef860a24SChandler Carruth bool ArrayType::isValidElementType(Type *ElemTy) {
651ef860a24SChandler Carruth return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() &&
652b611e3f5SDavid Majnemer !ElemTy->isMetadataTy() && !ElemTy->isFunctionTy() &&
653bcdaccfeSLuo, Yuanke !ElemTy->isTokenTy() && !ElemTy->isX86_AMXTy() &&
654bcdaccfeSLuo, Yuanke !isa<ScalableVectorType>(ElemTy);
655ef860a24SChandler Carruth }
656ef860a24SChandler Carruth
657ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
658ef860a24SChandler Carruth // VectorType Implementation
659ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
660ef860a24SChandler Carruth
VectorType(Type * ElType,unsigned EQ,Type::TypeID TID)661947be4a0SChristopher Tetreault VectorType::VectorType(Type *ElType, unsigned EQ, Type::TypeID TID)
662947be4a0SChristopher Tetreault : Type(ElType->getContext(), TID), ContainedType(ElType),
663947be4a0SChristopher Tetreault ElementQuantity(EQ) {
66468b03aeeSEli Friedman ContainedTys = &ContainedType;
66568b03aeeSEli Friedman NumContainedTys = 1;
66668b03aeeSEli Friedman }
667ef860a24SChandler Carruth
get(Type * ElementType,ElementCount EC)668957c40dbSGraham Hunter VectorType *VectorType::get(Type *ElementType, ElementCount EC) {
669f4257c58SDavid Sherwood if (EC.isScalable())
670f4257c58SDavid Sherwood return ScalableVectorType::get(ElementType, EC.getKnownMinValue());
6712dea3f12SChristopher Tetreault else
672f4257c58SDavid Sherwood return FixedVectorType::get(ElementType, EC.getKnownMinValue());
673ef860a24SChandler Carruth }
674ef860a24SChandler Carruth
isValidElementType(Type * ElemTy)675ef860a24SChandler Carruth bool VectorType::isValidElementType(Type *ElemTy) {
676ef860a24SChandler Carruth return ElemTy->isIntegerTy() || ElemTy->isFloatingPointTy() ||
677ef860a24SChandler Carruth ElemTy->isPointerTy();
678ef860a24SChandler Carruth }
679ef860a24SChandler Carruth
680ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
6812dea3f12SChristopher Tetreault // FixedVectorType Implementation
6822dea3f12SChristopher Tetreault //===----------------------------------------------------------------------===//
6832dea3f12SChristopher Tetreault
get(Type * ElementType,unsigned NumElts)6842dea3f12SChristopher Tetreault FixedVectorType *FixedVectorType::get(Type *ElementType, unsigned NumElts) {
6852dea3f12SChristopher Tetreault assert(NumElts > 0 && "#Elements of a VectorType must be greater than 0");
6862dea3f12SChristopher Tetreault assert(isValidElementType(ElementType) && "Element type of a VectorType must "
6872dea3f12SChristopher Tetreault "be an integer, floating point, or "
6882dea3f12SChristopher Tetreault "pointer type.");
6892dea3f12SChristopher Tetreault
690a407ec9bSMehdi Amini auto EC = ElementCount::getFixed(NumElts);
6912dea3f12SChristopher Tetreault
6922dea3f12SChristopher Tetreault LLVMContextImpl *pImpl = ElementType->getContext().pImpl;
6932dea3f12SChristopher Tetreault VectorType *&Entry = ElementType->getContext()
6942dea3f12SChristopher Tetreault .pImpl->VectorTypes[std::make_pair(ElementType, EC)];
6952dea3f12SChristopher Tetreault
6962dea3f12SChristopher Tetreault if (!Entry)
6972dea3f12SChristopher Tetreault Entry = new (pImpl->Alloc) FixedVectorType(ElementType, NumElts);
6982dea3f12SChristopher Tetreault return cast<FixedVectorType>(Entry);
6992dea3f12SChristopher Tetreault }
7002dea3f12SChristopher Tetreault
7012dea3f12SChristopher Tetreault //===----------------------------------------------------------------------===//
7022dea3f12SChristopher Tetreault // ScalableVectorType Implementation
7032dea3f12SChristopher Tetreault //===----------------------------------------------------------------------===//
7042dea3f12SChristopher Tetreault
get(Type * ElementType,unsigned MinNumElts)7052dea3f12SChristopher Tetreault ScalableVectorType *ScalableVectorType::get(Type *ElementType,
7062dea3f12SChristopher Tetreault unsigned MinNumElts) {
7072dea3f12SChristopher Tetreault assert(MinNumElts > 0 && "#Elements of a VectorType must be greater than 0");
7082dea3f12SChristopher Tetreault assert(isValidElementType(ElementType) && "Element type of a VectorType must "
7092dea3f12SChristopher Tetreault "be an integer, floating point, or "
7102dea3f12SChristopher Tetreault "pointer type.");
7112dea3f12SChristopher Tetreault
712a407ec9bSMehdi Amini auto EC = ElementCount::getScalable(MinNumElts);
7132dea3f12SChristopher Tetreault
7142dea3f12SChristopher Tetreault LLVMContextImpl *pImpl = ElementType->getContext().pImpl;
7152dea3f12SChristopher Tetreault VectorType *&Entry = ElementType->getContext()
7162dea3f12SChristopher Tetreault .pImpl->VectorTypes[std::make_pair(ElementType, EC)];
7172dea3f12SChristopher Tetreault
7182dea3f12SChristopher Tetreault if (!Entry)
7192dea3f12SChristopher Tetreault Entry = new (pImpl->Alloc) ScalableVectorType(ElementType, MinNumElts);
7202dea3f12SChristopher Tetreault return cast<ScalableVectorType>(Entry);
7212dea3f12SChristopher Tetreault }
7222dea3f12SChristopher Tetreault
7232dea3f12SChristopher Tetreault //===----------------------------------------------------------------------===//
724ef860a24SChandler Carruth // PointerType Implementation
725ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
726ef860a24SChandler Carruth
get(Type * EltTy,unsigned AddressSpace)727ef860a24SChandler Carruth PointerType *PointerType::get(Type *EltTy, unsigned AddressSpace) {
728ef860a24SChandler Carruth assert(EltTy && "Can't get a pointer to <null> type!");
729ef860a24SChandler Carruth assert(isValidElementType(EltTy) && "Invalid type for pointer element!");
730ef860a24SChandler Carruth
731ef860a24SChandler Carruth LLVMContextImpl *CImpl = EltTy->getContext().pImpl;
732ef860a24SChandler Carruth
73390ec6dffSNikita Popov // Automatically convert typed pointers to opaque pointers.
734*1caabbefSVitaly Buka if (CImpl->getOpaquePointers())
7354c8174f5SArthur Eubanks return get(EltTy->getContext(), AddressSpace);
7364c8174f5SArthur Eubanks
737ef860a24SChandler Carruth // Since AddressSpace #0 is the common case, we special case it.
738ef860a24SChandler Carruth PointerType *&Entry = AddressSpace == 0 ? CImpl->PointerTypes[EltTy]
739ef860a24SChandler Carruth : CImpl->ASPointerTypes[std::make_pair(EltTy, AddressSpace)];
740ef860a24SChandler Carruth
741c620761cSCraig Topper if (!Entry)
74210c548cdSPeter Collingbourne Entry = new (CImpl->Alloc) PointerType(EltTy, AddressSpace);
743ef860a24SChandler Carruth return Entry;
744ef860a24SChandler Carruth }
745ef860a24SChandler Carruth
get(LLVMContext & C,unsigned AddressSpace)7462155dc51SArthur Eubanks PointerType *PointerType::get(LLVMContext &C, unsigned AddressSpace) {
7472155dc51SArthur Eubanks LLVMContextImpl *CImpl = C.pImpl;
748*1caabbefSVitaly Buka assert(CImpl->getOpaquePointers() &&
74990ec6dffSNikita Popov "Can only create opaque pointers in opaque pointer mode");
7502155dc51SArthur Eubanks
7512155dc51SArthur Eubanks // Since AddressSpace #0 is the common case, we special case it.
7522155dc51SArthur Eubanks PointerType *&Entry =
7532155dc51SArthur Eubanks AddressSpace == 0
7542155dc51SArthur Eubanks ? CImpl->PointerTypes[nullptr]
7552155dc51SArthur Eubanks : CImpl->ASPointerTypes[std::make_pair(nullptr, AddressSpace)];
7562155dc51SArthur Eubanks
7572155dc51SArthur Eubanks if (!Entry)
7582155dc51SArthur Eubanks Entry = new (CImpl->Alloc) PointerType(C, AddressSpace);
7592155dc51SArthur Eubanks return Entry;
7602155dc51SArthur Eubanks }
7612155dc51SArthur Eubanks
PointerType(Type * E,unsigned AddrSpace)762ef860a24SChandler Carruth PointerType::PointerType(Type *E, unsigned AddrSpace)
7634568158cSPeter Collingbourne : Type(E->getContext(), PointerTyID), PointeeTy(E) {
7644568158cSPeter Collingbourne ContainedTys = &PointeeTy;
7654568158cSPeter Collingbourne NumContainedTys = 1;
766ef860a24SChandler Carruth setSubclassData(AddrSpace);
767ef860a24SChandler Carruth }
768ef860a24SChandler Carruth
PointerType(LLVMContext & C,unsigned AddrSpace)7692155dc51SArthur Eubanks PointerType::PointerType(LLVMContext &C, unsigned AddrSpace)
7702155dc51SArthur Eubanks : Type(C, PointerTyID), PointeeTy(nullptr) {
7712155dc51SArthur Eubanks setSubclassData(AddrSpace);
7722155dc51SArthur Eubanks }
7732155dc51SArthur Eubanks
getPointerTo(unsigned AddrSpace) const7747bb7fa12SNikita Popov PointerType *Type::getPointerTo(unsigned AddrSpace) const {
7757bb7fa12SNikita Popov return PointerType::get(const_cast<Type*>(this), AddrSpace);
776ef860a24SChandler Carruth }
777ef860a24SChandler Carruth
isValidElementType(Type * ElemTy)778ef860a24SChandler Carruth bool PointerType::isValidElementType(Type *ElemTy) {
779ef860a24SChandler Carruth return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() &&
780bcdaccfeSLuo, Yuanke !ElemTy->isMetadataTy() && !ElemTy->isTokenTy() &&
7811e6303e6SNikita Popov !ElemTy->isX86_AMXTy();
782ef860a24SChandler Carruth }
78311bb8495SFilipe Cabecinhas
isLoadableOrStorableType(Type * ElemTy)78411bb8495SFilipe Cabecinhas bool PointerType::isLoadableOrStorableType(Type *ElemTy) {
78511bb8495SFilipe Cabecinhas return isValidElementType(ElemTy) && !ElemTy->isFunctionTy();
78611bb8495SFilipe Cabecinhas }
787