xref: /llvm-project/clang/lib/CodeGen/ABIInfo.h (revision 03744d2aaffee04bc1e4d0668c41556c3c20d406)
1 //===----- ABIInfo.h - ABI information access & encapsulation ---*- 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 #ifndef LLVM_CLANG_LIB_CODEGEN_ABIINFO_H
10 #define LLVM_CLANG_LIB_CODEGEN_ABIINFO_H
11 
12 #include "clang/AST/Attr.h"
13 #include "clang/AST/CharUnits.h"
14 #include "clang/AST/Type.h"
15 #include "llvm/IR/CallingConv.h"
16 #include "llvm/IR/Type.h"
17 
18 namespace llvm {
19 class Value;
20 class LLVMContext;
21 class DataLayout;
22 class Type;
23 class FixedVectorType;
24 } // namespace llvm
25 
26 namespace clang {
27 class ASTContext;
28 class CodeGenOptions;
29 class TargetInfo;
30 
31 namespace CodeGen {
32 class ABIArgInfo;
33 class Address;
34 class CGCXXABI;
35 class CGFunctionInfo;
36 class CodeGenFunction;
37 class CodeGenTypes;
38 class RValue;
39 class AggValueSlot;
40 
41 // FIXME: All of this stuff should be part of the target interface
42 // somehow. It is currently here because it is not clear how to factor
43 // the targets to support this, since the Targets currently live in a
44 // layer below types n'stuff.
45 
46 /// ABIInfo - Target specific hooks for defining how a type should be
47 /// passed or returned from functions.
48 class ABIInfo {
49 protected:
50   CodeGen::CodeGenTypes &CGT;
51   llvm::CallingConv::ID RuntimeCC;
52 
53 public:
54   ABIInfo(CodeGen::CodeGenTypes &cgt)
55       : CGT(cgt), RuntimeCC(llvm::CallingConv::C) {}
56 
57   virtual ~ABIInfo();
58 
59   virtual bool allowBFloatArgsAndRet() const { return false; }
60 
61   CodeGen::CGCXXABI &getCXXABI() const;
62   ASTContext &getContext() const;
63   llvm::LLVMContext &getVMContext() const;
64   const llvm::DataLayout &getDataLayout() const;
65   const TargetInfo &getTarget() const;
66   const CodeGenOptions &getCodeGenOpts() const;
67 
68   /// Return the calling convention to use for system runtime
69   /// functions.
70   llvm::CallingConv::ID getRuntimeCC() const { return RuntimeCC; }
71 
72   virtual void computeInfo(CodeGen::CGFunctionInfo &FI) const = 0;
73 
74   /// EmitVAArg - Emit the target dependent code to load a value of
75   /// \arg Ty from the va_list pointed to by \arg VAListAddr.
76 
77   // FIXME: This is a gaping layering violation if we wanted to drop
78   // the ABI information any lower than CodeGen. Of course, for
79   // VAArg handling it has to be at this level; there is no way to
80   // abstract this out.
81   virtual RValue EmitVAArg(CodeGen::CodeGenFunction &CGF,
82                            CodeGen::Address VAListAddr, QualType Ty,
83                            AggValueSlot Slot) const = 0;
84 
85   bool isAndroid() const;
86   bool isOHOSFamily() const;
87 
88   /// Emit the target dependent code to load a value of
89   /// \arg Ty from the \c __builtin_ms_va_list pointed to by \arg VAListAddr.
90   virtual RValue EmitMSVAArg(CodeGen::CodeGenFunction &CGF,
91                              CodeGen::Address VAListAddr, QualType Ty,
92                              AggValueSlot Slot) const;
93 
94   virtual bool isHomogeneousAggregateBaseType(QualType Ty) const;
95 
96   virtual bool isHomogeneousAggregateSmallEnough(const Type *Base,
97                                                  uint64_t Members) const;
98   virtual bool isZeroLengthBitfieldPermittedInHomogeneousAggregate() const;
99 
100   /// isHomogeneousAggregate - Return true if a type is an ELFv2 homogeneous
101   /// aggregate.  Base is set to the base element type, and Members is set
102   /// to the number of base elements.
103   bool isHomogeneousAggregate(QualType Ty, const Type *&Base,
104                               uint64_t &Members) const;
105 
106   // Implement the Type::IsPromotableIntegerType for ABI specific needs. The
107   // only difference is that this considers bit-precise integer types as well.
108   bool isPromotableIntegerTypeForABI(QualType Ty) const;
109 
110   /// A convenience method to return an indirect ABIArgInfo with an
111   /// expected alignment equal to the ABI alignment of the given type.
112   CodeGen::ABIArgInfo
113   getNaturalAlignIndirect(QualType Ty, bool ByVal = true, bool Realign = false,
114                           llvm::Type *Padding = nullptr) const;
115 
116   CodeGen::ABIArgInfo getNaturalAlignIndirectInReg(QualType Ty,
117                                                    bool Realign = false) const;
118 
119   virtual void appendAttributeMangling(TargetAttr *Attr,
120                                        raw_ostream &Out) const;
121   virtual void appendAttributeMangling(TargetVersionAttr *Attr,
122                                        raw_ostream &Out) const;
123   virtual void appendAttributeMangling(TargetClonesAttr *Attr, unsigned Index,
124                                        raw_ostream &Out) const;
125   virtual void appendAttributeMangling(StringRef AttrStr,
126                                        raw_ostream &Out) const;
127 
128   /// Returns the optimal vector memory type based on the given vector type. For
129   /// example, on certain targets, a vector with 3 elements might be promoted to
130   /// one with 4 elements to improve performance.
131   virtual llvm::FixedVectorType *
132   getOptimalVectorMemoryType(llvm::FixedVectorType *T,
133                              const LangOptions &Opt) const;
134 };
135 
136 /// Target specific hooks for defining how a type should be passed or returned
137 /// from functions with one of the Swift calling conventions.
138 class SwiftABIInfo {
139 protected:
140   CodeGenTypes &CGT;
141   bool SwiftErrorInRegister;
142 
143   bool occupiesMoreThan(ArrayRef<llvm::Type *> scalarTypes,
144                         unsigned maxAllRegisters) const;
145 
146 public:
147   SwiftABIInfo(CodeGen::CodeGenTypes &CGT, bool SwiftErrorInRegister)
148       : CGT(CGT), SwiftErrorInRegister(SwiftErrorInRegister) {}
149 
150   virtual ~SwiftABIInfo();
151 
152   /// Returns true if an aggregate which expands to the given type sequence
153   /// should be passed / returned indirectly.
154   virtual bool shouldPassIndirectly(ArrayRef<llvm::Type *> ComponentTys,
155                                     bool AsReturnValue) const;
156 
157   /// Returns true if the given vector type is legal from Swift's calling
158   /// convention perspective.
159   virtual bool isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy,
160                                  unsigned NumElts) const;
161 
162   /// Returns true if swifterror is lowered to a register by the target ABI.
163   bool isSwiftErrorInRegister() const { return SwiftErrorInRegister; };
164 };
165 } // end namespace CodeGen
166 } // end namespace clang
167 
168 #endif
169