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