summaryrefslogtreecommitdiff
path: root/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2007-08-04 01:47:41 +0000
committerChris Lattner <sabre@nondot.org>2007-08-04 01:47:41 +0000
commit5dd75b4ca7e582f44da2f50362e8ab4c59972b5f (patch)
tree9b1cd8f590eda03d73d75217cd5dee307e1affcc /lib/Transforms/Utils/PromoteMemoryToRegister.cpp
parentbbe104002fe7398bbde5d5ec2c2e5e324cf72305 (diff)
downloadllvm-5dd75b4ca7e582f44da2f50362e8ab4c59972b5f.tar.gz
llvm-5dd75b4ca7e582f44da2f50362e8ab4c59972b5f.tar.bz2
llvm-5dd75b4ca7e582f44da2f50362e8ab4c59972b5f.tar.xz
split rewriting of single-store allocas into its own
method. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@40806 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Utils/PromoteMemoryToRegister.cpp')
-rw-r--r--lib/Transforms/Utils/PromoteMemoryToRegister.cpp96
1 files changed, 57 insertions, 39 deletions
diff --git a/lib/Transforms/Utils/PromoteMemoryToRegister.cpp b/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
index f895d1955c..6be25d6dfe 100644
--- a/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
+++ b/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
@@ -78,6 +78,7 @@ bool llvm::isAllocaPromotable(const AllocaInst *AI) {
}
namespace {
+ struct AllocaInfo;
// Data package used by RenamePass()
class VISIBILITY_HIDDEN RenamePassData {
@@ -165,6 +166,8 @@ namespace {
--AllocaIdx;
}
+ void RewriteSingleStoreAlloca(AllocaInst *AI, AllocaInfo &Info);
+
void MarkDominatingPHILive(BasicBlock *BB, unsigned AllocaNum,
SmallPtrSet<PHINode*, 16> &DeadPHINodes);
bool PromoteLocallyUsedAlloca(BasicBlock *BB, AllocaInst *AI);
@@ -232,6 +235,7 @@ namespace {
} // end of anonymous namespace
+
void PromoteMem2Reg::run() {
Function &F = *DF.getRoot()->getParent();
@@ -282,45 +286,7 @@ void PromoteMem2Reg::run() {
// If there is only a single store to this value, replace any loads of
// it that are directly dominated by the definition with the value stored.
if (Info.DefiningBlocks.size() == 1) {
- // Be aware of loads before the store.
- std::set<BasicBlock*> 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(Info.OnlyStore->getParent(), Info.UsingBlocks[i]))
- if (ProcessedBlocks.insert(Info.UsingBlocks[i]).second) {
- BasicBlock *UseBlock = Info.UsingBlocks[i];
-
- // If the use and store are in the same block, do a quick scan to
- // verify that there are no uses before the store.
- if (UseBlock == Info.OnlyStore->getParent()) {
- BasicBlock::iterator I = UseBlock->begin();
- for (; &*I != Info.OnlyStore; ++I) { // scan block for store.
- if (isa<LoadInst>(I) && I->getOperand(0) == AI)
- break;
- }
- if (&*I != Info.OnlyStore) break; // Do not handle this case.
- }
-
- // Otherwise, if this is a different block or if all uses happen
- // after the store, do a simple linear scan to replace loads with
- // the stored value.
- for (BasicBlock::iterator I = UseBlock->begin(),E = UseBlock->end();
- I != E; ) {
- if (LoadInst *LI = dyn_cast<LoadInst>(I++)) {
- if (LI->getOperand(0) == AI) {
- LI->replaceAllUsesWith(Info.OnlyStore->getOperand(0));
- if (AST && isa<PointerType>(LI->getType()))
- AST->deleteValue(LI);
- LI->eraseFromParent();
- }
- }
- }
-
- // Finally, remove this block from the UsingBlock set.
- Info.UsingBlocks[i] = Info.UsingBlocks.back();
- --i; --e;
- }
+ RewriteSingleStoreAlloca(AI, Info);
// Finally, after the scan, check to see if the store is all that is left.
if (Info.UsingBlocks.empty()) {
@@ -559,6 +525,58 @@ void PromoteMem2Reg::run() {
NewPhiNodes.clear();
}
+
+/// RewriteSingleStoreAlloca - If there is only a single store to this value,
+/// replace any loads of it that are directly dominated by the definition with
+/// the value stored.
+void PromoteMem2Reg::RewriteSingleStoreAlloca(AllocaInst *AI,
+ AllocaInfo &Info) {
+ // Be aware of loads before the store.
+ std::set<BasicBlock*> 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(Info.OnlyStore->getParent(), Info.UsingBlocks[i]))
+ continue;
+
+ if (!ProcessedBlocks.insert(Info.UsingBlocks[i]).second)
+ continue;
+
+ BasicBlock *UseBlock = Info.UsingBlocks[i];
+
+ // If the use and store are in the same block, do a quick scan to
+ // verify that there are no uses before the store.
+ if (UseBlock == Info.OnlyStore->getParent()) {
+ BasicBlock::iterator I = UseBlock->begin();
+ for (; &*I != Info.OnlyStore; ++I) { // scan block for store.
+ if (isa<LoadInst>(I) && I->getOperand(0) == AI)
+ break;
+ }
+ if (&*I != Info.OnlyStore) break; // Do not handle this case.
+ }
+
+ // Otherwise, if this is a different block or if all uses happen
+ // after the store, do a simple linear scan to replace loads with
+ // the stored value.
+ for (BasicBlock::iterator I = UseBlock->begin(),E = UseBlock->end();
+ I != E; ) {
+ if (LoadInst *LI = dyn_cast<LoadInst>(I++)) {
+ if (LI->getOperand(0) == AI) {
+ LI->replaceAllUsesWith(Info.OnlyStore->getOperand(0));
+ if (AST && isa<PointerType>(LI->getType()))
+ AST->deleteValue(LI);
+ LI->eraseFromParent();
+ }
+ }
+ }
+
+ // Finally, remove this block from the UsingBlock set.
+ Info.UsingBlocks[i] = Info.UsingBlocks.back();
+ --i; --e;
+ }
+}
+
+
// MarkDominatingPHILive - Mem2Reg wants to construct "pruned" SSA form, not
// "minimal" SSA form. To do this, it inserts all of the PHI nodes on the IDF
// as usual (inserting the PHI nodes in the DeadPHINodes set), then processes