summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGCall.cpp
diff options
context:
space:
mode:
authorHal Finkel <hfinkel@anl.gov>2014-07-19 01:41:07 +0000
committerHal Finkel <hfinkel@anl.gov>2014-07-19 01:41:07 +0000
commit48d53e2c4c9131766e61fb52c7876fbcf9859463 (patch)
tree82adc871289f565e71d1207baa8f3e278664ae47 /clang/lib/CodeGen/CGCall.cpp
parent1b98ccc4e9576e86fb3e235bac3076472a84f875 (diff)
downloadbcm5719-llvm-48d53e2c4c9131766e61fb52c7876fbcf9859463.tar.gz
bcm5719-llvm-48d53e2c4c9131766e61fb52c7876fbcf9859463.zip
Use the dereferenceable attribute on C99 array parameters with static
In C99, an array parameter declarator might have the form: direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']' where the static keyword indicates that the caller will always provide a pointer to the beginning of an array with at least the number of elements specified by the assignment expression. For constant sizes, we can use the new dereferenceable attribute to pass this information to the optimizer. For VLAs, we don't know the size, but (for addrspace(0)) do know that the pointer must be nonnull (and so we can use the nonnull attribute). llvm-svn: 213444
Diffstat (limited to 'clang/lib/CodeGen/CGCall.cpp')
-rw-r--r--clang/lib/CodeGen/CGCall.cpp38
1 files changed, 37 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 4ee2373793b..f15c1b7321a 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -1486,13 +1486,49 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
assert(AI != Fn->arg_end() && "Argument mismatch!");
llvm::Value *V = AI;
- if (const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(Arg))
+ if (const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(Arg)) {
if ((NNAtt && NNAtt->isNonNull(PVD->getFunctionScopeIndex())) ||
PVD->hasAttr<NonNullAttr>())
AI->addAttr(llvm::AttributeSet::get(getLLVMContext(),
AI->getArgNo() + 1,
llvm::Attribute::NonNull));
+ QualType OTy = PVD->getOriginalType();
+ if (const auto *ArrTy =
+ getContext().getAsConstantArrayType(OTy)) {
+ // A C99 array parameter declaration with the static keyword also
+ // indicates dereferenceability, and if the size is constant we can
+ // use the dereferenceable attribute (which requires the size in
+ // bytes).
+ if (ArrTy->getSizeModifier() == VariableArrayType::Static) {
+ QualType ETy = ArrTy->getElementType();
+ uint64_t ArrSize = ArrTy->getSize().getZExtValue();
+ if (!ETy->isIncompleteType() && ETy->isConstantSizeType() &&
+ ArrSize) {
+ llvm::AttrBuilder Attrs;
+ Attrs.addDereferenceableAttr(
+ getContext().getTypeSizeInChars(ETy).getQuantity()*ArrSize);
+ AI->addAttr(llvm::AttributeSet::get(getLLVMContext(),
+ AI->getArgNo() + 1, Attrs));
+ } else if (getContext().getTargetAddressSpace(ETy) == 0) {
+ AI->addAttr(llvm::AttributeSet::get(getLLVMContext(),
+ AI->getArgNo() + 1,
+ llvm::Attribute::NonNull));
+ }
+ }
+ } else if (const auto *ArrTy =
+ getContext().getAsVariableArrayType(OTy)) {
+ // For C99 VLAs with the static keyword, we don't know the size so
+ // we can't use the dereferenceable attribute, but in addrspace(0)
+ // we know that it must be nonnull.
+ if (ArrTy->getSizeModifier() == VariableArrayType::Static &&
+ !getContext().getTargetAddressSpace(ArrTy->getElementType()))
+ AI->addAttr(llvm::AttributeSet::get(getLLVMContext(),
+ AI->getArgNo() + 1,
+ llvm::Attribute::NonNull));
+ }
+ }
+
if (Arg->getType().isRestrictQualified())
AI->addAttr(llvm::AttributeSet::get(getLLVMContext(),
AI->getArgNo() + 1,
OpenPOWER on IntegriCloud