SwiftCallingConv.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //==-- SwiftCallingConv.h - Swift ABI lowering ------------------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // Defines constants and types related to Swift ABI lowering. The same ABI
  15. // lowering applies to both sync and async functions.
  16. //
  17. //===----------------------------------------------------------------------===//
  18. #ifndef LLVM_CLANG_CODEGEN_SWIFTCALLINGCONV_H
  19. #define LLVM_CLANG_CODEGEN_SWIFTCALLINGCONV_H
  20. #include "clang/AST/CanonicalType.h"
  21. #include "clang/AST/CharUnits.h"
  22. #include "clang/AST/Type.h"
  23. #include "llvm/Support/TrailingObjects.h"
  24. #include <cassert>
  25. namespace llvm {
  26. class IntegerType;
  27. class Type;
  28. class StructType;
  29. class VectorType;
  30. }
  31. namespace clang {
  32. class FieldDecl;
  33. class ASTRecordLayout;
  34. namespace CodeGen {
  35. class ABIArgInfo;
  36. class CodeGenModule;
  37. class CGFunctionInfo;
  38. namespace swiftcall {
  39. class SwiftAggLowering {
  40. CodeGenModule &CGM;
  41. struct StorageEntry {
  42. CharUnits Begin;
  43. CharUnits End;
  44. llvm::Type *Type;
  45. CharUnits getWidth() const {
  46. return End - Begin;
  47. }
  48. };
  49. SmallVector<StorageEntry, 4> Entries;
  50. bool Finished = false;
  51. public:
  52. SwiftAggLowering(CodeGenModule &CGM) : CGM(CGM) {}
  53. void addOpaqueData(CharUnits begin, CharUnits end) {
  54. addEntry(nullptr, begin, end);
  55. }
  56. void addTypedData(QualType type, CharUnits begin);
  57. void addTypedData(const RecordDecl *record, CharUnits begin);
  58. void addTypedData(const RecordDecl *record, CharUnits begin,
  59. const ASTRecordLayout &layout);
  60. void addTypedData(llvm::Type *type, CharUnits begin);
  61. void addTypedData(llvm::Type *type, CharUnits begin, CharUnits end);
  62. void finish();
  63. /// Does this lowering require passing any data?
  64. bool empty() const {
  65. assert(Finished && "didn't finish lowering before calling empty()");
  66. return Entries.empty();
  67. }
  68. /// According to the target Swift ABI, should a value with this lowering
  69. /// be passed indirectly?
  70. ///
  71. /// Note that this decision is based purely on the data layout of the
  72. /// value and does not consider whether the type is address-only,
  73. /// must be passed indirectly to match a function abstraction pattern, or
  74. /// anything else that is expected to be handled by high-level lowering.
  75. ///
  76. /// \param asReturnValue - if true, answer whether it should be passed
  77. /// indirectly as a return value; if false, answer whether it should be
  78. /// passed indirectly as an argument
  79. bool shouldPassIndirectly(bool asReturnValue) const;
  80. using EnumerationCallback =
  81. llvm::function_ref<void(CharUnits offset, CharUnits end, llvm::Type *type)>;
  82. /// Enumerate the expanded components of this type.
  83. ///
  84. /// The component types will always be legal vector, floating-point,
  85. /// integer, or pointer types.
  86. void enumerateComponents(EnumerationCallback callback) const;
  87. /// Return the types for a coerce-and-expand operation.
  88. ///
  89. /// The first type matches the memory layout of the data that's been
  90. /// added to this structure, including explicit [N x i8] arrays for any
  91. /// internal padding.
  92. ///
  93. /// The second type removes any internal padding members and, if only
  94. /// one element remains, is simply that element type.
  95. std::pair<llvm::StructType*, llvm::Type*> getCoerceAndExpandTypes() const;
  96. private:
  97. void addBitFieldData(const FieldDecl *field, CharUnits begin,
  98. uint64_t bitOffset);
  99. void addLegalTypedData(llvm::Type *type, CharUnits begin, CharUnits end);
  100. void addEntry(llvm::Type *type, CharUnits begin, CharUnits end);
  101. void splitVectorEntry(unsigned index);
  102. static bool shouldMergeEntries(const StorageEntry &first,
  103. const StorageEntry &second,
  104. CharUnits chunkSize);
  105. };
  106. /// Should an aggregate which expands to the given type sequence
  107. /// be passed/returned indirectly under swiftcall?
  108. bool shouldPassIndirectly(CodeGenModule &CGM,
  109. ArrayRef<llvm::Type*> types,
  110. bool asReturnValue);
  111. /// Return the maximum voluntary integer size for the current target.
  112. CharUnits getMaximumVoluntaryIntegerSize(CodeGenModule &CGM);
  113. /// Return the Swift CC's notion of the natural alignment of a type.
  114. CharUnits getNaturalAlignment(CodeGenModule &CGM, llvm::Type *type);
  115. /// Is the given integer type "legal" for Swift's perspective on the
  116. /// current platform?
  117. bool isLegalIntegerType(CodeGenModule &CGM, llvm::IntegerType *type);
  118. /// Is the given vector type "legal" for Swift's perspective on the
  119. /// current platform?
  120. bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
  121. llvm::VectorType *vectorTy);
  122. bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
  123. llvm::Type *eltTy, unsigned numElts);
  124. /// Minimally split a legal vector type.
  125. std::pair<llvm::Type*, unsigned>
  126. splitLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
  127. llvm::VectorType *vectorTy);
  128. /// Turn a vector type in a sequence of legal component vector types.
  129. ///
  130. /// The caller may assume that the sum of the data sizes of the resulting
  131. /// types will equal the data size of the vector type.
  132. void legalizeVectorType(CodeGenModule &CGM, CharUnits vectorSize,
  133. llvm::VectorType *vectorTy,
  134. llvm::SmallVectorImpl<llvm::Type*> &types);
  135. /// Is the given record type required to be passed and returned indirectly
  136. /// because of language restrictions?
  137. ///
  138. /// This considers *only* mandatory indirectness due to language restrictions,
  139. /// such as C++'s non-trivially-copyable types and Objective-C's __weak
  140. /// references. A record for which this returns true may still be passed
  141. /// indirectly for other reasons, such as being too large to fit in a
  142. /// reasonable number of registers.
  143. bool mustPassRecordIndirectly(CodeGenModule &CGM, const RecordDecl *record);
  144. /// Classify the rules for how to return a particular type.
  145. ABIArgInfo classifyReturnType(CodeGenModule &CGM, CanQualType type);
  146. /// Classify the rules for how to pass a particular type.
  147. ABIArgInfo classifyArgumentType(CodeGenModule &CGM, CanQualType type);
  148. /// Compute the ABI information of a swiftcall function. This is a
  149. /// private interface for Clang.
  150. void computeABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI);
  151. /// Is swifterror lowered to a register by the target ABI?
  152. bool isSwiftErrorLoweredInRegister(CodeGenModule &CGM);
  153. } // end namespace swiftcall
  154. } // end namespace CodeGen
  155. } // end namespace clang
  156. #endif
  157. #ifdef __GNUC__
  158. #pragma GCC diagnostic pop
  159. #endif