[llvm-commits] [llvm] r123596 - in /llvm/trunk: lib/Transforms/IPO/DeadArgumentElimination.cpp test/Transforms/DeadArgElim/deadexternal.ll
Anders Carlsson
andersca at mac.com
Sun Jan 16 13:25:33 PST 2011
Author: andersca
Date: Sun Jan 16 15:25:33 2011
New Revision: 123596
URL: http://llvm.org/viewvc/llvm-project?rev=123596&view=rev
Log:
Teach DAE to look for functions whose arguments are unused, and change all callers to pass in an undefvalue instead.
Modified:
llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp
llvm/trunk/test/Transforms/DeadArgElim/deadexternal.ll
Modified: llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp?rev=123596&r1=123595&r2=123596&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp Sun Jan 16 15:25:33 2011
@@ -39,7 +39,8 @@
STATISTIC(NumArgumentsEliminated, "Number of unread args removed");
STATISTIC(NumRetValsEliminated , "Number of unused return values removed");
-
+STATISTIC(NumArgumentsReplacedWithUndef,
+ "Number of unread args replaced with undef");
namespace {
/// DAE - The dead argument elimination pass.
///
@@ -148,6 +149,7 @@
void PropagateLiveness(const RetOrArg &RA);
bool RemoveDeadStuffFromFunction(Function *F);
bool DeleteDeadVarargs(Function &Fn);
+ bool RemoveDeadArgumentsFromCallers(Function &Fn);
};
}
@@ -287,6 +289,55 @@
return true;
}
+/// RemoveDeadArgumentsFromCallers - Checks if the given function has any
+/// arguments that are unused, and changes the caller parameters to be undefined
+/// instead.
+bool DAE::RemoveDeadArgumentsFromCallers(Function &Fn)
+{
+ if (Fn.isDeclaration())
+ return false;
+
+ // Functions with local linkage should already have been handled.
+ if (Fn.hasLocalLinkage())
+ return false;
+
+ if (Fn.use_empty())
+ return false;
+
+ llvm::SmallVector<unsigned, 8> UnusedArgs;
+ for (Function::arg_iterator I = Fn.arg_begin(), E = Fn.arg_end();
+ I != E; ++I) {
+ Argument *Arg = I;
+
+ if (Arg->use_empty() && !Arg->hasByValAttr())
+ UnusedArgs.push_back(Arg->getArgNo());
+ }
+
+ if (UnusedArgs.empty())
+ return false;
+
+ bool Changed = false;
+
+ for (Function::use_iterator I = Fn.use_begin(), E = Fn.use_end();
+ I != E; ++I) {
+ CallSite CS(*I);
+ if (!CS || !CS.isCallee(I))
+ continue;
+
+ // Now go through all unused args and replace them with "undef".
+ for (unsigned I = 0, E = UnusedArgs.size(); I != E; ++I) {
+ unsigned ArgNo = UnusedArgs[I];
+
+ Value *Arg = CS.getArgument(ArgNo);
+ CS.setArgument(ArgNo, UndefValue::get(Arg->getType()));
+ ++NumArgumentsReplacedWithUndef;
+ Changed = true;
+ }
+ }
+
+ return Changed;
+}
+
/// Convenience function that returns the number of return values. It returns 0
/// for void functions and 1 for functions not returning a struct. It returns
/// the number of struct elements for functions returning a struct.
@@ -939,5 +990,14 @@
Function *F = I++;
Changed |= RemoveDeadStuffFromFunction(F);
}
+
+ // Finally, look for any unused parameters in functions with non-local
+ // linkage and replace the passed in parameters with undef.
+ for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
+ Function& F = *I;
+
+ Changed |= RemoveDeadArgumentsFromCallers(F);
+ }
+
return Changed;
}
Modified: llvm/trunk/test/Transforms/DeadArgElim/deadexternal.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/DeadArgElim/deadexternal.ll?rev=123596&r1=123595&r2=123596&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/DeadArgElim/deadexternal.ll (original)
+++ llvm/trunk/test/Transforms/DeadArgElim/deadexternal.ll Sun Jan 16 15:25:33 2011
@@ -1,5 +1,4 @@
; RUN: opt -deadargelim -S %s | FileCheck %s
-; XFAIL: *
define void @test(i32) {
ret void
@@ -11,3 +10,30 @@
; CHECK: @foo
; CHECK: i32 undef
}
+
+define void @f(i32 %X) {
+entry:
+ tail call void @sideeffect() nounwind
+ ret void
+}
+
+declare void @sideeffect()
+
+define void @g(i32 %n) {
+entry:
+ %add = add nsw i32 %n, 1
+; CHECK: tail call void @f(i32 undef)
+ tail call void @f(i32 %add)
+ ret void
+}
+
+define void @h() {
+entry:
+ %i = alloca i32, align 4
+ volatile store i32 10, i32* %i, align 4
+; CHECK: %tmp = volatile load i32* %i, align 4
+; CHECK-next: call void @f(i32 undef)
+ %tmp = volatile load i32* %i, align 4
+ call void @f(i32 %tmp)
+ ret void
+}
More information about the llvm-commits
mailing list