summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/TargetInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/TargetInfo.cpp')
-rw-r--r--clang/lib/CodeGen/TargetInfo.cpp43
1 files changed, 27 insertions, 16 deletions
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index cae8f5fb1a0..2ee662c1e70 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -98,8 +98,8 @@ unsigned TargetCodeGenInfo::getSizeOfUnwindException() const {
return 32;
}
-bool TargetCodeGenInfo::isNoProtoCallVariadic(
- const CodeGen::CGFunctionInfo &) const {
+bool TargetCodeGenInfo::isNoProtoCallVariadic(const CallArgList &args,
+ const FunctionNoProtoType *fnType) const {
// The following conventions are known to require this to be false:
// x86_stdcall
// MIPS
@@ -935,6 +935,17 @@ public:
X86_64ABIInfo(CodeGen::CodeGenTypes &CGT, bool hasavx) :
ABIInfo(CGT), HasAVX(hasavx) {}
+ bool isPassedUsingAVXType(QualType type) const {
+ unsigned neededInt, neededSSE;
+ ABIArgInfo info = classifyArgumentType(type, neededInt, neededSSE);
+ if (info.isDirect()) {
+ llvm::Type *ty = info.getCoerceToType();
+ if (llvm::VectorType *vectorTy = dyn_cast_or_null<llvm::VectorType>(ty))
+ return (vectorTy->getBitWidth() > 128);
+ }
+ return false;
+ }
+
virtual void computeInfo(CGFunctionInfo &FI) const;
virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
@@ -960,6 +971,10 @@ public:
X86_64TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, bool HasAVX)
: TargetCodeGenInfo(new X86_64ABIInfo(CGT, HasAVX)) {}
+ const X86_64ABIInfo &getABIInfo() const {
+ return static_cast<const X86_64ABIInfo&>(TargetCodeGenInfo::getABIInfo());
+ }
+
int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const {
return 7;
}
@@ -980,33 +995,29 @@ public:
return X86AdjustInlineAsmType(CGF, Constraint, Ty);
}
- bool isNoProtoCallVariadic(const CodeGen::CGFunctionInfo &FI) const {
+ bool isNoProtoCallVariadic(const CallArgList &args,
+ const FunctionNoProtoType *fnType) const {
// The default CC on x86-64 sets %al to the number of SSA
// registers used, and GCC sets this when calling an unprototyped
// function, so we override the default behavior. However, don't do
// that when AVX types are involved: the ABI explicitly states it is
// undefined, and it doesn't work in practice because of how the ABI
// defines varargs anyway.
- if (FI.getCallingConvention() == llvm::CallingConv::C) {
+ if (fnType->getCallConv() == CC_Default || fnType->getCallConv() == CC_C) {
bool HasAVXType = false;
- for (CGFunctionInfo::const_arg_iterator it = FI.arg_begin(),
- ie = FI.arg_end();
- it != ie; ++it) {
- if (it->info.isDirect()) {
- llvm::Type *Ty = it->info.getCoerceToType();
- if (llvm::VectorType *VTy = dyn_cast_or_null<llvm::VectorType>(Ty)) {
- if (VTy->getBitWidth() > 128) {
- HasAVXType = true;
- break;
- }
- }
+ for (CallArgList::const_iterator
+ it = args.begin(), ie = args.end(); it != ie; ++it) {
+ if (getABIInfo().isPassedUsingAVXType(it->Ty)) {
+ HasAVXType = true;
+ break;
}
}
+
if (!HasAVXType)
return true;
}
- return TargetCodeGenInfo::isNoProtoCallVariadic(FI);
+ return TargetCodeGenInfo::isNoProtoCallVariadic(args, fnType);
}
};
OpenPOWER on IntegriCloud