clang  14.0.0git
SwiftCallingConv.h
Go to the documentation of this file.
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 
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 
43  CodeGenModule &CGM;
44 
45  struct StorageEntry {
47  CharUnits End;
48  llvm::Type *Type;
49 
50  CharUnits getWidth() const {
51  return End - Begin;
52  }
53  };
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  static bool shouldMergeEntries(const StorageEntry &first,
118  const StorageEntry &second,
119  CharUnits chunkSize);
120 };
121 
122 /// Should an aggregate which expands to the given type sequence
123 /// be passed/returned indirectly under swiftcall?
126  bool asReturnValue);
127 
128 /// Return the maximum voluntary integer size for the current target.
130 
131 /// Return the Swift CC's notion of the natural alignment of a type.
133 
134 /// Is the given integer type "legal" for Swift's perspective on the
135 /// current platform?
136 bool isLegalIntegerType(CodeGenModule &CGM, llvm::IntegerType *type);
137 
138 /// Is the given vector type "legal" for Swift's perspective on the
139 /// current platform?
140 bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
141  llvm::VectorType *vectorTy);
142 bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
143  llvm::Type *eltTy, unsigned numElts);
144 
145 /// Minimally split a legal vector type.
146 std::pair<llvm::Type*, unsigned>
148  llvm::VectorType *vectorTy);
149 
150 /// Turn a vector type in a sequence of legal component vector types.
151 ///
152 /// The caller may assume that the sum of the data sizes of the resulting
153 /// types will equal the data size of the vector type.
154 void legalizeVectorType(CodeGenModule &CGM, CharUnits vectorSize,
155  llvm::VectorType *vectorTy,
157 
158 /// Is the given record type required to be passed and returned indirectly
159 /// because of language restrictions?
160 ///
161 /// This considers *only* mandatory indirectness due to language restrictions,
162 /// such as C++'s non-trivially-copyable types and Objective-C's __weak
163 /// references. A record for which this returns true may still be passed
164 /// indirectly for other reasons, such as being too large to fit in a
165 /// reasonable number of registers.
166 bool mustPassRecordIndirectly(CodeGenModule &CGM, const RecordDecl *record);
167 
168 /// Classify the rules for how to return a particular type.
170 
171 /// Classify the rules for how to pass a particular type.
173 
174 /// Compute the ABI information of a swiftcall function. This is a
175 /// private interface for Clang.
177 
178 /// Is swifterror lowered to a register by the target ABI?
180 
181 } // end namespace swiftcall
182 } // end namespace CodeGen
183 } // end namespace clang
184 
185 #endif
llvm
Definition: Dominators.h:30
clang::CodeGen::swiftcall::SwiftAggLowering::empty
bool empty() const
Does this lowering require passing any data?
Definition: SwiftCallingConv.h:74
type
clang::CodeGen::swiftcall::SwiftAggLowering
Definition: SwiftCallingConv.h:42
llvm::SmallVector< StorageEntry, 4 >
clang::QualType
A (possibly-)qualified type.
Definition: Type.h:673
clang::CodeGen::swiftcall::SwiftAggLowering::addOpaqueData
void addOpaqueData(CharUnits begin, CharUnits end)
Definition: SwiftCallingConv.h:60
clang::FieldDecl
Represents a member of a struct/union/class.
Definition: Decl.h:2835
clang::CodeGen::swiftcall::mustPassRecordIndirectly
bool mustPassRecordIndirectly(CodeGenModule &CGM, const RecordDecl *record)
Is the given record type required to be passed and returned indirectly because of language restrictio...
Definition: SwiftCallingConv.cpp:794
End
SourceLocation End
Definition: USRLocFinder.cpp:167
clang::CodeGen::swiftcall::SwiftAggLowering::enumerateComponents
void enumerateComponents(EnumerationCallback callback) const
Enumerate the expanded components of this type.
Definition: SwiftCallingConv.cpp:558
clang::Type
The base class of the type hierarchy.
Definition: Type.h:1490
clang::CodeGen::AlignmentSource::Decl
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
clang::CodeGen::ABIArgInfo
ABIArgInfo - Helper class to encapsulate information about how a specific C type should be passed to ...
Definition: CGFunctionInfo.h:32
clang::CodeGen::swiftcall::classifyReturnType
ABIArgInfo classifyReturnType(CodeGenModule &CGM, CanQualType type)
Classify the rules for how to return a particular type.
Definition: SwiftCallingConv.cpp:860
clang::CodeGen::swiftcall::SwiftAggLowering::EnumerationCallback
llvm::function_ref< void(CharUnits offset, CharUnits end, llvm::Type *type)> EnumerationCallback
Definition: SwiftCallingConv.h:93
clang::CodeGen::swiftcall::SwiftAggLowering::getCoerceAndExpandTypes
std::pair< llvm::StructType *, llvm::Type * > getCoerceAndExpandTypes() const
Return the types for a coerce-and-expand operation.
Definition: SwiftCallingConv.cpp:567
clang::CodeGen::swiftcall::SwiftAggLowering::shouldPassIndirectly
bool shouldPassIndirectly(bool asReturnValue) const
According to the target Swift ABI, should a value with this lowering be passed indirectly?
Definition: SwiftCallingConv.cpp:625
clang::CodeGen::swiftcall::SwiftAggLowering::SwiftAggLowering
SwiftAggLowering(CodeGenModule &CGM)
Definition: SwiftCallingConv.h:58
Type.h
clang::CodeGen::swiftcall::computeABIInfo
void computeABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI)
Compute the ABI information of a swiftcall function.
Definition: SwiftCallingConv.cpp:869
clang::CanQual< Type >
clang::CodeGen::swiftcall::isLegalIntegerType
bool isLegalIntegerType(CodeGenModule &CGM, llvm::IntegerType *type)
Is the given integer type "legal" for Swift's perspective on the current platform?
Definition: SwiftCallingConv.cpp:671
CharUnits.h
clang::CodeGen::swiftcall::isLegalVectorType
bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize, llvm::VectorType *vectorTy)
Is the given vector type "legal" for Swift's perspective on the current platform?
Definition: SwiftCallingConv.cpp:691
clang::CodeGen::swiftcall::getMaximumVoluntaryIntegerSize
CharUnits getMaximumVoluntaryIntegerSize(CodeGenModule &CGM)
Return the maximum voluntary integer size for the current target.
Definition: SwiftCallingConv.cpp:654
clang::ASTRecordLayout
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
Definition: RecordLayout.h:38
clang::CodeGen::swiftcall::SwiftAggLowering::finish
void finish()
Definition: SwiftCallingConv.cpp:467
clang::CodeGen::CodeGenModule
This class organizes the cross-function state that is used while generating LLVM code.
Definition: CodeGenModule.h:284
clang::CodeGen::swiftcall::getNaturalAlignment
CharUnits getNaturalAlignment(CodeGenModule &CGM, llvm::Type *type)
Return the Swift CC's notion of the natural alignment of a type.
Definition: SwiftCallingConv.cpp:660
Begin
SourceLocation Begin
Definition: USRLocFinder.cpp:165
llvm::ArrayRef
Definition: LLVM.h:34
clang::CodeGen::swiftcall::legalizeVectorType
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.
Definition: SwiftCallingConv.cpp:720
clang::CodeGen::CGFunctionInfo
CGFunctionInfo - Class to encapsulate the information about a function definition.
Definition: CGFunctionInfo.h:546
clang::driver::types
Definition: Types.h:22
clang
Definition: CalledOnceCheck.h:17
clang::CodeGen::swiftcall::classifyArgumentType
ABIArgInfo classifyArgumentType(CodeGenModule &CGM, CanQualType type)
Classify the rules for how to pass a particular type.
Definition: SwiftCallingConv.cpp:864
clang::CodeGen::swiftcall::splitLegalVectorType
std::pair< llvm::Type *, unsigned > splitLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize, llvm::VectorType *vectorTy)
Minimally split a legal vector type.
Definition: SwiftCallingConv.cpp:706
clang::CodeGen::swiftcall::SwiftAggLowering::addTypedData
void addTypedData(QualType type, CharUnits begin)
Definition: SwiftCallingConv.cpp:63
clang::CodeGen::swiftcall::shouldPassIndirectly
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...
Definition: SwiftCallingConv.cpp:647
CanonicalType.h
clang::CharUnits
CharUnits - This is an opaque type for sizes expressed in character units.
Definition: CharUnits.h:38
llvm::SmallVectorImpl
Definition: LLVM.h:39
clang::RecordDecl
Represents a struct/union/class.
Definition: Decl.h:3863
clang::CodeGen::swiftcall::isSwiftErrorLoweredInRegister
bool isSwiftErrorLoweredInRegister(CodeGenModule &CGM)
Is swifterror lowered to a register by the target ABI?
Definition: SwiftCallingConv.cpp:880
Type
MatchType Type
Definition: ASTMatchFinder.cpp:70