diff options
author | Evan Cheng <evan.cheng@apple.com> | 2009-06-02 00:56:07 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2009-06-02 00:56:07 +0000 |
commit | b00d928b57f8c212ab25ce3b7480845e53ce909c (patch) | |
tree | 04664029aa51e88a6513698524f46b5c9837141e /lib/Transforms/IPO | |
parent | 600ad047c13c1c8a0e0cbde1e67998bd6d2e5f94 (diff) | |
download | external_llvm-b00d928b57f8c212ab25ce3b7480845e53ce909c.zip external_llvm-b00d928b57f8c212ab25ce3b7480845e53ce909c.tar.gz external_llvm-b00d928b57f8c212ab25ce3b7480845e53ce909c.tar.bz2 |
Avoid infinite looping in AllGlobalLoadUsesSimpleEnoughForHeapSRA(). This can happen when PHI uses are recursively dependent on each other.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@72710 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/IPO')
-rw-r--r-- | lib/Transforms/IPO/GlobalOpt.cpp | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp index 8a752c2..2c01cc3 100644 --- a/lib/Transforms/IPO/GlobalOpt.cpp +++ b/lib/Transforms/IPO/GlobalOpt.cpp @@ -1020,7 +1020,8 @@ static void ReplaceUsesOfMallocWithGlobal(Instruction *Alloc, /// of a load) are simple enough to perform heap SRA on. This permits GEP's /// that index through the array and struct field, icmps of null, and PHIs. static bool LoadUsesSimpleEnoughForHeapSRA(Value *V, - SmallPtrSet<PHINode*, 32> &LoadUsingPHIs) { + SmallPtrSet<PHINode*, 32> &LoadUsingPHIs, + SmallPtrSet<PHINode*, 32> &LoadUsingPHIsPerLoad) { // We permit two users of the load: setcc comparing against the null // pointer, and a getelementptr of a specific form. for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E;++UI){ @@ -1044,12 +1045,17 @@ static bool LoadUsesSimpleEnoughForHeapSRA(Value *V, } if (PHINode *PN = dyn_cast<PHINode>(User)) { - // If we have already recursively analyzed this PHI, then it is safe. - if (LoadUsingPHIs.insert(PN)) + if (!LoadUsingPHIsPerLoad.insert(PN)) + // This means some phi nodes are dependent on each other. + // Avoid infinite looping! + return false; + if (!LoadUsingPHIs.insert(PN)) + // If we have already analyzed this PHI, then it is safe. continue; // Make sure all uses of the PHI are simple enough to transform. - if (!LoadUsesSimpleEnoughForHeapSRA(PN, LoadUsingPHIs)) + if (!LoadUsesSimpleEnoughForHeapSRA(PN, + LoadUsingPHIs, LoadUsingPHIsPerLoad)) return false; continue; @@ -1068,11 +1074,15 @@ static bool LoadUsesSimpleEnoughForHeapSRA(Value *V, static bool AllGlobalLoadUsesSimpleEnoughForHeapSRA(GlobalVariable *GV, MallocInst *MI) { SmallPtrSet<PHINode*, 32> LoadUsingPHIs; + SmallPtrSet<PHINode*, 32> LoadUsingPHIsPerLoad; for (Value::use_iterator UI = GV->use_begin(), E = GV->use_end(); UI != E; ++UI) - if (LoadInst *LI = dyn_cast<LoadInst>(*UI)) - if (!LoadUsesSimpleEnoughForHeapSRA(LI, LoadUsingPHIs)) + if (LoadInst *LI = dyn_cast<LoadInst>(*UI)) { + if (!LoadUsesSimpleEnoughForHeapSRA(LI, LoadUsingPHIs, + LoadUsingPHIsPerLoad)) return false; + LoadUsingPHIsPerLoad.clear(); + } // If we reach here, we know that all uses of the loads and transitive uses // (through PHI nodes) are simple enough to transform. However, we don't know |