[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