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