[llvm-commits] [llvm] r101213 - /llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp

Nick Lewycky nicholas at mxc.ca
Tue Apr 13 20:38:11 PDT 2010


Author: nicholas
Date: Tue Apr 13 22:38:11 2010
New Revision: 101213

URL: http://llvm.org/viewvc/llvm-project?rev=101213&view=rev
Log:
While DAE can't modify the function signature of an externally visible function,
it can check whether the visible direct callers are passing in parameters to
dead arguments and replace those with undef.

This reinstates r94322 with bugs fixed.

Modified:
    llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp

Modified: llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp?rev=101213&r1=101212&r2=101213&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp Tue Apr 13 22:38:11 2010
@@ -30,6 +30,7 @@
 #include "llvm/Support/CallSite.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/Utils/Local.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/StringExtras.h"
@@ -37,8 +38,9 @@
 #include <set>
 using namespace llvm;
 
-STATISTIC(NumArgumentsEliminated, "Number of unread args removed");
-STATISTIC(NumRetValsEliminated  , "Number of unused return values removed");
+STATISTIC(NumArgumentsEliminated , "Number of unread args removed");
+STATISTIC(NumRetValsEliminated   , "Number of unused return values removed");
+STATISTIC(NumParametersEliminated, "Number of parameters replaced with undef");
 
 namespace {
   /// DAE - The dead argument elimination pass.
@@ -140,6 +142,7 @@
     void MarkLive(const Function &F);
     void PropagateLiveness(const RetOrArg &RA);
     bool RemoveDeadStuffFromFunction(Function *F);
+    bool RemoveDeadParamsFromCallersOf(Function *F);
     bool DeleteDeadVarargs(Function &Fn);
   };
 }
@@ -397,7 +400,9 @@
 // map.
 //
 // We consider arguments of non-internal functions to be intrinsically alive as
-// well as arguments to functions which have their "address taken".
+// well as arguments to functions which have their "address taken". Externally
+// visible functions are assumed to only have their return values intrinsically
+// alive, permitting removal of parameters to unused arguments in callers.
 //
 void DAE::SurveyFunction(const Function &F) {
   unsigned RetCount = NumRetVals(&F);
@@ -420,7 +425,14 @@
         return;
       }
 
-  if (!F.hasLocalLinkage() && (!ShouldHackArguments() || F.isIntrinsic())) {
+  if (F.hasExternalLinkage() && !F.isDeclaration()) {
+    DEBUG(dbgs() << "DAE - Intrinsically live return from " << F.getName()
+                 << "\n");
+    // Mark the return values alive.
+    for (unsigned i = 0, e = NumRetVals(&F); i != e; ++i)
+      MarkLive(CreateRet(&F, i));
+  } else if (!F.hasLocalLinkage() &&
+             (!ShouldHackArguments() || F.isIntrinsic())) {
     MarkLive(F);
     return;
   }
@@ -532,14 +544,14 @@
 /// values (according to Uses) live as well.
 void DAE::MarkLive(const Function &F) {
   DEBUG(dbgs() << "DAE - Intrinsically live fn: " << F.getName() << "\n");
-    // Mark the function as live.
-    LiveFunctions.insert(&F);
-    // Mark all arguments as live.
-    for (unsigned i = 0, e = F.arg_size(); i != e; ++i)
-      PropagateLiveness(CreateArg(&F, i));
-    // Mark all return values as live.
-    for (unsigned i = 0, e = NumRetVals(&F); i != e; ++i)
-      PropagateLiveness(CreateRet(&F, i));
+  // Mark the function as live.
+  LiveFunctions.insert(&F);
+  // Mark all arguments as live.
+  for (unsigned i = 0, e = F.arg_size(); i != e; ++i)
+    PropagateLiveness(CreateArg(&F, i));
+  // Mark all return values as live.
+  for (unsigned i = 0, e = NumRetVals(&F); i != e; ++i)
+    PropagateLiveness(CreateRet(&F, i));
 }
 
 /// MarkLive - Mark the given return value or argument as live. Additionally,
@@ -853,7 +865,7 @@
       if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) {
         Value *RetVal;
 
-        if (NFTy->getReturnType() == Type::getVoidTy(F->getContext())) {
+        if (NFTy->getReturnType()->isVoidTy()) {
           RetVal = 0;
         } else {
           assert (RetTy->isStructTy());
@@ -894,6 +906,43 @@
   return true;
 }
 
+bool DAE::RemoveDeadParamsFromCallersOf(Function *F) {
+  // Don't modify fully live functions
+  if (LiveFunctions.count(F))
+    return false;
+
+  // Make a list of the dead arguments.
+  SmallVector<int, 10> ArgDead;
+  unsigned i = 0;
+  for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end();
+       I != E; ++I, ++i) {
+    RetOrArg Arg = CreateArg(F, i);
+    if (!LiveValues.count(Arg))
+      ArgDead.push_back(i);
+  }
+  if (ArgDead.empty())
+    return false;
+
+  bool MadeChange = false;
+  for (Function::use_iterator I = F->use_begin(), E = F->use_end();
+       I != E; ++I) {
+    CallSite CS = CallSite::get(*I);
+    if (CS.getInstruction() && CS.isCallee(I)) {
+      for (unsigned i = 0, e = ArgDead.size(); i != e; ++i) {
+        Value *A = CS.getArgument(ArgDead[i]);
+        if (!isa<UndefValue>(A)) {
+	  ++NumParametersEliminated;
+          MadeChange = true;
+          CS.setArgument(ArgDead[i], UndefValue::get(A->getType()));
+          RecursivelyDeleteTriviallyDeadInstructions(A);
+        }
+      }
+    }
+  }
+
+  return MadeChange;
+}
+
 bool DAE::runOnModule(Module &M) {
   bool Changed = false;
 
@@ -922,7 +971,10 @@
     // Increment now, because the function will probably get removed (ie.
     // replaced by a new one).
     Function *F = I++;
-    Changed |= RemoveDeadStuffFromFunction(F);
+    if (F->hasExternalLinkage() && !F->isDeclaration())
+      Changed |= RemoveDeadParamsFromCallersOf(F);
+    else
+      Changed |= RemoveDeadStuffFromFunction(F);
   }
   return Changed;
 }





More information about the llvm-commits mailing list