xref: /freebsd/contrib/llvm-project/clang/lib/CodeGen/ABIInfo.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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:
ABIInfo(CodeGen::CodeGenTypes & cgt)54   ABIInfo(CodeGen::CodeGenTypes &cgt)
55       : CGT(cgt), RuntimeCC(llvm::CallingConv::C) {}
56 
57   virtual ~ABIInfo();
58 
allowBFloatArgsAndRet()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.
getRuntimeCC()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, unsigned AddrSpace, bool ByVal = true,
114                           bool Realign = false,
115                           llvm::Type *Padding = nullptr) const;
116 
117   CodeGen::ABIArgInfo getNaturalAlignIndirectInReg(QualType Ty,
118                                                    bool Realign = false) const;
119 
120   virtual void appendAttributeMangling(TargetAttr *Attr,
121                                        raw_ostream &Out) const;
122   virtual void appendAttributeMangling(TargetVersionAttr *Attr,
123                                        raw_ostream &Out) const;
124   virtual void appendAttributeMangling(TargetClonesAttr *Attr, unsigned Index,
125                                        raw_ostream &Out) const;
126   virtual void appendAttributeMangling(StringRef AttrStr,
127                                        raw_ostream &Out) const;
128 
129   /// Returns the optimal vector memory type based on the given vector type. For
130   /// example, on certain targets, a vector with 3 elements might be promoted to
131   /// one with 4 elements to improve performance.
132   virtual llvm::FixedVectorType *
133   getOptimalVectorMemoryType(llvm::FixedVectorType *T,
134                              const LangOptions &Opt) const;
135 };
136 
137 /// Target specific hooks for defining how a type should be passed or returned
138 /// from functions with one of the Swift calling conventions.
139 class SwiftABIInfo {
140 protected:
141   CodeGenTypes &CGT;
142   bool SwiftErrorInRegister;
143 
144   bool occupiesMoreThan(ArrayRef<llvm::Type *> scalarTypes,
145                         unsigned maxAllRegisters) const;
146 
147 public:
SwiftABIInfo(CodeGen::CodeGenTypes & CGT,bool SwiftErrorInRegister)148   SwiftABIInfo(CodeGen::CodeGenTypes &CGT, bool SwiftErrorInRegister)
149       : CGT(CGT), SwiftErrorInRegister(SwiftErrorInRegister) {}
150 
151   virtual ~SwiftABIInfo();
152 
153   /// Returns true if an aggregate which expands to the given type sequence
154   /// should be passed / returned indirectly.
155   virtual bool shouldPassIndirectly(ArrayRef<llvm::Type *> ComponentTys,
156                                     bool AsReturnValue) const;
157 
158   /// Returns true if the given vector type is legal from Swift's calling
159   /// convention perspective.
160   virtual bool isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy,
161                                  unsigned NumElts) const;
162 
163   /// Returns true if swifterror is lowered to a register by the target ABI.
isSwiftErrorInRegister()164   bool isSwiftErrorInRegister() const { return SwiftErrorInRegister; };
165 };
166 } // end namespace CodeGen
167 } // end namespace clang
168 
169 #endif
170