;
20using namespaceCodeGen;
21using namespaceswiftcall;
32staticllvm::Type *
getCommonType(llvm::Type *first, llvm::Type *second) {
33assert(first != second);
36 if(first->isIntegerTy()) {
37 if(second->isPointerTy())
returnfirst;
38}
else if(first->isPointerTy()) {
39 if(second->isIntegerTy())
returnsecond;
40 if(second->isPointerTy())
returnfirst;
44}
else if(
autofirstVecTy = dyn_cast<llvm::VectorType>(first)) {
45 if(
autosecondVecTy = dyn_cast<llvm::VectorType>(second)) {
46 if(
autocommonTy =
getCommonType(firstVecTy->getElementType(),
47secondVecTy->getElementType())) {
48 return(commonTy == firstVecTy->getElementType() ? first : second);
72}
else if(
type->isArrayType()) {
80 for(uint64_t i = 0, e =
arrayType->getZExtSize(); i != e; ++i) {
90 addTypedData(eltLLVMType, begin + eltSize, begin + 2 * eltSize);
106 autoatomicPadding = atomicSize - valueSize;
127 for(
auto*field : record->
fields()) {
128 if(field->isBitField()) {
129addBitFieldData(field, begin, 0);
142 autocxxRecord = dyn_cast<CXXRecordDecl>(record);
150 for(
auto&baseSpecifier : cxxRecord->bases()) {
151 if(baseSpecifier.isVirtual())
continue;
153 autobaseRecord = baseSpecifier.getType()->getAsCXXRecordDecl();
164 for(
auto*field : record->
fields()) {
165 autofieldOffsetInBits = layout.
getFieldOffset(field->getFieldIndex());
166 if(field->isBitField()) {
167addBitFieldData(field, begin, fieldOffsetInBits);
177 for(
auto&vbaseSpecifier : cxxRecord->vbases()) {
178 autobaseRecord = vbaseSpecifier.getType()->getAsCXXRecordDecl();
184voidSwiftAggLowering::addBitFieldData(
const FieldDecl*bitfield,
186uint64_t bitfieldBitBegin) {
192 if(width == 0)
return;
195 CharUnitsbitfieldByteBegin = ctx.toCharUnitsFromBits(bitfieldBitBegin);
200uint64_t bitfieldBitLast = bitfieldBitBegin + width - 1;
204recordBegin + bitfieldByteEnd);
208assert(
type&&
"didn't provide type for typed data");
214assert(
type&&
"didn't provide type for typed data");
218 if(
autovecTy = dyn_cast<llvm::VectorType>(
type)) {
221assert(componentTys.size() >= 1);
224 for(
size_ti = 0, e = componentTys.size(); i != e - 1; ++i) {
225llvm::Type *componentTy = componentTys[i];
227assert(componentSize < end - begin);
228addLegalTypedData(componentTy, begin, begin + componentSize);
229begin += componentSize;
232 returnaddLegalTypedData(componentTys.back(), begin, end);
236 if(
autointTy = dyn_cast<llvm::IntegerType>(
type)) {
242 returnaddLegalTypedData(
type, begin, end);
245voidSwiftAggLowering::addLegalTypedData(llvm::Type *
type,
251 if(
autovecTy = dyn_cast<llvm::VectorType>(
type)) {
253 autoeltTy = split.first;
254 autonumElts = split.second;
256 autoeltSize = (end - begin) / numElts;
258 for(
size_ti = 0, e = numElts; i != e; ++i) {
259addLegalTypedData(eltTy, begin, begin + eltSize);
262assert(begin == end);
269addEntry(
type, begin, end);
272voidSwiftAggLowering::addEntry(llvm::Type *
type,
275(!isa<llvm::StructType>(
type) && !isa<llvm::ArrayType>(
type))) &&
276 "cannot add aggregate-typed data");
280 if(Entries.empty() || Entries.back().End <= begin) {
281Entries.push_back({begin, end,
type});
287 size_tindex = Entries.size() - 1;
289 if(Entries[index - 1].End <= begin)
break;
295 if(Entries[index].
Begin>= end) {
299Entries.insert(Entries.begin() + index, {begin, end, type});
308 if(Entries[index].
Begin== begin && Entries[index].End == end) {
310 if(Entries[index].
Type==
type)
return;
313 if(Entries[index].
Type==
nullptr) {
315}
else if(
type==
nullptr) {
316Entries[index].Type =
nullptr;
323Entries[index].Type = entryType;
328Entries[index].Type =
nullptr;
335 if(
autovecTy = dyn_cast_or_null<llvm::VectorType>(
type)) {
336 autoeltTy = vecTy->getElementType();
338(end - begin) / cast<llvm::FixedVectorType>(vecTy)->getNumElements();
340 for(
unsignedi = 0,
341e = cast<llvm::FixedVectorType>(vecTy)->getNumElements();
343addEntry(eltTy, begin, begin + eltSize);
346assert(begin == end);
351 if(Entries[index].
Type&& Entries[index].
Type->isVectorTy()) {
352splitVectorEntry(index);
353 gotorestartAfterSplit;
358Entries[index].Type =
nullptr;
361 if(begin < Entries[index].
Begin) {
362Entries[index].Begin = begin;
363assert(index == 0 || begin >= Entries[index - 1].End);
368 while(end > Entries[index].End) {
369assert(Entries[index].
Type==
nullptr);
372 if(index == Entries.size() - 1 || end <= Entries[index + 1].Begin) {
373Entries[index].End = end;
378Entries[index].End = Entries[index + 1].Begin;
384 if(Entries[index].
Type==
nullptr)
388 if(Entries[index].
Type->isVectorTy() &&
389end < Entries[index].End) {
390splitVectorEntry(index);
394Entries[index].Type =
nullptr;
400voidSwiftAggLowering::splitVectorEntry(
unsignedindex) {
401 autovecTy = cast<llvm::VectorType>(Entries[index].
Type);
404 autoeltTy = split.first;
406 autonumElts = split.second;
407Entries.insert(Entries.begin() + index + 1, numElts - 1, StorageEntry());
410 for(
unsignedi = 0; i != numElts; ++i) {
411 unsignedidx = index + i;
412Entries[idx].Type = eltTy;
413Entries[idx].Begin = begin;
414Entries[idx].End = begin + eltSize;
437 if(
type==
nullptr)
return true;
452 return(!
type->isFloatingPointTy() && !
type->isVectorTy());
455boolSwiftAggLowering::shouldMergeEntries(
constStorageEntry &first,
456 constStorageEntry &second,
470 if(Entries.empty()) {
482 boolhasOpaqueEntries = (Entries[0].Type ==
nullptr);
483 for(
size_ti = 1, e = Entries.size(); i != e; ++i) {
484 if(shouldMergeEntries(Entries[i - 1], Entries[i], chunkSize)) {
485Entries[i - 1].Type =
nullptr;
486Entries[i].Type =
nullptr;
487Entries[i - 1].End = Entries[i].Begin;
488hasOpaqueEntries =
true;
490}
else if(Entries[i].
Type==
nullptr) {
491hasOpaqueEntries =
true;
497 if(!hasOpaqueEntries) {
503 autoorig = std::move(Entries);
504assert(Entries.empty());
506 for(
size_ti = 0, e = orig.size(); i != e; ++i) {
508 if(orig[i].
Type!=
nullptr) {
509Entries.push_back(orig[i]);
516 autobegin = orig[i].Begin;
517 autoend = orig[i].End;
519orig[i + 1].
Type==
nullptr&&
520end == orig[i + 1].
Begin) {
521end = orig[i + 1].End;
532 CharUnitschunkEnd = chunkBegin + chunkSize;
533 CharUnitslocalEnd = std::min(end, chunkEnd);
538 for(; ; unitSize *= 2) {
539assert(unitSize <= chunkSize);
541unitEnd = unitBegin + unitSize;
542 if(unitEnd >= localEnd)
break;
549Entries.push_back({unitBegin, unitEnd, entryTy});
553}
while(begin != end);
561assert(Finished &&
"haven't yet finished lowering");
563 for(
auto&entry : Entries) {
564callback(entry.Begin, entry.End, entry.Type);
568std::pair<llvm::StructType*, llvm::Type*>
570assert(Finished &&
"haven't yet finished lowering");
574 if(Entries.empty()) {
575 auto type= llvm::StructType::get(ctx);
581 boolhasPadding =
false;
582 boolpacked =
false;
583 for(
auto&entry : Entries) {
584 if(entry.Begin != lastEnd) {
585 autopaddingSize = entry.Begin - lastEnd;
586assert(!paddingSize.isNegative());
588 autopadding = llvm::ArrayType::get(llvm::Type::getInt8Ty(ctx),
589paddingSize.getQuantity());
590elts.push_back(padding);
598elts.push_back(entry.Type);
601assert(entry.End <= lastEnd);
606 autocoercionType = llvm::StructType::get(ctx, elts, packed);
608llvm::Type *unpaddedType = coercionType;
611 for(
auto&entry : Entries) {
612elts.push_back(entry.Type);
614 if(elts.size() == 1) {
615unpaddedType = elts[0];
617unpaddedType = llvm::StructType::get(ctx, elts,
false);
619}
else if(Entries.size() == 1) {
620unpaddedType = Entries[0].Type;
623 return{ coercionType, unpaddedType };
627assert(Finished &&
"haven't yet finished lowering");
630 if(Entries.empty())
return false;
633 if(Entries.size() == 1) {
639componentTys.reserve(Entries.size());
640 for(
auto&entry : Entries) {
641componentTys.push_back(entry.Type);
648 boolasReturnValue) {
662size = llvm::bit_ceil(size);
668llvm::IntegerType *intTy) {
669 autosize = intTy->getBitWidth();
688llvm::VectorType *vectorTy) {
690CGM, vectorSize, vectorTy->getElementType(),
691cast<llvm::FixedVectorType>(vectorTy)->getNumElements());
695llvm::Type *eltTy,
unsignednumElts) {
696assert(numElts > 1 &&
"illegal vector length");
700std::pair<llvm::Type*, unsigned>
702llvm::VectorType *vectorTy) {
703 autonumElts = cast<llvm::FixedVectorType>(vectorTy)->getNumElements();
704 autoeltTy = vectorTy->getElementType();
709 return{llvm::FixedVectorType::get(eltTy, numElts / 2), 2};
712 return{eltTy, numElts};
716llvm::VectorType *origVectorTy,
720components.push_back(origVectorTy);
725 autonumElts = cast<llvm::FixedVectorType>(origVectorTy)->getNumElements();
726 autoeltTy = origVectorTy->getElementType();
727assert(numElts != 1);
731 unsignedlogCandidateNumElts = llvm::Log2_32(numElts);
732 unsignedcandidateNumElts = 1U << logCandidateNumElts;
733assert(candidateNumElts <= numElts && candidateNumElts * 2 > numElts);
736 if(candidateNumElts == numElts) {
737logCandidateNumElts--;
738candidateNumElts >>= 1;
741 CharUnitseltSize = (origVectorSize / numElts);
742 CharUnitscandidateSize = eltSize * candidateNumElts;
747 while(logCandidateNumElts > 0) {
748assert(candidateNumElts == 1U << logCandidateNumElts);
749assert(candidateNumElts <= numElts);
750assert(candidateSize == eltSize * candidateNumElts);
754logCandidateNumElts--;
755candidateNumElts /= 2;
761 autonumVecs = numElts >> logCandidateNumElts;
762components.append(numVecs,
763llvm::FixedVectorType::get(eltTy, candidateNumElts));
764numElts -= (numVecs << logCandidateNumElts);
766 if(numElts == 0)
return;
773components.push_back(llvm::FixedVectorType::get(eltTy, numElts));
779logCandidateNumElts--;
780candidateNumElts /= 2;
782}
while(candidateNumElts > numElts);
786components.append(numElts, eltTy);
800 if(lowering.
empty()) {
828 if(isa<ComplexType>(
type)) {
833 if(isa<VectorType>(
type)) {
847 if(
type->isVoidType()) {
868 for(
unsignedi = 0, e = FI.
arg_size(); i != e; ++i) {
static ABIArgInfo classifyType(CodeGenModule &CGM, CanQualType type, bool forReturn)
static llvm::Type * getCommonType(llvm::Type *first, llvm::Type *second)
Given two types with the same size, try to find a common type.
static CharUnits getOffsetAtStartOfUnit(CharUnits offset, CharUnits unitSize)
Given a power-of-two unit size, return the offset of the aligned unit of that size which contains the...
static CharUnits getTypeAllocSize(CodeGenModule &CGM, llvm::Type *type)
static bool isPowerOf2(unsigned n)
static ABIArgInfo classifyExpandedType(SwiftAggLowering &lowering, bool forReturn, CharUnits alignmentForIndirect)
static CharUnits getTypeStoreSize(CodeGenModule &CGM, llvm::Type *type)
static bool areBytesInSameUnit(CharUnits first, CharUnits second, CharUnits chunkSize)
static const SwiftABIInfo & getSwiftABIInfo(CodeGenModule &CGM)
static bool isMergeableEntryType(llvm::Type *type)
const ConstantArrayType * getAsConstantArrayType(QualType T) const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
bool hasOwnVFPtr() const
hasOwnVFPtr - Does this class provide its own virtual-function table pointer, rather than inheriting ...
bool hasOwnVBPtr() const
hasOwnVBPtr - Does this class provide its own virtual-base table pointer, rather than inheriting one ...
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getVBPtrOffset() const
getVBPtrOffset - Get the offset for virtual base table pointer.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits - This is an opaque type for sizes expressed in character units.
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
bool isMultipleOf(CharUnits N) const
Test whether this is a multiple of the other value.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
ABIArgInfo - Helper class to encapsulate information about how a specific C type should be passed to ...
static ABIArgInfo getIgnore()
static ABIArgInfo getExpand()
static ABIArgInfo getIndirect(CharUnits Alignment, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr)
static ABIArgInfo getDirect(llvm::Type *T=nullptr, unsigned Offset=0, llvm::Type *Padding=nullptr, bool CanBeFlattened=true, unsigned Align=0)
static ABIArgInfo getCoerceAndExpand(llvm::StructType *coerceToType, llvm::Type *unpaddedCoerceToType)
CGFunctionInfo - Class to encapsulate the information about a function definition.
ABIArgInfo & getReturnInfo()
const_arg_iterator arg_begin() const
CanQualType getReturnType() const
unsigned arg_size() const
This class organizes the cross-function state that is used while generating LLVM code.
CodeGenTypes & getTypes()
const llvm::DataLayout & getDataLayout() const
ASTContext & getContext() const
const TargetCodeGenInfo & getTargetCodeGenInfo()
llvm::LLVMContext & getLLVMContext()
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
Target specific hooks for defining how a type should be passed or returned from functions with one of...
virtual bool isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy, unsigned NumElts) const
Returns true if the given vector type is legal from Swift's calling convention perspective.
bool isSwiftErrorInRegister() const
Returns true if swifterror is lowered to a register by the target ABI.
virtual bool shouldPassIndirectly(ArrayRef< llvm::Type * > ComponentTys, bool AsReturnValue) const
Returns true if an aggregate which expands to the given type sequence should be passed / returned ind...
const SwiftABIInfo & getSwiftABIInfo() const
Returns Swift ABI info helper for the target.
void addOpaqueData(CharUnits begin, CharUnits end)
std::pair< llvm::StructType *, llvm::Type * > getCoerceAndExpandTypes() const
Return the types for a coerce-and-expand operation.
void enumerateComponents(EnumerationCallback callback) const
Enumerate the expanded components of this type.
llvm::function_ref< void(CharUnits offset, CharUnits end, llvm::Type *type)> EnumerationCallback
bool empty() const
Does this lowering require passing any data?
void addTypedData(QualType type, CharUnits begin)
bool shouldPassIndirectly(bool asReturnValue) const
According to the target Swift ABI, should a value with this lowering be passed indirectly?
Complex values, per C99 6.2.5p11.
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getBitWidthValue() const
Computes the bit width of this field, if this is a bit field.
A pointer to member type per C++ 8.3.3 - Pointers to members.
A (possibly-)qualified type.
Represents a struct/union/class.
bool canPassInRegisters() const
Determine whether this class can be passed in registers.
field_range fields() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
virtual bool hasInt128Type() const
Determine whether the __int128 type is supported on this target.
The base class of the type hierarchy.
Defines the clang::TargetInfo interface.
bool isSwiftErrorLoweredInRegister(CodeGenModule &CGM)
Is swifterror lowered to a register by the target ABI?
bool shouldPassIndirectly(CodeGenModule &CGM, ArrayRef< llvm::Type * > types, bool asReturnValue)
Should an aggregate which expands to the given type sequence be passed/returned indirectly under swif...
ABIArgInfo classifyReturnType(CodeGenModule &CGM, CanQualType type)
Classify the rules for how to return a particular type.
bool mustPassRecordIndirectly(CodeGenModule &CGM, const RecordDecl *record)
Is the given record type required to be passed and returned indirectly because of language restrictio...
ABIArgInfo classifyArgumentType(CodeGenModule &CGM, CanQualType type)
Classify the rules for how to pass a particular type.
bool isLegalIntegerType(CodeGenModule &CGM, llvm::IntegerType *type)
Is the given integer type "legal" for Swift's perspective on the current platform?
void legalizeVectorType(CodeGenModule &CGM, CharUnits vectorSize, llvm::VectorType *vectorTy, llvm::SmallVectorImpl< llvm::Type * > &types)
Turn a vector type in a sequence of legal component vector types.
void computeABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI)
Compute the ABI information of a swiftcall function.
bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize, llvm::VectorType *vectorTy)
Is the given vector type "legal" for Swift's perspective on the current platform?
std::pair< llvm::Type *, unsigned > splitLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize, llvm::VectorType *vectorTy)
Minimally split a legal vector type.
CharUnits getNaturalAlignment(CodeGenModule &CGM, llvm::Type *type)
Return the Swift CC's notion of the natural alignment of a type.
CharUnits getMaximumVoluntaryIntegerSize(CodeGenModule &CGM)
Return the maximum voluntary integer size for the current target.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< ArrayType > arrayType
Matches all kinds of arrays.
const AstTypeMatcher< AtomicType > atomicType
Matches atomic types.
const AstTypeMatcher< RecordType > recordType
Matches record types (e.g.
const AstTypeMatcher< ComplexType > complexType
Matches C99 complex types.
The JSON file list parser is used to communicate input to InstallAPI.
llvm::PointerType * Int8PtrTy
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4