Home | History | Annotate | Download | only in CodeGen
      1 //==-- SwiftCallingConv.h - Swift ABI lowering -----------------------------==//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // Defines constants and types related to Swift ABI lowering.
     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 Decl;
     32 class FieldDecl;
     33 class ASTRecordLayout;
     34 
     35 namespace CodeGen {
     36 class ABIArgInfo;
     37 class CodeGenModule;
     38 class CGFunctionInfo;
     39 
     40 namespace swiftcall {
     41 
     42 class SwiftAggLowering {
     43   CodeGenModule &CGM;
     44 
     45   struct StorageEntry {
     46     CharUnits Begin;
     47     CharUnits End;
     48     llvm::Type *Type;
     49 
     50     CharUnits getWidth() const {
     51       return End - Begin;
     52     }
     53   };
     54   SmallVector<StorageEntry, 4> Entries;
     55   bool Finished = false;
     56 
     57 public:
     58   SwiftAggLowering(CodeGenModule &CGM) : CGM(CGM) {}
     59 
     60   void addOpaqueData(CharUnits begin, CharUnits end) {
     61     addEntry(nullptr, begin, end);
     62   }
     63 
     64   void addTypedData(QualType type, CharUnits begin);
     65   void addTypedData(const RecordDecl *record, CharUnits begin);
     66   void addTypedData(const RecordDecl *record, CharUnits begin,
     67                     const ASTRecordLayout &layout);
     68   void addTypedData(llvm::Type *type, CharUnits begin);
     69   void addTypedData(llvm::Type *type, CharUnits begin, CharUnits end);
     70 
     71   void finish();
     72 
     73   /// Does this lowering require passing any data?
     74   bool empty() const {
     75     assert(Finished && "didn't finish lowering before calling empty()");
     76     return Entries.empty();
     77   }
     78 
     79   /// According to the target Swift ABI, should a value with this lowering
     80   /// be passed indirectly?
     81   ///
     82   /// Note that this decision is based purely on the data layout of the
     83   /// value and does not consider whether the type is address-only,
     84   /// must be passed indirectly to match a function abstraction pattern, or
     85   /// anything else that is expected to be handled by high-level lowering.
     86   ///
     87   /// \param asReturnValue - if true, answer whether it should be passed
     88   ///   indirectly as a return value; if false, answer whether it should be
     89   ///   passed indirectly as an argument
     90   bool shouldPassIndirectly(bool asReturnValue) const;
     91 
     92   using EnumerationCallback =
     93     llvm::function_ref<void(CharUnits offset, CharUnits end, llvm::Type *type)>;
     94 
     95   /// Enumerate the expanded components of this type.
     96   ///
     97   /// The component types will always be legal vector, floating-point,
     98   /// integer, or pointer types.
     99   void enumerateComponents(EnumerationCallback callback) const;
    100 
    101   /// Return the types for a coerce-and-expand operation.
    102   ///
    103   /// The first type matches the memory layout of the data that's been
    104   /// added to this structure, including explicit [N x i8] arrays for any
    105   /// internal padding.
    106   ///
    107   /// The second type removes any internal padding members and, if only
    108   /// one element remains, is simply that element type.
    109   std::pair<llvm::StructType*, llvm::Type*> getCoerceAndExpandTypes() const;
    110 
    111 private:
    112   void addBitFieldData(const FieldDecl *field, CharUnits begin,
    113                        uint64_t bitOffset);
    114   void addLegalTypedData(llvm::Type *type, CharUnits begin, CharUnits end);
    115   void addEntry(llvm::Type *type, CharUnits begin, CharUnits end);
    116   void splitVectorEntry(unsigned index);
    117 };
    118 
    119 /// Return the maximum voluntary integer size for the current target.
    120 CharUnits getMaximumVoluntaryIntegerSize(CodeGenModule &CGM);
    121 
    122 /// Return the Swift CC's notion of the natural alignment of a type.
    123 CharUnits getNaturalAlignment(CodeGenModule &CGM, llvm::Type *type);
    124 
    125 /// Is the given integer type "legal" for Swift's perspective on the
    126 /// current platform?
    127 bool isLegalIntegerType(CodeGenModule &CGM, llvm::IntegerType *type);
    128 
    129 /// Is the given vector type "legal" for Swift's perspective on the
    130 /// current platform?
    131 bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
    132                        llvm::VectorType *vectorTy);
    133 bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
    134                        llvm::Type *eltTy, unsigned numElts);
    135 
    136 /// Minimally split a legal vector type.
    137 std::pair<llvm::Type*, unsigned>
    138 splitLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
    139                      llvm::VectorType *vectorTy);
    140 
    141 /// Turn a vector type in a sequence of legal component vector types.
    142 ///
    143 /// The caller may assume that the sum of the data sizes of the resulting
    144 /// types will equal the data size of the vector type.
    145 void legalizeVectorType(CodeGenModule &CGM, CharUnits vectorSize,
    146                         llvm::VectorType *vectorTy,
    147                         llvm::SmallVectorImpl<llvm::Type*> &types);
    148 
    149 /// Should a C++ record type be passed and returned indirectly?
    150 bool shouldPassCXXRecordIndirectly(CodeGenModule &CGM,
    151                                    const CXXRecordDecl *record);
    152 
    153 /// Classify the rules for how to return a particular type.
    154 ABIArgInfo classifyReturnType(CodeGenModule &CGM, CanQualType type);
    155 
    156 /// Classify the rules for how to pass a particular type.
    157 ABIArgInfo classifyArgumentType(CodeGenModule &CGM, CanQualType type);
    158 
    159 /// Compute the ABI information of a swiftcall function.  This is a
    160 /// private interface for Clang.
    161 void computeABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI);
    162 
    163 /// Is swifterror lowered to a register by the target ABI.
    164 bool isSwiftErrorLoweredInRegister(CodeGenModule &CGM);
    165 
    166 } // end namespace swiftcall
    167 } // end namespace CodeGen
    168 } // end namespace clang
    169 
    170 #endif
    171