summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/TargetInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/TargetInfo.cpp')
-rw-r--r--lib/CodeGen/TargetInfo.cpp83
1 files changed, 58 insertions, 25 deletions
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp
index 59e8e77..e1fdf86 100644
--- a/lib/CodeGen/TargetInfo.cpp
+++ b/lib/CodeGen/TargetInfo.cpp
@@ -43,7 +43,8 @@ void ABIArgInfo::dump() const {
getCoerceToType()->print(OS);
break;
case Indirect:
- OS << "Indirect Align=" << getIndirectAlign();
+ OS << "Indirect Align=" << getIndirectAlign()
+ << " Byal=" << getIndirectByVal();
break;
case Expand:
OS << "Expand";
@@ -270,7 +271,7 @@ ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty,
llvm::LLVMContext &VMContext) const {
if (CodeGenFunction::hasAggregateLLVMType(Ty))
return ABIArgInfo::getIndirect(0);
-
+
// Treat an enum type as its underlying type.
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
Ty = EnumTy->getDecl()->getIntegerType();
@@ -291,8 +292,10 @@ class X86_32ABIInfo : public ABIInfo {
static bool shouldReturnTypeInRegister(QualType Ty, ASTContext &Context);
- static unsigned getIndirectArgumentAlignment(QualType Ty,
- ASTContext &Context);
+ /// getIndirectResult - Give a source type \arg Ty, return a suitable result
+ /// such that the argument will be passed in memory.
+ ABIArgInfo getIndirectResult(QualType Ty, ASTContext &Context,
+ bool ByVal = true) const;
public:
ABIArgInfo classifyReturnType(QualType RetTy,
@@ -490,14 +493,19 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
}
}
-unsigned X86_32ABIInfo::getIndirectArgumentAlignment(QualType Ty,
- ASTContext &Context) {
- unsigned Align = Context.getTypeAlign(Ty);
- if (Align < 128) return 0;
- if (const RecordType* RT = Ty->getAs<RecordType>())
- if (typeContainsSSEVector(RT->getDecl(), Context))
- return 16;
- return 0;
+ABIArgInfo X86_32ABIInfo::getIndirectResult(QualType Ty,
+ ASTContext &Context,
+ bool ByVal) const {
+ if (!ByVal)
+ return ABIArgInfo::getIndirect(0, false);
+
+ // Compute the byval alignment. We trust the back-end to honor the
+ // minimum ABI alignment for byval, to make cleaner IR.
+ const unsigned MinABIAlign = 4;
+ unsigned Align = Context.getTypeAlign(Ty) / 8;
+ if (Align > MinABIAlign)
+ return ABIArgInfo::getIndirect(Align);
+ return ABIArgInfo::getIndirect(0);
}
ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
@@ -510,11 +518,10 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
// Structures with either a non-trivial destructor or a non-trivial
// copy constructor are always indirect.
if (hasNonTrivialDestructorOrCopyConstructor(RT))
- return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
-
+ return getIndirectResult(Ty, Context, /*ByVal=*/false);
+
if (RT->getDecl()->hasFlexibleArrayMember())
- return ABIArgInfo::getIndirect(getIndirectArgumentAlignment(Ty,
- Context));
+ return getIndirectResult(Ty, Context);
}
// Ignore empty structs.
@@ -529,7 +536,7 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
canExpandIndirectArgument(Ty, Context))
return ABIArgInfo::getExpand();
- return ABIArgInfo::getIndirect(getIndirectArgumentAlignment(Ty, Context));
+ return getIndirectResult(Ty, Context);
} else {
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
Ty = EnumTy->getDecl()->getIntegerType();
@@ -685,9 +692,12 @@ class X86_64ABIInfo : public ABIInfo {
ASTContext &Context) const;
/// getIndirectResult - Give a source type \arg Ty, return a suitable result
+ /// such that the argument will be returned in memory.
+ ABIArgInfo getIndirectReturnResult(QualType Ty, ASTContext &Context) const;
+
+ /// getIndirectResult - Give a source type \arg Ty, return a suitable result
/// such that the argument will be passed in memory.
- ABIArgInfo getIndirectResult(QualType Ty,
- ASTContext &Context) const;
+ ABIArgInfo getIndirectResult(QualType Ty, ASTContext &Context) const;
ABIArgInfo classifyReturnType(QualType RetTy,
ASTContext &Context,
@@ -1060,6 +1070,22 @@ ABIArgInfo X86_64ABIInfo::getCoerceResult(QualType Ty,
return ABIArgInfo::getCoerce(CoerceTo);
}
+ABIArgInfo X86_64ABIInfo::getIndirectReturnResult(QualType Ty,
+ ASTContext &Context) const {
+ // If this is a scalar LLVM value then assume LLVM will pass it in the right
+ // place naturally.
+ if (!CodeGenFunction::hasAggregateLLVMType(Ty)) {
+ // Treat an enum type as its underlying type.
+ if (const EnumType *EnumTy = Ty->getAs<EnumType>())
+ Ty = EnumTy->getDecl()->getIntegerType();
+
+ return (Ty->isPromotableIntegerType() ?
+ ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
+ }
+
+ return ABIArgInfo::getIndirect(0);
+}
+
ABIArgInfo X86_64ABIInfo::getIndirectResult(QualType Ty,
ASTContext &Context) const {
// If this is a scalar LLVM value then assume LLVM will pass it in the right
@@ -1073,10 +1099,16 @@ ABIArgInfo X86_64ABIInfo::getIndirectResult(QualType Ty,
ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
}
- bool ByVal = !isRecordWithNonTrivialDestructorOrCopyConstructor(Ty);
+ if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty))
+ return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
- // FIXME: Set alignment correctly.
- return ABIArgInfo::getIndirect(0, ByVal);
+ // Compute the byval alignment. We trust the back-end to honor the
+ // minimum ABI alignment for byval, to make cleaner IR.
+ const unsigned MinABIAlign = 8;
+ unsigned Align = Context.getTypeAlign(Ty) / 8;
+ if (Align > MinABIAlign)
+ return ABIArgInfo::getIndirect(Align);
+ return ABIArgInfo::getIndirect(0);
}
ABIArgInfo X86_64ABIInfo::classifyReturnType(QualType RetTy,
@@ -1104,7 +1136,7 @@ ABIArgInfo X86_64ABIInfo::classifyReturnType(QualType RetTy,
// AMD64-ABI 3.2.3p4: Rule 2. Types of class memory are returned via
// hidden argument.
case Memory:
- return getIndirectResult(RetTy, Context);
+ return getIndirectReturnResult(RetTy, Context);
// AMD64-ABI 3.2.3p4: Rule 3. If the class is INTEGER, the next
// available register of the sequence %rax, %rdx is used.
@@ -1126,7 +1158,8 @@ ABIArgInfo X86_64ABIInfo::classifyReturnType(QualType RetTy,
// %st1.
case ComplexX87:
assert(Hi == ComplexX87 && "Unexpected ComplexX87 classification.");
- ResType = llvm::StructType::get(VMContext, llvm::Type::getX86_FP80Ty(VMContext),
+ ResType = llvm::StructType::get(VMContext,
+ llvm::Type::getX86_FP80Ty(VMContext),
llvm::Type::getX86_FP80Ty(VMContext),
NULL);
break;
@@ -1574,7 +1607,7 @@ ABIArgInfo PIC16ABIInfo::classifyArgumentType(QualType Ty,
llvm::Value *PIC16ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
CodeGenFunction &CGF) const {
- const llvm::Type *BP = llvm::PointerType::getUnqual(llvm::Type::getInt8Ty(CGF.getLLVMContext()));
+ const llvm::Type *BP = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
const llvm::Type *BPP = llvm::PointerType::getUnqual(BP);
CGBuilderTy &Builder = CGF.Builder;
OpenPOWER on IntegriCloud