aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/TargetInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/TargetInfo.cpp')
-rw-r--r--lib/CodeGen/TargetInfo.cpp624
1 files changed, 450 insertions, 174 deletions
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp
index 612e72bdd7..f9689affa0 100644
--- a/lib/CodeGen/TargetInfo.cpp
+++ b/lib/CodeGen/TargetInfo.cpp
@@ -14,6 +14,7 @@
#include "TargetInfo.h"
#include "ABIInfo.h"
+#include "CGCXXABI.h"
#include "CodeGenFunction.h"
#include "clang/AST/RecordLayout.h"
#include "clang/Frontend/CodeGenOptions.h"
@@ -43,6 +44,37 @@ static bool isAggregateTypeForABI(QualType T) {
ABIInfo::~ABIInfo() {}
+static bool isRecordReturnIndirect(const RecordType *RT, CodeGen::CodeGenTypes &CGT) {
+ const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
+ if (!RD)
+ return false;
+ return CGT.CGM.getCXXABI().isReturnTypeIndirect(RD);
+}
+
+
+static bool isRecordReturnIndirect(QualType T, CodeGen::CodeGenTypes &CGT) {
+ const RecordType *RT = T->getAs<RecordType>();
+ if (!RT)
+ return false;
+ return isRecordReturnIndirect(RT, CGT);
+}
+
+static CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT,
+ CodeGen::CodeGenTypes &CGT) {
+ const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
+ if (!RD)
+ return CGCXXABI::RAA_Default;
+ return CGT.CGM.getCXXABI().getRecordArgABI(RD);
+}
+
+static CGCXXABI::RecordArgABI getRecordArgABI(QualType T,
+ CodeGen::CodeGenTypes &CGT) {
+ const RecordType *RT = T->getAs<RecordType>();
+ if (!RT)
+ return CGCXXABI::RAA_Default;
+ return getRecordArgABI(RT, CGT);
+}
+
ASTContext &ABIInfo::getContext() const {
return CGT.getContext();
}
@@ -55,6 +87,9 @@ const llvm::DataLayout &ABIInfo::getDataLayout() const {
return CGT.getDataLayout();
}
+const TargetInfo &ABIInfo::getTarget() const {
+ return CGT.getTarget();
+}
void ABIArgInfo::dump() const {
raw_ostream &OS = llvm::errs();
@@ -167,27 +202,6 @@ static bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays) {
return true;
}
-/// hasNonTrivialDestructorOrCopyConstructor - Determine if a type has either
-/// a non-trivial destructor or a non-trivial copy constructor.
-static bool hasNonTrivialDestructorOrCopyConstructor(const RecordType *RT) {
- const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
- if (!RD)
- return false;
-
- return !RD->hasTrivialDestructor() || RD->hasNonTrivialCopyConstructor();
-}
-
-/// isRecordWithNonTrivialDestructorOrCopyConstructor - Determine if a type is
-/// a record type with either a non-trivial destructor or a non-trivial copy
-/// constructor.
-static bool isRecordWithNonTrivialDestructorOrCopyConstructor(QualType T) {
- const RecordType *RT = T->getAs<RecordType>();
- if (!RT)
- return false;
-
- return hasNonTrivialDestructorOrCopyConstructor(RT);
-}
-
/// isSingleElementStruct - Determine if a structure is a "single
/// element struct", i.e. it has exactly one non-empty field or
/// exactly one field which is itself a single element
@@ -367,7 +381,7 @@ ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty) const {
if (isAggregateTypeForABI(Ty)) {
// Records with non trivial destructors/constructors should not be passed
// by value.
- if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty))
+ if (isRecordReturnIndirect(Ty, CGT))
return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
return ABIArgInfo::getIndirect(0);
@@ -398,6 +412,9 @@ ABIArgInfo DefaultABIInfo::classifyReturnType(QualType RetTy) const {
//===----------------------------------------------------------------------===//
// le32/PNaCl bitcode ABI Implementation
+//
+// This is a simplified version of the x86_32 ABI. Arguments and return values
+// are always passed on the stack.
//===----------------------------------------------------------------------===//
class PNaClABIInfo : public ABIInfo {
@@ -405,7 +422,7 @@ class PNaClABIInfo : public ABIInfo {
PNaClABIInfo(CodeGen::CodeGenTypes &CGT) : ABIInfo(CGT) {}
ABIArgInfo classifyReturnType(QualType RetTy) const;
- ABIArgInfo classifyArgumentType(QualType RetTy, unsigned &FreeRegs) const;
+ ABIArgInfo classifyArgumentType(QualType RetTy) const;
virtual void computeInfo(CGFunctionInfo &FI) const;
virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
@@ -425,11 +442,9 @@ class PNaClTargetCodeGenInfo : public TargetCodeGenInfo {
void PNaClABIInfo::computeInfo(CGFunctionInfo &FI) const {
FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
- unsigned FreeRegs = FI.getHasRegParm() ? FI.getRegParm() : 0;
-
for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
it != ie; ++it)
- it->info = classifyArgumentType(it->type, FreeRegs);
+ it->info = classifyArgumentType(it->type);
}
llvm::Value *PNaClABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
@@ -437,42 +452,29 @@ llvm::Value *PNaClABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
return 0;
}
-ABIArgInfo PNaClABIInfo::classifyArgumentType(QualType Ty,
- unsigned &FreeRegs) const {
+/// \brief Classify argument of given type \p Ty.
+ABIArgInfo PNaClABIInfo::classifyArgumentType(QualType Ty) const {
if (isAggregateTypeForABI(Ty)) {
- // Records with non trivial destructors/constructors should not be passed
- // by value.
- FreeRegs = 0;
- if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty))
- return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
-
+ if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, CGT))
+ return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory);
return ABIArgInfo::getIndirect(0);
- }
-
- // Treat an enum type as its underlying type.
- if (const EnumType *EnumTy = Ty->getAs<EnumType>())
+ } else if (const EnumType *EnumTy = Ty->getAs<EnumType>()) {
+ // Treat an enum type as its underlying type.
Ty = EnumTy->getDecl()->getIntegerType();
+ } else if (Ty->isFloatingType()) {
+ // Floating-point types don't go inreg.
+ return ABIArgInfo::getDirect();
+ }
- ABIArgInfo BaseInfo = (Ty->isPromotableIntegerType() ?
+ return (Ty->isPromotableIntegerType() ?
ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
-
- // Regparm regs hold 32 bits.
- unsigned SizeInRegs = (getContext().getTypeSize(Ty) + 31) / 32;
- if (SizeInRegs == 0) return BaseInfo;
- if (SizeInRegs > FreeRegs) {
- FreeRegs = 0;
- return BaseInfo;
- }
- FreeRegs -= SizeInRegs;
- return BaseInfo.isDirect() ?
- ABIArgInfo::getDirectInReg(BaseInfo.getCoerceToType()) :
- ABIArgInfo::getExtendInReg(BaseInfo.getCoerceToType());
}
ABIArgInfo PNaClABIInfo::classifyReturnType(QualType RetTy) const {
if (RetTy->isVoidType())
return ABIArgInfo::getIgnore();
+ // In the PNaCl ABI we always return records/structures on the stack.
if (isAggregateTypeForABI(RetTy))
return ABIArgInfo::getIndirect(0);
@@ -484,11 +486,9 @@ ABIArgInfo PNaClABIInfo::classifyReturnType(QualType RetTy) const {
ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
}
-/// UseX86_MMXType - Return true if this is an MMX type that should use the
-/// special x86_mmx type.
-bool UseX86_MMXType(llvm::Type *IRType) {
- // If the type is an MMX type <2 x i32>, <4 x i16>, or <8 x i8>, use the
- // special x86_mmx type.
+/// IsX86_MMXType - Return true if this is an MMX type.
+bool IsX86_MMXType(llvm::Type *IRType) {
+ // Return true if the type is an MMX type <2 x i32>, <4 x i16>, or <8 x i8>.
return IRType->isVectorTy() && IRType->getPrimitiveSizeInBits() == 64 &&
cast<llvm::VectorType>(IRType)->getElementType()->isIntegerTy() &&
IRType->getScalarSizeInBits() != 64;
@@ -517,8 +517,7 @@ class X86_32ABIInfo : public ABIInfo {
bool IsDarwinVectorABI;
bool IsSmallStructInRegABI;
- bool IsMMXDisabled;
- bool IsWin32FloatStructABI;
+ bool IsWin32StructABI;
unsigned DefaultNumRegisterParameters;
static bool isRegisterSize(unsigned Size) {
@@ -550,26 +549,24 @@ public:
virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
CodeGenFunction &CGF) const;
- X86_32ABIInfo(CodeGen::CodeGenTypes &CGT, bool d, bool p, bool m, bool w,
+ X86_32ABIInfo(CodeGen::CodeGenTypes &CGT, bool d, bool p, bool w,
unsigned r)
: ABIInfo(CGT), IsDarwinVectorABI(d), IsSmallStructInRegABI(p),
- IsMMXDisabled(m), IsWin32FloatStructABI(w),
- DefaultNumRegisterParameters(r) {}
+ IsWin32StructABI(w), DefaultNumRegisterParameters(r) {}
};
class X86_32TargetCodeGenInfo : public TargetCodeGenInfo {
public:
X86_32TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT,
- bool d, bool p, bool m, bool w, unsigned r)
- :TargetCodeGenInfo(new X86_32ABIInfo(CGT, d, p, m, w, r)) {}
+ bool d, bool p, bool w, unsigned r)
+ :TargetCodeGenInfo(new X86_32ABIInfo(CGT, d, p, w, r)) {}
void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
CodeGen::CodeGenModule &CGM) const;
int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const {
// Darwin uses different dwarf register numbers for EH.
- if (CGM.isTargetDarwin()) return 5;
-
+ if (CGM.getTarget().getTriple().isOSDarwin()) return 5;
return 4;
}
@@ -681,9 +678,7 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
if (isAggregateTypeForABI(RetTy)) {
if (const RecordType *RT = RetTy->getAs<RecordType>()) {
- // Structures with either a non-trivial destructor or a non-trivial
- // copy constructor are always indirect.
- if (hasNonTrivialDestructorOrCopyConstructor(RT))
+ if (isRecordReturnIndirect(RT, CGT))
return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
// Structures with flexible arrays are always indirect.
@@ -707,7 +702,7 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
// We apply a similar transformation for pointer types to improve the
// quality of the generated IR.
if (const Type *SeltTy = isSingleElementStruct(RetTy, getContext()))
- if ((!IsWin32FloatStructABI && SeltTy->isRealFloatingType())
+ if ((!IsWin32StructABI && SeltTy->isRealFloatingType())
|| SeltTy->hasPointerRepresentation())
return ABIArgInfo::getDirect(CGT.ConvertType(QualType(SeltTy, 0)));
@@ -864,13 +859,14 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
bool IsFastCall) const {
// FIXME: Set alignment on indirect arguments.
if (isAggregateTypeForABI(Ty)) {
- // Structures with flexible arrays are always indirect.
if (const RecordType *RT = Ty->getAs<RecordType>()) {
- // Structures with either a non-trivial destructor or a non-trivial
- // copy constructor are always indirect.
- if (hasNonTrivialDestructorOrCopyConstructor(RT))
- return getIndirectResult(Ty, false, FreeRegs);
+ if (IsWin32StructABI)
+ return getIndirectResult(Ty, true, FreeRegs);
+
+ if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(RT, CGT))
+ return getIndirectResult(Ty, RAA == CGCXXABI::RAA_DirectInMemory, FreeRegs);
+ // Structures with flexible arrays are always indirect.
if (RT->getDecl()->hasFlexibleArrayMember())
return getIndirectResult(Ty, true, FreeRegs);
}
@@ -914,15 +910,8 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
Size));
}
- llvm::Type *IRType = CGT.ConvertType(Ty);
- if (UseX86_MMXType(IRType)) {
- if (IsMMXDisabled)
- return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(),
- 64));
- ABIArgInfo AAI = ABIArgInfo::getDirect(IRType);
- AAI.setCoerceToType(llvm::Type::getX86_MMXTy(getVMContext()));
- return AAI;
- }
+ if (IsX86_MMXType(CGT.ConvertType(Ty)))
+ return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(), 64));
return ABIArgInfo::getDirect();
}
@@ -1044,7 +1033,7 @@ bool X86_32TargetCodeGenInfo::initDwarfEHRegSizeTable(
// 8 is %eip.
AssignToArrayRange(Builder, Address, Four8, 0, 8);
- if (CGF.CGM.isTargetDarwin()) {
+ if (CGF.CGM.getTarget().getTriple().isOSDarwin()) {
// 12-16 are st(0..4). Not sure why we stop at 4.
// These have size 16, which is sizeof(long double) on
// platforms with 8-byte alignment for that type.
@@ -1169,7 +1158,7 @@ class X86_64ABIInfo : public ABIInfo {
/// required strict binary compatibility with older versions of GCC
/// may need to exempt themselves.
bool honorsRevision0_98() const {
- return !getContext().getTargetInfo().getTriple().isOSDarwin();
+ return !getTarget().getTriple().isOSDarwin();
}
bool HasAVX;
@@ -1204,7 +1193,7 @@ public:
/// WinX86_64ABIInfo - The Windows X86_64 ABI information.
class WinX86_64ABIInfo : public ABIInfo {
- ABIArgInfo classify(QualType Ty) const;
+ ABIArgInfo classify(QualType Ty, bool IsReturnType) const;
public:
WinX86_64ABIInfo(CodeGen::CodeGenTypes &CGT) : ABIInfo(CGT) {}
@@ -1393,8 +1382,7 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase,
Current = Integer;
} else if ((k == BuiltinType::Float || k == BuiltinType::Double) ||
(k == BuiltinType::LongDouble &&
- getContext().getTargetInfo().getTriple().getOS() ==
- llvm::Triple::NaCl)) {
+ getTarget().getTriple().getOS() == llvm::Triple::NaCl)) {
Current = SSE;
} else if (k == BuiltinType::LongDouble) {
Lo = X87;
@@ -1482,8 +1470,7 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase,
Current = SSE;
else if (ET == getContext().DoubleTy ||
(ET == getContext().LongDoubleTy &&
- getContext().getTargetInfo().getTriple().getOS() ==
- llvm::Triple::NaCl))
+ getTarget().getTriple().getOS() == llvm::Triple::NaCl))
Lo = Hi = SSE;
else if (ET == getContext().LongDoubleTy)
Current = ComplexX87;
@@ -1552,7 +1539,7 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase,
// AMD64-ABI 3.2.3p2: Rule 2. If a C++ object has either a non-trivial
// copy constructor or a non-trivial destructor, it is passed by invisible
// reference.
- if (hasNonTrivialDestructorOrCopyConstructor(RT))
+ if (getRecordArgABI(RT, CGT))
return;
const RecordDecl *RD = RT->getDecl();
@@ -1702,8 +1689,8 @@ ABIArgInfo X86_64ABIInfo::getIndirectResult(QualType Ty,
ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
}
- if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty))
- return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
+ if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, CGT))
+ return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory);
// Compute the byval alignment. We specify the alignment of the byval in all
// cases so that the mid-level optimizer knows the alignment of the byval.
@@ -2191,7 +2178,7 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType(
// COMPLEX_X87, it is passed in memory.
case X87:
case ComplexX87:
- if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty))
+ if (getRecordArgABI(Ty, CGT) == CGCXXABI::RAA_Indirect)
++neededInt;
return getIndirectResult(Ty, freeIntRegs);
@@ -2522,7 +2509,7 @@ llvm::Value *X86_64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
return ResAddr;
}
-ABIArgInfo WinX86_64ABIInfo::classify(QualType Ty) const {
+ABIArgInfo WinX86_64ABIInfo::classify(QualType Ty, bool IsReturnType) const {
if (Ty->isVoidType())
return ABIArgInfo::getIgnore();
@@ -2533,14 +2520,19 @@ ABIArgInfo WinX86_64ABIInfo::classify(QualType Ty) const {
uint64_t Size = getContext().getTypeSize(Ty);
if (const RecordType *RT = Ty->getAs<RecordType>()) {
- if (hasNonTrivialDestructorOrCopyConstructor(RT) ||
- RT->getDecl()->hasFlexibleArrayMember())
+ if (IsReturnType) {
+ if (isRecordReturnIndirect(RT, CGT))
+ return ABIArgInfo::getIndirect(0, false);
+ } else {
+ if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(RT, CGT))
+ return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory);
+ }
+
+ if (RT->getDecl()->hasFlexibleArrayMember())
return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
// FIXME: mingw-w64-gcc emits 128-bit struct as i128
- if (Size == 128 &&
- getContext().getTargetInfo().getTriple().getOS()
- == llvm::Triple::MinGW32)
+ if (Size == 128 && getTarget().getTriple().getOS() == llvm::Triple::MinGW32)
return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(),
Size));
@@ -2563,11 +2555,11 @@ ABIArgInfo WinX86_64ABIInfo::classify(QualType Ty) const {
void WinX86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const {
QualType RetTy = FI.getReturnType();
- FI.getReturnInfo() = classify(RetTy);
+ FI.getReturnInfo() = classify(RetTy, true);
for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
it != ie; ++it)
- it->info = classify(it->type);
+ it->info = classify(it->type, false);
}
llvm::Value *WinX86_64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
@@ -2794,10 +2786,8 @@ PPC64_SVR4_ABIInfo::classifyArgumentType(QualType Ty) const {
return ABIArgInfo::getDirect();
if (isAggregateTypeForABI(Ty)) {
- // Records with non trivial destructors/constructors should not be passed
- // by value.
- if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty))
- return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
+ if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, CGT))
+ return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory);
return ABIArgInfo::getIndirect(0);
}
@@ -2970,8 +2960,7 @@ public:
}
bool isEABI() const {
- StringRef Env =
- getContext().getTargetInfo().getTriple().getEnvironmentName();
+ StringRef Env = getTarget().getTriple().getEnvironmentName();
return (Env == "gnueabi" || Env == "eabi" ||
Env == "android" || Env == "androideabi");
}
@@ -3070,7 +3059,7 @@ void ARMABIInfo::computeInfo(CGFunctionInfo &FI) const {
/// Return the default calling convention that LLVM will use.
llvm::CallingConv::ID ARMABIInfo::getLLVMDefaultCC() const {
// The default calling convention that LLVM will infer.
- if (getContext().getTargetInfo().getTriple().getEnvironmentName()=="gnueabihf")
+ if (getTarget().getTriple().getEnvironmentName()=="gnueabihf")
return llvm::CallingConv::ARM_AAPCS_VFP;
else if (isEABI())
return llvm::CallingConv::ARM_AAPCS;
@@ -3262,10 +3251,8 @@ ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty, int *VFPRegs,
if (isEmptyRecord(getContext(), Ty, true))
return ABIArgInfo::getIgnore();
- // Structures with either a non-trivial destructor or a non-trivial
- // copy constructor are always indirect.
- if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty))
- return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
+ if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, CGT))
+ return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory);
if (getABIKind() == ARMABIInfo::AAPCS_VFP) {
// Homogeneous Aggregates need to be expanded when we can fit the aggregate
@@ -3428,7 +3415,7 @@ ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy) const {
// Structures with either a non-trivial destructor or a non-trivial
// copy constructor are always indirect.
- if (isRecordWithNonTrivialDestructorOrCopyConstructor(RetTy))
+ if (isRecordReturnIndirect(RetTy, CGT))
return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
// Are we following APCS?
@@ -3752,12 +3739,10 @@ ABIArgInfo AArch64ABIInfo::classifyGenericType(QualType Ty,
return tryUseRegs(Ty, FreeIntRegs, RegsNeeded, /*IsInt=*/ true);
}
- // Structures with either a non-trivial destructor or a non-trivial
- // copy constructor are always indirect.
- if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty)) {
- if (FreeIntRegs > 0)
+ if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, CGT)) {
+ if (FreeIntRegs > 0 && RAA == CGCXXABI::RAA_Indirect)
--FreeIntRegs;
- return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
+ return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory);
}
if (isEmptyRecord(getContext(), Ty, true)) {
@@ -4032,7 +4017,7 @@ namespace {
class NVPTXABIInfo : public ABIInfo {
public:
- NVPTXABIInfo(CodeGenTypes &CGT) : ABIInfo(CGT) { setRuntimeCC(); }
+ NVPTXABIInfo(CodeGenTypes &CGT) : ABIInfo(CGT) {}
ABIArgInfo classifyReturnType(QualType RetTy) const;
ABIArgInfo classifyArgumentType(QualType Ty) const;
@@ -4040,8 +4025,6 @@ public:
virtual void computeInfo(CGFunctionInfo &FI) const;
virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
CodeGenFunction &CFG) const;
-private:
- void setRuntimeCC();
};
class NVPTXTargetCodeGenInfo : public TargetCodeGenInfo {
@@ -4051,6 +4034,8 @@ public:
virtual void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
CodeGen::CodeGenModule &M) const;
+private:
+ static void addKernelMetadata(llvm::Function *F);
};
ABIArgInfo NVPTXABIInfo::classifyReturnType(QualType RetTy) const {
@@ -4081,25 +4066,6 @@ void NVPTXABIInfo::computeInfo(CGFunctionInfo &FI) const {
FI.setEffectiveCallingConvention(getRuntimeCC());
}
-void NVPTXABIInfo::setRuntimeCC() {
- // Calling convention as default by an ABI.
- // We're still using the PTX_Kernel/PTX_Device calling conventions here,
- // but we should switch to NVVM metadata later on.
- const LangOptions &LangOpts = getContext().getLangOpts();
- if (LangOpts.OpenCL || LangOpts.CUDA) {
- // If we are in OpenCL or CUDA mode, then default to device functions
- RuntimeCC = llvm::CallingConv::PTX_Device;
- } else {
- // If we are in standard C/C++ mode, use the triple to decide on the default
- StringRef Env =
- getContext().getTargetInfo().getTriple().getEnvironmentName();
- if (Env == "device")
- RuntimeCC = llvm::CallingConv::PTX_Device;
- else
- RuntimeCC = llvm::CallingConv::PTX_Kernel;
- }
-}
-
llvm::Value *NVPTXABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
CodeGenFunction &CFG) const {
llvm_unreachable("NVPTX does not support varargs");
@@ -4115,11 +4081,11 @@ SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
// Perform special handling in OpenCL mode
if (M.getLangOpts().OpenCL) {
- // Use OpenCL function attributes to set proper calling conventions
+ // Use OpenCL function attributes to check for kernel functions
// By default, all functions are device functions
if (FD->hasAttr<OpenCLKernelAttr>()) {
- // OpenCL __kernel functions get a kernel calling convention
- F->setCallingConv(llvm::CallingConv::PTX_Kernel);
+ // OpenCL __kernel functions get kernel metadata
+ addKernelMetadata(F);
// And kernel functions are not subject to inlining
F->addFnAttr(llvm::Attribute::NoInline);
}
@@ -4127,14 +4093,318 @@ SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
// Perform special handling in CUDA mode.
if (M.getLangOpts().CUDA) {
- // CUDA __global__ functions get a kernel calling convention. Since
+ // CUDA __global__ functions get a kernel metadata entry. Since
// __global__ functions cannot be called from the device, we do not
// need to set the noinline attribute.
if (FD->getAttr<CUDAGlobalAttr>())
- F->setCallingConv(llvm::CallingConv::PTX_Kernel);
+ addKernelMetadata(F);
}
}
+void NVPTXTargetCodeGenInfo::addKernelMetadata(llvm::Function *F) {
+ llvm::Module *M = F->getParent();
+ llvm::LLVMContext &Ctx = M->getContext();
+
+ // Get "nvvm.annotations" metadata node
+ llvm::NamedMDNode *MD = M->getOrInsertNamedMetadata("nvvm.annotations");
+
+ // Create !{<func-ref>, metadata !"kernel", i32 1} node
+ llvm::SmallVector<llvm::Value *, 3> MDVals;
+ MDVals.push_back(F);
+ MDVals.push_back(llvm::MDString::get(Ctx, "kernel"));
+ MDVals.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(Ctx), 1));
+
+ // Append metadata to nvvm.annotations
+ MD->addOperand(llvm::MDNode::get(Ctx, MDVals));
+}
+
+}
+
+//===----------------------------------------------------------------------===//
+// SystemZ ABI Implementation
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+class SystemZABIInfo : public ABIInfo {
+public:
+ SystemZABIInfo(CodeGenTypes &CGT) : ABIInfo(CGT) {}
+
+ bool isPromotableIntegerType(QualType Ty) const;
+ bool isCompoundType(QualType Ty) const;
+ bool isFPArgumentType(QualType Ty) const;
+
+ ABIArgInfo classifyReturnType(QualType RetTy) const;
+ ABIArgInfo classifyArgumentType(QualType ArgTy) const;
+
+ virtual void computeInfo(CGFunctionInfo &FI) const {
+ FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
+ for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
+ it != ie; ++it)
+ it->info = classifyArgumentType(it->type);
+ }
+
+ virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+ CodeGenFunction &CGF) const;
+};
+
+class SystemZTargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+ SystemZTargetCodeGenInfo(CodeGenTypes &CGT)
+ : TargetCodeGenInfo(new SystemZABIInfo(CGT)) {}
+};
+
+}
+
+bool SystemZABIInfo::isPromotableIntegerType(QualType Ty) const {
+ // Treat an enum type as its underlying type.
+ if (const EnumType *EnumTy = Ty->getAs<EnumType>())
+ Ty = EnumTy->getDecl()->getIntegerType();
+
+ // Promotable integer types are required to be promoted by the ABI.
+ if (Ty->isPromotableIntegerType())
+ return true;
+
+ // 32-bit values must also be promoted.
+ if (const BuiltinType *BT = Ty->getAs<BuiltinType>())
+ switch (BT->getKind()) {
+ case BuiltinType::Int:
+ case BuiltinType::UInt:
+ return true;
+ default:
+ return false;
+ }
+ return false;
+}
+
+bool SystemZABIInfo::isCompoundType(QualType Ty) const {
+ return Ty->isAnyComplexType() || isAggregateTypeForABI(Ty);
+}
+
+bool SystemZABIInfo::isFPArgumentType(QualType Ty) const {
+ if (const BuiltinType *BT = Ty->getAs<BuiltinType>())
+ switch (BT->getKind()) {
+ case BuiltinType::Float:
+ case BuiltinType::Double:
+ return true;
+ default:
+ return false;
+ }
+
+ if (const RecordType *RT = Ty->getAsStructureType()) {
+ const RecordDecl *RD = RT->getDecl();
+ bool Found = false;
+
+ // If this is a C++ record, check the bases first.
+ if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
+ for (CXXRecordDecl::base_class_const_iterator I = CXXRD->bases_begin(),
+ E = CXXRD->bases_end(); I != E; ++I) {
+ QualType Base = I->getType();
+
+ // Empty bases don't affect things either way.
+ if (isEmptyRecord(getContext(), Base, true))
+ continue;
+
+ if (Found)
+ return false;
+ Found = isFPArgumentType(Base);
+ if (!Found)
+ return false;
+ }
+
+ // Check the fields.
+ for (RecordDecl::field_iterator I = RD->field_begin(),
+ E = RD->field_end(); I != E; ++I) {
+ const FieldDecl *FD = *I;
+
+ // Empty bitfields don't affect things either way.
+ // Unlike isSingleElementStruct(), empty structure and array fields
+ // do count. So do anonymous bitfields that aren't zero-sized.
+ if (FD->isBitField() && FD->getBitWidthValue(getContext()) == 0)
+ return true;
+
+ // Unlike isSingleElementStruct(), arrays do not count.
+ // Nested isFPArgumentType structures still do though.
+ if (Found)
+ return false;
+ Found = isFPArgumentType(FD->getType());
+ if (!Found)
+ return false;
+ }
+
+ // Unlike isSingleElementStruct(), trailing padding is allowed.
+ // An 8-byte aligned struct s { float f; } is passed as a double.
+ return Found;
+ }
+
+ return false;
+}
+
+llvm::Value *SystemZABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+ CodeGenFunction &CGF) const {
+ // Assume that va_list type is correct; should be pointer to LLVM type:
+ // struct {
+ // i64 __gpr;
+ // i64 __fpr;
+ // i8 *__overflow_arg_area;
+ // i8 *__reg_save_area;
+ // };
+
+ // Every argument occupies 8 bytes and is passed by preference in either
+ // GPRs or FPRs.
+ Ty = CGF.getContext().getCanonicalType(Ty);
+ ABIArgInfo AI = classifyArgumentType(Ty);
+ bool InFPRs = isFPArgumentType(Ty);
+
+ llvm::Type *APTy = llvm::PointerType::getUnqual(CGF.ConvertTypeForMem(Ty));
+ bool IsIndirect = AI.isIndirect();
+ unsigned UnpaddedBitSize;
+ if (IsIndirect) {
+ APTy = llvm::PointerType::getUnqual(APTy);
+ UnpaddedBitSize = 64;
+ } else
+ UnpaddedBitSize = getContext().getTypeSize(Ty);
+ unsigned PaddedBitSize = 64;
+ assert((UnpaddedBitSize <= PaddedBitSize) && "Invalid argument size.");
+
+ unsigned PaddedSize = PaddedBitSize / 8;
+ unsigned Padding = (PaddedBitSize - UnpaddedBitSize) / 8;
+
+ unsigned MaxRegs, RegCountField, RegSaveIndex, RegPadding;
+ if (InFPRs) {
+ MaxRegs = 4; // Maximum of 4 FPR arguments
+ RegCountField = 1; // __fpr
+ RegSaveIndex = 16; // save offset for f0
+ RegPadding = 0; // floats are passed in the high bits of an FPR
+ } else {
+ MaxRegs = 5; // Maximum of 5 GPR arguments
+ RegCountField = 0; // __gpr
+ RegSaveIndex = 2; // save offset for r2
+ RegPadding = Padding; // values are passed in the low bits of a GPR
+ }
+
+ llvm::Value *RegCountPtr =
+ CGF.Builder.CreateStructGEP(VAListAddr, RegCountField, "reg_count_ptr");
+ llvm::Value *RegCount = CGF.Builder.CreateLoad(RegCountPtr, "reg_count");
+ llvm::Type *IndexTy = RegCount->getType();
+ llvm::Value *MaxRegsV = llvm::ConstantInt::get(IndexTy, MaxRegs);
+ llvm::Value *InRegs = CGF.Builder.CreateICmpULT(RegCount, MaxRegsV,
+ "fits_in_regs");
+
+ llvm::BasicBlock *InRegBlock = CGF.createBasicBlock("vaarg.in_reg");
+ llvm::BasicBlock *InMemBlock = CGF.createBasicBlock("vaarg.in_mem");
+ llvm::BasicBlock *ContBlock = CGF.createBasicBlock("vaarg.end");
+ CGF.Builder.CreateCondBr(InRegs, InRegBlock, InMemBlock);
+
+ // Emit code to load the value if it was passed in registers.
+ CGF.EmitBlock(InRegBlock);
+
+ // Work out the address of an argument register.
+ llvm::Value *PaddedSizeV = llvm::ConstantInt::get(IndexTy, PaddedSize);
+ llvm::Value *ScaledRegCount =
+ CGF.Builder.CreateMul(RegCount, PaddedSizeV, "scaled_reg_count");
+ llvm::Value *RegBase =
+ llvm::ConstantInt::get(IndexTy, RegSaveIndex * PaddedSize + RegPadding);
+ llvm::Value *RegOffset =
+ CGF.Builder.CreateAdd(ScaledRegCount, RegBase, "reg_offset");
+ llvm::Value *RegSaveAreaPtr =
+ CGF.Builder.CreateStructGEP(VAListAddr, 3, "reg_save_area_ptr");
+ llvm::Value *RegSaveArea =
+ CGF.Builder.CreateLoad(RegSaveAreaPtr, "reg_save_area");
+ llvm::Value *RawRegAddr =
+ CGF.Builder.CreateGEP(RegSaveArea, RegOffset, "raw_reg_addr");
+ llvm::Value *RegAddr =
+ CGF.Builder.CreateBitCast(RawRegAddr, APTy, "reg_addr");
+
+ // Update the register count
+ llvm::Value *One = llvm::ConstantInt::get(IndexTy, 1);
+ llvm::Value *NewRegCount =
+ CGF.Builder.CreateAdd(RegCount, One, "reg_count");
+ CGF.Builder.CreateStore(NewRegCount, RegCountPtr);
+ CGF.EmitBranch(ContBlock);
+
+ // Emit code to load the value if it was passed in memory.
+ CGF.EmitBlock(InMemBlock);
+
+ // Work out the address of a stack argument.
+ llvm::Value *OverflowArgAreaPtr =
+ CGF.Builder.CreateStructGEP(VAListAddr, 2, "overflow_arg_area_ptr");
+ llvm::Value *OverflowArgArea =
+ CGF.Builder.CreateLoad(OverflowArgAreaPtr, "overflow_arg_area");
+ llvm::Value *PaddingV = llvm::ConstantInt::get(IndexTy, Padding);
+ llvm::Value *RawMemAddr =
+ CGF.Builder.CreateGEP(OverflowArgArea, PaddingV, "raw_mem_addr");
+ llvm::Value *MemAddr =
+ CGF.Builder.CreateBitCast(RawMemAddr, APTy, "mem_addr");
+
+ // Update overflow_arg_area_ptr pointer
+ llvm::Value *NewOverflowArgArea =
+ CGF.Builder.CreateGEP(OverflowArgArea, PaddedSizeV, "overflow_arg_area");
+ CGF.Builder.CreateStore(NewOverflowArgArea, OverflowArgAreaPtr);
+ CGF.EmitBranch(ContBlock);
+
+ // Return the appropriate result.
+ CGF.EmitBlock(ContBlock);
+ llvm::PHINode *ResAddr = CGF.Builder.CreatePHI(APTy, 2, "va_arg.addr");
+ ResAddr->addIncoming(RegAddr, InRegBlock);
+ ResAddr->addIncoming(MemAddr, InMemBlock);
+
+ if (IsIndirect)
+ return CGF.Builder.CreateLoad(ResAddr, "indirect_arg");
+
+ return ResAddr;
+}
+
+
+ABIArgInfo SystemZABIInfo::classifyReturnType(QualType RetTy) const {
+ if (RetTy->isVoidType())
+ return ABIArgInfo::getIgnore();
+ if (isCompoundType(RetTy) || getContext().getTypeSize(RetTy) > 64)
+ return ABIArgInfo::getIndirect(0);
+ return (isPromotableIntegerType(RetTy) ?
+ ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
+}
+
+ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty) const {
+ // Handle the generic C++ ABI.
+ if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, CGT))
+ return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory);
+
+ // Integers and enums are extended to full register width.
+ if (isPromotableIntegerType(Ty))
+ return ABIArgInfo::getExtend();
+
+ // Values that are not 1, 2, 4 or 8 bytes in size are passed indirectly.
+ uint64_t Size = getContext().getTypeSize(Ty);
+ if (Size != 8 && Size != 16 && Size != 32 && Size != 64)
+ return ABIArgInfo::getIndirect(0);
+
+ // Handle small structures.
+ if (const RecordType *RT = Ty->getAs<RecordType>()) {
+ // Structures with flexible arrays have variable length, so really
+ // fail the size test above.
+ const RecordDecl *RD = RT->getDecl();
+ if (RD->hasFlexibleArrayMember())
+ return ABIArgInfo::getIndirect(0);
+
+ // The structure is passed as an unextended integer, a float, or a double.
+ llvm::Type *PassTy;
+ if (isFPArgumentType(Ty)) {
+ assert(Size == 32 || Size == 64);
+ if (Size == 32)
+ PassTy = llvm::Type::getFloatTy(getVMContext());
+ else
+ PassTy = llvm::Type::getDoubleTy(getVMContext());
+ } else
+ PassTy = llvm::IntegerType::get(getVMContext(), Size);
+ return ABIArgInfo::getDirect(PassTy);
+ }
+
+ // Non-structure compounds are passed indirectly.
+ if (isCompoundType(Ty))
+ return ABIArgInfo::getIndirect(0);
+
+ return ABIArgInfo::getDirect(0);
}
//===----------------------------------------------------------------------===//
@@ -4325,11 +4595,17 @@ public:
void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
CodeGen::CodeGenModule &CGM) const {
- //
- // can fill this in when new attribute work in llvm is done.
- // attributes mips16 and nomips16 need to be handled here.
- //
+ const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
+ if (!FD) return;
+ llvm::Function *Fn = cast<llvm::Function>(GV);
+ if (FD->hasAttr<Mips16Attr>()) {
+ Fn->addFnAttr("mips16");
+ }
+ else if (FD->hasAttr<NoMips16Attr>()) {
+ Fn->addFnAttr("nomips16");
+ }
}
+
bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
llvm::Value *Address) const;
@@ -4438,11 +4714,9 @@ MipsABIInfo::classifyArgumentType(QualType Ty, uint64_t &Offset) const {
if (TySize == 0)
return ABIArgInfo::getIgnore();
- // Records with non trivial destructors/constructors should not be passed
- // by value.
- if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty)) {
+ if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, CGT)) {
Offset = OrigOffset + MinABIStackAlignInBytes;
- return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
+ return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory);
}
// If we have reached here, aggregates are passed directly by coercing to
@@ -4512,6 +4786,9 @@ ABIArgInfo MipsABIInfo::classifyReturnType(QualType RetTy) const {
return ABIArgInfo::getIgnore();
if (isAggregateTypeForABI(RetTy) || RetTy->isVectorType()) {
+ if (isRecordReturnIndirect(RetTy, CGT))
+ return ABIArgInfo::getIndirect(0);
+
if (Size <= 128) {
if (RetTy->isAnyComplexType())
return ABIArgInfo::getDirect();
@@ -4520,7 +4797,7 @@ ABIArgInfo MipsABIInfo::classifyReturnType(QualType RetTy) const {
if (IsO32 && RetTy->isVectorType() && !RetTy->hasFloatingRepresentation())
return ABIArgInfo::getDirect(returnAggregateInRegs(RetTy, Size));
- if (!IsO32 && !isRecordWithNonTrivialDestructorOrCopyConstructor(RetTy))
+ if (!IsO32)
return ABIArgInfo::getDirect(returnAggregateInRegs(RetTy, Size));
}
@@ -4558,7 +4835,7 @@ llvm::Value* MipsABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
int64_t TypeAlign = getContext().getTypeAlign(Ty) / 8;
llvm::Type *PTy = llvm::PointerType::getUnqual(CGF.ConvertType(Ty));
llvm::Value *AddrTyped;
- unsigned PtrWidth = getContext().getTargetInfo().getPointerWidth(0);
+ unsigned PtrWidth = getTarget().getPointerWidth(0);
llvm::IntegerType *IntTy = (PtrWidth == 32) ? CGF.Int32Ty : CGF.Int64Ty;
if (TypeAlign > MinABIStackAlignInBytes) {
@@ -4730,10 +5007,8 @@ ABIArgInfo HexagonABIInfo::classifyArgumentType(QualType Ty) const {
if (isEmptyRecord(getContext(), Ty, true))
return ABIArgInfo::getIgnore();
- // Structures with either a non-trivial destructor or a non-trivial
- // copy constructor are always indirect.
- if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty))
- return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
+ if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, CGT))
+ return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory);
uint64_t Size = getContext().getTypeSize(Ty);
if (Size > 64)
@@ -4768,7 +5043,7 @@ ABIArgInfo HexagonABIInfo::classifyReturnType(QualType RetTy) const {
// Structures with either a non-trivial destructor or a non-trivial
// copy constructor are always indirect.
- if (isRecordWithNonTrivialDestructorOrCopyConstructor(RetTy))
+ if (isRecordReturnIndirect(RetTy, CGT))
return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
if (isEmptyRecord(getContext(), RetTy, true))
@@ -4819,7 +5094,7 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {
if (TheTargetCodeGenInfo)
return *TheTargetCodeGenInfo;
- const llvm::Triple &Triple = getContext().getTargetInfo().getTriple();
+ const llvm::Triple &Triple = getTarget().getTriple();
switch (Triple.getArch()) {
default:
return *(TheTargetCodeGenInfo = new DefaultTargetCodeGenInfo(Types));
@@ -4841,10 +5116,11 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {
case llvm::Triple::thumb:
{
ARMABIInfo::ABIKind Kind = ARMABIInfo::AAPCS;
- if (strcmp(getContext().getTargetInfo().getABI(), "apcs-gnu") == 0)
+ if (strcmp(getTarget().getABI(), "apcs-gnu") == 0)
Kind = ARMABIInfo::APCS;
else if (CodeGenOpts.FloatABI == "hard" ||
- (CodeGenOpts.FloatABI != "soft" && Triple.getEnvironment()==llvm::Triple::GNUEABIHF))
+ (CodeGenOpts.FloatABI != "soft" &&
+ Triple.getEnvironment() == llvm::Triple::GNUEABIHF))
Kind = ARMABIInfo::AAPCS_VFP;
switch (Triple.getOS()) {
@@ -4875,15 +5151,16 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {
case llvm::Triple::msp430:
return *(TheTargetCodeGenInfo = new MSP430TargetCodeGenInfo(Types));
+ case llvm::Triple::systemz:
+ return *(TheTargetCodeGenInfo = new SystemZTargetCodeGenInfo(Types));
+
case llvm::Triple::tce:
return *(TheTargetCodeGenInfo = new TCETargetCodeGenInfo(Types));
case llvm::Triple::x86: {
- bool DisableMMX = strcmp(getContext().getTargetInfo().getABI(), "no-mmx") == 0;
-
if (Triple.isOSDarwin())
return *(TheTargetCodeGenInfo =
- new X86_32TargetCodeGenInfo(Types, true, true, DisableMMX, false,
+ new X86_32TargetCodeGenInfo(Types, true, true, false,
CodeGenOpts.NumRegisterParameters));
switch (Triple.getOS()) {
@@ -4895,25 +5172,23 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {
case llvm::Triple::OpenBSD:
case llvm::Triple::Bitrig:
return *(TheTargetCodeGenInfo =
- new X86_32TargetCodeGenInfo(Types, false, true, DisableMMX,
- false,
+ new X86_32TargetCodeGenInfo(Types, false, true, false,
CodeGenOpts.NumRegisterParameters));
case llvm::Triple::Win32:
return *(TheTargetCodeGenInfo =
- new X86_32TargetCodeGenInfo(Types, false, true, DisableMMX, true,
+ new X86_32TargetCodeGenInfo(Types, false, true, true,
CodeGenOpts.NumRegisterParameters));
default:
return *(TheTargetCodeGenInfo =
- new X86_32TargetCodeGenInfo(Types, false, false, DisableMMX,
- false,
+ new X86_32TargetCodeGenInfo(Types, false, false, false,
CodeGenOpts.NumRegisterParameters));
}
}
case llvm::Triple::x86_64: {
- bool HasAVX = strcmp(getContext().getTargetInfo().getABI(), "avx") == 0;
+ bool HasAVX = strcmp(getTarget().getABI(), "avx") == 0;
switch (Triple.getOS()) {
case llvm::Triple::Win32:
@@ -4921,7 +5196,8 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {
case llvm::Triple::Cygwin:
return *(TheTargetCodeGenInfo = new WinX86_64TargetCodeGenInfo(Types));
case llvm::Triple::NaCl:
- return *(TheTargetCodeGenInfo = new NaClX86_64TargetCodeGenInfo(Types, HasAVX));
+ return *(TheTargetCodeGenInfo = new NaClX86_64TargetCodeGenInfo(Types,
+ HasAVX));
default:
return *(TheTargetCodeGenInfo = new X86_64TargetCodeGenInfo(Types,
HasAVX));