forked from OSchip/llvm-project
[clang][CodeGen] Factor out Swift ABI hooks (NFCI)
Swift calling conventions stands out in the way that they are lowered in mostly target-independent manner, with very few customization points. As such, swift-related methods of ABIInfo do not reference the rest of ABIInfo and vice versa. This change follows interface segregation principle; it removes dependency of SwiftABIInfo on ABIInfo. Targets must now implement SwiftABIInfo separately if they support Swift calling conventions. Almost all targets implemented `shouldPassIndirectly` the same way. This de-facto default implementation has been moved into the base class. `isSwiftErrorInRegister` used to be virtual, now it is not. It didn't accept any arguments which could have an effect on the returned value. This is now a static property of the target ABI. Reviewed By: rusyaev-roman, inclyc Differential Revision: https://reviews.llvm.org/D130394
This commit is contained in:
parent
dbff03b858
commit
87dc7d4b61
|
@ -33,7 +33,6 @@ namespace CodeGen {
|
|||
class CGFunctionInfo;
|
||||
class CodeGenFunction;
|
||||
class CodeGenTypes;
|
||||
class SwiftABIInfo;
|
||||
|
||||
// FIXME: All of this stuff should be part of the target interface
|
||||
// somehow. It is currently here because it is not clear how to factor
|
||||
|
@ -44,9 +43,8 @@ namespace CodeGen {
|
|||
/// ABIInfo - Target specific hooks for defining how a type should be
|
||||
/// passed or returned from functions.
|
||||
class ABIInfo {
|
||||
public:
|
||||
CodeGen::CodeGenTypes &CGT;
|
||||
protected:
|
||||
CodeGen::CodeGenTypes &CGT;
|
||||
llvm::CallingConv::ID RuntimeCC;
|
||||
public:
|
||||
ABIInfo(CodeGen::CodeGenTypes &cgt)
|
||||
|
@ -54,8 +52,6 @@ namespace CodeGen {
|
|||
|
||||
virtual ~ABIInfo();
|
||||
|
||||
virtual bool supportsSwift() const { return false; }
|
||||
|
||||
virtual bool allowBFloatArgsAndRet() const { return false; }
|
||||
|
||||
CodeGen::CGCXXABI &getCXXABI() const;
|
||||
|
@ -114,33 +110,33 @@ namespace CodeGen {
|
|||
|
||||
CodeGen::ABIArgInfo
|
||||
getNaturalAlignIndirectInReg(QualType Ty, bool Realign = false) const;
|
||||
|
||||
|
||||
};
|
||||
|
||||
/// A refining implementation of ABIInfo for targets that support swiftcall.
|
||||
///
|
||||
/// If we find ourselves wanting multiple such refinements, they'll probably
|
||||
/// be independent refinements, and we should probably find another way
|
||||
/// to do it than simple inheritance.
|
||||
class SwiftABIInfo : public ABIInfo {
|
||||
/// Target specific hooks for defining how a type should be passed or returned
|
||||
/// from functions with one of the Swift calling conventions.
|
||||
class SwiftABIInfo {
|
||||
protected:
|
||||
CodeGenTypes &CGT;
|
||||
bool SwiftErrorInRegister;
|
||||
|
||||
public:
|
||||
SwiftABIInfo(CodeGen::CodeGenTypes &cgt) : ABIInfo(cgt) {}
|
||||
SwiftABIInfo(CodeGen::CodeGenTypes &CGT, bool SwiftErrorInRegister)
|
||||
: CGT(CGT), SwiftErrorInRegister(SwiftErrorInRegister) {}
|
||||
|
||||
bool supportsSwift() const final { return true; }
|
||||
virtual ~SwiftABIInfo();
|
||||
|
||||
virtual bool shouldPassIndirectlyForSwift(ArrayRef<llvm::Type*> types,
|
||||
bool asReturnValue) const = 0;
|
||||
/// Returns true if an aggregate which expands to the given type sequence
|
||||
/// should be passed / returned indirectly.
|
||||
virtual bool shouldPassIndirectly(ArrayRef<llvm::Type *> ComponentTys,
|
||||
bool AsReturnValue) const;
|
||||
|
||||
virtual bool isLegalVectorTypeForSwift(CharUnits totalSize,
|
||||
llvm::Type *eltTy,
|
||||
unsigned elts) const;
|
||||
/// Returns true if the given vector type is legal from Swift's calling
|
||||
/// convention perspective.
|
||||
virtual bool isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy,
|
||||
unsigned NumElts) const;
|
||||
|
||||
virtual bool isSwiftErrorInRegister() const = 0;
|
||||
|
||||
static bool classof(const ABIInfo *info) {
|
||||
return info->supportsSwift();
|
||||
}
|
||||
/// Returns true if swifterror is lowered to a register by the target ABI.
|
||||
bool isSwiftErrorInRegister() const { return SwiftErrorInRegister; };
|
||||
};
|
||||
} // end namespace CodeGen
|
||||
} // end namespace clang
|
||||
|
|
|
@ -21,7 +21,7 @@ using namespace CodeGen;
|
|||
using namespace swiftcall;
|
||||
|
||||
static const SwiftABIInfo &getSwiftABIInfo(CodeGenModule &CGM) {
|
||||
return cast<SwiftABIInfo>(CGM.getTargetCodeGenInfo().getABIInfo());
|
||||
return CGM.getTargetCodeGenInfo().getSwiftABIInfo();
|
||||
}
|
||||
|
||||
static bool isPowerOf2(unsigned n) {
|
||||
|
@ -631,9 +631,8 @@ bool SwiftAggLowering::shouldPassIndirectly(bool asReturnValue) const {
|
|||
|
||||
// Avoid copying the array of types when there's just a single element.
|
||||
if (Entries.size() == 1) {
|
||||
return getSwiftABIInfo(CGM).shouldPassIndirectlyForSwift(
|
||||
Entries.back().Type,
|
||||
asReturnValue);
|
||||
return getSwiftABIInfo(CGM).shouldPassIndirectly(Entries.back().Type,
|
||||
asReturnValue);
|
||||
}
|
||||
|
||||
SmallVector<llvm::Type*, 8> componentTys;
|
||||
|
@ -641,15 +640,13 @@ bool SwiftAggLowering::shouldPassIndirectly(bool asReturnValue) const {
|
|||
for (auto &entry : Entries) {
|
||||
componentTys.push_back(entry.Type);
|
||||
}
|
||||
return getSwiftABIInfo(CGM).shouldPassIndirectlyForSwift(componentTys,
|
||||
asReturnValue);
|
||||
return getSwiftABIInfo(CGM).shouldPassIndirectly(componentTys, asReturnValue);
|
||||
}
|
||||
|
||||
bool swiftcall::shouldPassIndirectly(CodeGenModule &CGM,
|
||||
ArrayRef<llvm::Type*> componentTys,
|
||||
bool asReturnValue) {
|
||||
return getSwiftABIInfo(CGM).shouldPassIndirectlyForSwift(componentTys,
|
||||
asReturnValue);
|
||||
return getSwiftABIInfo(CGM).shouldPassIndirectly(componentTys, asReturnValue);
|
||||
}
|
||||
|
||||
CharUnits swiftcall::getMaximumVoluntaryIntegerSize(CodeGenModule &CGM) {
|
||||
|
@ -699,8 +696,7 @@ bool swiftcall::isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
|
|||
bool swiftcall::isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
|
||||
llvm::Type *eltTy, unsigned numElts) {
|
||||
assert(numElts > 1 && "illegal vector length");
|
||||
return getSwiftABIInfo(CGM)
|
||||
.isLegalVectorTypeForSwift(vectorSize, eltTy, numElts);
|
||||
return getSwiftABIInfo(CGM).isLegalVectorType(vectorSize, eltTy, numElts);
|
||||
}
|
||||
|
||||
std::pair<llvm::Type*, unsigned>
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include "clang/Basic/CodeGenOptions.h"
|
||||
#include "clang/Basic/DiagnosticFrontend.h"
|
||||
#include "clang/CodeGen/CGFunctionInfo.h"
|
||||
#include "clang/CodeGen/SwiftCallingConv.h"
|
||||
#include "llvm/ADT/SmallBitVector.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
|
@ -117,7 +116,9 @@ bool ABIInfo::isPromotableIntegerTypeForABI(QualType Ty) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
ABIInfo::~ABIInfo() {}
|
||||
ABIInfo::~ABIInfo() = default;
|
||||
|
||||
SwiftABIInfo::~SwiftABIInfo() = default;
|
||||
|
||||
/// Does the given lowering require more than the given number of
|
||||
/// registers when expanded?
|
||||
|
@ -151,12 +152,16 @@ static bool occupiesMoreThan(CodeGenTypes &cgt,
|
|||
return (intCount + fpCount > maxAllRegisters);
|
||||
}
|
||||
|
||||
bool SwiftABIInfo::isLegalVectorTypeForSwift(CharUnits vectorSize,
|
||||
llvm::Type *eltTy,
|
||||
unsigned numElts) const {
|
||||
bool SwiftABIInfo::shouldPassIndirectly(ArrayRef<llvm::Type *> ComponentTys,
|
||||
bool AsReturnValue) const {
|
||||
return occupiesMoreThan(CGT, ComponentTys, /*total=*/4);
|
||||
}
|
||||
|
||||
bool SwiftABIInfo::isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy,
|
||||
unsigned NumElts) const {
|
||||
// The default implementation of this assumes that the target guarantees
|
||||
// 128-bit SIMD support but nothing more.
|
||||
return (vectorSize.getQuantity() > 8 && vectorSize.getQuantity() <= 16);
|
||||
return (VectorSize.getQuantity() > 8 && VectorSize.getQuantity() <= 16);
|
||||
}
|
||||
|
||||
static CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT,
|
||||
|
@ -814,7 +819,7 @@ ABIArgInfo DefaultABIInfo::classifyReturnType(QualType RetTy) const {
|
|||
// This is a very simple ABI that relies a lot on DefaultABIInfo.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class WebAssemblyABIInfo final : public SwiftABIInfo {
|
||||
class WebAssemblyABIInfo final : public ABIInfo {
|
||||
public:
|
||||
enum ABIKind {
|
||||
MVP = 0,
|
||||
|
@ -827,7 +832,7 @@ private:
|
|||
|
||||
public:
|
||||
explicit WebAssemblyABIInfo(CodeGen::CodeGenTypes &CGT, ABIKind Kind)
|
||||
: SwiftABIInfo(CGT), defaultInfo(CGT), Kind(Kind) {}
|
||||
: ABIInfo(CGT), defaultInfo(CGT), Kind(Kind) {}
|
||||
|
||||
private:
|
||||
ABIArgInfo classifyReturnType(QualType RetTy) const;
|
||||
|
@ -845,22 +850,16 @@ private:
|
|||
|
||||
Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
|
||||
QualType Ty) const override;
|
||||
|
||||
bool shouldPassIndirectlyForSwift(ArrayRef<llvm::Type*> scalars,
|
||||
bool asReturnValue) const override {
|
||||
return occupiesMoreThan(CGT, scalars, /*total*/ 4);
|
||||
}
|
||||
|
||||
bool isSwiftErrorInRegister() const override {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class WebAssemblyTargetCodeGenInfo final : public TargetCodeGenInfo {
|
||||
public:
|
||||
explicit WebAssemblyTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT,
|
||||
WebAssemblyABIInfo::ABIKind K)
|
||||
: TargetCodeGenInfo(std::make_unique<WebAssemblyABIInfo>(CGT, K)) {}
|
||||
: TargetCodeGenInfo(std::make_unique<WebAssemblyABIInfo>(CGT, K)) {
|
||||
SwiftInfo =
|
||||
std::make_unique<SwiftABIInfo>(CGT, /*SwiftErrorInRegister=*/false);
|
||||
}
|
||||
|
||||
void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
|
||||
CodeGen::CodeGenModule &CGM) const override {
|
||||
|
@ -1136,7 +1135,7 @@ struct CCState {
|
|||
};
|
||||
|
||||
/// X86_32ABIInfo - The X86-32 ABI information.
|
||||
class X86_32ABIInfo : public SwiftABIInfo {
|
||||
class X86_32ABIInfo : public ABIInfo {
|
||||
enum Class {
|
||||
Integer,
|
||||
Float
|
||||
|
@ -1210,26 +1209,27 @@ public:
|
|||
X86_32ABIInfo(CodeGen::CodeGenTypes &CGT, bool DarwinVectorABI,
|
||||
bool RetSmallStructInRegABI, bool Win32StructABI,
|
||||
unsigned NumRegisterParameters, bool SoftFloatABI)
|
||||
: SwiftABIInfo(CGT), IsDarwinVectorABI(DarwinVectorABI),
|
||||
IsRetSmallStructInRegABI(RetSmallStructInRegABI),
|
||||
IsWin32StructABI(Win32StructABI), IsSoftFloatABI(SoftFloatABI),
|
||||
IsMCUABI(CGT.getTarget().getTriple().isOSIAMCU()),
|
||||
IsLinuxABI(CGT.getTarget().getTriple().isOSLinux() ||
|
||||
CGT.getTarget().getTriple().isOSCygMing()),
|
||||
DefaultNumRegisterParameters(NumRegisterParameters) {}
|
||||
: ABIInfo(CGT), IsDarwinVectorABI(DarwinVectorABI),
|
||||
IsRetSmallStructInRegABI(RetSmallStructInRegABI),
|
||||
IsWin32StructABI(Win32StructABI), IsSoftFloatABI(SoftFloatABI),
|
||||
IsMCUABI(CGT.getTarget().getTriple().isOSIAMCU()),
|
||||
IsLinuxABI(CGT.getTarget().getTriple().isOSLinux() ||
|
||||
CGT.getTarget().getTriple().isOSCygMing()),
|
||||
DefaultNumRegisterParameters(NumRegisterParameters) {}
|
||||
};
|
||||
|
||||
bool shouldPassIndirectlyForSwift(ArrayRef<llvm::Type*> scalars,
|
||||
bool asReturnValue) const override {
|
||||
class X86_32SwiftABIInfo : public SwiftABIInfo {
|
||||
public:
|
||||
explicit X86_32SwiftABIInfo(CodeGenTypes &CGT)
|
||||
: SwiftABIInfo(CGT, /*SwiftErrorInRegister=*/false) {}
|
||||
|
||||
bool shouldPassIndirectly(ArrayRef<llvm::Type *> ComponentTys,
|
||||
bool AsReturnValue) const override {
|
||||
// LLVM's x86-32 lowering currently only assigns up to three
|
||||
// integer registers and three fp registers. Oddly, it'll use up to
|
||||
// four vector registers for vectors, but those can overlap with the
|
||||
// scalar registers.
|
||||
return occupiesMoreThan(CGT, scalars, /*total*/ 3);
|
||||
}
|
||||
|
||||
bool isSwiftErrorInRegister() const override {
|
||||
// x86-32 lowering does not support passing swifterror in a register.
|
||||
return false;
|
||||
return occupiesMoreThan(CGT, ComponentTys, /*total=*/3);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1240,7 +1240,9 @@ public:
|
|||
unsigned NumRegisterParameters, bool SoftFloatABI)
|
||||
: TargetCodeGenInfo(std::make_unique<X86_32ABIInfo>(
|
||||
CGT, DarwinVectorABI, RetSmallStructInRegABI, Win32StructABI,
|
||||
NumRegisterParameters, SoftFloatABI)) {}
|
||||
NumRegisterParameters, SoftFloatABI)) {
|
||||
SwiftInfo = std::make_unique<X86_32SwiftABIInfo>(CGT);
|
||||
}
|
||||
|
||||
static bool isStructReturnInRegABI(
|
||||
const llvm::Triple &Triple, const CodeGenOptions &Opts);
|
||||
|
@ -2250,7 +2252,7 @@ static unsigned getNativeVectorSizeForAVXABI(X86AVXABILevel AVXLevel) {
|
|||
}
|
||||
|
||||
/// X86_64ABIInfo - The X86_64 ABI information.
|
||||
class X86_64ABIInfo : public SwiftABIInfo {
|
||||
class X86_64ABIInfo : public ABIInfo {
|
||||
enum Class {
|
||||
Integer = 0,
|
||||
SSE,
|
||||
|
@ -2396,10 +2398,9 @@ class X86_64ABIInfo : public SwiftABIInfo {
|
|||
bool Has64BitPointers;
|
||||
|
||||
public:
|
||||
X86_64ABIInfo(CodeGen::CodeGenTypes &CGT, X86AVXABILevel AVXLevel) :
|
||||
SwiftABIInfo(CGT), AVXLevel(AVXLevel),
|
||||
Has64BitPointers(CGT.getDataLayout().getPointerSize(0) == 8) {
|
||||
}
|
||||
X86_64ABIInfo(CodeGen::CodeGenTypes &CGT, X86AVXABILevel AVXLevel)
|
||||
: ABIInfo(CGT), AVXLevel(AVXLevel),
|
||||
Has64BitPointers(CGT.getDataLayout().getPointerSize(0) == 8) {}
|
||||
|
||||
bool isPassedUsingAVXType(QualType type) const {
|
||||
unsigned neededInt, neededSSE;
|
||||
|
@ -2424,21 +2425,13 @@ public:
|
|||
bool has64BitPointers() const {
|
||||
return Has64BitPointers;
|
||||
}
|
||||
|
||||
bool shouldPassIndirectlyForSwift(ArrayRef<llvm::Type*> scalars,
|
||||
bool asReturnValue) const override {
|
||||
return occupiesMoreThan(CGT, scalars, /*total*/ 4);
|
||||
}
|
||||
bool isSwiftErrorInRegister() const override {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/// WinX86_64ABIInfo - The Windows X86_64 ABI information.
|
||||
class WinX86_64ABIInfo : public SwiftABIInfo {
|
||||
class WinX86_64ABIInfo : public ABIInfo {
|
||||
public:
|
||||
WinX86_64ABIInfo(CodeGen::CodeGenTypes &CGT, X86AVXABILevel AVXLevel)
|
||||
: SwiftABIInfo(CGT), AVXLevel(AVXLevel),
|
||||
: ABIInfo(CGT), AVXLevel(AVXLevel),
|
||||
IsMingw64(getTarget().getTriple().isWindowsGNUEnvironment()) {}
|
||||
|
||||
void computeInfo(CGFunctionInfo &FI) const override;
|
||||
|
@ -2457,15 +2450,6 @@ public:
|
|||
return isX86VectorCallAggregateSmallEnough(NumMembers);
|
||||
}
|
||||
|
||||
bool shouldPassIndirectlyForSwift(ArrayRef<llvm::Type *> scalars,
|
||||
bool asReturnValue) const override {
|
||||
return occupiesMoreThan(CGT, scalars, /*total*/ 4);
|
||||
}
|
||||
|
||||
bool isSwiftErrorInRegister() const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
ABIArgInfo classify(QualType Ty, unsigned &FreeSSERegs, bool IsReturnType,
|
||||
bool IsVectorCall, bool IsRegCall) const;
|
||||
|
@ -2480,7 +2464,10 @@ private:
|
|||
class X86_64TargetCodeGenInfo : public TargetCodeGenInfo {
|
||||
public:
|
||||
X86_64TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, X86AVXABILevel AVXLevel)
|
||||
: TargetCodeGenInfo(std::make_unique<X86_64ABIInfo>(CGT, AVXLevel)) {}
|
||||
: TargetCodeGenInfo(std::make_unique<X86_64ABIInfo>(CGT, AVXLevel)) {
|
||||
SwiftInfo =
|
||||
std::make_unique<SwiftABIInfo>(CGT, /*SwiftErrorInRegister=*/true);
|
||||
}
|
||||
|
||||
const X86_64ABIInfo &getABIInfo() const {
|
||||
return static_cast<const X86_64ABIInfo&>(TargetCodeGenInfo::getABIInfo());
|
||||
|
@ -2722,7 +2709,10 @@ class WinX86_64TargetCodeGenInfo : public TargetCodeGenInfo {
|
|||
public:
|
||||
WinX86_64TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT,
|
||||
X86AVXABILevel AVXLevel)
|
||||
: TargetCodeGenInfo(std::make_unique<WinX86_64ABIInfo>(CGT, AVXLevel)) {}
|
||||
: TargetCodeGenInfo(std::make_unique<WinX86_64ABIInfo>(CGT, AVXLevel)) {
|
||||
SwiftInfo =
|
||||
std::make_unique<SwiftABIInfo>(CGT, /*SwiftErrorInRegister=*/true);
|
||||
}
|
||||
|
||||
void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
|
||||
CodeGen::CodeGenModule &CGM) const override;
|
||||
|
@ -4984,7 +4974,7 @@ PPC32TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
|
|||
|
||||
namespace {
|
||||
/// PPC64_SVR4_ABIInfo - The 64-bit PowerPC ELF (SVR4) ABI information.
|
||||
class PPC64_SVR4_ABIInfo : public SwiftABIInfo {
|
||||
class PPC64_SVR4_ABIInfo : public ABIInfo {
|
||||
public:
|
||||
enum ABIKind {
|
||||
ELFv1 = 0,
|
||||
|
@ -4999,7 +4989,7 @@ private:
|
|||
public:
|
||||
PPC64_SVR4_ABIInfo(CodeGen::CodeGenTypes &CGT, ABIKind Kind,
|
||||
bool SoftFloatABI)
|
||||
: SwiftABIInfo(CGT), Kind(Kind), IsSoftFloatABI(SoftFloatABI) {}
|
||||
: ABIInfo(CGT), Kind(Kind), IsSoftFloatABI(SoftFloatABI) {}
|
||||
|
||||
bool isPromotableTypeForABI(QualType Ty) const;
|
||||
CharUnits getParamTypeAlignment(QualType Ty) const;
|
||||
|
@ -5040,15 +5030,6 @@ public:
|
|||
|
||||
Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
|
||||
QualType Ty) const override;
|
||||
|
||||
bool shouldPassIndirectlyForSwift(ArrayRef<llvm::Type*> scalars,
|
||||
bool asReturnValue) const override {
|
||||
return occupiesMoreThan(CGT, scalars, /*total*/ 4);
|
||||
}
|
||||
|
||||
bool isSwiftErrorInRegister() const override {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class PPC64_SVR4_TargetCodeGenInfo : public TargetCodeGenInfo {
|
||||
|
@ -5058,7 +5039,10 @@ public:
|
|||
PPC64_SVR4_ABIInfo::ABIKind Kind,
|
||||
bool SoftFloatABI)
|
||||
: TargetCodeGenInfo(
|
||||
std::make_unique<PPC64_SVR4_ABIInfo>(CGT, Kind, SoftFloatABI)) {}
|
||||
std::make_unique<PPC64_SVR4_ABIInfo>(CGT, Kind, SoftFloatABI)) {
|
||||
SwiftInfo =
|
||||
std::make_unique<SwiftABIInfo>(CGT, /*SwiftErrorInRegister=*/false);
|
||||
}
|
||||
|
||||
int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override {
|
||||
// This is recovered from gcc output.
|
||||
|
@ -5492,7 +5476,7 @@ PPC64TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
|
|||
|
||||
namespace {
|
||||
|
||||
class AArch64ABIInfo : public SwiftABIInfo {
|
||||
class AArch64ABIInfo : public ABIInfo {
|
||||
public:
|
||||
enum ABIKind {
|
||||
AAPCS = 0,
|
||||
|
@ -5504,8 +5488,7 @@ private:
|
|||
ABIKind Kind;
|
||||
|
||||
public:
|
||||
AArch64ABIInfo(CodeGenTypes &CGT, ABIKind Kind)
|
||||
: SwiftABIInfo(CGT), Kind(Kind) {}
|
||||
AArch64ABIInfo(CodeGenTypes &CGT, ABIKind Kind) : ABIInfo(CGT), Kind(Kind) {}
|
||||
|
||||
private:
|
||||
ABIKind getABIKind() const { return Kind; }
|
||||
|
@ -5553,26 +5536,26 @@ private:
|
|||
Address EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,
|
||||
QualType Ty) const override;
|
||||
|
||||
bool shouldPassIndirectlyForSwift(ArrayRef<llvm::Type*> scalars,
|
||||
bool asReturnValue) const override {
|
||||
return occupiesMoreThan(CGT, scalars, /*total*/ 4);
|
||||
}
|
||||
bool isSwiftErrorInRegister() const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isLegalVectorTypeForSwift(CharUnits totalSize, llvm::Type *eltTy,
|
||||
unsigned elts) const override;
|
||||
|
||||
bool allowBFloatArgsAndRet() const override {
|
||||
return getTarget().hasBFloat16Type();
|
||||
}
|
||||
};
|
||||
|
||||
class AArch64SwiftABIInfo : public SwiftABIInfo {
|
||||
public:
|
||||
explicit AArch64SwiftABIInfo(CodeGenTypes &CGT)
|
||||
: SwiftABIInfo(CGT, /*SwiftErrorInRegister=*/true) {}
|
||||
|
||||
bool isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy,
|
||||
unsigned NumElts) const override;
|
||||
};
|
||||
|
||||
class AArch64TargetCodeGenInfo : public TargetCodeGenInfo {
|
||||
public:
|
||||
AArch64TargetCodeGenInfo(CodeGenTypes &CGT, AArch64ABIInfo::ABIKind Kind)
|
||||
: TargetCodeGenInfo(std::make_unique<AArch64ABIInfo>(CGT, Kind)) {}
|
||||
: TargetCodeGenInfo(std::make_unique<AArch64ABIInfo>(CGT, Kind)) {
|
||||
SwiftInfo = std::make_unique<AArch64SwiftABIInfo>(CGT);
|
||||
}
|
||||
|
||||
StringRef getARCRetainAutoreleasedReturnValueMarker() const override {
|
||||
return "mov\tfp, fp\t\t// marker for objc_retainAutoreleaseReturnValue";
|
||||
|
@ -5946,13 +5929,13 @@ bool AArch64ABIInfo::isIllegalVectorType(QualType Ty) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool AArch64ABIInfo::isLegalVectorTypeForSwift(CharUnits totalSize,
|
||||
llvm::Type *eltTy,
|
||||
unsigned elts) const {
|
||||
if (!llvm::isPowerOf2_32(elts))
|
||||
bool AArch64SwiftABIInfo::isLegalVectorType(CharUnits VectorSize,
|
||||
llvm::Type *EltTy,
|
||||
unsigned NumElts) const {
|
||||
if (!llvm::isPowerOf2_32(NumElts))
|
||||
return false;
|
||||
if (totalSize.getQuantity() != 8 &&
|
||||
(totalSize.getQuantity() != 16 || elts == 1))
|
||||
if (VectorSize.getQuantity() != 8 &&
|
||||
(VectorSize.getQuantity() != 16 || NumElts == 1))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
@ -6290,7 +6273,7 @@ Address AArch64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,
|
|||
|
||||
namespace {
|
||||
|
||||
class ARMABIInfo : public SwiftABIInfo {
|
||||
class ARMABIInfo : public ABIInfo {
|
||||
public:
|
||||
enum ABIKind {
|
||||
APCS = 0,
|
||||
|
@ -6304,8 +6287,7 @@ private:
|
|||
bool IsFloatABISoftFP;
|
||||
|
||||
public:
|
||||
ARMABIInfo(CodeGenTypes &CGT, ABIKind _Kind)
|
||||
: SwiftABIInfo(CGT), Kind(_Kind) {
|
||||
ARMABIInfo(CodeGenTypes &CGT, ABIKind Kind) : ABIInfo(CGT), Kind(Kind) {
|
||||
setCCs();
|
||||
IsFloatABISoftFP = CGT.getCodeGenOpts().FloatABI == "softfp" ||
|
||||
CGT.getCodeGenOpts().FloatABI == ""; // default
|
||||
|
@ -6369,22 +6351,23 @@ private:
|
|||
llvm::CallingConv::ID getLLVMDefaultCC() const;
|
||||
llvm::CallingConv::ID getABIDefaultCC() const;
|
||||
void setCCs();
|
||||
};
|
||||
|
||||
bool shouldPassIndirectlyForSwift(ArrayRef<llvm::Type*> scalars,
|
||||
bool asReturnValue) const override {
|
||||
return occupiesMoreThan(CGT, scalars, /*total*/ 4);
|
||||
}
|
||||
bool isSwiftErrorInRegister() const override {
|
||||
return true;
|
||||
}
|
||||
bool isLegalVectorTypeForSwift(CharUnits totalSize, llvm::Type *eltTy,
|
||||
unsigned elts) const override;
|
||||
class ARMSwiftABIInfo : public SwiftABIInfo {
|
||||
public:
|
||||
explicit ARMSwiftABIInfo(CodeGenTypes &CGT)
|
||||
: SwiftABIInfo(CGT, /*SwiftErrorInRegister=*/true) {}
|
||||
|
||||
bool isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy,
|
||||
unsigned NumElts) const override;
|
||||
};
|
||||
|
||||
class ARMTargetCodeGenInfo : public TargetCodeGenInfo {
|
||||
public:
|
||||
ARMTargetCodeGenInfo(CodeGenTypes &CGT, ARMABIInfo::ABIKind K)
|
||||
: TargetCodeGenInfo(std::make_unique<ARMABIInfo>(CGT, K)) {}
|
||||
: TargetCodeGenInfo(std::make_unique<ARMABIInfo>(CGT, K)) {
|
||||
SwiftInfo = std::make_unique<ARMSwiftABIInfo>(CGT);
|
||||
}
|
||||
|
||||
const ARMABIInfo &getABIInfo() const {
|
||||
return static_cast<const ARMABIInfo&>(TargetCodeGenInfo::getABIInfo());
|
||||
|
@ -6986,16 +6969,15 @@ bool ARMABIInfo::containsAnyFP16Vectors(QualType Ty) const {
|
|||
}
|
||||
}
|
||||
|
||||
bool ARMABIInfo::isLegalVectorTypeForSwift(CharUnits vectorSize,
|
||||
llvm::Type *eltTy,
|
||||
unsigned numElts) const {
|
||||
if (!llvm::isPowerOf2_32(numElts))
|
||||
bool ARMSwiftABIInfo::isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy,
|
||||
unsigned NumElts) const {
|
||||
if (!llvm::isPowerOf2_32(NumElts))
|
||||
return false;
|
||||
unsigned size = getDataLayout().getTypeStoreSizeInBits(eltTy);
|
||||
unsigned size = CGT.getDataLayout().getTypeStoreSizeInBits(EltTy);
|
||||
if (size > 64)
|
||||
return false;
|
||||
if (vectorSize.getQuantity() != 8 &&
|
||||
(vectorSize.getQuantity() != 16 || numElts == 1))
|
||||
if (VectorSize.getQuantity() != 8 &&
|
||||
(VectorSize.getQuantity() != 16 || NumElts == 1))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
@ -7380,13 +7362,13 @@ bool NVPTXTargetCodeGenInfo::shouldEmitStaticExternCAliases() const {
|
|||
|
||||
namespace {
|
||||
|
||||
class SystemZABIInfo : public SwiftABIInfo {
|
||||
class SystemZABIInfo : public ABIInfo {
|
||||
bool HasVector;
|
||||
bool IsSoftFloatABI;
|
||||
|
||||
public:
|
||||
SystemZABIInfo(CodeGenTypes &CGT, bool HV, bool SF)
|
||||
: SwiftABIInfo(CGT), HasVector(HV), IsSoftFloatABI(SF) {}
|
||||
: ABIInfo(CGT), HasVector(HV), IsSoftFloatABI(SF) {}
|
||||
|
||||
bool isPromotableIntegerTypeForABI(QualType Ty) const;
|
||||
bool isCompoundType(QualType Ty) const;
|
||||
|
@ -7406,21 +7388,16 @@ public:
|
|||
|
||||
Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
|
||||
QualType Ty) const override;
|
||||
|
||||
bool shouldPassIndirectlyForSwift(ArrayRef<llvm::Type*> scalars,
|
||||
bool asReturnValue) const override {
|
||||
return occupiesMoreThan(CGT, scalars, /*total*/ 4);
|
||||
}
|
||||
bool isSwiftErrorInRegister() const override {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class SystemZTargetCodeGenInfo : public TargetCodeGenInfo {
|
||||
public:
|
||||
SystemZTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector, bool SoftFloatABI)
|
||||
: TargetCodeGenInfo(
|
||||
std::make_unique<SystemZABIInfo>(CGT, HasVector, SoftFloatABI)) {}
|
||||
std::make_unique<SystemZABIInfo>(CGT, HasVector, SoftFloatABI)) {
|
||||
SwiftInfo =
|
||||
std::make_unique<SwiftABIInfo>(CGT, /*SwiftErrorInRegister=*/false);
|
||||
}
|
||||
|
||||
llvm::Value *testFPKind(llvm::Value *V, unsigned BuiltinID,
|
||||
CGBuilderTy &Builder,
|
||||
|
|
|
@ -38,6 +38,7 @@ class ABIInfo;
|
|||
class CallArgList;
|
||||
class CodeGenFunction;
|
||||
class CGBlockInfo;
|
||||
class SwiftABIInfo;
|
||||
|
||||
/// TargetCodeGenInfo - This class organizes various target-specific
|
||||
/// codegeneration issues, like target-specific attributes, builtins and so
|
||||
|
@ -45,6 +46,12 @@ class CGBlockInfo;
|
|||
class TargetCodeGenInfo {
|
||||
std::unique_ptr<ABIInfo> Info;
|
||||
|
||||
protected:
|
||||
// Target hooks supporting Swift calling conventions. The target must
|
||||
// initialize this field if it claims to support these calling conventions
|
||||
// by returning true from TargetInfo::checkCallingConvention for them.
|
||||
std::unique_ptr<SwiftABIInfo> SwiftInfo;
|
||||
|
||||
public:
|
||||
TargetCodeGenInfo(std::unique_ptr<ABIInfo> Info);
|
||||
virtual ~TargetCodeGenInfo();
|
||||
|
@ -52,6 +59,12 @@ public:
|
|||
/// getABIInfo() - Returns ABI info helper for the target.
|
||||
const ABIInfo &getABIInfo() const { return *Info; }
|
||||
|
||||
/// Returns Swift ABI info helper for the target.
|
||||
const SwiftABIInfo &getSwiftABIInfo() const {
|
||||
assert(SwiftInfo && "Swift ABI info has not been initialized");
|
||||
return *SwiftInfo;
|
||||
}
|
||||
|
||||
/// setTargetAttributes - Provides a convenient hook to handle extra
|
||||
/// target-specific attributes for the given global.
|
||||
virtual void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
|
||||
|
|
Loading…
Reference in New Issue