aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms/IPO
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2009-06-02 00:56:07 +0000
committerEvan Cheng <evan.cheng@apple.com>2009-06-02 00:56:07 +0000
commitb00d928b57f8c212ab25ce3b7480845e53ce909c (patch)
tree04664029aa51e88a6513698524f46b5c9837141e /lib/Transforms/IPO
parent600ad047c13c1c8a0e0cbde1e67998bd6d2e5f94 (diff)
downloadexternal_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.cpp22
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