123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //==-- SwiftCallingConv.h - Swift ABI lowering ------------------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // Defines constants and types related to Swift ABI lowering. The same ABI
- // lowering applies to both sync and async functions.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_CLANG_CODEGEN_SWIFTCALLINGCONV_H
- #define LLVM_CLANG_CODEGEN_SWIFTCALLINGCONV_H
- #include "clang/AST/CanonicalType.h"
- #include "clang/AST/CharUnits.h"
- #include "clang/AST/Type.h"
- #include "llvm/Support/TrailingObjects.h"
- #include <cassert>
- namespace llvm {
- class IntegerType;
- class Type;
- class StructType;
- class VectorType;
- }
- namespace clang {
- class FieldDecl;
- class ASTRecordLayout;
- namespace CodeGen {
- class ABIArgInfo;
- class CodeGenModule;
- class CGFunctionInfo;
- namespace swiftcall {
- class SwiftAggLowering {
- CodeGenModule &CGM;
- struct StorageEntry {
- CharUnits Begin;
- CharUnits End;
- llvm::Type *Type;
- CharUnits getWidth() const {
- return End - Begin;
- }
- };
- SmallVector<StorageEntry, 4> Entries;
- bool Finished = false;
- public:
- SwiftAggLowering(CodeGenModule &CGM) : CGM(CGM) {}
- void addOpaqueData(CharUnits begin, CharUnits end) {
- addEntry(nullptr, begin, end);
- }
- void addTypedData(QualType type, CharUnits begin);
- void addTypedData(const RecordDecl *record, CharUnits begin);
- void addTypedData(const RecordDecl *record, CharUnits begin,
- const ASTRecordLayout &layout);
- void addTypedData(llvm::Type *type, CharUnits begin);
- void addTypedData(llvm::Type *type, CharUnits begin, CharUnits end);
- void finish();
- /// Does this lowering require passing any data?
- bool empty() const {
- assert(Finished && "didn't finish lowering before calling empty()");
- return Entries.empty();
- }
- /// According to the target Swift ABI, should a value with this lowering
- /// be passed indirectly?
- ///
- /// Note that this decision is based purely on the data layout of the
- /// value and does not consider whether the type is address-only,
- /// must be passed indirectly to match a function abstraction pattern, or
- /// anything else that is expected to be handled by high-level lowering.
- ///
- /// \param asReturnValue - if true, answer whether it should be passed
- /// indirectly as a return value; if false, answer whether it should be
- /// passed indirectly as an argument
- bool shouldPassIndirectly(bool asReturnValue) const;
- using EnumerationCallback =
- llvm::function_ref<void(CharUnits offset, CharUnits end, llvm::Type *type)>;
- /// Enumerate the expanded components of this type.
- ///
- /// The component types will always be legal vector, floating-point,
- /// integer, or pointer types.
- void enumerateComponents(EnumerationCallback callback) const;
- /// Return the types for a coerce-and-expand operation.
- ///
- /// The first type matches the memory layout of the data that's been
- /// added to this structure, including explicit [N x i8] arrays for any
- /// internal padding.
- ///
- /// The second type removes any internal padding members and, if only
- /// one element remains, is simply that element type.
- std::pair<llvm::StructType*, llvm::Type*> getCoerceAndExpandTypes() const;
- private:
- void addBitFieldData(const FieldDecl *field, CharUnits begin,
- uint64_t bitOffset);
- void addLegalTypedData(llvm::Type *type, CharUnits begin, CharUnits end);
- void addEntry(llvm::Type *type, CharUnits begin, CharUnits end);
- void splitVectorEntry(unsigned index);
- static bool shouldMergeEntries(const StorageEntry &first,
- const StorageEntry &second,
- CharUnits chunkSize);
- };
- /// Should an aggregate which expands to the given type sequence
- /// be passed/returned indirectly under swiftcall?
- bool shouldPassIndirectly(CodeGenModule &CGM,
- ArrayRef<llvm::Type*> types,
- bool asReturnValue);
- /// Return the maximum voluntary integer size for the current target.
- CharUnits getMaximumVoluntaryIntegerSize(CodeGenModule &CGM);
- /// Return the Swift CC's notion of the natural alignment of a type.
- CharUnits getNaturalAlignment(CodeGenModule &CGM, llvm::Type *type);
- /// Is the given integer type "legal" for Swift's perspective on the
- /// current platform?
- bool isLegalIntegerType(CodeGenModule &CGM, llvm::IntegerType *type);
- /// Is the given vector type "legal" for Swift's perspective on the
- /// current platform?
- bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
- llvm::VectorType *vectorTy);
- bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
- llvm::Type *eltTy, unsigned numElts);
- /// Minimally split a legal vector type.
- std::pair<llvm::Type*, unsigned>
- splitLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
- llvm::VectorType *vectorTy);
- /// Turn a vector type in a sequence of legal component vector types.
- ///
- /// The caller may assume that the sum of the data sizes of the resulting
- /// types will equal the data size of the vector type.
- void legalizeVectorType(CodeGenModule &CGM, CharUnits vectorSize,
- llvm::VectorType *vectorTy,
- llvm::SmallVectorImpl<llvm::Type*> &types);
- /// Is the given record type required to be passed and returned indirectly
- /// because of language restrictions?
- ///
- /// This considers *only* mandatory indirectness due to language restrictions,
- /// such as C++'s non-trivially-copyable types and Objective-C's __weak
- /// references. A record for which this returns true may still be passed
- /// indirectly for other reasons, such as being too large to fit in a
- /// reasonable number of registers.
- bool mustPassRecordIndirectly(CodeGenModule &CGM, const RecordDecl *record);
- /// Classify the rules for how to return a particular type.
- ABIArgInfo classifyReturnType(CodeGenModule &CGM, CanQualType type);
- /// Classify the rules for how to pass a particular type.
- ABIArgInfo classifyArgumentType(CodeGenModule &CGM, CanQualType type);
- /// Compute the ABI information of a swiftcall function. This is a
- /// private interface for Clang.
- void computeABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI);
- /// Is swifterror lowered to a register by the target ABI?
- bool isSwiftErrorLoweredInRegister(CodeGenModule &CGM);
- } // end namespace swiftcall
- } // end namespace CodeGen
- } // end namespace clang
- #endif
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|