aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Transforms/Utils/PromoteMemoryToRegister.cpp')
-rw-r--r--lib/Transforms/Utils/PromoteMemoryToRegister.cpp22
1 files changed, 16 insertions, 6 deletions
diff --git a/lib/Transforms/Utils/PromoteMemoryToRegister.cpp b/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
index 8fb9124a5f..02eeb3cc0a 100644
--- a/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
+++ b/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
@@ -532,17 +532,26 @@ void PromoteMem2Reg::run() {
void PromoteMem2Reg::RewriteSingleStoreAlloca(AllocaInst *AI,
AllocaInfo &Info) {
StoreInst *OnlyStore = Info.OnlyStore;
+ bool StoringGlobalVal = !isa<Instruction>(OnlyStore->getOperand(0));
// Be aware of loads before the store.
SmallPtrSet<BasicBlock*, 32> ProcessedBlocks;
for (unsigned i = 0, e = Info.UsingBlocks.size(); i != e; ++i) {
- // If the store dominates the block and if we haven't processed it yet,
- // do so now.
- if (!dominates(OnlyStore->getParent(), Info.UsingBlocks[i]))
+ BasicBlock *UseBlock = Info.UsingBlocks[i];
+
+ // If we already processed this block, don't reprocess it.
+ if (!ProcessedBlocks.insert(UseBlock)) {
+ Info.UsingBlocks[i] = Info.UsingBlocks.back();
+ Info.UsingBlocks.pop_back();
+ --i; --e;
continue;
+ }
- BasicBlock *UseBlock = Info.UsingBlocks[i];
- if (!ProcessedBlocks.insert(UseBlock))
+ // If the store dominates the block and if we haven't processed it yet,
+ // do so now. We can't handle the case where the store doesn't dominate a
+ // block because there may be a path between the store and the use, but we
+ // may need to insert phi nodes to handle dominance properly.
+ if (StoringGlobalVal || !dominates(OnlyStore->getParent(), UseBlock))
continue;
// If the use and store are in the same block, do a quick scan to
@@ -553,7 +562,8 @@ void PromoteMem2Reg::RewriteSingleStoreAlloca(AllocaInst *AI,
if (isa<LoadInst>(I) && I->getOperand(0) == AI)
break;
}
- if (&*I != OnlyStore) break; // Do not handle this case.
+ if (&*I != OnlyStore)
+ break; // Do not handle this alloca.
}
// Otherwise, if this is a different block or if all uses happen