aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CodeGenFunction.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp107
1 files changed, 66 insertions, 41 deletions
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index e2a18d3eb9..27ef65fa94 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -77,45 +77,53 @@ llvm::Type *CodeGenFunction::ConvertType(QualType T) {
return CGM.getTypes().ConvertType(T);
}
-bool CodeGenFunction::hasAggregateLLVMType(QualType type) {
- switch (type.getCanonicalType()->getTypeClass()) {
+TypeEvaluationKind CodeGenFunction::getEvaluationKind(QualType type) {
+ type = type.getCanonicalType();
+ while (true) {
+ switch (type->getTypeClass()) {
#define TYPE(name, parent)
#define ABSTRACT_TYPE(name, parent)
#define NON_CANONICAL_TYPE(name, parent) case Type::name:
#define DEPENDENT_TYPE(name, parent) case Type::name:
#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(name, parent) case Type::name:
#include "clang/AST/TypeNodes.def"
- llvm_unreachable("non-canonical or dependent type in IR-generation");
-
- case Type::Builtin:
- case Type::Pointer:
- case Type::BlockPointer:
- case Type::LValueReference:
- case Type::RValueReference:
- case Type::MemberPointer:
- case Type::Vector:
- case Type::ExtVector:
- case Type::FunctionProto:
- case Type::FunctionNoProto:
- case Type::Enum:
- case Type::ObjCObjectPointer:
- return false;
+ llvm_unreachable("non-canonical or dependent type in IR-generation");
- // Complexes, arrays, records, and Objective-C objects.
- case Type::Complex:
- case Type::ConstantArray:
- case Type::IncompleteArray:
- case Type::VariableArray:
- case Type::Record:
- case Type::ObjCObject:
- case Type::ObjCInterface:
- return true;
+ // Various scalar types.
+ case Type::Builtin:
+ case Type::Pointer:
+ case Type::BlockPointer:
+ case Type::LValueReference:
+ case Type::RValueReference:
+ case Type::MemberPointer:
+ case Type::Vector:
+ case Type::ExtVector:
+ case Type::FunctionProto:
+ case Type::FunctionNoProto:
+ case Type::Enum:
+ case Type::ObjCObjectPointer:
+ return TEK_Scalar;
+
+ // Complexes.
+ case Type::Complex:
+ return TEK_Complex;
- // In IRGen, atomic types are just the underlying type
- case Type::Atomic:
- return hasAggregateLLVMType(type->getAs<AtomicType>()->getValueType());
+ // Arrays, records, and Objective-C objects.
+ case Type::ConstantArray:
+ case Type::IncompleteArray:
+ case Type::VariableArray:
+ case Type::Record:
+ case Type::ObjCObject:
+ case Type::ObjCInterface:
+ return TEK_Aggregate;
+
+ // We operate on atomic values according to their underlying type.
+ case Type::Atomic:
+ type = cast<AtomicType>(type)->getValueType();
+ continue;
+ }
+ llvm_unreachable("unknown type kind!");
}
- llvm_unreachable("unknown type kind!");
}
void CodeGenFunction::EmitReturnBlock() {
@@ -258,9 +266,12 @@ void CodeGenFunction::EmitFunctionInstrumentation(const char *Fn) {
llvm::ConstantInt::get(Int32Ty, 0),
"callsite");
- Builder.CreateCall2(F,
- llvm::ConstantExpr::getBitCast(CurFn, PointerTy),
- CallSite);
+ llvm::Value *args[] = {
+ llvm::ConstantExpr::getBitCast(CurFn, PointerTy),
+ CallSite
+ };
+
+ EmitNounwindRuntimeCall(F, args);
}
void CodeGenFunction::EmitMCountInstrumentation() {
@@ -268,7 +279,7 @@ void CodeGenFunction::EmitMCountInstrumentation() {
llvm::Constant *MCountFn = CGM.CreateRuntimeFunction(FTy,
Target.getMCountName());
- Builder.CreateCall(MCountFn);
+ EmitNounwindRuntimeCall(MCountFn);
}
// OpenCL v1.2 s5.6.4.6 allows the compiler to store kernel argument
@@ -312,6 +323,23 @@ void CodeGenFunction::EmitOpenCLKernelMetadata(const FunctionDecl *FD,
if (CGM.getCodeGenOpts().EmitOpenCLArgMetadata)
GenOpenCLArgMetadata(FD, Fn, CGM, Context, kernelMDArgs);
+ if (FD->hasAttr<VecTypeHintAttr>()) {
+ VecTypeHintAttr *attr = FD->getAttr<VecTypeHintAttr>();
+ QualType hintQTy = attr->getTypeHint();
+ const ExtVectorType *hintEltQTy = hintQTy->getAs<ExtVectorType>();
+ bool isSignedInteger =
+ hintQTy->isSignedIntegerType() ||
+ (hintEltQTy && hintEltQTy->getElementType()->isSignedIntegerType());
+ llvm::Value *attrMDArgs[] = {
+ llvm::MDString::get(Context, "vec_type_hint"),
+ llvm::UndefValue::get(CGM.getTypes().ConvertType(attr->getTypeHint())),
+ llvm::ConstantInt::get(
+ llvm::IntegerType::get(Context, 32),
+ llvm::APInt(32, (uint64_t)(isSignedInteger ? 1 : 0)))
+ };
+ kernelMDArgs.push_back(llvm::MDNode::get(Context, attrMDArgs));
+ }
+
if (FD->hasAttr<WorkGroupSizeHintAttr>()) {
WorkGroupSizeHintAttr *attr = FD->getAttr<WorkGroupSizeHintAttr>();
llvm::Value *attrMDArgs[] = {
@@ -392,19 +420,16 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
// Emit subprogram debug descriptor.
if (CGDebugInfo *DI = getDebugInfo()) {
- unsigned NumArgs = 0;
- QualType *ArgsArray = new QualType[Args.size()];
+ SmallVector<QualType, 16> ArgTypes;
for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end();
i != e; ++i) {
- ArgsArray[NumArgs++] = (*i)->getType();
+ ArgTypes.push_back((*i)->getType());
}
QualType FnType =
- getContext().getFunctionType(RetTy, ArgsArray, NumArgs,
+ getContext().getFunctionType(RetTy, ArgTypes,
FunctionProtoType::ExtProtoInfo());
- delete[] ArgsArray;
-
DI->setLocation(StartLoc);
DI->EmitFunctionStart(GD, FnType, CurFn, Builder);
}
@@ -419,7 +444,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
// Void type; nothing to return.
ReturnValue = 0;
} else if (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect &&
- hasAggregateLLVMType(CurFnInfo->getReturnType())) {
+ !hasScalarEvaluationKind(CurFnInfo->getReturnType())) {
// Indirect aggregate return; emit returned value directly into sret slot.
// This reduces code size, and affects correctness in C++.
ReturnValue = CurFn->arg_begin();