changeset 1319:c32e27f9a61d

Some tweaks to -simplify-drtcalls.
author Frits van Bommel <fvbommel wxs.nl>
date Sat, 09 May 2009 02:34:27 +0200
parents bac742d3a72d
children d55945bcb02d
files gen/passes/SimplifyDRuntimeCalls.cpp
diffstat 1 files changed, 37 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/gen/passes/SimplifyDRuntimeCalls.cpp	Sat May 09 00:55:47 2009 +0200
+++ b/gen/passes/SimplifyDRuntimeCalls.cpp	Sat May 09 02:34:27 2009 +0200
@@ -29,6 +29,7 @@
 using namespace llvm;
 
 STATISTIC(NumSimplified, "Number of runtime calls simplified");
+STATISTIC(NumDeleted, "Number of runtime calls deleted");
 
 //===----------------------------------------------------------------------===//
 // Optimizer Base Class
@@ -80,6 +81,11 @@
             FT->getParamType(3) != FT->getReturnType())
           return 0;
         
+        // Whether or not this allocates is irrelevant if the result isn't used.
+        // Just delete if that's the case.
+        if (CI->use_empty())
+            return CI;
+        
         Value* NewLen = CI->getOperand(2);
         if (Constant* NewCst = dyn_cast<Constant>(NewLen)) {
             Value* Data = CI->getOperand(4);
@@ -182,6 +188,8 @@
         void InitOptimizations();
         bool runOnFunction(Function &F);
         
+        bool runOnce(Function &F, const TargetData& TD);
+            
         virtual void getAnalysisUsage(AnalysisUsage &AU) const {
           AU.addRequired<TargetData>();
         }
@@ -233,6 +241,22 @@
     
     const TargetData &TD = getAnalysis<TargetData>();
     
+    // Iterate to catch opportunities opened up by other optimizations,
+    // such as calls that are only used as arguments to unused calls:
+    // When the second call gets deleted the first call will become unused, but
+    // without iteration we wouldn't notice if we inspected the first call
+    // before the second one.
+    bool EverChanged = false;
+    bool Changed;
+    do {
+        Changed = runOnce(F, TD);
+        EverChanged |= Changed;
+    } while (Changed);
+    
+    return EverChanged;
+}
+
+bool SimplifyDRuntimeCalls::runOnce(Function &F, const TargetData& TD) {
     IRBuilder<> Builder;
     
     bool Changed = false;
@@ -268,17 +292,24 @@
             
             // Something changed!
             Changed = true;
-            ++NumSimplified;
+            
+            if (Result == CI) {
+                assert(CI->use_empty());
+                ++NumDeleted;
+            } else {
+                ++NumSimplified;
+                
+                if (!CI->use_empty())
+                    CI->replaceAllUsesWith(Result);
+                
+                if (!Result->hasName())
+                    Result->takeName(CI);
+            }
             
             // Inspect the instruction after the call (which was potentially just
             // added) next.
             I = CI; ++I;
             
-            if (CI != Result && !CI->use_empty()) {
-                CI->replaceAllUsesWith(Result);
-                if (!Result->hasName())
-                    Result->takeName(CI);
-            }
             CI->eraseFromParent();
         }
     }