[llvm-commits] [llvm] r61552 - in /llvm/trunk: lib/Transforms/IPO/FunctionAttrs.cpp test/Transforms/FunctionAttrs/2008-12-31-NoCapture.ll
Nick Lewycky
nicholas at mxc.ca
Thu Jan 1 19:46:56 PST 2009
Author: nicholas
Date: Thu Jan 1 21:46:56 2009
New Revision: 61552
URL: http://llvm.org/viewvc/llvm-project?rev=61552&view=rev
Log:
Make adding nocapture a bit stronger. FreeInst is nocapture. Also,
functions that don't write can't leak a pointer except through
the return value, so a void readonly function is implicitly nocapture.
Test these, and add a test that verifies that f1 calling f2 with an
otherwise dead pointer gets both of them marked nocapture.
Modified:
llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp
llvm/trunk/test/Transforms/FunctionAttrs/2008-12-31-NoCapture.ll
Modified: llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp?rev=61552&r1=61551&r2=61552&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp Thu Jan 1 21:46:56 2009
@@ -208,10 +208,20 @@
continue;
}
+ if (isa<FreeInst>(I)) {
+ // Freeing a pointer does not cause it to escape.
+ continue;
+ }
+
CallSite CS = CallSite::get(I);
if (CS.getInstruction()) {
- // Does not escape if only passed via 'nocapture' arguments. Note
- // that calling a function pointer does not in itself cause that
+ // Does not escape if the callee is readonly and doesn't return a
+ // copy through its own return value.
+ if (CS.onlyReadsMemory() && I->getType() == Type::VoidTy)
+ continue;
+
+ // Does not escape if passed via 'nocapture' arguments. Note that
+ // calling a function pointer does not in itself cause that
// function pointer to escape. This is a subtle point considering
// that (for example) the callee might return its own address. It
// is analogous to saying that loading a value from a pointer does
@@ -264,6 +274,20 @@
// External node - skip it;
continue;
+ // If the function is readonly and doesn't return any value, we
+ // know that the pointer value can't escape. Mark all of its pointer
+ // arguments nocapture.
+ if (F->onlyReadsMemory() && F->getReturnType() == Type::VoidTy) {
+ for (Function::arg_iterator A = F->arg_begin(), E = F->arg_end();
+ A != E; ++A)
+ if (isa<PointerType>(A->getType()) && !A->hasNoCaptureAttr()) {
+ A->addAttr(Attribute::NoCapture);
+ ++NumNoCapture;
+ Changed = true;
+ }
+ continue;
+ }
+
// Definitions with weak linkage may be overridden at linktime with
// something that writes memory, so treat them like declarations.
if (F->isDeclaration() || F->mayBeOverridden())
@@ -273,7 +297,7 @@
if (isa<PointerType>(A->getType()) && !A->hasNoCaptureAttr() &&
!isCaptured(*F, A)) {
A->addAttr(Attribute::NoCapture);
- NumNoCapture++;
+ ++NumNoCapture;
Changed = true;
}
}
Modified: llvm/trunk/test/Transforms/FunctionAttrs/2008-12-31-NoCapture.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/FunctionAttrs/2008-12-31-NoCapture.ll?rev=61552&r1=61551&r2=61552&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/FunctionAttrs/2008-12-31-NoCapture.ll (original)
+++ llvm/trunk/test/Transforms/FunctionAttrs/2008-12-31-NoCapture.ll Thu Jan 1 21:46:56 2009
@@ -1,5 +1,5 @@
; RUN: llvm-as < %s | opt -functionattrs | llvm-dis | not grep {nocapture *%%q}
-; RUN: llvm-as < %s | opt -functionattrs | llvm-dis | grep {nocapture *%%p} | count 3
+; RUN: llvm-as < %s | opt -functionattrs | llvm-dis | grep {nocapture *%%p} | count 8
@g = global i32* null ; <i32**> [#uses=1]
define i32* @c1(i32* %q) {
@@ -62,3 +62,25 @@
call void %p()
ret void
}
+
+declare void @external(i8*) readonly
+define void @nc4(i8* %p) {
+ call void @external(i8* %p)
+ ret void
+}
+
+define void @nc5(void (i8*)* %f, i8* %p) {
+ call void %f(i8* %p) readonly
+ call void %f(i8* nocapture %p)
+ ret void
+}
+
+define void @nc6(i8* %p) {
+ call void @nc7(i8* %p)
+ ret void
+}
+
+define void @nc7(i8* %p) {
+ call void @nc6(i8* %p)
+ ret void
+}
More information about the llvm-commits
mailing list