diff options
| author | Bjorn Steinbrink <bsteinbr@gmail.com> | 2014-10-16 19:43:08 +0000 |
|---|---|---|
| committer | Bjorn Steinbrink <bsteinbr@gmail.com> | 2014-10-16 19:43:08 +0000 |
| commit | d20816fde95cb3c2467ef726790c06e8009a2653 (patch) | |
| tree | d4d8f2f76be9647f098c886c8d40822c0e5fed92 /llvm/lib/Transforms | |
| parent | 51720673915e21fbe2756e9ec7a2b38f9b53396c (diff) | |
| download | bcm5719-llvm-d20816fde95cb3c2467ef726790c06e8009a2653.tar.gz bcm5719-llvm-d20816fde95cb3c2467ef726790c06e8009a2653.zip | |
Allow call-slop optzn for destinations with a suitable dereferenceable attribute
Summary:
Currently, call slot optimization requires that if the destination is an
argument, the argument has the sret attribute. This is to ensure that
the memory access won't trap. In addition to sret, we can also allow the
optimization to happen for arguments that have the new dereferenceable
attribute, which gives the same guarantee.
Subscribers: llvm-commits
Differential Revision: http://reviews.llvm.org/D5832
llvm-svn: 219950
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp | 30 |
1 files changed, 16 insertions, 14 deletions
diff --git a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp index 9709dfcc1f6..be524be0082 100644 --- a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp +++ b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp @@ -634,22 +634,24 @@ bool MemCpyOpt::performCallSlotOptzn(Instruction *cpy, if (destSize < srcSize) return false; } else if (Argument *A = dyn_cast<Argument>(cpyDest)) { - // If the destination is an sret parameter then only accesses that are - // outside of the returned struct type can trap. - if (!A->hasStructRetAttr()) - return false; + if (A->getDereferenceableBytes() < srcSize) { + // If the destination is an sret parameter then only accesses that are + // outside of the returned struct type can trap. + if (!A->hasStructRetAttr()) + return false; - Type *StructTy = cast<PointerType>(A->getType())->getElementType(); - if (!StructTy->isSized()) { - // The call may never return and hence the copy-instruction may never - // be executed, and therefore it's not safe to say "the destination - // has at least <cpyLen> bytes, as implied by the copy-instruction", - return false; - } + Type *StructTy = cast<PointerType>(A->getType())->getElementType(); + if (!StructTy->isSized()) { + // The call may never return and hence the copy-instruction may never + // be executed, and therefore it's not safe to say "the destination + // has at least <cpyLen> bytes, as implied by the copy-instruction", + return false; + } - uint64_t destSize = DL->getTypeAllocSize(StructTy); - if (destSize < srcSize) - return false; + uint64_t destSize = DL->getTypeAllocSize(StructTy); + if (destSize < srcSize) + return false; + } } else { return false; } |

