LLVM 19.0.0git
Type.cpp
Go to the documentation of this file.
1//===- Type.cpp - Implement the Type class --------------------------------===//
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//
9// This file implements the Type class for the IR library.
10//
11//===----------------------------------------------------------------------===//
12
13#include "llvm/IR/Type.h"
14#include "LLVMContextImpl.h"
15#include "llvm/ADT/APInt.h"
17#include "llvm/ADT/StringMap.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/IR/Constant.h"
20#include "llvm/IR/Constants.h"
22#include "llvm/IR/LLVMContext.h"
23#include "llvm/IR/Value.h"
27#include <cassert>
28#include <utility>
29
30using namespace llvm;
31
32//===----------------------------------------------------------------------===//
33// Type Class Implementation
34//===----------------------------------------------------------------------===//
35
37 switch (IDNumber) {
38 case VoidTyID : return getVoidTy(C);
39 case HalfTyID : return getHalfTy(C);
40 case BFloatTyID : return getBFloatTy(C);
41 case FloatTyID : return getFloatTy(C);
42 case DoubleTyID : return getDoubleTy(C);
43 case X86_FP80TyID : return getX86_FP80Ty(C);
44 case FP128TyID : return getFP128Ty(C);
45 case PPC_FP128TyID : return getPPC_FP128Ty(C);
46 case LabelTyID : return getLabelTy(C);
47 case MetadataTyID : return getMetadataTy(C);
48 case X86_MMXTyID : return getX86_MMXTy(C);
49 case X86_AMXTyID : return getX86_AMXTy(C);
50 case TokenTyID : return getTokenTy(C);
51 default:
52 return nullptr;
53 }
54}
55
56bool Type::isIntegerTy(unsigned Bitwidth) const {
57 return isIntegerTy() && cast<IntegerType>(this)->getBitWidth() == Bitwidth;
58}
59
60bool Type::isScalableTy() const {
61 if (const auto *ATy = dyn_cast<ArrayType>(this))
62 return ATy->getElementType()->isScalableTy();
63 if (const auto *STy = dyn_cast<StructType>(this)) {
65 return STy->containsScalableVectorType(&Visited);
66 }
68}
69
71 switch (getTypeID()) {
72 case HalfTyID: return APFloat::IEEEhalf();
73 case BFloatTyID: return APFloat::BFloat();
74 case FloatTyID: return APFloat::IEEEsingle();
75 case DoubleTyID: return APFloat::IEEEdouble();
77 case FP128TyID: return APFloat::IEEEquad();
79 default: llvm_unreachable("Invalid floating type");
80 }
81}
82
83bool Type::isIEEE() const {
85}
86
87bool Type::isScalableTargetExtTy() const {
88 if (auto *TT = dyn_cast<TargetExtType>(this))
89 return isa<ScalableVectorType>(TT->getLayoutType());
90 return false;
91}
92
94 Type *Ty;
95 if (&S == &APFloat::IEEEhalf())
96 Ty = Type::getHalfTy(C);
97 else if (&S == &APFloat::BFloat())
98 Ty = Type::getBFloatTy(C);
99 else if (&S == &APFloat::IEEEsingle())
100 Ty = Type::getFloatTy(C);
101 else if (&S == &APFloat::IEEEdouble())
102 Ty = Type::getDoubleTy(C);
103 else if (&S == &APFloat::x87DoubleExtended())
105 else if (&S == &APFloat::IEEEquad())
106 Ty = Type::getFP128Ty(C);
107 else {
108 assert(&S == &APFloat::PPCDoubleDouble() && "Unknown FP format");
110 }
111 return Ty;
112}
113
114bool Type::canLosslesslyBitCastTo(Type *Ty) const {
115 // Identity cast means no change so return true
116 if (this == Ty)
117 return true;
118
119 // They are not convertible unless they are at least first class types
120 if (!this->isFirstClassType() || !Ty->isFirstClassType())
121 return false;
122
123 // Vector -> Vector conversions are always lossless if the two vector types
124 // have the same size, otherwise not.
125 if (isa<VectorType>(this) && isa<VectorType>(Ty))
127
128 // 64-bit fixed width vector types can be losslessly converted to x86mmx.
129 if (((isa<FixedVectorType>(this)) && Ty->isX86_MMXTy()) &&
130 getPrimitiveSizeInBits().getFixedValue() == 64)
131 return true;
132 if ((isX86_MMXTy() && isa<FixedVectorType>(Ty)) &&
134 return true;
135
136 // 8192-bit fixed width vector types can be losslessly converted to x86amx.
137 if (((isa<FixedVectorType>(this)) && Ty->isX86_AMXTy()) &&
138 getPrimitiveSizeInBits().getFixedValue() == 8192)
139 return true;
140 if ((isX86_AMXTy() && isa<FixedVectorType>(Ty)) &&
142 return true;
143
144 // Conservatively assume we can't losslessly convert between pointers with
145 // different address spaces.
146 return false;
147}
148
149bool Type::isEmptyTy() const {
150 if (auto *ATy = dyn_cast<ArrayType>(this)) {
151 unsigned NumElements = ATy->getNumElements();
152 return NumElements == 0 || ATy->getElementType()->isEmptyTy();
153 }
154
155 if (auto *STy = dyn_cast<StructType>(this)) {
156 unsigned NumElements = STy->getNumElements();
157 for (unsigned i = 0; i < NumElements; ++i)
158 if (!STy->getElementType(i)->isEmptyTy())
159 return false;
160 return true;
161 }
162
163 return false;
164}
165
167 switch (getTypeID()) {
168 case Type::HalfTyID:
169 return TypeSize::getFixed(16);
170 case Type::BFloatTyID:
171 return TypeSize::getFixed(16);
172 case Type::FloatTyID:
173 return TypeSize::getFixed(32);
174 case Type::DoubleTyID:
175 return TypeSize::getFixed(64);
177 return TypeSize::getFixed(80);
178 case Type::FP128TyID:
179 return TypeSize::getFixed(128);
181 return TypeSize::getFixed(128);
183 return TypeSize::getFixed(64);
185 return TypeSize::getFixed(8192);
187 return TypeSize::getFixed(cast<IntegerType>(this)->getBitWidth());
190 const VectorType *VTy = cast<VectorType>(this);
191 ElementCount EC = VTy->getElementCount();
192 TypeSize ETS = VTy->getElementType()->getPrimitiveSizeInBits();
193 assert(!ETS.isScalable() && "Vector type should have fixed-width elements");
194 return {ETS.getFixedValue() * EC.getKnownMinValue(), EC.isScalable()};
195 }
196 default:
197 return TypeSize::getFixed(0);
198 }
199}
200
201unsigned Type::getScalarSizeInBits() const {
202 // It is safe to assume that the scalar types have a fixed size.
204}
205
206int Type::getFPMantissaWidth() const {
207 if (auto *VTy = dyn_cast<VectorType>(this))
208 return VTy->getElementType()->getFPMantissaWidth();
209 assert(isFloatingPointTy() && "Not a floating point type!");
210 if (getTypeID() == HalfTyID) return 11;
211 if (getTypeID() == BFloatTyID) return 8;
212 if (getTypeID() == FloatTyID) return 24;
213 if (getTypeID() == DoubleTyID) return 53;
214 if (getTypeID() == X86_FP80TyID) return 64;
215 if (getTypeID() == FP128TyID) return 113;
216 assert(getTypeID() == PPC_FP128TyID && "unknown fp type");
217 return -1;
218}
219
220bool Type::isSizedDerivedType(SmallPtrSetImpl<Type*> *Visited) const {
221 if (auto *ATy = dyn_cast<ArrayType>(this))
222 return ATy->getElementType()->isSized(Visited);
223
224 if (auto *VTy = dyn_cast<VectorType>(this))
225 return VTy->getElementType()->isSized(Visited);
226
227 if (auto *TTy = dyn_cast<TargetExtType>(this))
228 return TTy->getLayoutType()->isSized(Visited);
229
230 return cast<StructType>(this)->isSized(Visited);
231}
232
233//===----------------------------------------------------------------------===//
234// Primitive 'Type' data
235//===----------------------------------------------------------------------===//
236
237Type *Type::getVoidTy(LLVMContext &C) { return &C.pImpl->VoidTy; }
238Type *Type::getLabelTy(LLVMContext &C) { return &C.pImpl->LabelTy; }
239Type *Type::getHalfTy(LLVMContext &C) { return &C.pImpl->HalfTy; }
240Type *Type::getBFloatTy(LLVMContext &C) { return &C.pImpl->BFloatTy; }
241Type *Type::getFloatTy(LLVMContext &C) { return &C.pImpl->FloatTy; }
242Type *Type::getDoubleTy(LLVMContext &C) { return &C.pImpl->DoubleTy; }
243Type *Type::getMetadataTy(LLVMContext &C) { return &C.pImpl->MetadataTy; }
244Type *Type::getTokenTy(LLVMContext &C) { return &C.pImpl->TokenTy; }
245Type *Type::getX86_FP80Ty(LLVMContext &C) { return &C.pImpl->X86_FP80Ty; }
246Type *Type::getFP128Ty(LLVMContext &C) { return &C.pImpl->FP128Ty; }
247Type *Type::getPPC_FP128Ty(LLVMContext &C) { return &C.pImpl->PPC_FP128Ty; }
248Type *Type::getX86_MMXTy(LLVMContext &C) { return &C.pImpl->X86_MMXTy; }
249Type *Type::getX86_AMXTy(LLVMContext &C) { return &C.pImpl->X86_AMXTy; }
250
251IntegerType *Type::getInt1Ty(LLVMContext &C) { return &C.pImpl->Int1Ty; }
252IntegerType *Type::getInt8Ty(LLVMContext &C) { return &C.pImpl->Int8Ty; }
253IntegerType *Type::getInt16Ty(LLVMContext &C) { return &C.pImpl->Int16Ty; }
254IntegerType *Type::getInt32Ty(LLVMContext &C) { return &C.pImpl->Int32Ty; }
255IntegerType *Type::getInt64Ty(LLVMContext &C) { return &C.pImpl->Int64Ty; }
256IntegerType *Type::getInt128Ty(LLVMContext &C) { return &C.pImpl->Int128Ty; }
257
259 return IntegerType::get(C, N);
260}
261
263 // opaque pointer in addrspace(10)
264 static PointerType *Ty = PointerType::get(C, 10);
265 return Ty;
266}
267
269 // opaque pointer in addrspace(20)
270 static PointerType *Ty = PointerType::get(C, 20);
271 return Ty;
272}
273
274//===----------------------------------------------------------------------===//
275// IntegerType Implementation
276//===----------------------------------------------------------------------===//
277
279 assert(NumBits >= MIN_INT_BITS && "bitwidth too small");
280 assert(NumBits <= MAX_INT_BITS && "bitwidth too large");
281
282 // Check for the built-in integer types
283 switch (NumBits) {
284 case 1: return cast<IntegerType>(Type::getInt1Ty(C));
285 case 8: return cast<IntegerType>(Type::getInt8Ty(C));
286 case 16: return cast<IntegerType>(Type::getInt16Ty(C));
287 case 32: return cast<IntegerType>(Type::getInt32Ty(C));
288 case 64: return cast<IntegerType>(Type::getInt64Ty(C));
289 case 128: return cast<IntegerType>(Type::getInt128Ty(C));
290 default:
291 break;
292 }
293
294 IntegerType *&Entry = C.pImpl->IntegerTypes[NumBits];
295
296 if (!Entry)
297 Entry = new (C.pImpl->Alloc) IntegerType(C, NumBits);
298
299 return Entry;
300}
301
303
304//===----------------------------------------------------------------------===//
305// FunctionType Implementation
306//===----------------------------------------------------------------------===//
307
308FunctionType::FunctionType(Type *Result, ArrayRef<Type*> Params,
309 bool IsVarArgs)
310 : Type(Result->getContext(), FunctionTyID) {
311 Type **SubTys = reinterpret_cast<Type**>(this+1);
312 assert(isValidReturnType(Result) && "invalid return type for function");
313 setSubclassData(IsVarArgs);
314
315 SubTys[0] = Result;
316
317 for (unsigned i = 0, e = Params.size(); i != e; ++i) {
318 assert(isValidArgumentType(Params[i]) &&
319 "Not a valid type for function argument!");
320 SubTys[i+1] = Params[i];
321 }
322
323 ContainedTys = SubTys;
324 NumContainedTys = Params.size() + 1; // + 1 for result type
325}
326
327// This is the factory function for the FunctionType class.
329 ArrayRef<Type*> Params, bool isVarArg) {
330 LLVMContextImpl *pImpl = ReturnType->getContext().pImpl;
331 const FunctionTypeKeyInfo::KeyTy Key(ReturnType, Params, isVarArg);
332 FunctionType *FT;
333 // Since we only want to allocate a fresh function type in case none is found
334 // and we don't want to perform two lookups (one for checking if existent and
335 // one for inserting the newly allocated one), here we instead lookup based on
336 // Key and update the reference to the function type in-place to a newly
337 // allocated one if not found.
338 auto Insertion = pImpl->FunctionTypes.insert_as(nullptr, Key);
339 if (Insertion.second) {
340 // The function type was not found. Allocate one and update FunctionTypes
341 // in-place.
342 FT = (FunctionType *)pImpl->Alloc.Allocate(
343 sizeof(FunctionType) + sizeof(Type *) * (Params.size() + 1),
344 alignof(FunctionType));
345 new (FT) FunctionType(ReturnType, Params, isVarArg);
346 *Insertion.first = FT;
347 } else {
348 // The function type was found. Just return it.
349 FT = *Insertion.first;
350 }
351 return FT;
352}
353
354FunctionType *FunctionType::get(Type *Result, bool isVarArg) {
355 return get(Result, std::nullopt, isVarArg);
356}
357
359 return !RetTy->isFunctionTy() && !RetTy->isLabelTy() &&
360 !RetTy->isMetadataTy();
361}
362
364 return ArgTy->isFirstClassType();
365}
366
367//===----------------------------------------------------------------------===//
368// StructType Implementation
369//===----------------------------------------------------------------------===//
370
371// Primitive Constructors.
372
374 bool isPacked) {
376 const AnonStructTypeKeyInfo::KeyTy Key(ETypes, isPacked);
377
378 StructType *ST;
379 // Since we only want to allocate a fresh struct type in case none is found
380 // and we don't want to perform two lookups (one for checking if existent and
381 // one for inserting the newly allocated one), here we instead lookup based on
382 // Key and update the reference to the struct type in-place to a newly
383 // allocated one if not found.
384 auto Insertion = pImpl->AnonStructTypes.insert_as(nullptr, Key);
385 if (Insertion.second) {
386 // The struct type was not found. Allocate one and update AnonStructTypes
387 // in-place.
388 ST = new (Context.pImpl->Alloc) StructType(Context);
389 ST->setSubclassData(SCDB_IsLiteral); // Literal struct.
390 ST->setBody(ETypes, isPacked);
391 *Insertion.first = ST;
392 } else {
393 // The struct type was found. Just return it.
394 ST = *Insertion.first;
395 }
396
397 return ST;
398}
399
401 SmallPtrSetImpl<Type *> *Visited) const {
402 if ((getSubclassData() & SCDB_ContainsScalableVector) != 0)
403 return true;
404
405 if ((getSubclassData() & SCDB_NotContainsScalableVector) != 0)
406 return false;
407
408 if (Visited && !Visited->insert(const_cast<StructType *>(this)).second)
409 return false;
410
411 for (Type *Ty : elements()) {
412 if (isa<ScalableVectorType>(Ty)) {
413 const_cast<StructType *>(this)->setSubclassData(
414 getSubclassData() | SCDB_ContainsScalableVector);
415 return true;
416 }
417 if (auto *STy = dyn_cast<StructType>(Ty)) {
418 if (STy->containsScalableVectorType(Visited)) {
419 const_cast<StructType *>(this)->setSubclassData(
420 getSubclassData() | SCDB_ContainsScalableVector);
421 return true;
422 }
423 }
424 }
425
426 // For structures that are opaque, return false but do not set the
427 // SCDB_NotContainsScalableVector flag since it may gain scalable vector type
428 // when it becomes non-opaque.
429 if (!isOpaque())
430 const_cast<StructType *>(this)->setSubclassData(
431 getSubclassData() | SCDB_NotContainsScalableVector);
432 return false;
433}
434
436 Type *FirstTy = getNumElements() > 0 ? elements()[0] : nullptr;
437 if (!FirstTy || !isa<ScalableVectorType>(FirstTy))
438 return false;
439 for (Type *Ty : elements())
440 if (Ty != FirstTy)
441 return false;
442 return true;
443}
444
445void StructType::setBody(ArrayRef<Type*> Elements, bool isPacked) {
446 assert(isOpaque() && "Struct body already set!");
447
448 setSubclassData(getSubclassData() | SCDB_HasBody);
449 if (isPacked)
450 setSubclassData(getSubclassData() | SCDB_Packed);
451
452 NumContainedTys = Elements.size();
453
454 if (Elements.empty()) {
455 ContainedTys = nullptr;
456 return;
457 }
458
459 ContainedTys = Elements.copy(getContext().pImpl->Alloc).data();
460}
461
463 if (Name == getName()) return;
464
466
468
469 // If this struct already had a name, remove its symbol table entry. Don't
470 // delete the data yet because it may be part of the new name.
472 SymbolTable.remove((EntryTy *)SymbolTableEntry);
473
474 // If this is just removing the name, we're done.
475 if (Name.empty()) {
476 if (SymbolTableEntry) {
477 // Delete the old string data.
478 ((EntryTy *)SymbolTableEntry)->Destroy(SymbolTable.getAllocator());
479 SymbolTableEntry = nullptr;
480 }
481 return;
482 }
483
484 // Look up the entry for the name.
485 auto IterBool =
486 getContext().pImpl->NamedStructTypes.insert(std::make_pair(Name, this));
487
488 // While we have a name collision, try a random rename.
489 if (!IterBool.second) {
490 SmallString<64> TempStr(Name);
491 TempStr.push_back('.');
492 raw_svector_ostream TmpStream(TempStr);
493 unsigned NameSize = Name.size();
494
495 do {
496 TempStr.resize(NameSize + 1);
497 TmpStream << getContext().pImpl->NamedStructTypesUniqueID++;
498
499 IterBool = getContext().pImpl->NamedStructTypes.insert(
500 std::make_pair(TmpStream.str(), this));
501 } while (!IterBool.second);
502 }
503
504 // Delete the old string data.
506 ((EntryTy *)SymbolTableEntry)->Destroy(SymbolTable.getAllocator());
507 SymbolTableEntry = &*IterBool.first;
508}
509
510//===----------------------------------------------------------------------===//
511// StructType Helper functions.
512
515 if (!Name.empty())
516 ST->setName(Name);
517 return ST;
518}
519
520StructType *StructType::get(LLVMContext &Context, bool isPacked) {
521 return get(Context, std::nullopt, isPacked);
522}
523
525 StringRef Name, bool isPacked) {
527 ST->setBody(Elements, isPacked);
528 return ST;
529}
530
532 return create(Context, Elements, StringRef());
533}
534
536 return create(Context, StringRef());
537}
538
540 bool isPacked) {
541 assert(!Elements.empty() &&
542 "This method may not be invoked with an empty list");
543 return create(Elements[0]->getContext(), Elements, Name, isPacked);
544}
545
547 assert(!Elements.empty() &&
548 "This method may not be invoked with an empty list");
549 return create(Elements[0]->getContext(), Elements, StringRef());
550}
551
553 if ((getSubclassData() & SCDB_IsSized) != 0)
554 return true;
555 if (isOpaque())
556 return false;
557
558 if (Visited && !Visited->insert(const_cast<StructType*>(this)).second)
559 return false;
560
561 // Okay, our struct is sized if all of the elements are, but if one of the
562 // elements is opaque, the struct isn't sized *yet*, but may become sized in
563 // the future, so just bail out without caching.
564 // The ONLY special case inside a struct that is considered sized is when the
565 // elements are homogeneous of a scalable vector type.
567 const_cast<StructType *>(this)->setSubclassData(getSubclassData() |
568 SCDB_IsSized);
569 return true;
570 }
571 for (Type *Ty : elements()) {
572 // If the struct contains a scalable vector type, don't consider it sized.
573 // This prevents it from being used in loads/stores/allocas/GEPs. The ONLY
574 // special case right now is a structure of homogenous scalable vector
575 // types and is handled by the if-statement before this for-loop.
576 if (Ty->isScalableTy())
577 return false;
578 if (!Ty->isSized(Visited))
579 return false;
580 }
581
582 // Here we cheat a bit and cast away const-ness. The goal is to memoize when
583 // we find a sized type, as types can only move from opaque to sized, not the
584 // other way.
585 const_cast<StructType*>(this)->setSubclassData(
586 getSubclassData() | SCDB_IsSized);
587 return true;
588}
589
591 assert(!isLiteral() && "Literal structs never have names");
592 if (!SymbolTableEntry) return StringRef();
593
594 return ((StringMapEntry<StructType*> *)SymbolTableEntry)->getKey();
595}
596
598 return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() &&
599 !ElemTy->isMetadataTy() && !ElemTy->isFunctionTy() &&
600 !ElemTy->isTokenTy();
601}
602
604 if (this == Other) return true;
605
606 if (isPacked() != Other->isPacked())
607 return false;
608
609 return elements() == Other->elements();
610}
611
613 unsigned Idx = (unsigned)cast<Constant>(V)->getUniqueInteger().getZExtValue();
614 assert(indexValid(Idx) && "Invalid structure index!");
615 return getElementType(Idx);
616}
617
618bool StructType::indexValid(const Value *V) const {
619 // Structure indexes require (vectors of) 32-bit integer constants. In the
620 // vector case all of the indices must be equal.
621 if (!V->getType()->isIntOrIntVectorTy(32))
622 return false;
623 if (isa<ScalableVectorType>(V->getType()))
624 return false;
625 const Constant *C = dyn_cast<Constant>(V);
626 if (C && V->getType()->isVectorTy())
627 C = C->getSplatValue();
628 const ConstantInt *CU = dyn_cast_or_null<ConstantInt>(C);
629 return CU && CU->getZExtValue() < getNumElements();
630}
631
633 return C.pImpl->NamedStructTypes.lookup(Name);
634}
635
636//===----------------------------------------------------------------------===//
637// ArrayType Implementation
638//===----------------------------------------------------------------------===//
639
640ArrayType::ArrayType(Type *ElType, uint64_t NumEl)
641 : Type(ElType->getContext(), ArrayTyID), ContainedType(ElType),
642 NumElements(NumEl) {
643 ContainedTys = &ContainedType;
644 NumContainedTys = 1;
645}
646
647ArrayType *ArrayType::get(Type *ElementType, uint64_t NumElements) {
648 assert(isValidElementType(ElementType) && "Invalid type for array element!");
649
650 LLVMContextImpl *pImpl = ElementType->getContext().pImpl;
651 ArrayType *&Entry =
652 pImpl->ArrayTypes[std::make_pair(ElementType, NumElements)];
653
654 if (!Entry)
655 Entry = new (pImpl->Alloc) ArrayType(ElementType, NumElements);
656 return Entry;
657}
658
660 return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() &&
661 !ElemTy->isMetadataTy() && !ElemTy->isFunctionTy() &&
662 !ElemTy->isTokenTy() && !ElemTy->isX86_AMXTy();
663}
664
665//===----------------------------------------------------------------------===//
666// VectorType Implementation
667//===----------------------------------------------------------------------===//
668
670 : Type(ElType->getContext(), TID), ContainedType(ElType),
671 ElementQuantity(EQ) {
672 ContainedTys = &ContainedType;
673 NumContainedTys = 1;
674}
675
677 if (EC.isScalable())
678 return ScalableVectorType::get(ElementType, EC.getKnownMinValue());
679 else
680 return FixedVectorType::get(ElementType, EC.getKnownMinValue());
681}
682
684 return ElemTy->isIntegerTy() || ElemTy->isFloatingPointTy() ||
685 ElemTy->isPointerTy() || ElemTy->getTypeID() == TypedPointerTyID;
686}
687
688//===----------------------------------------------------------------------===//
689// FixedVectorType Implementation
690//===----------------------------------------------------------------------===//
691
692FixedVectorType *FixedVectorType::get(Type *ElementType, unsigned NumElts) {
693 assert(NumElts > 0 && "#Elements of a VectorType must be greater than 0");
694 assert(isValidElementType(ElementType) && "Element type of a VectorType must "
695 "be an integer, floating point, or "
696 "pointer type.");
697
698 auto EC = ElementCount::getFixed(NumElts);
699
700 LLVMContextImpl *pImpl = ElementType->getContext().pImpl;
701 VectorType *&Entry = ElementType->getContext()
702 .pImpl->VectorTypes[std::make_pair(ElementType, EC)];
703
704 if (!Entry)
705 Entry = new (pImpl->Alloc) FixedVectorType(ElementType, NumElts);
706 return cast<FixedVectorType>(Entry);
707}
708
709//===----------------------------------------------------------------------===//
710// ScalableVectorType Implementation
711//===----------------------------------------------------------------------===//
712
714 unsigned MinNumElts) {
715 assert(MinNumElts > 0 && "#Elements of a VectorType must be greater than 0");
716 assert(isValidElementType(ElementType) && "Element type of a VectorType must "
717 "be an integer, floating point, or "
718 "pointer type.");
719
720 auto EC = ElementCount::getScalable(MinNumElts);
721
722 LLVMContextImpl *pImpl = ElementType->getContext().pImpl;
723 VectorType *&Entry = ElementType->getContext()
724 .pImpl->VectorTypes[std::make_pair(ElementType, EC)];
725
726 if (!Entry)
727 Entry = new (pImpl->Alloc) ScalableVectorType(ElementType, MinNumElts);
728 return cast<ScalableVectorType>(Entry);
729}
730
731//===----------------------------------------------------------------------===//
732// PointerType Implementation
733//===----------------------------------------------------------------------===//
734
736 assert(EltTy && "Can't get a pointer to <null> type!");
737 assert(isValidElementType(EltTy) && "Invalid type for pointer element!");
738
739 // Automatically convert typed pointers to opaque pointers.
740 return get(EltTy->getContext(), AddressSpace);
741}
742
744 LLVMContextImpl *CImpl = C.pImpl;
745
746 // Since AddressSpace #0 is the common case, we special case it.
747 PointerType *&Entry = AddressSpace == 0 ? CImpl->AS0PointerType
748 : CImpl->PointerTypes[AddressSpace];
749
750 if (!Entry)
751 Entry = new (CImpl->Alloc) PointerType(C, AddressSpace);
752 return Entry;
753}
754
755PointerType::PointerType(LLVMContext &C, unsigned AddrSpace)
756 : Type(C, PointerTyID) {
757 setSubclassData(AddrSpace);
758}
759
760PointerType *Type::getPointerTo(unsigned AddrSpace) const {
761 return PointerType::get(const_cast<Type*>(this), AddrSpace);
762}
763
765 return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() &&
766 !ElemTy->isMetadataTy() && !ElemTy->isTokenTy() &&
767 !ElemTy->isX86_AMXTy();
768}
769
771 return isValidElementType(ElemTy) && !ElemTy->isFunctionTy();
772}
773
774//===----------------------------------------------------------------------===//
775// TargetExtType Implementation
776//===----------------------------------------------------------------------===//
777
778TargetExtType::TargetExtType(LLVMContext &C, StringRef Name,
780 : Type(C, TargetExtTyID), Name(C.pImpl->Saver.save(Name)) {
781 NumContainedTys = Types.size();
782
783 // Parameter storage immediately follows the class in allocation.
784 Type **Params = reinterpret_cast<Type **>(this + 1);
785 ContainedTys = Params;
786 for (Type *T : Types)
787 *Params++ = T;
788
789 setSubclassData(Ints.size());
790 unsigned *IntParamSpace = reinterpret_cast<unsigned *>(Params);
791 IntParams = IntParamSpace;
792 for (unsigned IntParam : Ints)
793 *IntParamSpace++ = IntParam;
794}
795
797 ArrayRef<Type *> Types,
798 ArrayRef<unsigned> Ints) {
799 const TargetExtTypeKeyInfo::KeyTy Key(Name, Types, Ints);
800 TargetExtType *TT;
801 // Since we only want to allocate a fresh target type in case none is found
802 // and we don't want to perform two lookups (one for checking if existent and
803 // one for inserting the newly allocated one), here we instead lookup based on
804 // Key and update the reference to the target type in-place to a newly
805 // allocated one if not found.
806 auto Insertion = C.pImpl->TargetExtTypes.insert_as(nullptr, Key);
807 if (Insertion.second) {
808 // The target type was not found. Allocate one and update TargetExtTypes
809 // in-place.
810 TT = (TargetExtType *)C.pImpl->Alloc.Allocate(
811 sizeof(TargetExtType) + sizeof(Type *) * Types.size() +
812 sizeof(unsigned) * Ints.size(),
813 alignof(TargetExtType));
814 new (TT) TargetExtType(C, Name, Types, Ints);
815 *Insertion.first = TT;
816 } else {
817 // The target type was found. Just return it.
818 TT = *Insertion.first;
819 }
820 return TT;
821}
822
823namespace {
824struct TargetTypeInfo {
825 Type *LayoutType;
826 uint64_t Properties;
827
828 template <typename... ArgTys>
829 TargetTypeInfo(Type *LayoutType, ArgTys... Properties)
830 : LayoutType(LayoutType), Properties((0 | ... | Properties)) {}
831};
832} // anonymous namespace
833
834static TargetTypeInfo getTargetTypeInfo(const TargetExtType *Ty) {
835 LLVMContext &C = Ty->getContext();
836 StringRef Name = Ty->getName();
837 if (Name.equals("spirv.Image"))
838 return TargetTypeInfo(PointerType::get(C, 0), TargetExtType::CanBeGlobal);
839 if (Name.starts_with("spirv."))
840 return TargetTypeInfo(PointerType::get(C, 0), TargetExtType::HasZeroInit,
842
843 // Opaque types in the AArch64 name space.
844 if (Name == "aarch64.svcount")
845 return TargetTypeInfo(ScalableVectorType::get(Type::getInt1Ty(C), 16),
847
848 return TargetTypeInfo(Type::getVoidTy(C));
849}
850
852 return getTargetTypeInfo(this).LayoutType;
853}
854
856 uint64_t Properties = getTargetTypeInfo(this).Properties;
857 return (Properties & Prop) == Prop;
858}
This file defines the StringMap class.
This file implements a class to represent arbitrary precision integral constant values and operations...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
return RetTy
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
std::string Name
LLVMContext & Context
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallString class.
static TargetTypeInfo getTargetTypeInfo(const TargetExtType *Ty)
Definition: Type.cpp:834
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
bool isIEEE() const
Definition: APFloat.h:1313
static APFloat getZero(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Zero.
Definition: APFloat.h:957
Class for arbitrary precision integers.
Definition: APInt.h:76
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
Definition: APInt.h:212
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:165
Class to represent array types.
Definition: DerivedTypes.h:371
static bool isValidElementType(Type *ElemTy)
Return true if the specified type is valid as a element type.
Definition: Type.cpp:659
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
Definition: Type.cpp:647
LLVM_ATTRIBUTE_RETURNS_NONNULL void * Allocate(size_t Size, Align Alignment)
Allocate space at the specified alignment.
Definition: Allocator.h:148
This is the shared class of boolean and integer constants.
Definition: Constants.h:79
This is an important base class in LLVM.
Definition: Constant.h:41
static constexpr ElementCount getScalable(ScalarTy MinVal)
Definition: TypeSize.h:299
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition: TypeSize.h:296
Class to represent fixed width SIMD vectors.
Definition: DerivedTypes.h:539
static FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition: Type.cpp:692
Class to represent function types.
Definition: DerivedTypes.h:103
static bool isValidArgumentType(Type *ArgTy)
Return true if the specified type is valid as an argument type.
Definition: Type.cpp:363
static bool isValidReturnType(Type *RetTy)
Return true if the specified type is valid as a return type.
Definition: Type.cpp:358
bool isVarArg() const
Definition: DerivedTypes.h:123
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
Class to represent integer types.
Definition: DerivedTypes.h:40
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition: Type.cpp:278
APInt getMask() const
For example, this is 0xFF for an 8 bit integer, 0xFFFF for i16, etc.
Definition: Type.cpp:302
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
Definition: DerivedTypes.h:72
@ MIN_INT_BITS
Minimum number of bits that can be specified.
Definition: DerivedTypes.h:51
@ MAX_INT_BITS
Maximum number of bits that can be specified.
Definition: DerivedTypes.h:52
StructTypeSet AnonStructTypes
DenseMap< std::pair< Type *, uint64_t >, ArrayType * > ArrayTypes
BumpPtrAllocator Alloc
DenseMap< unsigned, PointerType * > PointerTypes
StringMap< StructType * > NamedStructTypes
PointerType * AS0PointerType
FunctionTypeSet FunctionTypes
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
LLVMContextImpl *const pImpl
Definition: LLVMContext.h:69
Class to represent pointers.
Definition: DerivedTypes.h:646
static bool isLoadableOrStorableType(Type *ElemTy)
Return true if we can load or store from a pointer to this type.
Definition: Type.cpp:770
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
static bool isValidElementType(Type *ElemTy)
Return true if the specified type is valid as a element type.
Definition: Type.cpp:764
Class to represent scalable SIMD vectors.
Definition: DerivedTypes.h:586
static ScalableVectorType * get(Type *ElementType, unsigned MinNumElts)
Definition: Type.cpp:713
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
Definition: SmallPtrSet.h:321
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:342
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:427
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
void resize(size_type N)
Definition: SmallVector.h:651
void push_back(const T &Elt)
Definition: SmallVector.h:426
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:128
void remove(MapEntryTy *KeyValue)
remove - Remove the specified key/value pair from the map, but do not erase it.
Definition: StringMap.h:413
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Class to represent struct types.
Definition: DerivedTypes.h:216
bool indexValid(const Value *V) const
Definition: Type.cpp:618
static 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:373
ArrayRef< Type * > elements() const
Definition: DerivedTypes.h:333
void setBody(ArrayRef< Type * > Elements, bool isPacked=false)
Specify a body for an opaque identified type.
Definition: Type.cpp:445
bool containsHomogeneousScalableVectorTypes() const
Returns true if this struct contains homogeneous scalable vector types.
Definition: Type.cpp:435
static StructType * getTypeByName(LLVMContext &C, StringRef Name)
Return the type with the specified name, or null if there is none by that name.
Definition: Type.cpp:632
static StructType * create(LLVMContext &Context, StringRef Name)
This creates an identified struct.
Definition: Type.cpp:513
bool isPacked() const
Definition: DerivedTypes.h:278
static bool isValidElementType(Type *ElemTy)
Return true if the specified type is valid as a element type.
Definition: Type.cpp:597
unsigned getNumElements() const
Random access to the elements.
Definition: DerivedTypes.h:341
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
isSized - Return true if this is a sized type.
Definition: Type.cpp:552
bool containsScalableVectorType(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Returns true if this struct contains a scalable vector.
Definition: Type.cpp:400
void setName(StringRef Name)
Change the name of this type to the specified name, or to a name with a suffix if there is a collisio...
Definition: Type.cpp:462
bool isLayoutIdentical(StructType *Other) const
Return true if this is layout identical to the specified struct.
Definition: Type.cpp:603
Type * getTypeAtIndex(const Value *V) const
Given an index value into the type, return the type of the element.
Definition: Type.cpp:612
bool isLiteral() const
Return true if this type is uniqued by structural equivalence, false if it is a struct definition.
Definition: DerivedTypes.h:282
bool isOpaque() const
Return true if this is a type with an identity that has no body specified yet.
Definition: DerivedTypes.h:286
Type * getElementType(unsigned N) const
Definition: DerivedTypes.h:342
StringRef getName() const
Return the name for this struct type if it has an identity.
Definition: Type.cpp:590
Symbol info for RuntimeDyld.
Class to represent target extensions types, which are generally unintrospectable from target-independ...
Definition: DerivedTypes.h:720
static TargetExtType * get(LLVMContext &Context, StringRef Name, ArrayRef< Type * > Types=std::nullopt, ArrayRef< unsigned > Ints=std::nullopt)
Return a target extension type having the specified name and optional type and integer parameters.
Definition: Type.cpp:796
bool hasProperty(Property Prop) const
Returns true if the target extension type contains the given property.
Definition: Type.cpp:855
@ HasZeroInit
zeroinitializer is valid for this target extension type.
Definition: DerivedTypes.h:769
@ CanBeGlobal
This type may be used as the value type of a global variable.
Definition: DerivedTypes.h:771
StringRef getName() const
Return the name for this target extension type.
Definition: DerivedTypes.h:741
Type * getLayoutType() const
Returns an underlying layout type for the target extension type.
Definition: Type.cpp:851
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition: TypeSize.h:330
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
static Type * getHalfTy(LLVMContext &C)
static Type * getDoubleTy(LLVMContext &C)
const fltSemantics & getFltSemantics() const
static Type * getFloatingPointTy(LLVMContext &C, const fltSemantics &S)
PointerType * getPointerTo(unsigned AddrSpace=0) const
Return a pointer to the current type.
static Type * getX86_FP80Ty(LLVMContext &C)
bool isLabelTy() const
Return true if this is 'label'.
Definition: Type.h:219
static Type * getBFloatTy(LLVMContext &C)
bool isPointerTy() const
True if this is an instance of PointerType.
Definition: Type.h:255
static IntegerType * getInt1Ty(LLVMContext &C)
bool isEmptyTy() const
Return true if this type is empty, that is, it has no elements or all of its elements are empty.
static Type * getX86_AMXTy(LLVMContext &C)
static Type * getMetadataTy(LLVMContext &C)
TypeID
Definitions of all of the base types for the Type system.
Definition: Type.h:54
@ X86_MMXTyID
MMX vectors (64 bits, X86 specific)
Definition: Type.h:66
@ X86_AMXTyID
AMX vectors (8192 bits, X86 specific)
Definition: Type.h:67
@ TypedPointerTyID
Typed pointer used by some GPU targets.
Definition: Type.h:78
@ HalfTyID
16-bit floating point type
Definition: Type.h:56
@ VoidTyID
type with no size
Definition: Type.h:63
@ ScalableVectorTyID
Scalable SIMD vector type.
Definition: Type.h:77
@ LabelTyID
Labels.
Definition: Type.h:64
@ FloatTyID
32-bit floating point type
Definition: Type.h:58
@ IntegerTyID
Arbitrary bit width integers.
Definition: Type.h:71
@ FixedVectorTyID
Fixed width SIMD vector type.
Definition: Type.h:76
@ BFloatTyID
16-bit floating point type (7-bit significand)
Definition: Type.h:57
@ DoubleTyID
64-bit floating point type
Definition: Type.h:59
@ X86_FP80TyID
80-bit floating point type (X87)
Definition: Type.h:60
@ PPC_FP128TyID
128-bit floating point type (two 64-bits, PowerPC)
Definition: Type.h:62
@ MetadataTyID
Metadata.
Definition: Type.h:65
@ TokenTyID
Tokens.
Definition: Type.h:68
@ FP128TyID
128-bit floating point type (112-bit significand)
Definition: Type.h:61
bool isX86_MMXTy() const
Return true if this is X86 MMX.
Definition: Type.h:201
unsigned NumContainedTys
Keeps track of how many Type*'s there are in the ContainedTys list.
Definition: Type.h:107
static Type * getX86_MMXTy(LLVMContext &C)
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
static Type * getVoidTy(LLVMContext &C)
static Type * getLabelTy(LLVMContext &C)
bool isScalableTargetExtTy() const
Return true if this is a target extension type with a scalable layout.
bool isFirstClassType() const
Return true if the type is "first class", meaning it is a valid type for a Value.
Definition: Type.h:281
static Type * getFP128Ty(LLVMContext &C)
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
Definition: Type.h:302
static IntegerType * getInt16Ty(LLVMContext &C)
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition: Type.h:129
static Type * getPrimitiveType(LLVMContext &C, TypeID IDNumber)
Return a type based on an identifier.
int getFPMantissaWidth() const
Return the width of the mantissa of this type.
Type *const * ContainedTys
A pointer to the array of Types contained by this Type.
Definition: Type.h:114
unsigned getSubclassData() const
Definition: Type.h:98
static IntegerType * getInt8Ty(LLVMContext &C)
bool isIEEE() const
Return whether the type is IEEE compatible, as defined by the eponymous method in APFloat.
static IntegerType * getInt128Ty(LLVMContext &C)
void setSubclassData(unsigned val)
Definition: Type.h:100
static Type * getTokenTy(LLVMContext &C)
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
Definition: Type.h:185
bool isX86_AMXTy() const
Return true if this is X86 AMX.
Definition: Type.h:204
bool isFunctionTy() const
True if this is an instance of FunctionType.
Definition: Type.h:246
bool isScalableTy() const
Return true if this is a type whose size is a known multiple of vscale.
bool canLosslesslyBitCastTo(Type *Ty) const
Return true if this type could be converted with a lossless BitCast to type 'Ty'.
static IntegerType * getInt32Ty(LLVMContext &C)
static IntegerType * getInt64Ty(LLVMContext &C)
static Type * getFloatTy(LLVMContext &C)
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition: Type.h:228
TypeID getTypeID() const
Return the type id for the type.
Definition: Type.h:137
static Type * getWasm_FuncrefTy(LLVMContext &C)
bool isTokenTy() const
Return true if this is 'token'.
Definition: Type.h:225
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
static Type * getPPC_FP128Ty(LLVMContext &C)
static Type * getWasm_ExternrefTy(LLVMContext &C)
bool isVoidTy() const
Return true if this is 'void'.
Definition: Type.h:140
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition: Type.h:348
bool isMetadataTy() const
Return true if this is 'metadata'.
Definition: Type.h:222
LLVM Value Representation.
Definition: Value.h:74
Base class of all SIMD vector types.
Definition: DerivedTypes.h:403
static bool isValidElementType(Type *ElemTy)
Return true if the specified type is valid as a element type.
Definition: Type.cpp:683
VectorType(Type *ElType, unsigned EQ, Type::TypeID TID)
Definition: Type.cpp:669
static VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
Definition: Type.cpp:676
std::pair< iterator, bool > insert_as(const ValueT &V, const LookupKeyT &LookupKey)
Alternative version of insert that uses a different (and possibly less expensive) key type.
Definition: DenseSet.h:219
constexpr ScalarTy getFixedValue() const
Definition: TypeSize.h:187
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition: TypeSize.h:171
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:690
StringRef str() const
Return a StringRef for the vector contents.
Definition: raw_ostream.h:715
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Key
PAL metadata keys.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
constexpr size_t NameSize
Definition: XCOFF.h:29
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
AddressSpace
Definition: NVPTXBaseInfo.h:21
@ Other
Any other memory.
#define N
#define EQ(a, b)
Definition: regexec.c:112
static const fltSemantics & IEEEsingle() LLVM_READNONE
Definition: APFloat.cpp:249
static const fltSemantics & PPCDoubleDouble() LLVM_READNONE
Definition: APFloat.cpp:252
static const fltSemantics & x87DoubleExtended() LLVM_READNONE
Definition: APFloat.cpp:263
static const fltSemantics & IEEEquad() LLVM_READNONE
Definition: APFloat.cpp:251
static const fltSemantics & IEEEdouble() LLVM_READNONE
Definition: APFloat.cpp:250
static const fltSemantics & IEEEhalf() LLVM_READNONE
Definition: APFloat.cpp:247
static const fltSemantics & BFloat() LLVM_READNONE
Definition: APFloat.cpp:248