diff options
author | Chris Lattner <sabre@nondot.org> | 2007-09-13 16:37:20 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2007-09-13 16:37:20 +0000 |
commit | e7606f4485acd6d11fd8e2a77f379708eb1a74ce (patch) | |
tree | 693ef031409b472a9fff596a7c28460db72d2a51 /lib/Transforms/IPO/GlobalOpt.cpp | |
parent | bdf77460a8f2031f3461a2d91b9096861e11c2c8 (diff) | |
download | external_llvm-e7606f4485acd6d11fd8e2a77f379708eb1a74ce.zip external_llvm-e7606f4485acd6d11fd8e2a77f379708eb1a74ce.tar.gz external_llvm-e7606f4485acd6d11fd8e2a77f379708eb1a74ce.tar.bz2 |
Make ValueIsOnlyUsedLocallyOrStoredToOneGlobal smart enough to see through
bitcasts and phis. This is a step to fixing PR1639.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@41928 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/IPO/GlobalOpt.cpp')
-rw-r--r-- | lib/Transforms/IPO/GlobalOpt.cpp | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp index 51398b8..91e1296 100644 --- a/lib/Transforms/IPO/GlobalOpt.cpp +++ b/lib/Transforms/IPO/GlobalOpt.cpp @@ -811,7 +811,8 @@ static GlobalVariable *OptimizeGlobalAddressOfMalloc(GlobalVariable *GV, /// like dereferencing the pointer, but not storing through the address, unless /// it is to the specified global. static bool ValueIsOnlyUsedLocallyOrStoredToOneGlobal(Instruction *V, - GlobalVariable *GV) { + GlobalVariable *GV, + SmallPtrSet<PHINode*, 8> &PHIs) { for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E;++UI) if (isa<LoadInst>(*UI) || isa<CmpInst>(*UI)) { // Fine, ignore. @@ -819,9 +820,16 @@ static bool ValueIsOnlyUsedLocallyOrStoredToOneGlobal(Instruction *V, if (SI->getOperand(0) == V && SI->getOperand(1) != GV) return false; // Storing the pointer itself... bad. // Otherwise, storing through it, or storing into GV... fine. - } else if (isa<GetElementPtrInst>(*UI) || isa<SelectInst>(*UI)) { - if (!ValueIsOnlyUsedLocallyOrStoredToOneGlobal(cast<Instruction>(*UI),GV)) + } else if (isa<GetElementPtrInst>(*UI) || isa<SelectInst>(*UI) || + isa<BitCastInst>(*UI)) { + if (!ValueIsOnlyUsedLocallyOrStoredToOneGlobal(cast<Instruction>(*UI), + GV, PHIs)) return false; + } else if (PHINode *PN = dyn_cast<PHINode>(*UI)) { + // PHIs are ok if all uses are ok. Don't infinitely recurse through PHI + // cycles. + if (PHIs.insert(PN)) + return ValueIsOnlyUsedLocallyOrStoredToOneGlobal(PN, GV, PHIs); } else { return false; } @@ -1125,8 +1133,11 @@ static bool OptimizeOnceStoredGlobal(GlobalVariable *GV, Value *StoredOnceVal, // malloc to be stored into the specified global, loaded setcc'd, and // GEP'd. These are all things we could transform to using the global // for. - if (!ValueIsOnlyUsedLocallyOrStoredToOneGlobal(MI, GV)) - return false; + { + SmallPtrSet<PHINode*, 8> PHIs; + if (!ValueIsOnlyUsedLocallyOrStoredToOneGlobal(MI, GV, PHIs)) + return false; + } // If we have a global that is only initialized with a fixed size malloc, |