Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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