Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

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