[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:
Sergei Barannikov 2022-08-08 00:21:40 +08:00 committed by YingChi Long
parent dbff03b858
commit 87dc7d4b61
No known key found for this signature in database
GPG Key ID: 7C44FE7AD4EF9C49
4 changed files with 142 additions and 160 deletions

View File

@ -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

View File

@ -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>

View File

@ -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,

View File

@ -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,