summaryrefslogtreecommitdiff
path: root/lib/CodeGen/CodeGenFunction.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-08-20 20:50:49 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-08-20 20:50:49 +0000
commit2298981669bf3bd63335a4be179bc0f96823a8f4 (patch)
tree1cbe2eb27f030d2d70b80ee5ca3c86bee7326a9f /lib/CodeGen/CodeGenFunction.cpp
parent9a83721404652cea39e9f02ae3e3b5c964602a5c (diff)
Notes
Diffstat (limited to 'lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp251
1 files changed, 42 insertions, 209 deletions
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index 1713e40c312b7..eafe26674434f 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -1,9 +1,8 @@
//===--- CodeGenFunction.cpp - Emit LLVM Code from ASTs for a Function ----===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -256,6 +255,7 @@ llvm::DebugLoc CodeGenFunction::EmitReturnBlock() {
if (CurBB->empty() || ReturnBlock.getBlock()->use_empty()) {
ReturnBlock.getBlock()->replaceAllUsesWith(CurBB);
delete ReturnBlock.getBlock();
+ ReturnBlock = JumpDest();
} else
EmitBlock(ReturnBlock.getBlock());
return llvm::DebugLoc();
@@ -275,6 +275,7 @@ llvm::DebugLoc CodeGenFunction::EmitReturnBlock() {
Builder.SetInsertPoint(BI->getParent());
BI->eraseFromParent();
delete ReturnBlock.getBlock();
+ ReturnBlock = JumpDest();
return Loc;
}
}
@@ -449,6 +450,19 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
// 5. Width of vector aguments and return types for functions called by this
// function.
CurFn->addFnAttr("min-legal-vector-width", llvm::utostr(LargestVectorWidth));
+
+ // If we generated an unreachable return block, delete it now.
+ if (ReturnBlock.isValid() && ReturnBlock.getBlock()->use_empty()) {
+ Builder.ClearInsertionPoint();
+ ReturnBlock.getBlock()->eraseFromParent();
+ }
+ if (ReturnValue.isValid()) {
+ auto *RetAlloca = dyn_cast<llvm::AllocaInst>(ReturnValue.getPointer());
+ if (RetAlloca && RetAlloca->use_empty()) {
+ RetAlloca->eraseFromParent();
+ ReturnValue = Address::invalid();
+ }
+ }
}
/// ShouldInstrumentFunction - Return true if the current function should be
@@ -522,205 +536,6 @@ CodeGenFunction::DecodeAddrUsedInPrologue(llvm::Value *F,
"decoded_addr");
}
-static void removeImageAccessQualifier(std::string& TyName) {
- std::string ReadOnlyQual("__read_only");
- std::string::size_type ReadOnlyPos = TyName.find(ReadOnlyQual);
- if (ReadOnlyPos != std::string::npos)
- // "+ 1" for the space after access qualifier.
- TyName.erase(ReadOnlyPos, ReadOnlyQual.size() + 1);
- else {
- std::string WriteOnlyQual("__write_only");
- std::string::size_type WriteOnlyPos = TyName.find(WriteOnlyQual);
- if (WriteOnlyPos != std::string::npos)
- TyName.erase(WriteOnlyPos, WriteOnlyQual.size() + 1);
- else {
- std::string ReadWriteQual("__read_write");
- std::string::size_type ReadWritePos = TyName.find(ReadWriteQual);
- if (ReadWritePos != std::string::npos)
- TyName.erase(ReadWritePos, ReadWriteQual.size() + 1);
- }
- }
-}
-
-// Returns the address space id that should be produced to the
-// kernel_arg_addr_space metadata. This is always fixed to the ids
-// as specified in the SPIR 2.0 specification in order to differentiate
-// for example in clGetKernelArgInfo() implementation between the address
-// spaces with targets without unique mapping to the OpenCL address spaces
-// (basically all single AS CPUs).
-static unsigned ArgInfoAddressSpace(LangAS AS) {
- switch (AS) {
- case LangAS::opencl_global: return 1;
- case LangAS::opencl_constant: return 2;
- case LangAS::opencl_local: return 3;
- case LangAS::opencl_generic: return 4; // Not in SPIR 2.0 specs.
- default:
- return 0; // Assume private.
- }
-}
-
-// OpenCL v1.2 s5.6.4.6 allows the compiler to store kernel argument
-// information in the program executable. The argument information stored
-// includes the argument name, its type, the address and access qualifiers used.
-static void GenOpenCLArgMetadata(const FunctionDecl *FD, llvm::Function *Fn,
- CodeGenModule &CGM, llvm::LLVMContext &Context,
- CGBuilderTy &Builder, ASTContext &ASTCtx) {
- // Create MDNodes that represent the kernel arg metadata.
- // Each MDNode is a list in the form of "key", N number of values which is
- // the same number of values as their are kernel arguments.
-
- const PrintingPolicy &Policy = ASTCtx.getPrintingPolicy();
-
- // MDNode for the kernel argument address space qualifiers.
- SmallVector<llvm::Metadata *, 8> addressQuals;
-
- // MDNode for the kernel argument access qualifiers (images only).
- SmallVector<llvm::Metadata *, 8> accessQuals;
-
- // MDNode for the kernel argument type names.
- SmallVector<llvm::Metadata *, 8> argTypeNames;
-
- // MDNode for the kernel argument base type names.
- SmallVector<llvm::Metadata *, 8> argBaseTypeNames;
-
- // MDNode for the kernel argument type qualifiers.
- SmallVector<llvm::Metadata *, 8> argTypeQuals;
-
- // MDNode for the kernel argument names.
- SmallVector<llvm::Metadata *, 8> argNames;
-
- for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) {
- const ParmVarDecl *parm = FD->getParamDecl(i);
- QualType ty = parm->getType();
- std::string typeQuals;
-
- if (ty->isPointerType()) {
- QualType pointeeTy = ty->getPointeeType();
-
- // Get address qualifier.
- addressQuals.push_back(llvm::ConstantAsMetadata::get(Builder.getInt32(
- ArgInfoAddressSpace(pointeeTy.getAddressSpace()))));
-
- // Get argument type name.
- std::string typeName =
- pointeeTy.getUnqualifiedType().getAsString(Policy) + "*";
-
- // Turn "unsigned type" to "utype"
- std::string::size_type pos = typeName.find("unsigned");
- if (pointeeTy.isCanonical() && pos != std::string::npos)
- typeName.erase(pos+1, 8);
-
- argTypeNames.push_back(llvm::MDString::get(Context, typeName));
-
- std::string baseTypeName =
- pointeeTy.getUnqualifiedType().getCanonicalType().getAsString(
- Policy) +
- "*";
-
- // Turn "unsigned type" to "utype"
- pos = baseTypeName.find("unsigned");
- if (pos != std::string::npos)
- baseTypeName.erase(pos+1, 8);
-
- argBaseTypeNames.push_back(llvm::MDString::get(Context, baseTypeName));
-
- // Get argument type qualifiers:
- if (ty.isRestrictQualified())
- typeQuals = "restrict";
- if (pointeeTy.isConstQualified() ||
- (pointeeTy.getAddressSpace() == LangAS::opencl_constant))
- typeQuals += typeQuals.empty() ? "const" : " const";
- if (pointeeTy.isVolatileQualified())
- typeQuals += typeQuals.empty() ? "volatile" : " volatile";
- } else {
- uint32_t AddrSpc = 0;
- bool isPipe = ty->isPipeType();
- if (ty->isImageType() || isPipe)
- AddrSpc = ArgInfoAddressSpace(LangAS::opencl_global);
-
- addressQuals.push_back(
- llvm::ConstantAsMetadata::get(Builder.getInt32(AddrSpc)));
-
- // Get argument type name.
- std::string typeName;
- if (isPipe)
- typeName = ty.getCanonicalType()->getAs<PipeType>()->getElementType()
- .getAsString(Policy);
- else
- typeName = ty.getUnqualifiedType().getAsString(Policy);
-
- // Turn "unsigned type" to "utype"
- std::string::size_type pos = typeName.find("unsigned");
- if (ty.isCanonical() && pos != std::string::npos)
- typeName.erase(pos+1, 8);
-
- std::string baseTypeName;
- if (isPipe)
- baseTypeName = ty.getCanonicalType()->getAs<PipeType>()
- ->getElementType().getCanonicalType()
- .getAsString(Policy);
- else
- baseTypeName =
- ty.getUnqualifiedType().getCanonicalType().getAsString(Policy);
-
- // Remove access qualifiers on images
- // (as they are inseparable from type in clang implementation,
- // but OpenCL spec provides a special query to get access qualifier
- // via clGetKernelArgInfo with CL_KERNEL_ARG_ACCESS_QUALIFIER):
- if (ty->isImageType()) {
- removeImageAccessQualifier(typeName);
- removeImageAccessQualifier(baseTypeName);
- }
-
- argTypeNames.push_back(llvm::MDString::get(Context, typeName));
-
- // Turn "unsigned type" to "utype"
- pos = baseTypeName.find("unsigned");
- if (pos != std::string::npos)
- baseTypeName.erase(pos+1, 8);
-
- argBaseTypeNames.push_back(llvm::MDString::get(Context, baseTypeName));
-
- if (isPipe)
- typeQuals = "pipe";
- }
-
- argTypeQuals.push_back(llvm::MDString::get(Context, typeQuals));
-
- // Get image and pipe access qualifier:
- if (ty->isImageType()|| ty->isPipeType()) {
- const Decl *PDecl = parm;
- if (auto *TD = dyn_cast<TypedefType>(ty))
- PDecl = TD->getDecl();
- const OpenCLAccessAttr *A = PDecl->getAttr<OpenCLAccessAttr>();
- if (A && A->isWriteOnly())
- accessQuals.push_back(llvm::MDString::get(Context, "write_only"));
- else if (A && A->isReadWrite())
- accessQuals.push_back(llvm::MDString::get(Context, "read_write"));
- else
- accessQuals.push_back(llvm::MDString::get(Context, "read_only"));
- } else
- accessQuals.push_back(llvm::MDString::get(Context, "none"));
-
- // Get argument name.
- argNames.push_back(llvm::MDString::get(Context, parm->getName()));
- }
-
- Fn->setMetadata("kernel_arg_addr_space",
- llvm::MDNode::get(Context, addressQuals));
- Fn->setMetadata("kernel_arg_access_qual",
- llvm::MDNode::get(Context, accessQuals));
- Fn->setMetadata("kernel_arg_type",
- llvm::MDNode::get(Context, argTypeNames));
- Fn->setMetadata("kernel_arg_base_type",
- llvm::MDNode::get(Context, argBaseTypeNames));
- Fn->setMetadata("kernel_arg_type_qual",
- llvm::MDNode::get(Context, argTypeQuals));
- if (CGM.getCodeGenOpts().EmitOpenCLArgMetadata)
- Fn->setMetadata("kernel_arg_name",
- llvm::MDNode::get(Context, argNames));
-}
-
void CodeGenFunction::EmitOpenCLKernelMetadata(const FunctionDecl *FD,
llvm::Function *Fn)
{
@@ -729,7 +544,7 @@ void CodeGenFunction::EmitOpenCLKernelMetadata(const FunctionDecl *FD,
llvm::LLVMContext &Context = getLLVMContext();
- GenOpenCLArgMetadata(FD, Fn, CGM, Context, Builder, getContext());
+ CGM.GenOpenCLArgMetadata(Fn, FD, this);
if (const VecTypeHintAttr *A = FD->getAttr<VecTypeHintAttr>()) {
QualType HintQTy = A->getTypeHint();
@@ -881,6 +696,8 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,
Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
if (SanOpts.hasOneOf(SanitizerKind::HWAddress | SanitizerKind::KernelHWAddress))
Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);
+ if (SanOpts.has(SanitizerKind::MemTag))
+ Fn->addFnAttr(llvm::Attribute::SanitizeMemTag);
if (SanOpts.has(SanitizerKind::Thread))
Fn->addFnAttr(llvm::Attribute::SanitizeThread);
if (SanOpts.hasOneOf(SanitizerKind::Memory | SanitizerKind::KernelMemory))
@@ -1080,6 +897,13 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,
if (CurFnInfo->getReturnInfo().isSRetAfterThis())
++AI;
ReturnValue = Address(&*AI, CurFnInfo->getReturnInfo().getIndirectAlign());
+ if (!CurFnInfo->getReturnInfo().getIndirectByVal()) {
+ ReturnValuePointer =
+ CreateDefaultAlignTempAlloca(Int8PtrTy, "result.ptr");
+ Builder.CreateStore(Builder.CreatePointerBitCastOrAddrSpaceCast(
+ ReturnValue.getPointer(), Int8PtrTy),
+ ReturnValuePointer);
+ }
} else if (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::InAlloca &&
!hasScalarEvaluationKind(CurFnInfo->getReturnType())) {
// Load the sret pointer from the argument struct and return into that.
@@ -1087,6 +911,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,
llvm::Function::arg_iterator EI = CurFn->arg_end();
--EI;
llvm::Value *Addr = Builder.CreateStructGEP(nullptr, &*EI, Idx);
+ ReturnValuePointer = Address(Addr, getPointerAlign());
Addr = Builder.CreateAlignedLoad(Addr, getPointerAlign(), "agg.result");
ReturnValue = Address(Addr, getNaturalTypeAlignment(RetTy));
} else {
@@ -2135,6 +1960,7 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) {
case Type::Attributed:
case Type::SubstTemplateTypeParm:
case Type::PackExpansion:
+ case Type::MacroQualified:
// Keep walking after single level desugaring.
type = type.getSingleStepDesugaredType(getContext());
break;
@@ -2174,7 +2000,7 @@ Address CodeGenFunction::EmitMSVAListRef(const Expr *E) {
void CodeGenFunction::EmitDeclRefExprDbgValue(const DeclRefExpr *E,
const APValue &Init) {
- assert(!Init.isUninit() && "Invalid DeclRefExpr initializer!");
+ assert(Init.hasValue() && "Invalid DeclRefExpr initializer!");
if (CGDebugInfo *Dbg = getDebugInfo())
if (CGM.getCodeGenOpts().getDebugInfo() >= codegenoptions::LimitedDebugInfo)
Dbg->EmitGlobalVariable(E->getDecl(), Init);
@@ -2250,7 +2076,7 @@ void CodeGenFunction::EmitAlignmentAssumption(llvm::Value *PtrValue,
OffsetValue);
}
-llvm::Value *CodeGenFunction::EmitAnnotationCall(llvm::Value *AnnotationFn,
+llvm::Value *CodeGenFunction::EmitAnnotationCall(llvm::Function *AnnotationFn,
llvm::Value *AnnotatedVal,
StringRef AnnotationStr,
SourceLocation Location) {
@@ -2278,7 +2104,7 @@ Address CodeGenFunction::EmitFieldAnnotations(const FieldDecl *D,
assert(D->hasAttr<AnnotateAttr>() && "no annotate attribute");
llvm::Value *V = Addr.getPointer();
llvm::Type *VTy = V->getType();
- llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::ptr_annotation,
+ llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::ptr_annotation,
CGM.Int8PtrTy);
for (const auto *I : D->specific_attrs<AnnotateAttr>()) {
@@ -2355,6 +2181,13 @@ static bool hasRequiredFeatures(const SmallVectorImpl<StringRef> &ReqFeatures,
// called function.
void CodeGenFunction::checkTargetFeatures(const CallExpr *E,
const FunctionDecl *TargetDecl) {
+ return checkTargetFeatures(E->getBeginLoc(), TargetDecl);
+}
+
+// Emits an error if we don't have a valid set of target features for the
+// called function.
+void CodeGenFunction::checkTargetFeatures(SourceLocation Loc,
+ const FunctionDecl *TargetDecl) {
// Early exit if this is an indirect call.
if (!TargetDecl)
return;
@@ -2379,7 +2212,7 @@ void CodeGenFunction::checkTargetFeatures(const CallExpr *E,
return;
StringRef(FeatureList).split(ReqFeatures, ',');
if (!hasRequiredFeatures(ReqFeatures, CGM, FD, MissingFeature))
- CGM.getDiags().Report(E->getBeginLoc(), diag::err_builtin_needs_feature)
+ CGM.getDiags().Report(Loc, diag::err_builtin_needs_feature)
<< TargetDecl->getDeclName()
<< CGM.getContext().BuiltinInfo.getRequiredFeatures(BuiltinID);
@@ -2405,7 +2238,7 @@ void CodeGenFunction::checkTargetFeatures(const CallExpr *E,
ReqFeatures.push_back(F.getKey());
}
if (!hasRequiredFeatures(ReqFeatures, CGM, FD, MissingFeature))
- CGM.getDiags().Report(E->getBeginLoc(), diag::err_function_needs_feature)
+ CGM.getDiags().Report(Loc, diag::err_function_needs_feature)
<< FD->getDeclName() << TargetDecl->getDeclName() << MissingFeature;
}
}