[llvm-commits] CVS: llvm/lib/Transforms/IPO/GlobalOpt.cpp

Chris Lattner lattner at cs.uiuc.edu
Sun Feb 27 10:59:05 PST 2005



Changes in directory llvm/lib/Transforms/IPO:

GlobalOpt.cpp updated: 1.36 -> 1.37
---
Log message:

Teach globalopt how memset/cpy/move affect memory, to allow better optimization.


---
Diffs of the changes:  (+40 -25)

 GlobalOpt.cpp |   65 +++++++++++++++++++++++++++++++++++-----------------------
 1 files changed, 40 insertions(+), 25 deletions(-)


Index: llvm/lib/Transforms/IPO/GlobalOpt.cpp
diff -u llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.36 llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.37
--- llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.36	Wed Feb 23 10:52:58 2005
+++ llvm/lib/Transforms/IPO/GlobalOpt.cpp	Sun Feb 27 12:58:52 2005
@@ -18,6 +18,7 @@
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Instructions.h"
+#include "llvm/IntrinsicInst.h"
 #include "llvm/Module.h"
 #include "llvm/Pass.h"
 #include "llvm/Support/Debug.h"
@@ -194,7 +195,7 @@
           } else {
             GS.StoredType = GlobalStatus::isStored;
           }
-      } else if (I->getOpcode() == Instruction::GetElementPtr) {
+      } else if (isa<GetElementPtrInst>(I)) {
         if (AnalyzeGlobal(I, GS, PHIUsers)) return true;
 
         // If the first two indices are constants, this can be SRA'd.
@@ -212,7 +213,7 @@
         } else {
           GS.isNotSuitableForSRA = true;
         }
-      } else if (I->getOpcode() == Instruction::Select) {
+      } else if (isa<SelectInst>(I)) {
         if (AnalyzeGlobal(I, GS, PHIUsers)) return true;
         GS.isNotSuitableForSRA = true;
       } else if (PHINode *PN = dyn_cast<PHINode>(I)) {
@@ -223,6 +224,16 @@
         GS.isNotSuitableForSRA = true;
       } else if (isa<SetCondInst>(I)) {
         GS.isNotSuitableForSRA = true;
+      } else if (isa<MemCpyInst>(I) || isa<MemMoveInst>(I)) {
+        if (I->getOperand(1) == V)
+          GS.StoredType = GlobalStatus::isStored;
+        if (I->getOperand(2) == V)
+          GS.isLoaded = true;
+        GS.isNotSuitableForSRA = true;
+      } else if (isa<MemSetInst>(I)) {
+        assert(I->getOperand(1) == V && "Memset only takes one pointer!");
+        GS.StoredType = GlobalStatus::isStored;
+        GS.isNotSuitableForSRA = true;
       } else {
         return true;  // Any other non-load instruction might take address!
       }
@@ -270,6 +281,7 @@
 }
 
 static Constant *TraverseGEPInitializer(User *GEP, Constant *Init) {
+  if (Init == 0) return 0;
   if (GEP->getNumOperands() == 1 ||
       !isa<Constant>(GEP->getOperand(1)) ||
       !cast<Constant>(GEP->getOperand(1))->isNullValue())
@@ -294,47 +306,50 @@
     User *U = *UI++;
     
     if (LoadInst *LI = dyn_cast<LoadInst>(U)) {
-      // Replace the load with the initializer.
-      LI->replaceAllUsesWith(Init);
-      LI->eraseFromParent();
-      Changed = true;
+      if (Init) {
+        // Replace the load with the initializer.
+        LI->replaceAllUsesWith(Init);
+        LI->eraseFromParent();
+        Changed = true;
+      }
     } else if (StoreInst *SI = dyn_cast<StoreInst>(U)) {
       // Store must be unreachable or storing Init into the global.
       SI->eraseFromParent();
       Changed = true;
     } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U)) {
       if (CE->getOpcode() == Instruction::GetElementPtr) {
-        if (Constant *SubInit = TraverseGEPInitializer(CE, Init))
-          Changed |= CleanupConstantGlobalUsers(CE, SubInit);
-        if (CE->use_empty()) {
-          CE->destroyConstant();
-          Changed = true;
-        }
+        Constant *SubInit = TraverseGEPInitializer(CE, Init);
+        Changed |= CleanupConstantGlobalUsers(CE, SubInit);
+      } else if (CE->getOpcode() == Instruction::Cast &&
+                 isa<PointerType>(CE->getType())) {
+        // Pointer cast, delete any stores and memsets to the global.
+        Changed |= CleanupConstantGlobalUsers(CE, 0);
       }
-    } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(U)) {
-      if (Constant *SubInit = TraverseGEPInitializer(GEP, Init))
-        Changed |= CleanupConstantGlobalUsers(GEP, SubInit);
-      else {
-        // If this GEP has variable indexes, we should still be able to delete
-        // any stores through it.
-        for (Value::use_iterator GUI = GEP->use_begin(), E = GEP->use_end();
-             GUI != E;)
-          if (StoreInst *SI = dyn_cast<StoreInst>(*GUI++)) {
-            SI->eraseFromParent();
-            Changed = true;
-          }
+
+      if (CE->use_empty()) {
+        CE->destroyConstant();
+        Changed = true;
       }
+    } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(U)) {
+      Constant *SubInit = TraverseGEPInitializer(GEP, Init);
+      Changed |= CleanupConstantGlobalUsers(GEP, SubInit);
 
       if (GEP->use_empty()) {
         GEP->eraseFromParent();
         Changed = true;
       }
+    } else if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(U)) { // memset/cpy/mv
+      if (MI->getRawDest() == V) {
+        MI->eraseFromParent();
+        Changed = true;
+      }
+
     } else if (Constant *C = dyn_cast<Constant>(U)) {
       // If we have a chain of dead constantexprs or other things dangling from
       // us, and if they are all dead, nuke them without remorse.
       if (ConstantIsDead(C)) {
         C->destroyConstant();
-        // This could have incalidated UI, start over from scratch.x
+        // This could have invalidated UI, start over from scratch.
         CleanupConstantGlobalUsers(V, Init);
         return true;
       }






More information about the llvm-commits mailing list