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